However, one of the features I've been greatly missing is a quick way to check which files have been changed between two revisions in a way as simple as the hg status does for the current working directory v. the last committed change: perhaps there is a way (if so, please do let me know) but it's certainly well hidden.
After a bit of tinkering with regular expressions and grep, one can easily come up with the following:
hg diff -g --nodates ${REV1} ${REV2}|grep -E '^\-{3}|^\+{3}'|grep -v '/dev/null'and get a reasonable (if not terribly readable) list of files changed: there are obviously "duplicates," (they are actually the majority of the list's entries) but one cannot limit the RegEx to just the '- - -' or '+++', as one would miss either the new files or the deleted ones.
I then came across this nice little trick by James Falkner that, in one shot, taught me about Zenity and gave me an idea as to how achieve the optional bonus of being also able to view the changes in tkdiff.
Before we get into the actual script, a very warm recommendation about installing Zenity (why that doesn't come as standard with every Ubuntu install is now beyond me: it is so totally easy to use and mind-blowingly useful that I'm kicking myself for not having discovered it earlier).
In a standard Ubuntu desktop install, you are likely to miss a few packages: gtk+ 2.0, libglade 2.0 and libgnomecanvas 2.0, and it's not obvious which packages contain them: they are, respectively, libgtk2.0-dev, libglade2-dev and libgnomecanvas2-dev.
sudo apt-get install libgtk2.0-dev libglade2-dev libgnomecanvas2-devI also recommend installing GTK's documentation, the build-essential package and devhelp (the latter can be found in Applications > Programming and is a simple tool to visualize a wealth of docs and information about various libraries, including GTK+ 2.0 and Libglade):
sudo apt-get install libgtk2.0-doc devhelp build-essentialTo install Zenity, the usual drill: unpack the tar file into a directory of your own chosing, then run:
$ ./configure(note the last command to be run as root, or you won't be able to install the binaries and other files in directories owned by root).
$ make
$ sudo make install
Help about Zenity and examples as how to use it can be found in the standard Gnome Help Centre (there is typically a shortcut in the menu bar at the far right top end, and in the standard Ubuntu theme looks like a lifesaver).
I now have all the bits in place, and the script looks thus:
#!/bin/bashAgain, not pretty, but it does the job.
# Lists the files changed from two revisions
# Usage: hgfiles 50 55
#
# Clones the current repository at -r 50 and -r 55, into two temporary directories, and, optionally, saves
# the SECOND clone in a directory of the user's choosing, possibly after the user has edited the files.
# Uses tkdiff to show the diffs and Zenity to show the dialogs
# See http://codetrips.blogspot.com/ for further information
TMPDIR=/tmp
FILES=$TMPDIR/hg_files.tmp
if [ -n "$1" ]; then
REV1="-r $1"
TMPDIR1=$TMPDIR/clone_$1
else
echo "At least one revision must be specified"
exit -1
fi
if [ -n "$2" ]; then
REV2="-r $2"
TMPDIR2=$TMPDIR/clone_$2
else
zenity --question --width=400 --text="Using current revision for diff: was this expected?"
echo "Zenity says: $?"
if [ $? == 1 ]; then
zenity --error --text="Diff canceled"
exit 0
fi
TMPDIR2=$TMPDIR/clonelatest
fi
hg diff -g --nodates ${REV1} ${REV2}|grep -E '^\-{3}|^\+{3}'|grep -v '/dev/null' > $FILES
FILELIST=`cat $FILES |java -cp /home/marco/bin com.alertavert.simple.HgDiff`
hg clone $REV1 ./ $TMPDIR1
hg clone $REV2 ./ $TMPDIR2
while [ 1 ] ; do
FILE=`zenity --list --width=700 --column="File to show diffs for" $FILELIST`
if [ -z "$FILE" ] ; then
FOLDERCOPY=`zenity --file-selection --directory --save \
--title="Select a folder to save changes"`
case $? in
0)
echo "Folder selected: $FOLDERCOPY" && cp -r --target-directory="$FOLDERCOPY" "$TMPDIR2"/*;;
1)
echo "No folder selected";;
-1)
echo "No folder selected";;
esac
rm -rf $TMPDIR1 $TMPDIR2
exit 0
fi
tkdiff $TMPDIR1/$FILE $TMPDIR2/$FILE
done
The only bit of "mystery" may be that command piped just after the grep:
java -cp /home/marco/bin com.alertavert.simple.HgDiffbut that is a really trivial class to remove the "+++ a/" (or "--- b/" from each of the lines grepped from the output of hg diff:
package com.alertavert.simple;It's that trivial: there's a reason why it wound up in the 'simple' package...
import java.io.*;
public class HgDiff {
public static void main(String args[]) {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String line;
try {
while ((line = reader.readLine()) != null) {
if (line.startsWith("+++") || line.startsWith("+++")) {
String trimmedLine = line.substring(6);
System.out.println(trimmedLine);
}
}
} catch(IOException ex) {
// ignore
System.exit(-1);
}
}
}
I could have probably achieved the same effect with some twisting of sed/awk, but honestly, it took me less time to knock this together (it was a strange feeling going back to using gedit and javac, as I really felt that really, just booting up Eclipse to create it would have taken longer!) than even look'em up on Google.
Just remember to change the -cp /home/marco/bin to reflect the folder under which you will install the .class file.
Blogged with the Flock Browser
There is a really easy way to make a list of what files changes, that way is differed. So, to get a list of files that have changed between change sets A and B do:
ReplyDeletehg diff -r A -r B | differed -l
Then feed that list.
Not differed but diffstat, i..e:
ReplyDeletehg diff -r A -r B | diffstat -l
Bloody autocorrect can give interesting results :)
Thanks, Kevin - that works very nicely indeed!
ReplyDeleteWell, turns out that doesn't work so well for 'added' files.
ReplyDeleteDiffstat adds a a/ to the filename:
$ hg diff -r 75 -r 79|diffstat -l
.hgtags
AndroidManifest.xml
a/common/META-INF/persistence.xml
a/common/com/alertavert/receiptscan/ReceiptscanModel.gwt.xml
a/common/com/alertavert/receiptscan/model/PictureStorage.java
a/common/receiptscan_model.jardesc
common/com/alertavert/receiptscan/model/Receipt.java
default.properties
res/values/strings.xml
src/com/alertavert/android/applications/receiptscan/ControllerActivity.java
src/com/alertavert/android/applications/receiptscan/ReceiptsGalleryActivity.java
src/com/alertavert/android/applications/receiptscan/connectivity/MailSender.java
src/com/alertavert/android/applications/receiptscan/settings/SettingsDialog.java
src/com/alertavert/android/applications/receiptscan/storage/FileUtils.java
src/com/alertavert/android/applications/receiptscan/ui/ReceiptsImagesAdapter.java
and I don't seem to find an option to turn that off.