diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Documentation/git-clean.txt | 50 | ||||
-rwxr-xr-x | GIT-VERSION-GEN | 2 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | date.c | 4 | ||||
-rw-r--r-- | diff.c | 44 | ||||
-rwxr-xr-x | git-clean.sh | 80 | ||||
-rwxr-xr-x | git-cvsimport.perl | 6 | ||||
-rwxr-xr-x | git-ls-remote.sh | 2 | ||||
-rwxr-xr-x | gitk | 331 | ||||
-rw-r--r-- | http.c | 2 | ||||
-rw-r--r-- | imap-send.c | 8 | ||||
-rw-r--r-- | xdiff/xdiffi.c | 7 | ||||
-rw-r--r-- | xdiff/xprepare.c | 63 | ||||
-rw-r--r-- | xdiff/xutils.c | 17 | ||||
-rw-r--r-- | xdiff/xutils.h | 1 |
16 files changed, 462 insertions, 161 deletions
diff --git a/.gitignore b/.gitignore index 75891c393b..b5959d6311 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ git-checkout git-checkout-index git-cherry git-cherry-pick +git-clean git-clone git-clone-pack git-commit diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt new file mode 100644 index 0000000000..36890c543d --- /dev/null +++ b/Documentation/git-clean.txt @@ -0,0 +1,50 @@ +git-clean(1) +============ + +NAME +---- +git-clean - Remove untracked files from the working tree + +SYNOPSIS +-------- +[verse] +'git-clean' [-d] [-n] [-q] [-x | -X] + +DESCRIPTION +----------- +Removes files unknown to git. This allows to clean the working tree +from files that are not under version control. If the '-x' option is +specified, ignored files are also removed, allowing to remove all +build products. + +OPTIONS +------- +-d:: + Remove untracked directories in addition to untracked files. + +-n:: + Don't actually remove anything, just show what would be done. + +-q:: + Be quiet, only report errors, but not the files that are + successfully removed. + +-x:: + Don't use the ignore rules. This allows removing all untracked + files, including build products. This can be used (possibly in + conjunction with gitlink:git-reset[1]) to create a pristine + working directory to test a clean build. + +-X:: + Remove only files ignored by git. This may be useful to rebuild + everything from scratch, but keep manually created files. + + +Author +------ +Written by Pavel Roskin <proski@gnu.org> + + +GIT +--- +Part of the gitlink:git[7] suite diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 4764fd2515..d2200acd7a 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.3-rc1.GIT +DEF_VER=v1.3-rc2.GIT # First try git-describe, then see if there is a version file # (included in release tarballs), then default @@ -114,7 +114,7 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ SCRIPT_SH = \ git-add.sh git-bisect.sh git-branch.sh git-checkout.sh \ - git-cherry.sh git-clone.sh git-commit.sh \ + git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \ git-count-objects.sh git-diff.sh git-fetch.sh \ git-format-patch.sh git-log.sh git-ls-remote.sh \ git-merge-one-file.sh git-parse-remote.sh \ @@ -510,6 +510,9 @@ git$X git.spec \ exec_cmd.o: exec_cmd.c $(CC) -o $*.o -c $(ALL_CFLAGS) '-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' $< +http.o: http.c + $(CC) -o $*.o -c $(ALL_CFLAGS) -DGIT_USER_AGENT='"git/$(GIT_VERSION)"' $< + git-%$X: %.o $(GITLIBS) $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) @@ -255,10 +255,10 @@ static int match_multi_number(unsigned long num, char c, const char *date, char break; } /* mm/dd/yy ? */ - if (is_date(num3, num2, num, tm)) + if (is_date(num3, num, num2, tm)) break; /* dd/mm/yy ? */ - if (is_date(num3, num, num2, tm)) + if (is_date(num3, num2, num, tm)) break; return 0; } @@ -1282,28 +1282,34 @@ void diff_flush(struct diff_options *options) for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; - if ((diff_output_format == DIFF_FORMAT_NO_OUTPUT) || - (p->status == DIFF_STATUS_UNKNOWN)) - continue; - if (p->status == 0) - die("internal error in diff-resolve-rename-copy"); - switch (diff_output_format) { - case DIFF_FORMAT_PATCH: - diff_flush_patch(p, options); - break; - case DIFF_FORMAT_RAW: - case DIFF_FORMAT_NAME_STATUS: - diff_flush_raw(p, line_termination, - inter_name_termination, - options); + + switch (p->status) { + case DIFF_STATUS_UNKNOWN: break; - case DIFF_FORMAT_NAME: - diff_flush_name(p, - inter_name_termination, - line_termination); + case 0: + die("internal error in diff-resolve-rename-copy"); break; + default: + switch (diff_output_format) { + case DIFF_FORMAT_PATCH: + diff_flush_patch(p, options); + break; + case DIFF_FORMAT_RAW: + case DIFF_FORMAT_NAME_STATUS: + diff_flush_raw(p, line_termination, + inter_name_termination, + options); + break; + case DIFF_FORMAT_NAME: + diff_flush_name(p, + inter_name_termination, + line_termination); + break; + case DIFF_FORMAT_NO_OUTPUT: + break; + } } - diff_free_filepair(q->queue[i]); + diff_free_filepair(p); } free(q->queue); q->queue = NULL; diff --git a/git-clean.sh b/git-clean.sh new file mode 100755 index 0000000000..b200868e60 --- /dev/null +++ b/git-clean.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# +# Copyright (c) 2005-2006 Pavel Roskin +# + +USAGE="[-d] [-n] [-q] [-x | -X]" +LONG_USAGE='Clean untracked files from the working directory + -d remove directories as well + -n don'\''t remove anything, just show what would be done + -q be quiet, only report errors + -x remove ignored files as well + -X remove only ignored files as well' +SUBDIRECTORY_OK=Yes +. git-sh-setup + +ignored= +ignoredonly= +cleandir= +quiet= +rmf="rm -f" +rmrf="rm -rf" +rm_refuse="echo Not removing" +echo1="echo" + +while case "$#" in 0) break ;; esac +do + case "$1" in + -d) + cleandir=1 + ;; + -n) + quiet=1 + rmf="echo Would remove" + rmrf="echo Would remove" + rm_refuse="echo Would not remove" + echo1=":" + ;; + -q) + quiet=1 + ;; + -x) + ignored=1 + ;; + -X) + ignoredonly=1 + ;; + *) + usage + esac + shift +done + +case "$ignored,$ignoredonly" in + 1,1) usage;; +esac + +if [ -z "$ignored" ]; then + excl="--exclude-per-directory=.gitignore" + if [ -f "$GIT_DIR/info/exclude" ]; then + excl_info="--exclude-from=$GIT_DIR/info/exclude" + fi + if [ "$ignoredonly" ]; then + excl="$excl --ignored" + fi +fi + +git-ls-files --others --directory $excl ${excl_info:+"$excl_info"} | +while read -r file; do + if [ -d "$file" -a ! -L "$file" ]; then + if [ -z "$cleandir" ]; then + $rm_refuse "$file" + continue + fi + $echo1 "Removing $file" + $rmrf "$file" + else + $echo1 "Removing $file" + $rmf "$file" + fi +done diff --git a/git-cvsimport.perl b/git-cvsimport.perl index 3728294e74..c0ae00bda7 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -677,11 +677,7 @@ my $commit = sub { waitpid($pid,0); die "Error running git-commit-tree: $?\n" if $?; - open(C,">$git_dir/refs/heads/$branch") - or die "Cannot open branch $branch for update: $!\n"; - print C "$cid\n" - or die "Cannot write branch $branch for update: $!\n"; - close(C) + system("git-update-ref refs/heads/$branch $cid") == 0 or die "Cannot write branch $branch for update: $!\n"; if($tag) { diff --git a/git-ls-remote.sh b/git-ls-remote.sh index 2c9a588d21..b6882a90c1 100755 --- a/git-ls-remote.sh +++ b/git-ls-remote.sh @@ -53,7 +53,7 @@ http://* | https://* ) if [ -n "$GIT_SSL_NO_VERIFY" ]; then curl_extra_args="-k" fi - curl -nsf $curl_extra_args "$peek_repo/info/refs" || + curl -nsf $curl_extra_args --header "Pragma: no-cache" "$peek_repo/info/refs" || echo "failed slurping" ;; @@ -75,6 +75,7 @@ proc getcommitlines {commfd} { global commitlisted nextupdate global leftover global displayorder commitidx commitrow commitdata + global parentlist childlist children set stuff [read $commfd] if {$stuff == {}} { @@ -140,15 +141,26 @@ proc getcommitlines {commfd} { set id [lindex $ids 0] if {$listed} { set olds [lrange $ids 1 end] - set commitlisted($id) 1 + if {[llength $olds] > 1} { + set olds [lsort -unique $olds] + } + foreach p $olds { + lappend children($p) $id + } } else { set olds {} } - updatechildren $id $olds + lappend parentlist $olds + if {[info exists children($id)]} { + lappend childlist $children($id) + } else { + lappend childlist {} + } set commitdata($id) [string range $cmit [expr {$j + 1}] end] set commitrow($id) $commitidx incr commitidx lappend displayorder $id + lappend commitlisted $listed set gotsome 1 } if {$gotsome} { @@ -181,14 +193,12 @@ proc doupdate {reading} { proc readcommit {id} { if {[catch {set contents [exec git-cat-file commit $id]}]} return - updatechildren $id {} parsecommit $id $contents 0 } proc updatecommits {rargs} { stopfindproc - foreach v {children nchildren parents nparents commitlisted - colormap selectedline matchinglines treediffs + foreach v {colormap selectedline matchinglines treediffs mergefilelist currentid rowtextx commitrow rowidlist rowoffsets idrowranges idrangedrawn iddrawn linesegends crossings cornercrossings} { @@ -200,26 +210,6 @@ proc updatecommits {rargs} { getcommits $rargs } -proc updatechildren {id olds} { - global children nchildren parents nparents - - if {![info exists nchildren($id)]} { - set children($id) {} - set nchildren($id) 0 - } - set parents($id) $olds - set nparents($id) [llength $olds] - foreach p $olds { - if {![info exists nchildren($p)]} { - set children($p) [list $id] - set nchildren($p) 1 - } elseif {[lsearch -exact $children($p) $id] < 0} { - lappend children($p) $id - incr nchildren($p) - } - } -} - proc parsecommit {id contents listed} { global commitinfo cdate @@ -274,7 +264,7 @@ proc parsecommit {id contents listed} { } proc getcommit {id} { - global commitdata commitinfo nparents + global commitdata commitinfo if {[info exists commitdata($id)]} { parsecommit $id $commitdata($id) 1 @@ -282,7 +272,6 @@ proc getcommit {id} { readcommit $id if {![info exists commitinfo($id)]} { set commitinfo($id) {"No commit information available"} - set nparents($id) 0 } } return 1 @@ -295,7 +284,7 @@ proc readrefs {} { foreach v {tagids idtags headids idheads otherrefids idotherrefs} { catch {unset $v} } - set refd [open [list | git-ls-remote [gitdir]] r] + set refd [open [list | git ls-remote [gitdir]] r] while {0 <= [set n [gets $refd line]]} { if {![regexp {^([0-9a-f]{40}) refs/([^^]*)$} $line \ match id path]} { @@ -346,7 +335,7 @@ proc error_popup msg { } proc makewindow {rargs} { - global canv canv2 canv3 linespc charspc ctext cflist textfont + global canv canv2 canv3 linespc charspc ctext cflist textfont mainfont uifont global findtype findtypemenu findloc findstring fstring geometry global entries sha1entry sha1string sha1but global maincursor textcursor curtextcursor @@ -354,16 +343,21 @@ proc makewindow {rargs} { menu .bar .bar add cascade -label "File" -menu .bar.file + .bar configure -font $uifont menu .bar.file .bar.file add command -label "Update" -command [list updatecommits $rargs] .bar.file add command -label "Reread references" -command rereadrefs .bar.file add command -label "Quit" -command doquit + .bar.file configure -font $uifont menu .bar.edit .bar add cascade -label "Edit" -menu .bar.edit .bar.edit add command -label "Preferences" -command doprefs + .bar.edit configure -font $uifont menu .bar.help .bar add cascade -label "Help" -menu .bar.help .bar.help add command -label "About gitk" -command about + .bar.help add command -label "Key bindings" -command keys + .bar.help configure -font $uifont . configure -menu .bar if {![info exists geometry(canv1)]} { @@ -410,7 +404,7 @@ proc makewindow {rargs} { set entries $sha1entry set sha1but .ctop.top.bar.sha1label button $sha1but -text "SHA1 ID: " -state disabled -relief flat \ - -command gotocommit -width 8 + -command gotocommit -width 8 -font $uifont $sha1but conf -disabledforeground [$sha1but cget -foreground] pack .ctop.top.bar.sha1label -side left entry $sha1entry -width 40 -font $textfont -textvariable sha1string @@ -440,19 +434,24 @@ proc makewindow {rargs} { -state disabled -width 26 pack .ctop.top.bar.rightbut -side left -fill y - button .ctop.top.bar.findbut -text "Find" -command dofind + button .ctop.top.bar.findbut -text "Find" -command dofind -font $uifont pack .ctop.top.bar.findbut -side left set findstring {} set fstring .ctop.top.bar.findstring lappend entries $fstring - entry $fstring -width 30 -font $textfont -textvariable findstring + entry $fstring -width 30 -font $textfont -textvariable findstring -font $textfont pack $fstring -side left -expand 1 -fill x set findtype Exact set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \ findtype Exact IgnCase Regexp] + .ctop.top.bar.findtype configure -font $uifont + .ctop.top.bar.findtype.menu configure -font $uifont set findloc "All fields" tk_optionMenu .ctop.top.bar.findloc findloc "All fields" Headline \ Comments Author Committer Files Pickaxe + .ctop.top.bar.findloc configure -font $uifont + .ctop.top.bar.findloc.menu configure -font $uifont + pack .ctop.top.bar.findloc -side right pack .ctop.top.bar.findtype -side right # for making sure type==Exact whenever loc==Pickaxe @@ -499,7 +498,7 @@ proc makewindow {rargs} { frame .ctop.cdet.right set cflist .ctop.cdet.right.cfiles listbox $cflist -bg white -selectmode extended -width $geometry(cflistw) \ - -yscrollcommand ".ctop.cdet.right.sb set" + -yscrollcommand ".ctop.cdet.right.sb set" -font $mainfont scrollbar .ctop.cdet.right.sb -command "$cflist yview" pack .ctop.cdet.right.sb -side right -fill y pack $cflist -side left -fill both -expand 1 @@ -514,12 +513,20 @@ proc makewindow {rargs} { bindall <ButtonRelease-5> "allcanvs yview scroll 5 units" bindall <2> "canvscan mark %W %x %y" bindall <B2-Motion> "canvscan dragto %W %x %y" + bindkey <Home> selfirstline + bindkey <End> sellastline bind . <Key-Up> "selnextline -1" bind . <Key-Down> "selnextline 1" - bind . <Key-Right> "goforw" - bind . <Key-Left> "goback" - bind . <Key-Prior> "allcanvs yview scroll -1 pages" - bind . <Key-Next> "allcanvs yview scroll 1 pages" + bindkey <Key-Right> "goforw" + bindkey <Key-Left> "goback" + bind . <Key-Prior> "selnextpage -1" + bind . <Key-Next> "selnextpage 1" + bind . <Control-Home> "allcanvs yview moveto 0.0" + bind . <Control-End> "allcanvs yview moveto 1.0" + bind . <Control-Key-Up> "allcanvs yview scroll -1 units" + bind . <Control-Key-Down> "allcanvs yview scroll 1 units" + bind . <Control-Key-Prior> "allcanvs yview scroll -1 pages" + bind . <Control-Key-Next> "allcanvs yview scroll 1 pages" bindkey <Key-Delete> "$ctext yview scroll -1 pages" bindkey <Key-BackSpace> "$ctext yview scroll -1 pages" bindkey <Key-space> "$ctext yview scroll 1 pages" @@ -612,7 +619,7 @@ proc click {w} { } proc savestuff {w} { - global canv canv2 canv3 ctext cflist mainfont textfont + global canv canv2 canv3 ctext cflist mainfont textfont uifont global stuffsaved findmergefiles maxgraphpct global maxwidth @@ -622,6 +629,7 @@ proc savestuff {w} { set f [open "~/.gitk-new" w] puts $f [list set mainfont $mainfont] puts $f [list set textfont $textfont] + puts $f [list set uifont $uifont] puts $f [list set findmergefiles $findmergefiles] puts $f [list set maxgraphpct $maxgraphpct] puts $f [list set maxwidth $maxwidth] @@ -729,6 +737,55 @@ Use and redistribute under the terms of the GNU General Public License} \ pack $w.ok -side bottom } +proc keys {} { + set w .keys + if {[winfo exists $w]} { + raise $w + return + } + toplevel $w + wm title $w "Gitk key bindings" + message $w.m -text { +Gitk key bindings: + +<Ctrl-Q> Quit +<Home> Move to first commit +<End> Move to last commit +<Up>, p, i Move up one commit +<Down>, n, k Move down one commit +<Left>, z, j Go back in history list +<Right>, x, l Go forward in history list +<PageUp> Move up one page in commit list +<PageDown> Move down one page in commit list +<Ctrl-Home> Scroll to top of commit list +<Ctrl-End> Scroll to bottom of commit list +<Ctrl-Up> Scroll commit list up one line +<Ctrl-Down> Scroll commit list down one line +<Ctrl-PageUp> Scroll commit list up one page +<Ctrl-PageDown> Scroll commit list down one page +<Delete>, b Scroll diff view up one page +<Backspace> Scroll diff view up one page +<Space> Scroll diff view down one page +u Scroll diff view up 18 lines +d Scroll diff view down 18 lines +<Ctrl-F> Find +<Ctrl-G> Move to next find hit +<Ctrl-R> Move to previous find hit +<Return> Move to next find hit +/ Move to next find hit, or redo find +? Move to previous find hit +f Scroll diff view to next file +<Ctrl-KP+> Increase font size +<Ctrl-plus> Increase font size +<Ctrl-KP-> Decrease font size +<Ctrl-minus> Decrease font size +} \ + -justify left -bg white -border 2 -relief sunken + pack $w.m -side top -fill both + button $w.ok -text Close -command "destroy $w" + pack $w.ok -side bottom +} + proc shortids {ids} { set res {} foreach id $ids { @@ -843,15 +900,20 @@ proc makeuparrow {oid x y z} { } proc initlayout {} { - global rowidlist rowoffsets displayorder + global rowidlist rowoffsets displayorder commitlisted global rowlaidout rowoptim global idinlist rowchk global commitidx numcommits canvxmax canv global nextcolor + global parentlist childlist children set commitidx 0 set numcommits 0 set displayorder {} + set commitlisted {} + set parentlist {} + set childlist {} + catch {unset children} set nextcolor 0 set rowidlist {{}} set rowoffsets {{}} @@ -950,7 +1012,7 @@ proc showstuff {canshow} { proc layoutrows {row endrow last} { global rowidlist rowoffsets displayorder global uparrowlen downarrowlen maxwidth mingaplen - global nchildren parents nparents + global childlist parentlist global idrowranges linesegends global commitidx global idinlist rowchk @@ -961,7 +1023,7 @@ proc layoutrows {row endrow last} { set id [lindex $displayorder $row] set oldolds {} set newolds {} - foreach p $parents($id) { + foreach p [lindex $parentlist $row] { if {![info exists idinlist($p)]} { lappend newolds $p } elseif {!$idinlist($p)} { @@ -1000,7 +1062,7 @@ proc layoutrows {row endrow last} { lappend idlist $id lset rowidlist $row $idlist set z {} - if {$nchildren($id) > 0} { + if {[lindex $childlist $row] ne {}} { set z [expr {[llength [lindex $rowidlist [expr {$row-1}]]] - $col}] unset idinlist($id) } @@ -1053,16 +1115,22 @@ proc layoutrows {row endrow last} { } proc addextraid {id row} { - global displayorder commitrow commitinfo nparents + global displayorder commitrow commitinfo global commitidx + global parentlist childlist children incr commitidx lappend displayorder $id + lappend parentlist {} set commitrow($id) $row readcommit $id if {![info exists commitinfo($id)]} { set commitinfo($id) {"No commit information available"} - set nparents($id) 0 + } + if {[info exists children($id)]} { + lappend childlist $children($id) + } else { + lappend childlist {} } } @@ -1365,7 +1433,7 @@ proc drawparentlinks {id row col olds} { proc drawlines {id} { global colormap canv global idrowranges idrangedrawn - global children iddrawn commitrow rowidlist + global childlist iddrawn commitrow rowidlist $canv delete lines.$id set nr [expr {[llength $idrowranges($id)] / 2}] @@ -1374,14 +1442,12 @@ proc drawlines {id} { drawlineseg $id $i } } - if {[info exists children($id)]} { - foreach child $children($id) { - if {[info exists iddrawn($child)]} { - set row $commitrow($child) - set col [lsearch -exact [lindex $rowidlist $row] $child] - if {$col >= 0} { - drawparentlinks $child $row $col [list $id] - } + foreach child [lindex $childlist $commitrow($id)] { + if {[info exists iddrawn($child)]} { + set row $commitrow($child) + set col [lsearch -exact [lindex $rowidlist $row] $child] + if {$col >= 0} { + drawparentlinks $child $row $col [list $id] } } } @@ -1394,7 +1460,7 @@ proc drawcmittext {id row col rmx} { global linehtag linentag linedtag global mainfont namefont canvxmax - set ofill [expr {[info exists commitlisted($id)]? "blue": "white"}] + set ofill [expr {[lindex $commitlisted $row]? "blue": "white"}] set x [xc $row $col] set y [yc $row] set orad [expr {$linespc / 3}] @@ -1434,7 +1500,7 @@ proc drawcmittext {id row col rmx} { proc drawcmitrow {row} { global displayorder rowidlist global idrowranges idrangedrawn iddrawn - global commitinfo commitlisted parents numcommits + global commitinfo commitlisted parentlist numcommits if {$row >= $numcommits} return foreach id [lindex $rowidlist $row] { @@ -1465,9 +1531,9 @@ proc drawcmitrow {row} { getcommit $id } assigncolor $id - if {[info exists commitlisted($id)] && [info exists parents($id)] - && $parents($id) ne {}} { - set rmx [drawparentlinks $id $row $col $parents($id)] + set olds [lindex $parentlist $row] + if {$olds ne {}} { + set rmx [drawparentlinks $id $row $col $olds] } else { set rmx 0 } @@ -1511,15 +1577,22 @@ proc clear_display {} { proc assigncolor {id} { global colormap colors nextcolor - global parents nparents children nchildren + global commitrow parentlist children childlist global cornercrossings crossings if {[info exists colormap($id)]} return set ncolors [llength $colors] - if {$nchildren($id) == 1} { - set child [lindex $children($id) 0] + if {[info exists commitrow($id)]} { + set kids [lindex $childlist $commitrow($id)] + } elseif {[info exists children($id)]} { + set kids $children($id) + } else { + set kids {} + } + if {[llength $kids] == 1} { + set child [lindex $kids 0] if {[info exists colormap($child)] - && $nparents($child) == 1} { + && [llength [lindex $parentlist $commitrow($child)]] == 1} { set colormap($id) $colormap($child) return } @@ -1552,17 +1625,15 @@ proc assigncolor {id} { set origbad $badcolors } if {[llength $badcolors] < $ncolors - 1} { - foreach child $children($id) { + foreach child $kids { if {[info exists colormap($child)] && [lsearch -exact $badcolors $colormap($child)] < 0} { lappend badcolors $colormap($child) } - if {[info exists parents($child)]} { - foreach p $parents($child) { - if {[info exists colormap($p)] - && [lsearch -exact $badcolors $colormap($p)] < 0} { - lappend badcolors $colormap($p) - } + foreach p [lindex $parentlist $commitrow($child)] { + if {[info exists colormap($p)] + && [lsearch -exact $badcolors $colormap($p)] < 0} { + lappend badcolors $colormap($p) } } } @@ -1657,14 +1728,14 @@ proc drawtags {id x xt y1} { } proc checkcrossings {row endrow} { - global displayorder parents rowidlist + global displayorder parentlist rowidlist for {} {$row < $endrow} {incr row} { set id [lindex $displayorder $row] set i [lsearch -exact [lindex $rowidlist $row] $id] if {$i < 0} continue set idlist [lindex $rowidlist [expr {$row+1}]] - foreach p $parents($id) { + foreach p [lindex $parentlist $row] { set j [lsearch -exact $idlist $p] if {$j > 0} { if {$j < $i - 1} { @@ -2046,7 +2117,7 @@ proc insertmatch {l id} { proc findfiles {} { global selectedline numcommits displayorder ctext - global ffileline finddidsel parents nparents + global ffileline finddidsel parentlist global findinprogress findstartline findinsertpos global treediffs fdiffid fdiffsneeded fdiffpos global findmergefiles @@ -2064,7 +2135,7 @@ proc findfiles {} { set fdiffsneeded {} while 1 { set id [lindex $displayorder $l] - if {$findmergefiles || $nparents($id) == 1} { + if {$findmergefiles || [llength [lindex $parentlist $l]] == 1} { if {![info exists treediffs($id)]} { append diffsneeded "$id\n" lappend fdiffsneeded $id @@ -2096,7 +2167,7 @@ proc findfiles {} { . config -cursor watch settextcursor watch set findinprogress 1 - findcont $id + findcont update } @@ -2143,7 +2214,7 @@ proc donefilediff {} { set treediffs($nullid) {} if {[info exists findid] && $nullid eq $findid} { unset findid - findcont $nullid + findcont } incr fdiffpos } @@ -2154,20 +2225,21 @@ proc donefilediff {} { } if {[info exists findid] && $fdiffid eq $findid} { unset findid - findcont $fdiffid + findcont } } } proc findcont {id} { - global findid treediffs parents nparents + global findid treediffs parentlist global ffileline findstartline finddidsel global displayorder numcommits matchinglines findinprogress global findmergefiles set l $ffileline - while 1 { - if {$findmergefiles || $nparents($id) == 1} { + while {1} { + set id [lindex $displayorder $l] + if {$findmergefiles || [llength [lindex $parentlist $l]] == 1} { if {![info exists treediffs($id)]} { set findid $id set ffileline $l @@ -2189,7 +2261,6 @@ proc findcont {id} { set l 0 } if {$l == $findstartline} break - set id [lindex $displayorder $l] } stopfindproc if {!$finddidsel} { @@ -2286,10 +2357,26 @@ proc appendwithlinks {text} { $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor } } +proc viewnextline {dir} { + global canv linespc + + $canv delete hover + set ymax [lindex [$canv cget -scrollregion] 3] + set wnow [$canv yview] + set wtop [expr {[lindex $wnow 0] * $ymax}] + set newtop [expr {$wtop + $dir * $linespc}] + if {$newtop < 0} { + set newtop 0 + } elseif {$newtop > $ymax} { + set newtop $ymax + } + allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}] +} + proc selectline {l isnew} { global canv canv2 canv3 ctext commitinfo selectedline global displayorder linehtag linentag linedtag - global canvy0 linespc parents nparents children + global canvy0 linespc parentlist childlist global cflist currentid sha1entry global commentend idtags linknum global mergemax numcommits @@ -2379,9 +2466,10 @@ proc selectline {l isnew} { } set comment {} - if {$nparents($id) > 1} { + set olds [lindex $parentlist $l] + if {[llength $olds] > 1} { set np 0 - foreach p $parents($id) { + foreach p $olds { if {$np >= $mergemax} { set tag mmax } else { @@ -2392,17 +2480,13 @@ proc selectline {l isnew} { incr np } } else { - if {[info exists parents($id)]} { - foreach p $parents($id) { - append comment "Parent: [commit_descriptor $p]\n" - } + foreach p $olds { + append comment "Parent: [commit_descriptor $p]\n" } } - if {[info exists children($id)]} { - foreach c $children($id) { - append comment "Child: [commit_descriptor $c]\n" - } + foreach c [lindex $childlist $l] { + append comment "Child: [commit_descriptor $c]\n" } append comment "\n" append comment [lindex $info 5] @@ -2417,13 +2501,25 @@ proc selectline {l isnew} { $cflist delete 0 end $cflist insert end "Comments" - if {$nparents($id) <= 1} { + if {[llength $olds] <= 1} { startdiff $id } else { - mergediff $id + mergediff $id $l } } +proc selfirstline {} { + unmarkmatches + selectline 0 1 +} + +proc sellastline {} { + global numcommits + unmarkmatches + set l [expr {$numcommits - 1}] + selectline $l 1 +} + proc selnextline {dir} { global selectedline if {![info exists selectedline]} return @@ -2432,6 +2528,25 @@ proc selnextline {dir} { selectline $l 1 } +proc selnextpage {dir} { + global canv linespc selectedline numcommits + + set lpp [expr {([winfo height $canv] - 2) / $linespc}] + if {$lpp < 1} { + set lpp 1 + } + allcanvs yview scroll [expr {$dir * $lpp}] units + if {![info exists selectedline]} return + set l [expr {$selectedline + $dir * $lpp}] + if {$l < 0} { + set l 0 + } elseif {$l >= $numcommits} { + set l [expr $numcommits - 1] + } + unmarkmatches + selectline $l 1 +} + proc unselectline {} { global selectedline @@ -2489,9 +2604,10 @@ proc goforw {} { } } -proc mergediff {id} { - global parents diffmergeid diffopts mdifffd +proc mergediff {id l} { + global diffmergeid diffopts mdifffd global difffilestart diffids + global parentlist set diffmergeid $id set diffids $id @@ -2505,12 +2621,13 @@ proc mergediff {id} { } fconfigure $mdf -blocking 0 set mdifffd($id) $mdf - fileevent $mdf readable [list getmergediffline $mdf $id] + set np [llength [lindex $parentlist $l]] + fileevent $mdf readable [list getmergediffline $mdf $id $np] set nextupdate [expr {[clock clicks -milliseconds] + 100}] } -proc getmergediffline {mdf id} { - global diffmergeid ctext cflist nextupdate nparents mergemax +proc getmergediffline {mdf id np} { + global diffmergeid ctext cflist nextupdate mergemax global difffilestart mdifffd set n [gets $mdf line] @@ -2543,7 +2660,6 @@ proc getmergediffline {mdf id} { # do nothing } else { # parse the prefix - one ' ', '-' or '+' for each parent - set np $nparents($id) set spaces {} set minuses {} set pluses {} @@ -2611,7 +2727,7 @@ proc addtocflist {ids} { } proc gettreediffs {ids} { - global treediff parents treepending + global treediff treepending set treepending $ids set treediff {} if {[catch \ @@ -2846,13 +2962,15 @@ proc sha1change {n1 n2 op} { } proc gotocommit {} { - global sha1string currentid commitrow tagids + global sha1string currentid commitrow tagids headids global displayorder numcommits if {$sha1string == {} || ([info exists currentid] && $sha1string == $currentid)} return if {[info exists tagids($sha1string)]} { set id $tagids($sha1string) + } elseif {[info exists headids($sha1string)]} { + set id $headids($sha1string) } else { set id [string tolower $sha1string] if {[regexp {^[0-9a-f]{4,39}$} $id]} { @@ -2878,7 +2996,7 @@ proc gotocommit {} { if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} { set type "SHA1 id" } else { - set type "Tag" + set type "Tag/Head" } error_popup "$type $sha1string is not known" } @@ -2979,7 +3097,7 @@ proc arrowjump {id n y} { } proc lineclick {x y id isnew} { - global ctext commitinfo children cflist canv thickerline + global ctext commitinfo childlist commitrow cflist canv thickerline if {![info exists commitinfo($id)] && ![getcommit $id]} return unmarkmatches @@ -3018,10 +3136,11 @@ proc lineclick {x y id isnew} { $ctext insert end "\tAuthor:\t[lindex $info 1]\n" set date [formatdate [lindex $info 2]] $ctext insert end "\tDate:\t$date\n" - if {[info exists children($id)]} { + set kids [lindex $childlist $commitrow($id)] + if {$kids ne {}} { $ctext insert end "\nChildren:" set i 0 - foreach child $children($id) { + foreach child $kids { incr i if {![info exists commitinfo($child)] && ![getcommit $child]} continue set info $commitinfo($child) @@ -3368,7 +3487,6 @@ proc listrefs {id} { proc rereadrefs {} { global idtags idheads idotherrefs - global tagids headids otherrefids set refids [concat [array names idtags] \ [array names idheads] [array names idotherrefs]] @@ -3777,6 +3895,7 @@ if {$tclencoding == {}} { set mainfont {Helvetica 9} set textfont {Courier 9} +set uifont {Helvetica 9 bold} set findmergefiles 0 set maxgraphpct 50 set maxwidth 16 @@ -195,6 +195,8 @@ static CURL* get_curl_handle(void) if (getenv("GIT_CURL_VERBOSE")) curl_easy_setopt(result, CURLOPT_VERBOSE, 1); + curl_easy_setopt(result, CURLOPT_USERAGENT, GIT_USER_AGENT); + return result; } diff --git a/imap-send.c b/imap-send.c index f3cb79b1f8..52e2400b57 100644 --- a/imap-send.c +++ b/imap-send.c @@ -1202,6 +1202,7 @@ read_message( FILE *f, msg_data_t *msg ) p = xrealloc(msg->data, len+1); if (!p) break; + msg->data = p; } r = fread( &msg->data[msg->len], 1, len - msg->len, f ); if (r <= 0) @@ -1332,6 +1333,12 @@ main(int argc, char **argv) return 1; } + total = count_messages( &all_msgs ); + if (!total) { + fprintf(stderr,"no messages to send\n"); + return 1; + } + /* write it to the imap server */ ctx = imap_open_store( &server ); if (!ctx) { @@ -1339,7 +1346,6 @@ main(int argc, char **argv) return 1; } - total = count_messages( &all_msgs ); fprintf( stderr, "sending %d message%s\n", total, (total!=1)?"s":"" ); ctx->name = imap_folder; while (1) { diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c index 8ea04837ec..e81bca633e 100644 --- a/xdiff/xdiffi.c +++ b/xdiff/xdiffi.c @@ -349,12 +349,7 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, kvdf += xe->xdf2.nreff + 1; kvdb += xe->xdf2.nreff + 1; - /* - * Classical integer square root approximation using shifts. - */ - xenv.mxcost = 1; - for (; ndiags; ndiags >>= 2) - xenv.mxcost <<= 1; + xenv.mxcost = xdl_bogosqrt(ndiags); if (xenv.mxcost < XDL_MAX_COST_MIN) xenv.mxcost = XDL_MAX_COST_MIN; xenv.snake_cnt = XDL_SNAKE_CNT; diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c index 27a08791a2..add5a75c77 100644 --- a/xdiff/xprepare.c +++ b/xdiff/xprepare.c @@ -25,6 +25,7 @@ #define XDL_KPDIS_RUN 4 +#define XDL_MAX_EQLIMIT 1024 @@ -305,26 +306,48 @@ void xdl_free_env(xdfenv_t *xe) { static int xdl_clean_mmatch(char const *dis, long i, long s, long e) { - long r, rdis, rpdis; - - for (r = 1, rdis = 0, rpdis = 1; (i - r) >= s; r++) { + long r, rdis0, rpdis0, rdis1, rpdis1; + + /* + * Scans the lines before 'i' to find a run of lines that either + * have no match (dis[j] == 0) or have multiple matches (dis[j] > 1). + * Note that we always call this function with dis[i] > 1, so the + * current line (i) is already a multimatch line. + */ + for (r = 1, rdis0 = 0, rpdis0 = 1; (i - r) >= s; r++) { if (!dis[i - r]) - rdis++; + rdis0++; else if (dis[i - r] == 2) - rpdis++; + rpdis0++; else break; } - for (r = 1; (i + r) <= e; r++) { + /* + * If the run before the line 'i' found only multimatch lines, we + * return 0 and hence we don't make the current line (i) discarded. + * We want to discard multimatch lines only when they appear in the + * middle of runs with nomatch lines (dis[j] == 0). + */ + if (rdis0 == 0) + return 0; + for (r = 1, rdis1 = 0, rpdis1 = 1; (i + r) <= e; r++) { if (!dis[i + r]) - rdis++; + rdis1++; else if (dis[i + r] == 2) - rpdis++; + rpdis1++; else break; } - - return rpdis * XDL_KPDIS_RUN < (rpdis + rdis); + /* + * If the run after the line 'i' found only multimatch lines, we + * return 0 and hence we don't make the current line (i) discarded. + */ + if (rdis1 == 0) + return 0; + rdis1 += rdis0; + rpdis1 += rpdis0; + + return rpdis1 * XDL_KPDIS_RUN < (rpdis1 + rdis1); } @@ -334,34 +357,40 @@ static int xdl_clean_mmatch(char const *dis, long i, long s, long e) { * might be potentially discarded if they happear in a run of discardable. */ static int xdl_cleanup_records(xdfile_t *xdf1, xdfile_t *xdf2) { - long i, rhi, nreff; + long i, nm, rhi, nreff, mlim; unsigned long hav; xrecord_t **recs; xrecord_t *rec; char *dis, *dis1, *dis2; - if (!(dis = (char *) xdl_malloc((xdf1->nrec + xdf2->nrec + 2) * sizeof(char)))) { + if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) { return -1; } - memset(dis, 0, (xdf1->nrec + xdf2->nrec + 2) * sizeof(char)); + memset(dis, 0, xdf1->nrec + xdf2->nrec + 2); dis1 = dis; dis2 = dis1 + xdf1->nrec + 1; + if ((mlim = xdl_bogosqrt(xdf1->nrec)) > XDL_MAX_EQLIMIT) + mlim = XDL_MAX_EQLIMIT; for (i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart]; i <= xdf1->dend; i++, recs++) { hav = (*recs)->ha; rhi = (long) XDL_HASHLONG(hav, xdf2->hbits); - for (rec = xdf2->rhash[rhi]; rec; rec = rec->next) - if (rec->ha == hav && ++dis1[i] == 2) + for (nm = 0, rec = xdf2->rhash[rhi]; rec; rec = rec->next) + if (rec->ha == hav && ++nm == mlim) break; + dis1[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1; } + if ((mlim = xdl_bogosqrt(xdf2->nrec)) > XDL_MAX_EQLIMIT) + mlim = XDL_MAX_EQLIMIT; for (i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart]; i <= xdf2->dend; i++, recs++) { hav = (*recs)->ha; rhi = (long) XDL_HASHLONG(hav, xdf1->hbits); - for (rec = xdf1->rhash[rhi]; rec; rec = rec->next) - if (rec->ha == hav && ++dis2[i] == 2) + for (nm = 0, rec = xdf1->rhash[rhi]; rec; rec = rec->next) + if (rec->ha == hav && ++nm == mlim) break; + dis2[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1; } for (nreff = 0, i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart]; diff --git a/xdiff/xutils.c b/xdiff/xutils.c index afaada1edf..21ab8e7e26 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -29,6 +29,19 @@ +long xdl_bogosqrt(long n) { + long i; + + /* + * Classical integer square root approximation using shifts. + */ + for (i = 1; n > 0; n >>= 2) + i <<= 1; + + return i; +} + + int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize, xdemitcb_t *ecb) { mmbuffer_t mb[3]; @@ -244,7 +257,7 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, memcpy(buf, "@@ -", 4); nb += 4; - nb += xdl_num_out(buf + nb, c1 ? s1: 0); + nb += xdl_num_out(buf + nb, c1 ? s1: s1 - 1); if (c1 != 1) { memcpy(buf + nb, ",", 1); @@ -256,7 +269,7 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, memcpy(buf + nb, " +", 2); nb += 2; - nb += xdl_num_out(buf + nb, c2 ? s2: 0); + nb += xdl_num_out(buf + nb, c2 ? s2: s2 - 1); if (c2 != 1) { memcpy(buf + nb, ",", 1); diff --git a/xdiff/xutils.h b/xdiff/xutils.h index 55b0d39f49..ea38ee903f 100644 --- a/xdiff/xutils.h +++ b/xdiff/xutils.h @@ -24,6 +24,7 @@ #define XUTILS_H +long xdl_bogosqrt(long n); int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize, xdemitcb_t *ecb); int xdl_cha_init(chastore_t *cha, long isize, long icount); |