monotone

monotone Mtn Source Tree

Root/contrib/mtbrowse.sh

  • Property mtn:execute set to true
1#!/bin/sh
2#
3# File: mtbrowse.sh
4# Description: Text based browser for monotone source control.
5# url: http://www.monotone.ca/
6# Licence: GPL
7# Author: Henry Nestler <Henry at BigFoot.de>
8#
9# Simple text based browser for Monotone repositories, written as shell script.
10# Can select branch, revision. Views diff from revision, logs, certs and more.
11# Base is dialog function and "automate" command of Monotone, with some
12# sorting and grepping functionaly.
13#
14# To use:
15# - Copy this script into a bin PATH
16# - Run from working copy of existing project.
17# Or give full filename to database.
18# - Change your configuration
19# Delete the "VISUAL", to use the "PAGER", deleto both for internal viewer.
20# Save configuration.
21# - Begin with menu "S Select revision"
22# - Browse in branches, revisions, diff files, view logs ...
23#
24# Needed tools:
25# Monotone (tested 0.19, 0.23, mtn 0.26-0.33)
26# dialog (tested Version 0.9b)
27# bash, sh, dash
28# less, vi or vim (use $VISUAL or $PAGER)
29# cat, cut, echo, eval, head, sort, tail, tr, wc, xargs ...
30#
31# Known Bugs / ToDo-List:
32# * better make "sed -n -e '1p'" for merge two different branches.
33
34VERSION="0.3.0"
35
36# Binary
37MTN="mtn"
38
39# Save users settings
40# Default values, can overwrite on .mtbrowserc
41CONFIGFILE="$HOME/.mtbrowserc"
42
43# Store lists for menu here
44TEMPDIR="$HOME/.mtbrowse"
45TEMPFILE="$TEMPDIR/tmp"
46
47# Called with filename.
48VISUAL="vim -R"
49
50# Called with stdin redirection.
51# Set VISUAL empty to use PAGER!
52# If VISUAL and PAGER are empty, than use an internal viewer.
53PAGER="less"
54
55# 1=Certs Cached, 0=Clean at end (slow and save mode)
56CACHE="1"
57
58# T=Toposort revisions, D=Date sort, R=Date reverse (reverse toposort),
59# N=None (unsorted from list)
60TOPOSORT="T"
61
62# count of certs to get from DB, "0" for all
63CERTS_MAX="20"
64
65# Trim hash code
66HASH_TRIM="10"
67
68# Format for Date/Time
69FORMAT_DATE="L"
70
71# Format Branch: F=Full,S=Short,N=None
72FORMAT_BRANCH="N"
73
74# Format author: F=Full, S=strip domain from mail address, N=None
75FORMAT_AUTHOR="S"
76
77# Changelog format
78FORMAT_LOG="F"
79
80# Author coloring?
81FORMAT_COLOR="\\Z7\\Zb"
82
83# How get automate ancestors: I=interal function, A=automate ancestors,
84# L=log brief with changelog, B=brief log
85ANCESTORS="L"
86
87# Don't view merges. Can overwrite in .mtbrowserc
88NOMERGES="--no-merges"
89
90# read saved settings
91if [ -f $CONFIGFILE ]
92then
93 . $CONFIGFILE
94fi
95
96# Clear cached files
97do_clear_cache()
98{
99 rm -f $TEMPFILE.certs.$BRANCH \
100 $TEMPFILE.changelog.$BRANCH
101}
102
103
104# clear temp files
105do_clear_on_exit()
106{
107 rm -f $TEMPFILE.branches $TEMPFILE.ancestors $TEMPFILE.toposort \
108 $TEMPFILE.action-select $TEMPFILE.menu $TEMPFILE.input \
109 $TEMPFILE.ncolor $TEMPFILE.tfc $TEMPFILE.error
110
111 if [ "$CACHE" != "1" ]
112 then
113do_clear_cache
114 fi
115}
116
117
118# View any file (with vim, less or dialog)
119do_pager()
120{
121 if [ -n "$VISUAL" ]
122 then
123$VISUAL $1
124 elif [ -n "$PAGER" ]
125 then
126$PAGER < $1
127 else
128dialog --textbox $1 0 0
129 fi
130 rm $1
131}
132
133
134# Add the date, author and changlog to the list of revisions
135
136# Scanning for:
137# Key : name@domain.de
138# Sig : ok
139# Name : date
140# Value : 2005-05-31T22:29:50<<---
141# --------------------------------------
142# Key : name@domain.de
143# Sig : ok
144# Name : changelog
145# Value : Handle merged parents<<---
146
147# Output
148# 123456 "2005-05-31 22:29 name@domain.de Handle merged parents"
149
150fill_date_key()
151{
152 local in_file=$1
153 local out_file=$2
154 local hash short_hash dat bra aut log lineno color tfc
155
156 line_count=`wc -l < $in_file`
157 if [ "$line_count" -eq 0 ]
158 then
159unset line_count
160 fi
161
162 lineno=0
163 rm -f $out_file
164 tfc=$TEMPFILE.tfc
165
166 # Read Key and Date value from certs
167 cat $in_file | \
168 while read hash
169 do
170if [ -n "$line_count" ]
171then
172 lineno=$(( $lineno+1 ))
173 echo "$(( 100*$lineno/$line_count ))"
174else
175 echo -n "." 1>&2
176fi
177
178short_hash=`echo $hash | cut -c 1-$HASH_TRIM`
179
180# get certs of revision, remove special chars, cache it
181LANG=POSIX $MTN --db=$DB list certs $hash | tr '\\\t\042' '/ \047' > $tfc
182
183# Date format
184case $FORMAT_DATE in
185 F) # 2005-12-31T23:59:59
186dat=`sed -n -r -e \
187 '/^Name : date/,+1s/Value : (.+)$/\1 /p' \
188 < $tfc | sed -n -e '1p'`
189;;
190 L) # 2005-12-31 23:59
191dat=`sed -n -r -e \
192 '/^Name : date/,+1s/Value : (.{10})T(.{5}).+$/\1 \2 /p' \
193 < $tfc | sed -n -e '1p'`
194;;
195 D) # 2005-12-31
196dat=`sed -n -r -e \
197 '/^Name : date/,+1s/Value : (.+)T.+$/\1 /p' \
198 < $tfc | sed -n -e '1p'`
199;;
200 S) # 12-31 23:59
201dat=`sed -n -r -e \
202 '/^Name : date/,+1s/Value : .{4}-(.+)T(.{5}).+$/\1 \2 /p' \
203 < $tfc | sed -n -e '1p'`
204;;
205 T) # 23:59:59
206dat=`sed -n -r -e \
207 '/^Name : date/,+1s/Value : .{10}T(.+{8})$/\1 /p' \
208 < $tfc | sed -n -e '1p'`
209;;
210esac
211
212# Branch format
213case $FORMAT_BRANCH in
214 F) # full
215bra=`sed -n -r -e \
216 '/^Name : branch/,+1s/Value :(.+)$/\1 /p' \
217 < $tfc | sed -n -e '1p'`
218;;
219 S) # short
220bra=`sed -n -r -e \
221 '/^Name : branch/,+1s/Value :.*\.([^\.]+)$/\1 /p' \
222 < $tfc | sed -n -e '1p'`
223;;
224esac
225
226# Author format
227case $FORMAT_AUTHOR in
228 F) # full
229aut=`sed -n -r -e \
230 '/^Name : author/,+1s/Value : (.+)$/\1/p' \
231 < $tfc | sed -n -e '1p'`
232;;
233 S) # short
234aut=`sed -n -r -e \
235 '/^Name : author/,+1s/Value : (.{1,10}).*[@ ].+$/\1/p' \
236 < $tfc | sed -n -e '1p'`
237;;
238esac
239
240# Changelog format
241case $FORMAT_LOG in
242 F) # full
243log=`sed -n -r -e \
244 '/^Name : changelog/,+1s/Value : (.+)$/ \1/p' \
245 < $tfc | sed -n -e '1p'`
246;;
247 S) # short
248log=`sed -n -r -e \
249 '/^Name : changelog/,+1s/Value : (.{1,20}).*$/ \1/p' \
250 < $tfc | sed -n -e '1p'`
251;;
252esac
253
254# Author coloring?
255if [ -n "$FORMAT_COLOR" -a "$FORMAT_AUTHOR" != "N" ]
256then
257 # Bug in dialog: Don't allow empty string after \\Zn
258 test -z "$log" && log=" "
259
260 if [ "$last_aut" != "$aut" ]
261 then
262 # Automatic color by author?
263 if [ "$FORMAT_COLOR" = "A" ]
264 then
265color=`grep -n "$aut" $TEMPFILE.ncolor | cut -d ':' -f 1`
266if [ -z "$color" ]
267then
268 color=$(( `wc -l < $TEMPFILE.ncolor` % 16 + 1 ))
269 echo "$aut" >> $TEMPFILE.ncolor
270fi
271
272if [ $color -le 8 ]
273then
274 color="\\Zb\\Z$color"
275else
276 color8=$(( $color - 8 ))
277 color="\\Z$color8"
278fi
279 else
280color="$FORMAT_COLOR"
281 fi
282 last_aut="$aut"
283 fi
284 echo "$short_hash \"$dat$bra\\ZR$color$aut\\Zn$log\"" \
285>> $out_file
286else
287 echo "$short_hash \"$dat$bra\\ZR$aut$log\"" >> $out_file
288fi
289 done | dialog --gauge "$line_count certs reading" 6 60
290 rm $tfc
291}
292
293do_log_brief_ancestors()
294{
295 local out_file=$1
296 local hash short_hash dat bra aut lineno color
297
298 # Brief output
299 # e51dc90425c6371a176e87df294b47fcdba3f0bb Full Name <name@domain.de> 2005-11-20T20:31:34 mtbrowse
300
301 lineno=0
302 $MTN log --brief --last=$CERTS_MAX $ARG_FROM=$HEAD --db=$DB $NO_GRAPH $NOMERGES |\
303 while read line
304 do
305lineno=$(( $lineno+1 ))
306# TODO: Why MT give more than "--last"?
307if [ $lineno -le $CERTS_MAX ]
308then
309 echo "$(( 100*$lineno/$CERTS_MAX ))"
310fi
311
312set -- `echo "$line" | sed -n -r -e 's/^([^ ]+) (.+) ([0-9\-]{10})T([0-9:]{8}) (.+)$/\1 \3 \4 \5/p'`
313author=`echo "$line" | sed -n -r -e 's/^([^ ]+) (.+) ([0-9\-]{10})T([0-9:]{8}) (.+)$/\2/p'`
314hash=$1
315date=$2
316time=$3
317branch="$4"
318
319# Skip wrong formats, special case
320# 37416b924fc25a48bba11ed8b2cd62e9dab7e637 First Name <name@domain.de>,name2@domain.com.au,third@domain.org 2006-01-20T08:21:37,2006-01-20T08:35:46,2006-01-20T08:35:33 net.venge.monotone
321
322if [ -n "$hash" -a -n "$date" -a -n "$time" -a -n "$author" ]
323then
324
325 short_hash=`echo $hash | cut -c 1-$HASH_TRIM`
326
327 # Date format
328 case $FORMAT_DATE in
329 F) # 2005-12-31T23:59:59
330dat="${date}T$time "
331;;
332 L) # 2005-12-31 23:59
333dat="`echo "$date $time" | cut -c 1-16` "
334;;
335 D) # 2005-12-31
336dat=$date
337;;
338 S) # 12-31 23:59
339dat=`echo "$date $time" | sed -n -r -e \
340 '.{4}-(.+) (.{5}).+/\1 \2 /p'`
341;;
342 T) # 23:59:59
343dat=$time
344;;
345 esac
346
347 # Branch format
348 case $FORMAT_BRANCH in
349 F) # full
350bra=$branch
351;;
352 S) # short
353bra=`echo "$branch" | sed -n -r -e \
354 '/.*\.([^\.]+)$/\1 /p' `
355;;
356 esac
357
358 # Author format
359 case $FORMAT_AUTHOR in
360 F) # full
361aut="$author"
362;;
363 S) # short
364aut=`echo "$author " | sed -n -r -e \
365 's/(.{1,10}).*[@ ].+$/\1/p'`
366;;
367 esac
368
369 # TODO: Copied from fill_date_key
370 # Author coloring?
371 if [ -n "$FORMAT_COLOR" -a "$FORMAT_AUTHOR" != "N" ]
372 then
373if [ "$last_aut" != "$aut" ]
374then
375 # Automatic color by author?
376 if [ "$FORMAT_COLOR" = "A" ]
377 then
378color=`grep -n "$aut" $TEMPFILE.ncolor | cut -d ':' -f 1`
379if [ -z "$color" ]
380then
381 color=$(( `wc -l < $TEMPFILE.ncolor` % 16 + 1 ))
382 echo "$aut" >> $TEMPFILE.ncolor
383fi
384
385if [ $color -le 8 ]
386then
387 color="\\Zb\\Z$color"
388else
389 color8=$(( $color - 8 ))
390 color="\\Z$color8"
391fi
392 else
393color="$FORMAT_COLOR"
394 fi
395 last_aut="$aut"
396fi
397echo "$short_hash \"$dat$bra\\ZR$color$aut\"" >> $out_file
398 else
399echo "$short_hash \"$dat$bra\\ZR$aut\"" >> $out_file
400 fi
401fi
402 done | dialog --gauge "$CERTS_MAX certs reading" 6 60
403}
404
405# Select a branch
406# Is parameter given: No user select, if branch known.
407do_branch_sel()
408{
409 local OLD_BRANCH
410
411 if [ ! -f "$DB" ]
412 then
413echo "$DB: File not found! (mtbrowse)"
414exit 1
415 fi
416
417 if [ ! -r "$DB" ]
418 then
419echo "$DB: Can't read file! (mtbrowse)"
420exit 1
421 fi
422
423 SHORT_DB=`basename $DB`
424
425 # is Branch set, than can return
426 if [ -n "$BRANCH" -a -n "$1" ]
427 then
428return
429 fi
430
431 # New DB?
432 if [ "$DB" != "`cat $TEMPFILE.fname`" ]
433 then
434echo "$DB" > $TEMPFILE.fname
435unset BRANCH
436 fi
437
438 OLD_BRANCH=$BRANCH
439
440 # Get branches from DB
441 if [ ! -f $TEMPFILE.branches -o $DB -nt $TEMPFILE.branches \
442-o "$CACHE" != "1" ]
443 then
444$MTN --db=$DB list branches \
445 | sed -n -r -e 's/^(.+)$/\1\t-/p' > $TEMPFILE.branches \
446 || exit 200
447 fi
448
449 if [ ! -s $TEMPFILE.branches ]
450 then
451echo "Error: No branches found."
452exit 1
453 fi
454
455 dialog --begin 1 2 \
456--default-item "$OLD_BRANCH" \
457--menu "Select branch" 0 0 0 \
458`cat $TEMPFILE.branches` \
4592> $TEMPFILE.input
460 BRANCH=`cat $TEMPFILE.input`
461
462 # Clear Head, if branch changed
463 if [ "$OLD_BRANCH" != "$BRANCH" ]
464 then
465# Clear cached files
466do_clear_cache
467do_clear_on_exit
468unset HEAD
469unset SHORT_HEAD
470 fi
471}
472
473
474# Get head from DB (need for full log)
475# Is parameter given: No user select, if head known.
476do_head_sel()
477{
478 # is Head set, than can return
479 if [ -n "$HEAD" -a -n "$1" ]
480 then
481return
482 fi
483
484 if ! $MTN --db=$DB automate heads $BRANCH > $TEMPFILE.heads 2>$TEMPFILE.error
485 then
486cat $TEMPFILE.error
487exit -1
488 fi
489
490 # Only one head ?
491 if [ `wc -l < $TEMPFILE.heads` -eq 1 -a -n "$1" ]
492 then
493HEAD=`head -n 1 < $TEMPFILE.heads`
494 else
495# List heads with author and date. Select by user.
496$MTN --db=$DB heads --branch=$BRANCH \
497 | sed -n -r -e 's/^([^ ]+) ([^ ]+) ([^ ]+)$/\1 \"\2 \3\"/p' \
498 | xargs dialog --begin 1 2 --menu "Select head" 0 0 0 \
499 2> $TEMPFILE.input
500HEAD=`cat $TEMPFILE.input`
501 fi
502
503 # trim for some outputs
504 SHORT_HEAD=`echo $HEAD | cut -c 1-$HASH_TRIM`
505
506 rm -f $TEMPFILE.heads
507}
508
509
510# User menu for current branch
511do_action_sel()
512{
513 # Action-Menu
514 while dialog \
515--backtitle "h:$HEAD b:$BRANCH f:$SHORT_DB" \
516--menu "Action for $REVISION" 0 60 0 \
517"L" "Logview of current revision" \
518"P" "Diff files from parent" \
519"W" "Diff files from working copy head" \
520"S" "Diff files from selected revision" \
521"C" "List Certs" \
522"F" "List changed file revision" \
523"-" "-" \
524"Q" "Return" \
5252> $TEMPFILE.action-select
526 do
527
528case `cat $TEMPFILE.action-select` in
529 L)
530 # LOG
531 # 0.19 monotone log --depth=n --revision=id
532 # 0.19+ monotone log --last=n --revision=id
533 # 0.29 monotone log --last=n --revision=id
534 # 0.33 monotone log --last=n --from=id --no-graph
535 $MTN --db=$DB log $DEPTH_LAST=1 $ARG_FROM=$REVISION $NO_GRAPH \
536 > $TEMPFILE.change.log || exit 200
537
538 do_pager $TEMPFILE.change.log
539 ;;
540 P)
541 # DIFF parent
542 $MTN --db=$DB automate parents $REVISION > $TEMPFILE.parents
543
544 if [ `wc -l < $TEMPFILE.parents` -ne 1 ]
545 then
546# multiple parents (from merge)
547
548# Create, if used a cached list
549touch $TEMPFILE.ncolor
550
551# Set DATE/KEY information
552fill_date_key $TEMPFILE.parents $TEMPFILE.certs3tmp
553
554cat $TEMPFILE.certs3tmp | \
555 xargs dialog --begin 1 2 --colors \
556--default-item "$PARENT" \
557--menu "Select parent for $REVISION" 0 0 0 \
5582> $TEMPFILE.input \
559&& PARENT=`cat $TEMPFILE.input`
560rm $TEMPFILE.certs3tmp
561 else
562# Single parent only
563PARENT=`cat $TEMPFILE.parents`
564 fi
565 rm $TEMPFILE.parents
566
567 if [ -z "$PARENT" ]
568 then
569dialog --msgbox "No parent found\n$REVISION" 6 45
570 else
571$MTN --db=$DB diff \
572 --revision=$PARENT --revision=$REVISION \
573 > $TEMPFILE.parent.diff || exit 200
574do_pager $TEMPFILE.parent.diff
575 fi
576 ;;
577 W)
578 # DIFF
579 # $MTN diff --revision=id
580 if [ "$HEAD" = "$REVISION" ]
581 then
582dialog --msgbox "Can't diff with head self\n$HEAD" 6 45
583 else
584# exist working copy?
585if [ -f $BK_DIR/options ]
586then
587 $MTN --db=$DB diff \
588 --revision=$REVISION \
589 > $TEMPFILE.cwd.diff || exit 200
590else
591 # w/o MT dir don't work:
592 # Help MT with HEAD info ;-)
593 $MTN --db=$DB diff \
594 --revision=$HEAD --revision=$REVISION \
595 > $TEMPFILE.cwd.diff || exit 200
596fi
597do_pager $TEMPFILE.cwd.diff
598 fi
599 ;;
600 S)
601 # DIFF2: from other revision (not working dir)
602 # Select second revision
603 if cat $TEMPFILE.certs.$BRANCH | \
604 xargs dialog --default-item "$REV2" --colors --menu \
605 "Select _older_ revision for branch:$BRANCH\nrev:$REVISION" \
606 0 0 0 2> $TEMPFILE.revision-select
607 then
608REV2=`cat $TEMPFILE.revision-select`
609
610# $MTN diff --revision=id1 --revision=id2
611$MTN --db=$DB diff \
612 --revision=$REV2 --revision=$REVISION \
613 > $TEMPFILE.ref.diff || exit 200
614do_pager $TEMPFILE.ref.diff
615 fi
616 rm -f $TEMPFILE.revision-select
617 ;;
618 C)
619 # List certs
620 $MTN --db=$DB list certs $REVISION > $TEMPFILE.certs.log \
621 || exit 200
622 do_pager $TEMPFILE.certs.log
623 ;;
624 F)
625 # List changed files
626 # 0.22: monotone cat revision <id>
627 # 0.23: monotone automate get_revision <id>
628 $MTN --db=$DB automate get_revision $REVISION > $TEMPFILE.rev.changed \
629 || exit 200
630 do_pager $TEMPFILE.rev.changed
631 ;;
632 Q)
633 # Menu return
634 return
635 ;;
636esac
637 done
638}
639
640# Get parents recursive.
641# Same as automate ancestors, but limit the depth
642# Function called recursive!
643do_automate_ancestors_depth()
644{
645locale depth head rev
646
647depth=$1
648head=$2
649
650# Empty parm?
651if [ -z "$depth" -o -z "$depth" ]
652then
653return 0
654fi
655
656# Limit by depth?
657if [ "$depth" -gt $CERTS_MAX -o "$depth" -gt 200 ]
658then
659return 0
660fi
661
662depth=$(( $depth+1 ))
663$MTN --db=$DB automate parents $head |\
664while read rev
665do
666 if ! grep -q -l -e "$rev" $TEMPFILE.ancestors
667 then
668echo "$rev" >> $TEMPFILE.ancestors
669do_automate_ancestors_depth $depth $rev || return $?
670 fi
671done
672depth=$(( $depth-1 ))
673
674return 0
675}
676
677# Select a revision
678do_revision_sel()
679{
680 local SHORT_REV
681
682 # if branch or head not known, ask user
683 echo "branch check..."
684 do_branch_sel check
685 echo "head check..."
686 do_head_sel check
687
688 # Building revisions list
689 if [ ! -f $TEMPFILE.certs.$BRANCH -o $DB -nt $TEMPFILE.certs.$BRANCH ]
690 then
691# Name color new
692rm -f $TEMPFILE.ncolor
693touch $TEMPFILE.ncolor
694
695echo "Reading ancestors ($HEAD)"
696
697case $ANCESTORS in
698 B)# TODO:
699# Get ancestors from log, brief format
700do_log_brief_ancestors $TEMPFILE.certs3tmp
701 ;;
702 L)
703# Get ancestors from log
704$MTN log --brief --last=$CERTS_MAX $ARG_FROM=$HEAD $NO_GRAPH $NOMERGES \
705 --db=$DB | cut -d ' ' -f 1 > $TEMPFILE.ancestors
706# Check empty output, if fails
707test -s $TEMPFILE.ancestors || exit 200
708 ;;
709 I)
710# Get only 'CERTS_MAX' of ancestors
711echo "$HEAD" > $TEMPFILE.ancestors
712do_automate_ancestors_depth 1 $HEAD || exit 200
713 ;;
714 *)
715# Get all ancestors
716echo "$HEAD" > $TEMPFILE.ancestors
717$MTN --db=$DB automate ancestors $HEAD \
718 >> $TEMPFILE.ancestors || exit 200
719 ;;
720esac
721
722if [ "$ANCESTORS" != "B" ]
723then
724 # Must toposort, if enabled by user, or before tailing
725 if [ "$TOPOSORT" = "T" -o "$CERTS_MAX" -gt 0 -a "$ANCESTORS" != "L" ]
726 then
727echo "Toposort..."
728$MTN --db=$DB automate toposort `cat $TEMPFILE.ancestors` \
729 > $TEMPFILE.toposort || exit 200
730
731if [ "$CERTS_MAX" -gt 0 ]
732then
733# Only last certs. Remember: Last line is newest!
734tail -n "$CERTS_MAX" < $TEMPFILE.toposort \
735 > $TEMPFILE.toposort2
736mv $TEMPFILE.toposort2 $TEMPFILE.toposort
737fi
738 else
739mv $TEMPFILE.ancestors $TEMPFILE.toposort
740 fi
741
742 # Reading revisions and fill with date, names and changelog
743 fill_date_key $TEMPFILE.toposort $TEMPFILE.certs3tmp
744fi
745
746case $TOPOSORT in
747 D)
748# Sort by date+time
749sort -k 2 < $TEMPFILE.certs3tmp > $TEMPFILE.certs.$BRANCH
750rm $TEMPFILE.certs3tmp
751 ;;
752 R)
753# Reverse sort by date+time
754sort -k 2 -r < $TEMPFILE.certs3tmp > $TEMPFILE.certs.$BRANCH
755rm $TEMPFILE.certs3tmp
756 ;;
757 *)
758# Not sorted, or toposort
759mv $TEMPFILE.certs3tmp $TEMPFILE.certs.$BRANCH
760 ;;
761esac
762 fi
763
764 # if first rev is empty, use head instand
765 if [ -z "$REVISION" ]
766 then
767SHORT_REV=`echo $HEAD | cut -c 1-$HASH_TRIM`
768 else
769SHORT_REV=`echo $REVISION | cut -c 1-$HASH_TRIM`
770 fi
771
772 # Select revision
773 while cat $TEMPFILE.certs.$BRANCH | \
774xargs dialog \
775 --backtitle "h:$HEAD b:$BRANCH f:$SHORT_DB" \
776 --no-shadow \
777 --colors \
778 --default-item "$SHORT_REV" \
779 --menu "Select revision for branch:$BRANCH" \
780 0 0 0 2> $TEMPFILE.revision-select
781 do
782SHORT_REV=`cat $TEMPFILE.revision-select`
783
784# Remove old marker, set new marker
785if [ "$FORMAT_DATE" = "N" -a "$FORMAT_BRANCH" = "N" ]
786then
787 sed -r \
788-e "s/^(.+\")\*(.+)\$/\1\2/" \
789-e "s/^($SHORT_REV.* \")(.+)\$/\1\*\2/" \
790< $TEMPFILE.certs.$BRANCH > $TEMPFILE.marker
791else
792 sed -r \
793-e "s/^(.+\")\\\\Zr(.+)\$/\1\2/" \
794-e "s/^($SHORT_REV.* \")(.+)\$/\1\\\\Zr\2/" \
795< $TEMPFILE.certs.$BRANCH > $TEMPFILE.marker
796fi
797mv $TEMPFILE.marker $TEMPFILE.certs.$BRANCH
798
799# Error, on "monotone automate parents XXXXXX", if short revision. :-(
800# Expand revision here, if short revision (is alway short now)
801REVISION=`$MTN --db=$DB complete revision $SHORT_REV`
802
803# OK Button: Sub Menu
804do_action_sel
805 done
806 rm -f $TEMPFILE.revision-select
807}
808
809
810# Menu for configuration
811do_config()
812{
813 local item
814
815 while dialog --default-item "$item" \
816--menu "Configuration" 0 0 0 \
817"V" "VISUAL [$VISUAL]" \
818"Vd" "Set VISUAL default to vim -R" \
819"P" "PAGER [$PAGER]" \
820"Pd" "set PAGER default to less" \
821"T" "Time and date format [$FORMAT_DATE]" \
822"B" "Branch format [$FORMAT_BRANCH]" \
823"A" "Author format [$FORMAT_AUTHOR]" \
824"Ac" "Author Color format [$FORMAT_COLOR]" \
825"L" "changeLog format [$FORMAT_LOG]" \
826"C" "Certs limit in Select-List [$CERTS_MAX]" \
827"D" "Depth limit for ancestors [$ANCESTORS]" \
828"S" "Sort by Toposort, Date or none [$TOPOSORT]" \
829"-" "-" \
830"W" "Write configuration file" \
831"R" "Return to main menu" \
8322> $TEMPFILE.menu
833 do
834item=`cat $TEMPFILE.menu`
835case $item in
836 V)
837 # Setup for VISUAL
838 if dialog --inputbox \
839"Config for file viewer\nuse in sample: \"vim -R changes.diff\"" \
8409 70 "$VISUAL" 2> $TEMPFILE.input
841 then
842VISUAL=`cat $TEMPFILE.input`
843 fi
844 ;;
845 Vd)
846 # set Visual default
847 VISUAL="vim -R"
848 ;;
849 P)
850 # Setup for PAGER
851 if dialog --inputbox \
852"Config for pipe pager\nuse in sample: \"$MTN log | less\"" \
8539 70 "$PAGER" 2> $TEMPFILE.input
854 then
855PAGER=`cat $TEMPFILE.input`
856 fi
857 ;;
858 Pd)
859 # set Pager default
860 PAGER="less"
861 ;;
862 S)
863 # change T=Toposort revisions, D=Date sort, N=None (from list)
864 if dialog --default-item "$TOPOSORT" \
865--menu "Sort revisions by" 0 0 0 \
866"T" "Toposort, oldest top (from Monotone)" \
867"D" "Date/Time, oldest top (internal function)" \
868"R" "Reverse Date/Time (reverse toposort)" \
869"N" "None. Simple get from list" \
8702> $TEMPFILE.input
871 then
872TOPOSORT=`cat $TEMPFILE.input`
873 fi
874 ;;
875 T)
876 # change date/time format
877 if dialog --default-item "$FORMAT_DATE" \
878--menu "Format for date and time" 0 0 0 \
879"F" "2005-12-31T23:59:59 -- Full date and time" \
880"L" "2005-12-31 23:59 -- Long date and time" \
881"D" "2005-21-31 -- Date only" \
882"S" "12-31 23:59:59 -- Short date and time" \
883"T" "23:59:59 -- Time only" \
884"N" "no date and no time" \
8852> $TEMPFILE.input
886 then
887FORMAT_DATE=`cat $TEMPFILE.input`
888 fi
889 ;;
890 B)
891 # change branch format
892 if dialog --default-item "$FORMAT_BRANCH" \
893--menu "Format for branch" 0 0 0 \
894"F" "Full branch" \
895"S" "Short branch, right side only" \
896"N" "no branch" \
8972> $TEMPFILE.input
898 then
899FORMAT_BRANCH=`cat $TEMPFILE.input`
900 fi
901 ;;
902 A)
903 # change author's format
904 if dialog --default-item "$FORMAT_AUTHOR" \
905--menu "Format for author" 0 0 0 \
906"F" "Full author" \
907"S" "Short author, strip domain from email address" \
908"N" "no author" \
9092> $TEMPFILE.input
910 then
911FORMAT_AUTHOR=`cat $TEMPFILE.input`
912 fi
913 ;;
914 Ac)
915 # Author coloring
916 if dialog --default-item \
917"`test -n \"$FORMAT_COLOR\" && echo \"yes\" || echo \"no\"`" \
918--menu "Color author in selection" 0 0 0 \
919"yes" "author is color" \
920"no" "author has no special color" \
9212> $TEMPFILE.input
922 then
923if [ "`cat $TEMPFILE.input`" = "yes" ]
924then
925 dialog --colors \
926 --default-item "$FORMAT_COLOR" \
927 --menu "Select color for author" 0 0 0 \
928"A" "Automatic color" \
929"\\Z0" "\Z0Color\Zn 0" \
930"\\Z1" "\Z1Color\Zn 1" \
931"\\Z2" "\Z2Color\Zn 2" \
932"\\Z3" "\Z3Color\Zn 3" \
933"\\Z4" "\Z4Color\Zn 4" \
934"\\Z5" "\Z5Color\Zn 5" \
935"\\Z6" "\Z6Color\Zn 6" \
936"\\Z7" "\Z7Color\Zn 7" \
937"\\Zb\\Z0" "\Zb\Z0Color\Zn 0b" \
938"\\Zb\\Z1" "\Zb\Z1Color\Zn 1b" \
939"\\Zb\\Z2" "\Zb\Z2Color\Zn 2b" \
940"\\Zb\\Z3" "\Zb\Z3Color\Zn 3b" \
941"\\Zb\\Z4" "\Zb\Z4Color\Zn 4b" \
942"\\Zb\\Z5" "\Zb\Z5Color\Zn 5b" \
943"\\Zb\\Z6" "\Zb\Z6Color\Zn 6b" \
944"\\Zb\\Z7" "\Zb\Z7Color\Zn 7b" \
945"\\Zb" "\ZbBold\Zn b" \
946"\\Zu" "\ZuUnderline\Zn u" \
9472> $TEMPFILE.input \
948 && FORMAT_COLOR=`cat $TEMPFILE.input`
949else
950 FORMAT_COLOR=""
951fi
952 fi
953 ;;
954 L)
955 # Changelog format
956 dialog \
957--default-item "$FORMAT_LOG" \
958--menu "Format for ChangeLog in selection" 0 0 0 \
959"F" "Full changelog line" \
960"S" "Short changelog" \
961"N" "no changelog in selection" \
9622> $TEMPFILE.input \
963&& FORMAT_LOG=`cat $TEMPFILE.input`
964 ;;
965 D)
966 # How to get ancestors
967 if dialog --default-item "$ANCESTORS" \
968--menu "Get ancestors by using" 0 0 0 \
969"B" "Brief log, without changelog (fastest)" \
970"L" "Monotone \"log --brief\" with changelog" \
971"I" "Internal function with depth limit (faster)" \
972"A" "Monotone \"automate ancestor\" (save mode, very slow)" \
9732> $TEMPFILE.input
974 then
975ANCESTORS=`cat $TEMPFILE.input`
976
977if [ "$ANCESTORS" = "A" ]
978then
979 # functions don't work with big database
980 dialog --title " Info " --msgbox \
981"\"automate ancestor\":
982
983Big database can overflow command line.
984It's saver to use internal function (I)." 0 0
985fi
986 fi
987 ;;
988 C)
989 # Change CERTS_MAX
990 dialog --inputbox \
991 "Set maximum lines for revision selction menu\n(0=disabled)" \
992 9 70 "$CERTS_MAX" 2> $TEMPFILE.input \
993 && CERTS_MAX=`cat $TEMPFILE.input`
994 ;;
995 W)
996 # Save environment
997 cat > $CONFIGFILE << EOF
998# File: ~/.mtbrowserc
999# Created for Monotone $MT_MAJOR.$MT_MINOR
1000
1001DB="$DB"
1002BRANCH="$BRANCH"
1003VISUAL="$VISUAL"
1004PAGER="$PAGER"
1005TEMPDIR="$TEMPDIR"
1006TEMPFILE="$TEMPFILE"
1007TOPOSORT="$TOPOSORT"
1008CACHE="$CACHE"
1009CERTS_MAX="$CERTS_MAX"
1010FORMAT_DATE="$FORMAT_DATE"
1011FORMAT_BRANCH="$FORMAT_BRANCH"
1012FORMAT_AUTHOR="$FORMAT_AUTHOR"
1013FORMAT_LOG="$FORMAT_LOG"
1014FORMAT_COLOR="$FORMAT_COLOR"
1015ANCESTORS="$ANCESTORS"
1016NOMERGES="$NOMERGES"
1017EOF
1018dialog --title " Info " --sleep 2 --infobox \
1019 "Configration wrote to\n$CONFIGFILE" 0 0
1020 echo "config saved"
1021 ;;
1022 *)
1023 # Return to Main
1024 rm -f $TEMPFILE.input
1025 return
1026 ;;
1027esac
1028
1029# Check non working combinations
1030if [ $ANCESTORS = "L" -a \( $MT_MAJOR -eq 0 -a $MT_MINOR -lt 20 \) ]
1031then
1032 dialog --title " Info " --msgbox \
1033"\"log brief\" is only supported on Monotone version 0.20 or newer
1034Automatic corrected" 0 0
1035 ANCESTORS="I"
1036fi
1037
1038if [ "$CERTS_MAX" -le 0 -a "$ANCESTORS" != "A" ]
1039then
1040 # functions don't work without limit
1041 dialog --title " Info " --msgbox \
1042"Certs limit in Select-List:
1043
1044Negative or zero limit not allowed
1045Automatic corrected" 0 0
1046 CERTS_MAX=20
1047fi
1048
1049if [ \( "$TOPOSORT" = "D" -o "$TOPOSORT" = "R" \) -a "$FORMAT_DATE" = "N" ]
1050then
1051 dialog --title " Info " --msgbox \
1052"\"Sort Date/Time\" is not usable, if no time in list
1053Automatic corrected" 0 0
1054 FORMAT_DATE="L"
1055fi
1056 done
1057}
1058
1059# Is dialog installed?
1060if ! dialog --version </dev/null >/dev/null 2>&1
1061then
1062 # Hm, need this here
1063 echo
1064 echo "dialog - display dialog boxes from shell scripts."
1065 echo "Dialog is needed for this tool, please install it!"
1066 echo
1067 exit -1
1068fi
1069
1070# Save args
1071arg1=$1
1072
1073# Check for binary
1074if [ -z "`which $MTN 2>/dev/null`" ]
1075then
1076 if [ -n "`which monotone 2>/dev/null`" ]
1077 then
1078# fall back to older binary name
1079MTN="monotone"
1080 fi
1081fi
1082
1083# Get $MTN version
1084set -- `$MTN --version | sed -n -r -e 's/^.+ ([0-9]+)\.([0-9]+).+$/\1 \2/p'`
1085MT_MAJOR=$1
1086MT_MINOR=$2
1087
1088if [ -z "$MT_MAJOR" -o -z "$MT_MINOR" ]
1089then
1090 # Hm, need this here
1091 echo
1092 echo "$MTN - distributed version control system."
1093 echo "Can't execute!"
1094 echo
1095 exit -1
1096fi
1097
1098# "log --depth=n" was changed to "log --last=n" in 0.20
1099# 0.19 monotone log --depth=n
1100# 0.20+ monotone log --last=n
1101if [ $MT_MAJOR -eq 0 -a $MT_MINOR -lt 20 ]
1102then
1103 DEPTH_LAST="--depth"
1104else
1105 DEPTH_LAST="--last"
1106fi
1107
1108# New bookkeeping directory is _MTN, in 0.26+
1109if [ $MT_MAJOR -eq 0 -a $MT_MINOR -lt 26 ]
1110then
1111 BK_DIR="MT"
1112else
1113 BK_DIR="_MTN"
1114fi
1115
1116# "log --revision=n" was changed to "log --from=n" in 0.32
1117if [ $MT_MAJOR -eq 0 -a $MT_MINOR -lt 32 ]
1118then
1119 ARG_FROM="--revision"
1120else
1121 ARG_FROM="--from"
1122fi
1123
1124# "log --no-graph" need for 0.33
1125if [ $MT_MAJOR -eq 0 -a $MT_MINOR -lt 33 ]
1126then
1127 NO_GRAPH=""
1128else
1129 NO_GRAPH="--no-graph"
1130fi
1131
1132# exist working copy?
1133if [ -f $BK_DIR/options ]
1134then
1135 # Read parameters from file
1136 # branch "mtbrowse"
1137 #database "/home/hn/mtbrowse.db"
1138 # key ""
1139
1140 eval `sed -n -r \
1141 -e 's/^[ ]*(branch) \"([^\"]+)\"$/\1=\2/p' \
1142 -e 's/^[ ]*(database) \"([^\"]+)\"$/\1=\2/p' < $BK_DIR/options`
1143
1144 if [ -n "$database" ]
1145 then
1146DB=$database
1147BRANCH=$branch
1148 fi
1149fi
1150
1151
1152# Simple program args supported
1153if [ -n "$arg1" ]
1154then
1155 case $arg1 in
1156 --version)
1157echo "mtbrowse $VERSION"
1158exit 0
1159 ;;
1160 --help|-h)
1161echo "mtbrowse [dbfile]"
1162exit 0
1163 ;;
1164 *)
1165# Databasefile from command line
1166DB="$arg1"
1167unset BRANCH
1168
1169# MT change the options, if you continue with other DB here!
1170if [ -f $BK_DIR/options ]
1171then
1172 if ! dialog --cr-wrap \
1173--title " *********** WARNING! ********** " \
1174--defaultno --colors --yesno "
1175Your \Zb\Z1$BK_DIR/options\Zn will be overwrite, if
1176continue with different DB file or branch
1177in exist working directory!
1178
1179YES confirm / NO abbort" 0 0
1180 then
1181echo "abbort"
1182exit 1
1183 fi
1184fi
1185 ;;
1186 esac
1187fi
1188
1189mkdir -p $TEMPDIR
1190
1191while dialog \
1192--cancel-label "Exit" \
1193--backtitle "$DB" \
1194--menu "Main - mtbrowse v$VERSION" 0 0 0 \
1195"S" "Select revision" \
1196"I" "Input revision" \
1197"F" "Change DB File [`basename $DB`]" \
1198"B" "Branch select [$BRANCH]" \
1199"H" "Head select [$SHORT_HEAD]" \
1200"R" "Reload DB, clear cache" \
1201"-" "-" \
1202"l" "Sumary complete log" \
1203"t" "List Tags" \
1204"h" "List Heads" \
1205"k" "List Keys" \
1206"-" "-" \
1207"C" "Configuration" \
1208"-" "-" \
1209"X" "eXit" \
12102> $TEMPFILE.menu
1211do
1212 case `cat $TEMPFILE.menu` in
1213 S)
1214# Revision selection
1215do_revision_sel
1216;;
1217 I)
1218# Input Revision
1219if dialog --inputbox \
1220 "Input 5 to 40 digits of known revision" 8 60 "$REVISION" \
1221 2> $TEMPFILE.input
1222then
1223 REVISION=`cat $TEMPFILE.input`
1224
1225 if [ `echo "$REVISION" | wc -L` -lt 40 ]
1226 then
1227# Error, on "$MTN automate parents XXXXXX", if short revision. :-(
1228# Expand revision here, if short revision
1229REVISION=`$MTN --db=$DB complete revision $REVISION`
1230 fi
1231
1232 do_action_sel
1233 do_revision_sel
1234fi
1235;;
1236 R)
1237# Cache del and Revision selection
1238do_clear_cache
1239do_revision_sel
1240;;
1241 B)
1242# Branch config
1243rm -f $TEMPFILE.branches
1244do_branch_sel
1245;;
1246 H)
1247 # Select head
1248# if branch or head not known, ask user
1249do_branch_sel check
1250do_head_sel
1251do_clear_cache
1252;;
1253 F)
1254# Change DB file
1255DNAME=`dirname $DB`
1256if [ -z "$DNAME" ]
1257then
1258 DNAME=`pwd`
1259fi
1260
1261if dialog --fselect $DNAME/`basename $DB` 15 70 2> $TEMPFILE.name-db
1262then
1263 DB=`cat $TEMPFILE.name-db`
1264 dialog --msgbox "file changed to\n$DB" 0 0
1265 unset BRANCH
1266else
1267 dialog --msgbox "filename unchanged" 0 0
1268fi
1269rm -f $TEMPFILE.name-db
1270;;
1271 C)
1272do_config
1273# Clear cache
1274do_clear_cache
1275;;
1276 l)
1277# Sumary complete LOG
1278# if not branch known, ask user
1279do_branch_sel check
1280do_head_sel check
1281
1282if [ ! -f $TEMPFILE.changelog.$BRANCH -o \
1283 $DB -nt $TEMPFILE.changelog.$BRANCH ]
1284then
1285 echo "Reading log...($BRANCH)"
1286 $MTN --db=$DB log $ARG_FROM=$HEAD $NO_GRAPH \
1287 > $TEMPFILE.changelog.$BRANCH || exit 200
1288fi
1289cp $TEMPFILE.changelog.$BRANCH $TEMPFILE.change.log
1290do_pager $TEMPFILE.change.log
1291;;
1292 t)
1293# List Tags
1294echo "Reading Tags..."
1295$MTN --db=$DB list tags > $TEMPFILE.tags.log || exit 200
1296do_pager $TEMPFILE.tags.log
1297;;
1298 h)
1299# if not branch known, ask user
1300do_branch_sel check
1301
1302$MTN --db=$DB heads --branch=$BRANCH > $TEMPFILE.txt || exit 200
1303do_pager $TEMPFILE.txt
1304;;
1305 k)
1306# List keys
1307$MTN --db=$DB list keys > $TEMPFILE.txt || exit 200
1308do_pager $TEMPFILE.txt
1309;;
1310 X)
1311do_clear_on_exit
1312clear
1313exit 0
1314 ;;
1315 *)
1316echo "Error in Menu!"
1317exit 250
1318 ;;
1319 esac
1320done
1321
1322do_clear_on_exit
1323clear

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status