From fde97d8ac63efa466dd48436d2178bd364b846de Mon Sep 17 00:00:00 2001 From: Sean Date: Mon, 27 Nov 2006 14:37:43 -0500 Subject: [PATCH 01/19] Update documentation to remove incorrect GIT_DIFF_OPTS example. Git no longer calls an external diff program to generate patches. Remove the documentation which suggests that you can pass arbitrary diff options via the GIT_DIFF_OPTS environment variable. Signed-off-by: Sean Estabrooks Signed-off-by: Junio C Hamano --- Documentation/diff-format.txt | 57 ++++------------------------------- Documentation/git.txt | 32 +++++++++++++++++--- 2 files changed, 34 insertions(+), 55 deletions(-) diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt index e4520e28e5..883c1bb0a6 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.txt @@ -65,62 +65,17 @@ Generating patches with -p When "git-diff-index", "git-diff-tree", or "git-diff-files" are run with a '-p' option, they do not produce the output described above; -instead they produce a patch file. +instead they produce a patch file. You can customize the creation +of such patches via the GIT_EXTERNAL_DIFF and the GIT_DIFF_OPTS +environment variables. -The patch generation can be customized at two levels. - -1. When the environment variable 'GIT_EXTERNAL_DIFF' is not set, - these commands internally invoke "diff" like this: - - diff -L a/ -L b/ -pu -+ -For added files, `/dev/null` is used for . For removed -files, `/dev/null` is used for -+ -The "diff" formatting options can be customized via the -environment variable 'GIT_DIFF_OPTS'. For example, if you -prefer context diff: - - GIT_DIFF_OPTS=-c git-diff-index -p HEAD - - -2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the - program named by it is called, instead of the diff invocation - described above. -+ -For a path that is added, removed, or modified, -'GIT_EXTERNAL_DIFF' is called with 7 parameters: - - path old-file old-hex old-mode new-file new-hex new-mode -+ -where: - - -file:: are files GIT_EXTERNAL_DIFF can use to read the - contents of , - -hex:: are the 40-hexdigit SHA1 hashes, - -mode:: are the octal representation of the file modes. - -+ -The file parameters can point at the user's working file -(e.g. `new-file` in "git-diff-files"), `/dev/null` (e.g. `old-file` -when a new file is added), or a temporary file (e.g. `old-file` in the -index). 'GIT_EXTERNAL_DIFF' should not worry about unlinking the -temporary file --- it is removed when 'GIT_EXTERNAL_DIFF' exits. - -For a path that is unmerged, 'GIT_EXTERNAL_DIFF' is called with 1 -parameter, . - - -git specific extension to diff format -------------------------------------- - -What -p option produces is slightly different from the -traditional diff format. +What the -p option produces is slightly different from the traditional +diff format. 1. It is preceded with a "git diff" header, that looks like this: - diff --git a/file1 b/file2 + diff --git a/file1 b/file2 + The `a/` and `b/` filenames are the same unless rename/copy is involved. Especially, even for a creation or a deletion, diff --git a/Documentation/git.txt b/Documentation/git.txt index 619d65685e..6382ef0a02 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -639,11 +639,35 @@ git Commits git Diffs ~~~~~~~~~ 'GIT_DIFF_OPTS':: + Only valid setting is "--unified=??" or "-u??" to set the + number of context lines shown when a unified diff is created. + This takes precedence over any "-U" or "--unified" option + value passed on the git diff command line. + 'GIT_EXTERNAL_DIFF':: - see the "generating patches" section in : - gitlink:git-diff-index[1]; - gitlink:git-diff-files[1]; - gitlink:git-diff-tree[1] + When the environment variable 'GIT_EXTERNAL_DIFF' is set, the + program named by it is called, instead of the diff invocation + described above. For a path that is added, removed, or modified, + 'GIT_EXTERNAL_DIFF' is called with 7 parameters: + + path old-file old-hex old-mode new-file new-hex new-mode ++ +where: + + -file:: are files GIT_EXTERNAL_DIFF can use to read the + contents of , + -hex:: are the 40-hexdigit SHA1 hashes, + -mode:: are the octal representation of the file modes. + ++ +The file parameters can point at the user's working file +(e.g. `new-file` in "git-diff-files"), `/dev/null` (e.g. `old-file` +when a new file is added), or a temporary file (e.g. `old-file` in the +index). 'GIT_EXTERNAL_DIFF' should not worry about unlinking the +temporary file --- it is removed when 'GIT_EXTERNAL_DIFF' exits. ++ +For a path that is unmerged, 'GIT_EXTERNAL_DIFF' is called with 1 +parameter, . other ~~~~~ From 4ad91321ee95598c2488ab5e39afec13575d4e3f Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 03:40:47 -0500 Subject: [PATCH 02/19] Teach git-completion.bash how to complete git-merge. Now that git-merge is high-level Porcelain users are going to expect to be able to use it from the command line, in which case we really should also be able to complete ref names as parameters. I'm also including completion support for the merge strategies that are supported by git-merge.sh, should the user wish to use a different strategy than their default. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index a43a177160..28bd0e3ba7 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -81,6 +81,16 @@ __git_remotes () done } +__git_merge_strategies () +{ + sed -n "/^all_strategies='/{ + s/^all_strategies='// + s/'// + p + q + }" "$(git --exec-path)/git-merge" +} + __git_complete_file () { local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}" @@ -240,6 +250,24 @@ _git_log () esac } +_git_merge () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + --*) + COMPREPLY=($(compgen -W " + --no-commit --no-summary --squash + " -- "$cur")) + return + esac + if [ $COMP_CWORD -gt 1 -a X-s = "X${COMP_WORDS[COMP_CWORD-1]}" ] + then + COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur")) + else + COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) + fi +} + _git_merge_base () { local cur="${COMP_WORDS[COMP_CWORD]}" @@ -348,6 +376,7 @@ _git () log) _git_log ;; ls-remote) _git_ls_remote ;; ls-tree) _git_ls_tree ;; + merge) _git_merge;; merge-base) _git_merge_base ;; pull) _git_pull ;; push) _git_push ;; @@ -376,6 +405,7 @@ complete -o default -o nospace -F _git_fetch git-fetch complete -o default -o nospace -F _git_log git-log complete -o default -F _git_ls_remote git-ls-remote complete -o default -o nospace -F _git_ls_tree git-ls-tree +complete -o default -F _git_merge git-merge complete -o default -F _git_merge_base git-merge-base complete -o default -o nospace -F _git_pull git-pull complete -o default -o nospace -F _git_push git-push From f2bb9f88805f370b9de1c116f42e3ceb30321c80 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 03:41:01 -0500 Subject: [PATCH 03/19] Hide plumbing/transport commands from bash completion. Users generally are not going to need to invoke plumbing-level commands from within one line shell commands. If they are invoking these commands then it is likely that they are glueing them together into a shell script to perform an action, in which case bash completion for these commands is of relatively little use. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 62 +++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 28bd0e3ba7..b55431fbf2 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -125,6 +125,58 @@ __git_complete_file () esac } +__git_commands () +{ + local i IFS=" "$'\n' + for i in $(git help -a|egrep '^ ') + do + case $i in + check-ref-format) : plumbing;; + commit-tree) : plumbing;; + convert-objects) : plumbing;; + cvsserver) : daemon;; + daemon) : daemon;; + fetch-pack) : plumbing;; + hash-object) : plumbing;; + http-*) : transport;; + index-pack) : plumbing;; + local-fetch) : plumbing;; + mailinfo) : plumbing;; + mailsplit) : plumbing;; + merge-*) : plumbing;; + mktree) : plumbing;; + mktag) : plumbing;; + pack-objects) : plumbing;; + pack-redundant) : plumbing;; + pack-refs) : plumbing;; + parse-remote) : plumbing;; + patch-id) : plumbing;; + peek-remote) : plumbing;; + read-tree) : plumbing;; + receive-pack) : plumbing;; + rerere) : plumbing;; + rev-list) : plumbing;; + rev-parse) : plumbing;; + runstatus) : plumbing;; + sh-setup) : internal;; + shell) : daemon;; + send-pack) : plumbing;; + show-index) : plumbing;; + ssh-*) : transport;; + stripspace) : plumbing;; + symbolic-ref) : plumbing;; + unpack-file) : plumbing;; + unpack-objects) : plumbing;; + update-ref) : plumbing;; + update-server-info) : daemon;; + upload-archive) : plumbing;; + upload-pack) : plumbing;; + write-tree) : plumbing;; + *) echo $i;; + esac + done +} + __git_aliases () { local i IFS=$'\n' @@ -355,11 +407,11 @@ _git () done if [ $c -eq $COMP_CWORD -a -z "$command" ]; then - COMPREPLY=($(compgen \ - -W "--git-dir= --version \ - $(git help -a|egrep '^ ') \ - $(__git_aliases)" \ - -- "${COMP_WORDS[COMP_CWORD]}")) + COMPREPLY=($(compgen -W " + --git-dir= --version --exec-path + $(__git_commands) + $(__git_aliases) + " -- "${COMP_WORDS[COMP_CWORD]}")) return; fi From d33909bf6e78e6ab8a45bfdd19bc19213fde5501 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 03:41:12 -0500 Subject: [PATCH 04/19] Teach bash how to complete options for git-name-rev. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index b55431fbf2..1dfb59207a 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -326,6 +326,12 @@ _git_merge_base () COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) } +_git_name_rev () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + COMPREPLY=($(compgen -W "--tags --all --stdin" -- "$cur")) +} + _git_pull () { local cur="${COMP_WORDS[COMP_CWORD]}" @@ -430,6 +436,7 @@ _git () ls-tree) _git_ls_tree ;; merge) _git_merge;; merge-base) _git_merge_base ;; + name-rev) _git_name_rev ;; pull) _git_pull ;; push) _git_push ;; reset) _git_reset ;; @@ -459,6 +466,7 @@ complete -o default -F _git_ls_remote git-ls-remote complete -o default -o nospace -F _git_ls_tree git-ls-tree complete -o default -F _git_merge git-merge complete -o default -F _git_merge_base git-merge-base +complete -o default -F _git_name_rev git-name-rev complete -o default -o nospace -F _git_pull git-pull complete -o default -o nospace -F _git_push git-push complete -o default -F _git_reset git-reset @@ -479,6 +487,7 @@ complete -o default -o nospace -F _git_diff_tree git-diff-tree.exe complete -o default -o nospace -F _git_log git-log.exe complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe complete -o default -F _git_merge_base git-merge-base.exe +complete -o default -F _git_name_rev git-name-rev.exe complete -o default -o nospace -F _git_push git-push.exe complete -o default -o nospace -F _git_log git-show-branch.exe complete -o default -o nospace -F _git_log git-whatchanged.exe From d3d717a4ad0c8d7329e79f7d0313baec57c6b585 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 03:41:28 -0500 Subject: [PATCH 05/19] Add current branch in PS1 support to git-completion.bash. Many users want to display the current branch name of the current git repository as part of their PS1 prompt, much as their PS1 prompt might also display the current working directory name. We don't force our own PS1 onto the user. Instead we let them craft their own PS1 string and offer them the function __git_ps1 which they can invoke to obtain either "" (when not in a git repository) or "(%s)" where %s is the name of the current branch, as read from HEAD, with the leading refs/heads/ removed. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 1dfb59207a..a740d05e28 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -18,12 +18,31 @@ # 2) Added the following line to your .bashrc: # source ~/.git-completion.sh # +# 3) Consider changing your PS1 to also show the current branch: +# PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' +# +# The argument to __git_ps1 will be displayed only if you +# are currently in a git repository. The %s token will be +# the name of the current branch. +# __gitdir () { echo "${__git_dir:-$(git rev-parse --git-dir 2>/dev/null)}" } +__git_ps1 () +{ + local b="$(git symbolic-ref HEAD 2>/dev/null)" + if [ -n "$b" ]; then + if [ -n "$1" ]; then + printf "$1" "${b##refs/heads/}" + else + printf " (%s)" "${b##refs/heads/}" + fi + fi +} + __git_refs () { local cmd i is_hash=y dir="${1:-$(__gitdir)}" From f53352fbaf2bcc6d209388bb2a68d888ceb8014e Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 03:41:43 -0500 Subject: [PATCH 06/19] Teach bash how to complete git-format-patch. Provide completion for currently known long options supported by git-format-patch as well as the revision list specification argument, which is generally either a refname or in the form a..b. Since _git_log was the only code that knew how to complete a..b, but we want to start adding option support to _git_log also refactor the a..b completion logic out into its own function. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 60 +++++++++++++++++++------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index a740d05e28..dfdc3968b8 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -144,6 +144,26 @@ __git_complete_file () esac } +__git_complete_revlist () +{ + local pfx cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + *...*) + pfx="${cur%...*}..." + cur="${cur#*...}" + COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur")) + ;; + *..*) + pfx="${cur%..*}.." + cur="${cur#*..}" + COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) + ;; + esac +} + __git_commands () { local i IFS=" "$'\n' @@ -290,6 +310,26 @@ _git_fetch () esac } +_git_format_patch () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + --*) + COMPREPLY=($(compgen -W " + --stdout --attach --thread + --output-directory + --numbered --start-number + --keep-subject + --signoff + --in-reply-to= + --full-index --binary + " -- "$cur")) + return + ;; + esac + __git_complete_revlist +} + _git_ls_remote () { local cur="${COMP_WORDS[COMP_CWORD]}" @@ -303,22 +343,7 @@ _git_ls_tree () _git_log () { - local pfx cur="${COMP_WORDS[COMP_CWORD]}" - case "$cur" in - *...*) - pfx="${cur%...*}..." - cur="${cur#*...}" - COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur")) - ;; - *..*) - pfx="${cur%..*}.." - cur="${cur#*..}" - COMPREPLY=($(compgen -P "$pfx" -W "$(__git_refs)" -- "$cur")) - ;; - *) - COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) - ;; - esac + __git_complete_revlist } _git_merge () @@ -450,6 +475,7 @@ _git () diff) _git_diff ;; diff-tree) _git_diff_tree ;; fetch) _git_fetch ;; + format-patch) _git_format_patch ;; log) _git_log ;; ls-remote) _git_ls_remote ;; ls-tree) _git_ls_tree ;; @@ -480,6 +506,7 @@ complete -o default -F _git_checkout git-checkout complete -o default -o nospace -F _git_diff git-diff complete -o default -F _git_diff_tree git-diff-tree complete -o default -o nospace -F _git_fetch git-fetch +complete -o default -o nospace -F _git_format_patch git-format-patch complete -o default -o nospace -F _git_log git-log complete -o default -F _git_ls_remote git-ls-remote complete -o default -o nospace -F _git_ls_tree git-ls-tree @@ -503,6 +530,7 @@ complete -o default -F _git_branch git-branch.exe complete -o default -o nospace -F _git_cat_file git-cat-file.exe complete -o default -o nospace -F _git_diff git-diff.exe complete -o default -o nospace -F _git_diff_tree git-diff-tree.exe +complete -o default -o nospace -F _git_format_patch git-format-patch.exe complete -o default -o nospace -F _git_log git-log.exe complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe complete -o default -F _git_merge_base git-merge-base.exe From 1273231ee9c7a576a3654d8f2ba77267393564ab Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 03:41:59 -0500 Subject: [PATCH 07/19] Teach bash how to complete git-cherry-pick. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index dfdc3968b8..5582561acd 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -269,6 +269,21 @@ _git_checkout () COMPREPLY=($(compgen -W "-l -b $(__git_refs)" -- "$cur")) } +_git_cherry_pick () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + --*) + COMPREPLY=($(compgen -W " + --edit --no-commit + " -- "$cur")) + ;; + *) + COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) + ;; + esac +} + _git_diff () { __git_complete_file @@ -472,6 +487,7 @@ _git () branch) _git_branch ;; cat-file) _git_cat_file ;; checkout) _git_checkout ;; + cherry-pick) _git_cherry_pick ;; diff) _git_diff ;; diff-tree) _git_diff_tree ;; fetch) _git_fetch ;; @@ -503,6 +519,7 @@ complete -o default -F _gitk gitk complete -o default -F _git_branch git-branch complete -o default -o nospace -F _git_cat_file git-cat-file complete -o default -F _git_checkout git-checkout +complete -o default -F _git_cherry_pick git-cherry-pick complete -o default -o nospace -F _git_diff git-diff complete -o default -F _git_diff_tree git-diff-tree complete -o default -o nospace -F _git_fetch git-fetch From 61d926a3cdb8f03147580de53e448fc22370cbb1 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 03:42:07 -0500 Subject: [PATCH 08/19] Teach bash how to complete git-rebase. As git-rebase is a popular command bash should know how to complete reference names and its long options. We only support completions which make sense given the current state of the repository, that way users don't get shown --continue/--skip/--abort on the first execution. Also added support for long option --strategy to git-merge, as I missed that option earlier and just noticed it while implementing git-rebase. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 38 ++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 5582561acd..9f63ff62f8 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -367,16 +367,16 @@ _git_merge () case "$cur" in --*) COMPREPLY=($(compgen -W " - --no-commit --no-summary --squash + --no-commit --no-summary --squash --strategy " -- "$cur")) return esac - if [ $COMP_CWORD -gt 1 -a X-s = "X${COMP_WORDS[COMP_CWORD-1]}" ] - then + case "${COMP_WORDS[COMP_CWORD-1]}" in + -s|--strategy) COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur")) - else - COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) - fi + return + esac + COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) } _git_merge_base () @@ -443,6 +443,30 @@ _git_push () esac } +_git_rebase () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + if [ -d .dotest ]; then + COMPREPLY=($(compgen -W " + --continue --skip --abort + " -- "$cur")) + return + fi + case "$cur" in + --*) + COMPREPLY=($(compgen -W " + --onto --merge --strategy + " -- "$cur")) + return + esac + case "${COMP_WORDS[COMP_CWORD-1]}" in + -s|--strategy) + COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur")) + return + esac + COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) +} + _git_reset () { local cur="${COMP_WORDS[COMP_CWORD]}" @@ -500,6 +524,7 @@ _git () name-rev) _git_name_rev ;; pull) _git_pull ;; push) _git_push ;; + rebase) _git_rebase ;; reset) _git_reset ;; show) _git_show ;; show-branch) _git_log ;; @@ -532,6 +557,7 @@ complete -o default -F _git_merge_base git-merge-base complete -o default -F _git_name_rev git-name-rev complete -o default -o nospace -F _git_pull git-pull complete -o default -o nospace -F _git_push git-push +complete -o default -F _git_rebase git-rebase complete -o default -F _git_reset git-reset complete -o default -F _git_show git-show complete -o default -o nospace -F _git_log git-show-branch From 6e31b866e4c8e6fc432e6087d56be73c08cf0f83 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 03:42:18 -0500 Subject: [PATCH 09/19] Teach bash about git log/show/whatchanged options. Typing out options to git log/show/whatchanged can take a while, but we can easily complete them with bash. So list the most common ones, especially --pretty=online|short|medium|... so that users don't need to type everything out. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 34 ++++++++++++++++++++------ 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 9f63ff62f8..3852f467d8 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -358,6 +358,29 @@ _git_ls_tree () _git_log () { + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + --pretty=*) + COMPREPLY=($(compgen -W " + oneline short medium full fuller email raw + " -- "${cur##--pretty=}")) + return + ;; + --*) + COMPREPLY=($(compgen -W " + --max-count= --max-age= --since= --after= + --min-age= --before= --until= + --root --not --topo-order --date-order + --no-merges + --abbrev-commit --abbrev= + --relative-date + --author= --committer= --grep= + --all-match + --pretty= --name-status --name-only + " -- "$cur")) + return + ;; + esac __git_complete_revlist } @@ -474,12 +497,6 @@ _git_reset () COMPREPLY=($(compgen -W "$opt $(__git_refs)" -- "$cur")) } -_git_show () -{ - local cur="${COMP_WORDS[COMP_CWORD]}" - COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) -} - _git () { local i c=1 command __git_dir @@ -526,7 +543,7 @@ _git () push) _git_push ;; rebase) _git_rebase ;; reset) _git_reset ;; - show) _git_show ;; + show) _git_log ;; show-branch) _git_log ;; whatchanged) _git_log ;; *) COMPREPLY=() ;; @@ -559,7 +576,7 @@ complete -o default -o nospace -F _git_pull git-pull complete -o default -o nospace -F _git_push git-push complete -o default -F _git_rebase git-rebase complete -o default -F _git_reset git-reset -complete -o default -F _git_show git-show +complete -o default -F _git_log git-show complete -o default -o nospace -F _git_log git-show-branch complete -o default -o nospace -F _git_log git-whatchanged @@ -579,6 +596,7 @@ complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe complete -o default -F _git_merge_base git-merge-base.exe complete -o default -F _git_name_rev git-name-rev.exe complete -o default -o nospace -F _git_push git-push.exe +complete -o default -o nospace -F _git_log git-show.exe complete -o default -o nospace -F _git_log git-show-branch.exe complete -o default -o nospace -F _git_log git-whatchanged.exe fi From 35e65ecca78ceeca8eca72149e7546de94ed8607 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 03:42:32 -0500 Subject: [PATCH 10/19] Support bash completion of refs/remote. Now that people are really likely to start using separate remotes (due to the default in git-clone changing) we should support ref completion for these refs in as many commands as possible. While we are working on this routine we should use for-each-ref to obtain a list of local refs, as this should run faster than peek-remote as it does not need to dereference tag objects in order to produce the list of refs back to us. It should also be more friendly to users of StGIT as we won't generate a list of the StGIT metadata refs. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 3852f467d8..a9c456f61b 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -47,16 +47,26 @@ __git_refs () { local cmd i is_hash=y dir="${1:-$(__gitdir)}" if [ -d "$dir" ]; then - cmd=git-peek-remote - else - cmd=git-ls-remote + if [ -e "$dir/HEAD" ]; then echo HEAD; fi + for i in $(git --git-dir="$dir" \ + for-each-ref --format='%(refname)' \ + refs/tags refs/heads refs/remotes); do + case "$i" in + refs/tags/*) echo "${i#refs/tags/}" ;; + refs/heads/*) echo "${i#refs/heads/}" ;; + refs/remotes/*) echo "${i#refs/remotes/}" ;; + *) echo "$i" ;; + esac + done + return fi - for i in $($cmd "$dir" 2>/dev/null); do + for i in $(git-ls-remote "$dir" 2>/dev/null); do case "$is_hash,$i" in y,*) is_hash=n ;; n,*^{}) is_hash=y ;; n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;; n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;; + n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;; n,*) is_hash=y; echo "$i" ;; esac done From 5de40f59d4954738448e238b06eed72f73cca740 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 04:44:47 -0500 Subject: [PATCH 11/19] Teach bash about git-repo-config. This is a really ugly completion script for git-repo-config, but it has some nice properties. I've added all of the documented configuration parameters from Documentation/config.txt to the script, allowing the user to complete any standard configuration parameter name. We also have some intelligence for the remote.*.* and branch.*.* keys by completing not only the key name (e.g. remote.origin) but also the values (e.g. remote.*.fetch completes to the branches available on the corresponding remote). Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 154 +++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index a9c456f61b..73c67691c9 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -43,6 +43,27 @@ __git_ps1 () fi } +__git_heads () +{ + local cmd i is_hash=y dir="${1:-$(__gitdir)}" + if [ -d "$dir" ]; then + for i in $(git --git-dir="$dir" \ + for-each-ref --format='%(refname)' \ + refs/heads ); do + echo "${i#refs/heads/}" + done + return + fi + for i in $(git-ls-remote "$dir" 2>/dev/null); do + case "$is_hash,$i" in + y,*) is_hash=n ;; + n,*^{}) is_hash=y ;; + n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;; + n,*) is_hash=y; echo "$i" ;; + esac + done +} + __git_refs () { local cmd i is_hash=y dir="${1:-$(__gitdir)}" @@ -91,6 +112,23 @@ __git_refs2 () done } +__git_refs_remotes () +{ + local cmd i is_hash=y + for i in $(git-ls-remote "$1" 2>/dev/null); do + case "$is_hash,$i" in + n,refs/heads/*) + is_hash=y + echo "$i:refs/remotes/$1/${i#refs/heads/}" + ;; + y,*) is_hash=n ;; + n,*^{}) is_hash=y ;; + n,refs/tags/*) is_hash=y;; + n,*) is_hash=y; ;; + esac + done +} + __git_remotes () { local i ngoff IFS=$'\n' d="$(__gitdir)" @@ -500,6 +538,119 @@ _git_rebase () COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) } +_git_repo_config () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + local prv="${COMP_WORDS[COMP_CWORD-1]}" + case "$prv" in + branch.*.remote) + COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur")) + return + ;; + branch.*.merge) + COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) + return + ;; + remote.*.fetch) + local remote="${prv#remote.}" + remote="${remote%.fetch}" + COMPREPLY=($(compgen -W "$(__git_refs_remotes "$remote")" \ + -- "$cur")) + return + ;; + remote.*.push) + local remote="${prv#remote.}" + remote="${remote%.push}" + COMPREPLY=($(compgen -W "$(git --git-dir="$(__gitdir)" \ + for-each-ref --format='%(refname):%(refname)' \ + refs/heads)" -- "$cur")) + return + ;; + *.*) + COMPREPLY=() + return + ;; + esac + case "$cur" in + --*) + COMPREPLY=($(compgen -W " + --global --list --replace-all + --get --get-all --get-regexp + --unset --unset-all + " -- "$cur")) + return + ;; + branch.*.*) + local pfx="${cur%.*}." + cur="${cur##*.}" + COMPREPLY=($(compgen -P "$pfx" -W "remote merge" -- "$cur")) + return + ;; + branch.*) + local pfx="${cur%.*}." + cur="${cur#*.}" + COMPREPLY=($(compgen -P "$pfx" -S . \ + -W "$(__git_heads)" -- "$cur")) + return + ;; + remote.*.*) + local pfx="${cur%.*}." + cur="${cur##*.}" + COMPREPLY=($(compgen -P "$pfx" -W "url fetch push" -- "$cur")) + return + ;; + remote.*) + local pfx="${cur%.*}." + cur="${cur#*.}" + COMPREPLY=($(compgen -P "$pfx" -S . \ + -W "$(__git_remotes)" -- "$cur")) + return + ;; + esac + COMPREPLY=($(compgen -W " + apply.whitespace + core.fileMode + core.gitProxy + core.ignoreStat + core.preferSymlinkRefs + core.logAllRefUpdates + core.repositoryFormatVersion + core.sharedRepository + core.warnAmbiguousRefs + core.compression + core.legacyHeaders + i18n.commitEncoding + diff.color + diff.renameLimit + diff.renames + pager.color + status.color + log.showroot + show.difftree + showbranch.default + whatchanged.difftree + http.sslVerify + http.sslCert + http.sslKey + http.sslCAInfo + http.sslCAPath + http.maxRequests + http.lowSpeedLimit http.lowSpeedTime + http.noEPSV + pack.window + repack.useDeltaBaseOffset + pull.octopus pull.twohead + merge.summary + receive.unpackLimit + receive.denyNonFastForwards + user.name user.email + tar.umask + gitcvs.enabled + gitcvs.logfile + branch. remote. + " -- "$cur")) +} + _git_reset () { local cur="${COMP_WORDS[COMP_CWORD]}" @@ -552,6 +703,7 @@ _git () pull) _git_pull ;; push) _git_push ;; rebase) _git_rebase ;; + repo-config) _git_repo_config ;; reset) _git_reset ;; show) _git_log ;; show-branch) _git_log ;; @@ -585,6 +737,7 @@ complete -o default -F _git_name_rev git-name-rev complete -o default -o nospace -F _git_pull git-pull complete -o default -o nospace -F _git_push git-push complete -o default -F _git_rebase git-rebase +complete -o default -F _git_repo_config git-repo-config complete -o default -F _git_reset git-reset complete -o default -F _git_log git-show complete -o default -o nospace -F _git_log git-show-branch @@ -606,6 +759,7 @@ complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe complete -o default -F _git_merge_base git-merge-base.exe complete -o default -F _git_name_rev git-name-rev.exe complete -o default -o nospace -F _git_push git-push.exe +complete -o default -F _git_repo_config git-repo-config complete -o default -o nospace -F _git_log git-show.exe complete -o default -o nospace -F _git_log git-show-branch.exe complete -o default -o nospace -F _git_log git-whatchanged.exe From ce1e39d29ee373786ceda9e79d0906a6451ab5a5 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 15:10:42 -0500 Subject: [PATCH 12/19] Support --strategy=x completion in addition to --strategy x. Because git-merge and git-rebase both accept -s, --strategy or --strategy= we should recognize all three formats in the bash completion functions and issue back all merge strategies on demand. I also moved the prior word testing to be before the current word testing, as the current word cannot be completed with -- if the prior word was an option which requires a parameter, such as -s or --strategy. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 30 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 73c67691c9..16b8dda17d 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -435,18 +435,23 @@ _git_log () _git_merge () { local cur="${COMP_WORDS[COMP_CWORD]}" + case "${COMP_WORDS[COMP_CWORD-1]}" in + -s|--strategy) + COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur")) + return + esac case "$cur" in + --strategy=*) + COMPREPLY=($(compgen -W "$(__git_merge_strategies)" \ + -- "${cur##--strategy=}")) + return + ;; --*) COMPREPLY=($(compgen -W " --no-commit --no-summary --squash --strategy " -- "$cur")) return esac - case "${COMP_WORDS[COMP_CWORD-1]}" in - -s|--strategy) - COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur")) - return - esac COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) } @@ -523,18 +528,23 @@ _git_rebase () " -- "$cur")) return fi + case "${COMP_WORDS[COMP_CWORD-1]}" in + -s|--strategy) + COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur")) + return + esac case "$cur" in + --strategy=*) + COMPREPLY=($(compgen -W "$(__git_merge_strategies)" \ + -- "${cur##--strategy=}")) + return + ;; --*) COMPREPLY=($(compgen -W " --onto --merge --strategy " -- "$cur")) return esac - case "${COMP_WORDS[COMP_CWORD-1]}" in - -s|--strategy) - COMPREPLY=($(compgen -W "$(__git_merge_strategies)" -- "$cur")) - return - esac COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) } From b51ec6bddb572def384a21a18d5919a488e06ffb Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 15:11:52 -0500 Subject: [PATCH 13/19] Cache the list of merge strategies and available commands during load. Since the user's git installation is not likely to grow a new command or merge strategy in the lifespan of the current shell process we can save time during completion operations by caching these lists during sourcing of the completion support. If the git executable is not available or we run into errors while caching at load time then we defer these to runtime and generate the list on the fly. This might happen if the user doesn't put git into their PATH until after the completion script gets sourced. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 16b8dda17d..902f80b937 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -18,7 +18,13 @@ # 2) Added the following line to your .bashrc: # source ~/.git-completion.sh # -# 3) Consider changing your PS1 to also show the current branch: +# 3) You may want to make sure the git executable is available +# in your PATH before this script is sourced, as some caching +# is performed while the script loads. If git isn't found +# at source time then all lookups will be done on demand, +# which may be slightly slower. +# +# 4) Consider changing your PS1 to also show the current branch: # PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' # # The argument to __git_ps1 will be displayed only if you @@ -150,6 +156,10 @@ __git_remotes () __git_merge_strategies () { + if [ -n "$__git_merge_strategylist" ]; then + echo "$__git_merge_strategylist" + return + fi sed -n "/^all_strategies='/{ s/^all_strategies='// s/'// @@ -157,6 +167,8 @@ __git_merge_strategies () q }" "$(git --exec-path)/git-merge" } +__git_merge_strategylist= +__git_merge_strategylist="$(__git_merge_strategies 2>/dev/null)" __git_complete_file () { @@ -214,6 +226,10 @@ __git_complete_revlist () __git_commands () { + if [ -n "$__git_commandlist" ]; then + echo "$__git_commandlist" + return + fi local i IFS=" "$'\n' for i in $(git help -a|egrep '^ ') do @@ -263,6 +279,8 @@ __git_commands () esac done } +__git_commandlist= +__git_commandlist="$(__git_commands 2>/dev/null)" __git_aliases () { From 88329195159865c0fcc57a6017c959d13d7a1ad6 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 27 Nov 2006 15:12:03 -0500 Subject: [PATCH 14/19] Teach bash about git-am/git-apply and their whitespace options. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 53 ++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 902f80b937..d8ae4d7886 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -307,6 +307,54 @@ __git_aliased_command () done } +__git_whitespacelist="nowarn warn error error-all strip" + +_git_am () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + if [ -d .dotest ]; then + COMPREPLY=($(compgen -W " + --skip --resolved + " -- "$cur")) + return + fi + case "$cur" in + --whitespace=*) + COMPREPLY=($(compgen -W "$__git_whitespacelist" \ + -- "${cur##--whitespace=}")) + return + ;; + --*) + COMPREPLY=($(compgen -W " + --signoff --utf8 --binary --3way --interactive + --whitespace= + " -- "$cur")) + return + esac + COMPREPLY=() +} + +_git_apply () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + --whitespace=*) + COMPREPLY=($(compgen -W "$__git_whitespacelist" \ + -- "${cur##--whitespace=}")) + return + ;; + --*) + COMPREPLY=($(compgen -W " + --stat --numstat --summary --check --index + --cached --index-info --reverse --reject --unidiff-zero + --apply --no-add --exclude= + --whitespace= --inaccurate-eof --verbose + " -- "$cur")) + return + esac + COMPREPLY=() +} + _git_branch () { local cur="${COMP_WORDS[COMP_CWORD]}" @@ -714,6 +762,8 @@ _git () [ "$expansion" ] && command="$expansion" case "$command" in + am) _git_am ;; + apply) _git_apply ;; branch) _git_branch ;; cat-file) _git_cat_file ;; checkout) _git_checkout ;; @@ -748,6 +798,8 @@ _gitk () complete -o default -o nospace -F _git git complete -o default -F _gitk gitk +complete -o default -F _git_am git-am +complete -o default -F _git_apply git-apply complete -o default -F _git_branch git-branch complete -o default -o nospace -F _git_cat_file git-cat-file complete -o default -F _git_checkout git-checkout @@ -776,6 +828,7 @@ complete -o default -o nospace -F _git_log git-whatchanged # included the '.exe' suffix. # if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then +complete -o default -F _git_apply git-apply.exe complete -o default -o nospace -F _git git.exe complete -o default -F _git_branch git-branch.exe complete -o default -o nospace -F _git_cat_file git-cat-file.exe From 6f23ebf600188fe4246c2fb118f0c977ba1a2ed6 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 27 Nov 2006 13:20:53 -0800 Subject: [PATCH 15/19] git-svn: use ~/.subversion config files when using SVN:: libraries This allows users to use HTTP proxy information (among other settings) from ~/.subversion/servers and ~/.subversion/config --config-dir (as before) may be passed to git-svn to override the default choice of '~/.subversion' for the configuration directory. Thanks to tko on #git for pointing this out. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/git-svn.perl b/git-svn.perl index de4e74a60d..d5d9c49fd6 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -2822,7 +2822,9 @@ sub libsvn_connect { SVN::Client::get_username_prompt_provider( \&_username_prompt, 2), ]); + my $config = SVN::Core::config_get_config($_config_dir); my $ra = SVN::Ra->new(url => $url, auth => $baton, + config => $config, pool => SVN::Pool->new, auth_provider_callbacks => $callbacks); $ra->{svn_path} = $url; @@ -2834,8 +2836,8 @@ sub libsvn_connect { sub libsvn_dup_ra { my ($ra) = @_; - SVN::Ra->new(map { $_ => $ra->{$_} } - qw/url auth auth_provider_callbacks repos_root svn_path/); + SVN::Ra->new(map { $_ => $ra->{$_} } qw/config url + auth auth_provider_callbacks repos_root svn_path/); } sub libsvn_get_file { From 86d11cf264c55d570484cbdfff073092c77a6342 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 27 Nov 2006 14:21:30 -0800 Subject: [PATCH 16/19] cvsimport: style fixup. This should not change any functionality, but just makes it readable by having a space between syntactic construct keyword and open parenthesis (e.g. "if (expr", not "if(expr") and between close parenthesis and open brace (e.g. "if (expr) {" not "if (expr){"). Signed-off-by: Junio C Hamano --- git-cvsimport.perl | 168 ++++++++++++++++++++++----------------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/git-cvsimport.perl b/git-cvsimport.perl index 4310dea132..c5bf2d19cd 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -29,7 +29,7 @@ use IPC::Open2; $SIG{'PIPE'}="IGNORE"; $ENV{'TZ'}="UTC"; -our($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S,$opt_L); +our ($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S,$opt_L); my (%conv_author_name, %conv_author_email); sub usage() { @@ -90,15 +90,15 @@ usage if $opt_h; @ARGV <= 1 or usage(); -if($opt_d) { +if ($opt_d) { $ENV{"CVSROOT"} = $opt_d; -} elsif(-f 'CVS/Root') { +} elsif (-f 'CVS/Root') { open my $f, '<', 'CVS/Root' or die 'Failed to open CVS/Root'; $opt_d = <$f>; chomp $opt_d; close $f; $ENV{"CVSROOT"} = $opt_d; -} elsif($ENV{"CVSROOT"}) { +} elsif ($ENV{"CVSROOT"}) { $opt_d = $ENV{"CVSROOT"}; } else { die "CVSROOT needs to be set"; @@ -141,7 +141,7 @@ use File::Temp qw(tempfile); use POSIX qw(strftime dup2); sub new { - my($what,$repo,$subdir) = @_; + my ($what,$repo,$subdir) = @_; $what=ref($what) if ref($what); my $self = {}; @@ -161,38 +161,38 @@ sub new { sub conn { my $self = shift; my $repo = $self->{'fullrep'}; - if($repo =~ s/^:pserver(?:([^:]*)):(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?//) { - my($param,$user,$pass,$serv,$port) = ($1,$2,$3,$4,$5); + if ($repo =~ s/^:pserver(?:([^:]*)):(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?//) { + my ($param,$user,$pass,$serv,$port) = ($1,$2,$3,$4,$5); - my($proxyhost,$proxyport); - if($param && ($param =~ m/proxy=([^;]+)/)) { + my ($proxyhost,$proxyport); + if ($param && ($param =~ m/proxy=([^;]+)/)) { $proxyhost = $1; # Default proxyport, if not specified, is 8080. $proxyport = 8080; - if($ENV{"CVS_PROXY_PORT"}) { + if ($ENV{"CVS_PROXY_PORT"}) { $proxyport = $ENV{"CVS_PROXY_PORT"}; } - if($param =~ m/proxyport=([^;]+)/){ + if ($param =~ m/proxyport=([^;]+)/) { $proxyport = $1; } } $user="anonymous" unless defined $user; my $rr2 = "-"; - unless($port) { + unless ($port) { $rr2 = ":pserver:$user\@$serv:$repo"; $port=2401; } my $rr = ":pserver:$user\@$serv:$port$repo"; - unless($pass) { + unless ($pass) { open(H,$ENV{'HOME'}."/.cvspass") and do { # :pserver:cvs@mea.tmt.tele.fi:/cvsroot/zmailer Ah) { + while () { chomp; s/^\/\d+\s+//; my ($w,$p) = split(/\s/,$_,2); - if($w eq $rr or $w eq $rr2) { + if ($w eq $rr or $w eq $rr2) { $pass = $p; last; } @@ -202,7 +202,7 @@ sub conn { $pass="A" unless $pass; my ($s, $rep); - if($proxyhost) { + if ($proxyhost) { # Use a HTTP Proxy. Only works for HTTP proxies that # don't require user authentication @@ -218,7 +218,7 @@ sub conn { $rep = <$s>; # The answer should look like 'HTTP/1.x 2yy ....' - if(!($rep =~ m#^HTTP/1\.. 2[0-9][0-9]#)) { + if (!($rep =~ m#^HTTP/1\.. 2[0-9][0-9]#)) { die "Proxy connect: $rep\n"; } # Skip up to the empty line of the proxy server output @@ -239,7 +239,7 @@ sub conn { $rep = <$s>; - if($rep ne "I LOVE YOU\n") { + if ($rep ne "I LOVE YOU\n") { $rep="" unless $rep; die "AuthReply: $rep\n"; } @@ -271,7 +271,7 @@ sub conn { } } - unless($pid) { + unless ($pid) { $pr->writer(); $pw->reader(); dup2($pw->fileno(),0); @@ -294,7 +294,7 @@ sub conn { $self->{'socketo'}->flush(); chomp(my $rep=$self->readline()); - if($rep !~ s/^Valid-requests\s*//) { + if ($rep !~ s/^Valid-requests\s*//) { $rep="" unless $rep; die "Expected Valid-requests from server, but got: $rep\n"; } @@ -306,14 +306,14 @@ sub conn { } sub readline { - my($self) = @_; + my ($self) = @_; return $self->{'socketi'}->getline(); } sub _file { # Request a file with a given revision. # Trial and error says this is a good way to do it. :-/ - my($self,$fn,$rev) = @_; + my ($self,$fn,$rev) = @_; $self->{'socketo'}->write("Argument -N\n") or return undef; $self->{'socketo'}->write("Argument -P\n") or return undef; # -kk: Linus' version doesn't use it - defaults to off @@ -335,12 +335,12 @@ sub _file { sub _line { # Read a line from the server. # ... except that 'line' may be an entire file. ;-) - my($self, $fh) = @_; + my ($self, $fh) = @_; die "Not in lines" unless defined $self->{'lines'}; my $line; my $res=0; - while(defined($line = $self->readline())) { + while (defined($line = $self->readline())) { # M U gnupg-cvs-rep/AUTHORS # Updated gnupg-cvs-rep/ # /daten/src/rsync/gnupg-cvs-rep/AUTHORS @@ -349,7 +349,7 @@ sub _line { # 0 # ok - if($line =~ s/^(?:Created|Updated) //) { + if ($line =~ s/^(?:Created|Updated) //) { $line = $self->readline(); # path $line = $self->readline(); # Entries line my $mode = $self->readline(); chomp $mode; @@ -360,12 +360,12 @@ sub _line { die "Duh: Filesize $cnt" if $cnt !~ /^\d+$/; $line=""; $res = $self->_fetchfile($fh, $cnt); - } elsif($line =~ s/^ //) { + } elsif ($line =~ s/^ //) { print $fh $line; $res += length($line); - } elsif($line =~ /^M\b/) { + } elsif ($line =~ /^M\b/) { # output, do nothing - } elsif($line =~ /^Mbinary\b/) { + } elsif ($line =~ /^Mbinary\b/) { my $cnt; die "EOF from server after 'Mbinary'" unless defined ($cnt = $self->readline()); chomp $cnt; @@ -374,12 +374,12 @@ sub _line { $res += $self->_fetchfile($fh, $cnt); } else { chomp $line; - if($line eq "ok") { + if ($line eq "ok") { # print STDERR "S: ok (".length($res).")\n"; return $res; - } elsif($line =~ s/^E //) { + } elsif ($line =~ s/^E //) { # print STDERR "S: $line\n"; - } elsif($line =~ /^(Remove-entry|Removed) /i) { + } elsif ($line =~ /^(Remove-entry|Removed) /i) { $line = $self->readline(); # filename $line = $self->readline(); # OK chomp $line; @@ -393,7 +393,7 @@ sub _line { return undef; } sub file { - my($self,$fn,$rev) = @_; + my ($self,$fn,$rev) = @_; my $res; my ($fh, $name) = tempfile('gitcvs.XXXXXX', @@ -417,7 +417,7 @@ sub _fetchfile { my ($self, $fh, $cnt) = @_; my $res = 0; my $bufsize = 1024 * 1024; - while($cnt) { + while ($cnt) { if ($bufsize > $cnt) { $bufsize = $cnt; } @@ -438,7 +438,7 @@ my $cvs = CVSconn->new($opt_d, $cvs_tree); sub pdate($) { - my($d) = @_; + my ($d) = @_; m#(\d{2,4})/(\d\d)/(\d\d)\s(\d\d):(\d\d)(?::(\d\d))?# or die "Unparseable date: $d\n"; my $y=$1; $y-=1900 if $y>1900; @@ -446,22 +446,22 @@ sub pdate($) { } sub pmode($) { - my($mode) = @_; + my ($mode) = @_; my $m = 0; my $mm = 0; my $um = 0; for my $x(split(//,$mode)) { - if($x eq ",") { + if ($x eq ",") { $m |= $mm&$um; $mm = 0; $um = 0; - } elsif($x eq "u") { $um |= 0700; - } elsif($x eq "g") { $um |= 0070; - } elsif($x eq "o") { $um |= 0007; - } elsif($x eq "r") { $mm |= 0444; - } elsif($x eq "w") { $mm |= 0222; - } elsif($x eq "x") { $mm |= 0111; - } elsif($x eq "=") { # do nothing + } elsif ($x eq "u") { $um |= 0700; + } elsif ($x eq "g") { $um |= 0070; + } elsif ($x eq "o") { $um |= 0007; + } elsif ($x eq "r") { $mm |= 0444; + } elsif ($x eq "w") { $mm |= 0222; + } elsif ($x eq "x") { $mm |= 0111; + } elsif ($x eq "=") { # do nothing } else { die "Unknown mode: $mode\n"; } } @@ -485,7 +485,7 @@ sub get_headref ($$) { my $git_dir = shift; my $f = "$git_dir/refs/heads/$name"; - if(open(my $fh, $f)) { + if (open(my $fh, $f)) { chomp(my $r = <$fh>); is_sha1($r) or die "Cannot get head id for $name ($r): $!"; return $r; @@ -512,7 +512,7 @@ $orig_git_index = $ENV{GIT_INDEX_FILE} if exists $ENV{GIT_INDEX_FILE}; my %index; # holds filenames of one index per branch -unless(-d $git_dir) { +unless (-d $git_dir) { system("git-init-db"); die "Cannot init the GIT db at $git_tree: $?\n" if $?; system("git-read-tree"); @@ -531,7 +531,7 @@ unless(-d $git_dir) { chomp ($last_branch = ); $last_branch = basename($last_branch); close(F); - unless($last_branch) { + unless ($last_branch) { warn "Cannot read the last branch name: $! -- assuming 'master'\n"; $last_branch = "master"; } @@ -542,7 +542,7 @@ unless(-d $git_dir) { my $fmt = '($ref, $author) = (%(refname), %(author));'; open(H, "git-for-each-ref --perl --format='$fmt' refs/heads |") or die "Cannot run git-for-each-ref: $!\n"; - while(defined(my $entry = )) { + while (defined(my $entry = )) { my ($ref, $author); eval($entry) || die "cannot eval refs list: $@"; my ($head) = ($ref =~ m|^refs/heads/(.*)|); @@ -572,7 +572,7 @@ unless ($opt_P) { print "Running cvsps...\n" if $opt_v; my $pid = open(CVSPS,"-|"); die "Cannot fork: $!\n" unless defined $pid; - unless($pid) { + unless ($pid) { my @opt; @opt = split(/,/,$opt_p) if defined $opt_p; unshift @opt, '-z', $opt_z if defined $opt_z; @@ -642,8 +642,8 @@ sub write_tree () { return $tree; } -my($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg); -my(@old,@new,@skipped,%ignorebranch); +my ($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg); +my (@old,@new,@skipped,%ignorebranch); # commits that cvsps cannot place anywhere... $ignorebranch{'#CVSPS_NO_BRANCH'} = 1; @@ -684,7 +684,7 @@ sub commit { foreach my $rx (@mergerx) { next unless $logmsg =~ $rx && $1; my $mparent = $1 eq 'HEAD' ? $opt_o : $1; - if(my $sha1 = get_headref($mparent, $git_dir)) { + if (my $sha1 = get_headref($mparent, $git_dir)) { push @commit_args, '-p', $mparent; print "Merge parent branch: $mparent\n" if $opt_v; } @@ -725,9 +725,9 @@ sub commit { system("git-update-ref refs/heads/$branch $cid") == 0 or die "Cannot write branch $branch for update: $!\n"; - if($tag) { - my($in, $out) = ('',''); - my($xtag) = $tag; + if ($tag) { + my ($in, $out) = ('',''); + my ($xtag) = $tag; $xtag =~ s/\s+\*\*.*$//; # Remove stuff like ** INVALID ** and ** FUNKY ** $xtag =~ tr/_/\./ if ( $opt_u ); $xtag =~ s/[\/]/$opt_s/g; @@ -762,25 +762,25 @@ sub commit { }; my $commitcount = 1; -while() { +while () { chomp; - if($state == 0 and /^-+$/) { + if ($state == 0 and /^-+$/) { $state = 1; - } elsif($state == 0) { + } elsif ($state == 0) { $state = 1; redo; - } elsif(($state==0 or $state==1) and s/^PatchSet\s+//) { + } elsif (($state==0 or $state==1) and s/^PatchSet\s+//) { $patchset = 0+$_; $state=2; - } elsif($state == 2 and s/^Date:\s+//) { + } elsif ($state == 2 and s/^Date:\s+//) { $date = pdate($_); - unless($date) { + unless ($date) { print STDERR "Could not parse date: $_\n"; $state=0; next; } $state=3; - } elsif($state == 3 and s/^Author:\s+//) { + } elsif ($state == 3 and s/^Author:\s+//) { s/\s+$//; if (/^(.*?)\s+<(.*)>/) { ($author_name, $author_email) = ($1, $2); @@ -791,34 +791,34 @@ while() { $author_name = $author_email = $_; } $state = 4; - } elsif($state == 4 and s/^Branch:\s+//) { + } elsif ($state == 4 and s/^Branch:\s+//) { s/\s+$//; s/[\/]/$opt_s/g; $branch = $_; $state = 5; - } elsif($state == 5 and s/^Ancestor branch:\s+//) { + } elsif ($state == 5 and s/^Ancestor branch:\s+//) { s/\s+$//; $ancestor = $_; $ancestor = $opt_o if $ancestor eq "HEAD"; $state = 6; - } elsif($state == 5) { + } elsif ($state == 5) { $ancestor = undef; $state = 6; redo; - } elsif($state == 6 and s/^Tag:\s+//) { + } elsif ($state == 6 and s/^Tag:\s+//) { s/\s+$//; - if($_ eq "(none)") { + if ($_ eq "(none)") { $tag = undef; } else { $tag = $_; } $state = 7; - } elsif($state == 7 and /^Log:/) { + } elsif ($state == 7 and /^Log:/) { $logmsg = ""; $state = 8; - } elsif($state == 8 and /^Members:/) { + } elsif ($state == 8 and /^Members:/) { $branch = $opt_o if $branch eq "HEAD"; - if(defined $branch_date{$branch} and $branch_date{$branch} >= $date) { + if (defined $branch_date{$branch} and $branch_date{$branch} >= $date) { # skip print "skip patchset $patchset: $date before $branch_date{$branch}\n" if $opt_v; $state = 11; @@ -829,17 +829,17 @@ while() { $state = 11; next; } - if($ancestor) { - if($ancestor eq $branch) { + if ($ancestor) { + if ($ancestor eq $branch) { print STDERR "Branch $branch erroneously stems from itself -- changed ancestor to $opt_o\n"; $ancestor = $opt_o; } - if(-f "$git_dir/refs/heads/$branch") { + if (-f "$git_dir/refs/heads/$branch") { print STDERR "Branch $branch already exists!\n"; $state=11; next; } - unless(open(H,"$git_dir/refs/heads/$ancestor")) { + unless (open(H,"$git_dir/refs/heads/$ancestor")) { print STDERR "Branch $ancestor does not exist!\n"; $ignorebranch{$branch} = 1; $state=11; @@ -847,7 +847,7 @@ while() { } chomp(my $id = ); close(H); - unless(open(H,"> $git_dir/refs/heads/$branch")) { + unless (open(H,"> $git_dir/refs/heads/$branch")) { print STDERR "Could not create branch $branch: $!\n"; $ignorebranch{$branch} = 1; $state=11; @@ -860,9 +860,9 @@ while() { } $last_branch = $branch if $branch ne $last_branch; $state = 9; - } elsif($state == 8) { + } elsif ($state == 8) { $logmsg .= "$_\n"; - } elsif($state == 9 and /^\s+(.+?):(INITIAL|\d+(?:\.\d+)+)->(\d+(?:\.\d+)+)\s*$/) { + } elsif ($state == 9 and /^\s+(.+?):(INITIAL|\d+(?:\.\d+)+)->(\d+(?:\.\d+)+)\s*$/) { # VERSION:1.96->1.96.2.1 my $init = ($2 eq "INITIAL"); my $fn = $1; @@ -875,7 +875,7 @@ while() { } print "Fetching $fn v $rev\n" if $opt_v; my ($tmpname, $size) = $cvs->file($fn,$rev); - if($size == -1) { + if ($size == -1) { push(@old,$fn); print "Drop $fn\n" if $opt_v; } else { @@ -893,14 +893,14 @@ while() { push(@new,[$mode, $sha, $fn]); # may be resurrected! } unlink($tmpname); - } elsif($state == 9 and /^\s+(.+?):\d+(?:\.\d+)+->(\d+(?:\.\d+)+)\(DEAD\)\s*$/) { + } elsif ($state == 9 and /^\s+(.+?):\d+(?:\.\d+)+->(\d+(?:\.\d+)+)\(DEAD\)\s*$/) { my $fn = $1; $fn =~ s#^/+##; push(@old,$fn); print "Delete $fn\n" if $opt_v; - } elsif($state == 9 and /^\s*$/) { + } elsif ($state == 9 and /^\s*$/) { $state = 10; - } elsif(($state == 9 or $state == 10) and /^-+$/) { + } elsif (($state == 9 or $state == 10) and /^-+$/) { $commitcount++; if ($opt_L && $commitcount > $opt_L) { last; @@ -910,11 +910,11 @@ while() { system("git repack -a -d"); } $state = 1; - } elsif($state == 11 and /^-+$/) { + } elsif ($state == 11 and /^-+$/) { $state = 1; - } elsif(/^-+$/) { # end of unknown-line processing + } elsif (/^-+$/) { # end of unknown-line processing $state = 1; - } elsif($state != 11) { # ignore stuff when skipping + } elsif ($state != 11) { # ignore stuff when skipping print "* UNKNOWN LINE * $_\n"; } } @@ -943,7 +943,7 @@ if (defined $orig_git_index) { } # Now switch back to the branch we were in before all of this happened -if($orig_branch) { +if ($orig_branch) { print "DONE.\n" if $opt_v; if ($opt_i) { exit 0; From 1d541c120b4de5c70e73f8a20e1d961324cc55fe Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 28 Nov 2006 00:29:21 +0100 Subject: [PATCH 17/19] shortlog: use pager On request of the kingpenguin, shortlog now uses the pager if output goes to a tty. Signed-off-by: Johannes Schindelin 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 f97de602d2..357330e02c 100644 --- a/git.c +++ b/git.c @@ -260,7 +260,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "rev-parse", cmd_rev_parse, RUN_SETUP }, { "rm", cmd_rm, RUN_SETUP }, { "runstatus", cmd_runstatus, RUN_SETUP }, - { "shortlog", cmd_shortlog, RUN_SETUP }, + { "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER }, { "show-branch", cmd_show_branch, RUN_SETUP }, { "show", cmd_show, RUN_SETUP | USE_PAGER }, { "stripspace", cmd_stripspace }, From f0df4ed5629c25e9978708115ad654b9f83f55df Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 28 Nov 2006 00:18:55 +0100 Subject: [PATCH 18/19] sha1_object_info(): be consistent with read_sha1_file() We used to try loose objects first with sha1_object_info(), but packed objects first with read_sha1_file(). Now, prefer packed objects over loose ones with sha1_object_info(), too. Usually the old behaviour would pose no problem, but when you tried to fix a fscked up repository by inserting a known-good pack, git cat-file $(git cat-file -t ) could fail, even when git cat-file blob would _not_ fail. Worse, a repack would fail, too. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- sha1_file.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 09456d23f8..63f416bb5a 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1261,7 +1261,7 @@ struct packed_git *find_sha1_pack(const unsigned char *sha1, } -int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep) +static int sha1_loose_object_info(const unsigned char *sha1, char *type, unsigned long *sizep) { int status; unsigned long mapsize, size; @@ -1270,20 +1270,8 @@ int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep char hdr[128]; map = map_sha1_file(sha1, &mapsize); - if (!map) { - struct pack_entry e; - - if (!find_pack_entry(sha1, &e, NULL)) { - reprepare_packed_git(); - if (!find_pack_entry(sha1, &e, NULL)) - return error("unable to find %s", sha1_to_hex(sha1)); - } - if (use_packed_git(e.p)) - die("cannot map packed file"); - status = packed_object_info(e.p, e.offset, type, sizep); - unuse_packed_git(e.p); - return status; - } + if (!map) + return error("unable to find %s", sha1_to_hex(sha1)); if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0) status = error("unable to unpack %s header", sha1_to_hex(sha1)); @@ -1299,6 +1287,23 @@ int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep return status; } +int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep) +{ + int status; + struct pack_entry e; + + if (!find_pack_entry(sha1, &e, NULL)) { + reprepare_packed_git(); + if (!find_pack_entry(sha1, &e, NULL)) + return sha1_loose_object_info(sha1, type, sizep); + } + if (use_packed_git(e.p)) + die("cannot map packed file"); + status = packed_object_info(e.p, e.offset, type, sizep); + unuse_packed_git(e.p); + return status; +} + static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned long *size) { struct pack_entry e; From 255cae88bcc8fcb0088459df13b55fa3d311b9e2 Mon Sep 17 00:00:00 2001 From: Andy Parkins Date: Sun, 26 Nov 2006 12:10:52 +0000 Subject: [PATCH 19/19] Use .git/config for storing "origin" shortcut repository Rather than use a separate config .git/remotes/ for remote shortcuts, this patch adds the analagous definitions to .git/config using git-repo-config calls. For example what was previously .git/remotes/origin URL: proto://host/path Pull: refs/heads/master:refs/heads/origin Is now added to .git/config as [remote "origin"] url = proto://host/path fetch = refs/heads/master:refs/heads/origin Signed-off-by: Andy Parkins Signed-off-by: Junio C Hamano --- git-clone.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/git-clone.sh b/git-clone.sh index d4ee93f75b..b2d0f08e67 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -377,9 +377,9 @@ then *) origin_track="$remote_top/$origin" git-update-ref "refs/heads/$origin" "$head_sha1" ;; esac && - echo >"$GIT_DIR/remotes/$origin" \ - "URL: $repo -Pull: refs/heads/$head_points_at:$origin_track" && + git-repo-config remote."$origin".url "$repo" && + git-repo-config remote."$origin".fetch \ + "refs/heads/$head_points_at:$origin_track" && (cd "$GIT_DIR/$remote_top" && find . -type f -print) | while read dotslref do @@ -393,8 +393,8 @@ Pull: refs/heads/$head_points_at:$origin_track" && then continue fi - echo "Pull: refs/heads/${name}:$remote_top/${name}" - done >>"$GIT_DIR/remotes/$origin" && + git-repo-config remote."$origin".fetch "refs/heads/${name}:$remote_top/${name}" '^$' + done && case "$use_separate_remote" in t) rm -f "refs/remotes/$origin/HEAD"