#
# add_file "hmac.cc"
#
# add_file "hmac.hh"
#
# patch "AUTHORS"
# from [1bc23bee8e818ed6bc3b2d173b0f6435cbc92832]
# to [ff466bec33fb81e11e8f7dc8cc425e89ee70f745]
#
# patch "ChangeLog"
# from [dbed68c08f5bbda72e46fd6f3a557246e9f585a6]
# to [81eece5640970d2c6a838995ff56ed60e0868cd9]
#
# patch "Makefile.am"
# from [78ca8f5e5c7726ed29bf7ebd7db41367e8af60ae]
# to [cbd9fbc3d73a88f56a538bc5050a2ce3a2ffee31]
#
# patch "commands.cc"
# from [6d3576bd14d6e1fe8c595a75dcf50a478e6f1f65]
# to [c9dd7afdabd028f1a9ec18da9aa1a9de1670765d]
#
# patch "constants.cc"
# from [2258f6165b6db8f8c952f97aaacf0addbbed060f]
# to [dcbffe20599c26310957ee7c1310a44ae93dc2a0]
#
# patch "contrib/mtbrowse.sh"
# from [be25d5887954500c958377bc524161d7a641fcaa]
# to [9ad2130061d1372f803e9b59e3f45bf38609c31a]
#
# patch "file_io.cc"
# from [6125dbcc50e69e63ba8a22664e3e8126ee1115a0]
# to [ff47ce57304e48a07f9e6c539610f7d992c5e773]
#
# patch "hmac.cc"
# from []
# to [39bc2c1c84cb059b9d4095dd23daa369c33c4cbf]
#
# patch "hmac.hh"
# from []
# to [1aca898a8a90b9054cd1b4c0e966b298854cc924]
#
# patch "netcmd.cc"
# from [d6a4b557b616231cd233f2935c5c3c9cae327362]
# to [b8f2bfffbb6ebefdf274ea1d5ac59b58cd837671]
#
# patch "netcmd.hh"
# from [6054b45890695d2e78404a82f9f2bc6b85ca8330]
# to [f6262bdd5719defdd5ef6237e090687701ef4006]
#
# patch "netsync.cc"
# from [9715316b0883fb6d8dbfd0c524ee617c4a0225a4]
# to [f1056e86785d18c2a7da04c76086fd3c5106ab9c]
#
# patch "revision.cc"
# from [277c60b5acdedb97fe5cf8930b5f5452063abfd8]
# to [dab8f8c33fc1b34f01958d267e98164a96e52738]
#
# patch "tests/t_diff_currev.at"
# from [a14fc00cd1a98b790f305ec3ea257c9c2406639b]
# to [ee9a2d74b230a17a54292a4b2301f650330bf3ea]
#
# patch "transforms.cc"
# from [fe0f025921c7a342635e152d4f7c8b93499be401]
# to [589f2e927da5c33a2adb9bfea8f9b70d041ce212]
#
# patch "transforms.hh"
# from [446f1de66317ee1a5a4ee76fd0887a686c8264b8]
# to [9f9adf9a36619e493cceea57d78e6c4cc456598d]
#
# patch "vocab.hh"
# from [77bb3d7df9abc7e4e5202cb20b313c925dad2c13]
# to [e7d7947fe544166a511b44911cff89fa62ace2e9]
#
--- AUTHORS
+++ AUTHORS
@@ -60,6 +60,7 @@
Matthew Gregan
Riccardo Ghetta
Ethan Blanton
+ Eric Anderson
supporting files:
-----------------
--- ChangeLog
+++ ChangeLog
@@ -93,6 +93,32 @@
* transforms.hh (glob_to_regex, globs_to_regex, regexes_to_regex):
Prototype.
+2005-06-28 Matt Johnston
+
+ * constants.cc: increase db_version_cache_sz to 7 MB
+ * netsync.cc: use a deque rather than a single
+ string buffer for outbuf.
+ * netsync.cc (arm): only queue data when there is
+ available space
+ * AUTHORS: added Eric Anderson
+
+2005-06-26 Matt Johnston
+
+ * transforms.hh: remove extraneous #ifdef
+ * hmac.cc, hmac.hh: actually add them
+
+2005-06-26 Matt Johnston
+
+ * netcmd.cc (netcmd::read, netcmd::write): change to using a HMACs
+ chained by including the previous HMAC in the input data, rather
+ than altering the key each time.
+ * netcmd.cc ({read,write}_{data,delta}_cmd): use encode_gzip/decode_gzip
+ rather than raw xform.
+ * hmac.{cc,hh}: new chained_hmac abstraction
+ * Makefile.in: add them
+ * netsync.cc: each session keeps a chained_hmac for read/write
+ * transforms.hh: add a string variant for encode_gzip
+
2005-06-25 Nathaniel Smith
* netsync.cc: Tweak comment.
@@ -159,6 +185,57 @@
lua excerpts from hook reference.
* Makefile.am : make monotone.pdf/eps depend on monotone.info
+2005-06-24 Matt Johnston
+
+ * transforms.{cc,hh}: combine gzip and base64 in one
+ pipe for pack()/unpack() to save memory
+ * vocab.hh: add swap() to encodings/atomics
+ * file_io.cc: use swap() to avoid copying
+
+2005-06-21 Nathaniel Smith
+
+ * commands.cc (do_diff): Use calculate_arbitrary_change_set,
+ instead of reimplementing it.
+
+2005-06-21 Nathaniel Smith
+
+ * revision.cc (find_least_common_ancestor): Handle left == right
+ case.
+ * tests/t_diff_currev.at: Un-XFAIL.
+
+2005-06-21 Nathaniel Smith
+
+ * netsync.cc (rebuild_merkle_trees): Fix FIXME comments to match
+ reality.
+ * tests/t_netsync_diffbranch.at: No longer a bug, remove
+ priority.
+
+2005-06-20 Nathaniel Smith
+
+ * monotone.texi (Hook Reference): Oops, missed a @ref.
+
+2005-06-20 Nathaniel Smith
+
+ * monotone.texi (Default monotonerc): Rename section to...
+ (Default hooks): ...this, to emphasize is still read even when a
+ monotonerc exists.
+
+2005-06-19 Richard Levitte
+
+ * Makefile.am: There's no reason for monotone.pdf or .dvi to
+ depend on monotone.info, since they are built from the .texi
+ files. Also, make the monotone.html and html targets depend
+ on version.texi and std_hooks.lua as well.
+
+2005-06-18 Matt Johnston
+
+ * INSTALL: fix typo, should be -Iboost_1_31_0 not -Iboost_1_31_2
+
+2005-06-18 Riccardo Ghetta
+ * monotone.texi: include std_hooks.lua as an appendix and remove long
+ lua excerpts from hook reference.
+ * Makefile.am : make monotone.pdf/eps depend on monotone.info
+
2005-06-17 Matt Johnston
* database.cc (database::execute()): truncate long query log messages
--- Makefile.am
+++ Makefile.am
@@ -40,6 +40,7 @@
selectors.cc selectors.hh \
annotate.cc annotate.hh \
restrictions.cc restrictions.hh \
+ hmac.cc hmac.hh \
globish.cc globish.hh \
\
cleanup.hh unit_tests.hh interner.hh \
--- commands.cc
+++ commands.cc
@@ -2662,36 +2662,8 @@
N(find_least_common_ancestor(src_id, dst_id, anc_id, app),
F("no common ancestor for %s and %s") % src_id % dst_id);
- if (src_id == anc_id)
- {
- calculate_composite_change_set(src_id, dst_id, app, composite);
- L(F("calculated diff via direct analysis\n"));
- }
- else if (!(src_id == anc_id) && dst_id == anc_id)
- {
- change_set tmp;
- calculate_composite_change_set(dst_id, src_id, app, tmp);
- invert_change_set(tmp, m_new, composite);
- L(F("calculated diff via inverted direct analysis\n"));
- }
- else
- {
- change_set anc_to_src, src_to_anc, anc_to_dst;
- manifest_id anc_m_id;
- manifest_map m_anc;
+ calculate_arbitrary_change_set(src_id, dst_id, app, composite);
- I(!(src_id == anc_id || dst_id == anc_id));
-
- app.db.get_revision_manifest(anc_id, anc_m_id);
- app.db.get_manifest(anc_m_id, m_anc);
-
- calculate_composite_change_set(anc_id, src_id, app, anc_to_src);
- invert_change_set(anc_to_src, m_anc, src_to_anc);
- calculate_composite_change_set(anc_id, dst_id, app, anc_to_dst);
- concatenate_change_sets(src_to_anc, anc_to_dst, composite);
- L(F("calculated diff via common ancestor %s\n") % anc_id);
- }
-
if (!new_is_archived)
{
L(F("concatenating un-committed changeset to composite\n"));
--- constants.cc
+++ constants.cc
@@ -44,8 +44,11 @@
// truncated.
size_t const db_log_line_sz = 70;
- // size in bytes of the database xdelta version reconstruction cache
- size_t const db_version_cache_sz = 1 << 20;
+ // size in bytes of the database xdelta version reconstruction cache.
+ // the value of 7 MB was determined as the optimal point after timing
+ // various values with a pull of the monotone repository - it could
+ // be tweaked further.
+ size_t const db_version_cache_sz = 7 * (1 << 20);
// size of a line of text in the log buffer, beyond which log lines will be
// truncated.
--- contrib/mtbrowse.sh
+++ contrib/mtbrowse.sh
@@ -1,10 +1,10 @@
#!/bin/sh
#
# File: mtbrowse.sh
# Description: Text based browser for monotone source control.
# url: http://www.venge.net/monotone/
# Licence: GPL
-# Autor: Henry Nestler
+# Author: Henry Nestler
#
# Simple text based browser for Monotone repositories, written as shell script.
# Can select branch, revision. Views diff from revision, logs, certs and more.
@@ -63,10 +63,20 @@
# Check filname for reading before MT fails.
# Exit after --help or --version.
#
+# 2005/6/16 Version 0.1.8 address@hidden
+# automate ancestors, toposort, complete revision and
+# automate parents missing param --db (if no MT directory).
+# Switch --depth/--last without error dialog.
+# Bug: Select rev for multiple parents (from merge), remove "cat cat".
+# Use Author, not Key. Add Branch and Changelog in selection.
+# Selectable format for Date, Branch, Author, ChangeLog. Coloring author.
+# Current marker is asterix before date/time.
+#
# Known Bugs / ToDo-List:
# * For Monotone Version >0.19 s/--depth/--last/, remove the fallback
+# * better make "sed -n -e '1p'" for merge two different branches.
-VERSION="0.1.7"
+VERSION="0.1.8"
# Save users settings
# Default values, can overwrite on .mtbrowserc
@@ -84,14 +94,11 @@
# Don't VISUAL and PAGER to use internal viewer.
PAGER="less"
-# View date and keys in revision selection? (yes)
-SHOW_KEYS="yes"
-
# 1=Certs Cached, 0=Clean at end (slow and save mode)
CACHE="1"
# T=Topsort revisions, D=Date sort (reverse topsort)
-TOPSORT="D"
+TOPSORT="T"
# count of certs to get from DB, "0" for all
CERTS_MAX="20"
@@ -99,6 +106,21 @@
# Trim hash code
HASH_TRIM="10"
+# Format Date/Time
+FORMAT_DATE="L"
+
+# Format Branch Full,Short,None
+FORMAT_BRANCH="F"
+
+# Format author (strip domain from mail address)
+FORMAT_AUTHOR="F"
+
+# Changelog format
+FORMAT_LOG="F"
+
+# Author coloring?
+FORMAT_COLOR="\\Z7\\Zb"
+
# "log --depth=n" was changed to "log --last=n", see
# Author: address@hidden, Date: 2005-05-30T00:15:27
# Autodetect this and fallback for a while.
@@ -209,44 +231,104 @@
# Add the date and user-key to the list of revisions
fill_date_key()
{
- local in_file=$1
- local out_file=$2
- local short_hash date key
+ local in_file=$1
+ local out_file=$2
+ local short_hash dat bra aut log
- rm -f $out_file
- if [ "$SHOW_KEYS" = "yes" ]
- then
- # Read Key and Date value from certs
- cat $in_file | \
- while read hash ; do
- echo -n "."
+ rm -f $out_file
+ # Read Key and Date value from certs
+ cat $in_file | \
+ while read hash ; do
+ echo -n "."
- # Scanning for
- # Key : address@hidden <<---
- # Sig : ok
- # Name : date
- # Value : 2005-05-31T22:29:50 <<---
+ # Scanning for
+ # Key : address@hidden
+ # Sig : ok
+ # Name : date
+ # Value : 2005-05-31T22:29:50 <<---
- # Output
- # 123456 "2005-05-31T22:29:50 address@hidden"
+ # Output
+ # 123456 "2005-05-31 22:29 address@hidden"
- eval `monotone --db=$DB list certs $hash | \
- tail -n 6 | sed -n -r \
- -e 's/Key : ([^ address@hidden ]+)$/key=\1/p' \
- -e 's/Value : ([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:]{8})$/date=\1/p'`
- short_hash=`echo $hash | cut -c 1-$HASH_TRIM`
- echo "$short_hash \"$date $key\"" >> $out_file
- done
+ short_hash=`echo $hash | cut -c 1-$HASH_TRIM`
+
+ # get all certs of revision
+ monotone --db=$DB list certs $hash > $TEMPFILE.c.tmp
+
+ # Date format
+ case $FORMAT_DATE in
+ F) # 2005-12-31T23:59:59
+ dat=`cat $TEMPFILE.c.tmp | sed -n -r -e \
+ '/^Name : date/,+1s/Value : (.+)$/ \1/p'`
+ ;;
+ L) # 2005-12-31 23:59
+ dat=`cat $TEMPFILE.c.tmp | sed -n -r -e \
+ '/^Name : date/,+1s/Value : (.{10})T(.{5}).+$/ \1 \2/p'`
+ ;;
+ D) # 2005-12-31
+ dat=`cat $TEMPFILE.c.tmp | sed -n -r -e \
+ '/^Name : date/,+1s/Value : (.+)T.+$/ \1/p'`
+ ;;
+ S) # 12-31 23:59
+ dat=`cat $TEMPFILE.c.tmp | sed -n -r -e \
+ '/^Name : date/,+1s/Value : .{4}-(.+)T(.{5}).+$/ \1 \2/p'`
+ ;;
+ T) # 23:59:59
+ dat=`cat $TEMPFILE.c.tmp | sed -n -r -e \
+ '/^Name : date/,+1s/Value : .{10}T(.+{8})$/ \1/p'`
+ ;;
+ esac
+
+ # Branch format
+ case $FORMAT_BRANCH in
+ F) # full
+ bra=`cat $TEMPFILE.c.tmp | sed -n -r -e \
+ '/^Name : branch/,+1s/Value : (.+)$/ \1/p' | \
+ sed -n -e '1p'`
+ ;;
+ S) # short
+ bra=`cat $TEMPFILE.c.tmp | sed -n -r -e \
+ '/^Name : branch/,+1s/Value : .*\.([^\.]+)$/ \1/p' | \
+ sed -n -e '1p'`
+ ;;
+ esac
+
+ # Author format
+ case $FORMAT_AUTHOR in
+ F) # full
+ aut=`cat $TEMPFILE.c.tmp | sed -n -r -e \
+ '/^Name : author/,+1s/Value : (.+)$/\1/p'`
+ ;;
+ S) # short
+ aut=`cat $TEMPFILE.c.tmp | sed -n -r -e \
+ '/^Name : author/,+1s/Value : (.{1,10})address@hidden/\1/p'`
+ ;;
+ esac
+
+ # Changelog format
+ case $FORMAT_LOG in
+ F) # full
+ log=`cat $TEMPFILE.c.tmp | sed -n -r -e "y/\"/'/" -e \
+ '/^Name : changelog/,+1s/Value : (.+)$/ \1/p'`
+ ;;
+ S) # short
+ log=`cat $TEMPFILE.c.tmp | sed -n -r -e "y/\"/'/" -e \
+ '/^Name : changelog/,+1s/Value : (.{1,20}).*$/ \1/p'`
+ ;;
+ esac
+
+ # Coloring?
+ if [ -n "$FORMAT_COLOR" -a "$FORMAT_AUTHOR" != "N" ]
+ then
+ # Bug in dialog: Don't allow empty string after \\Zn
+ test -z "$log" && log=" "
+ echo "$short_hash \"$dat$bra $FORMAT_COLOR$aut\\Zn$log\"" \
+ >> $out_file
else
- # Read only Date value from certs
- cat $in_file | \
- while read hash ; do
- echo -n "."
- monotone --db=$DB list certs $hash | sed -n -r -e \
- "s/Value : ([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:]{8})\$/$hash \"\1\"/p" \
- | tail -n 1 >> $out_file
- done
+ echo "$short_hash \"$dat$bra $aut$log\"" >> $out_file
fi
+ done
+ rm $TEMPFILE.c.tmp
}
@@ -268,6 +350,8 @@
exit 1
fi
+ SHORT_DB=`basename $DB`
+
# is Branch set, than can return
if [ -n "$BRANCH" -a -n "$1" ]
then
@@ -281,8 +365,6 @@
unset BRANCH
fi
- SHORT_DB=`basename $DB`
-
OLD_BRANCH=$BRANCH
# Get branches from DB
@@ -335,7 +417,7 @@
then
HEAD=`cat $TEMPFILE.heads | head -n 1`
else
- # List heads with autor and date. Select by user.
+ # List heads with author and date. Select by user.
monotone --db=$DB heads --branch=$BRANCH \
| sed -n -r -e 's/^([^ ]+) ([^ ]+) ([^ ]+)$/\1 \"\2 \3\"/p' \
| xargs dialog --begin 1 2 --menu "Select head" 0 0 0 \
@@ -378,15 +460,18 @@
> $TEMPFILE.change.log
then
DEPTH_LAST="--depth"
- dialog --title " ERROR " --msgbox \
- "Fallback to \"$DEPTH_LAST\" usage.\nPlease try again." 6 40
- else
- do_pager $TEMPFILE.change.log
+ echo "Fallback to --depth usage."
+
+ # Try again
+ monotone --db=$DB log $DEPTH_LAST=1 --revision=$REVISION \
+ > $TEMPFILE.change.log || exit 200
fi
+
+ do_pager $TEMPFILE.change.log
;;
P)
# DIFF parent
- monotone automate parents $REVISION > $TEMPFILE.parents
+ monotone --db=$DB automate parents $REVISION > $TEMPFILE.parents
if [ `wc -l < $TEMPFILE.parents` -ne 1 ]
then
@@ -395,8 +480,9 @@
# Set DATE/KEY information
fill_date_key $TEMPFILE.parents $TEMPFILE.certs3tmp
- cat cat $TEMPFILE.certs3tmp | \
- xargs dialog --begin 1 2 --default-item "$PARENT" \
+ cat $TEMPFILE.certs3tmp | \
+ xargs dialog --begin 1 2 --colors \
+ --default-item "$PARENT" \
--menu "Select parent for $REVISION" 0 0 0 \
2> $TEMPFILE.input \
&& PARENT=`cat $TEMPFILE.input`
@@ -494,13 +580,13 @@
then
echo "Reading ancestors ($HEAD)"
echo "$HEAD" > $TEMPFILE.ancestors
- monotone automate ancestors $HEAD | cut -c 1-40 \
+ monotone --db=$DB automate ancestors $HEAD | cut -c 1-40 \
>> $TEMPFILE.ancestors || exit 200
if [ "$TOPSORT" = "T" -o "$CERTS_MAX" -gt 0 ]
then
echo "Topsort..."
- monotone automate toposort `cat $TEMPFILE.ancestors` \
+ monotone --db=$DB automate toposort `cat $TEMPFILE.ancestors` \
> $TEMPFILE.topsort || exit 200
if [ "$CERTS_MAX" -gt 0 ]
@@ -534,6 +620,8 @@
while cat $TEMPFILE.certs.$BRANCH | \
xargs dialog \
--backtitle "h:$HEAD b:$BRANCH f:$SHORT_DB" \
+ --no-shadow \
+ --colors \
--default-item "$SHORT_REV" \
--menu "Select revision for branch:$BRANCH" \
0 0 0 2> $TEMPFILE.revision-select
@@ -543,16 +631,14 @@
# Remove old marker, set new marker
cat $TEMPFILE.certs.$BRANCH | sed -r \
- -e "s/^(.+) <==\"\$/\1\"/" -e "s/^($SHORT_REV.+)\"\$/\1 <==\"/" \
+ -e "s/^(.+\")\*(.+)\$/\1 \2/" \
+ -e "s/^($SHORT_REV.* \") (.+)\$/\1\*\2/" \
> $TEMPFILE.certs.$BRANCH.base
mv $TEMPFILE.certs.$BRANCH.base $TEMPFILE.certs.$BRANCH
# Error, on "monotone automate parent XXXXXX", if short revision. :-(
- # Expand revision here, if short revision
- if [ "$SHOW_KEYS" = "yes" ]
- then
- REVISION=`monotone complete revision $SHORT_REV`
- fi
+ # Expand revision here, if short revision (is alway short now)
+ REVISION=`monotone --db=$DB complete revision $SHORT_REV`
# OK Button: Sub Menu
do_action_sel
@@ -564,15 +650,17 @@
# Menu for configuration
do_config()
{
- local y n
-
while dialog --menu "Configuration" 0 0 0 \
"V" "VISUAL [$VISUAL]" \
"Vd" "Set VISUAL default to vim -R" \
"P" "PAGER [$PAGER]" \
"Pd" "set PAGER default to less" \
- "K" "View KEY in selection [$SHOW_KEYS]" \
"S" "Sort by Topsort or Date [$TOPSORT]" \
+ "T" "Time and date format [$FORMAT_DATE]" \
+ "B" "Branch format [$FORMAT_BRANCH]" \
+ "A" "Author format [$FORMAT_AUTHOR]" \
+ "Ac" "Author Color format [$FORMAT_COLOR]" \
+ "L" "changeLog format [$FORMAT_LOG]" \
"C" "Certs limit in Select-List [$CERTS_MAX]" \
"-" "-" \
"W" "Write configuration file" \
@@ -602,35 +690,109 @@
# set Pager default
PAGER="less"
;;
- K)
- # change yes=View Keys, no=date only
-
- if [ "$SHOW_KEYS" = "yes" ]; then
- y="on" n="off"
- else
- y="off" n="on"
- fi
-
- dialog --radiolist "View Keys in Selection?" 0 0 0 \
- "yes" "Short revision, date and keys" $y \
- "no" "Long revision and Date" $n \
- 2> $TEMPFILE.input \
- && SHOW_KEYS=`cat $TEMPFILE.input`
- ;;
S)
# change T=Topsort revisions, D=Date sort (reverse topsort)
- if [ "$TOPSORT" = "T" ]; then
- y="on" n="off"
- else
- y="off" n="on"
- fi
-
dialog --radiolist "Sort revisions by" 0 0 0 \
- "D" "Date/Time (reverse topsort)" $n \
- "T" "Topsort (from Monotone)" $y \
+ "T" "Topsort, oldest top (from Monotone)" \
+ `test "$TOPSORT" = "T" && echo "on" || echo "off"` \
+ "D" "Date/Time (reverse topsort)" \
+ `test "$TOPSORT" = "D" && echo "on" || echo "off"` \
2> $TEMPFILE.input \
&& TOPSORT=`cat $TEMPFILE.input`
;;
+ T)
+ # change date/time format
+ dialog --radiolist "Format for date" 0 0 0 \
+ "F" "2005-12-31T23:59:59 -- Full date and time" \
+ `test "$FORMAT_DATE" = "F" && echo "on" || echo "off"` \
+ "L" "2005-12-31 23:59 -- Long date and time" \
+ `test "$FORMAT_DATE" = "L" && echo "on" || echo "off"` \
+ "D" "2005-21-31 -- Date only" \
+ `test "$FORMAT_DATE" = "D" && echo "on" || echo "off"` \
+ "S" "12-31 23:59:59 -- Short date and time" \
+ `test "$FORMAT_DATE" = "S" && echo "on" || echo "off"` \
+ "T" "23:59:59 -- Time only" \
+ `test "$FORMAT_DATE" = "T" && echo "on" || echo "off"` \
+ "N" "no date and no time" \
+ `test "$FORMAT_DATE" = "N" && echo "on" || echo "off"` \
+ 2> $TEMPFILE.input \
+ && FORMAT_DATE=`cat $TEMPFILE.input`
+ ;;
+ B)
+ # change branch format
+ dialog --radiolist "Format for branch" 0 0 0 \
+ "F" "Full author" \
+ `test "$FORMAT_BRANCH" = "F" && echo "on" || echo "off"` \
+ "S" "Short author, strip domain from email address" \
+ `test "$FORMAT_BRANCH" = "S" && echo "on" || echo "off"` \
+ "N" "no author" \
+ `test "$FORMAT_BRANCH" = "N" && echo "on" || echo "off"` \
+ 2> $TEMPFILE.input \
+ && FORMAT_BRANCH=`cat $TEMPFILE.input`
+ ;;
+ A)
+ # change author's format
+ dialog --radiolist "Format for author" 0 0 0 \
+ "F" "Full author" \
+ `test "$FORMAT_AUTHOR" = "F" && echo "on" || echo "off"` \
+ "S" "Short author, strip domain from email address" \
+ `test "$FORMAT_AUTHOR" = "S" && echo "on" || echo "off"` \
+ "N" "no author" \
+ `test "$FORMAT_AUTHOR" = "N" && echo "on" || echo "off"` \
+ 2> $TEMPFILE.input \
+ && FORMAT_AUTHOR=`cat $TEMPFILE.input`
+ ;;
+ Ac)
+ # Author coloring
+ dialog --radiolist "Color author in selecetion" 0 0 0 \
+ "yes" "author is color" \
+ `test -n "$FORMAT_COLOR" && echo "on" || echo "off"` \
+ "no" "author has no special color" \
+ `test -z "$FORMAT_COLOR" && echo "on" || echo "off"` \
+ 2> $TEMPFILE.input \
+ && {
+ if [ "`cat $TEMPFILE.input`" = "yes" ]
+ then
+ dialog --colors \
+ --default-item "$FORMAT_COLOR" \
+ --menu "Selecet color for author" 0 0 0 \
+ "\\Z0" "\Z0Color\Zn 0" \
+ "\\Z1" "\Z1Color\Zn 1" \
+ "\\Z2" "\Z2Color\Zn 2" \
+ "\\Z3" "\Z3Color\Zn 3" \
+ "\\Z4" "\Z4Color\Zn 4" \
+ "\\Z5" "\Z5Color\Zn 5" \
+ "\\Z6" "\Z6Color\Zn 6" \
+ "\\Z7" "\Z7Color\Zn 7" \
+ "\\Zb\\Z0" "\Zb\Z0Color\Zn 0b" \
+ "\\Zb\\Z1" "\Zb\Z1Color\Zn 1b" \
+ "\\Zb\\Z2" "\Zb\Z2Color\Zn 2b" \
+ "\\Zb\\Z3" "\Zb\Z3Color\Zn 3b" \
+ "\\Zb\\Z4" "\Zb\Z4Color\Zn 4b" \
+ "\\Zb\\Z5" "\Zb\Z5Color\Zn 5b" \
+ "\\Zb\\Z6" "\Zb\Z6Color\Zn 6b" \
+ "\\Zb\\Z7" "\Zb\Z7Color\Zn 7b" \
+ "\\Zb" "\ZbBold\Zn b" \
+ "\\Zu" "\ZuUnderline\Zn u" \
+ 2> $TEMPFILE.input \
+ && FORMAT_COLOR=`cat $TEMPFILE.input`
+ else
+ FORMAT_COLOR=""
+ fi
+ }
+ ;;
+ L)
+ # Changelog format
+ dialog --radiolist "Format for ChangeLog in selcetion" 0 0 0 \
+ "F" "Full changelog line" \
+ `test "$FORMAT_LOG" = "F" && echo "on" || echo "off"` \
+ "S" "Short changelog" \
+ `test "$FORMAT_LOG" = "S" && echo "on" || echo "off"` \
+ "N" "no changelog in selection" \
+ `test "$FORMAT_LOG" = "N" && echo "on" || echo "off"` \
+ 2> $TEMPFILE.input \
+ && FORMAT_LOG=`cat $TEMPFILE.input`
+ ;;
C)
# Change CERTS_MAX
dialog --inputbox \
@@ -649,11 +811,15 @@
PAGER="$PAGER"
TEMPDIR="$TEMPDIR"
TEMPFILE="$TEMPFILE"
-SHOW_KEYS="$SHOW_KEYS"
TOPSORT="$TOPSORT"
CACHE="$CACHE"
CERTS_MAX="$CERTS_MAX"
DEPTH_LAST="$DEPTH_LAST"
+FORMAT_DATE="$FORMAT_DATE"
+FORMAT_BRANCH="$FORMAT_BRANCH"
+FORMAT_AUTHOR="$FORMAT_AUTHOR"
+FORMAT_LOG="$FORMAT_LOG"
+FORMAT_COLOR="$FORMAT_COLOR"
EOF
dialog --title " Info " --sleep 2 --infobox \
"Configration wrote to\n$CONFIGFILE" 0 0
@@ -768,7 +934,8 @@
$DB -nt $TEMPFILE.changelog.$BRANCH ]
then
echo "Reading log...($BRANCH)"
- monotone --db=$DB log --revision=$HEAD > $TEMPFILE.changelog.$BRANCH || exit 200
+ monotone --db=$DB log --revision=$HEAD \
+ > $TEMPFILE.changelog.$BRANCH || exit 200
fi
cp $TEMPFILE.changelog.$BRANCH $TEMPFILE.change.log
do_pager $TEMPFILE.change.log
--- file_io.cc
+++ file_io.cc
@@ -384,7 +384,7 @@
if (!file)
throw oops(string("cannot open file ") + p.string() + " for reading");
CryptoPP::FileSource f(file, true, new CryptoPP::StringSink(in));
- dat = in;
+ dat.swap(in);
}
// This function can only be called once per run.
@@ -396,7 +396,7 @@
have_consumed_stdin = true;
string in;
CryptoPP::FileSource f(cin, true, new CryptoPP::StringSink(in));
- dat = in;
+ dat.swap(in);
}
void
@@ -461,7 +461,7 @@
read_data(path, tdat);
string tmp1, tmp2;
- tmp2 = tdat();
+ tdat.swap(tmp2);
if (do_charconv) {
tmp1 = tmp2;
charset_convert(ext_charset, db_charset, tmp1, tmp2);
@@ -470,7 +470,7 @@
tmp1 = tmp2;
line_end_convert(db_linesep, tmp1, tmp2);
}
- dat = tmp2;
+ dat.swap(tmp2);
}
--- hmac.cc
+++ hmac.cc
@@ -0,0 +1,43 @@
+#include
+
+#include "cryptopp/hmac.h"
+#include "cryptopp/sha.h"
+
+#include "sanity.hh"
+#include "hmac.hh"
+#include "vocab.hh"
+#include "constants.hh"
+
+chained_hmac::chained_hmac(netsync_session_key const & session_key) :
+ key(session_key)
+{
+ memset(chain_val, 0, sizeof(chain_val));
+}
+
+void
+chained_hmac::set_key(netsync_session_key const & session_key)
+{
+ key = session_key;
+}
+
+std::string
+chained_hmac::process(std::string const & str, size_t pos, size_t n)
+{
+ I(pos < str.size());
+ if (n == std::string::npos)
+ n = str.size() - pos;
+
+ I(pos + n <= str.size());
+
+ CryptoPP::HMAC
+ hmac(reinterpret_cast(key().data()),
+ constants::netsync_session_key_length_in_bytes);
+ hmac.Update(reinterpret_cast(chain_val),
+ sizeof(chain_val));
+ hmac.Update(reinterpret_cast(str.data() + pos),
+ n);
+ hmac.Final(reinterpret_cast(chain_val));
+
+ std::string out(chain_val, sizeof(chain_val));
+ return out;
+}
--- hmac.hh
+++ hmac.hh
@@ -0,0 +1,28 @@
+#ifndef __HMAC_HH__
+#define __HMAC_HH__
+
+#include
+
+#include "cryptopp/hmac.h"
+#include "cryptopp/sha.h"
+
+#include "vocab.hh"
+
+struct chained_hmac
+{
+ public:
+ chained_hmac(netsync_session_key const & session_key);
+ void set_key(netsync_session_key const & session_key);
+ std::string process(std::string const & str, size_t pos = 0,
+ size_t n = std::string::npos);
+
+ private:
+ netsync_session_key key;
+ char chain_val[CryptoPP::SHA::DIGESTSIZE];
+};
+
+
+
+
+#endif // __HMAC_HH__
+
--- netcmd.cc
+++ netcmd.cc
@@ -7,10 +7,6 @@
#include
#include
-#include "cryptopp/gzip.h"
-#include "cryptopp/hmac.h"
-#include "cryptopp/sha.h"
-
#include "adler32.hh"
#include "constants.hh"
#include "netcmd.hh"
@@ -18,6 +14,7 @@
#include "numeric_vocab.hh"
#include "sanity.hh"
#include "transforms.hh"
+#include "hmac.hh"
using namespace std;
using namespace boost;
@@ -68,34 +65,19 @@
}
void
-netcmd::write(string & out, netsync_session_key const & key,
- netsync_hmac_value & hmac_val) const
+netcmd::write(string & out, chained_hmac & hmac) const
{
size_t oldlen = out.size();
out += static_cast(version);
out += static_cast(cmd_code);
insert_variable_length_string(payload, out);
- I(key().size() == CryptoPP::SHA::DIGESTSIZE);
- I(key().size() == hmac_val().size());
- byte keybuf[CryptoPP::SHA::DIGESTSIZE];
- for (size_t i = 0; i < sizeof(keybuf); i++)
- {
- keybuf[i] = key()[i] ^ hmac_val()[i];
- }
- CryptoPP::HMAC hmac(keybuf, sizeof(keybuf));
- char digest[CryptoPP::SHA::DIGESTSIZE];
- hmac.CalculateDigest(reinterpret_cast(digest),
- reinterpret_cast(out.data() + oldlen),
- out.size() - oldlen);
- string digest_str(digest, sizeof(digest));
- hmac_val = netsync_hmac_value(digest_str);
- out.append(digest_str);
+ string digest = hmac.process(out, oldlen);
+ out.append(digest);
}
bool
-netcmd::read(string & inbuf, netsync_session_key const & key,
- netsync_hmac_value & hmac_val)
+netcmd::read(string & inbuf, chained_hmac & hmac)
{
size_t pos = 0;
@@ -142,15 +124,19 @@
throw bad_decode(F("oversized payload of '%d' bytes") % payload_len);
// there might not be enough data yet in the input buffer
- if (inbuf.size() < pos + payload_len + CryptoPP::SHA::DIGESTSIZE)
+ if (inbuf.size() < pos + payload_len + constants::netsync_hmac_value_length_in_bytes)
{
- inbuf.reserve(pos + payload_len + CryptoPP::SHA::DIGESTSIZE + constants::bufsz);
+ inbuf.reserve(pos + payload_len + constants::netsync_hmac_value_length_in_bytes + constants::bufsz);
return false;
}
// out.payload = extract_substring(inbuf, pos, payload_len, "netcmd payload");
// Do this ourselves, so we can swap the strings instead of copying.
require_bytes(inbuf, pos, payload_len, "netcmd payload");
+
+ // grab it before the data gets munged
+ string digest = hmac.process(inbuf, 0, pos + payload_len);
+
payload = inbuf.substr(pos + payload_len);
inbuf.erase(pos + payload_len, inbuf.npos);
inbuf.swap(payload);
@@ -158,26 +144,13 @@
pos = 0;
// they might have given us bogus data
- string cmd_digest = extract_substring(inbuf, pos, CryptoPP::SHA::DIGESTSIZE,
+ string cmd_digest = extract_substring(inbuf, pos,
+ constants::netsync_hmac_value_length_in_bytes,
"netcmd HMAC");
inbuf.erase(0, pos);
- I(key().size() == CryptoPP::SHA::DIGESTSIZE);
- I(key().size() == hmac_val().size());
- byte keybuf[CryptoPP::SHA::DIGESTSIZE];
- for (size_t i = 0; i < sizeof(keybuf); i++)
- {
- keybuf[i] = key()[i] ^ hmac_val()[i];
- }
- CryptoPP::HMAC hmac(keybuf, sizeof(keybuf));
- char digest_buf[CryptoPP::SHA::DIGESTSIZE];
- hmac.CalculateDigest(reinterpret_cast(digest_buf),
- reinterpret_cast(payload.data()),
- payload.size());
- string digest(digest_buf, sizeof(digest_buf));
if (cmd_digest != digest)
throw bad_decode(F("bad HMAC %s vs. %s") % encode_hexenc(cmd_digest)
% encode_hexenc(digest));
- hmac_val = netsync_hmac_value(digest);
payload.erase(0, payload_pos);
return true;
@@ -462,7 +435,13 @@
extract_variable_length_string(payload, dat, pos,
"data netcmd, data payload");
if (compressed_p == 1)
- dat = xform(dat);
+ {
+ gzip zdat;
+ data tdat;
+ zdat.swap(dat);
+ decode_gzip(zdat, tdat);
+ tdat.swap(dat);
+ }
assert_end_of_buffer(payload, pos, "data netcmd payload");
}
@@ -477,8 +456,10 @@
payload += item();
if (dat.size() > constants::netcmd_minimum_bytes_to_bother_with_gzip)
{
+ gzip zdat;
+ encode_gzip(dat, zdat);
string tmp;
- tmp = xform(dat);
+ zdat.swap(tmp);
payload += static_cast(1); // compressed flag
insert_variable_length_string(tmp, payload);
}
@@ -510,8 +491,14 @@
extract_variable_length_string(payload, tmp, pos,
"delta netcmd, delta payload");
if (compressed_p == 1)
- tmp = xform(tmp);
- del = delta(tmp);
+ {
+ gzip zdel(tmp);
+ decode_gzip(zdel, del);
+ }
+ else
+ {
+ del = tmp;
+ }
assert_end_of_buffer(payload, pos, "delta netcmd payload");
}
@@ -527,16 +514,19 @@
payload += base();
payload += ident();
- string tmp = del();
+ string tmp;
if (tmp.size() > constants::netcmd_minimum_bytes_to_bother_with_gzip)
{
payload += static_cast(1); // compressed flag
- tmp = xform(tmp);
+ gzip zdel;
+ encode_gzip(del, zdel);
+ tmp = zdel();
}
else
{
payload += static_cast(0); // compressed flag
+ tmp = del();
}
I(tmp.size() <= constants::netcmd_payload_limit);
insert_variable_length_string(tmp, payload);
--- netcmd.hh
+++ netcmd.hh
@@ -12,6 +12,7 @@
#include "merkle_tree.hh"
#include "numeric_vocab.hh"
#include "vocab.hh"
+#include "hmac.hh"
typedef enum
{
@@ -63,10 +64,9 @@
// basic cmd i/o (including checksums)
void write(std::string & out,
- netsync_session_key const & key,
- netsync_hmac_value & hmac_val) const;
+ chained_hmac & hmac) const;
bool read(std::string & inbuf,
- netsync_session_key const & key, netsync_hmac_value & hmac_val);
+ chained_hmac & hmac);
// i/o functions for each type of command payload
void read_error_cmd(std::string & errmsg) const;
--- netsync.cc
+++ netsync.cc
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#include
@@ -32,6 +33,7 @@
#include "xdelta.hh"
#include "epoch.hh"
#include "platform.hh"
+#include "hmac.hh"
#include "globish.hh"
#include "cryptopp/osrng.h"
@@ -246,7 +248,12 @@
Netxx::Stream str;
string inbuf;
- string outbuf;
+ // deque of pair
+ deque< pair > outbuf;
+ // the total data stored in outbuf - this is
+ // used as a valve to stop too much data
+ // backing up
+ size_t outbuf_size;
netcmd cmd;
bool armed;
@@ -255,8 +262,8 @@
id remote_peer_key_hash;
rsa_keypair_id remote_peer_key_name;
netsync_session_key session_key;
- netsync_hmac_value read_hmac;
- netsync_hmac_value write_hmac;
+ chained_hmac read_hmac;
+ chained_hmac write_hmac;
bool authenticated;
time_t last_io_time;
@@ -306,6 +313,8 @@
id mk_nonce();
void mark_recent_io();
+ void set_session_key(string const & key);
+
void setup_client_tickers();
bool done_all_refinements();
@@ -470,7 +479,7 @@
fd(sock),
str(sock, to),
inbuf(""),
- outbuf(""),
+ outbuf_size(0),
armed(false),
remote_peer_key_hash(""),
remote_peer_key_name(""),
@@ -611,6 +620,14 @@
}
void
+session::set_session_key(string const & key)
+{
+ session_key = netsync_session_key(key);
+ read_hmac.set_key(session_key);
+ write_hmac.set_key(session_key);
+}
+
+void
session::setup_client_tickers()
{
byte_in_ticker.reset(new ticker("bytes in", ">", 1024, true));
@@ -759,7 +776,12 @@
session::write_netcmd_and_try_flush(netcmd const & cmd)
{
if (!encountered_error)
- cmd.write(outbuf, session_key, write_hmac);
+ {
+ string buf;
+ cmd.write(buf, write_hmac);
+ outbuf.push_back(make_pair(buf, 0));
+ outbuf_size += buf.size();
+ }
else
L(F("dropping outgoing netcmd (because we're in error unwind mode)\n"));
// FIXME: this helps keep the protocol pipeline full but it seems to
@@ -1309,14 +1331,23 @@
session::write_some()
{
I(!outbuf.empty());
- Netxx::signed_size_type count = str.write(outbuf.data(),
- std::min(outbuf.size(),
+ size_t writelen = outbuf.front().first.size() - outbuf.front().second;
+ Netxx::signed_size_type count = str.write(outbuf.front().first.data() + outbuf.front().second,
+ std::min(writelen,
constants::bufsz));
if (count > 0)
{
- outbuf.erase(0, count);
- L(F("wrote %d bytes to fd %d (peer %s), %d remain in output buffer\n")
- % count % fd % peer_id % outbuf.size());
+ if ((size_t)count == writelen)
+ {
+ outbuf_size -= outbuf.front().first.size();
+ outbuf.pop_front();
+ }
+ else
+ {
+ outbuf.front().second += count;
+ }
+ L(F("wrote %d bytes to fd %d (peer %s)\n")
+ % count % fd % peer_id);
mark_recent_io();
if (byte_out_ticker.get() != NULL)
(*byte_out_ticker) += count;
@@ -1398,7 +1429,7 @@
cmd.write_anonymous_cmd(role, include_pattern, exclude_pattern,
hmac_key_encrypted);
write_netcmd_and_try_flush(cmd);
- session_key = netsync_session_key(nonce2());
+ set_session_key(nonce2());
}
void
@@ -1418,7 +1449,7 @@
cmd.write_auth_cmd(role, include_pattern, exclude_pattern, client,
nonce1, hmac_key_encrypted, signature);
write_netcmd_and_try_flush(cmd);
- session_key = netsync_session_key(nonce2());
+ set_session_key(nonce2());
}
void
@@ -1994,7 +2025,7 @@
load_priv_key(app, app.signing_key, our_priv);
string hmac_key;
decrypt_rsa(app.lua, app.signing_key, our_priv, hmac_key_encrypted, hmac_key);
- session_key = netsync_session_key(hmac_key);
+ set_session_key(hmac_key);
queue_confirm_cmd();
}
@@ -3138,9 +3169,11 @@
{
if (!armed)
{
- if (cmd.read(inbuf, session_key, read_hmac))
+ if (outbuf_size > constants::bufsz * 10)
+ return false; // don't pack the buffer unnecessarily
+
+ if (cmd.read(inbuf, read_hmac))
{
-// inbuf.erase(0, cmd.encoded_size());
armed = true;
}
}
--- revision.cc
+++ revision.cc
@@ -555,6 +555,12 @@
std::map< ctx, shared_bitmap >
parents, ancestors;
+ if (left == right)
+ {
+ anc = left;
+ return true;
+ }
+
ctx ln = intern.intern(left.inner()());
ctx rn = intern.intern(right.inner()());
--- tests/t_diff_currev.at
+++ tests/t_diff_currev.at
@@ -1,9 +1,7 @@
# -*- Autoconf -*-
AT_SETUP([diffing with explicit rev same as wc rev])
-AT_XFAIL_IF(true)
-
MONOTONE_SETUP
AT_DATA(foo1, [foo file 1
--- transforms.cc
+++ transforms.cc
@@ -157,10 +157,43 @@
return n;
}
+template
+void pack(T const & in, base64< gzip > & out)
+{
+ string tmp;
+ tmp.reserve(in().size()); // FIXME: do some benchmarking and make this a constant::
-// diffing and patching
+ CryptoPP::StringSource
+ str(in(), true,
+ new CryptoPP::Gzip(
+ new CryptoPP::Base64Encoder(
+ new CryptoPP::StringSink(tmp))));
+ out.swap(tmp);
+}
+template
+void unpack(base64< gzip > const & in, T & out)
+{
+ string tmp;
+ tmp.reserve(in().size()); // FIXME: do some benchmarking and make this a constant::
+ CryptoPP::StringSource
+ str(in(), true,
+ new CryptoPP::Base64Decoder(
+ new CryptoPP::Gunzip(
+ new CryptoPP::StringSink(tmp))));
+
+ out.swap(tmp);
+}
+
+// specialise them
+template void pack(data const &, base64< gzip > &);
+template void pack(delta const &, base64< gzip > &);
+template void unpack(base64< gzip > const &, data &);
+template void unpack(base64< gzip > const &, delta &);
+
+// diffing and patching
+
void
diff(data const & olddata,
data const & newdata,
--- transforms.hh
+++ transforms.hh
@@ -73,24 +73,22 @@
void decode_gzip(gzip const & in, T & out)
{ out = xform(in()); }
+// string variant for netsync
+template
+void encode_gzip(std::string const & in, gzip & out)
+{ out = xform(in); }
// both at once (this is relatively common)
template
-void pack(T const & in, base64< gzip > & out)
-{
- gzip tmp;
- encode_gzip(in, tmp);
- encode_base64(tmp, out);
-}
+void pack(T const & in, base64< gzip > & out);
+extern template void pack(data const &, base64< gzip > &);
+extern template void pack(delta const &, base64< gzip > &);
template
-void unpack(base64< gzip > const & in, T & out)
-{
- gzip tmp;
- decode_base64(in, tmp);
- decode_gzip(tmp, out);
-}
+void unpack(base64< gzip > const & in, T & out);
+extern template void unpack(base64< gzip > const &, data &);
+extern template void unpack(base64< gzip > const &, delta &);
// diffing and patching
--- vocab.hh
+++ vocab.hh
@@ -33,6 +33,8 @@
enc(std::string const & s); \
enc(INNER const & inner); \
enc(enc const & other); \
+ void swap(std::string & str) \
+ { i.swap(str); } \
std::string const & operator()() const \
{ return i(); } \
bool operator<(enc const & x) const \
@@ -86,6 +88,8 @@
ty(ty const & other); \
std::string const & operator()() const \
{ return s; } \
+ void swap(std::string & str) \
+ { s.swap(str); } \
bool operator<(ty const & other) const \
{ return s < other(); } \
ty const & operator=(ty const & other); \