From 8cca7616ae3a84e64bd3d0a880f09f18b4394b8e Mon Sep 17 00:00:00 2001 From: "https://www.google.com/accounts/o8/id?id=AItOawnoUOqs_lbuWyZBqyU6unHgUduJwDDgiKY" Date: Wed, 30 May 2012 00:25:22 +0000 Subject: [PATCH 01/30] --- doc/special_remotes/S3.mdwn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/special_remotes/S3.mdwn b/doc/special_remotes/S3.mdwn index f34b078ae1..195693b3b3 100644 --- a/doc/special_remotes/S3.mdwn +++ b/doc/special_remotes/S3.mdwn @@ -6,8 +6,8 @@ See [[tips/using_Amazon_S3]] and ## configuration -The standard environment variables `AWS_S3_ACCESS_KEY_ID` and -`AWS_S3_SECRET_ACCESS_KEY` are used to supply login credentials +The standard environment variables `AWS_ACCESS_KEY_ID` and +`AWS_SECRET_ACCESS_KEY` are used to supply login credentials for Amazon. When encryption is enabled, they are stored in encrypted form by `git annex initremote`, so you do not need to keep the environment variables set after the initial initalization of the remote. From 66d885aabc5e4afe94e303a2bd723970c6f36e48 Mon Sep 17 00:00:00 2001 From: "https://www.google.com/accounts/o8/id?id=AItOawnoUOqs_lbuWyZBqyU6unHgUduJwDDgiKY" Date: Wed, 30 May 2012 00:26:36 +0000 Subject: [PATCH 02/30] Added a comment --- .../comment_3_bcab2bd0f168954243aa9bcc9671bd94._comment | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 doc/special_remotes/S3/comment_3_bcab2bd0f168954243aa9bcc9671bd94._comment 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 0000000000..abb6aacc96 --- /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. +"""]] From 2150b8790645be32c8dd79b413e147daa8816c24 Mon Sep 17 00:00:00 2001 From: "https://www.google.com/accounts/o8/id?id=AItOawnoUOqs_lbuWyZBqyU6unHgUduJwDDgiKY" Date: Wed, 30 May 2012 00:27:23 +0000 Subject: [PATCH 03/30] --- doc/tips/using_Amazon_S3.mdwn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tips/using_Amazon_S3.mdwn b/doc/tips/using_Amazon_S3.mdwn index d941a19f01..128819fcbb 100644 --- a/doc/tips/using_Amazon_S3.mdwn +++ b/doc/tips/using_Amazon_S3.mdwn @@ -4,8 +4,8 @@ Amazon S3, and use git-annex to transfer files into the cloud. First, export your S3 credentials: - # export AWS_S3_ACCESS_KEY_ID="08TJMT99S3511WOZEP91" - # export AWS_S3_SECRET_ACCESS_KEY="s3kr1t" + # 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 From 2a61c5f2869c562ebd4433802c132b9bfac49ec4 Mon Sep 17 00:00:00 2001 From: "https://www.google.com/accounts/o8/id?id=AItOawnoUOqs_lbuWyZBqyU6unHgUduJwDDgiKY" Date: Wed, 30 May 2012 00:40:48 +0000 Subject: [PATCH 04/30] Added a comment --- .../comment_2_e90aa3259d9a12cd67daa27d42d69ab5._comment | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 doc/forum/Getting_started_with_Amazon_S3/comment_2_e90aa3259d9a12cd67daa27d42d69ab5._comment 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 0000000000..742e8d4469 --- /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? +"""]] From 1209972509a6014df2b3d85c1f3fb6f418c7c27d Mon Sep 17 00:00:00 2001 From: "https://www.google.com/accounts/o8/id?id=AItOawlBSuP2uCSUr5ONRVoyL7jg0ZhBc5us_w0" Date: Wed, 30 May 2012 00:51:29 +0000 Subject: [PATCH 05/30] smudge broken link --- doc/design/assistant/android.mdwn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/design/assistant/android.mdwn b/doc/design/assistant/android.mdwn index d936d53cc1..a33029b9db 100644 --- a/doc/design/assistant/android.mdwn +++ b/doc/design/assistant/android.mdwn @@ -32,7 +32,7 @@ Not ideal. #### implement git smudge filters -See [[smudge]]. +See [[todo/smudge]]. Difficult. Would make git-annex generally better. From bdb3c573934728c59c9dab6295cab8d65056bad5 Mon Sep 17 00:00:00 2001 From: "http://joeyh.name/" Date: Wed, 30 May 2012 00:54:38 +0000 Subject: [PATCH 06/30] Added a comment --- .../comment_3_c3adce7c0f29e71ed9dd07103ede2c1a._comment | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 doc/forum/Getting_started_with_Amazon_S3/comment_3_c3adce7c0f29e71ed9dd07103ede2c1a._comment 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 0000000000..450a1513ce --- /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. +"""]] From 65977a558446fd4208b04614191b68bae838b044 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 30 May 2012 17:01:22 -0400 Subject: [PATCH 07/30] lock: Reset unlocked file to index, rather than to branch head. Resetting an unlocked file to the branch head failed if it had just been added, not committed, and unlocked, since the branch didbn't have it. The code was concerned about dropping any changes that might be staged in the index, but I cannot see why. --- Command/Lock.hs | 6 +----- debian/changelog | 1 + doc/bugs/unlock_then_lock_of_uncommitted_file_loses_it.mdwn | 6 ++++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Command/Lock.hs b/Command/Lock.hs index b8aedb252b..ab97b14bcc 100644 --- a/Command/Lock.hs +++ b/Command/Lock.hs @@ -24,9 +24,5 @@ start file = do perform :: FilePath -> CommandPerform perform file = do - liftIO $ removeFile file - -- Checkout from HEAD to get rid of any changes that might be - -- staged in the index, and get back to the previous symlink to - -- the content. - Annex.Queue.add "checkout" [Param "HEAD", Param "--"] [file] + Annex.Queue.add "checkout" [Param "--"] [file] next $ return True -- no cleanup needed diff --git a/debian/changelog b/debian/changelog index 9c38d1727f..6b57a5580c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ git-annex (3.20120523) UNRELEASED; 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. -- Joey Hess Sun, 27 May 2012 20:55:29 -0400 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 index 69704bdd07..9c093de389 100644 --- a/doc/bugs/unlock_then_lock_of_uncommitted_file_loses_it.mdwn +++ b/doc/bugs/unlock_then_lock_of_uncommitted_file_loses_it.mdwn @@ -1,5 +1,7 @@ -Add a file, then unlock it, and then lock it. There is an error and the -symlink gets deleted. +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]] From 29b43cfa395c87f722be35fb45cfea94cd3338ea Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 30 May 2012 20:50:53 -0400 Subject: [PATCH 08/30] pairing --- doc/design/assistant.mdwn | 2 +- doc/design/assistant/configurators.mdwn | 7 +------ doc/design/assistant/pairing.mdwn | 13 +++++++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 doc/design/assistant/pairing.mdwn diff --git a/doc/design/assistant.mdwn b/doc/design/assistant.mdwn index 63f3c56d6f..7a720a5e08 100644 --- a/doc/design/assistant.mdwn +++ b/doc/design/assistant.mdwn @@ -9,7 +9,7 @@ Feel free to chip in with comments! --[[Joey]] * Month 1 "like dropbox": [[!traillink inotify]] [[!traillink syncing]] * Month 2 "shiny webapp": [[!traillink webapp]] [[!traillink progressbars]] -* Month 3 "easy setup": [[!traillink configurators]] +* Month 3 "easy setup": [[!traillink configurators]] [[!traillink pairing]] * Month 4 "polishing": [[!traillink cloud]] [[!traillink leftovers]] * Months 5-6 "9k bonus round": [[!traillink Android]] [[!traillink partial_content]] diff --git a/doc/design/assistant/configurators.mdwn b/doc/design/assistant/configurators.mdwn index b9e3a66328..e0e938efdd 100644 --- a/doc/design/assistant/configurators.mdwn +++ b/doc/design/assistant/configurators.mdwn @@ -10,12 +10,7 @@ through setting up common use cases. * Create a repository (run when the web app is started without a configured repository too). * Clone this repo to a USB drive. -* Clone this repo to another host: - 1. Prompt for the hostname (or do avahi local machine discovery). - 2. Enable the two hosts to ssh to one-another and run git-annex shell. - (A tricky problem, if ssh keys need to be added to do that.) - 3. Push over a clone of the repository. (Using git-annex-shell?) - 4. Start [[syncing]]. +* Clone this repo to another host. (Needs [[pairing]]) * Set up Amazon S3. * Set up rsync remote. * Set up encryption. diff --git a/doc/design/assistant/pairing.mdwn b/doc/design/assistant/pairing.mdwn new file mode 100644 index 0000000000..f33c5e11de --- /dev/null +++ b/doc/design/assistant/pairing.mdwn @@ -0,0 +1,13 @@ +For git-annex to be able to clone its repo to another host, it'd be good to +have some way of pairing devices. + +It could work like this: + +1. Prompt for the hostname (or do avahi local machine discovery). +2. Enable the two hosts to ssh to one-another and run git-annex shell. + (A tricky problem, if ssh keys need to be added to do that.) +3. Push over a clone of the repository. (Using git-annex-shell?) +4. Start [[syncing]]. + +Also look into the method used by + From 8c759893384d78bde6247ab200fab696113186dc Mon Sep 17 00:00:00 2001 From: "http://dlaxalde.myopenid.com/" Date: Thu, 31 May 2012 14:36:33 +0000 Subject: [PATCH 09/30] Added a comment --- ...omment_1_cf19b8dc304dc37c26717174c4a98aa4._comment | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 doc/tips/what_to_do_when_you_lose_a_repository/comment_1_cf19b8dc304dc37c26717174c4a98aa4._comment 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 0000000000..a7fce26ef8 --- /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`? +"""]] From 4f3b83d33043f07cbf94a6260052c1e20737bc7b Mon Sep 17 00:00:00 2001 From: "http://joeyh.name/" Date: Thu, 31 May 2012 17:00:59 +0000 Subject: [PATCH 10/30] Added a comment --- .../comment_2_e2f5d7d3efaaa8833a2cf2e9f1bd9962._comment | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 doc/tips/what_to_do_when_you_lose_a_repository/comment_2_e2f5d7d3efaaa8833a2cf2e9f1bd9962._comment diff --git a/doc/tips/what_to_do_when_you_lose_a_repository/comment_2_e2f5d7d3efaaa8833a2cf2e9f1bd9962._comment b/doc/tips/what_to_do_when_you_lose_a_repository/comment_2_e2f5d7d3efaaa8833a2cf2e9f1bd9962._comment new file mode 100644 index 0000000000..0e19b806c3 --- /dev/null +++ b/doc/tips/what_to_do_when_you_lose_a_repository/comment_2_e2f5d7d3efaaa8833a2cf2e9f1bd9962._comment @@ -0,0 +1,8 @@ +[[!comment format=mdwn + username="http://joeyh.name/" + ip="4.153.8.243" + subject="comment 2" + date="2012-05-31T17:00:59Z" + content=""" +`dead +"""]] From 9c72d42cf4881840b51535091c23126857260f98 Mon Sep 17 00:00:00 2001 From: "http://joeyh.name/" Date: Thu, 31 May 2012 17:01:37 +0000 Subject: [PATCH 11/30] Added a comment --- .../comment_3_fa9ca81668f5faebf2f61b10f82c97d2._comment | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 doc/tips/what_to_do_when_you_lose_a_repository/comment_3_fa9ca81668f5faebf2f61b10f82c97d2._comment 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 0000000000..a8d044c287 --- /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. +"""]] From cbace05372b05d0b7a73561e497edcae9b4abd6d Mon Sep 17 00:00:00 2001 From: "http://joeyh.name/" Date: Thu, 31 May 2012 17:01:51 +0000 Subject: [PATCH 12/30] removed --- .../comment_2_e2f5d7d3efaaa8833a2cf2e9f1bd9962._comment | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 doc/tips/what_to_do_when_you_lose_a_repository/comment_2_e2f5d7d3efaaa8833a2cf2e9f1bd9962._comment diff --git a/doc/tips/what_to_do_when_you_lose_a_repository/comment_2_e2f5d7d3efaaa8833a2cf2e9f1bd9962._comment b/doc/tips/what_to_do_when_you_lose_a_repository/comment_2_e2f5d7d3efaaa8833a2cf2e9f1bd9962._comment deleted file mode 100644 index 0e19b806c3..0000000000 --- a/doc/tips/what_to_do_when_you_lose_a_repository/comment_2_e2f5d7d3efaaa8833a2cf2e9f1bd9962._comment +++ /dev/null @@ -1,8 +0,0 @@ -[[!comment format=mdwn - username="http://joeyh.name/" - ip="4.153.8.243" - subject="comment 2" - date="2012-05-31T17:00:59Z" - content=""" -`dead -"""]] From 595d13020b4004b1813cc3bc31ed1a8edf2fe511 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 May 2012 15:25:26 -0400 Subject: [PATCH 13/30] updates --- doc/design/assistant/android.mdwn | 13 ++++++++++++- doc/design/assistant/inotify.mdwn | 4 +++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/design/assistant/android.mdwn b/doc/design/assistant/android.mdwn index a33029b9db..90dc551794 100644 --- a/doc/design/assistant/android.mdwn +++ b/doc/design/assistant/android.mdwn @@ -14,6 +14,14 @@ available in the App Store. * git (not all git commands are needed, but core plumbing and a few like `git-add` are.) +### Android specific features + +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. + ### FAT sucks The main media partition will use some awful FAT filesystem format from @@ -26,10 +34,13 @@ handle all of git's filenames.) Possible approaches to this follow. Keep only a bare git repo on Android. The app would then need to include a file browser to access the files in there, and adding a file would move -it into the repo. +it into the repo. Not ideal. +Could be improved some by registering git-annex as a file handling app on +Android, allowing you to "send to" git-annex. + #### implement git smudge filters See [[todo/smudge]]. diff --git a/doc/design/assistant/inotify.mdwn b/doc/design/assistant/inotify.mdwn index be38ef13cd..6bb810a755 100644 --- a/doc/design/assistant/inotify.mdwn +++ b/doc/design/assistant/inotify.mdwn @@ -8,7 +8,9 @@ useful, it needs to: - notice deleted files and stage the deletion (tricky; there's a race with add..) - notice renamed files, auto-fix the symlink, and stage the new file location -- periodically auto-commit staged changes +- periodically auto-commit staged changes (avoid autocommitting when + lots of changes are coming in) +- tunable delays before adding new files, etc - honor .gitignore, not adding files it excludesa Also to do: From 6ea9a88ede48fa6d37a0ac476ca775c0edaa56a4 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 May 2012 15:28:04 -0400 Subject: [PATCH 14/30] update --- doc/design/assistant/webapp.mdwn | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/design/assistant/webapp.mdwn b/doc/design/assistant/webapp.mdwn index 5322fe8a5f..857b5972bf 100644 --- a/doc/design/assistant/webapp.mdwn +++ b/doc/design/assistant/webapp.mdwn @@ -16,6 +16,11 @@ The webapp is a web server that displays a shiny interface. * cancel and pause * keep it usable w/o javascript, and accessible to blind, etc +## other features + +* there could be a UI to export a file, which would make it be served up + over http by the web app + ## implementation Hope to use Yesod. From 2941d30bda3adc7420dd8f800192d7154e960bc2 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 May 2012 15:48:26 -0400 Subject: [PATCH 15/30] update --- doc/design/assistant/webapp.mdwn | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/design/assistant/webapp.mdwn b/doc/design/assistant/webapp.mdwn index 857b5972bf..abf7b38c94 100644 --- a/doc/design/assistant/webapp.mdwn +++ b/doc/design/assistant/webapp.mdwn @@ -7,6 +7,9 @@ The webapp is a web server that displays a shiny interface. token. This guards against other users on the same system. * I would like to avoid passwords or other authentication methods, it's your local system. +* 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. ## interface From 263ee1d067c8ef7361ecdb096ee227011f8d25dd Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 31 May 2012 20:02:48 +0000 Subject: [PATCH 16/30] Add explanation of how git on Windows handles symlinks. --- doc/design/assistant/windows.mdwn | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/design/assistant/windows.mdwn b/doc/design/assistant/windows.mdwn index 0b176934b9..89c3082a85 100644 --- a/doc/design/assistant/windows.mdwn +++ b/doc/design/assistant/windows.mdwn @@ -8,7 +8,8 @@ Stackoverflow has some details. Make git use them, as it (apparently) does not yet. -(What **does** git do on Windows when it clones a repo with symlinks?) +Currently, on Windows, git checks out symlinks as files containing the symlink +target as their contents. ## POSIX From 233d4020755429785688ab91e99bd260ffbc1490 Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 31 May 2012 20:03:02 +0000 Subject: [PATCH 17/30] Fix typo. --- doc/design/assistant/windows.mdwn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/design/assistant/windows.mdwn b/doc/design/assistant/windows.mdwn index 89c3082a85..850f98194e 100644 --- a/doc/design/assistant/windows.mdwn +++ b/doc/design/assistant/windows.mdwn @@ -15,4 +15,4 @@ target as their contents. Lots of ifdefs and pain to deal with POSIX calls in the code base. -Or I could try to use Cywin. +Or I could try to use Cygwin. From c47b1ecda00cea6d9922e0733c3ab365bc2f004d Mon Sep 17 00:00:00 2001 From: josh Date: Thu, 31 May 2012 20:11:43 +0000 Subject: [PATCH 18/30] Discussion of NTFS symlinks, junction points, and reparse points. --- doc/design/assistant/windows.mdwn | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/design/assistant/windows.mdwn b/doc/design/assistant/windows.mdwn index 850f98194e..da669ad82c 100644 --- a/doc/design/assistant/windows.mdwn +++ b/doc/design/assistant/windows.mdwn @@ -6,6 +6,8 @@ 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. + Make git use them, as it (apparently) does not yet. Currently, on Windows, git checks out symlinks as files containing the symlink @@ -16,3 +18,7 @@ target as their contents. 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. From 3b09281b442e794213f2e296e42e2d74fddec733 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 May 2012 19:25:33 -0400 Subject: [PATCH 19/30] add dirContentsRecursive --- Utility/Directory.hs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/Utility/Directory.hs b/Utility/Directory.hs index 3041361dfd..5bfd49a9c1 100644 --- a/Utility/Directory.hs +++ b/Utility/Directory.hs @@ -17,6 +17,7 @@ import System.FilePath import Control.Applicative import Control.Exception (bracket_) import System.Posix.Directory +import System.IO.Unsafe (unsafeInterleaveIO) import Utility.SafeCommand import Utility.TempFile @@ -24,14 +25,37 @@ import Utility.Exception import Utility.Monad import Utility.Path +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 notcruft <$> getDirectoryContents d +dirContents d = map (d ) . filter (not . dirCruft) <$> getDirectoryContents d + +{- Gets contents of directory, and then its subdirectories, recursively, + - and lazily. -} +dirContentsRecursive :: FilePath -> IO [FilePath] +dirContentsRecursive topdir = dirContentsRecursive' topdir [""] + +dirContentsRecursive' :: FilePath -> [FilePath] -> IO [FilePath] +dirContentsRecursive' _ [] = return [] +dirContentsRecursive' topdir (dir:dirs) = unsafeInterleaveIO $ do + (files, dirs') <- collect [] [] =<< dirContents (topdir dir) + files' <- dirContentsRecursive' topdir (dirs' ++ dirs) + return (files ++ files') where - notcruft "." = False - notcruft ".." = False - notcruft _ = True + collect files dirs' [] = return (reverse files, reverse dirs') + collect files dirs' (entry:entries) + | dirCruft entry = collect files dirs' entries + | otherwise = do + let dirEntry = dir entry + ifM (doesDirectoryExist $ topdir dirEntry) + ( collect files (dirEntry:dirs') entries + , collect (dirEntry:files) dirs' entries + ) {- Moves one filename to another. - First tries a rename, but falls back to moving across devices if needed. -} From 3a10095d40cf9a9e0380b6b10e1ebe304f1537c0 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 May 2012 19:47:18 -0400 Subject: [PATCH 20/30] import: New subcommand, pulls files from a directory outside the annex and adds them Use case for this was developed somewhere on the Transiberian Railroad. --- Command/Import.hs | 39 +++++++++++++++++++++++++++++++++++++++ GitAnnex.hs | 2 ++ Seek.hs | 10 +++++++++- debian/changelog | 2 ++ doc/git-annex.mdwn | 9 +++++++++ 5 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 Command/Import.hs diff --git a/Command/Import.hs b/Command/Import.hs new file mode 100644 index 0000000000..e27a421f27 --- /dev/null +++ b/Command/Import.hs @@ -0,0 +1,39 @@ +{- git-annex command + - + - Copyright 2012 Joey Hess + - + - Licensed under the GNU GPL version 3 or higher. + -} + +module Command.Import where + +import Common.Annex +import Command +import qualified Annex +import qualified Command.Add + +def :: [Command] +def = [command "import" paramPaths seek "move and add files from outside git working copy"] + +seek :: [CommandSeek] +seek = [withPathContents start] + +start :: (FilePath, FilePath) -> CommandStart +start (srcfile, destfile) = notBareRepo $ + ifM (liftIO $ isRegularFile <$> getSymbolicLinkStatus srcfile) + ( do + showStart "import" destfile + next $ perform srcfile destfile + , stop + ) + +perform :: FilePath -> FilePath -> CommandPerform +perform srcfile destfile = 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 $ moveFile srcfile destfile + Command.Add.perform destfile diff --git a/GitAnnex.hs b/GitAnnex.hs index 9910e33d21..149b37f930 100644 --- a/GitAnnex.hs +++ b/GitAnnex.hs @@ -54,6 +54,7 @@ import qualified Command.Semitrust import qualified Command.Dead import qualified Command.Sync import qualified Command.AddUrl +import qualified Command.Import import qualified Command.Map import qualified Command.Upgrade import qualified Command.Version @@ -69,6 +70,7 @@ cmds = concat , Command.Lock.def , Command.Sync.def , Command.AddUrl.def + , Command.Import.def , Command.Init.def , Command.Describe.def , Command.InitRemote.def diff --git a/Seek.hs b/Seek.hs index 8d4f917e72..eed4a81558 100644 --- a/Seek.hs +++ b/Seek.hs @@ -4,7 +4,7 @@ - the values a user passes to a command, and prepare actions operating - on them. - - - Copyright 2010-2011 Joey Hess + - Copyright 2010-2012 Joey Hess - - Licensed under the GNU GPL version 3 or higher. -} @@ -41,6 +41,14 @@ withFilesNotInGit a params = do g <- gitRepo liftIO $ (\p -> LsFiles.notInRepo force p g) l +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 p f)) <$> dirContentsRecursive p + , return [(p, takeFileName p)] + ) + withWords :: ([String] -> CommandStart) -> CommandSeek withWords a params = return [a params] diff --git a/debian/changelog b/debian/changelog index 6b57a5580c..a110e94ce9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,8 @@ git-annex (3.20120523) UNRELEASED; 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. -- Joey Hess Sun, 27 May 2012 20:55:29 -0400 diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn index 5d41f86e9c..c7de59cd2a 100644 --- a/doc/git-annex.mdwn +++ b/doc/git-annex.mdwn @@ -160,6 +160,15 @@ subdirectories). 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. +* 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, all files in it are imported, and any + subdirectory structure inside it is preserved. + + git annex import /media/camera/DCIM/ + # REPOSITORY SETUP COMMANDS * init [description] From 6fd83851c13232b7810a33e8bb1d83e8a46bd354 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 May 2012 21:03:24 -0400 Subject: [PATCH 21/30] Fix display of warning message when encountering a file that uses an unsupported backend. --- Backend.hs | 8 ++++---- Locations.hs | 4 +++- debian/changelog | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Backend.hs b/Backend.hs index 8071b9b835..fa32669449 100644 --- a/Backend.hs +++ b/Backend.hs @@ -75,16 +75,16 @@ genKey' (b:bs) file = do - by examining what the file symlinks to. -} lookupFile :: FilePath -> Annex (Maybe (Key, Backend)) lookupFile file = do - tl <- liftIO $ tryIO getsymlink + tl <- liftIO $ tryIO $ readSymbolicLink file case tl of Left _ -> return Nothing Right l -> makekey l where - getsymlink = takeFileName <$> readSymbolicLink file - makekey l = maybe (return Nothing) (makeret l) (fileKey l) + makekey l = maybe (return Nothing) (makeret l) (fileKey $ takeFileName l) makeret l k = let bname = keyBackendName k in case maybeLookupBackendName bname of - Just backend -> return $ Just (k, backend) + Just backend -> do + return $ Just (k, backend) Nothing -> do when (isLinkToAnnex l) $ warning $ "skipping " ++ file ++ diff --git a/Locations.hs b/Locations.hs index 46a85e0ee1..db456388a6 100644 --- a/Locations.hs +++ b/Locations.hs @@ -155,7 +155,9 @@ gitAnnexRemotesDir r = addTrailingPathSeparator $ gitAnnexDir r "remotes" {- Checks a symlink target to see if it appears to point to annexed content. -} isLinkToAnnex :: FilePath -> Bool -isLinkToAnnex s = ("/.git/" ++ objectDir) `isInfixOf` s +isLinkToAnnex s = ("/" ++ d) `isInfixOf` s || d `isPrefixOf` s + where + d = ".git" objectDir {- Converts a key into a filename fragment without any directory. - diff --git a/debian/changelog b/debian/changelog index a110e94ce9..61290b1aaf 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,8 @@ git-annex (3.20120523) UNRELEASED; urgency=low * 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. -- Joey Hess Sun, 27 May 2012 20:55:29 -0400 From 1f951de014d0bfb3d2cf2b58e607cabefdf30d84 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 31 May 2012 21:31:25 -0400 Subject: [PATCH 22/30] add a nice one --- doc/testimonials.mdwn | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/testimonials.mdwn b/doc/testimonials.mdwn index 65bc5a5fe2..f053c58398 100644 --- a/doc/testimonials.mdwn +++ b/doc/testimonials.mdwn @@ -9,6 +9,13 @@ +
+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. +
+-- Jason Scott + Seen on IRC:
 oh my god, git-annex is amazing

From f5de183c7168627e9bd969aa48f8215f411bc507 Mon Sep 17 00:00:00 2001
From: Joey Hess 
Date: Thu, 31 May 2012 21:51:42 -0400
Subject: [PATCH 23/30] sha256sum not so optional

---
 doc/install/OSX.mdwn | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/install/OSX.mdwn b/doc/install/OSX.mdwn
index ffd9424372..08904aef9f 100644
--- a/doc/install/OSX.mdwn
+++ b/doc/install/OSX.mdwn
@@ -7,7 +7,7 @@ sudo port install git-core ossp-uuid md5sha1sum coreutils pcre
 
 sudo ln -s /opt/local/include/pcre.h  /usr/include/pcre.h # This is hack that allows pcre-light to find pcre
 
-# optional: this will enable the gnu tools, (to give sha224sum etc..., it does not override the BSD userland)
+# this will enable the gnu tools, (to give sha256sum etc..., it does not override the BSD userland)
 export PATH=$PATH:/opt/local/libexec/gnubin
 
 git clone git://git-annex.branchable.com/ git-annex

From 2183fd2abd95b6deaa9baef47e2f9c5f865123e1 Mon Sep 17 00:00:00 2001
From: Joey Hess 
Date: Thu, 31 May 2012 23:15:40 -0400
Subject: [PATCH 24/30] Require that the SHA256 backend can be used when
 building, since it's the default.

---
 Backend/SHA.hs     | 2 +-
 Build/Configure.hs | 9 +++++----
 debian/changelog   | 2 ++
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/Backend/SHA.hs b/Backend/SHA.hs
index 3adac65d8c..c2a6cf9761 100644
--- a/Backend/SHA.hs
+++ b/Backend/SHA.hs
@@ -45,7 +45,7 @@ genBackendE size =
 
 shaCommand :: SHASize -> Maybe String
 shaCommand 1 = SysConfig.sha1
-shaCommand 256 = SysConfig.sha256
+shaCommand 256 = Just SysConfig.sha256
 shaCommand 224 = SysConfig.sha224
 shaCommand 384 = SysConfig.sha384
 shaCommand 512 = SysConfig.sha512
diff --git a/Build/Configure.hs b/Build/Configure.hs
index 341b8840dc..86a3479244 100644
--- a/Build/Configure.hs
+++ b/Build/Configure.hs
@@ -26,15 +26,16 @@ tests =
 	, TestCase "bup" $ testCmd "bup" "bup --version >/dev/null"
 	, TestCase "gpg" $ testCmd "gpg" "gpg --version >/dev/null"
 	, TestCase "ssh connection caching" getSshConnectionCaching
-	] ++ shaTestCases [1, 256, 512, 224, 384]
+	] ++ shaTestCases False [1, 512, 224, 384] ++ shaTestCases True [256]
 
-shaTestCases :: [Int] -> [TestCase]
-shaTestCases l = map make l
+shaTestCases :: Bool -> [Int] -> [TestCase]
+shaTestCases required l = map make l
 	where make n =
 		let
 			cmds = map (\x -> "sha" ++ show n ++ x) ["", "sum"]
 			key = "sha" ++ show n
-		in TestCase key $ maybeSelectCmd key cmds "  Sun, 27 May 2012 20:55:29 -0400
 

From 665c0fbdaafab7b3ea2737f302a8951f26e4f01a Mon Sep 17 00:00:00 2001
From: Joey Hess 
Date: Thu, 31 May 2012 23:33:07 -0400
Subject: [PATCH 25/30] check at configure time for sha commands in Mac OSX
 location

---
 Build/Configure.hs   | 18 ++++++++++++------
 doc/install/OSX.mdwn |  3 ---
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/Build/Configure.hs b/Build/Configure.hs
index 86a3479244..2f79297ee9 100644
--- a/Build/Configure.hs
+++ b/Build/Configure.hs
@@ -6,6 +6,7 @@ import System.Directory
 import Data.List
 import System.Cmd.Utils
 import Control.Applicative
+import System.FilePath
 
 import Build.TestConfig
 import Utility.SafeCommand
@@ -30,12 +31,17 @@ tests =
 
 shaTestCases :: Bool -> [Int] -> [TestCase]
 shaTestCases required l = map make l
-	where make n =
-		let
-			cmds = map (\x -> "sha" ++ show n ++ x) ["", "sum"]
-			key = "sha" ++ show n
-			selector = if required then selectCmd else maybeSelectCmd
-		in TestCase key $ selector key cmds " [x, osxpath  x]) $
+			map (\x -> "sha" ++ show n ++ x) ["", "sum"]
+		-- Max OSX 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"
diff --git a/doc/install/OSX.mdwn b/doc/install/OSX.mdwn
index 08904aef9f..1d8a3b9437 100644
--- a/doc/install/OSX.mdwn
+++ b/doc/install/OSX.mdwn
@@ -7,9 +7,6 @@ sudo port install git-core ossp-uuid md5sha1sum coreutils pcre
 
 sudo ln -s /opt/local/include/pcre.h  /usr/include/pcre.h # This is hack that allows pcre-light to find pcre
 
-# this will enable the gnu tools, (to give sha256sum etc..., it does not override the BSD userland)
-export PATH=$PATH:/opt/local/libexec/gnubin
-
 git clone git://git-annex.branchable.com/ git-annex
 cd git-annex
 git checkout ghc7.0

From 3812e67a054d5bd479b7a4be6d28027664a89bcb Mon Sep 17 00:00:00 2001
From: 
 "https://www.google.com/accounts/o8/id?id=AItOawnHrjHxJAm39x8DR4bnbazQO6H0nMNuY9c"
 
Date: Fri, 1 Jun 2012 16:05:06 +0000
Subject: [PATCH 26/30] Added a comment: sha256 ?

---
 .../comment_5_69f71b49e6a434cc3426989102c65edf._comment   | 8 ++++++++
 1 file changed, 8 insertions(+)
 create mode 100644 doc/install/OSX/comment_5_69f71b49e6a434cc3426989102c65edf._comment

diff --git a/doc/install/OSX/comment_5_69f71b49e6a434cc3426989102c65edf._comment b/doc/install/OSX/comment_5_69f71b49e6a434cc3426989102c65edf._comment
new file mode 100644
index 0000000000..b37e9732fb
--- /dev/null
+++ b/doc/install/OSX/comment_5_69f71b49e6a434cc3426989102c65edf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnHrjHxJAm39x8DR4bnbazQO6H0nMNuY9c"
+ nickname="Damien"
+ subject="sha256 ?"
+ date="2012-06-01T16:05:05Z"
+ content="""
+homebrew's `md5sha1sum` does not provide a `sha256` command that seems to be required… where does yours come from ?
+"""]]

From ca755617d6fe0835c36371a90db75b3a2b4ce4a4 Mon Sep 17 00:00:00 2001
From: 
 "https://www.google.com/accounts/o8/id?id=AItOawnHrjHxJAm39x8DR4bnbazQO6H0nMNuY9c"
 
Date: Fri, 1 Jun 2012 16:10:17 +0000
Subject: [PATCH 27/30] removed

---
 .../comment_5_69f71b49e6a434cc3426989102c65edf._comment   | 8 --------
 1 file changed, 8 deletions(-)
 delete mode 100644 doc/install/OSX/comment_5_69f71b49e6a434cc3426989102c65edf._comment

diff --git a/doc/install/OSX/comment_5_69f71b49e6a434cc3426989102c65edf._comment b/doc/install/OSX/comment_5_69f71b49e6a434cc3426989102c65edf._comment
deleted file mode 100644
index b37e9732fb..0000000000
--- a/doc/install/OSX/comment_5_69f71b49e6a434cc3426989102c65edf._comment
+++ /dev/null
@@ -1,8 +0,0 @@
-[[!comment format=mdwn
- username="https://www.google.com/accounts/o8/id?id=AItOawnHrjHxJAm39x8DR4bnbazQO6H0nMNuY9c"
- nickname="Damien"
- subject="sha256 ?"
- date="2012-06-01T16:05:05Z"
- content="""
-homebrew's `md5sha1sum` does not provide a `sha256` command that seems to be required… where does yours come from ?
-"""]]

From be45ac2fa0d201ec3a7270c33c59be05ec43bab3 Mon Sep 17 00:00:00 2001
From: 
 "https://www.google.com/accounts/o8/id?id=AItOawnHrjHxJAm39x8DR4bnbazQO6H0nMNuY9c"
 
Date: Fri, 1 Jun 2012 16:13:06 +0000
Subject: [PATCH 28/30] Added a comment: sha256

---
 ...comment_5_50777853f808d57b957f8ce9a0f84b3d._comment | 10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100644 doc/install/OSX/comment_5_50777853f808d57b957f8ce9a0f84b3d._comment

diff --git a/doc/install/OSX/comment_5_50777853f808d57b957f8ce9a0f84b3d._comment b/doc/install/OSX/comment_5_50777853f808d57b957f8ce9a0f84b3d._comment
new file mode 100644
index 0000000000..eca1761786
--- /dev/null
+++ b/doc/install/OSX/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\"
+"""]]

From f74c287e7eea1900c2155ef200f90ba5f58c7caf Mon Sep 17 00:00:00 2001
From: "http://joeyh.name/" 
Date: Fri, 1 Jun 2012 17:24:29 +0000
Subject: [PATCH 29/30] Added a comment

---
 .../comment_6_18a8df794aa0ddd294dbf17d3d4c7fe2._comment    | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 doc/install/OSX/comment_6_18a8df794aa0ddd294dbf17d3d4c7fe2._comment

diff --git a/doc/install/OSX/comment_6_18a8df794aa0ddd294dbf17d3d4c7fe2._comment b/doc/install/OSX/comment_6_18a8df794aa0ddd294dbf17d3d4c7fe2._comment
new file mode 100644
index 0000000000..5cb813776b
--- /dev/null
+++ b/doc/install/OSX/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.
+"""]]

From 0064fc0beb98e7254dc026b614bad2e5518ea5dc Mon Sep 17 00:00:00 2001
From: 
 "https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
 
Date: Sat, 2 Jun 2012 12:06:38 +0000
Subject: [PATCH 30/30] Added a comment

---
 .../comment_1_a48fcfbf97f0a373ea375cd8f07f0fc8._comment   | 8 ++++++++
 1 file changed, 8 insertions(+)
 create mode 100644 doc/design/assistant/comment_1_a48fcfbf97f0a373ea375cd8f07f0fc8._comment

diff --git a/doc/design/assistant/comment_1_a48fcfbf97f0a373ea375cd8f07f0fc8._comment b/doc/design/assistant/comment_1_a48fcfbf97f0a373ea375cd8f07f0fc8._comment
new file mode 100644
index 0000000000..646a03398a
--- /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.
+"""]]