From fb0ca475c6ab02eeeb8ca7f2c0558d64301a8800 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 20 Jan 2008 14:11:52 -0500 Subject: [PATCH 01/33] git-gui: Honor the standard commit-msg hook Under core Git the git-commit tool will invoke the commit-msg hook if it exists and is executable to the user running git-commit. As a hook it has some limited value as it cannot alter the commit, but it can modify the message the user is attempting to commit. It is also able to examine the message to ensure it conforms to some local standards/conventions. Since the hook takes the name of a temporary file holding the message as its only parameter we need to move the code that creates the temp file up earlier in our commit code path, and then pass through that file name to the latest stage (where we call git-commit-tree). We let the hook alter the file as it sees fit and we don't bother to look at its content again until the commit succeeded and we need the subject for the reflog update. Signed-off-by: Shawn O. Pearce --- lib/commit.tcl | 114 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 31 deletions(-) diff --git a/lib/commit.tcl b/lib/commit.tcl index 1c0586c409..73e18bf982 100644 --- a/lib/commit.tcl +++ b/lib/commit.tcl @@ -192,6 +192,24 @@ A good commit message has the following format: return } + # -- Build the message file. + # + set msg_p [gitdir GITGUI_EDITMSG] + set msg_wt [open $msg_p w] + fconfigure $msg_wt -translation lf + if {[catch {set enc $repo_config(i18n.commitencoding)}]} { + set enc utf-8 + } + set use_enc [tcl_encoding $enc] + if {$use_enc ne {}} { + fconfigure $msg_wt -encoding $use_enc + } else { + puts stderr [mc "warning: Tcl does not support encoding '%s'." $enc] + fconfigure $msg_wt -encoding utf-8 + } + puts $msg_wt $msg + close $msg_wt + # -- Run the pre-commit hook. # set pchook [gitdir hooks pre-commit] @@ -207,7 +225,7 @@ A good commit message has the following format: } elseif {[file executable $pchook]} { set pchook [list $pchook |& cat] } else { - commit_writetree $curHEAD $msg + commit_commitmsg $curHEAD $msg_p return } @@ -216,21 +234,22 @@ A good commit message has the following format: set fd_ph [open "| $pchook" r] fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} fileevent $fd_ph readable \ - [list commit_prehook_wait $fd_ph $curHEAD $msg] + [list commit_prehook_wait $fd_ph $curHEAD $msg_p] } -proc commit_prehook_wait {fd_ph curHEAD msg} { +proc commit_prehook_wait {fd_ph curHEAD msg_p} { global pch_error append pch_error [read $fd_ph] fconfigure $fd_ph -blocking 1 if {[eof $fd_ph]} { if {[catch {close $fd_ph}]} { + catch {file delete $msg_p} ui_status {Commit declined by pre-commit hook.} hook_failed_popup pre-commit $pch_error unlock_index } else { - commit_writetree $curHEAD $msg + commit_commitmsg $curHEAD $msg_p } set pch_error {} return @@ -238,14 +257,64 @@ proc commit_prehook_wait {fd_ph curHEAD msg} { fconfigure $fd_ph -blocking 0 } -proc commit_writetree {curHEAD msg} { +proc commit_commitmsg {curHEAD msg_p} { + global pch_error + + # -- Run the commit-msg hook. + # + set pchook [gitdir hooks commit-msg] + + # On Cygwin [file executable] might lie so we need to ask + # the shell if the hook is executable. Yes that's annoying. + # + if {[is_Cygwin] && [file isfile $pchook]} { + set pchook [list sh -c [concat \ + "if test -x \"$pchook\";" \ + "then exec \"$pchook\" \"$msg_p\" 2>&1;" \ + "fi"]] + } elseif {[file executable $pchook]} { + set pchook [list $pchook $msg_p |& cat] + } else { + commit_writetree $curHEAD $msg_p + return + } + + ui_status {Calling commit-msg hook...} + set pch_error {} + set fd_ph [open "| $pchook" r] + fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fileevent $fd_ph readable \ + [list commit_commitmsg_wait $fd_ph $curHEAD $msg_p] +} + +proc commit_commitmsg_wait {fd_ph curHEAD msg_p} { + global pch_error + + append pch_error [read $fd_ph] + fconfigure $fd_ph -blocking 1 + if {[eof $fd_ph]} { + if {[catch {close $fd_ph}]} { + catch {file delete $msg_p} + ui_status {Commit declined by commit-msg hook.} + hook_failed_popup commit-msg $pch_error + unlock_index + } else { + commit_writetree $curHEAD $msg_p + } + set pch_error {} + return + } + fconfigure $fd_ph -blocking 0 +} + +proc commit_writetree {curHEAD msg_p} { ui_status {Committing changes...} set fd_wt [git_read write-tree] fileevent $fd_wt readable \ - [list commit_committree $fd_wt $curHEAD $msg] + [list commit_committree $fd_wt $curHEAD $msg_p] } -proc commit_committree {fd_wt curHEAD msg} { +proc commit_committree {fd_wt curHEAD msg_p} { global HEAD PARENT MERGE_HEAD commit_type global current_branch global ui_comm selected_commit_type @@ -254,6 +323,7 @@ proc commit_committree {fd_wt curHEAD msg} { gets $fd_wt tree_id if {[catch {close $fd_wt} err]} { + catch {file delete $msg_p} error_popup [strcat [mc "write-tree failed:"] "\n\n$err"] ui_status {Commit failed.} unlock_index @@ -276,6 +346,7 @@ proc commit_committree {fd_wt curHEAD msg} { } if {$tree_id eq $old_tree} { + catch {file delete $msg_p} info_popup [mc "No changes to commit. No files were modified by this commit and it was not a merge commit. @@ -288,24 +359,6 @@ A rescan will be automatically started now. } } - # -- Build the message. - # - set msg_p [gitdir COMMIT_EDITMSG] - set msg_wt [open $msg_p w] - fconfigure $msg_wt -translation lf - if {[catch {set enc $repo_config(i18n.commitencoding)}]} { - set enc utf-8 - } - set use_enc [tcl_encoding $enc] - if {$use_enc ne {}} { - fconfigure $msg_wt -encoding $use_enc - } else { - puts stderr [mc "warning: Tcl does not support encoding '%s'." $enc] - fconfigure $msg_wt -encoding utf-8 - } - puts $msg_wt $msg - close $msg_wt - # -- Create the commit. # set cmd [list commit-tree $tree_id] @@ -314,6 +367,7 @@ A rescan will be automatically started now. } lappend cmd <$msg_p if {[catch {set cmt_id [eval git $cmd]} err]} { + catch {file delete $msg_p} error_popup [strcat [mc "commit-tree failed:"] "\n\n$err"] ui_status {Commit failed.} unlock_index @@ -326,16 +380,14 @@ A rescan will be automatically started now. if {$commit_type ne {normal}} { append reflogm " ($commit_type)" } - set i [string first "\n" $msg] - if {$i >= 0} { - set subject [string range $msg 0 [expr {$i - 1}]] - } else { - set subject $msg - } + set msg_fd [open $msg_p r] + gets $msg_fd subject + close $msg_fd append reflogm {: } $subject if {[catch { git update-ref -m $reflogm HEAD $cmt_id $curHEAD } err]} { + catch {file delete $msg_p} error_popup [strcat [mc "update-ref failed:"] "\n\n$err"] ui_status {Commit failed.} unlock_index From c87238e19de70c1066e606df53f4f20f19621acd Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 20 Jan 2008 14:43:38 -0500 Subject: [PATCH 02/33] git-gui: Correct window title for hook failure dialogs During i18n translation work this message was partially broken by using "append" instead of "strcat" to join the two different parts of the message together. Signed-off-by: Shawn O. Pearce --- lib/error.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/error.tcl b/lib/error.tcl index 13565b7ab0..712d217553 100644 --- a/lib/error.tcl +++ b/lib/error.tcl @@ -99,6 +99,6 @@ proc hook_failed_popup {hook msg} { bind $w "grab $w; focus $w" bind $w "destroy $w" - wm title $w [append "[appname] ([reponame]): " [mc "error"]] + wm title $w [strcat "[appname] ([reponame]): " [mc "error"]] tkwait window $w } From ed76cb70f47225fc1a2ba4209b38b89be71adeb6 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 20 Jan 2008 14:46:59 -0500 Subject: [PATCH 03/33] git-gui: Consolidate hook execution code into a single function The code we use to test if a hook is executable or not differs on Cygwin from the normal POSIX case. Rather then repeating that for all three hooks we call in our commit code path we can place the common logic into a global procedure and invoke it when necessary. This also lets us get rid of the ugly "|& cat" we were using before as we can now rely on the Tcl 8.4 feature of "2>@1" or fallback to the "|& cat" when necessary. The post-commit hook is now run through the same API, but its outcome does not influence the commit status. As a result we now show any of the errors from the post-commit hook in a dialog window, instead of on the user's tty that was used to launch git-gui. This resolves a long standing bug related to not getting errors out of the post-commit hook when launched under git-gui. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 28 ++++++++++++++++++++++ lib/commit.tcl | 65 ++++++++++++++++++++------------------------------ lib/error.tcl | 16 +++++++------ 3 files changed, 63 insertions(+), 46 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index fcb2ab2fb7..f42e461fd4 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -438,6 +438,34 @@ proc git_write {args} { return [open [concat $opt $cmdp $args] w] } +proc githook_read {hook_name args} { + set pchook [gitdir hooks $hook_name] + lappend args 2>@1 + + # On Cygwin [file executable] might lie so we need to ask + # the shell if the hook is executable. Yes that's annoying. + # + if {[is_Cygwin]} { + upvar #0 _sh interp + if {![info exists interp]} { + set interp [_which sh] + } + if {$interp eq {}} { + error "hook execution requires sh (not in PATH)" + } + + set scr {if test -x "$1";then exec "$@";fi} + set sh_c [list | $interp -c $scr $interp $pchook] + return [_open_stdout_stderr [concat $sh_c $args]] + } + + if {[file executable $pchook]} { + return [_open_stdout_stderr [concat [list | $pchook] $args]] + } + + return {} +} + proc sq {value} { regsub -all ' $value "'\\''" value return "'$value'" diff --git a/lib/commit.tcl b/lib/commit.tcl index 73e18bf982..947b201c32 100644 --- a/lib/commit.tcl +++ b/lib/commit.tcl @@ -212,26 +212,14 @@ A good commit message has the following format: # -- Run the pre-commit hook. # - set pchook [gitdir hooks pre-commit] - - # On Cygwin [file executable] might lie so we need to ask - # the shell if the hook is executable. Yes that's annoying. - # - if {[is_Cygwin] && [file isfile $pchook]} { - set pchook [list sh -c [concat \ - "if test -x \"$pchook\";" \ - "then exec \"$pchook\" 2>&1;" \ - "fi"]] - } elseif {[file executable $pchook]} { - set pchook [list $pchook |& cat] - } else { + set fd_ph [githook_read pre-commit] + if {$fd_ph eq {}} { commit_commitmsg $curHEAD $msg_p return } ui_status {Calling pre-commit hook...} set pch_error {} - set fd_ph [open "| $pchook" r] fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} fileevent $fd_ph readable \ [list commit_prehook_wait $fd_ph $curHEAD $msg_p] @@ -262,26 +250,14 @@ proc commit_commitmsg {curHEAD msg_p} { # -- Run the commit-msg hook. # - set pchook [gitdir hooks commit-msg] - - # On Cygwin [file executable] might lie so we need to ask - # the shell if the hook is executable. Yes that's annoying. - # - if {[is_Cygwin] && [file isfile $pchook]} { - set pchook [list sh -c [concat \ - "if test -x \"$pchook\";" \ - "then exec \"$pchook\" \"$msg_p\" 2>&1;" \ - "fi"]] - } elseif {[file executable $pchook]} { - set pchook [list $pchook $msg_p |& cat] - } else { + set fd_ph [githook_read commit-msg $msg_p] + if {$fd_ph eq {}} { commit_writetree $curHEAD $msg_p return } ui_status {Calling commit-msg hook...} set pch_error {} - set fd_ph [open "| $pchook" r] fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} fileevent $fd_ph readable \ [list commit_commitmsg_wait $fd_ph $curHEAD $msg_p] @@ -415,17 +391,13 @@ A rescan will be automatically started now. # -- Run the post-commit hook. # - set pchook [gitdir hooks post-commit] - if {[is_Cygwin] && [file isfile $pchook]} { - set pchook [list sh -c [concat \ - "if test -x \"$pchook\";" \ - "then exec \"$pchook\";" \ - "fi"]] - } elseif {![file executable $pchook]} { - set pchook {} - } - if {$pchook ne {}} { - catch {exec $pchook &} + set fd_ph [githook_read post-commit] + if {$fd_ph ne {}} { + upvar #0 pch_error$cmt_id pc_err + set pc_err {} + fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fileevent $fd_ph readable \ + [list commit_postcommit_wait $fd_ph $cmt_id] } $ui_comm delete 0.0 end @@ -481,3 +453,18 @@ A rescan will be automatically started now. reshow_diff ui_status [mc "Created commit %s: %s" [string range $cmt_id 0 7] $subject] } + +proc commit_postcommit_wait {fd_ph cmt_id} { + upvar #0 pch_error$cmt_id pch_error + + append pch_error [read $fd_ph] + fconfigure $fd_ph -blocking 1 + if {[eof $fd_ph]} { + if {[catch {close $fd_ph}]} { + hook_failed_popup post-commit $pch_error 0 + } + unset pch_error + return + } + fconfigure $fd_ph -blocking 0 +} diff --git a/lib/error.tcl b/lib/error.tcl index 712d217553..0fdd7531da 100644 --- a/lib/error.tcl +++ b/lib/error.tcl @@ -62,7 +62,7 @@ proc ask_popup {msg} { eval $cmd } -proc hook_failed_popup {hook msg} { +proc hook_failed_popup {hook msg {is_fatal 1}} { set w .hookfail toplevel $w @@ -77,14 +77,16 @@ proc hook_failed_popup {hook msg} { -width 80 -height 10 \ -font font_diff \ -yscrollcommand [list $w.m.sby set] - label $w.m.l2 \ - -text [mc "You must correct the above errors before committing."] \ - -anchor w \ - -justify left \ - -font font_uibold scrollbar $w.m.sby -command [list $w.m.t yview] pack $w.m.l1 -side top -fill x - pack $w.m.l2 -side bottom -fill x + if {$is_fatal} { + label $w.m.l2 \ + -text [mc "You must correct the above errors before committing."] \ + -anchor w \ + -justify left \ + -font font_uibold + pack $w.m.l2 -side bottom -fill x + } pack $w.m.sby -side right -fill y pack $w.m.t -side left -fill both -expand 1 pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10 From 6caaf2daf0ea50ff99009b94f24252b8fa747e64 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 20 Jan 2008 23:03:23 -0500 Subject: [PATCH 04/33] git-gui: Correct encoding of glossary/fr.po to UTF-8 Junio noticed this was incorrectly added in ISO-8859-1 but it should be in UTF-8 (as the headers claim UTF-8, and our convention is to use only UTF-8). Signed-off-by: Shawn O. Pearce --- po/glossary/fr.po | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/po/glossary/fr.po b/po/glossary/fr.po index bb2feaf137..27c006abb2 100644 --- a/po/glossary/fr.po +++ b/po/glossary/fr.po @@ -34,7 +34,7 @@ msgstr "branche" #. "" msgid "branch [verb]" -msgstr "créer une branche" +msgstr "créer une branche" #. "" msgid "checkout [noun]" @@ -58,7 +58,7 @@ msgstr "commiter" #. "" msgid "diff [noun]" -msgstr "différence" +msgstr "différence" #. "" msgid "diff [verb]" @@ -70,11 +70,11 @@ msgstr "fusion par avance rapide" #. "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too." msgid "fetch" -msgstr "récupérer" +msgstr "récupérer" #. "A collection of files. The index is a stored version of your working tree." msgid "index (in git-gui: staging area)" -msgstr "pré-commit" +msgstr "pré-commit" #. "A successful merge results in the creation of a new commit representing the result of the merge." msgid "merge [noun]" @@ -106,15 +106,15 @@ msgstr "refaire" #. "An other repository ('remote'). One might have a set of remotes whose branches one tracks." msgid "remote" -msgstr "référentiel distant" +msgstr "référentiel distant" #. "A collection of refs (?) together with an object database containing all objects which are reachable from the refs... (oops, you've lost me here. Again, please an explanation for mere mortals?)" msgid "repository" -msgstr "référentiel" +msgstr "référentiel" #. "" msgid "reset" -msgstr "réinitialiser" +msgstr "réinitialiser" #. "" msgid "revert" @@ -122,7 +122,7 @@ msgstr "inverser" #. "A particular state of files and directories which was stored in the object database." msgid "revision" -msgstr "révision" +msgstr "révision" #. "" msgid "sign off" @@ -130,11 +130,11 @@ msgstr "signer" #. "" msgid "staging area" -msgstr "pré-commit" +msgstr "pré-commit" #. "" msgid "status" -msgstr "état" +msgstr "état" #. "A ref pointing to a tag or commit object" msgid "tag [noun]" @@ -150,15 +150,15 @@ msgstr "branche de suivi" #. "" msgid "undo" -msgstr "défaire" +msgstr "défaire" #. "" msgid "update" -msgstr "mise à jour" +msgstr "mise à jour" #. "" msgid "verify" -msgstr "vérifier" +msgstr "vérifier" #. "The tree of actual checked out files." msgid "working copy, working tree" From 23a485e3ee32a9445e1c20bd4fd4b93119cd4f7c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 15 Jan 2008 02:35:49 -0800 Subject: [PATCH 05/33] git-submodule: rename shell functions for consistency This renames the shell functions used in git-submodule that implement top-level subcommands. The rule is that the subcommand $foo is implemented by cmd_$foo function. A noteworthy change is that modules_list() is now known as cmd_status(). There is no "submodule list" command. Signed-off-by: Junio C Hamano --- git-submodule.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/git-submodule.sh b/git-submodule.sh index ad9fe628fd..3c104e30f7 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -86,9 +86,9 @@ module_name() # # Clone a submodule # -# Prior to calling, modules_update checks that a possibly existing +# Prior to calling, cmd_update checks that a possibly existing # path is not a git repository. -# Likewise, module_add checks that path does not exist at all, +# Likewise, cmd_add checks that path does not exist at all, # since it is the location of a new submodule. # module_clone() @@ -121,7 +121,7 @@ module_clone() # # optional branch is stored in global branch variable # -module_add() +cmd_add() { repo=$1 path=$2 @@ -174,7 +174,7 @@ module_add() # # $@ = requested paths (default to all) # -modules_init() +cmd_init() { git ls-files --stage -- "$@" | grep -e '^160000 ' | while read mode sha1 stage path @@ -207,7 +207,7 @@ modules_init() # # $@ = requested paths (default to all) # -modules_update() +cmd_update() { git ls-files --stage -- "$@" | grep -e '^160000 ' | while read mode sha1 stage path @@ -266,7 +266,7 @@ set_name_rev () { # # $@ = requested paths (default to all) # -modules_list() +cmd_status() { git ls-files --stage -- "$@" | grep -e '^160000 ' | while read mode sha1 stage path @@ -347,16 +347,16 @@ esac case "$add,$init,$update,$status,$cached" in 1,,,,) - module_add "$@" + cmd_add "$@" ;; ,1,,,) - modules_init "$@" + cmd_init "$@" ;; ,,1,,) - modules_update "$@" + cmd_update "$@" ;; ,,,*,*) - modules_list "$@" + cmd_status "$@" ;; *) usage From 5c08dbbdf1a2d2565606bb43f7e42a5968fcbdf1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 15 Jan 2008 02:48:45 -0800 Subject: [PATCH 06/33] git-submodule: fix subcommand parser The subcommand parser of "git submodule" made its subcommand names reserved words. As a consequence, a command like this: $ git submodule add init update which is meant to add a submodule called 'init' at path 'update' was misinterpreted as a request to invoke more than one mutually incompatible subcommands and incorrectly rejected. This patch fixes the issue by stopping the subcommand parsing at the first subcommand word, to allow the sample command line above to work as expected. It also introduces the usual -- option disambiguator, so that a submodule at path '-foo' can be updated with $ git submodule update -- -foo without triggering an "unrecognized option -foo" error. Signed-off-by: Junio C Hamano --- git-submodule.sh | 157 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 116 insertions(+), 41 deletions(-) diff --git a/git-submodule.sh b/git-submodule.sh index 3c104e30f7..a6aaf40b0a 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -9,11 +9,8 @@ OPTIONS_SPEC= . git-sh-setup require_work_tree -add= +command= branch= -init= -update= -status= quiet= cached= @@ -123,6 +120,32 @@ module_clone() # cmd_add() { + # parse $args after "submodule ... add". + while test $# -ne 0 + do + case "$1" in + -b | --branch) + case "$2" in '') usage ;; esac + branch=$2 + shift + ;; + -q|--quiet) + quiet=1 + ;; + --) + shift + break + ;; + -*) + usage + ;; + *) + break + ;; + esac + shift + done + repo=$1 path=$2 @@ -176,6 +199,27 @@ cmd_add() # cmd_init() { + # parse $args after "submodule ... init". + while test $# -ne 0 + do + case "$1" in + -q|--quiet) + quiet=1 + ;; + --) + shift + break + ;; + -*) + usage + ;; + *) + break + ;; + esac + shift + done + git ls-files --stage -- "$@" | grep -e '^160000 ' | while read mode sha1 stage path do @@ -209,6 +253,27 @@ cmd_init() # cmd_update() { + # parse $args after "submodule ... update". + while test $# -ne 0 + do + case "$1" in + -q|--quiet) + quiet=1 + ;; + --) + shift + break + ;; + -*) + usage + ;; + *) + break + ;; + esac + shift + done + git ls-files --stage -- "$@" | grep -e '^160000 ' | while read mode sha1 stage path do @@ -268,6 +333,30 @@ set_name_rev () { # cmd_status() { + # parse $args after "submodule ... status". + while test $# -ne 0 + do + case "$1" in + -q|--quiet) + quiet=1 + ;; + --cached) + cached=1 + ;; + --) + shift + break + ;; + -*) + usage + ;; + *) + break + ;; + esac + shift + done + git ls-files --stage -- "$@" | grep -e '^160000 ' | while read mode sha1 stage path do @@ -293,20 +382,17 @@ cmd_status() done } -while test $# != 0 +# This loop parses the command line arguments to find the +# subcommand name to dispatch. Parsing of the subcommand specific +# options are primarily done by the subcommand implementations. +# Subcommand specific options such as --branch and --cached are +# parsed here as well, for backward compatibility. + +while test $# != 0 && test -z "$command" do case "$1" in - add) - add=1 - ;; - init) - init=1 - ;; - update) - update=1 - ;; - status) - status=1 + add | init | update | status) + command=$1 ;; -q|--quiet) quiet=1 @@ -335,30 +421,19 @@ do shift done -case "$add,$branch" in -1,*) - ;; -,) - ;; -,*) - usage - ;; -esac +# No command word defaults to "status" +test -n "$command" || command=status -case "$add,$init,$update,$status,$cached" in -1,,,,) - cmd_add "$@" - ;; -,1,,,) - cmd_init "$@" - ;; -,,1,,) - cmd_update "$@" - ;; -,,,*,*) - cmd_status "$@" - ;; -*) +# "-b branch" is accepted only by "add" +if test -n "$branch" && test "$command" != add +then usage - ;; -esac +fi + +# "--cached" is accepted only by "status" +if test -n "$cached" && test "$command" != status +then + usage +fi + +"cmd_$command" "$@" From a2d93aea25e33468622fbd6d9a6e02f8dd8b3c58 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 15 Jan 2008 03:13:55 -0800 Subject: [PATCH 07/33] git-submodule: add test for the subcommand parser fix This modifies the existing t7400 test to use 'init' as the pathname that a submodule is bound to. Without the earlier subcommand parser fix, this fails. Signed-off-by: Junio C Hamano --- t/t7400-submodule-basic.sh | 56 +++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 4fe3a41f07..2ef85a869d 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -13,11 +13,11 @@ subcommands of git-submodule. # # Test setup: -# -create a repository in directory lib +# -create a repository in directory init # -add a couple of files -# -add directory lib to 'superproject', this creates a DIRLINK entry +# -add directory init to 'superproject', this creates a DIRLINK entry # -add a couple of regular files to enable testing of submodule filtering -# -mv lib subrepo +# -mv init subrepo # -add an entry to .gitmodules for submodule 'example' # test_expect_success 'Prepare submodule testing' ' @@ -25,8 +25,8 @@ test_expect_success 'Prepare submodule testing' ' git-add t && git-commit -m "initial commit" && git branch initial HEAD && - mkdir lib && - cd lib && + mkdir init && + cd init && git init && echo a >a && git add a && @@ -41,10 +41,10 @@ test_expect_success 'Prepare submodule testing' ' cd .. && echo a >a && echo z >z && - git add a lib z && + git add a init z && git-commit -m "super commit 1" && - mv lib .subrepo && - GIT_CONFIG=.gitmodules git config submodule.example.url git://example.com/lib.git + mv init .subrepo && + GIT_CONFIG=.gitmodules git config submodule.example.url git://example.com/init.git ' test_expect_success 'status should fail for unmapped paths' ' @@ -52,7 +52,7 @@ test_expect_success 'status should fail for unmapped paths' ' then echo "[OOPS] submodule status succeeded" false - elif ! GIT_CONFIG=.gitmodules git config submodule.example.path lib + elif ! GIT_CONFIG=.gitmodules git config submodule.example.path init then echo "[OOPS] git config failed to update .gitmodules" false @@ -71,7 +71,7 @@ test_expect_success 'status should initially be "missing"' ' test_expect_success 'init should register submodule url in .git/config' ' git-submodule init && url=$(git config submodule.example.url) && - if test "$url" != "git://example.com/lib.git" + if test "$url" != "git://example.com/init.git" then echo "[OOPS] init succeeded but submodule url is wrong" false @@ -83,41 +83,41 @@ test_expect_success 'init should register submodule url in .git/config' ' ' test_expect_success 'update should fail when path is used by a file' ' - echo "hello" >lib && + echo "hello" >init && if git-submodule update then echo "[OOPS] update should have failed" false - elif test "$(cat lib)" != "hello" + elif test "$(cat init)" != "hello" then - echo "[OOPS] update failed but lib file was molested" + echo "[OOPS] update failed but init file was molested" false else - rm lib + rm init fi ' test_expect_success 'update should fail when path is used by a nonempty directory' ' - mkdir lib && - echo "hello" >lib/a && + mkdir init && + echo "hello" >init/a && if git-submodule update then echo "[OOPS] update should have failed" false - elif test "$(cat lib/a)" != "hello" + elif test "$(cat init/a)" != "hello" then - echo "[OOPS] update failed but lib/a was molested" + echo "[OOPS] update failed but init/a was molested" false else - rm lib/a + rm init/a fi ' test_expect_success 'update should work when path is an empty dir' ' - rm -rf lib && - mkdir lib && + rm -rf init && + mkdir init && git-submodule update && - head=$(cd lib && git rev-parse HEAD) && + head=$(cd init && git rev-parse HEAD) && if test -z "$head" then echo "[OOPS] Failed to obtain submodule head" @@ -134,7 +134,7 @@ test_expect_success 'status should be "up-to-date" after update' ' ' test_expect_success 'status should be "modified" after submodule commit' ' - cd lib && + cd init && echo b >b && git add b && git-commit -m "submodule commit 2" && @@ -157,8 +157,8 @@ test_expect_success 'git diff should report the SHA1 of the new submodule commit ' test_expect_success 'update should checkout rev1' ' - git-submodule update && - head=$(cd lib && git rev-parse HEAD) && + git-submodule update init && + head=$(cd init && git rev-parse HEAD) && if test -z "$head" then echo "[OOPS] submodule git rev-parse returned nothing" @@ -182,13 +182,13 @@ test_expect_success 'checkout superproject with subproject already present' ' test_expect_success 'apply submodule diff' ' git branch second && ( - cd lib && + cd init && echo s >s && git add s && git commit -m "change subproject" ) && - git update-index --add lib && - git-commit -m "change lib" && + git update-index --add init && + git-commit -m "change init" && git-format-patch -1 --stdout >P.diff && git checkout second && git apply --index P.diff && From c4a95c9f4b9c7b4dc8b705d323309263aa154e6a Mon Sep 17 00:00:00 2001 From: Steffen Prohaska Date: Mon, 21 Jan 2008 07:41:27 +0100 Subject: [PATCH 08/33] submodule: Document the details of the command line syntax Only "status" accepts "--cached" and the preferred way of passing sub-command specific options is after the sub-command. The documentation is adapted to reflect this. Signed-off-by: Steffen Prohaska Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index cffc6d48fb..e818e6e789 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -9,8 +9,9 @@ git-submodule - Initialize, update or inspect submodules SYNOPSIS -------- [verse] -'git-submodule' [--quiet] [-b branch] add [] -'git-submodule' [--quiet] [--cached] [status|init|update] [--] [...] +'git-submodule' [--quiet] add [-b branch] [--] [] +'git-submodule' [--quiet] status [--cached] [--] [...] +'git-submodule' [--quiet] [init|update] [--] [...] COMMANDS From bb23fdfa6c13b7f9cd5e1dbe0ca2fea31a627c5c Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 20 Jan 2008 23:36:54 -0500 Subject: [PATCH 09/33] Teach fast-import to honor pack.compression and pack.depth We now use the configured pack.compression and pack.depth values within fast-import, as like builtin-pack-objects fast-import is generating a packfile for consumption by the Git tools. We use the same behavior as builtin-pack-objects does for these options, allowing core.compression to supply the default value for pack.compression. The default setting for pack.depth within fast-import is still 10 as users will generally repack fast-import generated packfiles by `repack -f`. A large delta depth within the fast-import packfile can significantly slow down such a later repack. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- fast-import.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/fast-import.c b/fast-import.c index 45b4edf36b..f6872fe23d 100644 --- a/fast-import.c +++ b/fast-import.c @@ -275,6 +275,8 @@ struct recent_command static unsigned long max_depth = 10; static off_t max_packsize = (1LL << 32) - 1; static int force_update; +static int pack_compression_level = Z_DEFAULT_COMPRESSION; +static int pack_compression_seen; /* Stats and misc. counters */ static uintmax_t alloc_count; @@ -1038,7 +1040,7 @@ static int store_object( delta = NULL; memset(&s, 0, sizeof(s)); - deflateInit(&s, zlib_compression_level); + deflateInit(&s, pack_compression_level); if (delta) { s.next_in = delta; s.avail_in = deltalen; @@ -1066,7 +1068,7 @@ static int store_object( delta = NULL; memset(&s, 0, sizeof(s)); - deflateInit(&s, zlib_compression_level); + deflateInit(&s, pack_compression_level); s.next_in = (void *)dat->buf; s.avail_in = dat->len; s.avail_out = deflateBound(&s, s.avail_in); @@ -2282,6 +2284,27 @@ static void import_marks(const char *input_file) fclose(f); } +static int git_pack_config(const char *k, const char *v) +{ + if (!strcmp(k, "pack.depth")) { + max_depth = git_config_int(k, v); + if (max_depth > MAX_DEPTH) + max_depth = MAX_DEPTH; + return 0; + } + if (!strcmp(k, "pack.compression")) { + int level = git_config_int(k, v); + if (level == -1) + level = Z_DEFAULT_COMPRESSION; + else if (level < 0 || level > Z_BEST_COMPRESSION) + die("bad pack compression level %d", level); + pack_compression_level = level; + pack_compression_seen = 1; + return 0; + } + return git_default_config(k, v); +} + static const char fast_import_usage[] = "git-fast-import [--date-format=f] [--max-pack-size=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]"; @@ -2289,7 +2312,10 @@ int main(int argc, const char **argv) { unsigned int i, show_stats = 1; - git_config(git_default_config); + git_config(git_pack_config); + if (!pack_compression_seen && core_compression_seen) + pack_compression_level = core_compression_level; + alloc_objects(object_entry_alloc); strbuf_init(&command_buf, 0); atom_table = xcalloc(atom_table_sz, sizeof(struct atom_str*)); From 7422bac441d6e00cfb8302600ae64512837ab4e3 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 20 Jan 2008 23:37:01 -0500 Subject: [PATCH 10/33] Document the hairy gfi_unpack_entry part of fast-import Junio pointed out this part of fast-import wasn't very clear on initial read, and it took some time for someone who was new to fast-import's "dirty little tricks" to understand how this was even working. So a little bit of commentary in the proper place may help future readers. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- fast-import.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/fast-import.c b/fast-import.c index f6872fe23d..a523b171e2 100644 --- a/fast-import.c +++ b/fast-import.c @@ -1125,6 +1125,24 @@ static int store_object( return 0; } +/* All calls must be guarded by find_object() or find_mark() to + * ensure the 'struct object_entry' passed was written by this + * process instance. We unpack the entry by the offset, avoiding + * the need for the corresponding .idx file. This unpacking rule + * works because we only use OBJ_REF_DELTA within the packfiles + * created by fast-import. + * + * oe must not be NULL. Such an oe usually comes from giving + * an unknown SHA-1 to find_object() or an undefined mark to + * find_mark(). Callers must test for this condition and use + * the standard read_sha1_file() when it happens. + * + * oe->pack_id must not be MAX_PACK_ID. Such an oe is usually from + * find_mark(), where the mark was reloaded from an existing marks + * file and is referencing an object that this fast-import process + * instance did not write out to a packfile. Callers must test for + * this condition and use read_sha1_file() instead. + */ static void *gfi_unpack_entry( struct object_entry *oe, unsigned long *sizep) @@ -1132,7 +1150,22 @@ static void *gfi_unpack_entry( enum object_type type; struct packed_git *p = all_packs[oe->pack_id]; if (p == pack_data && p->pack_size < (pack_size + 20)) { + /* The object is stored in the packfile we are writing to + * and we have modified it since the last time we scanned + * back to read a previously written object. If an old + * window covered [p->pack_size, p->pack_size + 20) its + * data is stale and is not valid. Closing all windows + * and updating the packfile length ensures we can read + * the newly written data. + */ close_pack_windows(p); + + /* We have to offer 20 bytes additional on the end of + * the packfile as the core unpacker code assumes the + * footer is present at the file end and must promise + * at least 20 bytes within any window it maps. But + * we don't actually create the footer here. + */ p->pack_size = pack_size + 20; } return unpack_entry(p, oe->offset, &type, sizep); From 97394ee4304a8d336663df5da23a33efbe1ab46b Mon Sep 17 00:00:00 2001 From: Gustaf Hendeby Date: Mon, 21 Jan 2008 20:57:46 +0100 Subject: [PATCH 11/33] send-email, fix breakage in combination with --compose This fixes the subtile bug in git send-email that was introduced into git send-email with aa54892f5ada8282643dc7387b33261c7135d784 (send-email: detect invocation errors earlier), which caused no patches to be sent out if the --compose flag was used. Signed-off-by: Gustaf Hendeby Tested-by: Seth Falcon Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-send-email.perl b/git-send-email.perl index 6c72952fcc..a1a9d14b00 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -462,7 +462,7 @@ EOT exit(0); } - @files = ($compose_filename . ".final"); + @files = ($compose_filename . ".final", @files); } # Variables we set as part of the loop over files From 9288bedafa5a61689d6bef920c707b1ff9fe080a Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Mon, 21 Jan 2008 21:53:25 +0100 Subject: [PATCH 12/33] Make t5710 more strict when creating nested repos The test 'creating too deep nesting' can fail even when cloning the repos, but is not its main purpose (it has to prepare nested repos and ensure the last one is invalid). So split the test into the creation and invalidity checking parts. Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- t/t5710-info-alternate.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh index 699df6ebd8..1908dc8b06 100755 --- a/t/t5710-info-alternate.sh +++ b/t/t5710-info-alternate.sh @@ -53,14 +53,18 @@ git prune' cd "$base_dir" -test_expect_failure 'creating too deep nesting' \ +test_expect_success 'creating too deep nesting' \ 'git clone -l -s C D && git clone -l -s D E && git clone -l -s E F && git clone -l -s F G && -git clone -l -s G H && -cd H && -test_valid_repo' +git clone -l -s G H' + +test_expect_success 'invalidity of deepest repository' \ +'cd H && { + test_valid_repo + test $? -ne 0 +}' cd "$base_dir" From 6fc74703dee571859d8be270f5496f4c9b2ff9c7 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 21 Jan 2008 11:07:15 -0500 Subject: [PATCH 13/33] pack-objects: Fix segfault when object count is less than thread count When partitioning the work amongst threads, dividing the number of objects by the number of threads may return 0 when there are less objects than threads; this will cause the subsequent code to segfault when accessing list[sub_size-1]. Allow some threads to have zero objects to work on instead of barfing, while letting others to have more. Signed-off-by: Junio C Hamano --- builtin-pack-objects.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index ec10238e4a..d3efeff03f 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -1672,7 +1672,8 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size, p[i].data_ready = 0; /* try to split chunks on "path" boundaries */ - while (sub_size < list_size && list[sub_size]->hash && + while (sub_size && sub_size < list_size && + list[sub_size]->hash && list[sub_size]->hash == list[sub_size-1]->hash) sub_size++; From 4f5f998fbd64c997ea875d69fd86b6362e04ce9b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 21 Jan 2008 17:34:43 -0800 Subject: [PATCH 14/33] Clarify that http-push being temporarily disabled with older cURL Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.5.4.txt | 14 ++++++++++++-- Documentation/git-http-push.txt | 3 +++ http.h | 8 ++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Documentation/RelNotes-1.5.4.txt b/Documentation/RelNotes-1.5.4.txt index 9c864c9def..9e43ac23a4 100644 --- a/Documentation/RelNotes-1.5.4.txt +++ b/Documentation/RelNotes-1.5.4.txt @@ -10,8 +10,18 @@ Removal * As git-commit and git-status have been rewritten, "git runstatus" helper script lost all its users and has been removed. - * Curl library older than 7.10 is not supported by "git http-push", - as it does not work without CURLM. + +Temporarily Disabled +-------------------- + + * "git http-push" is known not to work well with cURL library older + than 7.16, and we had reports of repository corruption. It is + disabled on such platforms for now. Unfortunately, 1.5.3.8 shares + the same issue. In other words, this does not mean you will be + fine if you stick to an older git release. For now, please do not + use http-push from older git with cURL older than 7.16 if you + value your data. A proper fix will hopefully materialize in + later versions. Deprecation notices diff --git a/Documentation/git-http-push.txt b/Documentation/git-http-push.txt index cca77f10d2..0b82722342 100644 --- a/Documentation/git-http-push.txt +++ b/Documentation/git-http-push.txt @@ -15,6 +15,9 @@ DESCRIPTION Sends missing objects to remote repository, and updates the remote branch. +*NOTE*: This command is temporarily disabled if your cURL +library is older than 7.16, as the combination has been reported +not to work and sometimes corrupts repository. OPTIONS ------- diff --git a/http.h b/http.h index aeba9301f8..9bab2c8821 100644 --- a/http.h +++ b/http.h @@ -8,6 +8,14 @@ #include "strbuf.h" +/* + * We detect based on the cURL version if multi-transfer is + * usable in this implementation and define this symbol accordingly. + * This is not something Makefile should set nor users should pass + * via CFLAGS. + */ +#undef USE_CURL_MULTI + #if LIBCURL_VERSION_NUM >= 0x071000 #define USE_CURL_MULTI #define DEFAULT_MAX_REQUESTS 5 From 3b839fd8610b440f072d0c1c0ec00801347f3793 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 21 Jan 2008 14:37:41 -0800 Subject: [PATCH 15/33] git-svn: default to repacking every 1000 commits This should reduce disk space usage when doing large imports. We'll be switching to "gc --auto" post-1.5.4 to handle repacking for us. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/git-svn.perl b/git-svn.perl index 9f2b587b25..75e97cc72f 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -1408,11 +1408,9 @@ sub read_all_remotes { } sub init_vars { - if (defined $_repack) { - $_repack = 1000 if ($_repack <= 0); - $_repack_nr = $_repack; - $_repack_flags ||= '-d'; - } + $_repack = 1000 unless (defined $_repack && $_repack > 0); + $_repack_nr = $_repack; + $_repack_flags ||= '-d'; } sub verify_remotes_sanity { @@ -2151,7 +2149,7 @@ sub do_git_commit { 0, $self->svm_uuid); } print " = $commit ($self->{ref_id})\n"; - if (defined $_repack && (--$_repack_nr == 0)) { + if ($_repack && (--$_repack_nr == 0)) { $_repack_nr = $_repack; # repack doesn't use any arguments with spaces in them, does it? print "Running git repack $_repack_flags ...\n"; From 3ddff72e581e5c7477aaeb8b97a17691f7ff55bf Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 22 Jan 2008 10:40:13 -0500 Subject: [PATCH 16/33] git-gui: Work around random missing scrollbar in revision list If the horizontal scrollbar isn't currently visible (because it has not been needed) but we get an update to the scroll port we may find the scrollbar window exists but the Tcl command doesn't. Apparently it is possible for Tk to have partially destroyed the scrollbar by removing the Tcl procedure name but still leaving the widget name in the window registry. Signed-off-by: Shawn O. Pearce --- lib/choose_rev.tcl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl index a063c5bc49..c8821c1463 100644 --- a/lib/choose_rev.tcl +++ b/lib/choose_rev.tcl @@ -451,7 +451,8 @@ method _sb_set {sb orient first last} { focus $old_focus } } - $sb set $first $last + + catch {$sb set $first $last} } method _show_tooltip {pos} { From 3470adabad8c02be152a8d536d23df692eb386d6 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 22 Jan 2008 23:44:36 -0500 Subject: [PATCH 17/33] git-gui: Fallback to Tcl based po2msg.sh if msgfmt isn't available If msgfmt fails with exit code 127 that typically means the program is not found in the user's PATH and thus cannot be executed by make. In such a case we can try to fallback to the Tcl based po2msg program that we distributed with git-gui, as it does a "good enough" job. We still don't default to po2msg.sh however as it does not perform a lot of the sanity checks that msgfmt does, and quite a few of those are too useful to give up. Signed-off-by: Shawn O. Pearce --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 1baf4b0861..5f1023e35f 100644 --- a/Makefile +++ b/Makefile @@ -198,6 +198,9 @@ ifdef NO_MSGFMT MSGFMT ?= $(TCL_PATH) po/po2msg.sh else MSGFMT ?= msgfmt + ifeq ($(shell $(MSGFMT) >/dev/null 2>&1 || echo $$?),127) + MSGFMT := $(TCL_PATH) po/po2msg.sh + endif endif msgsdir = $(gg_libdir)/msgs From 2cd9ad2e71c57b283e8caf03de065bba1dff5f5f Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 22 Jan 2008 23:52:07 -0500 Subject: [PATCH 18/33] git-gui: Make the statistics of po2msg match those of msgfmt The strings we were showing from po2msg didn't exactly match those of msgfmt's --statistics output so we didn't show quite the same results when building git-gui's message files. Now we're closer to what msgfmt shows (at least for an en_US locale) so the make output matches. I noticed that the fuzzy translation count is off by one for the current po/zh_cn.po file. Not sure why and I'm not going to try and debug it at this time as the po2msg is strictly a fallback, users building from source really should prefer msgfmt. Signed-off-by: Shawn O. Pearce --- po/po2msg.sh | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/po/po2msg.sh b/po/po2msg.sh index c63248e375..b7c4bf3fdf 100644 --- a/po/po2msg.sh +++ b/po/po2msg.sh @@ -127,7 +127,26 @@ foreach file $files { } if {$show_statistics} { - puts [concat "$translated_count translated messages, " \ - "$fuzzy_count fuzzy ones, " \ - "$not_translated_count untranslated ones."] + set str "" + + append str "$translated_count translated message" + if {$translated_count != 1} { + append str s + } + + if {$fuzzy_count > 1} { + append str ", $fuzzy_count fuzzy translation" + if {$fuzzy_count != 1} { + append str s + } + } + if {$not_translated_count > 0} { + append str ", $not_translated_count untranslated message" + if {$not_translated_count != 1} { + append str s + } + } + + append str . + puts $str } From 3b8f19a02c3dd6043a7a6bdd65de2d4610c26b81 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 22 Jan 2008 23:56:15 -0500 Subject: [PATCH 19/33] git-gui: Correctly cleanup msgfmt '1 message untranslated' output In the multiple message case we remove the word "messages" from the statistics output of msgfmt as it looks cleaner on the tty when you are watching the build process. However we failed to strip the word "message" when only 1 message was found to be untranslated or fuzzy, as msgfmt does not produce the 's' suffix. Signed-off-by: Shawn O. Pearce --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5f1023e35f..34438cdf5c 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,7 @@ ifndef V QUIET_GEN = $(QUIET)echo ' ' GEN '$@' && QUIET_INDEX = $(QUIET)echo ' ' INDEX $(dir $@) && QUIET_MSGFMT0 = $(QUIET)printf ' MSGFMT %12s ' $@ && v=` - QUIET_MSGFMT1 = 2>&1` && echo "$$v" | sed -e 's/fuzzy translations/fuzzy/' | sed -e 's/ messages//g' + QUIET_MSGFMT1 = 2>&1` && echo "$$v" | sed -e 's/fuzzy translations/fuzzy/' | sed -e 's/ messages*//g' QUIET_2DEVNULL = 2>/dev/null INSTALL_D0 = dir= From 28678b4f2f2e449986de4a6fc2dc93b32299ca74 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 22 Jan 2008 23:12:25 +0100 Subject: [PATCH 20/33] git-clone -s: document problems with git gc --prune There is a scenario when using git clone -s and git gc --prune togother is dangerous. Document this. Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- Documentation/git-clone.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index fdccbd4cbe..2341881614 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -62,6 +62,14 @@ OPTIONS .git/objects/info/alternates to share the objects with the source repository. The resulting repository starts out without any object of its own. + *NOTE*: this is a possibly dangerous operation; do *not* use + it unless you understand what it does. If you clone your + repository using this option, then delete branches in the + source repository and then run linkgit:git-gc[1] using the + '--prune' option in the source repository, it may remove + objects which are referenced by the cloned repository. + + --reference :: If the reference repository is on the local machine From 5a9dd3998fb4c3ddc048cbcab74a8df72bff91b7 Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Wed, 23 Jan 2008 11:21:22 -0600 Subject: [PATCH 21/33] git-commit: exit non-zero if we fail to commit the index In certain rare cases, the creation of the commit object and update of HEAD can succeed, but then installing the updated index will fail. This is most likely caused by a full disk or exceeded disk quota. When this happens the new index file will be removed, and the repository will be left with the original now-out-of-sync index. The user can recover with a "git reset HEAD" once the disk space issue is resolved. We should detect this failure and offer the user some helpful guidance. Signed-off-by: Brandon Casey Signed-off-by: Junio C Hamano --- builtin-commit.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/builtin-commit.c b/builtin-commit.c index 02279360f7..d8deb1ad03 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -122,19 +122,23 @@ static void rollback_index_files(void) } } -static void commit_index_files(void) +static int commit_index_files(void) { + int err = 0; + switch (commit_style) { case COMMIT_AS_IS: break; /* nothing to do */ case COMMIT_NORMAL: - commit_lock_file(&index_lock); + err = commit_lock_file(&index_lock); break; case COMMIT_PARTIAL: - commit_lock_file(&index_lock); + err = commit_lock_file(&index_lock); rollback_lock_file(&false_lock); break; } + + return err; } /* @@ -926,7 +930,10 @@ int cmd_commit(int argc, const char **argv, const char *prefix) unlink(git_path("MERGE_HEAD")); unlink(git_path("MERGE_MSG")); - commit_index_files(); + if (commit_index_files()) + die ("Repository has been updated, but unable to write\n" + "new_index file. Check that disk is not full or quota is\n" + "not exceeded, and then \"git reset HEAD\" to recover."); rerere(); run_hook(get_index_file(), "post-commit", NULL); From 2600973f2c565792b71e3aed62c40efb09e08c6e Mon Sep 17 00:00:00 2001 From: Robert Schiele Date: Thu, 24 Jan 2008 19:34:46 +0100 Subject: [PATCH 22/33] pre-POSIX.1-2001 systems do not have POSIX.1-2001 has declaration of select(2) in , but in the previous version of SUS, it was declared in (which is already included in git-compat-util.h). This introduces NO_SYS_SELECT_H macro in the Makefile to be set on older systems, to skip inclusion of that does not exist on them. We could check _POSIX_VERSION with 200112L and do this automatically, but earlier it was reported that the approach does not work well on some vintage of HP-UX. Other systems may get _POSIX_VERSION itself wrong. At least for now, this manual configuration is safer. Signed-off-by: Robert Schiele Signed-off-by: Junio C Hamano --- Makefile | 5 +++++ git-compat-util.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/Makefile b/Makefile index 5aac0c0c87..c9e54b15f7 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,8 @@ all:: # # Define NO_MKDTEMP if you don't have mkdtemp in the C library. # +# Define NO_SYS_SELECT_H if you don't have sys/select.h. +# # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link. # Enable it on Windows. By default, symrefs are still used. # @@ -635,6 +637,9 @@ ifdef NO_UNSETENV COMPAT_CFLAGS += -DNO_UNSETENV COMPAT_OBJS += compat/unsetenv.o endif +ifdef NO_SYS_SELECT_H + BASIC_CFLAGS += -DNO_SYS_SELECT_H +endif ifdef NO_MMAP COMPAT_CFLAGS += -DNO_MMAP COMPAT_OBJS += compat/mmap.o diff --git a/git-compat-util.h b/git-compat-util.h index b6ef5442b7..4df90cb34e 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -68,7 +68,9 @@ #include #include #include +#ifndef NO_SYS_SELECT_H #include +#endif #include #include #include From 81cc66a526b4d6c74ab7165d13718263c53210ea Mon Sep 17 00:00:00 2001 From: Robert Schiele Date: Thu, 24 Jan 2008 19:35:20 +0100 Subject: [PATCH 23/33] Makefile: customization for supporting HP-UX Signed-off-by: Robert Schiele Signed-off-by: Junio C Hamano --- Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Makefile b/Makefile index c9e54b15f7..dd12b6a123 100644 --- a/Makefile +++ b/Makefile @@ -505,6 +505,17 @@ ifeq ($(uname_S),IRIX64) # for now, build 32-bit version BASIC_LDFLAGS += -L/usr/lib32 endif +ifeq ($(uname_S),HP-UX) + NO_IPV6=YesPlease + NO_SETENV=YesPlease + NO_STRCASESTR=YesPlease + NO_MEMMEM = YesPlease + NO_STRLCPY = YesPlease + NO_MKDTEMP = YesPlease + NO_UNSETENV = YesPlease + NO_HSTRERROR = YesPlease + NO_SYS_SELECT_H = YesPlease +endif ifneq (,$(findstring arm,$(uname_M))) ARM_SHA1 = YesPlease endif From 3cf3237400f70329525d1085021910b4b76f8670 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Fri, 25 Jan 2008 12:19:41 +0100 Subject: [PATCH 24/33] autoconf: define NO_SYS_SELECT_H on systems without . Pre-POSIX.1-2001 systems don't have , but select(2) is declared in , which git-compat-util.h includes. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- config.mak.in | 1 + configure.ac | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/config.mak.in b/config.mak.in index 40b14d985a..ee6c33df03 100644 --- a/config.mak.in +++ b/config.mak.in @@ -30,6 +30,7 @@ NO_CURL=@NO_CURL@ NO_EXPAT=@NO_EXPAT@ NEEDS_LIBICONV=@NEEDS_LIBICONV@ NEEDS_SOCKET=@NEEDS_SOCKET@ +NO_SYS_SELECT_H=@NO_SYS_SELECT_H@ NO_D_INO_IN_DIRENT=@NO_D_INO_IN_DIRENT@ NO_D_TYPE_IN_DIRENT=@NO_D_TYPE_IN_DIRENT@ NO_SOCKADDR_STORAGE=@NO_SOCKADDR_STORAGE@ diff --git a/configure.ac b/configure.ac index af177fdb4d..85d7ef570d 100644 --- a/configure.ac +++ b/configure.ac @@ -235,6 +235,12 @@ test -n "$NEEDS_SOCKET" && LIBS="$LIBS -lsocket" ## Checks for header files. AC_MSG_NOTICE([CHECKS for header files]) # +# Define NO_SYS_SELECT_H if you don't have sys/select.h. +AC_CHECK_HEADER([sys/select.h], +[NO_SYS_SELECT_H=], +[NO_SYS_SELECT_H=UnfortunatelyYes]) +AC_SUBST(NO_SYS_SELECT_H) +# # Define OLD_ICONV if your library has an old iconv(), where the second # (input buffer pointer) parameter is declared with type (const char **). AC_DEFUN([OLDICONVTEST_SRC], [[ From 2b0d1033a3af476296af6b5d8f524829c6790c1f Mon Sep 17 00:00:00 2001 From: Sam Vilain Date: Fri, 25 Jan 2008 12:10:02 +1300 Subject: [PATCH 25/33] git-svn(1): update instructions for resuming a git-svn clone git-svn expects its references under refs/remotes/*; but these will not be copied or set by "git clone"; put in this man page the manual fiddling that is required with current git-svn to get this to work. Signed-off-by: Sam Vilain Signed-off-by: Junio C Hamano --- Documentation/git-svn.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index e1a1d46a9f..b1d527f74c 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -456,10 +456,13 @@ have each person clone that repository with 'git clone': ------------------------------------------------------------------------ # Do the initial import on a server ssh server "cd /pub && git-svn clone http://svn.foo.org/project -# Clone locally - git clone server:/pub/project -# Tell git-svn which branch contains the Subversion commits - git update-ref refs/remotes/git-svn origin/master +# Clone locally - make sure the refs/remotes/ space matches the server + mkdir project + cd project + git-init + git remote add origin server:/pub/project + git config --add remote.origin.fetch=+refs/remotes/*:refs/remotes/* + git fetch # Initialize git-svn locally (be sure to use the same URL and -T/-b/-t options as were used on server) git-svn init http://svn.foo.org/project # Pull the latest changes from Subversion From 10eb64f5fdaad47ff1973a9c55e7aa87a4524190 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Fri, 25 Jan 2008 10:17:38 +0000 Subject: [PATCH 26/33] git pull manpage: don't include -n from fetch-options.txt The -n option stands for --no-summary in git pull [jes: reworded the description to avoid mentioning 'git-fetch'; also exclude '-n' conditional on git-pull -- ugly because of the missing "else" statement in asciidoc] Signed-off-by: Miklos Vajna Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/fetch-options.txt | 12 ++++++++---- Documentation/git-pull.txt | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt index 61e48ccf02..b675911480 100644 --- a/Documentation/fetch-options.txt +++ b/Documentation/fetch-options.txt @@ -23,11 +23,15 @@ fetches is a descendant of ``. This option overrides that check. +ifdef::git-pull[] +\--no-tags:: +endif::git-pull[] +ifndef::git-pull[] -n, \--no-tags:: - By default, `git-fetch` fetches tags that point at - objects that are downloaded from the remote repository - and stores them locally. This option disables this - automatic tag following. +endif::git-pull[] + By default, tags that point at objects that are downloaded + from the remote repository are fetched and stored locally. + This option disables this automatic tag following. -t, \--tags:: Most of the tags are fetched automatically as branch diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index 77fdaf146e..f9f1e0d30b 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt @@ -25,6 +25,7 @@ OPTIONS ------- include::merge-options.txt[] +:git-pull: 1 include::fetch-options.txt[] include::pull-fetch-param.txt[] From 923e3ec84a4e792ca277aac08e52ec2f9b47a8eb Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sat, 26 Jan 2008 13:19:02 +0100 Subject: [PATCH 27/33] Add a missing dependency on http.h Signed-off-by: Mike Hommey Signed-off-by: Junio C Hamano --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index dd12b6a123..92341c4bbe 100644 --- a/Makefile +++ b/Makefile @@ -944,7 +944,7 @@ git-%$X: %.o $(GITLIBS) git-imap-send$X: imap-send.o $(LIB_FILE) -http.o http-walker.o http-push.o: http.h +http.o http-walker.o http-push.o transport.o: http.h git-http-push$X: revision.o http.o http-push.o $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ From 3a9f0f41db87e197708f84aeb2487bc983f99c9c Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sat, 26 Jan 2008 12:26:57 +0100 Subject: [PATCH 28/33] parse-options: catch likely typo in presense of aggregated options. If options are aggregated, and that the whole token is an exact prefix of a long option that is longer than 2 letters, reject it. This is to prevent a common typo: $ git commit -amend to get interpreted as "commit all with message 'end'". The typo check isn't performed if there is no aggregation, because the stuck form is the recommended one. If we have `-o` being a valid short option that takes an argument, and --option a long one, then we _MUST_ accept -option as "'o' option with argument 'ption'", which is our official recommended form. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- parse-options.c | 30 ++++++++++++++++++++++++++++-- t/t0040-parse-options.sh | 11 +++++++++++ test-parse-options.c | 1 + 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/parse-options.c b/parse-options.c index 7a08a0c64f..d9562ba504 100644 --- a/parse-options.c +++ b/parse-options.c @@ -216,6 +216,26 @@ is_abbreviated: return error("unknown option `%s'", arg); } +void check_typos(const char *arg, const struct option *options) +{ + if (strlen(arg) < 3) + return; + + if (!prefixcmp(arg, "no-")) { + error ("did you mean `--%s` (with two dashes ?)", arg); + exit(129); + } + + for (; options->type != OPTION_END; options++) { + if (!options->long_name) + continue; + if (!prefixcmp(options->long_name, arg)) { + error ("did you mean `--%s` (with two dashes ?)", arg); + exit(129); + } + } +} + static NORETURN void usage_with_options_internal(const char * const *, const struct option *, int); @@ -235,12 +255,18 @@ int parse_options(int argc, const char **argv, const struct option *options, if (arg[1] != '-') { args.opt = arg + 1; - do { + if (*args.opt == 'h') + usage_with_options(usagestr, options); + if (parse_short_opt(&args, options) < 0) + usage_with_options(usagestr, options); + if (args.opt) + check_typos(arg + 1, options); + while (args.opt) { if (*args.opt == 'h') usage_with_options(usagestr, options); if (parse_short_opt(&args, options) < 0) usage_with_options(usagestr, options); - } while (args.opt); + } continue; } diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 462fdf262f..0a3b55d121 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -19,6 +19,7 @@ string options get a string --string2 get another string --st get another string (pervert ordering) + -o get another string EOF @@ -103,4 +104,14 @@ test_expect_success 'non ambiguous option (after two options it abbreviates)' ' git diff expect output ' +cat > expect.err << EOF +error: did you mean \`--boolean\` (with two dashes ?) +EOF + +test_expect_success 'detect possible typos' ' + ! test-parse-options -boolean > output 2> output.err && + test ! -s output && + git diff expect.err output.err +' + test_done diff --git a/test-parse-options.c b/test-parse-options.c index 4d3e2ec39e..eed8a02c65 100644 --- a/test-parse-options.c +++ b/test-parse-options.c @@ -19,6 +19,7 @@ int main(int argc, const char **argv) OPT_STRING('s', "string", &string, "string", "get a string"), OPT_STRING(0, "string2", &string, "str", "get another string"), OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"), + OPT_STRING('o', NULL, &string, "str", "get another string"), OPT_END(), }; int i; From ab8daa183638cea6238ec5949c99fefdcc29bd8c Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sat, 26 Jan 2008 12:04:30 +0100 Subject: [PATCH 29/33] Documentation: add a bit about sendemail.to configuration While there is information about this in the configuration section, it was missing in the options section. Signed-off-by: Mike Hommey Signed-off-by: Junio C Hamano --- Documentation/git-send-email.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 4b8ec8a200..0554f2b374 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -137,6 +137,8 @@ The --cc option must be repeated for each user you want on the cc list. Specify the primary recipient of the emails generated. Generally, this will be the upstream maintainer of the project involved. + Default is the value of the 'sendemail.to' configuration value; + if that is unspecified, this will be prompted for. + The --to option must be repeated for each user you want on the to list. From 7549376587ba5ffea973663f72804072d8f1d5dd Mon Sep 17 00:00:00 2001 From: Steffen Prohaska Date: Sat, 26 Jan 2008 10:54:05 +0100 Subject: [PATCH 30/33] t9400-git-cvsserver-server: Wrap setup into test case It is preferable to have the test setup in a test case. The setup itself may fail and having it as a test case handles this situation more gracefully. Signed-off-by: Steffen Prohaska Signed-off-by: Junio C Hamano --- t/t9400-git-cvsserver-server.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index 641303e0a1..1f2749eefb 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -33,13 +33,14 @@ CVS_SERVER=git-cvsserver export CVSROOT CVS_SERVER rm -rf "$CVSWORK" "$SERVERDIR" -echo >empty && +test_expect_success 'setup' ' + echo >empty && git add empty && git commit -q -m "First Commit" && git clone -q --local --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 && GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true && - GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" || - exit 1 + GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" +' # note that cvs doesn't accept absolute pathnames # as argument to co -d From e509db990b2ecae642efe3cdef4014d57d525f24 Mon Sep 17 00:00:00 2001 From: Steffen Prohaska Date: Sat, 26 Jan 2008 10:54:06 +0100 Subject: [PATCH 31/33] cvsserver: Fix for histories with multiple roots Git histories may have multiple roots, which can cause git merge-base to fail and this caused git cvsserver to die. This commit teaches git cvsserver to handle a failing git merge-base gracefully, and modifies the test case to verify this. All the test cases now use a history with two roots. Signed-off-by: Steffen Prohaska git-cvsserver.perl | 9 ++++++++- t/t9400-git-cvsserver-server.sh | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) Signed-off-by: Junio C Hamano --- git-cvsserver.perl | 9 ++++++++- t/t9400-git-cvsserver-server.sh | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/git-cvsserver.perl b/git-cvsserver.perl index ecded3b9cb..afe3d0b7fe 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -2543,8 +2543,15 @@ sub update if ($parent eq $lastpicked) { next; } - my $base = safe_pipe_capture('git-merge-base', + my $base = eval { + safe_pipe_capture('git-merge-base', $lastpicked, $parent); + }; + # The two branches may not be related at all, + # in which case merge base simply fails to find + # any, but that's Ok. + next if ($@); + chomp $base; if ($base) { my @merged; diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index 1f2749eefb..75d1ce433d 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -37,6 +37,13 @@ test_expect_success 'setup' ' echo >empty && git add empty && git commit -q -m "First Commit" && + mkdir secondroot && + ( cd secondroot && + git init && + touch secondrootfile && + git add secondrootfile && + git commit -m "second root") && + git pull secondroot master && git clone -q --local --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 && GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true && GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" @@ -46,7 +53,8 @@ test_expect_success 'setup' ' # as argument to co -d test_expect_success 'basic checkout' \ 'GIT_CONFIG="$git_config" cvs -Q co -d cvswork master && - test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5))" = "empty/1.1/"' + test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | head -n 1))" = "empty/1.1/" + test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | tail -n 1))" = "secondrootfile/1.1/"' #------------------------ # PSERVER AUTHENTICATION From c85c79279df2c8a583d95449d1029baba41f8660 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 26 Jan 2008 18:04:37 +0000 Subject: [PATCH 32/33] pull --rebase: be cleverer with rebased upstream branches When the upstream branch is tracked, we can detect if that branch was rebased since it was last fetched. Teach git to use that information to rebase from the old remote head onto the new remote head. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-pull.txt | 6 +++++- git-pull.sh | 12 +++++++++++- t/t5520-pull.sh | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index f9f1e0d30b..4cc633a5ec 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt @@ -35,7 +35,11 @@ include::urls-remotes.txt[] include::merge-strategies.txt[] \--rebase:: - Instead of a merge, perform a rebase after fetching. + Instead of a merge, perform a rebase after fetching. If + there is a remote ref for the upstream branch, and this branch + was rebased since last fetched, the rebase uses that information + to avoid rebasing non-local changes. + *NOTE:* This is a potentially _dangerous_ mode of operation. It rewrites history, which does not bode well when you published that history already. Do *not* use this option diff --git a/git-pull.sh b/git-pull.sh index fa97b0f356..46da0f4ca2 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -106,6 +106,15 @@ error_on_no_merge_candidates () { exit 1 } +test true = "$rebase" && { + . git-parse-remote && + origin="$1" + test -z "$origin" && origin=$(get_default_remote) + reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null | + sed "s|refs/heads/\(.*\):|\1|")" && + oldremoteref="$(git rev-parse --verify \ + "refs/remotes/$origin/$reflist" 2>/dev/null)" +} orig_head=$(git rev-parse --verify HEAD 2>/dev/null) git-fetch --update-head-ok "$@" || exit 1 @@ -164,6 +173,7 @@ then fi merge_name=$(git fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit -test true = "$rebase" && exec git-rebase $merge_head +test true = "$rebase" && + exec git-rebase --onto $merge_head ${oldremoteref:-$merge_head} exec git-merge $no_summary $no_commit $squash $no_ff $strategy_args \ "$merge_name" HEAD $merge_head diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 52b3a0c6dd..9484129ca5 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -71,8 +71,25 @@ test_expect_success 'branch.to-rebase.rebase' ' git reset --hard before-rebase && git config branch.to-rebase.rebase 1 && git pull . copy && + git config branch.to-rebase.rebase 0 && test $(git rev-parse HEAD^) = $(git rev-parse copy) && test new = $(git show HEAD:file2) ' +test_expect_success '--rebase with rebased upstream' ' + + git remote add -f me . && + git checkout copy && + git reset --hard HEAD^ && + echo conflicting modification > file && + git commit -m conflict file && + git checkout to-rebase && + echo file > file2 && + git commit -m to-rebase file2 && + git pull --rebase me copy && + test "conflicting modification" = "$(cat file)" && + test file = $(cat file2) + +' + test_done From bf5aeb150681ed743d317702eaf123c34b05c311 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 26 Jan 2008 18:39:41 -0800 Subject: [PATCH 33/33] GIT 1.5.4-rc5 Hopefully the last rc before the final... Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.5.4.txt | 25 +++++++++++++------------ GIT-VERSION-GEN | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Documentation/RelNotes-1.5.4.txt b/Documentation/RelNotes-1.5.4.txt index 9e43ac23a4..f968fc4957 100644 --- a/Documentation/RelNotes-1.5.4.txt +++ b/Documentation/RelNotes-1.5.4.txt @@ -11,7 +11,7 @@ Removal helper script lost all its users and has been removed. -Temporarily Disabled +Temporarily disabled -------------------- * "git http-push" is known not to work well with cURL library older @@ -27,10 +27,10 @@ Temporarily Disabled Deprecation notices ------------------- - * The next feature release of git (this change is scheduled for v1.6.0) - will by default install dashed form of commands (e.g. "git-commit") - outside of users' normal $PATH, and will install only selected - commands ("git" itself, and "gitk") in $PATH. This implies: + * From v1.6.0, git will by default install dashed form of commands + (e.g. "git-commit") outside of users' normal $PATH, and will install + only selected commands ("git" itself, and "gitk") in $PATH. This + implies: - Using dashed forms of git commands (e.g. "git-commit") from the command line has been informally deprecated since early 2006, but @@ -44,8 +44,8 @@ Deprecation notices - Use of dashed forms with "PATH=$(git --exec-path):$PATH; export PATH" early in your script is not deprecated with this change. - Users are strongly encouraged to adjust their habits and scripts now - to prepare for this. + Users are strongly encouraged to adjust their habits and scripts now + to prepare for this change. * The post-receive hook was introduced in March 2007 to supersede the post-update hook, primarily to overcome the command line length @@ -80,7 +80,7 @@ Updates since v1.5.3 * Comes with much improved gitk, with i18n. - * Comes with "git gui" 0.9.1 with i18n. + * Comes with git-gui 0.9.2 with i18n. * gitk is now merged as a subdirectory of git.git project, in preparation for its i18n. @@ -242,8 +242,8 @@ Updates since v1.5.3 from its first parent. * "git commit" used to unconditionally strip comment lines that - began with '#' and removed excess blank lines. This - behaviour has been made configurable. + began with '#' and removed excess blank lines. This behavior has + been made configurable. * "git commit" has been rewritten in C. @@ -327,7 +327,7 @@ Updates since v1.5.3 * "git status" from a subdirectory now shows relative paths, which makes copy-and-pasting for git-checkout/git-add/git-rm easier. The - traditional behaviour to show the full path relative to the top of + traditional behavior to show the full path relative to the top of the work tree can be had by setting status.relativepaths configuration variable to false. @@ -351,6 +351,7 @@ Updates since v1.5.3 - enhancement and more use of the strbuf API. + * Makefile tweaks to support HP-UX is in. Fixes since v1.5.3 ------------------ @@ -377,6 +378,6 @@ series. -- exec >/var/tmp/1 -O=v1.5.4-rc4 +O=v1.5.4-rc5 echo O=`git describe refs/heads/master` git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 2ba142a11e..e0842c462c 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.5.4-rc3.GIT +DEF_VER=v1.5.4-rc5.GIT LF=' '