pre-commit hook should change content

View: New views
14 Messages — Rating Filter:   Alert me  

pre-commit hook should change content

by DanielP001 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I am trying to write a pre-commit hook, which should change the content of (some) files. What I did so far is to get all files that are being committed.

    File path = new File(args[0]);
    File repoRootDir = FSFS.findRepositoryRoot(path);
    FSFS fsfs = new FSFS(repoRootDir);
    fsfs.open();

    FSTransactionInfo info = new FSTransactionInfo(0, args[1]);
    FSTransactionRoot txnRoot = fsfs.createTransactionRoot(info);

    Map changedFiles = txnRoot.detectChanged();

    for(Iterator keyIterator = changedFiles.keySet().iterator(); keyIterator.hasNext();) {
          String pathChange = keyIterator.next().toString();
          changeContent(txnRoot, (FSPathChange)changedFiles.get(pathChange), pathChange);
    }

    fsfs.close();


The method "changeContent" should change to content of the file (just add a line).
I tried this:

   InputStream is = txnRoot.getFileStreamForPath(new SVNDeltaCombiner(), filePath);
   int b = -1;

   OutputStream outputStream = new ByteArrayOutputStream();
   outputStream.write( new String("*** NEW ***").getBytes() );
   while((b = is.read()) != -1) {
       outputStream.write(b);
   }
   txnRoot.writeChangeEntry(outputStream, pathChange, true);
   pathChange.setTextModified(true);

But, unfortunately, this didn't change the content - it does nothing.
What did I forget or how can I change the content of the committed files?

Greetings,
Daniel

Re: pre-commit hook should change content

by Alexander Sinyushkin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello Daniel,

Changing transaction contents from a pre-commit hook is a bad
approach and is not encouraged by Subversion. Here's a warning taken
from a pre-commit hook template:

*** NOTE: THE HOOK PROGRAM MUST NOT MODIFY THE TXN, EXCEPT ***
*** FOR REVISION PROPERTIES (like svn:log or svn:author). ***

This is why we recommend using the read-only 'svnlook' utility.                                                                    
#   In the future, Subversion may enforce the rule that pre-commit                                                                    
#   hooks should not modify the versioned data in txns, or else come                                                                  
#   up with a mechanism to make it safe to do so (by informing the                                                                    
#   committing client of the changes).  However, right now neither                                                                    
#   mechanism is implemented, so hook writers just have to be careful.



But still it's possible what you've asked about. I've edited your hook
program so that it
changes contents of every file being committed to "*** NEW ***". Find
the source code file attached to
this letter.

----
Alexander Sinyushkin,
TMate Software,
http://svnkit.com/ - Java [Sub]Versioning Library!



DanielP001 wrote:

> Hello,
>
> I am trying to write a pre-commit hook, which should change the content of
> (some) files. What I did so far is to get all files that are being
> committed.
>
>     File path = new File(args[0]);
>     File repoRootDir = FSFS.findRepositoryRoot(path);
>     FSFS fsfs = new FSFS(repoRootDir);
>     fsfs.open();
>
>     FSTransactionInfo info = new FSTransactionInfo(0, args[1]);
>     FSTransactionRoot txnRoot = fsfs.createTransactionRoot(info);
>
>     Map changedFiles = txnRoot.detectChanged();
>
>     for(Iterator keyIterator = changedFiles.keySet().iterator();
> keyIterator.hasNext();) {
>           String pathChange = keyIterator.next().toString();
>           changeContent(txnRoot, (FSPathChange)changedFiles.get(pathChange),
> pathChange);
>     }
>
>     fsfs.close();
>
>
> The method "changeContent" should change to content of the file (just add a
> line).
> I tried this:
>
>    InputStream is = txnRoot.getFileStreamForPath(new SVNDeltaCombiner(),
> filePath);
>    int b = -1;
>
>    OutputStream outputStream = new ByteArrayOutputStream();
>    outputStream.write( new String("*** NEW ***").getBytes() );
>    while((b = is.read()) != -1) {
>        outputStream.write(b);
>    }
>    txnRoot.writeChangeEntry(outputStream, pathChange, true);
>    pathChange.setTextModified(true);
>
> But, unfortunately, this didn't change the content - it does nothing.
> What did I forget or how can I change the content of the committed files?
>
> Greetings,
> Daniel
>

package org.tmatesoft.svn.cli;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;

import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNRevisionProperty;
import org.tmatesoft.svn.core.internal.delta.SVNDeltaCombiner;
import org.tmatesoft.svn.core.internal.io.fs.FSCommitter;
import org.tmatesoft.svn.core.internal.io.fs.FSDeltaConsumer;
import org.tmatesoft.svn.core.internal.io.fs.FSFS;
import org.tmatesoft.svn.core.internal.io.fs.FSPathChange;
import org.tmatesoft.svn.core.internal.io.fs.FSPathChangeKind;
import org.tmatesoft.svn.core.internal.io.fs.FSRevisionNode;
import org.tmatesoft.svn.core.internal.io.fs.FSTransactionInfo;
import org.tmatesoft.svn.core.internal.io.fs.FSTransactionRoot;
import org.tmatesoft.svn.core.io.diff.SVNDeltaGenerator;


/*
 * ====================================================================
 * Copyright (c) 2004-2009 TMate Software Ltd.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://svnkit.com/license.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 * ====================================================================
 */

/**
 * @version 1.3
 * @author  TMate Software Ltd.
 */
public class PreCommitTest {

    public static void main(String[] args) {
        File path = new File(args[0]);
        File repoRootDir = FSFS.findRepositoryRoot(path);
        FSFS fsfs = new FSFS(repoRootDir);
        try {
            fsfs.open();
   
            FSTransactionInfo info = new FSTransactionInfo(0, args[1]);
            FSTransactionRoot txnRoot = fsfs.createTransactionRoot(info);

            SVNProperties txnProps = fsfs.getTransactionProperties(info.getTxnId());
            String author = txnProps.getStringValue(SVNRevisionProperty.AUTHOR);
   
            Map changedFiles = txnRoot.detectChanged();
   
            for(Iterator keyIterator = changedFiles.keySet().iterator(); keyIterator.hasNext();) {
                String pathChange = keyIterator.next().toString();
                changeContent(txnRoot, (FSPathChange) changedFiles.get(pathChange), pathChange, author);
            }
        } catch (Throwable th) {
            th.printStackTrace();
        } finally {
            try {
                fsfs.close();
            } catch (SVNException svne) {
                //
            }
        }
    }
   
    private static void changeContent(FSTransactionRoot txnRoot, FSPathChange pathChange, String filePath, String author) throws SVNException {
        SVNDeltaGenerator generator = new SVNDeltaGenerator();
        InputStream is = txnRoot.getFileStreamForPath(new SVNDeltaCombiner(), filePath);

        FSCommitter committer = new FSCommitter(txnRoot.getOwner(), txnRoot, txnRoot.getTxn(), null, author);
        FSDeltaConsumer deltaConsumer = new FSDeltaConsumer("", txnRoot, txnRoot.getOwner(), committer, author, null);
        FSRevisionNode node = txnRoot.getRevisionNode(filePath);
        deltaConsumer.applyTextDelta(filePath, null);
        generator.sendDelta(filePath, is, 0, new ByteArrayInputStream("*** NEW ***".getBytes()), deltaConsumer, false);
        if (!pathChange.isTextModified()) {
            committer.addChange(filePath, node.getId(), FSPathChangeKind.FS_PATH_CHANGE_MODIFY, true, false,
                    -1, null, SVNNodeKind.FILE);
            pathChange.setTextModified(true);
        }
    }
}



---------------------------------------------------------------------
To unsubscribe, e-mail: svnkit-users-unsubscribe@...
For additional commands, e-mail: svnkit-users-help@...

Re: pre-commit hook should change content

by Ronald Brill :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi SVNKit developers,

i'm using SmartSVN for a long time on OS/2. It woks fine so far but there is one issue (that is related to the underlying SVNKit).
Is far as i can see, there are some calls related to file attributes that are not (yet) supported by the jdk. On windows and unix SVNKit uses JNA to do some wrapped calls to the os.

For OS/2 i allready build a jni lib that offers implementations of the needed mehtods.
So far i have implemented methods to request and to change the file attributes available on OS/2 (hidden, system, archived and readonly).
I have an implementation of the moveFile() method also. I made this method as compatible with the windows version as possible (copy to different drives via copy/delete and
replace existing stuff).

The source is availabe on http://svn.netlabs.org/os2io4j.

So far i have one singele class that offers some static methods. Is there any way to integrate this into SVNKit?

My idea is to implement some kind of adapter for SVNKit that implements some interface offerd by SVNKit. Then i have to set a environment variable to tell SVNKit to
try to load this adapter class. Maybe this variable points per default to your JNA stuff.
What do you think. Any better idea.

Looking forward to your suggestions

Thanks for your support (and the nice SVNKit)

        ronald


---------------------------------------------------------------------
To unsubscribe, e-mail: svnkit-users-unsubscribe@...
For additional commands, e-mail: svnkit-users-help@...


SVNKit on OS/2

by Ronald Brill :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi SVNKit developers,

i'm using SmartSVN for a long time on OS/2. It woks fine so far but there is one issue (that is related to the underlying SVNKit).
Is far as i can see, there are some calls related to file attributes that are not (yet) supported by the jdk. On windows and unix SVNKit uses JNA to do some wrapped calls to the os.

For OS/2 i allready build a jni lib that offers implementations of the needed mehtods.
So far i have implemented methods to request and to change the file attributes available on OS/2 (hidden, system, archived and readonly).
I have an implementation of the moveFile() method also. I made this method as compatible with the windows version as possible (copy to different drives via copy/delete and
replace existing stuff).

The source is availabe on http://svn.netlabs.org/os2io4j.

So far i have one singele class that offers some static methods. Is there any way to integrate this into SVNKit?

My idea is to implement some kind of adapter for SVNKit that implements some interface offerd by SVNKit. Then i have to set a environment variable to tell SVNKit to
try to load this adapter class. Maybe this variable points per default to your JNA stuff.
What do you think. Any better idea.

Looking forward to your suggestions

Thanks for your support (and the nice SVNKit)

        ronald



---------------------------------------------------------------------
To unsubscribe, e-mail: svnkit-users-unsubscribe@...
For additional commands, e-mail: svnkit-users-help@...


Re: pre-commit hook should change content

by Ronald Brill :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sorry wrong subject....

        ronald

On Mon, 21 Sep 2009 19:48:29 +0200 (CES) Ronald Brill wrote:
>
>Hi SVNKit developers,
>
>i'm using SmartSVN for a long time on OS/2. It woks fine so far but there is one issue
(that is related to the underlying SVNKit).
>Is far as i can see, there are some calls related to file attributes that are not (yet)
supported by the jdk. On windows and unix SVNKit uses JNA to do some wrapped calls to
the os.
>
>For OS/2 i allready build a jni lib that offers implementations of the needed mehtods.
>So far i have implemented methods to request and to change the file attributes available
on OS/2 (hidden, system, archived and readonly).
>I have an implementation of the moveFile() method also. I made this method as
compatible with the windows version as possible (copy to different drives via copy/delete
and
>replace existing stuff).
>
>The source is availabe on http://svn.netlabs.org/os2io4j.
>
>So far i have one singele class that offers some static methods. Is there any way to
integrate this into SVNKit?
>
>My idea is to implement some kind of adapter for SVNKit that implements some interface
offerd by SVNKit. Then i have to set a environment variable to tell SVNKit to

>try to load this adapter class. Maybe this variable points per default to your JNA stuff.
>What do you think. Any better idea.
>
>Looking forward to your suggestions
>
>Thanks for your support (and the nice SVNKit)
>
> ronald
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: svnkit-users-unsubscribe@...
>For additional commands, e-mail: svnkit-users-help@...
>
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: svnkit-users-unsubscribe@...
For additional commands, e-mail: svnkit-users-help@...


Re: SVNKit on OS/2

by Alexander Kitaev-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello Ronald,

> My idea is to implement some kind of adapter for SVNKit that
implements some interface offerd by SVNKit. Then i have to set a
environment variable to tell SVNKit to
> try to load this adapter class. Maybe this variable points per default
to your JNA stuff.
> What do you think. Any better idea.
The ideal way, I think, would be to integrate OS/2 support into JNA
library and then call native OS/2 API through JNA - thus making OS/2
support consistent with support for other OSes.

On the other side, I do not know how complex it will be to add OS/2
support into JNA library, so I think we could include your current
version into SVNKit for now.

I think for OS/2 we could do the following changes:

1. add class (SVNOS2Util) that will implement the following static methods:

boolean isEnabled() - returns true if corresponding native library is
available

boolean setWritable(File file) - makes file writable and returns true in
case operations succeeded, false in case of any error

boolean setHidden(File file) - same as above, but makes file 'hidden'

boolean moveFile(File src, File dst) - atomically renames src to dst,
and returns 'false' if there is any error on rename.

2. then modify SVNJNAUtil so, that when host is OS/2 it calls SVNOS2Util
class, not SVNWin32Util or SVNLinuxUtil ones.

3. For now, if understand correctly, SVNOS2Util will call separate
native library that we'll have to distribute along with SVNKit. Later,
SVNOS2Util could be changed to work through the JNA library (as soon as
JNA will get OS/2 support).

Please, send a patch in unified diff format (svn diff output) against
SVNKit trunk - I will review and include it into the current trunk
version and then will merge into 1.3.x branch.


Alexander Kitaev,
TMate Software,
http://svnkit.com/ - Java [Sub]Versioning Library!
http://sqljet.com/ - Java SQLite Library!

Ronald Brill wrote:

> Hi SVNKit developers,
>
> i'm using SmartSVN for a long time on OS/2. It woks fine so far but there is one issue (that is related to the underlying SVNKit).
> Is far as i can see, there are some calls related to file attributes that are not (yet) supported by the jdk. On windows and unix SVNKit uses JNA to do some wrapped calls to the os.
>
> For OS/2 i allready build a jni lib that offers implementations of the needed mehtods.
> So far i have implemented methods to request and to change the file attributes available on OS/2 (hidden, system, archived and readonly).
> I have an implementation of the moveFile() method also. I made this method as compatible with the windows version as possible (copy to different drives via copy/delete and
> replace existing stuff).
>
> The source is availabe on http://svn.netlabs.org/os2io4j.
>
> So far i have one singele class that offers some static methods. Is there any way to integrate this into SVNKit?
>
> My idea is to implement some kind of adapter for SVNKit that implements some interface offerd by SVNKit. Then i have to set a environment variable to tell SVNKit to
> try to load this adapter class. Maybe this variable points per default to your JNA stuff.
> What do you think. Any better idea.
>
> Looking forward to your suggestions
>
> Thanks for your support (and the nice SVNKit)
>
> ronald
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: svnkit-users-unsubscribe@...
> For additional commands, e-mail: svnkit-users-help@...
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: svnkit-users-unsubscribe@...
For additional commands, e-mail: svnkit-users-help@...


Re: SVNKit on OS/2

by Ronald Brill :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Alexander Kitaev wrote:

cool will try to do that in the next days.....

        ronald

>I think for OS/2 we could do the following changes:
>
>1. add class (SVNOS2Util) that will implement the following static methods:
>
>boolean isEnabled() - returns true if corresponding native library is
>available
>
>boolean setWritable(File file) - makes file writable and returns true in
>case operations succeeded, false in case of any error
>
>boolean setHidden(File file) - same as above, but makes file 'hidden'
>
>boolean moveFile(File src, File dst) - atomically renames src to dst,
>and returns 'false' if there is any error on rename.
>
>2. then modify SVNJNAUtil so, that when host is OS/2 it calls SVNOS2Util
>class, not SVNWin32Util or SVNLinuxUtil ones.
>
>3. For now, if understand correctly, SVNOS2Util will call separate
>native library that we'll have to distribute along with SVNKit. Later,
>SVNOS2Util could be changed to work through the JNA library (as soon as
>JNA will get OS/2 support).
>
>Please, send a patch in unified diff format (svn diff output) against
>SVNKit trunk - I will review and include it into the current trunk
>version and then will merge into 1.3.x branch.
>
>
>Alexander Kitaev,
>TMate Software,
>http://svnkit.com/ - Java [Sub]Versioning Library!
>http://sqljet.com/ - Java SQLite Library!
>
>Ronald Brill wrote:
>> Hi SVNKit developers,
>>
>> i'm using SmartSVN for a long time on OS/2. It woks fine so far but there is one issue
(that is related to the underlying SVNKit).
>> Is far as i can see, there are some calls related to file attributes that are not (yet)
supported by the jdk. On windows and unix SVNKit uses JNA to do some wrapped calls to
the os.
>>
>> For OS/2 i allready build a jni lib that offers implementations of the needed mehtods.
>> So far i have implemented methods to request and to change the file attributes available
on OS/2 (hidden, system, archived and readonly).
>> I have an implementation of the moveFile() method also. I made this method as
compatible with the windows version as possible (copy to different drives via copy/delete
and
>> replace existing stuff).
>>
>> The source is availabe on http://svn.netlabs.org/os2io4j.
>>
>> So far i have one singele class that offers some static methods. Is there any way to
integrate this into SVNKit?
>>
>> My idea is to implement some kind of adapter for SVNKit that implements some
interface offerd by SVNKit. Then i have to set a environment variable to tell SVNKit to

>> try to load this adapter class. Maybe this variable points per default to your JNA stuff.
>> What do you think. Any better idea.
>>
>> Looking forward to your suggestions
>>
>> Thanks for your support (and the nice SVNKit)
>>
>> ronald
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: svnkit-users-unsubscribe@...
>> For additional commands, e-mail: svnkit-users-help@...
>>
>>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: svnkit-users-unsubscribe@...
>For additional commands, e-mail: svnkit-users-help@...
>
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: svnkit-users-unsubscribe@...
For additional commands, e-mail: svnkit-users-help@...


Re: pre-commit hook should change content

by DanielP001 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Alexander,

thank you very much for your answer.
Indeed it's a bad idea to change the content by hooks. It would be better to reject it. But in this case, it isn't possible to reject the committed content (it is a little bit complicated to explain the facts).

Again, thank you very much for your answer.

Regards,
Daniel

Re: pre-commit hook should change content

by DanielP001 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Alexander,

it tried your attached program, but I got the following error:
svn: Invalid change kind in rev file

What does it mean? I am using version 1.6.5 (I just updated from 1.5.4).

Regards,
Daniel

Re: pre-commit hook should change content

by Alexander Sinyushkin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Daniel,

Actually I've missed some important checks in the hook program
which should be performed before trying to write anything to transaction
files.

You should be sure that you're going to modify file entries and that a
file entry is not deleted:

            for(Iterator keyIterator = changedFiles.keySet().iterator();
keyIterator.hasNext();) {
                String pathChangePath = keyIterator.next().toString();
                FSPathChange pathChange = (FSPathChange)
changedFiles.get(pathChangePath);
                if (pathChange.getKind() == SVNNodeKind.FILE &&
pathChange.getChangeKind() != FSPathChangeKind.FS_PATH_CHANGE_DELETE) {
                    changeContent(txnRoot, pathChange, pathChangePath,
author);
                }
            }

It looks like an incorrect rev change line was written into a rev or
transaction file.
I hope you didn't launch the hook on a production repository before
testing it properly :)

Do you have a stack trace?

----
Alexander Sinyushkin,
TMate Software,
http://svnkit.com/ - Java [Sub]Versioning Library!



DanielP001 wrote:

> Hi Alexander,
>
> it tried your attached program, but I got the following error:
> svn: Invalid change kind in rev file
>
> What does it mean? I am using version 1.6.5 (I just updated from 1.5.4).
>
> Regards,
> Daniel
>
>  

---------------------------------------------------------------------
To unsubscribe, e-mail: svnkit-users-unsubscribe@...
For additional commands, e-mail: svnkit-users-help@...


Re: pre-commit hook should change content

by DanielP001 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Alexander,

I found the problem. I forgot to restart the apache. After that, I was able to commit the file.
But the problem now is, that the committed file contains only the string *** NEW ***. The original content of the file is gone.

Regards,
Daniel


Re: pre-commit hook should change content

by Alexander Sinyushkin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello Daniel,

Yes, it was only an example of  how you can change a file rewriting its
contents. I have edited the
program to make it append a new line to every file being committed. The
source file is attached to
the letter. The idea is that you have to provide to SVNDeltaGenerator
input contents before your
modifications (as a source stream) and contents after you modifications
(as a target stream). So, I just get
the source contents, read it to a buffer and append new line bytes to
that buffer. After that I use the buffer
as the target contents stream.

----
Alexander Sinyushkin,
TMate Software,
http://svnkit.com/ - Java [Sub]Versioning Library!



DanielP001 wrote:

> Hi Alexander,
>
> I found the problem. I forgot to restart the apache. After that, I was able
> to commit the file.
> But the problem now is, that the committed file contains only the string ***
> NEW ***. The original content of the file is gone.
>
> Regards,
> Daniel
>
>


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;

import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNRevisionProperty;
import org.tmatesoft.svn.core.internal.delta.SVNDeltaCombiner;
import org.tmatesoft.svn.core.internal.io.fs.FSCommitter;
import org.tmatesoft.svn.core.internal.io.fs.FSDeltaConsumer;
import org.tmatesoft.svn.core.internal.io.fs.FSFS;
import org.tmatesoft.svn.core.internal.io.fs.FSPathChange;
import org.tmatesoft.svn.core.internal.io.fs.FSPathChangeKind;
import org.tmatesoft.svn.core.internal.io.fs.FSRevisionNode;
import org.tmatesoft.svn.core.internal.io.fs.FSTransactionInfo;
import org.tmatesoft.svn.core.internal.io.fs.FSTransactionRoot;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import org.tmatesoft.svn.core.io.diff.SVNDeltaGenerator;


/*
 * ====================================================================
 * Copyright (c) 2004-2009 TMate Software Ltd.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://svnkit.com/license.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 * ====================================================================
 */

/**
 * @version 1.3
 * @author  TMate Software Ltd.
 */
public class PreCommitTest {

    public static void main(String[] args) {
        File path = new File(args[0]);
        File repoRootDir = FSFS.findRepositoryRoot(path);
        FSFS fsfs = new FSFS(repoRootDir);
        try {
            fsfs.open();
   
            FSTransactionInfo info = new FSTransactionInfo(0, args[1]);
            FSTransactionRoot txnRoot = fsfs.createTransactionRoot(info);

            SVNProperties txnProps = fsfs.getTransactionProperties(info.getTxnId());
            String author = txnProps.getStringValue(SVNRevisionProperty.AUTHOR);
   
            Map changedFiles = txnRoot.detectChanged();
   
            for(Iterator keyIterator = changedFiles.keySet().iterator(); keyIterator.hasNext();) {
                String pathChangePath = keyIterator.next().toString();
                FSPathChange pathChange = (FSPathChange) changedFiles.get(pathChangePath);
                if (pathChange.getKind() == SVNNodeKind.FILE && pathChange.getChangeKind() != FSPathChangeKind.FS_PATH_CHANGE_DELETE) {
                    changeContent(txnRoot, pathChange, pathChangePath, author);
                }
            }
        } catch (Throwable th) {
            th.printStackTrace();
        } finally {
            try {
                fsfs.close();
            } catch (SVNException svne) {
                //
            }
        }
    }
   
    private static void changeContent(FSTransactionRoot txnRoot, FSPathChange pathChange, String filePath, String author) throws SVNException, IOException {
        SVNDeltaGenerator generator = new SVNDeltaGenerator();
        InputStream is = txnRoot.getFileStreamForPath(new SVNDeltaCombiner(), filePath);
        ByteArrayInputStream rightHandContents = addLineToStream(is, "*** NEW ***");
        is = txnRoot.getFileStreamForPath(new SVNDeltaCombiner(), filePath);
       
        FSCommitter committer = new FSCommitter(txnRoot.getOwner(), txnRoot, txnRoot.getTxn(), null, author);
        FSDeltaConsumer deltaConsumer = new FSDeltaConsumer("", txnRoot, txnRoot.getOwner(), committer, author, null);
        FSRevisionNode node = txnRoot.getRevisionNode(filePath);
        deltaConsumer.applyTextDelta(filePath, null);
        generator.sendDelta(filePath, is, 0, rightHandContents, deltaConsumer, false);
        if (!pathChange.isTextModified()) {
            committer.addChange(filePath, node.getId(), FSPathChangeKind.FS_PATH_CHANGE_MODIFY, true, false,
                    -1, null, SVNNodeKind.FILE);
            pathChange.setTextModified(true);
        }
    }
   
    private static ByteArrayInputStream addLineToStream(InputStream source, String line) throws IOException {
        byte[] buffer = new byte[1024];
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int r = -1;
        try {
            while ((r = source.read(buffer, 0, buffer.length)) != -1) {
                out.write(buffer, 0, r);
            }
        } finally {
            SVNFileUtil.closeFile(source);
        }
        out.write(line.getBytes());
        return new ByteArrayInputStream(out.toByteArray());
    }
}



---------------------------------------------------------------------
To unsubscribe, e-mail: svnkit-users-unsubscribe@...
For additional commands, e-mail: svnkit-users-help@...

Re: pre-commit hook should change content

by DanielP001 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Alexander,

thank you very much for your quick answer. It works (nearly) perfectly.
I know, that you told me, that's not a good idea to change the content. And, if there were another solution, I would prefer it. But unfortunately, there isn't - so we have to change the content. And now, after I committed my changes, I can't see the changes made by the hook in my local file (only in the repository). I also can't update my files, because the revision number is the same (as it should be). But the file in the repository now contains the string *** NEW ***, my local file doesn't. And, if I change the local file again, it is impossible to commit the file, because of a checksum error:

svn: Base checksum mismatch on '/test.sql':
   expected:  114f2bdce16dd27e66e425b4a6724539
     actual:  ab3cc38ae395475a0c87218595db65ad

Is there is possibility to update the local file with the changes made by the hook (like it is possible with svn:keywords)?

Regards,
Daniel

Re: pre-commit hook should change content

by Alexander Sinyushkin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

That's why I warned you that it's not a good idea. The working copy
becomes invalid, because there's no opportunity to update it in a
"normal way" after your hook has changed file contents in the repository.
I'm afraid it's not possible what you are asking about.

----
Alexander Sinyushkin,
TMate Software,
http://svnkit.com/ - Java [Sub]Versioning Library!



DanielP001 wrote:

> Hi Alexander,
>
> thank you very much for your quick answer. It works (nearly) perfectly.
> I know, that you told me, that's not a good idea to change the content. And,
> if there were another solution, I would prefer it. But unfortunately, there
> isn't - so we have to change the content. And now, after I committed my
> changes, I can't see the changes made by the hook in my local file (only in
> the repository). I also can't update my files, because the revision number
> is the same (as it should be). But the file in the repository now contains
> the string *** NEW ***, my local file doesn't. And, if I change the local
> file again, it is impossible to commit the file, because of a checksum
> error:
>
> svn: Base checksum mismatch on '/test.sql':
>    expected:  114f2bdce16dd27e66e425b4a6724539
>      actual:  ab3cc38ae395475a0c87218595db65ad
>
> Is there is possibility to update the local file with the changes made by
> the hook (like it is possible with svn:keywords)?
>
> Regards,
> Daniel
>

---------------------------------------------------------------------
To unsubscribe, e-mail: svnkit-users-unsubscribe@...
For additional commands, e-mail: svnkit-users-help@...