6

'svn log' shows the log of: 1) files whose content has changed AND/OR 2) files whose properties have changed.

Is there a way to show only files for which case 1 applies?

zr.
  • 7,528
  • 11
  • 50
  • 84
  • possible duplicate of [Is there a metadata exclusion filter for the SVN DIFF command?](http://stackoverflow.com/questions/402522/is-there-a-metadata-exclusion-filter-for-the-svn-diff-command) – Pekka Aug 09 '10 at 08:45
  • @Pekka I Did not find there any solution which is applicable here. The issues may resemble, but are not duplicates. – zr. Aug 09 '10 at 18:19
  • @zr I'm sorry. I overlooked the diff aspect of the other question. However, doesn't the simple grep construct introduced there go into the right direction? – Pekka Aug 09 '10 at 18:22
  • @zr Does my answer below meet the need? – LarsH Aug 18 '10 at 14:29
  • 1
    @zr: you missed giving away your bounty to a proper answer here... ouch – Abel Aug 19 '10 at 18:21

5 Answers5

4

'svn log' shows the log of: 1) files whose content has changed AND/OR 2) files whose properties have changed.

As you know, svn log's output is organized by commit log messages rather than by files. If you use verbose mode (-v), it will show the files ("paths") associated with each log entry. However some of those paths can be outside of the requested target (default: your current directory). Do you want the results to include those external paths as well? I guess taking your question at face value, you're just asking for filtering, so yes you would want those external paths if they represent a content change to files.

Here is a solution. It may be slow, but I tested it and it works in cygwin on Windows 7. (Don't forget, make sure your scripts have unixy line endings! with dos2unix if necessary)

It's really only one long line, except for an external sed script (which a real hacker could put on the command line but life is short to be messing with command-line escaping):

#!/bin/sh

# These paths are set up for cygwin
SED=/bin/sed
SORT=/bin/sort
UNIQ=/bin/uniq
XARGS=/bin/xargs
GREP=/bin/grep
SVN=svn

# Add desired log options here
LOG_OPTIONS=-v
SINCE_REV=10800
SED_SCRIPT=/cygdrive/c/temp/get-paths.sed
# Make sure you edit the sed script referenced above
# to set the base URL of your repository.

# 1) generate the list of log messages, including affected paths (svn log -v)
# 2) process out those paths (sed)
# 3) eliminate duplicates (sort | uniq)
# 4) get the change history for each of those paths (svn diff)
# 5) filter out the ones that involve only property changes (sed)
# 6) eliminate duplicates again (sort | uniq)
$SVN log $LOG_OPTIONS | $SED -n -f $SED_SCRIPT | $SORT | $UNIQ \
 | $XARGS -n20 -I PATHS $SVN diff -r $SINCE_REV --summarize PATHS 2> error.log \
 | $SED -n 's/^[^ ].... *//p' | $SORT | $UNIQ

Here is the external sed script. Be sure to change the svn repository base URL to the right base URL for your repository. I.e. the beginning part of the svn URL that is not output by svn log -v.

 # sed script to output all lines between
 # /^Changed paths:$/ and /^$/, exclusive.
 # Also removes first 5 columns (status) and replaces them with svn repository base url.

 /^Changed paths:$/,/^$/ {
   /^Changed paths:$/b
   /^$/b
   s|^.....|https://svn.myrepo.org/prefix|
   s/ (from .*)$//
   p
}

The script will output some error messages to error.log, primarily "path not found", which I believe is for files that used to be present in the repository but have been moved (renamed) or deleted.

Does this meet your requirements?

Credit to Michael Augustin at this page for ideas about grepping the output of svn diff to remove property-only changes.

P.S. This other page seems to ask the same question, but there's no full answer there.

P.P.S. Edited the above bash script to add an extra | sort | uniq to the end of the pipeline, since I have seen duplicates come out there. Though I don't see why they would occur.

Community
  • 1
  • 1
LarsH
  • 27,481
  • 8
  • 94
  • 152
  • +1! @LarsH: that's one of the nasty things of SO: the bounty system. The idea is nice, and many have complained of the auto-dismiss feature, but it is still there. I've often seen my answers ignored, or checked as answers way after the bounty-period was over. And see, here too, upvotes come in too late for the bounty to be won... (PS: see some discussions on meta.stackoverflow.com) – Abel Aug 18 '10 at 20:14
  • @Abel, Yeah... I spent a fair bit of time on that, and posted several hours before the deadline. Moreover @zr was online. But probably busy with another question. So thanks for voting it up. I'm up to a reasonable threshold now for rep, so losing the bounty is not as critical. – LarsH Aug 18 '10 at 20:43
  • Thanks a lot and sorry for not following up right away. My life and work outside of SO is such an interference... I will pay as soon as the chill-out period ends. – zr. Aug 20 '10 at 06:18
  • No problem... don't let a web site take precedence over real life! Thanks. – LarsH Aug 20 '10 at 16:07
2

Doesn't look like it: SVN log in the Subversion manual

Maybe filter them out afterwards, e.g. using a shell script? What system are you on?

Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • Yes. I believe this requires writing some post-processing script. I was hoping someone would be willing to share an existing solution, rather than having to reinvent the wheel. – zr. Aug 09 '10 at 08:11
  • @zr that is extremely difficult to do when you don't even reveal the operating system you need this to work on. You should add that information. – Pekka Aug 09 '10 at 08:23
  • I use both Windows and Linux. On Windows i have Cygwin intergrate to my shell, so a unix-style solution should work on both platforms. – zr. Aug 09 '10 at 08:36
1

Like you, I was sadly surprised that 'svn log' could not be told to list just the revisions in which a file's content had changed.

Each of the other suggestions required something that I did not have installed, so I created a version that works well for my needs (querying about a single file) and that requires only sh+awk. Put the following in "svn-log-contents.sh":

#!/bin/sh

while [ ! -z "$1" ]; do
   file="$1"
   base=`basename "$file"`
   echo "$base ($file)"
   shift
   svn log -v $file | \
      awk "/^r([1-9]+)/ { r=\$1 } /^ *[MAD] .*$base$/ { \
           system(\"svn log -l 1 -r \" r \" $file\") }"
done

Make it executable using 'chmod a+x svn-log-contents.sh', then supply the file name(s) on the command line:

./svn-log-contents.sh file.txt

The first regular expression (/^r[1-9]/) grabs each revision number in a variable r. The next regular expression ('/^ *[MAD].../') triggers only when the file has been modified in a significant way, at which time it will run 'svn log' on that one revision. I'm an awk novice, so suggestions are welcome.

1

Even before searching around I came to the conclusion that this would require taking each revision in the log and passing it to `svn diff' to see just what changed in the revision. Then I found this other SO question: how to detect modified properties using SVN log

There is svnlog.py which includes filtering options for authors and paths, but does not include any diff integration. You might be able to hack that.

I hope this helps.

Thank you,
Zachary

Community
  • 1
  • 1
Zach Young
  • 10,137
  • 4
  • 32
  • 53
0

Here is a way to show logs for only real file changes, ignoring the property changes:

#!/bin/sh

for i in $(svn log --xml --with-no-revprops | xml sel -t -m "/log/logentry" -v "@revision" -o " "); do
    j=$(svn diff -c $i --summarize | grep -v "^ ")
    if [ -n "$j" ]; then
        svn log -c $i
    fi
done

The above requires xmlstarlet to be installed.

MattK
  • 1,431
  • 13
  • 14