]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blobdiff - doc/rcs/details.mdwn
Merge branch 'master' into debian-jessie-backports
[git.ikiwiki.info.git] / doc / rcs / details.mdwn
index b9b3c7eadd17133dc08215dff18dbf7d30d28e4f..013ddb7451877d7e2de047e8e9b9c92d30098ce8 100644 (file)
@@ -1,6 +1,6 @@
 A few bits about the RCS backends
 
-[[toc ]]
+[[!toc ]]
 
 ## Terminology
 
@@ -32,90 +32,20 @@ You browse and web-edit the wiki on W.
 W "belongs" to ikiwiki and should not be edited directly.
 
 
-## [darcs](http://darcs.net/) (not yet included)
+## [[darcs]]
 
-Support for using darcs as a backend is being worked on by [Thomas
-Schwinge](mailto:tschwinge@gnu.org), although development is on hold curretly.
-There is a patch in [[todo/darcs]].
+Regarding the repository layout: There are two darcs repositories. One is the `srcdir`, the other we'll call `master`.
 
-### How will it work internally?
+*  HTML is generated from `srcdir`.
+*  CGI edits happen in `srcdir`.
+*  The backend pulls updates from `master` into `srcdir`, i.e. darcs commits should happen to `master`.
+*  `master` calls ikiwiki (through a wrapper) in its apply posthook, i.e. `master/_darcs/prefs/defaults` should look like this:
 
-``Master'' repository R1.
+       apply posthook ikiwrap
+       apply run-posthook
 
-RCS commits from the outside are installed into R1.
-
-HTML is generated from R1.  HTML is automatically generated (by using a
-``post-hook'') each time a new change is installed into R1.  It follows
-that rcs_update() is not needed.
-
-There is a working copy of R1: R2.
-
-CGI operates on R2.  rcs_commit() will push from R2 to R1.
-
-You browse the wiki on R1 and web-edit it on R2.  This means for example
-that R2 needs to be updated from R1 if you are going to web-edit a page,
-as the user otherwise might be irritated otherwise...
-
-How do changes get from R1 to R2?  Currently only internally in
-rcs\_commit().  Is rcs\_prepedit() suitable?
-
-It follows that the HTML rendering and the CGI handling can be completely
-separated parts in ikiwiki.
-
-What repository should [[RecentChanges]] and [[History]] work on?  R1?
-
-#### Rationale for doing it differently than in the Subversion case
-
-darcs is a distributed RCS, which means that every checkout of a
-repository is equal to the repository it was checked-out from.  There is
-no forced hierarchy.
-
-R1 is nevertheless called the master repository.  It's used for
-collecting all the changes and publishing them: on the one hand via the
-rendered HTML and on the other via the standard darcs RCS interface.
-
-R2, the repository the CGI operates on, is just a checkout of R1 and
-doesn't really differ from the other checkouts that people will branch
-off from R1.
-
-(To be continued.)
-
-#### Another possible approach
-
-Here's what I (tuomov) think, would be a “cleaner” approach:
-
- 1. Upon starting to edit, Ikiwiki gets a copy of the page, and `darcs changes --context`.
-     This context _and_ the present version of the page are stored in as the “version” of the
-     page in a hidden control of the HTML.
-     Thus the HTML includes all that is needed to generate a patch wrt. to the state of the
-     repository at the time the edit was started. This is of course all that darcs needs.
- 2. Once the user is done with editing, _Ikiwiki generates a patch bundle_ for darcs.
-     This should be easy with existing `Text::Diff` or somesuch modules, as the Web edits
-     only concern single files. The reason why the old version of the page is stored in
-     the HTML (possibly compressed) is that the diff can be generated.
- 3. Now this patch bundle is applied with `darcs apply`, or sent by email for moderation…
-     there are many possibilities.
-
-This approach avoids some of the problems of concurrent edits that the previous one may have,
-although there may be conflicts, which may or may not propagate to the displayed web page.
-(Unfortunately there is not an option to `darcs apply` to generate some sort of ‘confliction resolution
-bundle’.) Also, only one repository is needed, as it is never directly modified
-by Ikiwiki. 
-
-This approach might be applicable to other distributed VCSs as well, although they're not as oriented
-towards transmitting changes with standalone patch bundles (often by email) as darcs is.
-
-> The mercurial plugin seems to just use one repo and edit it directly - is
-> there some reason that's okay there but not for darcs? I agree with tuomov
-> that having just the one repo would be preferable; the point of a dvcs is
-> that there's no difference between one repo and another. I've got a
-> darcs.pm based on mercurial.pm, that's almost usable... --bma
-
->> IMHO it comes down to whatever works well for a given RCS. Seems like
->> the darcs approach _could_ be done with most any distributed system, but
->> it might be overkill for some (or all?) While there is the incomplete darcs
->> plugin in [[todo/darcs]], if you submit one that's complete, I will
->> probably accept it into ikiwiki.. --[[Joey]]
+*  The backend pushes CGI edits from `srcdir` back into `master` (triggering the apply hook).
+*  The working copies in `srcdir` and `master` should *not* be touched by the user, only by the CGI or darcs, respectively.
 
 ## [[Git]]
 
@@ -125,12 +55,128 @@ I have been testing it for the past few days and it seems satisfactory.  I
 haven't observed any race condition regarding the concurrent blog commits
 and it handles merge conflicts gracefully as far as I can see.
 
+(After about a year, git support is nearly as solid as subversion support --[[Joey]])
+
 As you may notice from the patch size, GIT support is not so trivial to
-implement (for me, at least).  Being a fairly fresh code base it has some
-bugs.  It also has some drawbacks (especially wrt merge which was the hard
-part).  GIT doesn't have a similar functionality like 'svn merge -rOLD:NEW
-FILE' (please see the relevant comment in mergepast for more details), so I
-had to invent an ugly hack just for the purpose.
+implement (for me, at least). It has some drawbacks (especially wrt merge
+which was the hard part).  GIT doesn't have a similar functionality like
+'svn merge -rOLD:NEW FILE' (please see the relevant comment in `_merge_past`
+for more details), so I had to invent an ugly hack just for the purpose.
+
+> I was looking at this, and WRT the problem of uncommitted local changes,
+> it seems to me you could just git-stash them now that git-stash exists.
+> I think it didn't when you first added the git support.. --[[Joey]]
+
+
+>> Yes,  git-stash had not existed before.  What about sth like below?  It
+>> seems to work (I haven't given much thought on the specific implementation
+details).  --[[roktas]]
+
+>>         # create test files
+>>         cd /tmp
+>>         seq 6 >page
+>>         cat page
+>>         1
+>>         2
+>>         3
+>>         4
+>>         5
+>>         6
+>>         sed -e 's/2/2ME/' page >page.me # my changes
+>>         cat page
+>>         1
+>>         2ME
+>>         3
+>>         4
+>>         5
+>>         6
+>>         sed -e 's/5/5SOMEONE/' page >page.someone # someone's changes
+>>         cat page
+>>         1
+>>         2
+>>         3
+>>         4
+>>         5SOMEONE
+>>         6
+>>
+>>         # create a test repository
+>>         mkdir t
+>>         cd t
+>>         cp ../page .
+>>         git init
+>>         git add .
+>>         git commit -m init
+>>
+>>         # save the current HEAD
+>>         ME=$(git rev-list HEAD -- page)
+>>         $EDITOR page # assume that I'm starting to edit page via web
+>>
+>>         # simulates someone's concurrent commit
+>>         cp ../page.someone page
+>>         git commit -m someone -- page
+>>
+>>         # My editing session ended, the resulting content is in page.me
+>>         cp ../page.me page
+>>         cat page
+>>         1
+>>         2ME
+>>         3
+>>         4
+>>         5
+>>         6
+>>
+>>         # let's start to save my uncommitted changes
+>>         git stash clear
+>>         git stash save "changes by me"
+>>         # we've reached a clean state
+>>         cat page
+>>         1
+>>         2
+>>         3
+>>         4
+>>         5SOMEONE
+>>         6
+>>
+>>         # roll-back to the $ME state
+>>         git reset --soft $ME
+>>         # now, the file is marked as modified
+>>         git stash save "changes by someone"
+>>
+>>         # now, we're at the $ME state
+>>         cat page
+>>         1
+>>         2
+>>         3
+>>         4
+>>         5
+>>         6
+>>         git stash list
+>>         stash@{0}: On master: changes by someone
+>>         stash@{1}: On master: changes by me
+>>
+>>         # first apply my changes
+>>         git stash apply stash@{1}
+>>         cat page
+>>         1
+>>         2ME
+>>         3
+>>         4
+>>         5
+>>         6
+>>         # ... and commit
+>>         git commit -m me -- page
+>>
+>>         # apply someone's changes
+>>         git stash apply stash@{0}
+>>         cat page
+>>         1
+>>         2ME
+>>         3
+>>         4
+>>         5SOMEONE
+>>         6
+>>         # ... and commit
+>>         git commit -m me+someone -- page
 
 By design, Git backend uses a "master-clone" repository pair approach in contrast
 to the single repository approach (here, _clone_ may be considered as the working
@@ -142,8 +188,25 @@ on the same local machine, I suggest to create the latter with the "`git clone -
 command to save disk space.
 
 Note that, as a rule of thumb, you should always put the rcs wrapper (`post-update`)
-into the master repository (`.git/hooks/`) as can be noticed in the Git wrappers of
-the sample [[ikiwiki.setup]].
+into the master repository (`.git/hooks/`).
+
+Here is how a web edit works with ikiwiki and git:
+
+* ikiwiki cgi modifies the page source in the clone
+* git-commit in the clone
+* git push origin master, pushes the commit from the clone to the master repo
+* the master repo's post-update hook notices this update, and runs ikiwiki
+* ikiwiki notices the modifies page source, and compiles it
+
+Here is a how a commit from a remote repository works:
+
+* git-commit in the remote repository
+* git-push, pushes the commit to the master repo on the server
+* (Optionally, the master repo's pre-receive hook runs, and checks that the
+  update only modifies files that the pushing user is allowed to update. 
+  If not, it aborts the receive.)
+* the master repo's post-update hook notices this update, and runs ikiwiki
+* ikiwiki notices the modifies page source, and compiles it
 
 ## [[Mercurial]]
 
@@ -178,6 +241,8 @@ please refer to [Emanuele](http://nerd.ocracy.org/em/)
 
 ## [[tla]]
 
+Nobody really understands how tla works. ;-)
+
 ## rcs
 
 There is a patch that needs a bit of work linked to from [[todo/rcs]].
@@ -221,3 +286,7 @@ merge again with a merger that inserts conflict markers.  It commits this new
 revision with conflict markers to the repository.  It then returns the text to the
 user for cleanup.  This is less neat than it could be, in that a conflict marked
 revision gets committed to the repository.
+
+## [[bzr]]
+
+## [[cvs]]