Merge with master for gitk and doc updates.

This commit is contained in:
Junio C Hamano 2005-08-18 11:48:22 -07:00
commit 0776f4cb34
5 changed files with 711 additions and 213 deletions

View File

@ -1,7 +1,7 @@
MAN1_TXT=$(wildcard git-*.txt)
MAN7_TXT=git.txt
DOC_HTML=$(patsubst %.txt,%.html,$(MAN1_TXT) $(MAN7_TXT))
DOC_HTML=$(patsubst %.txt,%.html,$(MAN1_TXT) $(MAN7_TXT)) glossary.html
DOC_MAN1=$(patsubst %.txt,%.1,$(MAN1_TXT))
DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT))
@ -54,3 +54,8 @@ clean:
%.xml : %.txt
asciidoc -b docbook -d manpage $<
glossary.html : glossary.txt sort_glossary.pl
cat $< | \
perl sort_glossary.pl | \
asciidoc -b xhtml11 - > glossary.html

View File

@ -3,21 +3,27 @@ object::
the SHA1 of its contents. Consequently, an object can not
be changed.
object name::
The unique identifier of an object. The hash of the object's contents
using the Secure Hash Algorithm 1 and usually represented by the 40
character hexadecimal encoding of the hash of the object (possibly
followed by a white space).
SHA1::
A 20-byte sequence (or 41-byte file containing the hex
representation and a newline). It is calculated from the
contents of an object by the Secure Hash Algorithm 1.
Synonym for object name.
object identifier::
Synonym for object name.
hash::
In git's context, synonym to object name.
object database::
Stores a set of "objects", and an individial object is identified
by its SHA1 (its ref). The objects are either stored as single
files, or live inside of packs.
object name::
Synonym for SHA1.
by its object name. The object usually live in $GIT_DIR/objects/.
blob object::
Untyped object, i.e. the contents of a file.
Untyped object, e.g. the contents of a file.
tree object::
An object containing a list of blob and/or tree objects.
@ -29,42 +35,43 @@ tree::
dependent blob and tree objects (i.e. a stored representation
of a working tree).
cache::
A collection of files whose contents are stored as objects.
The cache is a stored version of your working tree. Well, can
also contain a second, and even a third version of a working
tree, which are used when merging.
index::
A collection of files with stat information, whose contents are
stored as objects. The cache is a stored version of your working
tree. Truth be told, it can also contain a second, and even a third
version of a working tree, which are used when merging.
cache entry::
index entry::
The information regarding a particular file, stored in the index.
A cache entry can be unmerged, if a merge was started, but not
An index entry can be unmerged, if a merge was started, but not
yet finished (i.e. if the cache contains multiple versions of
that file).
index::
Contains information about the cache contents, in particular
timestamps and mode flags ("stat information") for the files
stored in the cache. An unmerged index is an index which contains
unmerged cache entries.
unmerged index:
An index which contains unmerged index entries.
cache::
Obsolete for: index.
working tree::
The set of files and directories currently being worked on.
Think "ls -laR"
The set of files and directories currently being worked on,
i.e. you can work in your working tree without using git at all.
directory::
The list you get with "ls" :-)
checkout::
The action of updating the working tree to a revision which was
stored in the object database.
revision::
A particular state of files and directories which was stored in
the object database. It is referenced by a commit object.
checkout::
The action of updating the working tree to a revision which was
stored in the object database.
commit::
The action of storing the current state of the cache in the
As a verb: The action of storing the current state of the cache in the
object database. The result is a revision.
As a noun: Short hand for commit object.
commit object::
An object which contains the information about a particular
@ -72,14 +79,15 @@ commit object::
tree object which corresponds to the top directory of the
stored revision.
parent::
A commit object contains a (possibly empty) list of the logical
predecessor(s) in the line of development, i.e. its parents.
changeset::
BitKeeper/cvsps speak for "commit". Since git does not store
changes, but states, it really does not make sense to use
the term "changesets" with git.
ent::
Favorite synonym to "tree-ish" by some total geeks.
clean::
A working tree is clean, if it corresponds to the revision
referenced by the current head.
@ -94,13 +102,12 @@ head::
branch::
A non-cyclical graph of revisions, i.e. the complete history of
a particular revision, which does not (yet) have children, which
is called the branch head. The branch heads are stored in
$GIT_DIR/refs/heads/.
a particular revision, which is called the branch head. The
branch heads are stored in $GIT_DIR/refs/heads/.
ref::
A 40-byte hex representation of a SHA1 pointing to a particular
object. These are stored in $GIT_DIR/refs/.
object. These may be stored in $GIT_DIR/refs/.
head ref::
A ref pointing to a head. Often, this is abbreviated to "head".
@ -108,7 +115,10 @@ head ref::
tree-ish::
A ref pointing to either a commit object, a tree object, or a
tag object pointing to a commit or tree object.
tag object pointing to a tag or commit or tree object.
ent::
Favorite synonym to "tree-ish" by some total geeks.
tag object::
An object containing a ref pointing to another object. It can
@ -120,6 +130,8 @@ tag::
a tag is not changed by a commit. Tags (not tag objects) are
stored in $GIT_DIR/refs/tags/. A git tag has nothing to do with
a Lisp tag (which is called object type in git's context).
A tag is most typically used to mark a particular point in the
commit ancestry chain.
merge::
To merge branches means to try to accumulate the changes since a
@ -133,9 +145,18 @@ resolve::
repository::
A collection of refs together with an object database containing
all objects, which are reachable from the refs. A repository can
all objects, which are reachable from the refs, possibly accompanied
by meta data from one or more porcelains. A repository can
share an object database with other repositories.
git archive::
Synonym for repository (for arch people).
file system::
Linus Torvalds originally designed git to be a user space file
system, i.e. the infrastructure to hold files and directories.
That ensured the efficiency and speed of git.
alternate object database::
Via the alternates mechanism, a repository can inherit part of its
object database from another object database, which is called
@ -150,10 +171,6 @@ chain::
reference to its successor (for example, the successor of a commit
could be one of its parents).
parent::
A commit object contains a (possibly empty) list of the logical
predecessor(s) in the line of development, i.e. its parents.
fetch::
Fetching a branch means to get the branch's head ref from a
remote repository, to find out which objects are missing from
@ -176,8 +193,8 @@ pack::
space or to transmit them efficiently).
pack index::
Contains offsets into a pack, so the pack can be used instead of
the unpacked objects.
The list of identifiers, and other information, of the objects in a
pack, to assist in efficiently accessing the contents of a pack.
plumbing::
Cute name for core git.
@ -196,3 +213,4 @@ SCM::
dircache::
You are *waaaaay* behind.

View File

@ -70,8 +70,8 @@ them too:
Now create the branches in which you are going to work, these start
out at the current tip of the linus branch.
$ git checkout -b test linus
$ git checkout -b release linus
$ git branch test linus
$ git branch release linus
These can be easily kept up to date by merging from the "linus" branch:
@ -144,6 +144,11 @@ is empty. At this point the branch can be deleted:
$ rm .git/refs/heads/branchname
Some changes are so trivial that it is not necessary to create a separate
branch and then merge into each of the test and release branches. For
these changes, just apply directly to the "release" branch, and then
merge that into the "test" branch.
To create diffstat and shortlog summaries of changes to include in a "please
pull" request to Linus you can use:
@ -151,3 +156,109 @@ pull" request to Linus you can use:
and
$ git-whatchanged release ^linus | git-shortlog
Here are some of the scripts that I use to simplify all this even further.
==== update script ====
# Update a branch in my GIT tree. If the branch to be updated
# is "linus", then pull from kernel.org. Otherwise merge local
# linus branch into test|release branch
case "$1" in
test|release)
git checkout $1 && git resolve $1 linus "Auto-update from upstream"
;;
linus)
before=$(cat .git/HEAD)
git checkout linus && git pull linus
after=$(cat .git/HEAD)
if [ $before != $after ]
then
git-whatchanged $after ^$before | git-shortlog
fi
;;
*)
echo "Usage: $0 linus|test|release" 1>&2
exit 1
;;
esac
==== merge script ====
# Merge a branch into either the test or release branch
pname=$0
usage()
{
echo "Usage: $pname branch test|release" 1>&2
exit 1
}
if [ ! -f .git/refs/heads/"$1" ]
then
echo "Can't see branch <$1>" 1>&2
usage
fi
case "$2" in
test|release)
if [ $(git-rev-list $1 ^$2 | wc -c) -eq 0 ]
then
echo $1 already merged into $2 1>&2
exit 1
fi
git checkout $2 && git resolve $2 $1 "Pull $1 into $2 branch"
;;
*)
usage
;;
esac
==== status script ====
# report on status of my ia64 GIT tree
gb=$(tput setab 2)
rb=$(tput setab 1)
restore=$(tput setab 9)
if [ `git-rev-tree release ^test | wc -c` -gt 0 ]
then
echo $rb Warning: commits in release that are not in test $restore
git-whatchanged release ^test
fi
for branch in `ls .git/refs/heads`
do
if [ $branch = linus -o $branch = test -o $branch = release ]
then
continue
fi
echo -n $gb ======= $branch ====== $restore " "
status=
for ref in test release linus
do
if [ `git-rev-tree $branch ^$ref | wc -c` -gt 0 ]
then
status=$status${ref:0:1}
fi
done
case $status in
trl)
echo $rb Need to pull into test $restore
;;
rl)
echo "In test"
;;
l)
echo "Waiting for linus"
;;
"")
echo $rb All done $restore
;;
*)
echo $rb "<$status>" $restore
;;
esac
git-whatchanged $branch ^linus | git-shortlog
done

View File

@ -0,0 +1,70 @@
#!/usr/bin/perl
%terms=();
while(<>) {
if(/^(\S.*)::$/) {
my $term=$1;
if(defined($terms{$term})) {
die "$1 defined twice\n";
}
$terms{$term}="";
LOOP: while(<>) {
if(/^$/) {
last LOOP;
}
if(/^ \S/) {
$terms{$term}.=$_;
} else {
die "Error 1: $_";
}
}
}
}
sub format_tab_80 ($) {
my $text=$_[0];
my $result="";
$text=~s/\s+/ /g;
$text=~s/^\s+//;
while($text=~/^(.{1,72})(|\s+(\S.*)?)$/) {
$result.=" ".$1."\n";
$text=$3;
}
return $result;
}
sub no_spaces ($) {
my $result=$_[0];
$result=~tr/ /_/;
return $result;
}
print 'GIT Glossary
============
Aug 2005
This list is sorted alphabetically:
';
@keys=sort {uc($a) cmp uc($b)} keys %terms;
$pattern='(\b'.join('\b|\b',reverse @keys).'\b)';
foreach $key (@keys) {
$terms{$key}=~s/$pattern/sprintf "<<ref_".no_spaces($1).",$1>>";/eg;
print '[[ref_'.no_spaces($key).']]'.$key."::\n"
.format_tab_80($terms{$key})."\n";
}
print '
Author
------
Written by Johannes Schindelin <Johannes.Schindelin@gmx.de> and
the git-list <git@vger.kernel.org>.
GIT
---
Part of the link:git.html[git] suite
';

628
gitk
View File

@ -59,7 +59,7 @@ proc getcommits {rargs} {
}
proc getcommitlines {commfd} {
global commits parents cdate children nchildren
global commits parents cdate children
global commitlisted phase commitinfo nextupdate
global stopped redisplaying leftover
@ -156,6 +156,7 @@ proc readcommit {id} {
proc parsecommit {id contents listed} {
global commitinfo children nchildren parents nparents cdate ncleft
global grafts
set inhdr 1
set comment {}
@ -171,13 +172,32 @@ proc parsecommit {id contents listed} {
}
set parents($id) {}
set nparents($id) 0
set grafted 0
if {[info exists grafts($id)]} {
set grafted 1
set parents($id) $grafts($id)
set nparents($id) [llength $grafts($id)]
if {$listed} {
foreach p $grafts($id) {
if {![info exists nchildren($p)]} {
set children($p) [list $id]
set nchildren($p) 1
set ncleft($p) 1
} elseif {[lsearch -exact $children($p) $id] < 0} {
lappend children($p) $id
incr nchildren($p)
incr ncleft($p)
}
}
}
}
foreach line [split $contents "\n"] {
if {$inhdr} {
if {$line == {}} {
set inhdr 0
} else {
set tag [lindex $line 0]
if {$tag == "parent"} {
if {$tag == "parent" && !$grafted} {
set p [lindex $line 1]
if {![info exists nchildren($p)]} {
set children($p) {}
@ -273,6 +293,32 @@ proc readrefs {} {
}
}
proc readgrafts {} {
global grafts env
catch {
set graftfile info/grafts
if {[info exists env(GIT_GRAFT_FILE)]} {
set graftfile $env(GIT_GRAFT_FILE)
}
set fd [open [gitdir]/$graftfile r]
while {[gets $fd line] >= 0} {
if {[string match "#*" $line]} continue
set ok 1
foreach x $line {
if {![regexp {^[0-9a-f]{40}$} $x]} {
set ok 0
break
}
}
if {$ok} {
set id [lindex $line 0]
set grafts($id) [lrange $line 1 end]
}
}
close $fd
}
}
proc error_popup msg {
set w .error
toplevel $w
@ -704,21 +750,24 @@ proc assigncolor {id} {
}
proc initgraph {} {
global canvy canvy0 lineno numcommits lthickness nextcolor linespc
global mainline sidelines
global canvy canvy0 lineno numcommits nextcolor linespc
global mainline mainlinearrow sidelines
global nchildren ncleft
global displist nhyperspace
allcanvs delete all
set nextcolor 0
set canvy $canvy0
set lineno -1
set numcommits 0
set lthickness [expr {int($linespc / 9) + 1}]
catch {unset mainline}
catch {unset mainlinearrow}
catch {unset sidelines}
foreach id [array names nchildren] {
set ncleft($id) $nchildren($id)
}
set displist {}
set nhyperspace 0
}
proc bindline {t id} {
@ -730,19 +779,21 @@ proc bindline {t id} {
$canv bind $t <Button-1> "lineclick %x %y $id 1"
}
# level here is an index in displist
proc drawcommitline {level} {
global parents children nparents nchildren todo
global parents children nparents displist
global canv canv2 canv3 mainfont namefont canvy linespc
global lineid linehtag linentag linedtag commitinfo
global colormap numcommits currentparents dupparents
global oldlevel oldnlines oldtodo
global idtags idline idheads
global lineno lthickness mainline sidelines
global commitlisted rowtextx idpos
global lineno lthickness mainline mainlinearrow sidelines
global commitlisted rowtextx idpos lastuse displist
global oldnlines olddlevel olddisplist
incr numcommits
incr lineno
set id [lindex $todo $level]
set id [lindex $displist $level]
set lastuse($id) $lineno
set lineid($lineno) $id
set idline($id) $lineno
set ofill [expr {[info exists commitlisted($id)]? "blue": "white"}]
@ -773,8 +824,12 @@ proc drawcommitline {level} {
[list 0 0 0 [expr $y1 + 0.5 * $linespc + 2]]
if {[info exists mainline($id)]} {
lappend mainline($id) $x $y1
if {$mainlinearrow($id) ne "none"} {
set mainline($id) [trimdiagstart $mainline($id)]
}
set t [$canv create line $mainline($id) \
-width $lthickness -fill $colormap($id)]
-width $lthickness -fill $colormap($id) \
-arrow $mainlinearrow($id)]
$canv lower $t
bindline $t $id
}
@ -782,8 +837,9 @@ proc drawcommitline {level} {
foreach ls $sidelines($id) {
set coords [lindex $ls 0]
set thick [lindex $ls 1]
set arrow [lindex $ls 2]
set t [$canv create line $coords -fill $colormap($id) \
-width [expr {$thick * $lthickness}]]
-width [expr {$thick * $lthickness}] -arrow $arrow]
$canv lower $t
bindline $t $id
}
@ -794,7 +850,7 @@ proc drawcommitline {level} {
-fill $ofill -outline black -width 1]
$canv raise $t
$canv bind $t <1> {selcanvline {} %x %y}
set xt [xcoord [llength $todo] $level $lineno]
set xt [xcoord [llength $displist] $level $lineno]
if {[llength $currentparents] > 2} {
set xt [expr {$xt + ([llength $currentparents] - 2) * $linespc}]
}
@ -813,6 +869,10 @@ proc drawcommitline {level} {
-text $name -font $namefont]
set linedtag($lineno) [$canv3 create text 3 $y1 -anchor w \
-text $date -font $mainfont]
set olddlevel $level
set olddisplist $displist
set oldnlines [llength $displist]
}
proc drawtags {id x xt y1} {
@ -867,46 +927,11 @@ proc drawtags {id x xt y1} {
return $xt
}
proc updatetodo {level noshortcut} {
global currentparents ncleft todo
global mainline oldlevel oldtodo oldnlines
global canvy linespc mainline
global commitinfo lineno xspc1
set oldlevel $level
set oldtodo $todo
set oldnlines [llength $todo]
if {!$noshortcut && [llength $currentparents] == 1} {
set p [lindex $currentparents 0]
if {$ncleft($p) == 1 && [lsearch -exact $todo $p] < 0} {
set ncleft($p) 0
set x [xcoord $level $level $lineno]
set y [expr $canvy - $linespc]
set mainline($p) [list $x $y]
set todo [lreplace $todo $level $level $p]
set xspc1([expr {$lineno + 1}]) $xspc1($lineno)
return 0
}
}
set todo [lreplace $todo $level $level]
set i $level
foreach p $currentparents {
incr ncleft($p) -1
set k [lsearch -exact $todo $p]
if {$k < 0} {
set todo [linsert $todo $i $p]
incr i
}
}
return 1
}
proc notecrossings {id lo hi corner} {
global oldtodo crossings cornercrossings
global olddisplist crossings cornercrossings
for {set i $lo} {[incr i] < $hi} {} {
set p [lindex $oldtodo $i]
set p [lindex $olddisplist $i]
if {$p == {}} continue
if {$i == $corner} {
if {![info exists cornercrossings($id)]
@ -942,37 +967,218 @@ proc xcoord {i level ln} {
return $x
}
proc drawslants {level} {
global canv mainline sidelines canvx0 canvy xspc1 xspc2 lthickness
global oldlevel oldtodo todo currentparents dupparents
# it seems Tk can't draw arrows on the end of diagonal line segments...
proc trimdiagend {line} {
while {[llength $line] > 4} {
set x1 [lindex $line end-3]
set y1 [lindex $line end-2]
set x2 [lindex $line end-1]
set y2 [lindex $line end]
if {($x1 == $x2) != ($y1 == $y2)} break
set line [lreplace $line end-1 end]
}
return $line
}
proc trimdiagstart {line} {
while {[llength $line] > 4} {
set x1 [lindex $line 0]
set y1 [lindex $line 1]
set x2 [lindex $line 2]
set y2 [lindex $line 3]
if {($x1 == $x2) != ($y1 == $y2)} break
set line [lreplace $line 0 1]
}
return $line
}
proc drawslants {id needonscreen nohs} {
global canv mainline mainlinearrow sidelines
global canvx0 canvy xspc1 xspc2 lthickness
global currentparents dupparents
global lthickness linespc canvy colormap lineno geometry
global maxgraphpct
global maxgraphpct maxwidth
global displist onscreen lastuse
global parents commitlisted
global oldnlines olddlevel olddisplist
global nhyperspace numcommits nnewparents
if {$lineno < 0} {
lappend displist $id
set onscreen($id) 1
return 0
}
set y1 [expr {$canvy - $linespc}]
set y2 $canvy
# work out what we need to get back on screen
set reins {}
if {$onscreen($id) < 0} {
# next to do isn't displayed, better get it on screen...
lappend reins [list $id 0]
}
# make sure all the previous commits's parents are on the screen
foreach p $currentparents {
if {$onscreen($p) < 0} {
lappend reins [list $p 0]
}
}
# bring back anything requested by caller
if {$needonscreen ne {}} {
lappend reins $needonscreen
}
# try the shortcut
if {$currentparents == $id && $onscreen($id) == 0 && $reins eq {}} {
set dlevel $olddlevel
set x [xcoord $dlevel $dlevel $lineno]
set mainline($id) [list $x $y1]
set mainlinearrow($id) none
set lastuse($id) $lineno
set displist [lreplace $displist $dlevel $dlevel $id]
set onscreen($id) 1
set xspc1([expr {$lineno + 1}]) $xspc1($lineno)
return $dlevel
}
# update displist
set displist [lreplace $displist $olddlevel $olddlevel]
set j $olddlevel
foreach p $currentparents {
set lastuse($p) $lineno
if {$onscreen($p) == 0} {
set displist [linsert $displist $j $p]
set onscreen($p) 1
incr j
}
}
if {$onscreen($id) == 0} {
lappend displist $id
}
# remove the null entry if present
set nullentry [lsearch -exact $displist {}]
if {$nullentry >= 0} {
set displist [lreplace $displist $nullentry $nullentry]
}
# bring back the ones we need now (if we did it earlier
# it would change displist and invalidate olddlevel)
foreach pi $reins {
# test again in case of duplicates in reins
set p [lindex $pi 0]
if {$onscreen($p) < 0} {
set onscreen($p) 1
set lastuse($p) $lineno
set displist [linsert $displist [lindex $pi 1] $p]
incr nhyperspace -1
}
}
set lastuse($id) $lineno
# see if we need to make any lines jump off into hyperspace
set displ [llength $displist]
if {$displ > $maxwidth} {
set ages {}
foreach x $displist {
lappend ages [list $lastuse($x) $x]
}
set ages [lsort -integer -index 0 $ages]
set k 0
while {$displ > $maxwidth} {
set use [lindex $ages $k 0]
set victim [lindex $ages $k 1]
if {$use >= $lineno - 5} break
incr k
if {[lsearch -exact $nohs $victim] >= 0} continue
set i [lsearch -exact $displist $victim]
set displist [lreplace $displist $i $i]
set onscreen($victim) -1
incr nhyperspace
incr displ -1
if {$i < $nullentry} {
incr nullentry -1
}
set x [lindex $mainline($victim) end-1]
lappend mainline($victim) $x $y1
set line [trimdiagend $mainline($victim)]
set arrow "last"
if {$mainlinearrow($victim) ne "none"} {
set line [trimdiagstart $line]
set arrow "both"
}
lappend sidelines($victim) [list $line 1 $arrow]
unset mainline($victim)
}
}
set dlevel [lsearch -exact $displist $id]
# If we are reducing, put in a null entry
if {$displ < $oldnlines} {
# does the next line look like a merge?
# i.e. does it have > 1 new parent?
if {$nnewparents($id) > 1} {
set i [expr {$dlevel + 1}]
} elseif {$nnewparents([lindex $olddisplist $olddlevel]) == 0} {
set i $olddlevel
if {$nullentry >= 0 && $nullentry < $i} {
incr i -1
}
} elseif {$nullentry >= 0} {
set i $nullentry
while {$i < $displ
&& [lindex $olddisplist $i] == [lindex $displist $i]} {
incr i
}
} else {
set i $olddlevel
if {$dlevel >= $i} {
incr i
}
}
if {$i < $displ} {
set displist [linsert $displist $i {}]
incr displ
if {$dlevel >= $i} {
incr dlevel
}
}
}
# decide on the line spacing for the next line
set lj [expr {$lineno + 1}]
set maxw [expr {$maxgraphpct * $geometry(canv1) / 100}]
set n [llength $todo]
if {$n <= 1 || $canvx0 + $n * $xspc2 <= $maxw} {
if {$displ <= 1 || $canvx0 + $displ * $xspc2 <= $maxw} {
set xspc1($lj) $xspc2
} else {
set xspc1($lj) [expr {($maxw - $canvx0 - $xspc2) / ($n - 1)}]
set xspc1($lj) [expr {($maxw - $canvx0 - $xspc2) / ($displ - 1)}]
if {$xspc1($lj) < $lthickness} {
set xspc1($lj) $lthickness
}
}
set y1 [expr $canvy - $linespc]
set y2 $canvy
foreach idi $reins {
set id [lindex $idi 0]
set j [lsearch -exact $displist $id]
set xj [xcoord $j $dlevel $lj]
set mainline($id) [list $xj $y2]
set mainlinearrow($id) first
}
set i -1
foreach id $oldtodo {
foreach id $olddisplist {
incr i
if {$id == {}} continue
set xi [xcoord $i $oldlevel $lineno]
if {$i == $oldlevel} {
if {$onscreen($id) <= 0} continue
set xi [xcoord $i $olddlevel $lineno]
if {$i == $olddlevel} {
foreach p $currentparents {
set j [lsearch -exact $todo $p]
set j [lsearch -exact $displist $p]
set coords [list $xi $y1]
set xj [xcoord $j $level $lj]
set xj [xcoord $j $dlevel $lj]
if {$xj < $xi - $linespc} {
lappend coords [expr {$xj + $linespc}] $y1
notecrossings $p $j $i [expr {$j + 1}]
@ -983,9 +1189,10 @@ proc drawslants {level} {
if {[lsearch -exact $dupparents $p] >= 0} {
# draw a double-width line to indicate the doubled parent
lappend coords $xj $y2
lappend sidelines($p) [list $coords 2]
lappend sidelines($p) [list $coords 2 none]
if {![info exists mainline($p)]} {
set mainline($p) [list $xj $y2]
set mainlinearrow($p) none
}
} else {
# normal case, no parent duplicated
@ -999,24 +1206,25 @@ proc drawslants {level} {
lappend coords $xj $yb
}
set mainline($p) $coords
set mainlinearrow($p) none
} else {
lappend coords $xj $yb
if {$yb < $y2} {
lappend coords $xj $y2
}
lappend sidelines($p) [list $coords 1]
lappend sidelines($p) [list $coords 1 none]
}
}
}
} else {
set j $i
if {[lindex $todo $i] != $id} {
set j [lsearch -exact $todo $id]
if {[lindex $displist $i] != $id} {
set j [lsearch -exact $displist $id]
}
if {$j != $i || $xspc1($lineno) != $xspc1($lj)
|| ($oldlevel <= $i && $i <= $level)
|| ($level <= $i && $i <= $oldlevel)} {
set xj [xcoord $j $level $lj]
|| ($olddlevel <= $i && $i <= $dlevel)
|| ($dlevel <= $i && $i <= $olddlevel)} {
set xj [xcoord $j $dlevel $lj]
set dx [expr {abs($xi - $xj)}]
set yb $y2
if {0 && $dx < $linespc} {
@ -1026,21 +1234,152 @@ proc drawslants {level} {
}
}
}
return $dlevel
}
# search for x in a list of lists
proc llsearch {llist x} {
set i 0
foreach l $llist {
if {$l == $x || [lsearch -exact $l $x] >= 0} {
return $i
}
incr i
}
return -1
}
proc drawmore {reading} {
global displayorder numcommits ncmupdate nextupdate
global stopped nhyperspace parents commitlisted
global maxwidth onscreen displist currentparents olddlevel
set n [llength $displayorder]
while {$numcommits < $n} {
set id [lindex $displayorder $numcommits]
set ctxend [expr {$numcommits + 10}]
if {!$reading && $ctxend > $n} {
set ctxend $n
}
set dlist {}
if {$numcommits > 0} {
set dlist [lreplace $displist $olddlevel $olddlevel]
set i $olddlevel
foreach p $currentparents {
if {$onscreen($p) == 0} {
set dlist [linsert $dlist $i $p]
incr i
}
}
}
set nohs {}
set reins {}
set isfat [expr {[llength $dlist] > $maxwidth}]
if {$nhyperspace > 0 || $isfat} {
if {$ctxend > $n} break
# work out what to bring back and
# what we want to don't want to send into hyperspace
set room 1
for {set k $numcommits} {$k < $ctxend} {incr k} {
set x [lindex $displayorder $k]
set i [llsearch $dlist $x]
if {$i < 0} {
set i [llength $dlist]
lappend dlist $x
}
if {[lsearch -exact $nohs $x] < 0} {
lappend nohs $x
}
if {$reins eq {} && $onscreen($x) < 0 && $room} {
set reins [list $x $i]
}
set newp {}
if {[info exists commitlisted($x)]} {
set right 0
foreach p $parents($x) {
if {[llsearch $dlist $p] < 0} {
lappend newp $p
if {[lsearch -exact $nohs $p] < 0} {
lappend nohs $p
}
if {$reins eq {} && $onscreen($p) < 0 && $room} {
set reins [list $p [expr {$i + $right}]]
}
}
set right 1
}
}
set l [lindex $dlist $i]
if {[llength $l] == 1} {
set l $newp
} else {
set j [lsearch -exact $l $x]
set l [concat [lreplace $l $j $j] $newp]
}
set dlist [lreplace $dlist $i $i $l]
if {$room && $isfat && [llength $newp] <= 1} {
set room 0
}
}
}
set dlevel [drawslants $id $reins $nohs]
drawcommitline $dlevel
if {[clock clicks -milliseconds] >= $nextupdate
&& $numcommits >= $ncmupdate} {
doupdate $reading
if {$stopped} break
}
}
}
# level here is an index in todo
proc updatetodo {level noshortcut} {
global ncleft todo nnewparents
global commitlisted parents onscreen
set id [lindex $todo $level]
set olds {}
if {[info exists commitlisted($id)]} {
foreach p $parents($id) {
if {[lsearch -exact $olds $p] < 0} {
lappend olds $p
}
}
}
if {!$noshortcut && [llength $olds] == 1} {
set p [lindex $olds 0]
if {$ncleft($p) == 1 && [lsearch -exact $todo $p] < 0} {
set ncleft($p) 0
set todo [lreplace $todo $level $level $p]
set onscreen($p) 0
set nnewparents($id) 1
return 0
}
}
set todo [lreplace $todo $level $level]
set i $level
set n 0
foreach p $olds {
incr ncleft($p) -1
set k [lsearch -exact $todo $p]
if {$k < 0} {
set todo [linsert $todo $i $p]
set onscreen($p) 0
incr i
incr n
}
}
set nnewparents($id) $n
return 1
}
proc decidenext {{noread 0}} {
global parents children nchildren ncleft todo
global canv canv2 canv3 mainfont namefont canvy linespc
global ncleft todo
global datemode cdate
global commitinfo
global currentparents oldlevel oldnlines oldtodo
global lineno lthickness
# remove the null entry if present
set nullentry [lsearch -exact $todo {}]
if {$nullentry >= 0} {
set todo [lreplace $todo $nullentry $nullentry]
}
# choose which one to do next time around
set todol [llength $todo]
@ -1076,73 +1415,43 @@ proc decidenext {{noread 0}} {
return -1
}
# If we are reducing, put in a null entry
if {$todol < $oldnlines} {
if {$nullentry >= 0} {
set i $nullentry
while {$i < $todol
&& [lindex $oldtodo $i] == [lindex $todo $i]} {
incr i
}
} else {
set i $oldlevel
if {$level >= $i} {
incr i
}
}
if {$i < $todol} {
set todo [linsert $todo $i {}]
if {$level >= $i} {
incr level
}
}
}
return $level
}
proc drawcommit {id} {
global phase todo nchildren datemode nextupdate
global startcommits numcommits ncmupdate
global numcommits ncmupdate displayorder todo onscreen
if {$phase != "incrdraw"} {
set phase incrdraw
set todo $id
set startcommits $id
set displayorder {}
set todo {}
initgraph
drawcommitline 0
updatetodo 0 $datemode
} else {
if {$nchildren($id) == 0} {
lappend todo $id
lappend startcommits $id
}
if {$nchildren($id) == 0} {
lappend todo $id
set onscreen($id) 0
}
set level [decidenext 1]
if {$level == {} || $id != [lindex $todo $level]} {
return
}
while 1 {
lappend displayorder [lindex $todo $level]
if {[updatetodo $level $datemode]} {
set level [decidenext 1]
if {$level == {}} break
}
set level [decidenext 1]
if {$level == {} || $id != [lindex $todo $level]} {
return
}
while 1 {
drawslants $level
drawcommitline $level
if {[updatetodo $level $datemode]} {
set level [decidenext 1]
if {$level == {}} break
}
set id [lindex $todo $level]
if {![info exists commitlisted($id)]} {
break
}
if {[clock clicks -milliseconds] >= $nextupdate
&& $numcommits >= $ncmupdate} {
doupdate 1
if {$stopped} break
}
set id [lindex $todo $level]
if {![info exists commitlisted($id)]} {
break
}
}
drawmore 1
}
proc finishcommits {} {
global phase
global startcommits
global canv mainfont ctext maincursor textcursor
if {$phase != "incrdraw"} {
@ -1151,9 +1460,7 @@ proc finishcommits {} {
-font $mainfont -tags textitems
set phase {}
} else {
set level [decidenext]
drawslants $level
drawrest $level [llength $startcommits]
drawrest
}
. config -cursor $maincursor
settextcursor $textcursor
@ -1171,54 +1478,38 @@ proc settextcursor {c} {
}
proc drawgraph {} {
global nextupdate startmsecs startcommits todo ncmupdate
global nextupdate startmsecs ncmupdate
global displayorder onscreen
if {$startcommits == {}} return
if {$displayorder == {}} return
set startmsecs [clock clicks -milliseconds]
set nextupdate [expr $startmsecs + 100]
set ncmupdate 1
initgraph
set todo [lindex $startcommits 0]
drawrest 0 1
foreach id $displayorder {
set onscreen($id) 0
}
drawmore 0
}
proc drawrest {level startix} {
proc drawrest {} {
global phase stopped redisplaying selectedline
global datemode currentparents todo
global datemode todo displayorder
global numcommits ncmupdate
global nextupdate startmsecs startcommits idline
global nextupdate startmsecs idline
set level [decidenext]
if {$level >= 0} {
set phase drawgraph
set startid [lindex $startcommits $startix]
set startline -1
if {$startid != {}} {
set startline $idline($startid)
}
while 1 {
if {$stopped} break
drawcommitline $level
lappend displayorder [lindex $todo $level]
set hard [updatetodo $level $datemode]
if {$numcommits == $startline} {
lappend todo $startid
set hard 1
incr startix
set startid [lindex $startcommits $startix]
set startline -1
if {$startid != {}} {
set startline $idline($startid)
}
}
if {$hard} {
set level [decidenext]
if {$level < 0} break
drawslants $level
}
if {[clock clicks -milliseconds] >= $nextupdate
&& $numcommits >= $ncmupdate} {
doupdate 0
}
}
drawmore 0
}
set phase {}
set drawmsecs [expr [clock clicks -milliseconds] - $startmsecs]
@ -1730,7 +2021,7 @@ proc commit_descriptor {p} {
proc selectline {l isnew} {
global canv canv2 canv3 ctext commitinfo selectedline
global lineid linehtag linentag linedtag
global canvy0 linespc parents nparents children nchildren
global canvy0 linespc parents nparents children
global cflist currentid sha1entry
global commentend idtags idline
@ -2654,12 +2945,13 @@ proc listboxsel {} {
proc setcoords {} {
global linespc charspc canvx0 canvy0 mainfont
global xspc1 xspc2
global xspc1 xspc2 lthickness
set linespc [font metrics $mainfont -linespace]
set charspc [font measure $mainfont "m"]
set canvy0 [expr 3 + 0.5 * $linespc]
set canvx0 [expr 3 + 0.5 * $linespc]
set lthickness [expr {int($linespc / 9) + 1}]
set xspc1(0) $linespc
set xspc2 $linespc
}
@ -3170,6 +3462,7 @@ set textfont {Courier 9}
set findmergefiles 0
set gaudydiff 0
set maxgraphpct 50
set maxwidth 16
set colors {green red blue magenta darkgrey brown orange}
@ -3202,4 +3495,5 @@ set patchnum 0
setcoords
makewindow
readrefs
readgrafts
getcommits $revtreeargs