[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [MirageOS-devel] Irmin API newbie questions
On 9 February 2015 at 14:41, Thomas Gazagnaire <thomas@xxxxxxxxxxxxxx> wrote: > Hi Thomas, > >> (BTW, I think it might be useful to add the equivalent git command >> next to functions in the documentation, since most people will >> understand that already) > > ack, I'll do this. > >> The BASIC docs are missing >> (https://mirage.github.io/irmin/Irmin.BASIC.html), but the code shows: >> >> type ('a, 'b) basic = (module BASIC with type key = 'a and type value = 'b) >> >> It seems that using Irmin.Contents.String gets me "key = string list", >> but "step" remains abstract. How do I use cons, decons, etc? > > Why do you need to use cons and decons? Normally you should just need to use > the usual list operators (ie. (::) for cons and pattern-matching for decons). > If you have a use-case where this is not enough, please share it! It's > possible that I forgot to export a type constraint somewhere. When walking the tree it's useful to get the last component with rdecons, since there's no built-in function for this. Easy enough to work around, of course. It's actually a bit strange that "list" returns a "key list" rather than a "step list" (i.e. it returns full paths). The docs say "list t k list the sub-paths of the path k in t", but it looks like it's just the immediate children. Returning a step would make that clear, if so. >> If I have a RW store, I can watch a key: >> >> val watch : t -> key -> value option Lwt_stream.t >> >> Presumably, I also need to take care to stop watching it when I'm >> done, otherwise the stream will grow without limit, right? I guess >> there should be an unwatch, or maybe this should be a React signal or >> something. > > Yes the watch API still needs some work. It's working-ish enough to demo > small examples (for instance you can run some of the examples and connect to > http://127.0.0.1:8080/graph to see a nice animated graph of the store), but > as you noticed there is no GC of ressources, maybe some leaks and the > behaviour under load is not satisfactory (see issue > https://github.com/mirage/irmin/issues/124). > >> I got a bit confused when I reached the BC page: >> >> https://mirage.github.io/irmin/Irmin.BC.html >> >> It uses 'tag' to mean a pointer to a commit that is updates on each >> operation (i.e. what Git would call a 'branch'). I realise that tags >> and branches are the same thing internally, but 'branch' seems to >> capture better what Irmin is using them for ("The tag value is updated >> every time the store is updated, so every handle connected or which >> will be connected to the same tag will see the changes."). [ BTW, >> what's a "handle"? ] > > The documentation is not totally clear here, you're right. You have two ways > to identify a branch: either by name or by hash. In Irmin terminology, a > branch name is a "tag". A commit hash is a "head". > >> val update_tag : t -> tag -> unit Lwt.t >> update_tag t tag updates t's current branch with the contents of the >> branch named tag. >> >> What does "update" mean here? Is this "git reset --hard tag"? A merge? >> A "--ff-only" merge? > > `update_tag` is similar to `git reset --hard <tag>`. merge_tag is similar to > `git merge <tag>`. I've tried to keep the update/merge duality in most of the > places (you can update/merge a head, a view, an other branch). Might be worth mentioning that this may cause data-loss then (I don't think that's clear from "update"). >> My mental model of Git is that the store is a DAG and I can append to >> any branch. e.g. we have: >> >> git commit-tree <tree> [(-p <parent>)...] < changelog >> >> If I'm understanding the Irmin API correctly, each "store" >> (repository? branch?) has a current "tag" (branch) and I need to set >> the tag I want to work on, e.g. >> >> val switch : Store.t -> tag -> unit Lwt.t > > The simplest way to initialise a branch using a tag is to use `Irmin.of_tag > ... <tag>`. If you want to create a branch in a "detached" mode, use > `Irmin.of_head ... <head>`. But yes, you can use switch to switch to another > named branch. > >> If I want to work on another branch without changing the current >> branch for other users, I should "clone" the store: >> >> val clone_force : ('a -> Irmin.task) -> t -> tag -> ('a -> t) Lwt.t >> >> But, this is not a "git clone", it's like "git branch tag" - a new >> branch I can work on without affecting the repository's default >> branch. It seems strange that Irmin has a mutable "current branch" at >> all - this seems like a UI concept that's only needed for command-line >> use (to save typing). > > Irmin has a concept of default branch (ie. "master") which is used when you > use "Irmin.create". I choose that because the simplest use-case is to use > Irmin as a normal k/v store, without having to worry about branches and such. OK, I think my confusion here is because (in my mind) there are two separate concepts here: a repository is a collection of branches and a branch head is a k/v store. But these are both combined into a single "store" type. >> A "head" is defined as "a given store revision" (i.e. what Git would >> call a commit). It wasn't clear to me at first whether a head was a >> commit or an anonymous branch. e.g. > > A head is a commit hash. You can use a head with Irmin.of_head to create an > anonymous branch. I agree that the documentation is not very clear on that. > >> val rename_tag : t -> tag -> [ `Duplicated_tag | `Ok ] Lwt.t >> Change the current tag name. Fail if a tag with the same name already >> exists. The head is unchanged. >> >> "The head is unchanged" suggests that heads might change in other >> cases. Looking at the code, I see a "type head = Commit.key" in one >> place, so I guess they're (usually?) commits. Does "head" here mean >> "the default branch"? > > I'll make another pass on that part of the documentation to try to make all > of these concepts clearer. I'll try to relate the API functions to Git > command-line arguments, although I'm not sure the Git command-line is a model > of clarity as well: `git reset --hard` is very different from `git reset > --soft` for instance, and there are no direct notion on index file in Irmin > (although the views can be seen as a kind of staging area). > >> Finally, how do I get history? e.g. if I want to show users the recent >> changes to a document. I see a "slice" type, but it's not clear what I >> can do with it. > > Anil asked me the question recently, and I promise him to add the missing > function in the "simple" API. For now on, the functions are well-hidden > inside the private API: The History[1] functor gives you a "closure" > function, which gives you a slice of the history graph. The functor needs a > contents store (if S is of type Irmin.S, then S,Private.Contents) and a node > store (S.Private.Node). But that's far too hard to use, I'll add an helper > function in the API to get you a OCamlgraph graph of commits (and optionally > tree and blobs) instead. > > Thanks for that very helpful report! I hope it makes things a little bit > clearer. Yes, much clearer, thanks! > Thomas > > [1] http://mirage.github.io/irmin/Irmin.Private.Commit.History.html > > >> >> >> Thanks! >> >> >> -- >> Dr Thomas Leonard http://0install.net/ >> GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 >> GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA >> >> _______________________________________________ >> MirageOS-devel mailing list >> MirageOS-devel@xxxxxxxxxxxxxxxxxxxx >> http://lists.xenproject.org/cgi-bin/mailman/listinfo/mirageos-devel > -- Dr Thomas Leonard http://0install.net/ GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA _______________________________________________ MirageOS-devel mailing list MirageOS-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/mirageos-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |