Make SVN Commit also print the diff
When I do svn commit and let my svn editor pick it up I'd LOVE for the svn editor to show the diff of the files that have changed instea开发者_运维技巧d of just the list of files. Really helps jog the memory when writing detailed commit messages. Any ideas on how to accomplish?
Looks like the script here works after all.
From - http://push.cx/2007/seeing-subversion-diffs-for-commit-messages
Needed to make a few changes. I'll paste the entire script here
create a file, name it svn in this case it's put in ~/bin
#!/bin/sh
REALSVN=/usr/bin/svn
ARGS="$@"
if [ "$1" = "commit" -o "$1" = "ci" ]; then
shift # pop off $1 for diff
TEMPLATE=`mktemp -t tmp`
$REALSVN diff "$@" > "$TEMPLATE"
$REALSVN $ARGS --editor-cmd="~/bin/svn-diff-editor '$TEMPLATE'"
else
$REALSVN $ARGS
fi
and also create a file named ~/bin/svn-diff-editor
echo >> "$2"
cat "$1" >> "$2"
rm "$1"
$SVN_EDITOR "$2"
for osx i had to add the '-t tmp' to mktmp and the orig script had $VISUAL which I did not have and had $SVN_EDITOR set instead, once I changed the last line of svn-diff-editor to that it worked.
Write a script
It would take some work, but you could write a script to front end as your SVN_EDITOR.
When svn
invokes your SVN_EDITOR, it passes the name of an svn-generated temporary comment file containing the summary list of affected files to be committed.
http://svnbook.red-bean.com/en/1.5/svn-book.html#svn.advanced.externaleditors
The value of any of these options or variables is the beginning of a command line to be executed by the shell. Subversion appends to that command line a space and the pathname of a temporary file to be edited. So, to be used with Subversion, the configured or specified editor needs to support an invocation in which its last command-line parameter is a file to be edited, and it should be able to save the file in place and return a zero exit code to indicate success.
Conceivably, you could write a shell script that takes a filename parameter that:
- opens the file indicated by the last arg (the svn temporary comment file)
- parses it for the files to be committed
- runs
svn diff
on each modified (non-binary) file and appends the diff output back to the end of the svn temporary comment file - invokes your real editor on the modified svn temporary comment file
Make sure your script returns the return code returned by your real editor or 0 to indicate success. Then set your SVN_EDITOR env var to point to your script.
Perhaps someone has already written such a script, but I couldn't find one (especially since you didn't indicate an OS). There's also a good chance that this script could generate an extremely large file.
Alternative - write a macro
I think a better alternative would be to use a programmable editor and program a macro that read a filename(s) from some selected line(s) and then run SVN diff on the file(s) - putting the results in a buffer or appending it to current buffer . You could then selectively highlight files from the svn temporary comment file and run SVN diff on just the key files you need. Sounds like a job for elisp!
Sorry I don't have an ready-made code for you. If you do either of these, it would be interesting to see come back and post your script/macro back here as an answer.
I wrote a simple script and set SVN_EDITOR
to its path:
#!/bin/bash
tmpFile="${!#}"
# Append changes in committed files to tmpFile
echo >> ${tmpFile}
grep '^[MR]' ${tmpFile} | awk '{print $2}' | \
xargs -n 1 --no-run-if-empty svn diff >> ${tmpFile}
# Run editor
exec ${EDITOR} ${tmpFile}
Note that it only looks for modified (M) and replaced (R) files and assumes EDITOR
is set. Should probably not try to diff binary files.
I couldn't find an answer that I felt like using. dstarh's answer is almost there. But it's too intrusive to me. What if there are arguments before commit
? Additionally, it's safer to delete the temporary file with a trap. And to please the paranoid folk, I escape the editor cmd:
svn-commit.sh
:
#!/usr/bin/env bash
set -eu
tmp=`mktemp` _trap="rm -r "$tmp"; ${_trap:-}" && trap "$_trap" EXIT
svn diff "$@" > "$tmp"
# svn diff "$@" | iconv -f utf-8 -t utf-8 -c > "$tmp" # skip malformed UTF-8 characters
svn commit "$@" "--editor-cmd=svn-editor.sh $(printf %q "$tmp")"
svn-editor.sh
:
#!/usr/bin/env bash
set -eu
diff_f=$1
commit_msg_f=$2
# dos2unix "$diff_f" # if svn repo has files with different line-ending styles
# dos2unix -f "$diff_f" # to make it always treat diff output as text
echo >> "$commit_msg_f"
cat "$diff_f" >> "$commit_msg_f"
"$EDITOR" "$commit_msg_f"
UPD I've run into this error:
svn: E135000: Commit failed (details follow):
svn: E135000: Error normalizing edited contents to internal format
svn: E135000: Inconsistent line ending style
svn: E135000: Your commit message was left in a temporary file:
svn: E135000: '.../svn-commit.tmp'
One could consider adding dos2unix
command or something as done in the comment.
UPD Additionally, you may want to skip malformed UTF-8 characters, or else svn will fail:
svn: E000022: Commit failed (details follow):
svn: E000022: Error normalizing edited contents to internal format
svn: E000022: Valid UTF-8 data
(hex: 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 0a 2b 0a 2b)
followed by invalid UTF-8 sequence
(hex: a4 20 3d 20)
svn: E000022: Your commit message was left in a temporary file:
svn: E000022: '.../svn-commit.tmp'
UPD And occasionally dos2unix
might treat diff
output as binary:
dos2unix: Binary symbol 0x00 found at line 742308
dos2unix: Skipping binary file /tmp/tmp.UCNcubZZlX
svn: E135000: Commit failed (details follow):
svn: E135000: Error normalizing edited contents to internal format
svn: E135000: Inconsistent line ending style
svn: E135000: Your commit message was left in a temporary file:
svn: E135000: '.../svn-commit.tmp'
You may want to force conversion.
精彩评论