From f8a2c0d14f5326e157b12ec549b864ddb492621d Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 5 Jul 2006 22:56:37 +1000 Subject: gitk: Allow the user to set some colors This makes the colors for the diff old/new lines and hunk headers configurable, as well as the background and foreground (text color) of the various panes. There is now a GUI in the edit->preferences window to set them. Signed-off-by: Paul Mackerras --- gitk | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 101 insertions(+), 23 deletions(-) diff --git a/gitk b/gitk index ba4644f45..d1adb9de4 100755 --- a/gitk +++ b/gitk @@ -386,6 +386,7 @@ proc makewindow {} { global rowctxmenu mergemax wrapcomment global highlight_files gdttype global searchstring sstring + global bgcolor fgcolor bglist fglist diffcolors menu .bar .bar add cascade -label "File" -menu .bar.file @@ -446,18 +447,19 @@ proc makewindow {} { .ctop add .ctop.top set canv .ctop.top.clist.canv canvas $canv -height $geometry(canvh) -width $geometry(canv1) \ - -bg white -bd 0 \ + -background $bgcolor -bd 0 \ -yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll" .ctop.top.clist add $canv set canv2 .ctop.top.clist.canv2 canvas $canv2 -height $geometry(canvh) -width $geometry(canv2) \ - -bg white -bd 0 -yscrollincr $linespc + -background $bgcolor -bd 0 -yscrollincr $linespc .ctop.top.clist add $canv2 set canv3 .ctop.top.clist.canv3 canvas $canv3 -height $geometry(canvh) -width $geometry(canv3) \ - -bg white -bd 0 -yscrollincr $linespc + -background $bgcolor -bd 0 -yscrollincr $linespc .ctop.top.clist add $canv3 bind .ctop.top.clist {resizeclistpanes %W %w} + lappend bglist $canv $canv2 $canv3 set sha1entry .ctop.top.bar.sha1 set entries $sha1entry @@ -563,19 +565,22 @@ proc makewindow {} { trace add variable searchstring write incrsearch pack $sstring -side left -expand 1 -fill x set ctext .ctop.cdet.left.ctext - text $ctext -bg white -state disabled -font $textfont \ + text $ctext -background $bgcolor -foreground $fgcolor \ + -state disabled -font $textfont \ -width $geometry(ctextw) -height $geometry(ctexth) \ -yscrollcommand scrolltext -wrap none scrollbar .ctop.cdet.left.sb -command "$ctext yview" pack .ctop.cdet.left.sb -side right -fill y pack $ctext -side left -fill both -expand 1 .ctop.cdet add .ctop.cdet.left + lappend bglist $ctext + lappend fglist $ctext $ctext tag conf comment -wrap $wrapcomment $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa" - $ctext tag conf hunksep -fore blue - $ctext tag conf d0 -fore red - $ctext tag conf d1 -fore "#00a000" + $ctext tag conf hunksep -fore [lindex $diffcolors 2] + $ctext tag conf d0 -fore [lindex $diffcolors 0] + $ctext tag conf d1 -fore [lindex $diffcolors 1] $ctext tag conf m0 -fore red $ctext tag conf m1 -fore blue $ctext tag conf m2 -fore green @@ -608,11 +613,15 @@ proc makewindow {} { pack .ctop.cdet.right.mode -side top -fill x set cflist .ctop.cdet.right.cfiles set indent [font measure $mainfont "nn"] - text $cflist -width $geometry(cflistw) -background white -font $mainfont \ + text $cflist -width $geometry(cflistw) \ + -background $bgcolor -foreground $fgcolor \ + -font $mainfont \ -tabs [list $indent [expr {2 * $indent}]] \ -yscrollcommand ".ctop.cdet.right.sb set" \ -cursor [. cget -cursor] \ -spacing1 1 -spacing3 1 + lappend bglist $cflist + lappend fglist $cflist 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 @@ -747,6 +756,7 @@ proc savestuff {w} { global maxwidth showneartags global viewname viewfiles viewargs viewperm nextviewnum global cmitmode wrapcomment + global colors bgcolor fgcolor diffcolors if {$stuffsaved} return if {![winfo viewable .]} return @@ -761,6 +771,10 @@ proc savestuff {w} { puts $f [list set cmitmode $cmitmode] puts $f [list set wrapcomment $wrapcomment] puts $f [list set showneartags $showneartags] + puts $f [list set bgcolor $bgcolor] + puts $f [list set fgcolor $fgcolor] + puts $f [list set colors $colors] + puts $f [list set diffcolors $diffcolors] puts $f "set geometry(width) [winfo width .ctop]" puts $f "set geometry(height) [winfo height .ctop]" puts $f "set geometry(canv1) [expr {[winfo width $canv]-2}]" @@ -2870,11 +2884,11 @@ proc drawlines {id} { } proc drawcmittext {id row col rmx} { - global linespc canv canv2 canv3 canvy0 + global linespc canv canv2 canv3 canvy0 fgcolor global commitlisted commitinfo rowidlist global rowtextx idpos idtags idheads idotherrefs global linehtag linentag linedtag - global mainfont canvxmax boldrows boldnamerows + global mainfont canvxmax boldrows boldnamerows fgcolor set ofill [expr {[lindex $commitlisted $row]? "blue": "white"}] set x [xc $row $col] @@ -2882,7 +2896,7 @@ proc drawcmittext {id row col rmx} { set orad [expr {$linespc / 3}] set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \ [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \ - -fill $ofill -outline black -width 1] + -fill $ofill -outline $fgcolor -width 1 -tags circle] $canv raise $t $canv bind $t <1> {selcanvline {} %x %y} set xt [xc $row [llength [lindex $rowidlist $row]]] @@ -2910,13 +2924,13 @@ proc drawcmittext {id row col rmx} { lappend nfont bold } } - set linehtag($row) [$canv create text $xt $y -anchor w \ - -text $headline -font $font] + set linehtag($row) [$canv create text $xt $y -anchor w -fill $fgcolor \ + -text $headline -font $font -tags text] $canv bind $linehtag($row) "rowmenu %X %Y $id" - set linentag($row) [$canv2 create text 3 $y -anchor w \ - -text $name -font $nfont] - set linedtag($row) [$canv3 create text 3 $y -anchor w \ - -text $date -font $mainfont] + set linentag($row) [$canv2 create text 3 $y -anchor w -fill $fgcolor \ + -text $name -font $nfont -tags text] + set linedtag($row) [$canv3 create text 3 $y -anchor w -fill $fgcolor \ + -text $date -font $mainfont -tags text] set xr [expr {$xt + [font measure $mainfont $headline]}] if {$xr > $canvxmax} { set canvxmax $xr @@ -3138,7 +3152,7 @@ proc bindline {t id} { proc drawtags {id x xt y1} { global idtags idheads idotherrefs global linespc lthickness - global canv mainfont commitrow rowtextx curview + global canv mainfont commitrow rowtextx curview fgcolor set marks {} set ntags 0 @@ -3201,8 +3215,8 @@ proc drawtags {id x xt y1} { -width 0 -fill "#ffddaa" -tags tag.$id } } - set t [$canv create text $xl $y1 -anchor w -text $tag \ - -font $mainfont -tags tag.$id] + set t [$canv create text $xl $y1 -anchor w -text $tag -fill $fgcolor \ + -font $mainfont -tags [list tag.$id text]] if {$ntags >= 0} { $canv bind $t <1> [list showtag $tag 1] } @@ -3223,10 +3237,11 @@ proc xcoord {i level ln} { } proc show_status {msg} { - global canv mainfont + global canv mainfont fgcolor clear_display - $canv create text 3 3 -anchor nw -text $msg -font $mainfont -tags textitems + $canv create text 3 3 -anchor nw -text $msg -font $mainfont \ + -tags text -fill $fgcolor } proc finishcommits {} { @@ -4574,7 +4589,8 @@ proc linehover {} { set t [$canv create rectangle $x0 $y0 $x1 $y1 \ -fill \#ffff80 -outline black -width 1 -tags hover] $canv raise $t - set t [$canv create text $x $y -anchor nw -text $text -tags hover -font $mainfont] + set t [$canv create text $x $y -anchor nw -text $text -tags hover \ + -font $mainfont] $canv raise $t } @@ -5242,6 +5258,7 @@ proc doquit {} { proc doprefs {} { global maxwidth maxgraphpct diffopts global oldprefs prefstop showneartags + global bgcolor fgcolor ctext diffcolors set top .gitkprefs set prefstop $top @@ -5265,6 +5282,7 @@ proc doprefs {} { -font optionfont spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct grid x $top.maxpctl $top.maxpct -sticky w + label $top.ddisp -text "Diff display options" grid $top.ddisp - -sticky w -pady 10 label $top.diffoptl -text "Options for diff program" \ @@ -5276,6 +5294,34 @@ proc doprefs {} { checkbutton $top.ntag.b -variable showneartags pack $top.ntag.b $top.ntag.l -side left grid x $top.ntag -sticky w + + label $top.cdisp -text "Colors: press to choose" + grid $top.cdisp - -sticky w -pady 10 + label $top.bg -padx 40 -relief sunk -background $bgcolor + button $top.bgbut -text "Background" -font optionfont \ + -command [list choosecolor bgcolor 0 $top.bg background setbg] + grid x $top.bgbut $top.bg -sticky w + label $top.fg -padx 40 -relief sunk -background $fgcolor + button $top.fgbut -text "Foreground" -font optionfont \ + -command [list choosecolor fgcolor 0 $top.fg foreground setfg] + grid x $top.fgbut $top.fg -sticky w + label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0] + button $top.diffoldbut -text "Diff: old lines" -font optionfont \ + -command [list choosecolor diffcolors 0 $top.diffold "diff old lines" \ + [list $ctext tag conf d0 -foreground]] + grid x $top.diffoldbut $top.diffold -sticky w + label $top.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1] + button $top.diffnewbut -text "Diff: new lines" -font optionfont \ + -command [list choosecolor diffcolors 1 $top.diffnew "diff new lines" \ + [list $ctext tag conf d1 -foreground]] + grid x $top.diffnewbut $top.diffnew -sticky w + label $top.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2] + button $top.hunksepbut -text "Diff: hunk header" -font optionfont \ + -command [list choosecolor diffcolors 2 $top.hunksep \ + "diff hunk header" \ + [list $ctext tag conf hunksep -foreground]] + grid x $top.hunksepbut $top.hunksep -sticky w + frame $top.buts button $top.buts.ok -text "OK" -command prefsok button $top.buts.can -text "Cancel" -command prefscan @@ -5285,6 +5331,35 @@ proc doprefs {} { grid $top.buts - - -pady 10 -sticky ew } +proc choosecolor {v vi w x cmd} { + global $v + + set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \ + -title "Gitk: choose color for $x"] + if {$c eq {}} return + $w conf -background $c + lset $v $vi $c + eval $cmd $c +} + +proc setbg {c} { + global bglist + + foreach w $bglist { + $w conf -background $c + } +} + +proc setfg {c} { + global fglist canv + + foreach w $fglist { + $w conf -foreground $c + } + allcanvs itemconf text -fill $c + $canv itemconf circle -outline $c +} + proc prefscan {} { global maxwidth maxgraphpct diffopts global oldprefs prefstop showneartags @@ -5620,6 +5695,9 @@ set wrapcomment "none" set showneartags 1 set colors {green red blue magenta darkgrey brown orange} +set bgcolor white +set fgcolor black +set diffcolors {red "#00a000" blue} catch {source ~/.gitk} -- cgit v1.2.1 From 8a48571ce52e5182ea32ed168e298882f8c470b3 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 6 Jul 2006 10:21:23 +1000 Subject: gitk: Show the currently checked-out head in bold font Signed-off-by: Paul Mackerras --- gitk | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/gitk b/gitk index d1adb9de4..7d540c1b0 100755 --- a/gitk +++ b/gitk @@ -312,7 +312,7 @@ proc getcommit {id} { proc readrefs {} { global tagids idtags headids idheads tagcontents - global otherrefids idotherrefs + global otherrefids idotherrefs mainhead foreach v {tagids idtags headids idheads otherrefids idotherrefs} { catch {unset $v} @@ -358,6 +358,13 @@ proc readrefs {} { } } close $refd + set mainhead {} + catch { + set thehead [exec git symbolic-ref HEAD] + if {[string match "refs/heads/*" $thehead]} { + set mainhead [string range $thehead 11 end] + } + } } proc show_error {w top msg} { @@ -3150,9 +3157,9 @@ proc bindline {t id} { } proc drawtags {id x xt y1} { - global idtags idheads idotherrefs + global idtags idheads idotherrefs mainhead global linespc lthickness - global canv mainfont commitrow rowtextx curview fgcolor + global canv mainfont commitrow rowtextx curview fgcolor bgcolor set marks {} set ntags 0 @@ -3177,8 +3184,14 @@ proc drawtags {id x xt y1} { set yb [expr {$yt + $linespc - 1}] set xvals {} set wvals {} + set i -1 foreach tag $marks { - set wid [font measure $mainfont $tag] + incr i + if {$i >= $ntags && $i < $ntags + $nheads && $tag eq $mainhead} { + set wid [font measure [concat $mainfont bold] $tag] + } else { + set wid [font measure $mainfont $tag] + } lappend xvals $xt lappend wvals $wid set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}] @@ -3189,6 +3202,7 @@ proc drawtags {id x xt y1} { foreach tag $marks x $xvals wid $wvals { set xl [expr {$x + $delta}] set xr [expr {$x + $delta + $wid + $lthickness}] + set font $mainfont if {[incr ntags -1] >= 0} { # draw a tag set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \ @@ -3200,6 +3214,9 @@ proc drawtags {id x xt y1} { # draw a head or other ref if {[incr nheads -1] >= 0} { set col green + if {$tag eq $mainhead} { + lappend font bold + } } else { set col "#ddddff" } @@ -3216,7 +3233,7 @@ proc drawtags {id x xt y1} { } } set t [$canv create text $xl $y1 -anchor w -text $tag -fill $fgcolor \ - -font $mainfont -tags [list tag.$id text]] + -font $font -tags [list tag.$id text]] if {$ntags >= 0} { $canv bind $t <1> [list showtag $tag 1] } -- cgit v1.2.1 From a0764cb838c2f1885fb58ca794c21523fb05c825 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Tue, 18 Jul 2006 19:14:51 +0200 Subject: upload-pack: fix timeout in create_pack_file Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- upload-pack.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/upload-pack.c b/upload-pack.c index b18eb9ba0..638e257c9 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -178,6 +178,8 @@ static void create_pack_file(void) ssize_t sz; int pe, pu, pollsize; + reset_timeout(); + pollsize = 0; pe = pu = -1; -- cgit v1.2.1 From 83c31614ceae2612b7cdba40e6401716fe854cd2 Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Thu, 27 Jul 2006 10:32:25 +0100 Subject: rebase: Fix the detection of fast-forwarding of the current branch to upstream. Previously, a rebasing operation with on a branch that is just tracking an upstream branch would output a confusing "Nothing to do" due to no patches being given to git-am. The test brings the behaviour back into line with that of just before e646c9c8c0aa995eac284ea0a2117add19c4461c. Signed-off-by: Robert Shearman Signed-off-by: Junio C Hamano --- git-rebase.sh | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/git-rebase.sh b/git-rebase.sh index 29028dd5f..240032f32 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -266,14 +266,11 @@ onto=$(git-rev-parse --verify "${onto_name}^0") || exit # Check if we are already based on $onto, but this should be # done only when upstream and onto are the same. -if test "$upstream" = "$onto" +mb=$(git-merge-base "$onto" "$branch") +if test "$upstream" = "$onto" && test "$mb" = "$onto" then - mb=$(git-merge-base "$onto" "$branch") - if test "$mb" = "$onto" - then - echo >&2 "Current branch $branch_name is up to date." - exit 0 - fi + echo >&2 "Current branch $branch_name is up to date." + exit 0 fi # Rewind the head to "$onto"; this saves our current head in ORIG_HEAD. @@ -281,7 +278,7 @@ git-reset --hard "$onto" # If the $onto is a proper descendant of the tip of the branch, then # we just fast forwarded. -if test "$mb" = "$onto" +if test "$mb" = "$branch" then echo >&2 "Fast-forwarded $branch to $newbase." exit 0 -- cgit v1.2.1 From d587ed13bc37550a6d21067127f6c057c5d5e7fc Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Thu, 27 Jul 2006 10:32:46 +0100 Subject: rebase: Make the fast-fowarding message more user-friendly by using branch names instead of SHA1 IDs. Signed-off-by: Robert Shearman Signed-off-by: Junio C Hamano --- git-rebase.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-rebase.sh b/git-rebase.sh index 240032f32..7d3a5d0e7 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -280,7 +280,7 @@ git-reset --hard "$onto" # we just fast forwarded. if test "$mb" = "$branch" then - echo >&2 "Fast-forwarded $branch to $newbase." + echo >&2 "Fast-forwarded $branch_name to $onto_name." exit 0 fi -- cgit v1.2.1 From 2608003f55ca3e02cfdcafbec54fdd325340a78e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 31 Jul 2006 03:07:12 -0700 Subject: git-checkout: allow "checkout HEAD -- path" Even though -- is redundant in this case, we should allow it to prevent confusion. Signed-off-by: Junio C Hamano --- git-checkout.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/git-checkout.sh b/git-checkout.sh index 5613bfc40..580a9e8a2 100755 --- a/git-checkout.sh +++ b/git-checkout.sh @@ -67,6 +67,10 @@ while [ "$#" != "0" ]; do set x "$arg" "$@" shift fi + case "$1" in + --) + shift ;; + esac break ;; esac -- cgit v1.2.1 From 7f8508e8d320d768a34483682e9f2dc5af1af04b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 31 Jul 2006 09:55:15 -0700 Subject: Fix double "close()" in ce_compare_data Doing an "strace" on "git diff" shows that we close() a file descriptor twice (getting EBADFD on the second one) when we end up in ce_compare_data if the index does not match the checked-out stat information. The "index_fd()" function will already have closed the fd for us, so we should not close it again. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- read-cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/read-cache.c b/read-cache.c index c0b031367..f92cdaace 100644 --- a/read-cache.c +++ b/read-cache.c @@ -61,7 +61,7 @@ static int ce_compare_data(struct cache_entry *ce, struct stat *st) unsigned char sha1[20]; if (!index_fd(sha1, fd, st, 0, NULL)) match = memcmp(sha1, ce->sha1, 20); - close(fd); + /* index_fd() closed the file descriptor already */ } return match; } -- cgit v1.2.1 From 3e04228b0c4bbb4b5cd46db9a714dfe699fa4cb8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 31 Jul 2006 13:13:55 -0700 Subject: Fix up some fallout from "setup_git_directory()" cleanups git-ls-files was broken by the setup_git_directory() calling changes, because I had missed the fact that the "prefix" variable in that file was static to the whole file, and unlike git-ls-tree (where I had fixed it up), it ended up using two different variables with the same name depending on what the scoping happened to be. This fixes it up properly (by just removing the static variable, and passing the automatic one around properly), and git-ls-files should work again. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin-ls-files.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/builtin-ls-files.c b/builtin-ls-files.c index 79ffe8f42..11386c432 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -24,7 +24,6 @@ static int show_valid_bit = 0; static int line_terminator = '\n'; static int prefix_len = 0, prefix_offset = 0; -static const char *prefix = NULL; static const char **pathspec = NULL; static int error_unmatch = 0; static char *ps_matched = NULL; @@ -207,7 +206,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce) } } -static void show_files(struct dir_struct *dir) +static void show_files(struct dir_struct *dir, const char *prefix) { int i; @@ -253,7 +252,7 @@ static void show_files(struct dir_struct *dir) /* * Prune the index to only contain stuff starting with "prefix" */ -static void prune_cache(void) +static void prune_cache(const char *prefix) { int pos = cache_name_pos(prefix, prefix_len); unsigned int first, last; @@ -276,7 +275,7 @@ static void prune_cache(void) active_nr = last; } -static void verify_pathspec(void) +static const char *verify_pathspec(const char *prefix) { const char **p, *n, *prev; char *real_prefix; @@ -313,7 +312,7 @@ static void verify_pathspec(void) memcpy(real_prefix, prev, max); real_prefix[max] = 0; } - prefix = real_prefix; + return real_prefix; } static const char ls_files_usage[] = @@ -453,7 +452,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix) /* Verify that the pathspec matches the prefix */ if (pathspec) - verify_pathspec(); + prefix = verify_pathspec(prefix); /* Treat unmatching pathspec elements as errors */ if (pathspec && error_unmatch) { @@ -476,8 +475,8 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix) read_cache(); if (prefix) - prune_cache(); - show_files(&dir); + prune_cache(prefix); + show_files(&dir, prefix); if (ps_matched) { /* We need to make sure all pathspec matched otherwise -- cgit v1.2.1 From 9590b041ea464c46d5a6811df5bce83c5dd4d457 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 31 Jul 2006 02:53:46 -0700 Subject: Builtins: control the use of pager from the command table. This moves the built-in "always-use-pager" logic for log family to the command dispatch table of git wrapper. This makes it easier to change the default use of pager, and has an added benefit that we fork and exec the pager early before packs are mmapped. Pointed out by Juergen Ruehle . Signed-off-by: Junio C Hamano --- builtin-log.c | 1 - git.c | 13 ++++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/builtin-log.c b/builtin-log.c index 82c69d1d0..bba1496bf 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -34,7 +34,6 @@ static int cmd_log_walk(struct rev_info *rev) struct commit *commit; prepare_revision_walk(rev); - setup_pager(); while ((commit = get_revision(rev)) != NULL) { log_tree_commit(rev, commit); free(commit->buffer); diff --git a/git.c b/git.c index 7321d6c3f..d031eb9a1 100644 --- a/git.c +++ b/git.c @@ -211,6 +211,7 @@ static int handle_alias(int *argcp, const char ***argv) const char git_version_string[] = GIT_VERSION; #define NEEDS_PREFIX 1 +#define USE_PAGER 2 static void handle_internal_command(int argc, const char **argv, char **envp) { @@ -218,13 +219,13 @@ static void handle_internal_command(int argc, const char **argv, char **envp) static struct cmd_struct { const char *cmd; int (*fn)(int, const char **, const char *); - int prefix; + int option; } commands[] = { { "version", cmd_version }, { "help", cmd_help }, - { "log", cmd_log, NEEDS_PREFIX }, - { "whatchanged", cmd_whatchanged, NEEDS_PREFIX }, - { "show", cmd_show, NEEDS_PREFIX }, + { "log", cmd_log, NEEDS_PREFIX | USE_PAGER }, + { "whatchanged", cmd_whatchanged, NEEDS_PREFIX | USE_PAGER }, + { "show", cmd_show, NEEDS_PREFIX | USE_PAGER }, { "push", cmd_push }, { "format-patch", cmd_format_patch, NEEDS_PREFIX }, { "count-objects", cmd_count_objects }, @@ -275,8 +276,10 @@ static void handle_internal_command(int argc, const char **argv, char **envp) continue; prefix = NULL; - if (p->prefix) + if (p->option & NEEDS_PREFIX) prefix = setup_git_directory(); + if (p->option & USE_PAGER) + setup_pager(); if (getenv("GIT_TRACE")) { int i; fprintf(stderr, "trace: built-in: git"); -- cgit v1.2.1 From aa086eb813d4fe21aac556a94efe5e29b44d8ca4 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Sun, 30 Jul 2006 00:27:43 +0200 Subject: pager: config variable pager.color enable/disable colored output when the pager is in use Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- Documentation/config.txt | 4 ++++ cache.h | 1 + config.c | 5 +++++ diff.c | 2 +- environment.c | 1 + 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 465eb13e7..e669003f7 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -116,6 +116,10 @@ apply.whitespace:: Tells `git-apply` how to handle whitespaces, in the same way as the '--whitespace' option. See gitlink:git-apply[1]. +pager.color:: + A boolean to enable/disable colored output when the pager is in + use (default is true). + diff.color:: When true (or `always`), always use colors in patch. When false (or `never`), never. When set to `auto`, use diff --git a/cache.h b/cache.h index c575b8a99..b8c21e07b 100644 --- a/cache.h +++ b/cache.h @@ -386,6 +386,7 @@ extern int receive_keep_pack(int fd[2], const char *me, int quiet, int); /* pager.c */ extern void setup_pager(void); extern int pager_in_use; +extern int pager_use_color; /* base85 */ int decode_85(char *dst, char *line, int linelen); diff --git a/config.c b/config.c index 0ac6aebbb..82b356245 100644 --- a/config.c +++ b/config.c @@ -309,6 +309,11 @@ int git_default_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "pager.color")) { + pager_use_color = git_config_bool(var,value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return 0; } diff --git a/diff.c b/diff.c index 6a7137648..607c357f5 100644 --- a/diff.c +++ b/diff.c @@ -175,7 +175,7 @@ int git_diff_ui_config(const char *var, const char *value) diff_use_color_default = 1; /* bool */ else if (!strcasecmp(value, "auto")) { diff_use_color_default = 0; - if (isatty(1) || pager_in_use) { + if (isatty(1) || (pager_in_use && pager_use_color)) { char *term = getenv("TERM"); if (term && strcmp(term, "dumb")) diff_use_color_default = 1; diff --git a/environment.c b/environment.c index 42f39d657..87162b257 100644 --- a/environment.c +++ b/environment.c @@ -23,6 +23,7 @@ int shared_repository = PERM_UMASK; const char *apply_default_whitespace = NULL; int zlib_compression_level = Z_DEFAULT_COMPRESSION; int pager_in_use; +int pager_use_color = 1; static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file; -- cgit v1.2.1 From dfa464781286e3a6fb1d56a834bb15ac7fc4fb16 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 1 Aug 2006 01:34:53 -0700 Subject: fetch/clone: mark messages from remote side stand out. When dealing with a corrupt or out of sync remote repository, the user often gets error messages like this: error: refs/heads/devel does not point to a valid commit object! which leaves the user wondering if the breakage is on the local end or on the remote end. This is unnecessarily alarming. This patch changes the way we display messages received from the remote side over the git protocol sideband (i.e. stderr stream of the remote process). It shows them with blue background with white letters, but this presentation is subject to proposals of better ways from the list. The problem was pointed out by Andrew Morton. Signed-off-by: Junio C Hamano --- fetch-clone.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fetch-clone.c b/fetch-clone.c index 81d137129..692d9b750 100644 --- a/fetch-clone.c +++ b/fetch-clone.c @@ -133,7 +133,10 @@ static pid_t setup_sideband(int sideband, const char *me, int fd[2], int xd[2]) fprintf(stderr, "\n"); exit(1); case 2: + /* color sideband */ + safe_write(2, "\033[44;37;1m", 10); safe_write(2, buf+1, len); + safe_write(2, "\033[m", 3); continue; case 1: safe_write(fd[1], buf+1, len); -- cgit v1.2.1 From 6ebdee5af47df0c64354e452419015a694c25f5f Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sat, 29 Jul 2006 17:12:34 +0100 Subject: Ensure git-clone exits with error if perl script fails. This helps tests 5400,5600,5700,5710 "fail correctly" rather than give some false positives. Also ensure cleanup actions in exit trap work correctly even if user has alias rm='rm -i'. Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- git-clone.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/git-clone.sh b/git-clone.sh index a92b22a13..acc7a51b9 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -205,7 +205,7 @@ dir="$2" [ -e "$dir" ] && echo "$dir already exists." && usage mkdir -p "$dir" && D=$(cd "$dir" && pwd) && -trap 'err=$?; cd ..; rm -r "$D"; exit $err' 0 +trap 'err=$?; cd ..; rm -rf "$D"; exit $err' 0 case "$bare" in yes) GIT_DIR="$D" ;; @@ -324,7 +324,8 @@ test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp" if test -f "$GIT_DIR/CLONE_HEAD" then # Read git-fetch-pack -k output and store the remote branches. - @@PERL@@ -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin" + @@PERL@@ -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin" || + exit fi cd "$D" || exit -- cgit v1.2.1 From 1fd4da643cb829618bbe76ab37df7f1b4dafc656 Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sat, 29 Jul 2006 17:20:41 +0100 Subject: Fix annotate test script; notice when git-annotate fails. The t8001-annotate.sh test claimed all tests pass, when in fact the git-annotate perl script failed to run! (prior to fixing the script to work with perl 5.5). Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- t/annotate-tests.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh index b6a2edd88..8baf2fef6 100644 --- a/t/annotate-tests.sh +++ b/t/annotate-tests.sh @@ -4,7 +4,8 @@ check_count () { head= case "$1" in -h) head="$2"; shift; shift ;; esac - $PROG file $head | perl -e ' + $PROG file $head >.result || return 1 + cat .result | perl -e ' my %expect = (@ARGV); my %count = (); while () { -- cgit v1.2.1 From 7ffe7098dca297016f87a7e10554e6736f7c3ae2 Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sat, 29 Jul 2006 17:25:03 +0100 Subject: Fix installation of templates on ancient systems. Do not use $(call) for 'shell quoting' paths, and pass DESTDIR down to the templates makefile. [jc: we have fixed the main Makefile long time ago, but somehow forgot to apply the same fix to templates Makefile.] Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- Makefile | 2 +- templates/Makefile | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 15864e23b..6df93c18f 100644 --- a/Makefile +++ b/Makefile @@ -712,7 +712,7 @@ install: all $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL) git$X gitk '$(DESTDIR_SQ)$(bindir_SQ)' - $(MAKE) -C templates install + $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)' $(INSTALL) $(PYMODULES) '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)' if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \ diff --git a/templates/Makefile b/templates/Makefile index 8f7f4fec3..9e1ae1a4e 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -6,11 +6,9 @@ prefix ?= $(HOME) template_dir ?= $(prefix)/share/git-core/templates/ # DESTDIR= -# Shell quote; -# Result of this needs to be placed inside '' -shq = $(subst ','\'',$(1)) -# This has surrounding '' -shellquote = '$(call shq,$(1))' +# Shell quote (do not use $(call) to accomodate ancient setups); +DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) +template_dir_SQ = $(subst ','\'',$(template_dir)) all: boilerplates.made custom @@ -43,6 +41,6 @@ clean: rm -rf blt boilerplates.made install: all - $(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(template_dir)) + $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(template_dir_SQ)' (cd blt && $(TAR) cf - .) | \ - (cd $(call shellquote,$(DESTDIR)$(template_dir)) && $(TAR) xf -) + (cd '$(DESTDIR_SQ)$(template_dir_SQ)' && $(TAR) xf -) -- cgit v1.2.1 From 446c6faec69f7ac521b8b9fc2b1874731729032f Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sat, 29 Jul 2006 18:15:47 +0100 Subject: New tests and en-passant modifications to mktag. These changes were originally part of the next patch, but have been split out since they were peripheral to the main purpose of that patch. - update comment describing the signature format to reflect the current code. - remove trailing \n in calls to error(), since a \n is already provided by error(). - remove redundant call to get_sha1_hex(). - call sha1_to_hex(sha1) to convert to ascii, rather than attempting to print the raw sha1. The new tests provide a regression suite to support the modifications to git-mktag in this and the next patch. Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- mktag.c | 35 ++++----- t/t3800-mktag.sh | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+), 17 deletions(-) create mode 100755 t/t3800-mktag.sh diff --git a/mktag.c b/mktag.c index 27f4c4f04..fa4a9e600 100644 --- a/mktag.c +++ b/mktag.c @@ -2,10 +2,11 @@ #include "tag.h" /* - * A signature file has a very simple fixed format: three lines - * of "object " + "type " + "tag ", - * followed by some free-form signature that git itself doesn't - * care about, but that can be verified with gpg or similar. + * A signature file has a very simple fixed format: four lines + * of "object " + "type " + "tag " + + * "tagger ", followed by a blank line, a free-form tag + * message and a signature block that git itself doesn't care about, + * but that can be verified with gpg or similar. * * The first three lines are guaranteed to be at least 63 bytes: * "object \n" is 48 bytes, "type tag\n" at 9 bytes is the @@ -46,45 +47,42 @@ static int verify_tag(char *buffer, unsigned long size) const char *object, *type_line, *tag_line, *tagger_line; if (size < 64) - return error("wanna fool me ? you obviously got the size wrong !\n"); + return error("wanna fool me ? you obviously got the size wrong !"); buffer[size] = 0; /* Verify object line */ object = buffer; if (memcmp(object, "object ", 7)) - return error("char%d: does not start with \"object \"\n", 0); + return error("char%d: does not start with \"object \"", 0); if (get_sha1_hex(object + 7, sha1)) - return error("char%d: could not get SHA1 hash\n", 7); + return error("char%d: could not get SHA1 hash", 7); /* Verify type line */ type_line = object + 48; if (memcmp(type_line - 1, "\ntype ", 6)) - return error("char%d: could not find \"\\ntype \"\n", 47); + return error("char%d: could not find \"\\ntype \"", 47); /* Verify tag-line */ tag_line = strchr(type_line, '\n'); if (!tag_line) - return error("char%td: could not find next \"\\n\"\n", type_line - buffer); + return error("char%td: could not find next \"\\n\"", type_line - buffer); tag_line++; if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n') - return error("char%td: no \"tag \" found\n", tag_line - buffer); + return error("char%td: no \"tag \" found", tag_line - buffer); /* Get the actual type */ typelen = tag_line - type_line - strlen("type \n"); if (typelen >= sizeof(type)) - return error("char%td: type too long\n", type_line+5 - buffer); + return error("char%td: type too long", type_line+5 - buffer); memcpy(type, type_line+5, typelen); type[typelen] = 0; /* Verify that the object matches */ - if (get_sha1_hex(object + 7, sha1)) - return error("char%d: could not get SHA1 hash but this is really odd since i got it before !\n", 7); - if (verify_object(sha1, type)) - return error("char%d: could not verify object %s\n", 7, sha1); + return error("char%d: could not verify object %s", 7, sha1_to_hex(sha1)); /* Verify the tag-name: we don't allow control characters or spaces in it */ tag_line += 4; @@ -94,14 +92,17 @@ static int verify_tag(char *buffer, unsigned long size) break; if (c > ' ') continue; - return error("char%td: could not verify tag name\n", tag_line - buffer); + return error("char%td: could not verify tag name", tag_line - buffer); } /* Verify the tagger line */ tagger_line = tag_line; if (memcmp(tagger_line, "tagger", 6) || (tagger_line[6] == '\n')) - return error("char%td: could not find \"tagger\"\n", tagger_line - buffer); + return error("char%td: could not find \"tagger\"", tagger_line - buffer); + + /* TODO: check for committer info + blank line? */ + /* Also, the minimum length is probably + "tagger .", or 63+8=71 */ /* The actual stuff afterwards we don't care about.. */ return 0; diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh new file mode 100755 index 000000000..5b23b7769 --- /dev/null +++ b/t/t3800-mktag.sh @@ -0,0 +1,227 @@ +#!/bin/sh +# +# + +test_description='git-mktag: tag object verify test' + +. ./test-lib.sh + +########################################################### +# check the tag.sig file, expecting verify_tag() to fail, +# and checking that the error message matches the pattern +# given in the expect.pat file. + +check_verify_failure () { + test_expect_success \ + "$1" \ + 'git-mktag message || + egrep -q -f expect.pat message' +} + +########################################################### +# first create a commit, so we have a valid object/type +# for the tag. +echo Hello >A +git-update-index --add A +git-commit -m "Initial commit" +head=$(git-rev-parse --verify HEAD) + +############################################################ +# 1. length check + +cat >tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig +echo -n "type tagsssssssssssssssssssssssssssssss" >>tag.sig + +cat >expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <expect.pat <tag.sig <.git/refs/tags/mytag 2>message' + +############################################################ +# 14. check mytag + +test_expect_success \ + 'check mytag' \ + 'git-tag -l | grep mytag' + + +test_done -- cgit v1.2.1 From 579d1fbfaf25550254014fa472faac95f88eb779 Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sun, 30 Jul 2006 16:38:28 +0100 Subject: Add NO_C99_FORMAT to support older compilers. The NO_C99_FORMAT macro allows compilers that lack support for the ll,hh,j,z,t size specifiers (eg. gcc 2.95.2) to adapt the code to avoid runtime errors in the formatted IO functions. Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- Makefile | 8 ++++++++ alloc.c | 15 ++++++++++++++- mktag.c | 18 +++++++++++++----- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 6df93c18f..e66e9b16a 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,11 @@ all: # Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks # d_type in struct dirent (latest Cygwin -- will be fixed soonish). # +# Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.) +# do not support the 'size specifiers' introduced by C99, namely ll, hh, +# j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t). +# some c compilers supported these specifiers prior to C99 as an extension. +# # Define NO_STRCASESTR if you don't have strcasestr. # # Define NO_STRLCPY if you don't have strlcpy. @@ -432,6 +437,9 @@ endif ifdef NO_D_INO_IN_DIRENT ALL_CFLAGS += -DNO_D_INO_IN_DIRENT endif +ifdef NO_C99_FORMAT + ALL_CFLAGS += -DNO_C99_FORMAT +endif ifdef NO_SYMLINK_HEAD ALL_CFLAGS += -DNO_SYMLINK_HEAD endif diff --git a/alloc.c b/alloc.c index e3b22f432..460db192d 100644 --- a/alloc.c +++ b/alloc.c @@ -39,8 +39,21 @@ DEFINE_ALLOCATOR(tree) DEFINE_ALLOCATOR(commit) DEFINE_ALLOCATOR(tag) +#ifdef NO_C99_FORMAT +#define SZ_FMT "%u" +#else +#define SZ_FMT "%zu" +#endif + +static void report(const char* name, unsigned int count, size_t size) +{ + fprintf(stderr, "%10s: %8u (" SZ_FMT " kB)\n", name, count, size); +} + +#undef SZ_FMT + #define REPORT(name) \ - fprintf(stderr, "%10s: %8u (%zu kB)\n", #name, name##_allocs, name##_allocs*sizeof(struct name) >> 10) + report(#name, name##_allocs, name##_allocs*sizeof(struct name) >> 10) void alloc_report(void) { diff --git a/mktag.c b/mktag.c index fa4a9e600..09b6e437d 100644 --- a/mktag.c +++ b/mktag.c @@ -39,6 +39,12 @@ static int verify_object(unsigned char *sha1, const char *expected_type) return ret; } +#ifdef NO_C99_FORMAT +#define PD_FMT "%d" +#else +#define PD_FMT "%td" +#endif + static int verify_tag(char *buffer, unsigned long size) { int typelen; @@ -67,15 +73,15 @@ static int verify_tag(char *buffer, unsigned long size) /* Verify tag-line */ tag_line = strchr(type_line, '\n'); if (!tag_line) - return error("char%td: could not find next \"\\n\"", type_line - buffer); + return error("char" PD_FMT ": could not find next \"\\n\"", type_line - buffer); tag_line++; if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n') - return error("char%td: no \"tag \" found", tag_line - buffer); + return error("char" PD_FMT ": no \"tag \" found", tag_line - buffer); /* Get the actual type */ typelen = tag_line - type_line - strlen("type \n"); if (typelen >= sizeof(type)) - return error("char%td: type too long", type_line+5 - buffer); + return error("char" PD_FMT ": type too long", type_line+5 - buffer); memcpy(type, type_line+5, typelen); type[typelen] = 0; @@ -92,14 +98,14 @@ static int verify_tag(char *buffer, unsigned long size) break; if (c > ' ') continue; - return error("char%td: could not verify tag name", tag_line - buffer); + return error("char" PD_FMT ": could not verify tag name", tag_line - buffer); } /* Verify the tagger line */ tagger_line = tag_line; if (memcmp(tagger_line, "tagger", 6) || (tagger_line[6] == '\n')) - return error("char%td: could not find \"tagger\"", tagger_line - buffer); + return error("char" PD_FMT ": could not find \"tagger\"", tagger_line - buffer); /* TODO: check for committer info + blank line? */ /* Also, the minimum length is probably + "tagger .", or 63+8=71 */ @@ -108,6 +114,8 @@ static int verify_tag(char *buffer, unsigned long size) return 0; } +#undef PD_FMT + int main(int argc, char **argv) { unsigned long size = 4096; -- cgit v1.2.1 From 8e76483ce0ce256b01345abc4ca97b1f94aed354 Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sun, 30 Jul 2006 17:00:40 +0100 Subject: Fix header breakage due to redefining PATH_MAX. The header builtin.h was, incorrectly, redefining PATH_MAX which causes a header order dependency in builtin-write-tree.c. The fix is to simply include directly to obtain the correct definition of PATH_MAX. Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- builtin.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/builtin.h b/builtin.h index 1c8637ae2..88c4d8471 100644 --- a/builtin.h +++ b/builtin.h @@ -2,10 +2,7 @@ #define BUILTIN_H #include - -#ifndef PATH_MAX -# define PATH_MAX 4096 -#endif +#include extern const char git_version_string[]; -- cgit v1.2.1 From 822a7d507151e1d6310f52d5b05234d65db11a88 Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sun, 30 Jul 2006 22:42:25 +0100 Subject: Remove cmd_usage() routine and re-organize the help/usage code. The cmd_usage() routine was causing warning messages due to a NULL format parameter being passed in three out of four calls. This is a problem if you want to compile with -Werror. A simple solution is to simply remove the GNU __attribute__ format pragma from the cmd_usage() declaration in the header file. The function interface was somewhat muddled anyway, so re-write the code to finesse the problem. [jc: this incidentally revealed that t9100 test assumed that the output from "git help" to be fixed in stone, but this patch lower-cases "Usage" to "usage". Update the test not to rely on "git help" output.] Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- builtin-help.c | 54 +++++++++++++++++++++--------------------------- builtin.h | 7 ++----- git.c | 7 +++++-- t/t9100-git-svn-basic.sh | 7 +++---- 4 files changed, 33 insertions(+), 42 deletions(-) diff --git a/builtin-help.c b/builtin-help.c index bb0b03f1a..fb731cc93 100644 --- a/builtin-help.c +++ b/builtin-help.c @@ -9,8 +9,6 @@ #include "exec_cmd.h" #include "common-cmds.h" -static const char git_usage[] = - "Usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]"; /* most GUI terminals set COLUMNS (although some don't export it) */ static int term_columns(void) @@ -178,31 +176,6 @@ static void list_common_cmds_help(void) puts("(use 'git help -a' to get a list of all installed git commands)"); } -void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...) -{ - if (fmt) { - va_list ap; - - va_start(ap, fmt); - printf("git: "); - vprintf(fmt, ap); - va_end(ap); - putchar('\n'); - } - else - puts(git_usage); - - if (exec_path) { - putchar('\n'); - if (show_all) - list_commands(exec_path, "git-*"); - else - list_common_cmds_help(); - } - - exit(1); -} - static void show_man_page(const char *git_cmd) { const char *page; @@ -221,6 +194,13 @@ static void show_man_page(const char *git_cmd) execlp("man", "man", page, NULL); } +void help_unknown_cmd(const char *cmd) +{ + printf("git: '%s' is not a git-command\n\n", cmd); + list_common_cmds_help(); + exit(1); +} + int cmd_version(int argc, const char **argv, const char *prefix) { printf("git version %s\n", git_version_string); @@ -230,12 +210,24 @@ int cmd_version(int argc, const char **argv, const char *prefix) int cmd_help(int argc, const char **argv, const char *prefix) { const char *help_cmd = argc > 1 ? argv[1] : NULL; - if (!help_cmd) - cmd_usage(0, git_exec_path(), NULL); - else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) - cmd_usage(1, git_exec_path(), NULL); + const char *exec_path = git_exec_path(); + + if (!help_cmd) { + printf("usage: %s\n\n", git_usage_string); + list_common_cmds_help(); + exit(1); + } + + else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) { + printf("usage: %s\n\n", git_usage_string); + if(exec_path) + list_commands(exec_path, "git-*"); + exit(1); + } + else show_man_page(help_cmd); + return 0; } diff --git a/builtin.h b/builtin.h index 88c4d8471..f10d3b77c 100644 --- a/builtin.h +++ b/builtin.h @@ -5,12 +5,9 @@ #include extern const char git_version_string[]; +extern const char git_usage_string[]; -void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...) -#ifdef __GNUC__ - __attribute__((__format__(__printf__, 3, 4), __noreturn__)) -#endif - ; +extern void help_unknown_cmd(const char *cmd); extern int cmd_help(int argc, const char **argv, const char *prefix); extern int cmd_version(int argc, const char **argv, const char *prefix); diff --git a/git.c b/git.c index d031eb9a1..110e82e9a 100644 --- a/git.c +++ b/git.c @@ -15,6 +15,9 @@ #include "builtin.h" +const char git_usage_string[] = + "git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]"; + static void prepend_to_path(const char *dir, int len) { const char *old_path = getenv("PATH"); @@ -78,7 +81,7 @@ static int handle_options(const char*** argv, int* argc) setenv("GIT_DIR", getcwd(git_dir, 1024), 1); } else { fprintf(stderr, "Unknown option: %s\n", cmd); - cmd_usage(0, NULL, NULL); + usage(git_usage_string); } (*argv)++; @@ -375,7 +378,7 @@ int main(int argc, const char **argv, char **envp) } if (errno == ENOENT) - cmd_usage(0, exec_path, "'%s' is not a git-command", cmd); + help_unknown_cmd(cmd); fprintf(stderr, "Failed to run command '%s': %s\n", cmd, strerror(errno)); diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index bf1d6381d..34a3ccd31 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -170,7 +170,7 @@ then test -L $SVN_TREE/exec-2.sh" name='modify a symlink to become a file' - git help > help || true + echo git help > help || true rm exec-2.sh cp help exec-2.sh git update-index exec-2.sh @@ -217,10 +217,10 @@ name='check imported tree checksums expected tree checksums' rm -f expected if test "$have_utf8" = t then - echo tree f735671b89a7eb30cab1d8597de35bd4271ab813 > expected + echo tree bf522353586b1b883488f2bc73dab0d9f774b9a9 > expected fi cat >> expected <<\EOF -tree 4b9af72bb861eaed053854ec502cf7df72618f0f +tree 83654bb36f019ae4fe77a0171f81075972087624 tree 031b8d557afc6fea52894eaebb45bec52f1ba6d1 tree 0b094cbff17168f24c302e297f55bfac65eb8bd3 tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e @@ -231,4 +231,3 @@ EOF test_expect_success "$name" "diff -u a expected" test_done - -- cgit v1.2.1 From da7bad50ed0816cf2ee7f558ed154a7c67fb546d Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Sun, 30 Jul 2006 16:52:09 +0100 Subject: Fix header breakage with _XOPEN_SOURCE. convert-objects.c sets _XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED before including , in order to get the declaration of strptime(). This leads to breakage in cache.h, due to S_ISLNK and S_IFLNK no longer being defined by . These definitions are protected by the __USE_BSD symbol, which is not set when _XOPEN_SOURCE is set. Moving the #defines and #include below all other #includes does not fix the problem, however, since now _USE_XOPEN, which protects the declaration of strptime(), is now not defined (don't ask!). The fix is to #define _GNU_SOURCE, which enables the definition of practically everything. Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- convert-objects.c | 1 + 1 file changed, 1 insertion(+) diff --git a/convert-objects.c b/convert-objects.c index ebea8e472..168771ed8 100644 --- a/convert-objects.c +++ b/convert-objects.c @@ -1,5 +1,6 @@ #define _XOPEN_SOURCE 500 /* glibc2 and AIX 5.3L need this */ #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */ +#define _GNU_SOURCE #include #include "cache.h" #include "blob.h" -- cgit v1.2.1 From 8f615493e6b6fd47bc4011c264cb7e6f01052d37 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 2 Aug 2006 11:28:16 -0400 Subject: git-push: allow -f as an alias for --force This was already documented in the options section of the manpage. This patch implements it, adds it to the usage message, and mentions it at the top of the manpage. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/git-push.txt | 2 +- builtin-push.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 56afd64f4..d4ae99fa5 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -8,7 +8,7 @@ git-push - Update remote refs along with associated objects SYNOPSIS -------- -'git-push' [--all] [--tags] [--force] ... +'git-push' [--all] [--tags] [-f | --force] ... DESCRIPTION ----------- diff --git a/builtin-push.c b/builtin-push.c index a82417106..c39dd1e09 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -8,7 +8,7 @@ #define MAX_URI (16) -static const char push_usage[] = "git push [--all] [--tags] [--force] [...]"; +static const char push_usage[] = "git push [--all] [--tags] [-f | --force] [...]"; static int all = 0, tags = 0, force = 0, thin = 1; static const char *execute = NULL; @@ -291,7 +291,7 @@ int cmd_push(int argc, const char **argv, const char *prefix) tags = 1; continue; } - if (!strcmp(arg, "--force")) { + if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) { force = 1; continue; } -- cgit v1.2.1 From ec19a22b74d39da1bf22e10acadc7f712a4976c5 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 2 Aug 2006 11:37:42 -0400 Subject: git-push: remove obsolete git-push.sh This was converted to a C builtin over three months ago. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-push.sh | 87 ------------------------------------------------------------- 1 file changed, 87 deletions(-) delete mode 100755 git-push.sh diff --git a/git-push.sh b/git-push.sh deleted file mode 100755 index 21775fc21..000000000 --- a/git-push.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/sh - -USAGE='[--all] [--tags] [--force] [...]' -. git-sh-setup - -# Parse out parameters and then stop at remote, so that we can -# translate it using .git/branches information -has_all= -has_force= -has_exec= -has_thin=--thin -remote= -do_tags= - -while case "$#" in 0) break ;; esac -do - case "$1" in - --all) - has_all=--all ;; - --tags) - do_tags=yes ;; - --force) - has_force=--force ;; - --exec=*) - has_exec="$1" ;; - --thin) - ;; # noop - --no-thin) - has_thin= ;; - -*) - usage ;; - *) - set x "$@" - shift - break ;; - esac - shift -done -case "$#" in -0) - echo "Where would you want to push today?" - usage ;; -esac - -. git-parse-remote -remote=$(get_remote_url "$@") - -case "$has_all" in ---all) - set x ;; -'') - case "$do_tags,$#" in - yes,1) - set x $(cd "$GIT_DIR/refs" && find tags -type f -print) ;; - yes,*) - set x $(cd "$GIT_DIR/refs" && find tags -type f -print) \ - $(get_remote_refs_for_push "$@") ;; - ,*) - set x $(get_remote_refs_for_push "$@") ;; - esac -esac - -shift ;# away the initial 'x' - -# $# is now 0 if there was no explicit refspec on the command line -# and there was no default refspec to push from remotes/ file. -# we will let git-send-pack to do its "matching refs" thing. - -case "$remote" in -git://*) - die "Cannot use READ-ONLY transport to push to $remote" ;; -rsync://*) - die "Pushing with rsync transport is deprecated" ;; -esac - -set x "$remote" "$@"; shift -test "$has_all" && set x "$has_all" "$@" && shift -test "$has_force" && set x "$has_force" "$@" && shift -test "$has_exec" && set x "$has_exec" "$@" && shift -test "$has_thin" && set x "$has_thin" "$@" && shift - -case "$remote" in -http://* | https://*) - exec git-http-push "$@";; -*) - exec git-send-pack "$@";; -esac -- cgit v1.2.1 From 7fe08af485a02e28ea11b978e6543fbb78d80943 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 2 Aug 2006 12:32:32 -0400 Subject: Documentation: convert uses of git-link macro to gitlink There isn't and never was such a macro; all uses are typos. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/config.txt | 6 +++--- Documentation/git-cvsimport.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index e669003f7..d89916bea 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -223,14 +223,14 @@ showbranch.default:: See gitlink:git-show-branch[1]. tar.umask:: - By default, git-link:git-tar-tree[1] sets file and directories modes + By default, gitlink:git-tar-tree[1] sets file and directories modes to 0666 or 0777. While this is both useful and acceptable for projects such as the Linux Kernel, it might be excessive for other projects. With this variable, it becomes possible to tell - git-link:git-tar-tree[1] to apply a specific umask to the modes above. + gitlink:git-tar-tree[1] to apply a specific umask to the modes above. The special value "user" indicates that the user's current umask will be used. This should be enough for most projects, as it will lead to - the same permissions as git-link:git-checkout[1] would use. The default + the same permissions as gitlink:git-checkout[1] would use. The default value remains 0, which means world read-write. user.email:: diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt index b0c6d7c30..d21d66bfe 100644 --- a/Documentation/git-cvsimport.txt +++ b/Documentation/git-cvsimport.txt @@ -116,7 +116,7 @@ file each time git-cvsimport is run. + It is not recommended to use this feature if you intend to export changes back to CVS again later with -git-link[1]::git-cvsexportcommit. +gitlink:git-cvsexportcommit[1]. OUTPUT ------ -- cgit v1.2.1 From d4ad9b0484fa17de3d161f48ae58190ec2cccd45 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 2 Aug 2006 12:34:44 -0400 Subject: git-annotate: remove extraneous debugging line Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-annotate.perl | 1 - 1 file changed, 1 deletion(-) diff --git a/git-annotate.perl b/git-annotate.perl index 6db2f4824..505b5ccb2 100755 --- a/git-annotate.perl +++ b/git-annotate.perl @@ -317,7 +317,6 @@ sub _git_diff_parse { $gotheader = 1; - printf("Copying from %d to %d\n", $ri, $remstart); foreach my $parent (@$parents) { for (my $i = $ri; $i < $remstart; $i++) { $plines{$parent}[$pi{$parent}++] = $slines->[$i]; -- cgit v1.2.1 From 53bb2c002a53cdd0746444defbf5323ea21eb8d5 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Wed, 2 Aug 2006 18:32:32 +0200 Subject: Make git-prune-packed a builtin Signed-off-by: Matthias Kestenholz Signed-off-by: Junio C Hamano --- Makefile | 6 ++-- builtin-prune-packed.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ builtin.h | 1 + git.c | 1 + prune-packed.c | 79 -------------------------------------------------- 5 files changed, 82 insertions(+), 82 deletions(-) create mode 100644 builtin-prune-packed.c delete mode 100644 prune-packed.c diff --git a/Makefile b/Makefile index e66e9b16a..fd45cd19b 100644 --- a/Makefile +++ b/Makefile @@ -178,7 +178,7 @@ PROGRAMS = \ git-hash-object$X git-index-pack$X git-local-fetch$X \ git-merge-base$X \ git-merge-index$X git-mktag$X git-mktree$X git-pack-objects$X git-patch-id$X \ - git-peek-remote$X git-prune-packed$X git-receive-pack$X \ + git-peek-remote$X git-receive-pack$X \ git-send-pack$X git-shell$X \ git-show-index$X git-ssh-fetch$X \ git-ssh-upload$X git-unpack-file$X \ @@ -197,7 +197,7 @@ BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \ git-read-tree$X git-commit-tree$X git-write-tree$X \ git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \ git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \ - git-fmt-merge-msg$X git-prune$X git-mv$X + git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X # what 'all' will build and 'install' will install, in gitexecdir ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) @@ -254,7 +254,7 @@ BUILTIN_OBJS = \ builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \ builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \ builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \ - builtin-mv.o + builtin-mv.o builtin-prune-packed.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz diff --git a/builtin-prune-packed.c b/builtin-prune-packed.c new file mode 100644 index 000000000..d0ff336c1 --- /dev/null +++ b/builtin-prune-packed.c @@ -0,0 +1,77 @@ +#include "cache.h" + +static const char prune_packed_usage[] = +"git-prune-packed [-n]"; + +static int dryrun; + +static void prune_dir(int i, DIR *dir, char *pathname, int len) +{ + struct dirent *de; + char hex[40]; + + sprintf(hex, "%02x", i); + while ((de = readdir(dir)) != NULL) { + unsigned char sha1[20]; + if (strlen(de->d_name) != 38) + continue; + memcpy(hex+2, de->d_name, 38); + if (get_sha1_hex(hex, sha1)) + continue; + if (!has_sha1_pack(sha1)) + continue; + memcpy(pathname + len, de->d_name, 38); + if (dryrun) + printf("rm -f %s\n", pathname); + else if (unlink(pathname) < 0) + error("unable to unlink %s", pathname); + } + pathname[len] = 0; + rmdir(pathname); +} + +static void prune_packed_objects(void) +{ + int i; + static char pathname[PATH_MAX]; + const char *dir = get_object_directory(); + int len = strlen(dir); + + if (len > PATH_MAX - 42) + die("impossible object directory"); + memcpy(pathname, dir, len); + if (len && pathname[len-1] != '/') + pathname[len++] = '/'; + for (i = 0; i < 256; i++) { + DIR *d; + + sprintf(pathname + len, "%02x/", i); + d = opendir(pathname); + if (!d) + continue; + prune_dir(i, d, pathname, len + 3); + closedir(d); + } +} + +int cmd_prune_packed(int argc, char **argv, const char *prefix) +{ + int i; + + for (i = 1; i < argc; i++) { + const char *arg = argv[i]; + + if (*arg == '-') { + if (!strcmp(arg, "-n")) + dryrun = 1; + else + usage(prune_packed_usage); + continue; + } + /* Handle arguments here .. */ + usage(prune_packed_usage); + } + sync(); + prune_packed_objects(); + return 0; +} diff --git a/builtin.h b/builtin.h index f10d3b77c..7ddfe2891 100644 --- a/builtin.h +++ b/builtin.h @@ -20,6 +20,7 @@ extern int cmd_format_patch(int argc, const char **argv, const char *prefix); extern int cmd_count_objects(int argc, const char **argv, const char *prefix); extern int cmd_prune(int argc, const char **argv, const char *prefix); +extern int cmd_prune_packed(int argc, const char **argv, const char *prefix); extern int cmd_push(int argc, const char **argv, const char *prefix); extern int cmd_grep(int argc, const char **argv, const char *prefix); diff --git a/git.c b/git.c index 110e82e9a..5b50762de 100644 --- a/git.c +++ b/git.c @@ -263,6 +263,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "fmt-merge-msg", cmd_fmt_merge_msg, NEEDS_PREFIX }, { "prune", cmd_prune, NEEDS_PREFIX }, { "mv", cmd_mv, NEEDS_PREFIX }, + { "prune-packed", cmd_prune_packed, NEEDS_PREFIX }, }; int i; diff --git a/prune-packed.c b/prune-packed.c deleted file mode 100644 index d24b09711..000000000 --- a/prune-packed.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "cache.h" - -static const char prune_packed_usage[] = -"git-prune-packed [-n]"; - -static int dryrun; - -static void prune_dir(int i, DIR *dir, char *pathname, int len) -{ - struct dirent *de; - char hex[40]; - - sprintf(hex, "%02x", i); - while ((de = readdir(dir)) != NULL) { - unsigned char sha1[20]; - if (strlen(de->d_name) != 38) - continue; - memcpy(hex+2, de->d_name, 38); - if (get_sha1_hex(hex, sha1)) - continue; - if (!has_sha1_pack(sha1)) - continue; - memcpy(pathname + len, de->d_name, 38); - if (dryrun) - printf("rm -f %s\n", pathname); - else if (unlink(pathname) < 0) - error("unable to unlink %s", pathname); - } - pathname[len] = 0; - rmdir(pathname); -} - -static void prune_packed_objects(void) -{ - int i; - static char pathname[PATH_MAX]; - const char *dir = get_object_directory(); - int len = strlen(dir); - - if (len > PATH_MAX - 42) - die("impossible object directory"); - memcpy(pathname, dir, len); - if (len && pathname[len-1] != '/') - pathname[len++] = '/'; - for (i = 0; i < 256; i++) { - DIR *d; - - sprintf(pathname + len, "%02x/", i); - d = opendir(pathname); - if (!d) - continue; - prune_dir(i, d, pathname, len + 3); - closedir(d); - } -} - -int main(int argc, char **argv) -{ - int i; - - setup_git_directory(); - - for (i = 1; i < argc; i++) { - const char *arg = argv[i]; - - if (*arg == '-') { - if (!strcmp(arg, "-n")) - dryrun = 1; - else - usage(prune_packed_usage); - continue; - } - /* Handle arguments here .. */ - usage(prune_packed_usage); - } - sync(); - prune_packed_objects(); - return 0; -} -- cgit v1.2.1 From e12c095aa69d8aca0326eb11960427d9bf9e2db7 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Wed, 2 Aug 2006 23:51:59 +0200 Subject: Make git-repo-config a builtin Signed-off-by: Matthias Kestenholz Signed-off-by: Junio C Hamano --- Makefile | 7 +- builtin-repo-config.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++ builtin.h | 1 + git.c | 1 + repo-config.c | 199 ------------------------------------------------- 5 files changed, 206 insertions(+), 202 deletions(-) create mode 100644 builtin-repo-config.c delete mode 100644 repo-config.c diff --git a/Makefile b/Makefile index fd45cd19b..700c77f56 100644 --- a/Makefile +++ b/Makefile @@ -185,7 +185,7 @@ PROGRAMS = \ git-unpack-objects$X git-update-server-info$X \ git-upload-pack$X git-verify-pack$X \ git-symbolic-ref$X \ - git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \ + git-name-rev$X git-pack-redundant$X git-var$X \ git-describe$X git-merge-tree$X git-blame$X git-imap-send$X BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \ @@ -197,7 +197,8 @@ BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \ git-read-tree$X git-commit-tree$X git-write-tree$X \ git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \ git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \ - git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X + git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X \ + git-repo-config$X # what 'all' will build and 'install' will install, in gitexecdir ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) @@ -254,7 +255,7 @@ BUILTIN_OBJS = \ builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \ builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \ builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \ - builtin-mv.o builtin-prune-packed.o + builtin-mv.o builtin-prune-packed.o builtin-repo-config.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz diff --git a/builtin-repo-config.c b/builtin-repo-config.c new file mode 100644 index 000000000..c821e2271 --- /dev/null +++ b/builtin-repo-config.c @@ -0,0 +1,200 @@ +#include "builtin.h" +#include "cache.h" +#include + +static const char git_config_set_usage[] = +"git-repo-config [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --unset | --unset-all] name [value [value_regex]] | --list"; + +static char* key = NULL; +static regex_t* key_regexp = NULL; +static regex_t* regexp = NULL; +static int show_keys = 0; +static int use_key_regexp = 0; +static int do_all = 0; +static int do_not_match = 0; +static int seen = 0; +static enum { T_RAW, T_INT, T_BOOL } type = T_RAW; + +static int show_all_config(const char *key_, const char *value_) +{ + if (value_) + printf("%s=%s\n", key_, value_); + else + printf("%s\n", key_); + return 0; +} + +static int show_config(const char* key_, const char* value_) +{ + char value[256]; + const char *vptr = value; + int dup_error = 0; + + if (!use_key_regexp && strcmp(key_, key)) + return 0; + if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0)) + return 0; + if (regexp != NULL && + (do_not_match ^ + regexec(regexp, (value_?value_:""), 0, NULL, 0))) + return 0; + + if (show_keys) + printf("%s ", key_); + if (seen && !do_all) + dup_error = 1; + if (type == T_INT) + sprintf(value, "%d", git_config_int(key_, value_?value_:"")); + else if (type == T_BOOL) + vptr = git_config_bool(key_, value_) ? "true" : "false"; + else + vptr = value_?value_:""; + seen++; + if (dup_error) { + error("More than one value for the key %s: %s", + key_, vptr); + } + else + printf("%s\n", vptr); + + return 0; +} + +static int get_value(const char* key_, const char* regex_) +{ + int ret = -1; + char *tl; + char *global = NULL, *repo_config = NULL; + const char *local; + + local = getenv("GIT_CONFIG"); + if (!local) { + const char *home = getenv("HOME"); + local = getenv("GIT_CONFIG_LOCAL"); + if (!local) + local = repo_config = strdup(git_path("config")); + if (home) + global = strdup(mkpath("%s/.gitconfig", home)); + } + + key = strdup(key_); + for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl) + *tl = tolower(*tl); + for (tl=key; *tl && *tl != '.'; ++tl) + *tl = tolower(*tl); + + if (use_key_regexp) { + key_regexp = (regex_t*)malloc(sizeof(regex_t)); + if (regcomp(key_regexp, key, REG_EXTENDED)) { + fprintf(stderr, "Invalid key pattern: %s\n", key_); + goto free_strings; + } + } + + if (regex_) { + if (regex_[0] == '!') { + do_not_match = 1; + regex_++; + } + + regexp = (regex_t*)malloc(sizeof(regex_t)); + if (regcomp(regexp, regex_, REG_EXTENDED)) { + fprintf(stderr, "Invalid pattern: %s\n", regex_); + goto free_strings; + } + } + + if (do_all && global) + git_config_from_file(show_config, global); + git_config_from_file(show_config, local); + if (!do_all && !seen && global) + git_config_from_file(show_config, global); + + free(key); + if (regexp) { + regfree(regexp); + free(regexp); + } + + if (do_all) + ret = !seen; + else + ret = (seen == 1) ? 0 : 1; + +free_strings: + if (repo_config) + free(repo_config); + if (global) + free(global); + return ret; +} + +int cmd_repo_config(int argc, const char **argv, const char *prefix) +{ + int nongit = 0; + setup_git_directory_gently(&nongit); + + while (1 < argc) { + if (!strcmp(argv[1], "--int")) + type = T_INT; + else if (!strcmp(argv[1], "--bool")) + type = T_BOOL; + else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l")) + return git_config(show_all_config); + else + break; + argc--; + argv++; + } + + switch (argc) { + case 2: + return get_value(argv[1], NULL); + case 3: + if (!strcmp(argv[1], "--unset")) + return git_config_set(argv[2], NULL); + else if (!strcmp(argv[1], "--unset-all")) + return git_config_set_multivar(argv[2], NULL, NULL, 1); + else if (!strcmp(argv[1], "--get")) + return get_value(argv[2], NULL); + else if (!strcmp(argv[1], "--get-all")) { + do_all = 1; + return get_value(argv[2], NULL); + } else if (!strcmp(argv[1], "--get-regexp")) { + show_keys = 1; + use_key_regexp = 1; + do_all = 1; + return get_value(argv[2], NULL); + } else + + return git_config_set(argv[1], argv[2]); + case 4: + if (!strcmp(argv[1], "--unset")) + return git_config_set_multivar(argv[2], NULL, argv[3], 0); + else if (!strcmp(argv[1], "--unset-all")) + return git_config_set_multivar(argv[2], NULL, argv[3], 1); + else if (!strcmp(argv[1], "--get")) + return get_value(argv[2], argv[3]); + else if (!strcmp(argv[1], "--get-all")) { + do_all = 1; + return get_value(argv[2], argv[3]); + } else if (!strcmp(argv[1], "--get-regexp")) { + show_keys = 1; + use_key_regexp = 1; + do_all = 1; + return get_value(argv[2], argv[3]); + } else if (!strcmp(argv[1], "--replace-all")) + + return git_config_set_multivar(argv[2], argv[3], NULL, 1); + else + + return git_config_set_multivar(argv[1], argv[2], argv[3], 0); + case 5: + if (!strcmp(argv[1], "--replace-all")) + return git_config_set_multivar(argv[2], argv[3], argv[4], 1); + case 1: + default: + usage(git_config_set_usage); + } + return 0; +} diff --git a/builtin.h b/builtin.h index 7ddfe2891..26ebcaf21 100644 --- a/builtin.h +++ b/builtin.h @@ -48,6 +48,7 @@ extern int cmd_update_index(int argc, const char **argv, const char *prefix); extern int cmd_update_ref(int argc, const char **argv, const char *prefix); extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix); extern int cmd_mv(int argc, const char **argv, const char *prefix); +extern int cmd_repo_config(int argc, const char **argv, const char *prefix); extern int cmd_write_tree(int argc, const char **argv, const char *prefix); extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); diff --git a/git.c b/git.c index 5b50762de..6e72a893b 100644 --- a/git.c +++ b/git.c @@ -264,6 +264,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "prune", cmd_prune, NEEDS_PREFIX }, { "mv", cmd_mv, NEEDS_PREFIX }, { "prune-packed", cmd_prune_packed, NEEDS_PREFIX }, + { "repo-config", cmd_repo_config }, }; int i; diff --git a/repo-config.c b/repo-config.c deleted file mode 100644 index 743f02b7d..000000000 --- a/repo-config.c +++ /dev/null @@ -1,199 +0,0 @@ -#include "cache.h" -#include - -static const char git_config_set_usage[] = -"git-repo-config [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --unset | --unset-all] name [value [value_regex]] | --list"; - -static char* key = NULL; -static regex_t* key_regexp = NULL; -static regex_t* regexp = NULL; -static int show_keys = 0; -static int use_key_regexp = 0; -static int do_all = 0; -static int do_not_match = 0; -static int seen = 0; -static enum { T_RAW, T_INT, T_BOOL } type = T_RAW; - -static int show_all_config(const char *key_, const char *value_) -{ - if (value_) - printf("%s=%s\n", key_, value_); - else - printf("%s\n", key_); - return 0; -} - -static int show_config(const char* key_, const char* value_) -{ - char value[256]; - const char *vptr = value; - int dup_error = 0; - - if (!use_key_regexp && strcmp(key_, key)) - return 0; - if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0)) - return 0; - if (regexp != NULL && - (do_not_match ^ - regexec(regexp, (value_?value_:""), 0, NULL, 0))) - return 0; - - if (show_keys) - printf("%s ", key_); - if (seen && !do_all) - dup_error = 1; - if (type == T_INT) - sprintf(value, "%d", git_config_int(key_, value_?value_:"")); - else if (type == T_BOOL) - vptr = git_config_bool(key_, value_) ? "true" : "false"; - else - vptr = value_?value_:""; - seen++; - if (dup_error) { - error("More than one value for the key %s: %s", - key_, vptr); - } - else - printf("%s\n", vptr); - - return 0; -} - -static int get_value(const char* key_, const char* regex_) -{ - int ret = -1; - char *tl; - char *global = NULL, *repo_config = NULL; - const char *local; - - local = getenv("GIT_CONFIG"); - if (!local) { - const char *home = getenv("HOME"); - local = getenv("GIT_CONFIG_LOCAL"); - if (!local) - local = repo_config = strdup(git_path("config")); - if (home) - global = strdup(mkpath("%s/.gitconfig", home)); - } - - key = strdup(key_); - for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl) - *tl = tolower(*tl); - for (tl=key; *tl && *tl != '.'; ++tl) - *tl = tolower(*tl); - - if (use_key_regexp) { - key_regexp = (regex_t*)malloc(sizeof(regex_t)); - if (regcomp(key_regexp, key, REG_EXTENDED)) { - fprintf(stderr, "Invalid key pattern: %s\n", key_); - goto free_strings; - } - } - - if (regex_) { - if (regex_[0] == '!') { - do_not_match = 1; - regex_++; - } - - regexp = (regex_t*)malloc(sizeof(regex_t)); - if (regcomp(regexp, regex_, REG_EXTENDED)) { - fprintf(stderr, "Invalid pattern: %s\n", regex_); - goto free_strings; - } - } - - if (do_all && global) - git_config_from_file(show_config, global); - git_config_from_file(show_config, local); - if (!do_all && !seen && global) - git_config_from_file(show_config, global); - - free(key); - if (regexp) { - regfree(regexp); - free(regexp); - } - - if (do_all) - ret = !seen; - else - ret = (seen == 1) ? 0 : 1; - -free_strings: - if (repo_config) - free(repo_config); - if (global) - free(global); - return ret; -} - -int main(int argc, const char **argv) -{ - int nongit = 0; - setup_git_directory_gently(&nongit); - - while (1 < argc) { - if (!strcmp(argv[1], "--int")) - type = T_INT; - else if (!strcmp(argv[1], "--bool")) - type = T_BOOL; - else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l")) - return git_config(show_all_config); - else - break; - argc--; - argv++; - } - - switch (argc) { - case 2: - return get_value(argv[1], NULL); - case 3: - if (!strcmp(argv[1], "--unset")) - return git_config_set(argv[2], NULL); - else if (!strcmp(argv[1], "--unset-all")) - return git_config_set_multivar(argv[2], NULL, NULL, 1); - else if (!strcmp(argv[1], "--get")) - return get_value(argv[2], NULL); - else if (!strcmp(argv[1], "--get-all")) { - do_all = 1; - return get_value(argv[2], NULL); - } else if (!strcmp(argv[1], "--get-regexp")) { - show_keys = 1; - use_key_regexp = 1; - do_all = 1; - return get_value(argv[2], NULL); - } else - - return git_config_set(argv[1], argv[2]); - case 4: - if (!strcmp(argv[1], "--unset")) - return git_config_set_multivar(argv[2], NULL, argv[3], 0); - else if (!strcmp(argv[1], "--unset-all")) - return git_config_set_multivar(argv[2], NULL, argv[3], 1); - else if (!strcmp(argv[1], "--get")) - return get_value(argv[2], argv[3]); - else if (!strcmp(argv[1], "--get-all")) { - do_all = 1; - return get_value(argv[2], argv[3]); - } else if (!strcmp(argv[1], "--get-regexp")) { - show_keys = 1; - use_key_regexp = 1; - do_all = 1; - return get_value(argv[2], argv[3]); - } else if (!strcmp(argv[1], "--replace-all")) - - return git_config_set_multivar(argv[2], argv[3], NULL, 1); - else - - return git_config_set_multivar(argv[1], argv[2], argv[3], 0); - case 5: - if (!strcmp(argv[1], "--replace-all")) - return git_config_set_multivar(argv[2], argv[3], argv[4], 1); - case 1: - default: - usage(git_config_set_usage); - } - return 0; -} -- cgit v1.2.1 From 25f38f064f7f9ccde337eafcf575e4a5a1079346 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Wed, 2 Aug 2006 23:52:00 +0200 Subject: use declarations from builtin.h for builtin commands Signed-off-by: Matthias Kestenholz Signed-off-by: Junio C Hamano --- builtin-fmt-merge-msg.c | 3 ++- builtin-prune-packed.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c index c84224ee8..485ede7ca 100644 --- a/builtin-fmt-merge-msg.c +++ b/builtin-fmt-merge-msg.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" #include "commit.h" #include "diff.h" @@ -242,7 +243,7 @@ static void shortlog(const char *name, unsigned char *sha1, free_list(&subjects); } -int cmd_fmt_merge_msg(int argc, char **argv, const char *prefix) +int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) { int limit = 20, i = 0; char line[1024]; diff --git a/builtin-prune-packed.c b/builtin-prune-packed.c index d0ff336c1..d3dd94d9e 100644 --- a/builtin-prune-packed.c +++ b/builtin-prune-packed.c @@ -1,3 +1,4 @@ +#include "builtin.h" #include "cache.h" static const char prune_packed_usage[] = @@ -54,7 +55,7 @@ static void prune_packed_objects(void) } } -int cmd_prune_packed(int argc, char **argv, const char *prefix) +int cmd_prune_packed(int argc, const char **argv, const char *prefix) { int i; -- cgit v1.2.1 From fba0cbd95d796857622d642160176907930ae511 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Thu, 3 Aug 2006 00:04:56 +0200 Subject: git-grep: document --and, --or, --not, ( and ) [jc: added an example section.] Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- Documentation/git-grep.txt | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index 62a8e7f22..dc7683383 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -16,7 +16,7 @@ SYNOPSIS [-n] [-l | --files-with-matches] [-L | --files-without-match] [-c | --count] [-A ] [-B ] [-C ] - [-f ] [-e] + [-f ] [-e] [--and|--or|--not|(|)|-e ...] [...] [--] [...] @@ -74,16 +74,30 @@ OPTIONS -e:: The next parameter is the pattern. This option has to be used for patterns starting with - and should be used in - scripts passing user input to grep. + scripts passing user input to grep. Multiple patterns are + combined by 'or'. + +--and | --or | --not | ( | ):: + Specify how multiple patterns are combined using boolean + expressions. `--or` is the default operator. `--and` has + higher precedence than `--or`. `-e` has to be used for all + patterns. `...`:: Search blobs in the trees for specified patterns. -`--`:: +\--:: Signals the end of options; the rest of the parameters are limiters. +Example +------- + +git grep -e \'#define\' --and \( -e MAX_PATH -e PATH_MAX \):: + Looks for a line that has `#define` and either `MAX_PATH` or + `PATH_MAX`. + Author ------ Originally written by Linus Torvalds , later -- cgit v1.2.1 From 70b9c59656f974590fc050dfb3429106fd37c9ee Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 2 Aug 2006 15:44:07 -0700 Subject: Cygwin needs NO_C99_FORMAT??? I noticed that t3800 test breaks with git built without this option. Signed-off-by: Junio C Hamano --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 700c77f56..f67b28f75 100644 --- a/Makefile +++ b/Makefile @@ -317,6 +317,7 @@ ifeq ($(uname_O),Cygwin) NO_STRLCPY = YesPlease NO_SYMLINK_HEAD = YesPlease NEEDS_LIBICONV = YesPlease + NO_C99_FORMAT = YesPlease # There are conflicting reports about this. # On some boxes NO_MMAP is needed, and not so elsewhere. # Try uncommenting this if you see things break -- YMMV. -- cgit v1.2.1 From f82cd3c6104733e2ff3305c325a440731aa1d17c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 3 Aug 2006 11:50:10 -0700 Subject: Fix "git diff blob1 blob2" showing the diff in reverse. This was introduced by mistake when revision.c::add_pending_object() was modified to use object-array instead of object-list. Signed-off-by: Junio C Hamano --- builtin-diff.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/builtin-diff.c b/builtin-diff.c index 48d2fd03b..ec27542d4 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -125,9 +125,6 @@ static int builtin_diff_blobs(struct rev_info *revs, int argc, const char **argv, struct blobinfo *blob) { - /* Blobs: the arguments are reversed when setup_revisions() - * picked them up. - */ unsigned mode = canon_mode(S_IFREG | 0644); if (argc > 1) @@ -135,7 +132,7 @@ static int builtin_diff_blobs(struct rev_info *revs, stuff_change(&revs->diffopt, mode, mode, - blob[1].sha1, blob[0].sha1, + blob[0].sha1, blob[1].sha1, blob[0].name, blob[0].name); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); -- cgit v1.2.1 From 47781bf7793205cfb7b8ce89b9c3627ecf5480fc Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 3 Aug 2006 17:42:44 +0200 Subject: fixed variable declaration in gitk Signed-off-by: Michael Signed-off-by: Junio C Hamano --- gitk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitk b/gitk index ba4644f45..5acaadf49 100755 --- a/gitk +++ b/gitk @@ -4901,7 +4901,7 @@ proc domktag {} { proc redrawtags {id} { global canv linehtag commitrow idpos selectedline curview - global mainfont + global mainfont canvxmax if {![info exists commitrow($curview,$id)]} return drawcmitrow $commitrow($curview,$id) -- cgit v1.2.1 From a91af794bb4349e0b35d6a9615db31ae2f6ee355 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 3 Aug 2006 13:44:09 -0700 Subject: read-tree: shadowed variable fix. Recent changes to built-ins broke committing from subdirectory, because the unused parameter "prefix" shadowed a global variable. Spotted by Jeff King. Signed-off-by: Junio C Hamano --- builtin-read-tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 49c10bf22..b30160a5b 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -870,7 +870,7 @@ static const char read_tree_usage[] = "git-read-tree ( | [[-m [--aggressive static struct lock_file lock_file; -int cmd_read_tree(int argc, const char **argv, const char *prefix) +int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) { int i, newfd, stage = 0; unsigned char sha1[20]; -- cgit v1.2.1 From c43ce6d603c68f716f83f1da68cc4692202085e0 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 3 Aug 2006 14:41:29 -0700 Subject: Add a couple of subdirectory tests. We still have too few of them, but we have to start from somewhere. The general rule is to make tests easy to debug when run with -v (notice use of seemingly useless echo everywhere in the new tests). Signed-off-by: Junio C Hamano --- t/t1003-read-tree-prefix.sh | 27 +++++++++++ t/t1020-subdirectory.sh | 109 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100755 t/t1003-read-tree-prefix.sh create mode 100755 t/t1020-subdirectory.sh diff --git a/t/t1003-read-tree-prefix.sh b/t/t1003-read-tree-prefix.sh new file mode 100755 index 000000000..48ab117d7 --- /dev/null +++ b/t/t1003-read-tree-prefix.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='git-read-tree --prefix test. +' + +. ./test-lib.sh + +test_expect_success setup ' + echo hello >one && + git-update-index --add one && + tree=`git-write-tree` && + echo tree is $tree +' + +echo 'one +two/one' >expect + +test_expect_success 'read-tree --prefix' ' + git-read-tree --prefix=two/ $tree && + git-ls-files >actual && + cmp expect actual +' + +test_done diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh new file mode 100755 index 000000000..4409b87f8 --- /dev/null +++ b/t/t1020-subdirectory.sh @@ -0,0 +1,109 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='Try various core-level commands in subdirectory. +' + +. ./test-lib.sh + +test_expect_success setup ' + long="a b c d e f g h i j k l m n o p q r s t u v w x y z" && + for c in $long; do echo $c; done >one && + mkdir dir && + for c in x y z $long a b c; do echo $c; done >dir/two && + cp one original.one && + cp dir/two original.two +' +HERE=`pwd` +LF=' +' + +test_expect_success 'update-index and ls-files' ' + cd $HERE && + git-update-index --add one && + case "`git-ls-files`" in + one) echo ok one ;; + *) echo bad one; exit 1 ;; + esac && + cd dir && + git-update-index --add two && + case "`git-ls-files`" in + two) echo ok two ;; + *) echo bad two; exit 1 ;; + esac && + cd .. && + case "`git-ls-files`" in + dir/two"$LF"one) echo ok both ;; + *) echo bad; exit 1 ;; + esac +' + +test_expect_success 'cat-file' ' + cd $HERE && + two=`git-ls-files -s dir/two` && + two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` && + echo "$two" && + git-cat-file -p "$two" >actual && + cmp dir/two actual && + cd dir && + git-cat-file -p "$two" >actual && + cmp two actual +' +rm -f actual dir/actual + +test_expect_success 'diff-files' ' + cd $HERE && + echo a >>one && + echo d >>dir/two && + case "`git-diff-files --name-only`" in + dir/two"$LF"one) echo ok top ;; + *) echo bad top; exit 1 ;; + esac && + # diff should not omit leading paths + cd dir && + case "`git-diff-files --name-only`" in + dir/two"$LF"one) echo ok subdir ;; + *) echo bad subdir; exit 1 ;; + esac && + case "`git-diff-files --name-only .`" in + dir/two) echo ok subdir limited ;; + *) echo bad subdir limited; exit 1 ;; + esac +' + +test_expect_success 'write-tree' ' + cd $HERE && + top=`git-write-tree` && + echo $top && + cd dir && + sub=`git-write-tree` && + echo $sub && + test "z$top" = "z$sub" +' + +test_expect_success 'checkout-index' ' + cd $HERE && + git-checkout-index -f -u one && + cmp one original.one && + cd dir && + git-checkout-index -f -u two && + cmp two ../original.two +' + +test_expect_success 'read-tree' ' + cd $HERE && + rm -f one dir/two && + tree=`git-write-tree` && + git-read-tree --reset -u "$tree" && + cmp one original.one && + cmp dir/two original.two && + cd dir && + rm -f two && + git-read-tree --reset -u "$tree" && + cmp two ../original.two && + cmp ../one ../original.one +' + +test_done -- cgit v1.2.1 From ef677686efe1868432d3cc9d4c41a93b44f3def8 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 3 Aug 2006 12:01:01 -0700 Subject: diff.c: do not use pathname comparison to tell renames The final output from diff used to compare pathnames between preimage and postimage to tell if the filepair is a rename/copy. By explicitly marking the filepair created by diffcore_rename(), the output routine, resolve_rename_copy(), does not have to do so anymore. This helps feeding a filepair that has different pathnames in one and two elements to the diff machinery (most notably, comparing two blobs). Signed-off-by: Junio C Hamano --- diff.c | 6 +----- diffcore-rename.c | 1 + diffcore.h | 3 ++- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/diff.c b/diff.c index 607c357f5..895c13765 100644 --- a/diff.c +++ b/diff.c @@ -1786,13 +1786,9 @@ struct diff_filepair *diff_queue(struct diff_queue_struct *queue, struct diff_filespec *one, struct diff_filespec *two) { - struct diff_filepair *dp = xmalloc(sizeof(*dp)); + struct diff_filepair *dp = xcalloc(1, sizeof(*dp)); dp->one = one; dp->two = two; - dp->score = 0; - dp->status = 0; - dp->source_stays = 0; - dp->broken_pair = 0; if (queue) diff_q(queue, dp); return dp; diff --git a/diffcore-rename.c b/diffcore-rename.c index 1de8d3250..0ec488a90 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -205,6 +205,7 @@ static void record_rename_pair(int dst_index, int src_index, int score) fill_filespec(two, dst->sha1, dst->mode); dp = diff_queue(NULL, one, two); + dp->renamed_pair = 1; if (!strcmp(src->path, dst->path)) dp->score = rename_src[src_index].score; else diff --git a/diffcore.h b/diffcore.h index 73c7842cc..2249bc2c0 100644 --- a/diffcore.h +++ b/diffcore.h @@ -53,11 +53,12 @@ struct diff_filepair { char status; /* M C R N D U (see Documentation/diff-format.txt) */ unsigned source_stays : 1; /* all of R/C are copies */ unsigned broken_pair : 1; + unsigned renamed_pair : 1; }; #define DIFF_PAIR_UNMERGED(p) \ (!DIFF_FILE_VALID((p)->one) && !DIFF_FILE_VALID((p)->two)) -#define DIFF_PAIR_RENAME(p) (strcmp((p)->one->path, (p)->two->path)) +#define DIFF_PAIR_RENAME(p) ((p)->renamed_pair) #define DIFF_PAIR_BROKEN(p) \ ( (!DIFF_FILE_VALID((p)->one) != !DIFF_FILE_VALID((p)->two)) && \ -- cgit v1.2.1 From 53dd8a9cb524ac2bd99072d86ee31ee48c99d0be Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 3 Aug 2006 11:57:11 -0700 Subject: Show both blob names from "git diff blob1 blob2" Earlier we deliberately showed only blob1's name because showing both names labeled the output as a renaming patch. Now the output routine (namely, diff.c::resolve_rename_copy()) is taught not to use pathname comparison to tell if a filepair is a rename, we can safely do this change. Signed-off-by: Junio C Hamano --- builtin-diff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin-diff.c b/builtin-diff.c index ec27542d4..cb4216eb8 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -133,7 +133,7 @@ static int builtin_diff_blobs(struct rev_info *revs, stuff_change(&revs->diffopt, mode, mode, blob[0].sha1, blob[1].sha1, - blob[0].name, blob[0].name); + blob[0].name, blob[1].name); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); return 0; -- cgit v1.2.1 From 2de196fec1feba8350f272c567989595901bb67e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 3 Aug 2006 16:01:58 -0700 Subject: sideband: do not use color, just say "remote:" ... per suggestion by Andrew. Signed-off-by: Junio C Hamano --- fetch-clone.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fetch-clone.c b/fetch-clone.c index 692d9b750..5e84c4620 100644 --- a/fetch-clone.c +++ b/fetch-clone.c @@ -129,14 +129,13 @@ static pid_t setup_sideband(int sideband, const char *me, int fd[2], int xd[2]) len--; switch (buf[0] & 0xFF) { case 3: + safe_write(2, "remote: ", 8); safe_write(2, buf+1, len); - fprintf(stderr, "\n"); + safe_write(2, "\n", 1); exit(1); case 2: - /* color sideband */ - safe_write(2, "\033[44;37;1m", 10); + safe_write(2, "remote: ", 8); safe_write(2, buf+1, len); - safe_write(2, "\033[m", 3); continue; case 1: safe_write(fd[1], buf+1, len); -- cgit v1.2.1 From f5fffbd3e878d2be4154174c588a229ca37b04f1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 3 Aug 2006 16:28:24 -0700 Subject: Documentation/git.txt: link git-svn and git-instaweb from the main page. Signed-off-by: Junio C Hamano --- Documentation/git.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/git.txt b/Documentation/git.txt index 7310a2b8b..bcf187a11 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -397,6 +397,9 @@ gitlink:git-quiltimport[1]:: gitlink:git-relink[1]:: Hardlink common objects in local repositories. +gitlink:git-svn[1]:: + Bidirectional operation between a single Subversion branch and git. + gitlink:git-svnimport[1]:: Import a SVN repository into git. @@ -442,6 +445,9 @@ gitlink:git-get-tar-commit-id[1]:: gitlink:git-imap-send[1]:: Dump a mailbox from stdin into an imap folder. +gitlink:git-instaweb[1]:: + Instantly browse your working repository in gitweb. + gitlink:git-mailinfo[1]:: Extracts patch and authorship information from a single e-mail message, optionally transliterating the commit -- cgit v1.2.1 From 5a716826a6f7f209777f344143cdd9e4f2903097 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 3 Aug 2006 16:40:20 -0700 Subject: GIT 1.4.2-rc3 We ended up merging too many stuff after -rc2, so here is another round of release candidate. Non bugfixes will be queued to "next" from now on until a real 1.4.2 happens. Signed-off-by: Junio C Hamano --- GIT-VERSION-GEN | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 5d25b7e12..1ce217dd7 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.4.GIT +DEF_VER=v1.4.2.GIT # First try git-describe, then see if there is a version file # (included in release tarballs), then default -- cgit v1.2.1 From 15e593e4d37d1d350fef20ab666d58f6881c7f5f Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Thu, 3 Aug 2006 16:38:39 +0100 Subject: Fixup command names in some usage strings. Most usage strings, such as for command xxx, start with "git-xxx". This updates the rebels to conform to the general pattern. (The git wrapper is an exception to this, of course ...) Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- blame.c | 2 +- builtin-diff.c | 2 +- builtin-push.c | 2 +- mktag.c | 2 +- mktree.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/blame.c b/blame.c index 76712b596..7099b53c7 100644 --- a/blame.c +++ b/blame.c @@ -20,7 +20,7 @@ #define DEBUG 0 -static const char blame_usage[] = "[-c] [-l] [-t] [-S ] [--] file [commit]\n" +static const char blame_usage[] = "git-blame [-c] [-l] [-t] [-S ] [--] file [commit]\n" " -c, --compatibility Use the same output mode as git-annotate (Default: off)\n" " -l, --long Show long commit SHA1 (Default: off)\n" " -t, --time Show raw timestamp (Default: off)\n" diff --git a/builtin-diff.c b/builtin-diff.c index cb4216eb8..107585510 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -23,7 +23,7 @@ struct blobinfo { }; static const char builtin_diff_usage[] = -"diff {0,2} -- *"; +"git-diff {0,2} -- *"; static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv) diff --git a/builtin-push.c b/builtin-push.c index c39dd1e09..53bc378f7 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -8,7 +8,7 @@ #define MAX_URI (16) -static const char push_usage[] = "git push [--all] [--tags] [-f | --force] [...]"; +static const char push_usage[] = "git-push [--all] [--tags] [-f | --force] [...]"; static int all = 0, tags = 0, force = 0, thin = 1; static const char *execute = NULL; diff --git a/mktag.c b/mktag.c index 09b6e437d..be23e589f 100644 --- a/mktag.c +++ b/mktag.c @@ -123,7 +123,7 @@ int main(int argc, char **argv) unsigned char result_sha1[20]; if (argc != 1) - usage("cat | git-mktag"); + usage("git-mktag < signaturefile"); setup_git_directory(); diff --git a/mktree.c b/mktree.c index ab63cd99d..9a6f0d2f6 100644 --- a/mktree.c +++ b/mktree.c @@ -71,7 +71,7 @@ static void write_tree(unsigned char *sha1) write_sha1_file(buffer, offset, tree_type, sha1); } -static const char mktree_usage[] = "mktree [-z]"; +static const char mktree_usage[] = "git-mktree [-z]"; int main(int ac, char **av) { -- cgit v1.2.1 From 8cdf33643dc0b21d9ea922a3fdd7f64226c421aa Mon Sep 17 00:00:00 2001 From: Ramsay Allan Jones Date: Thu, 3 Aug 2006 16:48:41 +0100 Subject: Replace some calls to die(usage_str) with usage(usage_str). The only change in behaviour should be having a "usage: " prefix on the output string rather than "fatal: ", and an exit code of 129 rather than 128. Signed-off-by: Ramsay Allan Jones Signed-off-by: Junio C Hamano --- builtin-add.c | 2 +- builtin-init-db.c | 2 +- builtin-rm.c | 2 +- builtin-write-tree.c | 2 +- hash-object.c | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/builtin-add.c b/builtin-add.c index f548b8007..096b611b5 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -117,7 +117,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) verbose = 1; continue; } - die(builtin_add_usage); + usage(builtin_add_usage); } pathspec = get_pathspec(prefix, argv + i); diff --git a/builtin-init-db.c b/builtin-init-db.c index 52473edf5..5085018e4 100644 --- a/builtin-init-db.c +++ b/builtin-init-db.c @@ -267,7 +267,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) else if (!strncmp(arg, "--shared=", 9)) shared_repository = git_config_perm("arg", arg+9); else - die(init_db_usage); + usage(init_db_usage); } /* diff --git a/builtin-rm.c b/builtin-rm.c index 92d205a71..a0882bf1b 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -80,7 +80,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) force = 1; continue; } - die(builtin_rm_usage); + usage(builtin_rm_usage); } if (argc <= i) usage(builtin_rm_usage); diff --git a/builtin-write-tree.c b/builtin-write-tree.c index 0289f5993..6b62d7dc8 100644 --- a/builtin-write-tree.c +++ b/builtin-write-tree.c @@ -73,7 +73,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix) else if (!strncmp(arg, "--prefix=", 9)) prefix = arg + 9; else - die(write_tree_usage); + usage(write_tree_usage); argc--; argv++; } diff --git a/hash-object.c b/hash-object.c index 43bd93bff..5f89e64c1 100644 --- a/hash-object.c +++ b/hash-object.c @@ -46,7 +46,7 @@ int main(int argc, char **argv) if (!no_more_flags && argv[i][0] == '-') { if (!strcmp(argv[i], "-t")) { if (argc <= ++i) - die(hash_object_usage); + usage(hash_object_usage); type = argv[i]; } else if (!strcmp(argv[i], "-w")) { @@ -66,8 +66,8 @@ int main(int argc, char **argv) hash_stdin(type, write_object); } else - die(hash_object_usage); - } + usage(hash_object_usage); + } else { const char *arg = argv[i]; if (0 <= prefix_length) -- cgit v1.2.1 From cba05fa840b637db2708014142a753680d930082 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 3 Aug 2006 21:55:41 -0700 Subject: Further clean-up: usage() vs die() This hopefully finishes the clean-up Ramsay started with recent commit 15e593e4d37d1d350fef20ab666d58f6881c7f5f and commit 8cdf33643dc0b21d9ea922a3fdd7f64226c421aa. Signed-off-by: Junio C Hamano --- builtin-check-ref-format.c | 2 +- builtin-mv.c | 2 +- builtin-prune.c | 2 +- builtin-rm.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/builtin-check-ref-format.c b/builtin-check-ref-format.c index 701de439a..fe04be77a 100644 --- a/builtin-check-ref-format.c +++ b/builtin-check-ref-format.c @@ -9,6 +9,6 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix) { if (argc != 2) - usage("git check-ref-format refname"); + usage("git-check-ref-format refname"); return !!check_ref_format(argv[1]); } diff --git a/builtin-mv.c b/builtin-mv.c index 62ae937cb..e47942c13 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -99,7 +99,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) ignore_errors = 1; continue; } - die(builtin_mv_usage); + usage(builtin_mv_usage); } count = argc - i - 1; if (count < 1) diff --git a/builtin-prune.c b/builtin-prune.c index 6a86eb52a..89ec7f142 100644 --- a/builtin-prune.c +++ b/builtin-prune.c @@ -10,7 +10,7 @@ #include "builtin.h" #include "cache-tree.h" -static const char prune_usage[] = "git prune [-n]"; +static const char prune_usage[] = "git-prune [-n]"; static int show_only = 0; static struct rev_info revs; diff --git a/builtin-rm.c b/builtin-rm.c index a0882bf1b..8af3d7eb4 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -115,7 +115,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) printf("rm '%s'\n", path); if (remove_file_from_cache(path)) - die("git rm: unable to remove %s", path); + die("git-rm: unable to remove %s", path); cache_tree_invalidate_path(active_cache_tree, path); } @@ -139,7 +139,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) continue; } if (!removed) - die("git rm: %s: %s", path, strerror(errno)); + die("git-rm: %s: %s", path, strerror(errno)); } } -- cgit v1.2.1 From d249b455475977f305240bb73473f25d040012cf Mon Sep 17 00:00:00 2001 From: Uwe Zeisberger Date: Fri, 4 Aug 2006 10:11:15 +0200 Subject: Document rev-list's option --merge Signed-off-by: Uwe Zeisberger Signed-off-by: Junio C Hamano --- Documentation/git-rev-list.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt index f60eacd93..dd9fff16d 100644 --- a/Documentation/git-rev-list.txt +++ b/Documentation/git-rev-list.txt @@ -22,6 +22,7 @@ SYNOPSIS [ [\--objects | \--objects-edge] [ \--unpacked ] ] [ \--pretty | \--header ] [ \--bisect ] + [ \--merge ] ... [ \-- ... ] DESCRIPTION @@ -123,6 +124,10 @@ OPTIONS topological order (i.e. descendant commits are shown before their parents). +--merge:: + After a failed merge, show refs that touch files having a + conflict and don't exist on all heads to merge. + Author ------ Written by Linus Torvalds -- cgit v1.2.1 From 7e18e56920bd38ffc1f2c068d943bfd3f012473d Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Fri, 4 Aug 2006 10:54:08 +0200 Subject: git-tar-tree: fix minor memory leak Free the root tree object buffer when we're done, plugging a minor leak in generate_tar(). Note: we cannot simply free(tree.buf) because this pointer is modified by tree_entry() calls in traverse_tree(). Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin-tar-tree.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c index 7c48db9ec..215892b69 100644 --- a/builtin-tar-tree.c +++ b/builtin-tar-tree.c @@ -314,6 +314,7 @@ static int generate_tar(int argc, const char **argv, const char *prefix) struct commit *commit; struct tree_desc tree; struct strbuf current_path; + void *buffer; current_path.buf = xmalloc(PATH_MAX); current_path.alloc = PATH_MAX; @@ -341,8 +342,8 @@ static int generate_tar(int argc, const char **argv, const char *prefix) } else archive_time = time(NULL); - tree.buf = read_object_with_reference(sha1, tree_type, &tree.size, - tree_sha1); + tree.buf = buffer = read_object_with_reference(sha1, tree_type, + &tree.size, tree_sha1); if (!tree.buf) die("not a reference to a tag, commit or tree object: %s", sha1_to_hex(sha1)); @@ -351,6 +352,7 @@ static int generate_tar(int argc, const char **argv, const char *prefix) write_entry(tree_sha1, ¤t_path, 040777, NULL, 0); traverse_tree(&tree, ¤t_path); write_trailer(); + free(buffer); free(current_path.buf); return 0; } -- cgit v1.2.1 From 3a3c3fc42a021f11aa8f35dc40cc69d4d4af7224 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 4 Aug 2006 17:46:19 +0200 Subject: Fix crash when GIT_DIR is invalid We used to test if a pointer was NULL, and if it was, try to access it. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.c b/setup.c index 358e139d8..2afdba414 100644 --- a/setup.c +++ b/setup.c @@ -184,7 +184,7 @@ const char *setup_git_directory_gently(int *nongit_ok) } return NULL; bad_dir_environ: - if (!nongit_ok) { + if (nongit_ok) { *nongit_ok = 1; return NULL; } -- cgit v1.2.1 From 07efc6a6b6e5098ccd2dcce853be421b7dd1e244 Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Fri, 4 Aug 2006 22:01:30 +0100 Subject: Allow config file to specify Signed-off-by identity in format-patch. Unlike git-commit, git-format-patch was not picking up and using the user.email config variable for the email part of the committer info. I was forced to use the GIT_COMMITTER_EMAIL environment variable to override the default . The fix was to simply move the call to setup_ident() to come before the git_config() call. Signed-off-by: Ramsay Allan Jones Acked-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin-log.c b/builtin-log.c index bba1496bf..691cf3aef 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -257,6 +257,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) char message_id[1024]; char ref_message_id[1024]; + setup_ident(); git_config(git_format_config); init_revisions(&rev, prefix); rev.commit_format = CMIT_FMT_EMAIL; @@ -306,7 +307,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) !strcmp(argv[i], "-s")) { const char *committer; const char *endpos; - setup_ident(); committer = git_committer_info(1); endpos = strchr(committer, '>'); if (!endpos) -- cgit v1.2.1 From 19c4588178463cd8f0745d430159ab806d9fa6e4 Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Fri, 4 Aug 2006 22:01:34 +0100 Subject: commit walkers: setup_ident() to record correct committer in ref-log. The function pull() in fetch.c calls write_ref_sha1(), which may need committer identity to update the ref-log, so they need to call setup_ident() before calling git_config() function. Acked-by: Shawn Pearce Signed-off-by: Junio C Hamano --- http-fetch.c | 1 + local-fetch.c | 1 + ssh-fetch.c | 1 + 3 files changed, 3 insertions(+) diff --git a/http-fetch.c b/http-fetch.c index 1aad39b4d..36af3e5b9 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -1226,6 +1226,7 @@ int main(int argc, const char **argv) int arg = 1; int rc = 0; + setup_ident(); setup_git_directory(); git_config(git_default_config); diff --git a/local-fetch.c b/local-fetch.c index b216bdd55..4bf86fbbe 100644 --- a/local-fetch.c +++ b/local-fetch.c @@ -210,6 +210,7 @@ int main(int argc, const char **argv) char **commit_id; int arg = 1; + setup_ident(); setup_git_directory(); git_config(git_default_config); diff --git a/ssh-fetch.c b/ssh-fetch.c index 6e16568f8..c7d8fa80e 100644 --- a/ssh-fetch.c +++ b/ssh-fetch.c @@ -132,6 +132,7 @@ int main(int argc, char **argv) prog = getenv("GIT_SSH_PUSH"); if (!prog) prog = "git-ssh-upload"; + setup_ident(); setup_git_directory(); git_config(git_default_config); -- cgit v1.2.1 From 0d958ac47a333b68b79cdc3ea206bb9a9b7486ad Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 5 Aug 2006 00:20:51 -0700 Subject: Makefile: Cygwin does not seem to need NO_STRLCPY Signed-off-by: Junio C Hamano --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index f67b28f75..0761d6c6e 100644 --- a/Makefile +++ b/Makefile @@ -314,7 +314,6 @@ ifeq ($(uname_O),Cygwin) NO_D_TYPE_IN_DIRENT = YesPlease NO_D_INO_IN_DIRENT = YesPlease NO_STRCASESTR = YesPlease - NO_STRLCPY = YesPlease NO_SYMLINK_HEAD = YesPlease NEEDS_LIBICONV = YesPlease NO_C99_FORMAT = YesPlease -- cgit v1.2.1 From f25b79397c9775df9eeef3d59d0cc3b1f913bc60 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Aug 2006 22:16:42 -0700 Subject: Fix "grep -w" We used to find the first match of the pattern and then if the match is not for the entire word, declared that the whole line does not match. But that is wrong. The command "git grep -w -e mmap" should find that a line "foo_mmap bar mmap baz" matches, by tring the second instance of pattern "mmap" on the same line. Problems an earlier round of "fix" had were pointed out by Morten Welinder, which have been incorporated in the t7002 tests. Signed-off-by: Junio C Hamano --- builtin-grep.c | 35 +++++++++++++++++------- t/t7002-grep.sh | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 10 deletions(-) create mode 100755 t/t7002-grep.sh diff --git a/builtin-grep.c b/builtin-grep.c index 69b7c4862..93b7e07b3 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -410,8 +410,10 @@ static int fixmatch(const char *pattern, char *line, regmatch_t *match) static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol) { int hit = 0; + int at_true_bol = 1; regmatch_t pmatch[10]; + again: if (!opt->fixed) { regex_t *exp = &p->regexp; hit = !regexec(exp, bol, ARRAY_SIZE(pmatch), @@ -422,22 +424,35 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol } if (hit && opt->word_regexp) { - /* Match beginning must be either - * beginning of the line, or at word - * boundary (i.e. the last char must - * not be alnum or underscore). - */ if ((pmatch[0].rm_so < 0) || (eol - bol) <= pmatch[0].rm_so || (pmatch[0].rm_eo < 0) || (eol - bol) < pmatch[0].rm_eo) die("regexp returned nonsense"); - if (pmatch[0].rm_so != 0 && - word_char(bol[pmatch[0].rm_so-1])) - hit = 0; - if (pmatch[0].rm_eo != (eol-bol) && - word_char(bol[pmatch[0].rm_eo])) + + /* Match beginning must be either beginning of the + * line, or at word boundary (i.e. the last char must + * not be a word char). Similarly, match end must be + * either end of the line, or at word boundary + * (i.e. the next char must not be a word char). + */ + if ( ((pmatch[0].rm_so == 0 && at_true_bol) || + !word_char(bol[pmatch[0].rm_so-1])) && + ((pmatch[0].rm_eo == (eol-bol)) || + !word_char(bol[pmatch[0].rm_eo])) ) + ; + else hit = 0; + + if (!hit && pmatch[0].rm_so + bol + 1 < eol) { + /* There could be more than one match on the + * line, and the first match might not be + * strict word match. But later ones could be! + */ + bol = pmatch[0].rm_so + bol + 1; + at_true_bol = 0; + goto again; + } } return hit; } diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh new file mode 100755 index 000000000..00a7d762c --- /dev/null +++ b/t/t7002-grep.sh @@ -0,0 +1,85 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='git grep -w +' + +. ./test-lib.sh + +test_expect_success setup ' + { + echo foo mmap bar + echo foo_mmap bar + echo foo_mmap bar mmap + echo foo mmap bar_mmap + echo foo_mmap bar mmap baz + } >file && + echo x x xx x >x && + echo y yy >y && + echo zzz > z && + git add file x y z && + git commit -m initial +' + +for H in HEAD '' +do + case "$H" in + HEAD) HC='HEAD:' L='HEAD' ;; + '') HC= L='in working tree' ;; + esac + + test_expect_success "grep -w $L" ' + { + echo ${HC}file:1:foo mmap bar + echo ${HC}file:3:foo_mmap bar mmap + echo ${HC}file:4:foo mmap bar_mmap + echo ${HC}file:5:foo_mmap bar mmap baz + } >expected && + git grep -n -w -e mmap $H >actual && + diff expected actual + ' + + test_expect_success "grep -w $L (x)" ' + { + echo ${HC}x:1:x x xx x + } >expected && + git grep -n -w -e "x xx* x" $H >actual && + diff expected actual + ' + + test_expect_success "grep -w $L (y-1)" ' + { + echo ${HC}y:1:y yy + } >expected && + git grep -n -w -e "^y" $H >actual && + diff expected actual + ' + + test_expect_success "grep -w $L (y-2)" ' + : >expected && + if git grep -n -w -e "^y y" $H >actual + then + echo should not have matched + cat actual + false + else + diff expected actual + fi + ' + + test_expect_success "grep -w $L (z)" ' + : >expected && + if git grep -n -w -e "^z" $H >actual + then + echo should not have matched + cat actual + false + else + diff expected actual + fi + ' +done + +test_done -- cgit v1.2.1 From b20805af603380c3abfc1b2e7859d28185e397f1 Mon Sep 17 00:00:00 2001 From: Michael Krelin Date: Mon, 7 Aug 2006 17:10:21 +0200 Subject: handle https:// protocol in git-clone Signed-off-by: Junio C Hamano --- git-clone.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-clone.sh b/git-clone.sh index acc7a51b9..7060bdab0 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -298,7 +298,7 @@ yes,yes) fi git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1 ;; - http://*) + https://*|http://*) if test -z "@@NO_CURL@@" then clone_dumb_http "$repo" "$D" -- cgit v1.2.1 From 1dcb69224ca4da3d97c502de88de73ec4b362082 Mon Sep 17 00:00:00 2001 From: Ryan Anderson Date: Mon, 7 Aug 2006 05:11:23 -0700 Subject: log-tree: show_log() should respect the setting of diffopt->line_termination Signed-off-by: Ryan Anderson Signed-off-by: Junio C Hamano --- log-tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/log-tree.c b/log-tree.c index b67b8dd17..05ede0c17 100644 --- a/log-tree.c +++ b/log-tree.c @@ -59,7 +59,7 @@ void show_log(struct rev_info *opt, const char *sep) fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout); if (opt->parents) show_parents(commit, abbrev_commit); - putchar('\n'); + putchar(opt->diffopt.line_termination); return; } -- cgit v1.2.1 From 7c49cb288173ab5264b3b9e4257aeeb13388334c Mon Sep 17 00:00:00 2001 From: Ryan Anderson Date: Mon, 7 Aug 2006 05:11:24 -0700 Subject: annotate: Fix bug when parsing merges with differing real and logical parents. Signed-off-by: Ryan Anderson Signed-off-by: Junio C Hamano --- git-annotate.perl | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 122 insertions(+), 6 deletions(-) diff --git a/git-annotate.perl b/git-annotate.perl index 505b5ccb2..215ed26f3 100755 --- a/git-annotate.perl +++ b/git-annotate.perl @@ -147,7 +147,7 @@ sub init_claim { sub handle_rev { - my $i = 0; + my $revseen = 0; my %seen; while (my $rev = shift @revqueue) { next if $seen{$rev}++; @@ -247,22 +247,129 @@ sub git_find_parent { return $parent; } +sub git_find_all_parents { + my ($rev) = @_; + + my $revparent = open_pipe("git-rev-list","--remove-empty", "--parents","--max-count=1","$rev") + or die "Failed to open git-rev-list to find a single parent: $!"; + + my $parentline = <$revparent>; + chomp $parentline; + my ($origrev, @parents) = split m/\s+/, $parentline; + + close($revparent); + + return @parents; +} + +sub git_merge_base { + my ($rev1, $rev2) = @_; + + my $mb = open_pipe("git-merge-base", $rev1, $rev2) + or die "Failed to open git-merge-base: $!"; + + my $base = <$mb>; + chomp $base; + + close($mb); + + return $base; +} + +# Construct a set of pseudo parents that are in the same order, +# and the same quantity as the real parents, +# but whose SHA1s are as similar to the logical parents +# as possible. +sub get_pseudo_parents { + my ($all, $fake) = @_; + + my @all = @$all; + my @fake = @$fake; + + my @pseudo; + + my %fake = map {$_ => 1} @fake; + my %seenfake; + + my $fakeidx = 0; + foreach my $p (@all) { + if (exists $fake{$p}) { + if ($fake[$fakeidx] ne $p) { + die sprintf("parent mismatch: %s != %s\nall:%s\nfake:%s\n", + $fake[$fakeidx], $p, + join(", ", @all), + join(", ", @fake), + ); + } + + push @pseudo, $p; + $fakeidx++; + $seenfake{$p}++; + + } else { + my $base = git_merge_base($fake[$fakeidx], $p); + if ($base ne $fake[$fakeidx]) { + die sprintf("Result of merge-base doesn't match fake: %s,%s != %s\n", + $fake[$fakeidx], $p, $base); + } + + # The details of how we parse the diffs + # mean that we cannot have a duplicate + # revision in the list, so if we've already + # seen the revision we would normally add, just use + # the actual revision. + if ($seenfake{$base}) { + push @pseudo, $p; + } else { + push @pseudo, $base; + $seenfake{$base}++; + } + } + } + + return @pseudo; +} + # Get a diff between the current revision and a parent. # Record the commit information that results. sub git_diff_parse { my ($parents, $rev, %revinfo) = @_; + my @pseudo_parents; + my @command = ("git-diff-tree"); + my $revision_spec; + + if (scalar @$parents == 1) { + + $revision_spec = join("..", $parents->[0], $rev); + @pseudo_parents = @$parents; + } else { + my @all_parents = git_find_all_parents($rev); + + if (@all_parents != @$parents) { + @pseudo_parents = get_pseudo_parents(\@all_parents, $parents); + } else { + @pseudo_parents = @$parents; + } + + $revision_spec = $rev; + push @command, "-c"; + } + my @filenames = ( $revs{$rev}{'filename'} ); + foreach my $parent (@$parents) { push @filenames, $revs{$parent}{'filename'}; } - my $diff = open_pipe("git-diff-tree","-M","-p","-c",$rev,"--", - @filenames ) + push @command, "-p", "-M", $revision_spec, "--", @filenames; + + + my $diff = open_pipe( @command ) or die "Failed to call git-diff for annotation: $!"; - _git_diff_parse($diff, $parents, $rev, %revinfo); + _git_diff_parse($diff, \@pseudo_parents, $rev, %revinfo); close($diff); } @@ -283,6 +390,7 @@ sub _git_diff_parse { $diff_header_regexp .= "@" x @$parents; $diff_header_regexp .= ' -\d+,\d+' x @$parents; $diff_header_regexp .= ' \+(\d+),\d+'; + $diff_header_regexp .= " " . ("@" x @$parents); my %claim_regexps; my $allparentplus = '^' . '\\+' x @$parents . '(.*)$'; @@ -311,6 +419,7 @@ sub _git_diff_parse { DIFF: while(<$diff>) { chomp; + #printf("%d:%s:\n", $gotheader, $_); if (m/$diff_header_regexp/) { $remstart = $1 - 1; # (0-based arrays) @@ -391,10 +500,17 @@ sub _git_diff_parse { printf("parent %s is on line %d\n", $parent, $pi{$parent}); } + my @context; + for (my $i = -2; $i < 2; $i++) { + push @context, get_line($slines, $ri + $i); + } + my $context = join("\n", @context); + + my $justline = substr($_, scalar @$parents); die sprintf("Line %d, does not match:\n|%s|\n|%s|\n%s\n", $ri, - substr($_,scalar @$parents), - get_line($slines,$ri), $rev); + $justline, + $context); } foreach my $parent (@$parents) { $plines{$parent}[$pi{$parent}++] = $slines->[$ri]; -- cgit v1.2.1 From aa5481c1af08edbca821a0d025d26e9bc41a5c49 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 8 Aug 2006 12:23:47 -0700 Subject: debugging: XMALLOC_POISON Compile with -DXMALLOC_POISON=1 to catch errors from using uninitialized memory returned by xmalloc. Signed-off-by: Junio C Hamano --- git-compat-util.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/git-compat-util.h b/git-compat-util.h index 93f558056..3bcf5b13f 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -91,6 +91,9 @@ static inline void *xmalloc(size_t size) ret = malloc(1); if (!ret) die("Out of memory, malloc failed"); +#ifdef XMALLOC_POISON + memset(ret, 0xA5, size); +#endif return ret; } -- cgit v1.2.1 From 329a304714255f6e5528b4311d29f9d83c85d201 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 8 Aug 2006 12:21:33 -0700 Subject: builtin-mv: fix use of uninitialized memory. Juergen Ruehle noticed that add_slash() tries to strcat() into uninitialized memory and fails. Signed-off-by: Junio C Hamano --- builtin-mv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builtin-mv.c b/builtin-mv.c index e47942c13..ce8187c1e 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -48,7 +48,8 @@ static const char *add_slash(const char *path) if (path[len - 1] != '/') { char *with_slash = xmalloc(len + 2); memcpy(with_slash, path, len); - strcat(with_slash + len, "/"); + with_slash[len++] = '/'; + with_slash[len] = 0; return with_slash; } return path; -- cgit v1.2.1 From c96c29093f70f04e01ff1d3a9c1d509ef6afdb00 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 8 Aug 2006 13:11:16 -0700 Subject: GIT-VERSION-GEN: adjust for ancient git When an ancient "git" that does not understand "describe" command is on the $PATH, "git describe" emitted a Usage message without exiting non-zero status (which is a mistake we cannot fix retroactively). Catch this case to make sure we do not try using phoney multi-line string as a version number. Signed-off-by: Junio C Hamano --- GIT-VERSION-GEN | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 1ce217dd7..14923c973 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -3,9 +3,17 @@ GVF=GIT-VERSION-FILE DEF_VER=v1.4.2.GIT +LF=' +' + # First try git-describe, then see if there is a version file # (included in release tarballs), then default -if VN=$(git describe --abbrev=4 HEAD 2>/dev/null); then +if VN=$(git describe --abbrev=4 HEAD 2>/dev/null) && + case "$VN" in + *$LF*) (exit 1) ;; + v[0-9]*) : happy ;; + esac +then VN=$(echo "$VN" | sed -e 's/-/./g'); elif test -f version then -- cgit v1.2.1 From 6c8d06aff107aa2132648d682a278111c1d08565 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Tue, 8 Aug 2006 16:01:32 -0400 Subject: git-push: allow pushing from subdirectories The semantics are equivalent to pushing from the root; we just try harder to find the .git directory. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git.c b/git.c index 6e72a893b..18ba14ade 100644 --- a/git.c +++ b/git.c @@ -229,7 +229,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "log", cmd_log, NEEDS_PREFIX | USE_PAGER }, { "whatchanged", cmd_whatchanged, NEEDS_PREFIX | USE_PAGER }, { "show", cmd_show, NEEDS_PREFIX | USE_PAGER }, - { "push", cmd_push }, + { "push", cmd_push, NEEDS_PREFIX }, { "format-patch", cmd_format_patch, NEEDS_PREFIX }, { "count-objects", cmd_count_objects }, { "diff", cmd_diff, NEEDS_PREFIX }, -- cgit v1.2.1 From d5dc6a76d49367cddc015e01d2e9aa22e64d7e28 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Wed, 9 Aug 2006 02:26:23 +0200 Subject: Update git-init-db(1) and documentation of core.sharedRepository Combine option descriptions in git-init-db(1). Reflect the changes to additionally allow all users to read the created git repository. Signed-off-by: Jonas Fonseca Signed-off-by: Junio C Hamano --- Documentation/config.txt | 9 +++++--- Documentation/git-init-db.txt | 51 +++++++++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index d89916bea..ce722a2db 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -83,9 +83,12 @@ core.repositoryFormatVersion:: version. core.sharedRepository:: - If true, the repository is made shareable between several users - in a group (making sure all the files and objects are group-writable). - See gitlink:git-init-db[1]. False by default. + When 'group' (or 'true'), the repository is made shareable between + several users in a group (making sure all the files and objects are + group-writable). When 'all' (or 'world' or 'everybody'), the + repository will be readable by all users, additionally to being + group-shareable. When 'umask' (or 'false'), git will use permissions + reported by umask(2). See gitlink:git-init-db[1]. False by default. core.warnAmbiguousRefs:: If true, git will warn you if the ref name you passed it is ambiguous diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt index 0a4fc14b9..63cd5dab3 100644 --- a/Documentation/git-init-db.txt +++ b/Documentation/git-init-db.txt @@ -8,17 +8,47 @@ git-init-db - Creates an empty git repository SYNOPSIS -------- -'git-init-db' [--template=] [--shared] +'git-init-db' [--template=] [--shared[=]] OPTIONS ------- + +-- + --template=:: - Provide the directory from which templates will be used. - The default template directory is `/usr/share/git-core/templates`. ---shared:: - Specify that the git repository is to be shared amongst several users. +Provide the directory from which templates will be used. The default template +directory is `/usr/share/git-core/templates`. + +When specified, `` is used as the source of the template +files rather than the default. The template files include some directory +structure, some suggested "exclude patterns", and copies of non-executing +"hook" files. The suggested patterns and hook files are all modifiable and +extensible. + +--shared[={false|true|umask|group|all|world|everybody}]:: + +Specify that the git repository is to be shared amongst several users. This +allows users belonging to the same group to push into that +repository. When specified, the config variable "core.sharedRepository" is +set so that files and directories under `$GIT_DIR` are created with the +requested permissions. When not specified, git will use permissions reported +by umask(2). + +The option can have the following values, defaulting to 'group' if no value +is given: + + - 'umask' (or 'false'): Use permissions reported by umask(2). The default, + when `--shared` is not specified. + + - 'group' (or 'true'): Make the repository group-writable, (and g+sx, since + the git group may be not the primary group of all users). + + - 'all' (or 'world' or 'everybody'): Same as 'group', but make the repository + readable by all users. + +-- DESCRIPTION @@ -29,12 +59,6 @@ template files. An initial `HEAD` file that references the HEAD of the master branch is also created. -If `--template=` is specified, `` -is used as the source of the template files rather than the default. -The template files include some directory structure, some suggested -"exclude patterns", and copies of non-executing "hook" files. The -suggested patterns and hook files are all modifiable and extensible. - If the `$GIT_DIR` environment variable is set then it specifies a path to use instead of `./.git` for the base of the repository. @@ -42,11 +66,6 @@ If the object storage directory is specified via the `$GIT_OBJECT_DIRECTORY` environment variable then the sha1 directories are created underneath - otherwise the default `$GIT_DIR/objects` directory is used. -A shared repository allows users belonging to the same group to push into that -repository. When specifying `--shared` the config variable "core.sharedRepository" -is set to 'true' so that directories under `$GIT_DIR` are made group writable -(and g+sx, since the git group may be not the primary group of all users). - Running `git-init-db` in an existing repository is safe. It will not overwrite things that are already there. The primary reason for rerunning `git-init-db` is to pick up newly added templates. -- cgit v1.2.1 From fb6ff943de33dccc3f43541ed4ae4b71abddac8b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 7 Aug 2006 22:41:32 -0700 Subject: Documentation: git-status takes the same options as git-commit Signed-off-by: Junio C Hamano --- Documentation/git-status.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt index e446f4812..ce7857e5a 100644 --- a/Documentation/git-status.txt +++ b/Documentation/git-status.txt @@ -8,7 +8,7 @@ git-status - Show working tree status SYNOPSIS -------- -'git-status' +'git-status' ... DESCRIPTION ----------- @@ -23,6 +23,10 @@ If there is no path that is different between the index file and the current HEAD commit, the command exits with non-zero status. +The command takes the same set of options as `git-commit`; it +shows what would be committed if the same options are given to +`git-commit`. + OUTPUT ------ -- cgit v1.2.1 From 1d17c25c38a6b98d20b7bbe789b45996fd84d672 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 00:57:01 -0700 Subject: Fix tutorial-2.html Honza Pazdziora noticed that one example did not match reality. Signed-off-by: Junio C Hamano --- Documentation/tutorial-2.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/tutorial-2.txt b/Documentation/tutorial-2.txt index 894ca5e06..2f4fe1217 100644 --- a/Documentation/tutorial-2.txt +++ b/Documentation/tutorial-2.txt @@ -244,6 +244,7 @@ $ git ls-files --stage $ git cat-file -t 513feba2 blob $ git cat-file blob 513feba2 +hello world! hello world, again ------------------------------------------------ -- cgit v1.2.1 From 72ee96c0f1861fcdb9eaf39e78d86888437a27a9 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 12:45:27 -0700 Subject: check return value from diff_setup_done() Signed-off-by: Junio C Hamano --- builtin-diff.c | 3 ++- revision.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/builtin-diff.c b/builtin-diff.c index 107585510..dd9886c6e 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -253,7 +253,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix) argc = setup_revisions(argc, argv, &rev, NULL); if (!rev.diffopt.output_format) { rev.diffopt.output_format = DIFF_FORMAT_PATCH; - diff_setup_done(&rev.diffopt); + if (diff_setup_done(&rev.diffopt) < 0) + die("diff_setup_done failed"); } /* Do we have --cached and not have a pending object, then diff --git a/revision.c b/revision.c index a58257ad8..5a91d06b9 100644 --- a/revision.c +++ b/revision.c @@ -936,7 +936,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch revs->diffopt.output_format = DIFF_FORMAT_PATCH; } revs->diffopt.abbrev = revs->abbrev; - diff_setup_done(&revs->diffopt); + if (diff_setup_done(&revs->diffopt) < 0) + die("diff_setup_done failed"); return left; } -- cgit v1.2.1 From 02c5cba2007856465710aa37cd41b404372ab95b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 13:17:04 -0700 Subject: find_unique_abbrev() with len=0 should not abbreviate Signed-off-by: Junio C Hamano --- sha1_name.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sha1_name.c b/sha1_name.c index 5fe8e5d4b..c5a05faeb 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -193,7 +193,7 @@ const char *find_unique_abbrev(const unsigned char *sha1, int len) is_null = !memcmp(sha1, null_sha1, 20); memcpy(hex, sha1_to_hex(sha1), 40); - if (len == 40) + if (len == 40 || !len) return hex; while (len < 40) { unsigned char sha1_ret[20]; -- cgit v1.2.1 From 03b9d560bed6029f43968ad3f09a8f9c015b20e0 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 13:17:19 -0700 Subject: make --find-copies-harder imply -C Signed-off-by: Junio C Hamano --- diff.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/diff.c b/diff.c index 895c13765..02a409d96 100644 --- a/diff.c +++ b/diff.c @@ -1515,9 +1515,10 @@ void diff_setup(struct diff_options *options) int diff_setup_done(struct diff_options *options) { - if ((options->find_copies_harder && - options->detect_rename != DIFF_DETECT_COPY) || - (0 <= options->rename_limit && !options->detect_rename)) + if (options->find_copies_harder) + options->detect_rename = DIFF_DETECT_COPY; + + if ((0 <= options->rename_limit && !options->detect_rename) return -1; if (options->output_format & (DIFF_FORMAT_NAME | -- cgit v1.2.1 From 943d5b73e2adf3cd0d3f72c9a06c75681a4ea3ca Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 14:05:23 -0700 Subject: allow diff.renamelimit to be set regardless of -M/-C Signed-off-by: Junio C Hamano --- diff.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/diff.c b/diff.c index 02a409d96..b3b1781a9 100644 --- a/diff.c +++ b/diff.c @@ -1518,9 +1518,6 @@ int diff_setup_done(struct diff_options *options) if (options->find_copies_harder) options->detect_rename = DIFF_DETECT_COPY; - if ((0 <= options->rename_limit && !options->detect_rename) - return -1; - if (options->output_format & (DIFF_FORMAT_NAME | DIFF_FORMAT_NAME_STATUS | DIFF_FORMAT_CHECKDIFF | -- cgit v1.2.1 From 2c71810b90d122abdcc57fc3cb62174d16e77b58 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 22:47:25 -0700 Subject: git-apply: applying a patch to make a symlink shorter. The internal representation of the result is counted string (i.e. char *buf and ulong size), which is fine for writing out to regular file, but throwing the buf at symlink(2) was a no-no. Reported by Willy Tarreau. Signed-off-by: Junio C Hamano --- builtin-apply.c | 11 +++++++++++ t/t4115-apply-symlink.sh | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100755 t/t4115-apply-symlink.sh diff --git a/builtin-apply.c b/builtin-apply.c index f8c6763c7..c15987386 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -1698,6 +1698,14 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry * desc.buffer = buf; if (apply_fragments(&desc, patch) < 0) return -1; + + /* NUL terminate the result */ + if (desc.alloc <= desc.size) { + desc.buffer = xrealloc(desc.buffer, desc.size + 1); + desc.alloc++; + } + desc.buffer[desc.size] = 0; + patch->result = desc.buffer; patch->resultsize = desc.size; @@ -2040,6 +2048,9 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf, int fd; if (S_ISLNK(mode)) + /* Although buf:size is counted string, it also is NUL + * terminated. + */ return symlink(buf, path); fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666); if (fd < 0) diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh new file mode 100755 index 000000000..d5f2cfb18 --- /dev/null +++ b/t/t4115-apply-symlink.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='git-apply symlinks and partial files + +' + +. ./test-lib.sh + +test_expect_success setup ' + + ln -s path1/path2/path3/path4/path5 link1 && + git add link? && + git commit -m initial && + + git branch side && + + rm -f link? && + + ln -s htap6 link1 && + git update-index link? && + git commit -m second && + + git diff-tree -p HEAD^ HEAD >patch && + git apply --stat --summary patch + +' + +test_expect_success 'apply symlink patch' ' + + git checkout side && + git apply patch && + git diff-files -p >patched && + diff -u patch patched + +' + +test_expect_success 'apply --index symlink patch' ' + + git checkout -f side && + git apply --index patch && + git diff-index --cached -p HEAD >patched && + diff -u patch patched + +' + +test_done -- cgit v1.2.1 From 1e8d304507b2d7e3b411d9b351fd348edd253df8 Mon Sep 17 00:00:00 2001 From: Rutger Nijlunsing Date: Wed, 9 Aug 2006 20:54:23 +0200 Subject: http-push: Make WebDAV work with (broken?) default apache2 WebDAV module WebDAV on Debian unstable cannot handle renames on WebDAV from file.ext to newfile (without ext) when newfile* already exists. Normally, git creates a file like 'objects/xx/sha1.token', which is renamed to 'objects/xx/sha1' when transferred completely. Just use '_' instead of '.' so WebDAV doesn't see it as an extension change. Signed-off-by: Rutger Nijlunsing Acked-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- http-push.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http-push.c b/http-push.c index 4021e7d92..d45733ef6 100644 --- a/http-push.c +++ b/http-push.c @@ -530,7 +530,7 @@ static void start_put(struct transfer_request *request) request->dest = xmalloc(strlen(request->url) + 14); sprintf(request->dest, "Destination: %s", request->url); posn += 38; - *(posn++) = '.'; + *(posn++) = '_'; strcpy(posn, request->lock->token); slot = get_active_slot(); -- cgit v1.2.1 From 567a03d14cb624b0edc76be9cffda11edac2bea3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 10 Aug 2006 00:30:33 -0700 Subject: combine-diff: use color Using the same mechanism as the regular diffs, color combined diff output. Signed-off-by: Junio C Hamano --- combine-diff.c | 50 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/combine-diff.c b/combine-diff.c index 919112bba..ba8baca0a 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -497,11 +497,17 @@ static void show_parent_lno(struct sline *sline, unsigned long l0, unsigned long printf(" -%lu,%lu", l0, l1-l0); } -static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent) +static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent, + int use_color) { unsigned long mark = (1UL<lost_head; while (ll) { + fputs(c_old, stdout); for (j = 0; j < num_parent; j++) { if (ll->parent_map & (1UL<line); + printf("%s%s\n", ll->line, c_reset); ll = ll->next; } if (cnt < lno) break; p_mask = 1; + if (!(sl->flag & (mark-1))) + fputs(c_plain, stdout); + else + fputs(c_new, stdout); for (j = 0; j < num_parent; j++) { if (p_mask & sl->flag) putchar('+'); @@ -554,7 +566,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent) putchar(' '); p_mask <<= 1; } - printf("%.*s\n", sl->len, sl->bol); + printf("%.*s%s\n", sl->len, sl->bol, c_reset); } } } @@ -586,14 +598,15 @@ static void reuse_combine_diff(struct sline *sline, unsigned long cnt, sline->p_lno[i] = sline->p_lno[j]; } -static void dump_quoted_path(const char *prefix, const char *path) +static void dump_quoted_path(const char *prefix, const char *path, + const char *c_meta, const char *c_reset) { - fputs(prefix, stdout); + printf("%s%s", c_meta, prefix); if (quote_c_style(path, NULL, NULL, 0)) quote_c_style(path, NULL, stdout, 0); else printf("%s", path); - putchar('\n'); + printf("%s\n", c_reset); } static int show_patch_diff(struct combine_diff_path *elem, int num_parent, @@ -699,18 +712,22 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, if (show_hunks || mode_differs || working_tree_file) { const char *abb; + int use_color = opt->color_diff; + const char *c_meta = diff_get_color(use_color, DIFF_METAINFO); + const char *c_reset = diff_get_color(use_color, DIFF_RESET); if (rev->loginfo) show_log(rev, opt->msg_sep); - dump_quoted_path(dense ? "diff --cc " : "diff --combined ", elem->path); - printf("index "); + dump_quoted_path(dense ? "diff --cc " : "diff --combined ", + elem->path, c_meta, c_reset); + printf("%sindex ", c_meta); for (i = 0; i < num_parent; i++) { abb = find_unique_abbrev(elem->parent[i].sha1, abbrev); printf("%s%s", i ? "," : "", abb); } abb = find_unique_abbrev(elem->sha1, abbrev); - printf("..%s\n", abb); + printf("..%s%s\n", abb, c_reset); if (mode_differs) { int added = !!elem->mode; @@ -719,10 +736,11 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, DIFF_STATUS_ADDED) added = 0; if (added) - printf("new file mode %06o", elem->mode); + printf("%snew file mode %06o", + c_meta, elem->mode); else { if (!elem->mode) - printf("deleted file "); + printf("%sdeleted file ", c_meta); printf("mode "); for (i = 0; i < num_parent; i++) { printf("%s%06o", i ? "," : "", @@ -731,11 +749,11 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, if (elem->mode) printf("..%06o", elem->mode); } - putchar('\n'); + printf("%s\n", c_reset); } - dump_quoted_path("--- a/", elem->path); - dump_quoted_path("+++ b/", elem->path); - dump_sline(sline, cnt, num_parent); + dump_quoted_path("--- a/", elem->path, c_meta, c_reset); + dump_quoted_path("+++ b/", elem->path, c_meta, c_reset); + dump_sline(sline, cnt, num_parent, opt->color_diff); } free(result); -- cgit v1.2.1 From 306ea2df03322ac8c29f4eb5a968acb7ef3c8f72 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 10 Aug 2006 00:50:15 -0700 Subject: Fix git-diff A...B Commit 9919f41 meant to make git-diff A...B to (usually) mean "git-diff `git-merge-base A B` B", but it got the parameters wrong and ended up showing "git-diff `git-merge-base A B` A" by mistake. Signed-off-by: Junio C Hamano --- builtin-diff.c | 1 + 1 file changed, 1 insertion(+) diff --git a/builtin-diff.c b/builtin-diff.c index dd9886c6e..a090e298a 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -349,6 +349,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) * A and B. We have ent[0] == merge-base, ent[1] == A, * and ent[2] == B. Show diff between the base and B. */ + ent[1] = ent[2]; return builtin_diff_tree(&rev, argc, argv, ent); } else -- cgit v1.2.1 From 242abf106c6929028c2dc916504879885cd64d4d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 10 Aug 2006 00:56:40 -0700 Subject: builtin-apply: remove unused increment We do not use desc.alloc after assigning desc.buffer to patch->result; do not bother to increment it. Signed-off-by: Junio C Hamano --- builtin-apply.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index c15987386..be2c7152c 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -1700,10 +1700,8 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry * return -1; /* NUL terminate the result */ - if (desc.alloc <= desc.size) { + if (desc.alloc <= desc.size) desc.buffer = xrealloc(desc.buffer, desc.size + 1); - desc.alloc++; - } desc.buffer[desc.size] = 0; patch->result = desc.buffer; -- cgit v1.2.1 From 83a2b841d6b90e6f4b797df40ed3a105364574b6 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:30 +0200 Subject: Add has_extension() The little helper has_extension() documents through its name what we are trying to do and makes sure we don't forget the underrun check. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin-help.c | 2 +- git-compat-util.h | 6 ++++++ http-fetch.c | 2 +- index-pack.c | 2 +- local-fetch.c | 4 ++-- refs.c | 2 +- sha1_file.c | 2 +- verify-pack.c | 2 +- 8 files changed, 14 insertions(+), 8 deletions(-) diff --git a/builtin-help.c b/builtin-help.c index fb731cc93..7a7f7759e 100644 --- a/builtin-help.c +++ b/builtin-help.c @@ -140,7 +140,7 @@ static void list_commands(const char *exec_path, const char *pattern) continue; entlen = strlen(de->d_name); - if (4 < entlen && !strcmp(de->d_name + entlen - 4, ".exe")) + if (has_extension(de->d_name, entlen, ".exe")) entlen -= 4; if (longest < entlen) diff --git a/git-compat-util.h b/git-compat-util.h index 3bcf5b13f..dd9209365 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -139,6 +139,12 @@ static inline ssize_t xwrite(int fd, const void *buf, size_t len) } } +static inline int has_extension(const char *filename, int len, const char *ext) +{ + int extlen = strlen(ext); + return len > extlen && !memcmp(filename + len - extlen, ext, extlen); +} + /* Sane ctype - no locale, and works with signed chars */ #undef isspace #undef isdigit diff --git a/http-fetch.c b/http-fetch.c index 36af3e5b9..6ea39f058 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -870,7 +870,7 @@ static void process_ls_pack(struct remote_ls_ctx *ls) if (strlen(ls->dentry_name) == 63 && !strncmp(ls->dentry_name, "objects/pack/pack-", 18) && - !strncmp(ls->dentry_name+58, ".pack", 5)) { + has_extension(ls->dentry_name, 63, ".pack")) { get_sha1_hex(ls->dentry_name + 18, sha1); setup_index(ls->repo, sha1); } diff --git a/index-pack.c b/index-pack.c index b39953dc6..a91e39ecd 100644 --- a/index-pack.c +++ b/index-pack.c @@ -447,7 +447,7 @@ int main(int argc, char **argv) usage(index_pack_usage); if (!index_name) { int len = strlen(pack_name); - if (len < 5 || strcmp(pack_name + len - 5, ".pack")) + if (!has_extension(pack_name, len, ".pack")) die("packfile name '%s' does not end with '.pack'", pack_name); index_name_buf = xmalloc(len); diff --git a/local-fetch.c b/local-fetch.c index 4bf86fbbe..b6ec170c0 100644 --- a/local-fetch.c +++ b/local-fetch.c @@ -43,8 +43,8 @@ static int setup_indices(void) return -1; while ((de = readdir(dir)) != NULL) { int namelen = strlen(de->d_name); - if (namelen != 50 || - strcmp(de->d_name + namelen - 5, ".pack")) + if (namelen != 50 || + !has_extension(de->d_name, namelen, ".pack")) continue; get_sha1_hex(de->d_name + 5, sha1); setup_index(sha1); diff --git a/refs.c b/refs.c index 02850b690..b01835f63 100644 --- a/refs.c +++ b/refs.c @@ -147,7 +147,7 @@ static int do_for_each_ref(const char *base, int (*fn)(const char *path, const u namelen = strlen(de->d_name); if (namelen > 255) continue; - if (namelen>5 && !strcmp(de->d_name+namelen-5,".lock")) + if (has_extension(de->d_name, namelen, ".lock")) continue; memcpy(path + baselen, de->d_name, namelen+1); if (stat(git_path("%s", path), &st) < 0) diff --git a/sha1_file.c b/sha1_file.c index 43bc2ea0c..a1bb01ca3 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -590,7 +590,7 @@ static void prepare_packed_git_one(char *objdir, int local) int namelen = strlen(de->d_name); struct packed_git *p; - if (strcmp(de->d_name + namelen - 4, ".idx")) + if (!has_extension(de->d_name, namelen, ".idx")) continue; /* we have .idx. Is it a file we can map? */ diff --git a/verify-pack.c b/verify-pack.c index c99db9dd7..ef00204ad 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -10,7 +10,7 @@ static int verify_one_pack(char *arg, int verbose) /* Should name foo.idx, but foo.pack may be named; * convert it to foo.idx */ - if (!strcmp(arg + len - 5, ".pack")) { + if (has_extension(arg, len, ".pack")) { strcpy(arg + len - 5, ".idx"); len--; } -- cgit v1.2.1 From 6f05b57da8e82c471ea6765da67e813d496ed278 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:31 +0200 Subject: git-verify-pack: show usage when no pack was specified Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/verify-pack.c b/verify-pack.c index ef00204ad..7201596bf 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -34,6 +34,7 @@ int main(int ac, char **av) int errs = 0; int verbose = 0; int no_more_options = 0; + int nothing_done = 1; while (1 < ac) { char path[PATH_MAX]; @@ -50,8 +51,13 @@ int main(int ac, char **av) strcpy(path, av[1]); if (verify_one_pack(path, verbose)) errs++; + nothing_done = 0; } ac--; av++; } + + if (nothing_done) + usage(verify_pack_usage); + return !!errs; } -- cgit v1.2.1 From ae9c86f2b6c89a3a0991209dae51086f884959c0 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:32 +0200 Subject: git-verify-pack: more careful path handling Use strlcpy() to copy the filename into a buffer and complain if it doesn't fit. Also move the path buffer into verify_one_pack(); it is used only there. Now we can const'ify the first argument of this function. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/verify-pack.c b/verify-pack.c index 7201596bf..77b3d282d 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -1,11 +1,16 @@ #include "cache.h" #include "pack.h" -static int verify_one_pack(char *arg, int verbose) +static int verify_one_pack(const char *path, int verbose) { - int len = strlen(arg); + char arg[PATH_MAX]; + int len; struct packed_git *g; - + + len = strlcpy(arg, path, PATH_MAX); + if (len >= PATH_MAX) + return error("name too long: %s", path); + while (1) { /* Should name foo.idx, but foo.pack may be named; * convert it to foo.idx @@ -37,8 +42,6 @@ int main(int ac, char **av) int nothing_done = 1; while (1 < ac) { - char path[PATH_MAX]; - if (!no_more_options && av[1][0] == '-') { if (!strcmp("-v", av[1])) verbose = 1; @@ -48,8 +51,7 @@ int main(int ac, char **av) usage(verify_pack_usage); } else { - strcpy(path, av[1]); - if (verify_one_pack(path, verbose)) + if (verify_one_pack(av[1], verbose)) errs++; nothing_done = 0; } -- cgit v1.2.1 From 68f4c78b95b9d119d8888b40b0a93b93a39b2f26 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:33 +0200 Subject: git-verify-pack: insist on .idx extension git-verify-pack can be called with a filename without .idx extension. add_packed_git() on the other hand depends on its presence. So instead of trying to call it with whatever the user gave us check for that extension and add it if it's missing. That means that you can't name your index file "blah" and your pack file ".pack" anymore ("git-verify-pack blah" currently works in that case). I think this regression is a good change. ;-) Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/verify-pack.c b/verify-pack.c index 77b3d282d..002b71161 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -18,13 +18,12 @@ static int verify_one_pack(const char *path, int verbose) if (has_extension(arg, len, ".pack")) { strcpy(arg + len - 5, ".idx"); len--; + } else if (!has_extension(arg, len, ".idx")) { + if (len + 4 >= PATH_MAX) + return error("name too long: %s.idx", arg); + strcpy(arg + len, ".idx"); + len += 4; } - /* Should name foo.idx now */ - if ((g = add_packed_git(arg, len, 1))) - break; - /* No? did you name just foo? */ - strcpy(arg + len, ".idx"); - len += 4; if ((g = add_packed_git(arg, len, 1))) break; return error("packfile %s not found.", arg); -- cgit v1.2.1 From fc5fc50980958f742a9f3d79fb7a64f02e87877a Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:34 +0200 Subject: git-verify-pack: get rid of while loop Get rid of that while loop which was apparently used as a way to avoid goto's (why?). It's easy now because there is only one break left at the end of it. Also make the comment clearer. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/verify-pack.c b/verify-pack.c index 002b71161..c7293140f 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -11,23 +11,23 @@ static int verify_one_pack(const char *path, int verbose) if (len >= PATH_MAX) return error("name too long: %s", path); - while (1) { - /* Should name foo.idx, but foo.pack may be named; - * convert it to foo.idx - */ - if (has_extension(arg, len, ".pack")) { - strcpy(arg + len - 5, ".idx"); - len--; - } else if (!has_extension(arg, len, ".idx")) { - if (len + 4 >= PATH_MAX) - return error("name too long: %s.idx", arg); - strcpy(arg + len, ".idx"); - len += 4; - } - if ((g = add_packed_git(arg, len, 1))) - break; - return error("packfile %s not found.", arg); + /* + * In addition to "foo.idx" we accept "foo.pack" and "foo"; + * normalize these forms to "foo.idx" for add_packed_git(). + */ + if (has_extension(arg, len, ".pack")) { + strcpy(arg + len - 5, ".idx"); + len--; + } else if (!has_extension(arg, len, ".idx")) { + if (len + 4 >= PATH_MAX) + return error("name too long: %s.idx", arg); + strcpy(arg + len, ".idx"); + len += 4; } + + if (!(g = add_packed_git(arg, len, 1))) + return error("packfile %s not found.", arg); + return verify_pack(g, verbose); } -- cgit v1.2.1 From d0d619c8c50b90fbbd6a7e0994fde073341bf92b Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:35 +0200 Subject: git-verify-pack: free pack after use and a cleanup Plug memory leak in verify_one_pack() by freeing the struct packed_git we got from add_packed_git(). Also rename g to pack and pull an assignment out of an if statement while we're at it. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/verify-pack.c b/verify-pack.c index c7293140f..78d789c62 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -5,7 +5,8 @@ static int verify_one_pack(const char *path, int verbose) { char arg[PATH_MAX]; int len; - struct packed_git *g; + struct packed_git *pack; + int err; len = strlcpy(arg, path, PATH_MAX); if (len >= PATH_MAX) @@ -25,10 +26,14 @@ static int verify_one_pack(const char *path, int verbose) len += 4; } - if (!(g = add_packed_git(arg, len, 1))) + pack = add_packed_git(arg, len, 1); + if (!pack) return error("packfile %s not found.", arg); - return verify_pack(g, verbose); + err = verify_pack(pack, verbose); + free(pack); + + return err; } static const char verify_pack_usage[] = "git-verify-pack [-v] ..."; -- cgit v1.2.1 From f711ab5470cd1da7fdafa3b7b5e39015dcfca5ce Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:36 +0200 Subject: git-verify-pack: buffer overrun paranoia Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/verify-pack.c b/verify-pack.c index 78d789c62..99c352ee3 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -26,6 +26,15 @@ static int verify_one_pack(const char *path, int verbose) len += 4; } + /* + * add_packed_git() uses our buffer (containing "foo.idx") to + * build the pack filename ("foo.pack"). Make sure it fits. + */ + if (len + 1 >= PATH_MAX) { + arg[len - 4] = '\0'; + return error("name too long: %s.pack", arg); + } + pack = add_packed_git(arg, len, 1); if (!pack) return error("packfile %s not found.", arg); -- cgit v1.2.1 From 0eaf22f4c4bba89457e733264e71343368712793 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:37 +0200 Subject: git-verify-pack: no need to count errors Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/verify-pack.c b/verify-pack.c index 99c352ee3..f440a3967 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -49,7 +49,7 @@ static const char verify_pack_usage[] = "git-verify-pack [-v] ..."; int main(int ac, char **av) { - int errs = 0; + int err = 0; int verbose = 0; int no_more_options = 0; int nothing_done = 1; @@ -65,7 +65,7 @@ int main(int ac, char **av) } else { if (verify_one_pack(av[1], verbose)) - errs++; + err = 1; nothing_done = 0; } ac--; av++; @@ -74,5 +74,5 @@ int main(int ac, char **av) if (nothing_done) usage(verify_pack_usage); - return !!errs; + return err; } -- cgit v1.2.1 From 65cdb5f1658c4911b3f17a2e99332e5397c52240 Mon Sep 17 00:00:00 2001 From: Rutger Nijlunsing Date: Thu, 10 Aug 2006 22:00:26 +0200 Subject: Add Documentation/howto/setup-git-server-over-http.txt A small howto on how to setup GIT over HTTP transport protocol by setting up WebDAV access on apache2. [jc: minimum ispell fixes applied] Signed-off-by: Rutger Nijlunsing Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/howto/setup-git-server-over-http.txt | 256 +++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 Documentation/howto/setup-git-server-over-http.txt diff --git a/Documentation/howto/setup-git-server-over-http.txt b/Documentation/howto/setup-git-server-over-http.txt new file mode 100644 index 000000000..ba191569a --- /dev/null +++ b/Documentation/howto/setup-git-server-over-http.txt @@ -0,0 +1,256 @@ +From: Rutger Nijlunsing +Subject: Setting up a git repository which can be pushed into and pulled from over HTTP. +Date: Thu, 10 Aug 2006 22:00:26 +0200 + +Since Apache is one of those packages people like to compile +themselves while others prefer the bureaucrat's dream Debian, it is +impossible to give guidelines which will work for everyone. Just send +some feedback to the mailing list at git@vger.kernel.org to get this +document tailored to your favorite distro. + + +What's needed: + +- Have an Apache web-server + + On Debian: + $ apt-get install apache2 + To get apache2 by default started, + edit /etc/default/apache2 and set NO_START=0 + +- can edit the configuration of it. + + This could be found under /etc/httpd, or refer to your Apache documentation. + + On Debian: this means being able to edit files under /etc/apache2 + +- can restart it. + + 'apachectl --graceful' might do. If it doesn't, just stop and + restart apache. Be warning that active connections to your server + might be aborted by this. + + On Debian: + $ /etc/init.d/apache2 restart + or + $ /etc/init.d/apache2 force-reload + (which seems to do the same) + This adds symlinks from the /etc/apache2/mods-enabled to + /etc/apache2/mods-available. + +- have permissions to chown a directory + +- have git installed at the server _and_ client + +In effect, this probably means you're going to be root. + + +Step 1: setup a bare GIT repository +----------------------------------- + +At the time of writing, git-http-push cannot remotely create a GIT +repository. So we have to do that at the server side with git. Another +option would be to generate an empty repository at the client and copy +it to the server with WebDAV. But then you're probably the first to +try that out :) + +Create the directory under the DocumentRoot of the directories served +by Apache. As an example we take /usr/local/apache2, but try "grep +DocumentRoot /where/ever/httpd.conf" to find your root: + + $ cd /usr/local/apache/htdocs + $ mkdir my-new-repo.git + + On Debian: + + $ cd /var/www + $ mkdir my-new-repo.git + + +Initialize a bare repository + + $ cd my-new-repo.git + $ git --bare init-db + + +Change the ownership to your web-server's credentials. Use "grep ^User +httpd.conf" and "grep ^Group httpd.conf" to find out: + + $ chown -R www.www . + + On Debian: + + $ chown -R www-data.www-data . + + +If you do not know which user Apache runs as, you can alternatively do +a "chmod -R a+w .", inspect the files which are created later on, and +set the permissions appropriately. + +Restart apache2, and check whether http://server/my-new-repo.git gives +a directory listing. If not, check whether apache started up +successfully. + + +Step 2: enable DAV on this repository +------------------------------------- + +First make sure the dav_module is loaded. For this, insert in httpd.conf: + + LoadModule dav_module libexec/httpd/libdav.so + AddModule mod_dav.c + +Also make sure that this line exists which is the file used for +locking DAV operations: + + DAVLockDB "/usr/local/apache2/temp/DAV.lock" + + On Debian these steps can be performed with: + + Enable the dav and dav_fs modules of apache: + $ a2enmod dav_fs + (just to be sure. dav_fs might be unneeded, I don't know) + $ a2enmod dav + The DAV lock is located in /etc/apache2/mods-available/dav_fs.conf: + DAVLockDB /var/lock/apache2/DAVLock + +Of course, it can point somewhere else, but the string is actually just a +prefix in some Apache configurations, and therefore the _directory_ has to +be writable by the user Apache runs as. + +Then, add something like this to your httpd.conf + + + DAV on + AuthType Basic + AuthName "Git" + AuthUserFile /usr/local/apache2/conf/passwd.git + Require valid-user + + + On Debian: + Create (or add to) /etc/apache2/conf.d/git.conf : + + + DAV on + AuthType Basic + AuthName "Git" + AuthUserFile /etc/apache2/passwd.git + Require valid-user + + + Debian automatically reads all files under /etc/apach2/conf.d. + +The password file can be somewhere else, but it has to be readable by +Apache and preferably not readable by the world. + +Create this file by + $ htpasswd -c /usr/local/apache2/conf/passwd.git + + On Debian: + $ htpasswd -c /etc/apache2/passwd.git + +You will be asked a password, and the file is created. Subsequent calls +to htpasswd should omit the '-c' option, since you want to append to the +existing file. + +You need to restart Apache. + +Now go to http://@/my-new-repo.git in your +browser to check whether it asks for a password and accepts the right +password. + +On Debian: + + To test the WebDAV part, do: + + $ apt-get install litmus + $ litmus http:///my-new-repo.git + + Most tests should pass. + +A command line tool to test WebDAV is cadaver. + +If you're into Windows, from XP onwards Internet Explorer supports +WebDAV. For this, do Internet Explorer -> Open Location -> +http:///my-new-repo.git [x] Open as webfolder -> login . + + +Step 3: setup the client +------------------------ + +Make sure that you have HTTP support, i.e. your git was built with curl. +The easiest way to check is to look for the executable 'git-http-push'. + +Then, add the following to your $HOME/.netrc (you can do without, but will be +asked to input your password a _lot_ of times): + + machine + login + password + +...and set permissions: + chmod 600 ~/.netrc + +If you want to access the web-server by its IP, you have to type that in, +instead of the server name. + +To check whether all is OK, do: + + curl --netrc --location -v http://@/my-new-repo.git/ + +...this should give a directory listing in HTML of /var/www/my-new-repo.git . + + +Now, add the remote in your existing repository which contains the project +you want to export: + + $ git-repo-config remote.upload.url \ + http://@/my-new-repo.git/ + +It is important to put the last '/'; Without it, the server will send +a redirect which git-http-push does not (yet) understand, and git-http-push +will repeat the request infinitely. + + +Step 4: make the initial push +----------------------------- + +From your client repository, do + + $ git push upload master + +This pushes branch 'master' (which is assumed to be the branch you +want to export) to repository called 'upload', which we previously +defined with git-repo-config. + + +Troubleshooting: +---------------- + +If git-http-push says + + Error: no DAV locking support on remote repo http://... + +then it means the web-server did not accept your authentication. Make sure +that the user name and password matches in httpd.conf, .netrc and the URL +you are uploading to. + +If git-http-push shows you an error (22/502) when trying to MOVE a blob, +it means that your web-server somehow does not recognize its name in the +request; This can happen when you start Apache, but then disable the +network interface. A simple restart of Apache helps. + +Errors like (22/502) are of format (curl error code/http error +code). So (22/404) means something like 'not found' at the server. + +Reading /usr/local/apache2/logs/error_log is often helpful. + + On Debian: Read /var/log/apache2/error.log instead. + + +Debian References: http://www.debian-administration.org/articles/285 + +Authors + Johannes Schindelin + Rutger Nijlunsing -- cgit v1.2.1 From 5bb1cda5f73988963e7470f3cd75a380751f6d99 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Fri, 11 Aug 2006 14:01:45 +0200 Subject: drop length argument of has_extension As Fredrik points out the current interface of has_extension() is potentially confusing. Its parameters include both a nul-terminated string and a length-limited string. This patch drops the length argument, requiring two nul-terminated strings; all callsites are updated. I checked that all of them indeed provide nul-terminated strings. Filenames need to be nul-terminated anyway if they are to be passed to open() etc. The performance penalty of the additional strlen() is negligible compared to the system calls which inevitably surround has_extension() calls. Additionally, change has_extension() to use size_t inside instead of int, as that is the exact type strlen() returns and memcmp() expects. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin-help.c | 2 +- git-compat-util.h | 5 +++-- http-fetch.c | 2 +- index-pack.c | 2 +- local-fetch.c | 2 +- refs.c | 2 +- sha1_file.c | 2 +- verify-pack.c | 4 ++-- 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/builtin-help.c b/builtin-help.c index 7a7f7759e..6484cb9df 100644 --- a/builtin-help.c +++ b/builtin-help.c @@ -140,7 +140,7 @@ static void list_commands(const char *exec_path, const char *pattern) continue; entlen = strlen(de->d_name); - if (has_extension(de->d_name, entlen, ".exe")) + if (has_extension(de->d_name, ".exe")) entlen -= 4; if (longest < entlen) diff --git a/git-compat-util.h b/git-compat-util.h index dd9209365..b2e18954c 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -139,9 +139,10 @@ static inline ssize_t xwrite(int fd, const void *buf, size_t len) } } -static inline int has_extension(const char *filename, int len, const char *ext) +static inline int has_extension(const char *filename, const char *ext) { - int extlen = strlen(ext); + size_t len = strlen(filename); + size_t extlen = strlen(ext); return len > extlen && !memcmp(filename + len - extlen, ext, extlen); } diff --git a/http-fetch.c b/http-fetch.c index 6ea39f058..de5fc44e6 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -870,7 +870,7 @@ static void process_ls_pack(struct remote_ls_ctx *ls) if (strlen(ls->dentry_name) == 63 && !strncmp(ls->dentry_name, "objects/pack/pack-", 18) && - has_extension(ls->dentry_name, 63, ".pack")) { + has_extension(ls->dentry_name, ".pack")) { get_sha1_hex(ls->dentry_name + 18, sha1); setup_index(ls->repo, sha1); } diff --git a/index-pack.c b/index-pack.c index a91e39ecd..b20659c25 100644 --- a/index-pack.c +++ b/index-pack.c @@ -447,7 +447,7 @@ int main(int argc, char **argv) usage(index_pack_usage); if (!index_name) { int len = strlen(pack_name); - if (!has_extension(pack_name, len, ".pack")) + if (!has_extension(pack_name, ".pack")) die("packfile name '%s' does not end with '.pack'", pack_name); index_name_buf = xmalloc(len); diff --git a/local-fetch.c b/local-fetch.c index b6ec170c0..7d01845d3 100644 --- a/local-fetch.c +++ b/local-fetch.c @@ -44,7 +44,7 @@ static int setup_indices(void) while ((de = readdir(dir)) != NULL) { int namelen = strlen(de->d_name); if (namelen != 50 || - !has_extension(de->d_name, namelen, ".pack")) + !has_extension(de->d_name, ".pack")) continue; get_sha1_hex(de->d_name + 5, sha1); setup_index(sha1); diff --git a/refs.c b/refs.c index b01835f63..28a939460 100644 --- a/refs.c +++ b/refs.c @@ -147,7 +147,7 @@ static int do_for_each_ref(const char *base, int (*fn)(const char *path, const u namelen = strlen(de->d_name); if (namelen > 255) continue; - if (has_extension(de->d_name, namelen, ".lock")) + if (has_extension(de->d_name, ".lock")) continue; memcpy(path + baselen, de->d_name, namelen+1); if (stat(git_path("%s", path), &st) < 0) diff --git a/sha1_file.c b/sha1_file.c index a1bb01ca3..3db956dd5 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -590,7 +590,7 @@ static void prepare_packed_git_one(char *objdir, int local) int namelen = strlen(de->d_name); struct packed_git *p; - if (!has_extension(de->d_name, namelen, ".idx")) + if (!has_extension(de->d_name, ".idx")) continue; /* we have .idx. Is it a file we can map? */ diff --git a/verify-pack.c b/verify-pack.c index f440a3967..357970da3 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -16,10 +16,10 @@ static int verify_one_pack(const char *path, int verbose) * In addition to "foo.idx" we accept "foo.pack" and "foo"; * normalize these forms to "foo.idx" for add_packed_git(). */ - if (has_extension(arg, len, ".pack")) { + if (has_extension(arg, ".pack")) { strcpy(arg + len - 5, ".idx"); len--; - } else if (!has_extension(arg, len, ".idx")) { + } else if (!has_extension(arg, ".idx")) { if (len + 4 >= PATH_MAX) return error("name too long: %s.idx", arg); strcpy(arg + len, ".idx"); -- cgit v1.2.1 From 17a10f3709c211769c9fada79bd1608aa64f6080 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 11 Aug 2006 04:34:07 -0700 Subject: git-svn: correctly kill keyword expansion without munging EOLs This bugfix applies to users of the svn command-line client only. We no longer muck with newlines when killing keyword expansion. This tended to generate unintended diffs in commits because svn revert -R would destroy the manual EOL changes we were doing. Of course, we didn't need the EOL munging in the first place, as svn seems to do it for us even in the text-base files. Now we set the mtime and atime the files changed by keyword expansion killing to avoid triggering a change on svn revert, which svn still seems to want to do. Thanks to Seth Falcon for reporting this bug. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 45 ++++----------------------------------------- 1 file changed, 4 insertions(+), 41 deletions(-) diff --git a/git-svn.perl b/git-svn.perl index 6453771f9..3327ad364 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -31,6 +31,7 @@ use File::Basename qw/dirname basename/; use File::Path qw/mkpath/; use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev pass_through/; use File::Spec qw//; +use File::Copy qw/copy/; use POSIX qw/strftime/; use IPC::Open3; use Memoize; @@ -77,9 +78,6 @@ my %cmt_opts = ( 'edit|e' => \$_edit, 'copy-similarity|C=i'=> \$_cp_similarity ); -# yes, 'native' sets "\n". Patches to fix this for non-*nix systems welcome: -my %EOL = ( CR => "\015", LF => "\012", CRLF => "\015\012", native => "\012" ); - my %cmd = ( fetch => [ \&fetch, "Download new revisions from SVN", { 'revision|r=s' => \$_revision, %fc_opts } ], @@ -1760,43 +1758,6 @@ sub svn_info { sub sys { system(@_) == 0 or croak $? } -sub eol_cp { - my ($from, $to) = @_; - my $es = svn_propget_base('svn:eol-style', $to); - open my $rfd, '<', $from or croak $!; - binmode $rfd or croak $!; - open my $wfd, '>', $to or croak $!; - binmode $wfd or croak $!; - eol_cp_fd($rfd, $wfd, $es); - close $rfd or croak $!; - close $wfd or croak $!; -} - -sub eol_cp_fd { - my ($rfd, $wfd, $es) = @_; - my $eol = defined $es ? $EOL{$es} : undef; - my $buf; - use bytes; - while (1) { - my ($r, $w, $t); - defined($r = sysread($rfd, $buf, 4096)) or croak $!; - return unless $r; - if ($eol) { - if ($buf =~ /\015$/) { - my $c; - defined($r = sysread($rfd,$c,1)) or croak $!; - $buf .= $c if $r > 0; - } - $buf =~ s/(?:\015\012|\015|\012)/$eol/gs; - $r = length($buf); - } - for ($w = 0; $w < $r; $w += $t) { - $t = syswrite($wfd, $buf, $r - $w, $w) or croak $!; - } - } - no bytes; -} - sub do_update_index { my ($z_cmd, $cmd, $no_text_base) = @_; @@ -1824,9 +1785,11 @@ sub do_update_index { 'text-base',"$f.svn-base"); $tb =~ s#^/##; } + my @s = stat($x); unlink $x or croak $!; - eol_cp($tb, $x); + copy($tb, $x); chmod(($mode &~ umask), $x) or croak $!; + utime $s[8], $s[9], $x; } print $ui $x,"\0"; } -- cgit v1.2.1 From 308906fa6e98132cab839a4f42701386fba368ef Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 11 Aug 2006 11:11:29 -0700 Subject: git-svn: bugfix: allow SVN:: lib users to track the root of the repository I'm not sure if anybody has hit this (besides me), but this fixes the problem where I ran into while attempting to import a small repo at the root level: I ended up with all the commits, but with no file/tree changes at all throughout the entire history. Also, fix a warning if the commit message is not defined for revision 0. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/git-svn.perl b/git-svn.perl index 3327ad364..7d9839e7a 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -2580,7 +2580,9 @@ sub libsvn_connect { sub libsvn_get_file { my ($gui, $f, $rev) = @_; my $p = $f; - return unless ($p =~ s#^\Q$SVN_PATH\E/##); + if (length $SVN_PATH > 0) { + return unless ($p =~ s#^\Q$SVN_PATH\E/##); + } my ($hash, $pid, $in, $out); my $pool = SVN::Pool->new; @@ -2627,6 +2629,7 @@ sub libsvn_log_entry { if (defined $_authors && ! defined $users{$author}) { die "Author: $author not defined in $_authors file\n"; } + $msg = '' if ($rev == 0 && !defined $msg); return { revision => $rev, date => "+0000 $Y-$m-$d $H:$M:$S", author => $author, msg => $msg."\n", parents => $parents || [] } } -- cgit v1.2.1 From c8769f76d992ed391d169cd71be009ca17727271 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 11 Aug 2006 18:47:50 -0700 Subject: git-sh-setup: do not use repo-config to test the git directory Since repo-config does not fail in non-git directory, it is not a good command to use to test the git-ness nor validate the repository revision of $GIT_DIR. Original patch by Robert Shearman but with minor fixes. Signed-off-by: Junio C Hamano --- git-sh-setup.sh | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/git-sh-setup.sh b/git-sh-setup.sh index d15747f1e..42f9b1c12 100755 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -35,17 +35,12 @@ case "$1" in exit esac +# Make sure we are in a valid repository of a vintage we understand. if [ -z "$SUBDIRECTORY_OK" ] then : ${GIT_DIR=.git} - : ${GIT_OBJECT_DIRECTORY="$GIT_DIR/objects"} - - # Make sure we are in a valid repository of a vintage we understand. - GIT_DIR="$GIT_DIR" git repo-config --get core.nosuch >/dev/null - if test $? = 128 - then - exit - fi + GIT_DIR=$(GIT_DIR="$GIT_DIR" git-rev-parse --git-dir) || exit else GIT_DIR=$(git-rev-parse --git-dir) || exit fi +: ${GIT_OBJECT_DIRECTORY="$GIT_DIR/objects"} -- cgit v1.2.1 From a69a165fb43c88ab5c2adc2fe33b065ff537177c Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 11 Aug 2006 23:21:41 -0700 Subject: git-svn: split the path from the url correctly with limited perms This version of the splitter (that only affects SVN:: library users) works when one only has limited read-permissions to the repository they're fetching from. Updated from the original patch to workaround some SVN bug somewhere, which only seems to happen against file:// repositories... Here's the diff against the original patch I submitted: @@ -1159,8 +1159,8 @@ sub repo_path_split { } if ($_use_lib) { - $SVN = libsvn_connect($full_url); - my $url = $SVN->get_repos_root; + my $tmp = libsvn_connect($full_url); + my $url = $tmp->get_repos_root; $full_url =~ s#^\Q$url\E/*##; push @repo_path_split_cache, qr/^(\Q$url\E)/; return ($url, $full_url); Somehow connecting to a repository with the full url makes the returned SVN::Ra object act strangely and break things, so now we just drop the SVN::Ra object that we made our initial connection with. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/git-svn.perl b/git-svn.perl index 7d9839e7a..0d58bb9b3 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -1158,27 +1158,24 @@ sub repo_path_split { } } - my ($url, $path) = ($full_url =~ m!^([a-z\+]+://[^/]*)(.*)$!i); - $path =~ s#^/+##; - my @paths = split(m#/+#, $path); - if ($_use_lib) { - while (1) { - $SVN = libsvn_connect($url); - last if (defined $SVN && - defined eval { $SVN->get_latest_revnum }); - my $n = shift @paths || last; - $url .= "/$n"; - } + my $tmp = libsvn_connect($full_url); + my $url = $tmp->get_repos_root; + $full_url =~ s#^\Q$url\E/*##; + push @repo_path_split_cache, qr/^(\Q$url\E)/; + return ($url, $full_url); } else { + my ($url, $path) = ($full_url =~ m!^([a-z\+]+://[^/]*)(.*)$!i); + $path =~ s#^/+##; + my @paths = split(m#/+#, $path); while (quiet_run(qw/svn ls --non-interactive/, $url)) { my $n = shift @paths || last; $url .= "/$n"; } + push @repo_path_split_cache, qr/^(\Q$url\E)/; + $path = join('/',@paths); + return ($url, $path); } - push @repo_path_split_cache, qr/^(\Q$url\E)/; - $path = join('/',@paths); - return ($url, $path); } sub setup_git_svn { -- cgit v1.2.1 From fd7bcfb524a3313ef5361bdd8493ba50635f50f0 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 12 Aug 2006 16:16:47 -0700 Subject: git-am: give better diagnostics when the patch does not apply during --3way If the user tries to apply a patch that was hand-edited in such a way that it does not apply to the original file recorded on its "index" line anymore, we did detect the situation but did not issue an error message that is specific enough. Signed-off-by: Junio C Hamano --- git-am.sh | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/git-am.sh b/git-am.sh index 04f011943..d0af786ae 100755 --- a/git-am.sh +++ b/git-am.sh @@ -45,6 +45,12 @@ go_next () { this=$next } +cannot_fallback () { + echo "$1" + echo "Cannot fall back to three-way merge." + exit 1 +} + fall_back_3way () { O_OBJECT=`cd "$GIT_OBJECT_DIRECTORY" && pwd` @@ -52,19 +58,23 @@ fall_back_3way () { mkdir "$dotest/patch-merge-tmp-dir" # First see if the patch records the index info that we can use. - if git-apply -z --index-info "$dotest/patch" \ - >"$dotest/patch-merge-index-info" 2>/dev/null && - GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ - git-update-index -z --index-info <"$dotest/patch-merge-index-info" && - GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ - git-write-tree >"$dotest/patch-merge-base+" && - # index has the base tree now. - GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ + git-apply -z --index-info "$dotest/patch" \ + >"$dotest/patch-merge-index-info" && + GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ + git-update-index -z --index-info <"$dotest/patch-merge-index-info" && + GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ + git-write-tree >"$dotest/patch-merge-base+" || + cannot_fallback "Patch does not record usable index information." + + echo Using index info to reconstruct a base tree... + if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ git-apply $binary --cached <"$dotest/patch" then - echo Using index info to reconstruct a base tree... mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base" mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index" + else + cannot_fallback "Did you hand edit your patch? +It does not apply to blobs recorded in its index." fi test -f "$dotest/patch-merge-index" && -- cgit v1.2.1 From 40aaae88adfe05be435b7bd17093d49869f3276f Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 12 Aug 2006 01:03:47 -0700 Subject: Better error message when we are unable to lock the index file Most of the callers except the one in refs.c use the function to update the index file. Among the index writers, everybody except write-tree dies if they cannot open it for writing. This gives the function an extra argument, to tell it to die when it cannot create a new file as the lockfile. The only caller that does not have to die is write-tree, because updating the index for the cache-tree part is optional and not being able to do so does not affect the correctness. I think we do not have to be so careful and make the failure into die() the same way as other callers, but that would be a different patch. Signed-off-by: Junio C Hamano --- builtin-add.c | 4 +--- builtin-apply.c | 7 ++----- builtin-mv.c | 5 +---- builtin-read-tree.c | 4 +--- builtin-rm.c | 4 +--- builtin-update-index.c | 4 +--- builtin-write-tree.c | 2 +- cache.h | 2 +- checkout-index.c | 2 +- lockfile.c | 10 +++++++++- refs.c | 8 +------- 11 files changed, 20 insertions(+), 32 deletions(-) diff --git a/builtin-add.c b/builtin-add.c index 096b611b5..0cb9c8120 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -93,9 +93,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) git_config(git_default_config); - newfd = hold_lock_file_for_update(&lock_file, get_index_file()); - if (newfd < 0) - die("unable to create new index file"); + newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1); if (read_cache() < 0) die("index file corrupt"); diff --git a/builtin-apply.c b/builtin-apply.c index be2c7152c..9cf477c70 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -2234,12 +2234,9 @@ static int apply_patch(int fd, const char *filename, apply = 0; write_index = check_index && apply; - if (write_index && newfd < 0) { + if (write_index && newfd < 0) newfd = hold_lock_file_for_update(&lock_file, - get_index_file()); - if (newfd < 0) - die("unable to create new index file"); - } + get_index_file(), 1); if (check_index) { if (read_cache() < 0) die("unable to read index file"); diff --git a/builtin-mv.c b/builtin-mv.c index ce8187c1e..a731f8d9c 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -72,10 +72,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) git_config(git_default_config); - newfd = hold_lock_file_for_update(&lock_file, get_index_file()); - if (newfd < 0) - die("unable to create new index file"); - + newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1); if (read_cache() < 0) die("index file corrupt"); diff --git a/builtin-read-tree.c b/builtin-read-tree.c index b30160a5b..71a7026df 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -884,9 +884,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) git_config(git_default_config); - newfd = hold_lock_file_for_update(&lock_file, get_index_file()); - if (newfd < 0) - die("unable to create new index file"); + newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1); git_config(git_default_config); diff --git a/builtin-rm.c b/builtin-rm.c index 8af3d7eb4..593d86744 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -52,9 +52,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) git_config(git_default_config); - newfd = hold_lock_file_for_update(&lock_file, get_index_file()); - if (newfd < 0) - die("unable to create new index file"); + newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1); if (read_cache() < 0) die("index file corrupt"); diff --git a/builtin-update-index.c b/builtin-update-index.c index 24dca47d8..d2556f376 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -491,9 +491,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) /* We can't free this memory, it becomes part of a linked list parsed atexit() */ lock_file = xcalloc(1, sizeof(struct lock_file)); - newfd = hold_lock_file_for_update(lock_file, get_index_file()); - if (newfd < 0) - die("unable to create new cachefile"); + newfd = hold_lock_file_for_update(lock_file, get_index_file(), 1); entries = read_cache(); if (entries < 0) diff --git a/builtin-write-tree.c b/builtin-write-tree.c index 6b62d7dc8..ca06149f1 100644 --- a/builtin-write-tree.c +++ b/builtin-write-tree.c @@ -18,7 +18,7 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix) /* We can't free this memory, it becomes part of a linked list parsed atexit() */ struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); - newfd = hold_lock_file_for_update(lock_file, get_index_file()); + newfd = hold_lock_file_for_update(lock_file, get_index_file(), 0); entries = read_cache(); if (entries < 0) diff --git a/cache.h b/cache.h index b8c21e07b..b2ab2088e 100644 --- a/cache.h +++ b/cache.h @@ -175,7 +175,7 @@ struct lock_file { struct lock_file *next; char filename[PATH_MAX]; }; -extern int hold_lock_file_for_update(struct lock_file *, const char *path); +extern int hold_lock_file_for_update(struct lock_file *, const char *path, int); extern int commit_lock_file(struct lock_file *); extern void rollback_lock_file(struct lock_file *); diff --git a/checkout-index.c b/checkout-index.c index 61152f34b..dfb1c4441 100644 --- a/checkout-index.c +++ b/checkout-index.c @@ -206,7 +206,7 @@ int main(int argc, char **argv) state.refresh_cache = 1; if (newfd < 0) newfd = hold_lock_file_for_update - (&lock_file, get_index_file()); + (&lock_file, get_index_file(), 1); if (newfd < 0) die("cannot open index.lock file."); continue; diff --git a/lockfile.c b/lockfile.c index 2346e0e9e..2a2fea3cb 100644 --- a/lockfile.c +++ b/lockfile.c @@ -22,7 +22,7 @@ static void remove_lock_file_on_signal(int signo) raise(signo); } -int hold_lock_file_for_update(struct lock_file *lk, const char *path) +static int lock_file(struct lock_file *lk, const char *path) { int fd; sprintf(lk->filename, "%s.lock", path); @@ -41,6 +41,14 @@ int hold_lock_file_for_update(struct lock_file *lk, const char *path) return fd; } +int hold_lock_file_for_update(struct lock_file *lk, const char *path, int die_on_error) +{ + int fd = lock_file(lk, path); + if (fd < 0 && die_on_error) + die("unable to create '%s': %s", path, strerror(errno)); + return fd; +} + int commit_lock_file(struct lock_file *lk) { char result_file[PATH_MAX]; diff --git a/refs.c b/refs.c index 28a939460..86ef91661 100644 --- a/refs.c +++ b/refs.c @@ -319,13 +319,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *path, if (safe_create_leading_directories(lock->ref_file)) die("unable to create directory for %s", lock->ref_file); - lock->lock_fd = hold_lock_file_for_update(lock->lk, lock->ref_file); - if (lock->lock_fd < 0) { - error("Couldn't open lock file %s: %s", - lock->lk->filename, strerror(errno)); - unlock_ref(lock); - return NULL; - } + lock->lock_fd = hold_lock_file_for_update(lock->lk, lock->ref_file, 1); return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock; } -- cgit v1.2.1 From 6c7f4cebdb40c0d95c63d59538fd235dcf978029 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 12 Aug 2006 18:04:07 -0700 Subject: t/t4013: fix futzing with the version string. Signed-off-by: Junio C Hamano --- t/t4013-diff-various.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index b24c829f0..71c454356 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -88,7 +88,7 @@ test_expect_success setup ' +*+ [initial] Initial EOF -V=`git version | sed -e 's/^git version //'` +V=`git version | sed -e 's/^git version //' -e 's/\./\\./g'` while read cmd do case "$cmd" in @@ -103,7 +103,9 @@ do test_expect_success "git $cmd" ' { echo "\$ git $cmd" - git $cmd | sed -e "s/$V/g-i-t--v-e-r-s-i-o-n/" + git $cmd | + sed -e "s/^\\(-*\\)$V\\(-*\\)\$/\\1g-i-t--v-e-r-s-i-o-n\2/" \ + -e "s/^\\( *boundary=\"-*\\)$V\\(-*\\)\"\$/\\1g-i-t--v-e-r-s-i-o-n\2\"/" echo "\$" } >"$actual" && if test -f "$expect" -- cgit v1.2.1