dokuwiki-plugin-gitbacked icon indicating copy to clipboard operation
dokuwiki-plugin-gitbacked copied to clipboard

Changes not appearing in DokuWiki's "revisions"/"recent changes"?

Open snan opened this issue 1 year ago • 7 comments

The new versions of pages that get pulled into the repo do show up on the web view of the wiki 👍🏻

But the fact that pages were edited doesn't show up on "recent changes" nor does the change show up on the page's "revisions.

I used to use dwpage.php to check out and commit one page at a time but gitbacked is way better since I can make more sweeping changes. I've also hacked in hooks so that it does check the lock dir properly. Fun fun fun. ♥︎ Now I wanna add in even more hooks so that page edits via git will "get recognized by DokuWiki" properly.

snan avatar Mar 05 '24 15:03 snan

Guess this is a fair request. If I get you right, you would like to get DW (DokuWiki) to follow and update DWs recent changes when pulling changes from the git repo?

mhoffrog avatar Mar 05 '24 16:03 mhoffrog

Right, recent changes and also page revisions. What happens currently is that the page text is just silently updated in place. I could get to hacking but I also wanted to double check whether this is an already solved issue and I'm just doing something unusual or wrong, or whether this is the typical behavior.

snan avatar Mar 05 '24 16:03 snan

@snan sounds useful :+1: would you be open to provide a pull request with the feature?

woolfg avatar Mar 06 '24 13:03 woolfg

... but I also wanted to double check whether this is an already solved issue and I'm just doing something unusual or wrong, or whether this is the typical behavior.

@snan You are doing all fine and this is not yet solved nor it was raised as a requirement yet as far as I know.

Just brainstorming on your requirement I'd like to share the following considerations:

  1. How to deal with the commit author - it must be mapped to the appropriate DW user

    • How to behave, if the commit author cannot be mapped to a DW user (e.g. since the eMail used by the git commit deviates from the eMail configured in DW)?
  2. Each commit can update multiple pages at a time - this means each particular page change has to be performed one by one.

    • What you could probably check is, if you can make use of the page edits as they are performed by DW unit tests. If you would use that way of doing it, then you would only have to bypass the gitbacked hook in this case to avoid another commit for that mimicked page edit (💡 We allow "empty" commits.).
  3. What if there are multiple commits within that pull for the same page - would you require DW to track the change of each particular commit? If yes, you cannot simply use the current work directory content to update the page(s) rather than taking the diffs from each particular commit and apply them to the page(s) one by one.

  4. It must be defined what to do with media changes

mhoffrog avatar Mar 09 '24 21:03 mhoffrog

If I manage to do it, part of the solution is gonna live in git hooks. Not sure that's something that the plugin can easily package and deploy?

  1. How to deal with the commit author - it must be mapped to the appropriate DW user

The dwpage.php solution doesn't do that, it instead thinks www-data made the commit. Whereas the gitbacked solution doesn't show any changes at all, instead it makes it look like the previous person who edited the page is responsible.

  1. Each commit can update multiple pages at a time

Yes, correct, that's the only reason why I switched to gitbacked instead of my previous solution (using dwpage.php).

  • this means each particular page change has to be performed one by one.

Yeah, that's like a smop. Dwpage.php in the bin directory is probably the code I need to study & grok.

  1. What if there are multiple commits within that pull for the same page - would you require DW to track the change of each particular commit? If yes, you cannot simply use the current work directory content to update the page(s) rather than taking the diffs from each particular commit and apply them to the page(s) one by one.
  2. It must be defined what to do with media changes

3&4… thanks for those. Something to ponder further 😰 But it's better to think of such snags sooner rather than later, so thank you 👍🏻

3, it's not necessary. Even just one DW revision would be an improvement on how it works now. But it might not be that impossible.

  1. I have no idea

I'm actually pushing to the gitbacked repo directly with git config receive.denyCurrentBranch updateInstead and a pre-recieve commit that checks to see if any page is being edited (by grepping the locks dir).

#!/bin/sh

find /path/to/dw/data/locks -type f -mmin -15 -exec cat {} \; |sort -u > /tmp/didi-locks

while read oldrev newrev refname; do
    git diff --name-only "$oldrev" "$newrev" > /tmp/didi-panix
    while read -r filo; do
	file="$(basename $(echo "$filo"|sed 's;/start.txt;;') ".txt")" # or whatever you've changed start to
	if grep -Fxq "$file" /tmp/didi-locks; then
	    echo "Someone is editing $file on the wiki right now."
	    exit 1
	fi
    done < /tmp/didi-panix
done

exit 0

No warrany on this jank which I only recently made and am still testing.

snan avatar Mar 09 '24 21:03 snan

Here is where I am right now:

I have a pre-receive hook that calls DokuWiki's own saveWikiText for each changed page but the problem is that that in turn triggers gitbacked which is not what we want since we are already receiving a git commit from a pushing remote.

I need to think a li'l more on how to get around that 😰

snan avatar Mar 15 '24 10:03 snan

This is how the script currently looks. I'm gonna have take a li'l break and then come at it later with another approach:

#!/bin/sh

## There is some stuff I just hardcoded for now:

### Replace this with the path to your own locks directory
find /var/dnd/data/locks -type f -mmin -15 -exec cat {} \; |sort -u > /tmp/didi-locks

### The word "start.txt" in the code below also should not be
### hardcoded since that can be changed by admins

### Finally, this include also should instead be some sorta relative path.

php_script=$(mktemp)
echo "<?php\ninclude '/var/dnd/inc/init.php';" > $php_script

while read oldrev newrev refname; do
    echo "$oldrev $newrev" >/tmp/pre-receive.log
    git diff --name-only "$oldrev" "$newrev" >>/tmp/pre-receive.log
    cat /tmp/didi-locks >> /tmp/pre-receive.log
    git diff --name-only "$oldrev" "$newrev"  > /tmp/didi-files-affected
    commit_message=$(git log --format=%B -n 1 $newrev | head -n 1|sed "s;';\\\\';g")
    while read -r filo; do
	file=$(echo $filo|sed -e 's;^pages/;;' -e 's;/start.txt$;;' -e 's;.txt$;;')
	echo $file >>  /tmp/pre-receive.log
	if grep -Fxq "$file" /tmp/didi-locks; then
	    echo "No, someone is editing $file on the wiki right now."
	    echo "that was locked" >>  /tmp/pre-receive.log
	    exit 1
	fi
	echo "saveWikiText(cleanID('$file'), '$(git show $newrev:$filo|sed "s;';\\\\';g")', '$commit_message', false);" >> $php_script
    done < /tmp/didi-files-affected
done

echo "running php with this file: $php_script" >>  /tmp/pre-receive.log
php "$php_script"
### TODO: remove that temp $php_script file here once I trust the code.

echo "exiting the hook safely" >>  /tmp/pre-receive.log
exit 0

# The remote isn't a bare repo. It's the repo that the wiki is working
# with directly thanks to docuwiki's gitbacked plugin. We're using:

# git config receive.denyCurrentBranch updateInstead

# in that repo. It checks if the working tree is clean, but what about
# unsaved changes when someone has just opened the editor?

# That's where this pre-receive script (rename "no-lock.sh" to
# "pre-receive" in the hooks dir) comes in handy. It rejects pushes if
# the push would clobber an opened page.

snan avatar Mar 15 '24 10:03 snan