diff options
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/buildsystems/engine.pl | 9 | ||||
-rw-r--r-- | contrib/ciabot/README | 12 | ||||
-rwxr-xr-x | contrib/ciabot/ciabot.py | 222 | ||||
-rwxr-xr-x | contrib/ciabot/ciabot.sh | 192 | ||||
-rwxr-xr-x | contrib/completion/git-completion.bash | 294 | ||||
-rwxr-xr-x | contrib/examples/git-commit.sh | 2 | ||||
-rwxr-xr-x | contrib/examples/git-fetch.sh | 4 | ||||
-rwxr-xr-x | contrib/examples/git-merge.sh | 3 | ||||
-rwxr-xr-x | contrib/examples/git-notes.sh | 121 | ||||
-rwxr-xr-x | contrib/fast-import/git-p4 | 11 | ||||
-rwxr-xr-x | contrib/fast-import/import-directories.perl | 2 | ||||
-rwxr-xr-x | contrib/fast-import/import-zips.py | 2 | ||||
-rwxr-xr-x | contrib/git-resurrect.sh | 1 | ||||
-rwxr-xr-x | contrib/hg-to-git/hg-to-git.py | 10 | ||||
-rwxr-xr-x | contrib/hooks/post-receive-email | 9 | ||||
-rw-r--r-- | contrib/p4import/git-p4import.py | 2 | ||||
-rw-r--r-- | contrib/svn-fe/.gitignore | 4 | ||||
-rw-r--r-- | contrib/svn-fe/Makefile | 63 | ||||
-rw-r--r-- | contrib/svn-fe/svn-fe.c | 15 | ||||
-rw-r--r-- | contrib/svn-fe/svn-fe.txt | 66 | ||||
-rwxr-xr-x | contrib/workdir/git-new-workdir | 4 |
21 files changed, 948 insertions, 100 deletions
diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index d506717bfd..23da787dc5 100644 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -135,6 +135,11 @@ sub parseMakeOutput } } while($ate_next); + if ($text =~ /^test /) { + # options to test (eg -o) may be mistaken for linker options + next; + } + if($text =~ / -c /) { # compilation handleCompileLine($text, $line); @@ -180,9 +185,6 @@ sub parseMakeOutput # } elsif ($text =~ /generate-cmdlist\.sh/) { # # command for generating list of commands # -# } elsif ($text =~ /^test / && $text =~ /|| rm -f /) { -# # commands removing executables, if they exist -# # } elsif ($text =~ /new locations or Tcl/) { # # command for detecting Tcl/Tk changes # @@ -317,6 +319,7 @@ sub handleLinkLine push(@libs, "zlib.lib"); } elsif ("$part" eq "-lcrypto") { push(@libs, "libeay32.lib"); + } elsif ("$part" eq "-lssl") { push(@libs, "ssleay32.lib"); } elsif ($part =~ /^-/) { push(@lflags, $part); diff --git a/contrib/ciabot/README b/contrib/ciabot/README new file mode 100644 index 0000000000..3b916acece --- /dev/null +++ b/contrib/ciabot/README @@ -0,0 +1,12 @@ +These are hook scripts for the CIA notification service at <http://cia.vc/> + +They are maintained by Eric S. Raymond <esr@thyrsus.com>. There is an +upstream resource page for them at <http://www.catb.org/esr/ciabot/>, +but they are unlikely to change rapidly. + +You probably want the Python version; it's faster, more capable, and +better documented. The shell version is maintained only as a fallback +for use on hosting sites that don't permit Python hook scripts. + +You will find installation instructions for each script in its comment +header. diff --git a/contrib/ciabot/ciabot.py b/contrib/ciabot/ciabot.py new file mode 100755 index 0000000000..d0627e0852 --- /dev/null +++ b/contrib/ciabot/ciabot.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python +# Copyright (c) 2010 Eric S. Raymond <esr@thyrsus.com> +# Distributed under BSD terms. +# +# This script contains porcelain and porcelain byproducts. +# It's Python because the Python standard libraries avoid portability/security +# issues raised by callouts in the ancestral Perl and sh scripts. It should +# be compatible back to Python 2.1.5 +# +# usage: ciabot.py [-V] [-n] [-p projectname] [refname [commits...]] +# +# This script is meant to be run either in a post-commit hook or in an +# update hook. If there's nothing unusual about your hosting setup, +# you can specify the project name with a -p option and avoid having +# to modify this script. Try it with -n to see the notification mail +# dumped to stdout and verify that it looks sane. With -V it dumps its +# version and exits. +# +# In post-commit, run it without arguments (other than possibly a -p +# option). It will query for current HEAD and the latest commit ID to +# get the information it needs. +# +# In update, call it with a refname followed by a list of commits: +# You want to reverse the order git rev-list emits becxause it lists +# from most recent to oldest. +# +# /path/to/ciabot.py ${refname} $(git rev-list ${oldhead}..${newhead} | tac) +# +# Note: this script uses mail, not XML-RPC, in order to avoid stalling +# until timeout when the CIA XML-RPC server is down. +# + +# +# The project as known to CIA. You will either want to change this +# or invoke the script with a -p option to set it. +# +project=None + +# +# You may not need to change these: +# +import os, sys, commands, socket, urllib + +# Name of the repository. +# You can hardwire this to make the script faster. +repo = os.path.basename(os.getcwd()) + +# Fully-qualified domain name of this host. +# You can hardwire this to make the script faster. +host = socket.getfqdn() + +# Changeset URL prefix for your repo: when the commit ID is appended +# to this, it should point at a CGI that will display the commit +# through gitweb or something similar. The defaults will probably +# work if you have a typical gitweb/cgit setup. +# +#urlprefix="http://%(host)s/cgi-bin/gitweb.cgi?p=%(repo)s;a=commit;h=" +urlprefix="http://%(host)s/cgi-bin/cgit.cgi/%(repo)s/commit/?id=" + +# The service used to turn your gitwebbish URL into a tinyurl so it +# will take up less space on the IRC notification line. +tinyifier = "http://tinyurl.com/api-create.php?url=" + +# The template used to generate the XML messages to CIA. You can make +# visible changes to the IRC-bot notification lines by hacking this. +# The default will produce a notfication line that looks like this: +# +# ${project}: ${author} ${repo}:${branch} * ${rev} ${files}: ${logmsg} ${url} +# +# By omitting $files you can collapse the files part to a single slash. +xml = '''\ +<message> + <generator> + <name>CIA Python client for Git</name> + <version>%(gitver)s</version> + <url>%(generator)s</url> + </generator> + <source> + <project>%(project)s</project> + <branch>%(repo)s:%(branch)s</branch> + </source> + <timestamp>%(ts)s</timestamp> + <body> + <commit> + <author>%(author)s</author> + <revision>%(rev)s</revision> + <files> + %(files)s + </files> + <log>%(logmsg)s %(url)s</log> + <url>%(url)s</url> + </commit> + </body> +</message> +''' + +# +# No user-serviceable parts below this line: +# + +# Addresses for the e-mail. The from address is a dummy, since CIA +# will never reply to this mail. +fromaddr = "CIABOT-NOREPLY@" + host +toaddr = "cia@cia.navi.cx" + +# Identify the generator script. +# Should only change when the script itself gets a new home and maintainer. +generator="http://www.catb.org/~esr/ciabot.py" + +def do(command): + return commands.getstatusoutput(command)[1] + +def report(refname, merged): + "Generate a commit notification to be reported to CIA" + + # Try to tinyfy a reference to a web view for this commit. + try: + url = open(urllib.urlretrieve(tinyifier + urlprefix + merged)[0]).read() + except: + url = urlprefix + merged + + branch = os.path.basename(refname) + + # Compute a shortnane for the revision + rev = do("git describe ${merged} 2>/dev/null") or merged[:12] + + # Extract the neta-information for the commit + rawcommit = do("git cat-file commit " + merged) + files=do("git diff-tree -r --name-only '"+ merged +"' | sed -e '1d' -e 's-.*-<file>&</file>-'") + inheader = True + headers = {} + logmsg = "" + for line in rawcommit.split("\n"): + if inheader: + if line: + fields = line.split() + headers[fields[0]] = " ".join(fields[1:]) + else: + inheader = False + else: + logmsg = line + break + (author, ts) = headers["author"].split(">") + + # This discards the part of the authors addrsss after @. + # Might be bnicece to ship the full email address, if not + # for spammers' address harvesters - getting this wrong + # would make the freenode #commits channel into harvester heaven. + author = author.replace("<", "").split("@")[0].split()[-1] + + # This ignores the timezone. Not clear what to do with it... + ts = ts.strip().split()[0] + + context = locals() + context.update(globals()) + + out = xml % context + + message = '''\ +Message-ID: <%(merged)s.%(author)s@%(project)s> +From: %(fromaddr)s +To: %(toaddr)s +Content-type: text/xml +Subject: DeliverXML + +%(out)s''' % locals() + + return message + +if __name__ == "__main__": + import getopt + + try: + (options, arguments) = getopt.getopt(sys.argv[1:], "np:V") + except getopt.GetoptError, msg: + print "ciabot.py: " + str(msg) + raise SystemExit, 1 + + mailit = True + for (switch, val) in options: + if switch == '-p': + project = val + elif switch == '-n': + mailit = False + elif switch == '-V': + print "ciabot.py: version 3.2" + sys.exit(0) + + # Cough and die if user has not specified a project + if not project: + sys.stderr.write("ciabot.py: no project specified, bailing out.\n") + sys.exit(1) + + # We'll need the git version number. + gitver = do("git --version").split()[0] + + urlprefix = urlprefix % globals() + + # The script wants a reference to head followed by the list of + # commit ID to report about. + if len(arguments) == 0: + refname = do("git symbolic-ref HEAD 2>/dev/null") + merges = [do("git rev-parse HEAD")] + else: + refname = arguments[0] + merges = arguments[1:] + + if mailit: + import smtplib + server = smtplib.SMTP('localhost') + + for merged in merges: + message = report(refname, merged) + if mailit: + server.sendmail(fromaddr, [toaddr], message) + else: + print message + + if mailit: + server.quit() + +#End diff --git a/contrib/ciabot/ciabot.sh b/contrib/ciabot/ciabot.sh new file mode 100755 index 0000000000..eb87bba38e --- /dev/null +++ b/contrib/ciabot/ciabot.sh @@ -0,0 +1,192 @@ +#!/bin/sh +# Distributed under the terms of the GNU General Public License v2 +# Copyright (c) 2006 Fernando J. Pereda <ferdy@gentoo.org> +# Copyright (c) 2008 Natanael Copa <natanael.copa@gmail.com> +# Copyright (c) 2010 Eric S. Raymond <esr@thyrsus.com> +# +# This is a version 3.x of ciabot.sh; use -V to find the exact +# version. Versions 1 and 2 were shipped in 2006 and 2008 and are not +# version-stamped. The version 2 maintainer has passed the baton. +# +# Note: This script should be considered obsolete. +# There is a faster, better-documented rewrite in Python: find it as ciabot.py +# Use this only if your hosting site forbids Python hooks. +# +# Originally based on Git ciabot.pl by Petr Baudis. +# This script contains porcelain and porcelain byproducts. +# +# usage: ciabot.sh [-V] [-n] [-p projectname] [refname commit] +# +# This script is meant to be run either in a post-commit hook or in an +# update hook. If there's nothing unusual about your hosting setup, +# you can specify the project name with a -p option and avoid having +# to modify this script. Try it with -n first to see the notification +# mail dumped to stdout and verify that it looks sane. Use -V to dump +# the version and exit. +# +# In post-commit, run it without arguments (other than possibly a -p +# option). It will query for current HEAD and the latest commit ID to +# get the information it needs. +# +# In update, you have to call it once per merged commit: +# +# refname=$1 +# oldhead=$2 +# newhead=$3 +# for merged in $(git rev-list ${oldhead}..${newhead} | tac) ; do +# /path/to/ciabot.bash ${refname} ${merged} +# done +# +# The reason for the tac call ids that git rev-list emits commits from +# most recent to least - better to ship notifactions from oldest to newest. +# +# Note: this script uses mail, not XML-RPC, in order to avoid stalling +# until timeout when the CIA XML-RPC server is down. +# + +# +# The project as known to CIA. You will either want to change this +# or set the project name with a -p option. +# +project= + +# +# You may not need to change these: +# + +# Name of the repository. +# You can hardwire this to make the script faster. +repo="`basename ${PWD}`" + +# Fully qualified domain name of the repo host. +# You can hardwire this to make the script faster. +host=`hostname --fqdn` + +# Changeset URL prefix for your repo: when the commit ID is appended +# to this, it should point at a CGI that will display the commit +# through gitweb or something similar. The defaults will probably +# work if you have a typical gitweb/cgit setup. +#urlprefix="http://${host}/cgi-bin/gitweb.cgi?p=${repo};a=commit;h=" +urlprefix="http://${host}/cgi-bin/cgit.cgi/${repo}/commit/?id=" + +# +# You probably will not need to change the following: +# + +# Identify the script. Should change only when the script itself +# gets a new home and maintainer. +generator="http://www.catb.org/~esr/ciabot/ciabot.sh" + +# Addresses for the e-mail +from="CIABOT-NOREPLY@${host}" +to="cia@cia.navi.cx" + +# SMTP client to use - may need to edit the absolute pathname for your system +sendmail="sendmail -t -f ${from}" + +# +# No user-serviceable parts below this line: +# + +# Should include all places sendmail is likely to lurk. +PATH="$PATH:/usr/sbin/" + +mode=mailit +while getopts pnV opt +do + case $opt in + p) project=$2; shift ; shift ;; + n) mode=dumpit; shift ;; + V) echo "ciabot.sh: version 3.2"; exit 0; shift ;; + esac +done + +# Cough and die if user has not specified a project +if [ -z "$project" ] +then + echo "ciabot.sh: no project specified, bailing out." >&2 + exit 1 +fi + +if [ $# -eq 0 ] ; then + refname=$(git symbolic-ref HEAD 2>/dev/null) + merged=$(git rev-parse HEAD) +else + refname=$1 + merged=$2 +fi + +# This tries to turn your gitwebbish URL into a tinyurl so it will take up +# less space on the IRC notification line. Some repo sites (I'm looking at +# you, berlios.de!) forbid wget calls for security reasons. On these, +# the code will fall back to the full un-tinyfied URL. +longurl=${urlprefix}${merged} +url=$(wget -O - -q http://tinyurl.com/api-create.php?url=${longurl} 2>/dev/null) +if [ -z "$url" ]; then + url="${longurl}" +fi + +refname=${refname##refs/heads/} + +gitver=$(git --version) +gitver=${gitver##* } + +rev=$(git describe ${merged} 2>/dev/null) +# ${merged:0:12} was the only bashism left in the 2008 version of this +# script, according to checkbashisms. Replace it with ${merged} here +# because it was just a fallback anyway, and it's worth accepting a +# longer fallback for faster execution and removing the bash +# dependency. +[ -z ${rev} ] && rev=${merged} + +# This discards the part of the author's address after @. +# Might be nice to ship the full email address, if not +# for spammers' address harvesters - getting this wrong +# would make the freenode #commits channel into harvester heaven. +rawcommit=$(git cat-file commit ${merged}) +author=$(echo "$rawcommit" | sed -n -e '/^author .*<\([^@]*\).*$/s--\1-p') +logmessage=$(echo "$rawcommit" | sed -e '1,/^$/d' | head -n 1) +logmessage=$(echo "$logmessage" | sed 's/\&/&\;/g; s/</<\;/g; s/>/>\;/g') +ts=$(echo "$rawcommit" | sed -n -e '/^author .*> \([0-9]\+\).*$/s--\1-p') +files=$(git diff-tree -r --name-only ${merged} | sed -e '1d' -e 's-.*-<file>&</file>-') + +out=" +<message> + <generator> + <name>CIA Shell client for Git</name> + <version>${gitver}</version> + <url>${generator}</url> + </generator> + <source> + <project>${project}</project> + <branch>$repo:${refname}</branch> + </source> + <timestamp>${ts}</timestamp> + <body> + <commit> + <author>${author}</author> + <revision>${rev}</revision> + <files> + ${files} + </files> + <log>${logmessage} ${url}</log> + <url>${url}</url> + </commit> + </body> +</message>" + +if [ "$mode" = "dumpit" ] +then + sendmail=cat +fi + +${sendmail} << EOM +Message-ID: <${merged}.${author}@${project}> +From: ${from} +To: ${to} +Content-type: text/xml +Subject: DeliverXML +${out} +EOM + +# vim: set tw=70 : diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 1a762e88e7..67569901e7 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -42,6 +42,24 @@ # set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're # untracked files, then a '%' will be shown next to the branch name. # +# If you would like to see the difference between HEAD and its +# upstream, set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates +# you are behind, ">" indicates you are ahead, and "<>" +# indicates you have diverged. You can further control +# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated +# list of values: +# verbose show number of commits ahead/behind (+/-) upstream +# legacy don't use the '--count' option available in recent +# versions of git-rev-list +# git always compare HEAD to @{upstream} +# svn always compare HEAD to your SVN upstream +# By default, __git_ps1 will compare HEAD to your SVN upstream +# if it can find one, or @{upstream} otherwise. Once you have +# set GIT_PS1_SHOWUPSTREAM, you can override it on a +# per-repository basis by setting the bash.showUpstream config +# variable. +# +# # To submit patches: # # *) Read Documentation/SubmittingPatches @@ -78,14 +96,133 @@ __gitdir () fi } +# stores the divergence from upstream in $p +# used by GIT_PS1_SHOWUPSTREAM +__git_ps1_show_upstream () +{ + local key value + local svn_remote=() svn_url_pattern count n + local upstream=git legacy="" verbose="" + + # get some config options from git-config + while read key value; do + case "$key" in + bash.showupstream) + GIT_PS1_SHOWUPSTREAM="$value" + if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then + p="" + return + fi + ;; + svn-remote.*.url) + svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value" + svn_url_pattern+="\\|$value" + upstream=svn+git # default upstream is SVN if available, else git + ;; + esac + done < <(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ') + + # parse configuration values + for option in ${GIT_PS1_SHOWUPSTREAM}; do + case "$option" in + git|svn) upstream="$option" ;; + verbose) verbose=1 ;; + legacy) legacy=1 ;; + esac + done + + # Find our upstream + case "$upstream" in + git) upstream="@{upstream}" ;; + svn*) + # get the upstream from the "git-svn-id: ..." in a commit message + # (git-svn uses essentially the same procedure internally) + local svn_upstream=($(git log --first-parent -1 \ + --grep="^git-svn-id: \(${svn_url_pattern:2}\)" 2>/dev/null)) + if [[ 0 -ne ${#svn_upstream[@]} ]]; then + svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]} + svn_upstream=${svn_upstream%@*} + for ((n=1; "$n" <= "${#svn_remote[@]}"; ++n)); do + svn_upstream=${svn_upstream#${svn_remote[$n]}} + done + + if [[ -z "$svn_upstream" ]]; then + # default branch name for checkouts with no layout: + upstream=${GIT_SVN_ID:-git-svn} + else + upstream=${svn_upstream#/} + fi + elif [[ "svn+git" = "$upstream" ]]; then + upstream="@{upstream}" + fi + ;; + esac + + # Find how many commits we are ahead/behind our upstream + if [[ -z "$legacy" ]]; then + count="$(git rev-list --count --left-right \ + "$upstream"...HEAD 2>/dev/null)" + else + # produce equivalent output to --count for older versions of git + local commits + if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)" + then + local commit behind=0 ahead=0 + for commit in $commits + do + case "$commit" in + "<"*) let ++behind + ;; + *) let ++ahead + ;; + esac + done + count="$behind $ahead" + else + count="" + fi + fi + + # calculate the result + if [[ -z "$verbose" ]]; then + case "$count" in + "") # no upstream + p="" ;; + "0 0") # equal to upstream + p="=" ;; + "0 "*) # ahead of upstream + p=">" ;; + *" 0") # behind upstream + p="<" ;; + *) # diverged from upstream + p="<>" ;; + esac + else + case "$count" in + "") # no upstream + p="" ;; + "0 0") # equal to upstream + p=" u=" ;; + "0 "*) # ahead of upstream + p=" u+${count#0 }" ;; + *" 0") # behind upstream + p=" u-${count% 0}" ;; + *) # diverged from upstream + p=" u+${count#* }-${count% *}" ;; + esac + fi + +} + + # __git_ps1 accepts 0 or 1 arguments (i.e., format string) # returns text to add to bash PS1 prompt (includes branch name) __git_ps1 () { local g="$(__gitdir)" if [ -n "$g" ]; then - local r - local b + local r="" + local b="" if [ -f "$g/rebase-merge/interactive" ]; then r="|REBASE-i" b="$(cat "$g/rebase-merge/head-name")" @@ -127,11 +264,12 @@ __git_ps1 () } fi - local w - local i - local s - local u - local c + local w="" + local i="" + local s="" + local u="" + local c="" + local p="" if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then @@ -159,13 +297,14 @@ __git_ps1 () u="%" fi fi - fi - if [ -n "${1-}" ]; then - printf "$1" "$c${b##refs/heads/}$w$i$s$u$r" - else - printf " (%s)" "$c${b##refs/heads/}$w$i$s$u$r" + if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then + __git_ps1_show_upstream + fi fi + + local f="$w$i$s$u" + printf "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p" fi } @@ -253,7 +392,9 @@ __git_refs () refs="${cur%/*}" ;; *) - if [ -e "$dir/HEAD" ]; then echo HEAD; fi + for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do + if [ -e "$dir/$i" ]; then echo $i; fi + done format="refname:short" refs="refs/tags refs/heads refs/remotes" ;; @@ -628,10 +769,19 @@ __git_aliased_command () local word cmdline=$(git --git-dir="$(__gitdir)" \ config --get "alias.$1") for word in $cmdline; do - if [ "${word##-*}" ]; then - echo $word + case "$word" in + \!gitk|gitk) + echo "gitk" return - fi + ;; + \!*) : shell command alias ;; + -*) : option ;; + *=*) : setting env ;; + git) : git itself ;; + *) + echo "$word" + return + esac done } @@ -670,7 +820,7 @@ _git_am () { local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)" if [ -d "$dir"/rebase-apply ]; then - __gitcomp "--skip --resolved --abort" + __gitcomp "--skip --continue --resolved --abort" return fi case "$cur" in @@ -789,6 +939,7 @@ _git_branch () __gitcomp " --color --no-color --verbose --abbrev= --no-abbrev --track --no-track --contains --merged --no-merged + --set-upstream " ;; *) @@ -833,7 +984,7 @@ _git_checkout () --*) __gitcomp " --quiet --ours --theirs --track --no-track --merge - --conflict= --patch + --conflict= --orphan --patch " ;; *) @@ -1043,7 +1194,7 @@ _git_format_patch () --numbered --start-number --numbered-files --keep-subject - --signoff + --signoff --signature --no-signature --in-reply-to= --cc= --full-index --binary --not --all @@ -1085,6 +1236,11 @@ _git_gc () COMPREPLY=() } +_git_gitk () +{ + _gitk +} + _git_grep () { __git_has_doubledash && return @@ -1310,6 +1466,24 @@ _git_name_rev () __gitcomp "--tags --all --stdin" } +_git_notes () +{ + local subcommands="edit show" + if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then + __gitcomp "$subcommands" + return + fi + + case "${COMP_WORDS[COMP_CWORD-1]}" in + -m|-F) + COMPREPLY=() + ;; + *) + __gitcomp "$(__git_refs)" + ;; + esac +} + _git_pull () { __git_complete_strategy && return @@ -1371,6 +1545,7 @@ _git_rebase () --preserve-merges --stat --no-stat --committer-date-is-author-date --ignore-date --ignore-whitespace --whitespace= + --autosquash " return @@ -1418,6 +1593,11 @@ _git_send_email () COMPREPLY=() } +_git_stage () +{ + _git_add +} + __git_config_get_set_variables () { local prevword word config_file= c=$COMP_CWORD @@ -1688,6 +1868,7 @@ _git_config () format.headers format.numbered format.pretty + format.signature format.signoff format.subjectprefix format.suffix @@ -2021,7 +2202,7 @@ _git_svn () init fetch clone rebase dcommit log find-rev set-tree commit-diff info create-ignore propget proplist show-ignore show-externals branch tag blame - migrate + migrate mkdirs reset gc " local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then @@ -2068,7 +2249,7 @@ _git_svn () __gitcomp "--stdin $cmt_opts $fc_opts" ;; create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\ - show-externals,--*) + show-externals,--*|mkdirs,--*) __gitcomp "--revision=" ;; log,--*) @@ -2105,6 +2286,9 @@ _git_svn () --no-auth-cache --username= " ;; + reset,--*) + __gitcomp "--revision= --parent" + ;; *) COMPREPLY=() ;; @@ -2146,6 +2330,11 @@ _git_tag () esac } +_git_whatchanged () +{ + _git_log +} + _git () { local i c=1 command __git_dir @@ -2182,63 +2371,14 @@ _git () return fi + local completion_func="_git_${command//-/_}" + declare -F $completion_func >/dev/null && $completion_func && return + local expansion=$(__git_aliased_command "$command") - [ "$expansion" ] && command="$expansion" - - case "$command" in - am) _git_am ;; - add) _git_add ;; - apply) _git_apply ;; - archive) _git_archive ;; - bisect) _git_bisect ;; - bundle) _git_bundle ;; - branch) _git_branch ;; - checkout) _git_checkout ;; - cherry) _git_cherry ;; - cherry-pick) _git_cherry_pick ;; - clean) _git_clean ;; - clone) _git_clone ;; - commit) _git_commit ;; - config) _git_config ;; - describe) _git_describe ;; - diff) _git_diff ;; - difftool) _git_difftool ;; - fetch) _git_fetch ;; - format-patch) _git_format_patch ;; - fsck) _git_fsck ;; - gc) _git_gc ;; - grep) _git_grep ;; - help) _git_help ;; - init) _git_init ;; - log) _git_log ;; - ls-files) _git_ls_files ;; - ls-remote) _git_ls_remote ;; - ls-tree) _git_ls_tree ;; - merge) _git_merge;; - mergetool) _git_mergetool;; - merge-base) _git_merge_base ;; - mv) _git_mv ;; - name-rev) _git_name_rev ;; - pull) _git_pull ;; - push) _git_push ;; - rebase) _git_rebase ;; - remote) _git_remote ;; - replace) _git_replace ;; - reset) _git_reset ;; - revert) _git_revert ;; - rm) _git_rm ;; - send-email) _git_send_email ;; - shortlog) _git_shortlog ;; - show) _git_show ;; - show-branch) _git_show_branch ;; - stash) _git_stash ;; - stage) _git_add ;; - submodule) _git_submodule ;; - svn) _git_svn ;; - tag) _git_tag ;; - whatchanged) _git_log ;; - *) COMPREPLY=() ;; - esac + if [ -n "$expansion" ]; then + completion_func="_git_${expansion//-/_}" + declare -F $completion_func >/dev/null && $completion_func + fi } _gitk () diff --git a/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh index 5c72f655c7..23ffb028d1 100755 --- a/contrib/examples/git-commit.sh +++ b/contrib/examples/git-commit.sh @@ -631,7 +631,7 @@ then if test -z "$quiet" then commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\ - --summary --root HEAD --` + --abbrev --summary --root HEAD --` echo "Created${initial_commit:+ initial} commit $commit" fi fi diff --git a/contrib/examples/git-fetch.sh b/contrib/examples/git-fetch.sh index e44af2c86d..a314273bd5 100755 --- a/contrib/examples/git-fetch.sh +++ b/contrib/examples/git-fetch.sh @@ -127,10 +127,12 @@ then orig_head=$(git rev-parse --verify HEAD 2>/dev/null) fi -# Allow --notags from remote.$1.tagopt +# Allow --tags/--notags from remote.$1.tagopt case "$tags$no_tags" in '') case "$(git config --get "remote.$1.tagopt")" in + --tags) + tags=t ;; --no-tags) no_tags=t ;; esac diff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh index 500635fe4b..8f617fcb70 100755 --- a/contrib/examples/git-merge.sh +++ b/contrib/examples/git-merge.sh @@ -31,10 +31,11 @@ LF=' ' all_strategies='recur recursive octopus resolve stupid ours subtree' +all_strategies="$all_strategies recursive-ours recursive-theirs" default_twohead_strategies='recursive' default_octopus_strategies='octopus' no_fast_forward_strategies='subtree ours' -no_trivial_strategies='recursive recur subtree ours' +no_trivial_strategies='recursive recur subtree ours recursive-ours recursive-theirs' use_strategies= allow_fast_forward=t diff --git a/contrib/examples/git-notes.sh b/contrib/examples/git-notes.sh new file mode 100755 index 0000000000..e642e47d9f --- /dev/null +++ b/contrib/examples/git-notes.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +USAGE="(edit [-F <file> | -m <msg>] | show) [commit]" +. git-sh-setup + +test -z "$1" && usage +ACTION="$1"; shift + +test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="$(git config core.notesref)" +test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="refs/notes/commits" + +MESSAGE= +while test $# != 0 +do + case "$1" in + -m) + test "$ACTION" = "edit" || usage + shift + if test "$#" = "0"; then + die "error: option -m needs an argument" + else + if [ -z "$MESSAGE" ]; then + MESSAGE="$1" + else + MESSAGE="$MESSAGE + +$1" + fi + shift + fi + ;; + -F) + test "$ACTION" = "edit" || usage + shift + if test "$#" = "0"; then + die "error: option -F needs an argument" + else + if [ -z "$MESSAGE" ]; then + MESSAGE="$(cat "$1")" + else + MESSAGE="$MESSAGE + +$(cat "$1")" + fi + shift + fi + ;; + -*) + usage + ;; + *) + break + ;; + esac +done + +COMMIT=$(git rev-parse --verify --default HEAD "$@") || +die "Invalid commit: $@" + +case "$ACTION" in +edit) + if [ "${GIT_NOTES_REF#refs/notes/}" = "$GIT_NOTES_REF" ]; then + die "Refusing to edit notes in $GIT_NOTES_REF (outside of refs/notes/)" + fi + + MSG_FILE="$GIT_DIR/new-notes-$COMMIT" + GIT_INDEX_FILE="$MSG_FILE.idx" + export GIT_INDEX_FILE + + trap ' + test -f "$MSG_FILE" && rm "$MSG_FILE" + test -f "$GIT_INDEX_FILE" && rm "$GIT_INDEX_FILE" + ' 0 + + CURRENT_HEAD=$(git show-ref "$GIT_NOTES_REF" | cut -f 1 -d ' ') + if [ -z "$CURRENT_HEAD" ]; then + PARENT= + else + PARENT="-p $CURRENT_HEAD" + git read-tree "$GIT_NOTES_REF" || die "Could not read index" + fi + + if [ -z "$MESSAGE" ]; then + GIT_NOTES_REF= git log -1 $COMMIT | sed "s/^/#/" > "$MSG_FILE" + if [ ! -z "$CURRENT_HEAD" ]; then + git cat-file blob :$COMMIT >> "$MSG_FILE" 2> /dev/null + fi + core_editor="$(git config core.editor)" + ${GIT_EDITOR:-${core_editor:-${VISUAL:-${EDITOR:-vi}}}} "$MSG_FILE" + else + echo "$MESSAGE" > "$MSG_FILE" + fi + + grep -v ^# < "$MSG_FILE" | git stripspace > "$MSG_FILE".processed + mv "$MSG_FILE".processed "$MSG_FILE" + if [ -s "$MSG_FILE" ]; then + BLOB=$(git hash-object -w "$MSG_FILE") || + die "Could not write into object database" + git update-index --add --cacheinfo 0644 $BLOB $COMMIT || + die "Could not write index" + else + test -z "$CURRENT_HEAD" && + die "Will not initialise with empty tree" + git update-index --force-remove $COMMIT || + die "Could not update index" + fi + + TREE=$(git write-tree) || die "Could not write tree" + NEW_HEAD=$(echo Annotate $COMMIT | git commit-tree $TREE $PARENT) || + die "Could not annotate" + git update-ref -m "Annotate $COMMIT" \ + "$GIT_NOTES_REF" $NEW_HEAD $CURRENT_HEAD +;; +show) + git rev-parse -q --verify "$GIT_NOTES_REF":$COMMIT > /dev/null || + die "No note for commit $COMMIT." + git show "$GIT_NOTES_REF":$COMMIT +;; +*) + usage +esac diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index 48059d0aa7..c1ea643ace 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -732,7 +732,7 @@ class P4Submit(Command): if os.environ.has_key("P4EDITOR"): editor = os.environ.get("P4EDITOR") else: - editor = read_pipe("git var GIT_EDITOR") + editor = read_pipe("git var GIT_EDITOR").strip() system(editor + " " + fileName) response = "y" @@ -802,7 +802,7 @@ class P4Submit(Command): self.oldWorkingDirectory = os.getcwd() chdir(self.clientPath) - print "Syncronizing p4 checkout..." + print "Synchronizing p4 checkout..." p4_system("sync ...") self.check() @@ -967,9 +967,8 @@ class P4Sync(Command): elif file["type"] == "symlink": mode = "120000" # p4 print on a symlink contains "target\n", so strip it off - last = contents.pop() - last = last[:-1] - contents.append(last) + data = ''.join(contents) + contents = [data[:-1]] if self.isWindows and file["type"].endswith("text"): mangled = [] @@ -1037,7 +1036,7 @@ class P4Sync(Command): if includeFile: filesForCommit.append(f) - if f['action'] not in ('delete', 'purge'): + if f['action'] not in ('delete', 'move/delete', 'purge'): filesToRead.append(f) else: filesToDelete.append(f) diff --git a/contrib/fast-import/import-directories.perl b/contrib/fast-import/import-directories.perl index 5782d80e26..3a5da4ab00 100755 --- a/contrib/fast-import/import-directories.perl +++ b/contrib/fast-import/import-directories.perl @@ -344,7 +344,7 @@ sub parsekeyvaluepair Key and value strings may be enclosed in quotes, in which case whitespace inside the quotes is preserved. Additionally, an equal -sign may be included in the key by preceeding it with a backslash. +sign may be included in the key by preceding it with a backslash. For example: "key1 "=value1 diff --git a/contrib/fast-import/import-zips.py b/contrib/fast-import/import-zips.py index 7051a83a59..82f5ed3ddc 100755 --- a/contrib/fast-import/import-zips.py +++ b/contrib/fast-import/import-zips.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python ## zip archive frontend for git-fast-import ## diff --git a/contrib/git-resurrect.sh b/contrib/git-resurrect.sh index c364dda696..a4ed4c3c62 100755 --- a/contrib/git-resurrect.sh +++ b/contrib/git-resurrect.sh @@ -9,6 +9,7 @@ other/Merge <other> into <name> (respectively) commit subjects, which is rather slow but allows you to resurrect other people's topic branches." +OPTIONS_KEEPDASHDASH= OPTIONS_SPEC="\ git resurrect $USAGE -- diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index 2a6839d81e..046cb2b268 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -1,4 +1,4 @@ -#! /usr/bin/python +#!/usr/bin/env python """ hg-to-git.py - A Mercurial to GIT converter @@ -59,14 +59,14 @@ def getgitenv(user, date): elems = re.compile('(.*?)\s+<(.*)>').match(user) if elems: env += 'export GIT_AUTHOR_NAME="%s" ;' % elems.group(1) - env += 'export GIT_COMMITER_NAME="%s" ;' % elems.group(1) + env += 'export GIT_COMMITTER_NAME="%s" ;' % elems.group(1) env += 'export GIT_AUTHOR_EMAIL="%s" ;' % elems.group(2) - env += 'export GIT_COMMITER_EMAIL="%s" ;' % elems.group(2) + env += 'export GIT_COMMITTER_EMAIL="%s" ;' % elems.group(2) else: env += 'export GIT_AUTHOR_NAME="%s" ;' % user - env += 'export GIT_COMMITER_NAME="%s" ;' % user + env += 'export GIT_COMMITTER_NAME="%s" ;' % user env += 'export GIT_AUTHOR_EMAIL= ;' - env += 'export GIT_COMMITER_EMAIL= ;' + env += 'export GIT_COMMITTER_EMAIL= ;' env += 'export GIT_AUTHOR_DATE="%s" ;' % date env += 'export GIT_COMMITTER_DATE="%s" ;' % date diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email index 58a35c8287..09c524105c 100755 --- a/contrib/hooks/post-receive-email +++ b/contrib/hooks/post-receive-email @@ -23,6 +23,13 @@ # possible for the email to be from someone other than the person doing the # push. # +# To help with debugging and use on pre-v1.5.1 git servers, this script will +# also obey the interface of hooks/update, taking its arguments on the +# command line. Unfortunately, hooks/update is called once for each ref. +# To avoid firing one email per ref, this script just prints its output to +# the screen when used in this mode. The output can then be redirected if +# wanted. +# # Config # ------ # hooks.mailinglist @@ -196,7 +203,7 @@ generate_email_header() # Generate header cat <<-EOF To: $recipients - Subject: ${emailprefix}$projectdesc $refname_type, $short_refname, ${change_type}d. $describe + Subject: ${emailprefix}$projectdesc $refname_type $short_refname ${change_type}d. $describe X-Git-Refname: $refname X-Git-Reftype: $refname_type X-Git-Oldrev: $oldrev diff --git a/contrib/p4import/git-p4import.py b/contrib/p4import/git-p4import.py index 0f3d97b67e..b6e534b65b 100644 --- a/contrib/p4import/git-p4import.py +++ b/contrib/p4import/git-p4import.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # This tool is copyright (c) 2006, Sean Estabrooks. # It is released under the Gnu Public License, version 2. diff --git a/contrib/svn-fe/.gitignore b/contrib/svn-fe/.gitignore new file mode 100644 index 0000000000..02a7791585 --- /dev/null +++ b/contrib/svn-fe/.gitignore @@ -0,0 +1,4 @@ +/*.xml +/*.1 +/*.html +/svn-fe diff --git a/contrib/svn-fe/Makefile b/contrib/svn-fe/Makefile new file mode 100644 index 0000000000..360d8da417 --- /dev/null +++ b/contrib/svn-fe/Makefile @@ -0,0 +1,63 @@ +all:: svn-fe$X + +CC = gcc +RM = rm -f +MV = mv + +CFLAGS = -g -O2 -Wall +LDFLAGS = +ALL_CFLAGS = $(CFLAGS) +ALL_LDFLAGS = $(LDFLAGS) +EXTLIBS = + +GIT_LIB = ../../libgit.a +VCSSVN_LIB = ../../vcs-svn/lib.a +LIBS = $(VCSSVN_LIB) $(GIT_LIB) $(EXTLIBS) + +QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir +QUIET_SUBDIR1 = + +ifneq ($(findstring $(MAKEFLAGS),w),w) +PRINT_DIR = --no-print-directory +else # "make -w" +NO_SUBDIR = : +endif + +ifneq ($(findstring $(MAKEFLAGS),s),s) +ifndef V + QUIET_CC = @echo ' ' CC $@; + QUIET_LINK = @echo ' ' LINK $@; + QUIET_SUBDIR0 = +@subdir= + QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \ + $(MAKE) $(PRINT_DIR) -C $$subdir +endif +endif + +svn-fe$X: svn-fe.o $(VCSSVN_LIB) $(GIT_LIB) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ svn-fe.o \ + $(ALL_LDFLAGS) $(LIBS) + +svn-fe.o: svn-fe.c ../../vcs-svn/svndump.h + $(QUIET_CC)$(CC) -I../../vcs-svn -o $*.o -c $(ALL_CFLAGS) $< + +svn-fe.html: svn-fe.txt + $(QUIET_SUBDIR0)../../Documentation $(QUIET_SUBDIR1) \ + MAN_TXT=../contrib/svn-fe/svn-fe.txt \ + ../contrib/svn-fe/$@ + +svn-fe.1: svn-fe.txt + $(QUIET_SUBDIR0)../../Documentation $(QUIET_SUBDIR1) \ + MAN_TXT=../contrib/svn-fe/svn-fe.txt \ + ../contrib/svn-fe/$@ + $(MV) ../../Documentation/svn-fe.1 . + +../../vcs-svn/lib.a: FORCE + $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) vcs-svn/lib.a + +../../libgit.a: FORCE + $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) libgit.a + +clean: + $(RM) svn-fe$X svn-fe.o svn-fe.html svn-fe.xml svn-fe.1 + +.PHONY: all clean FORCE diff --git a/contrib/svn-fe/svn-fe.c b/contrib/svn-fe/svn-fe.c new file mode 100644 index 0000000000..e9b9ba4da4 --- /dev/null +++ b/contrib/svn-fe/svn-fe.c @@ -0,0 +1,15 @@ +/* + * This file is in the public domain. + * You may freely use, modify, distribute, and relicense it. + */ + +#include <stdlib.h> +#include "svndump.h" + +int main(int argc, char **argv) +{ + svndump_init(NULL); + svndump_read((argc > 1) ? argv[1] : NULL); + svndump_reset(); + return 0; +} diff --git a/contrib/svn-fe/svn-fe.txt b/contrib/svn-fe/svn-fe.txt new file mode 100644 index 0000000000..de30f83a1f --- /dev/null +++ b/contrib/svn-fe/svn-fe.txt @@ -0,0 +1,66 @@ +svn-fe(1) +========= + +NAME +---- +svn-fe - convert an SVN "dumpfile" to a fast-import stream + +SYNOPSIS +-------- +svnadmin dump --incremental REPO | svn-fe [url] | git fast-import + +DESCRIPTION +----------- + +Converts a Subversion dumpfile (version: 2) into input suitable for +git-fast-import(1) and similar importers. REPO is a path to a +Subversion repository mirrored on the local disk. Remote Subversion +repositories can be mirrored on local disk using the `svnsync` +command. + +INPUT FORMAT +------------ +Subversion's repository dump format is documented in full in +`notes/dump-load-format.txt` from the Subversion source tree. +Files in this format can be generated using the 'svnadmin dump' or +'svk admin dump' command. + +OUTPUT FORMAT +------------- +The fast-import format is documented by the git-fast-import(1) +manual page. + +NOTES +----- +Subversion dumps do not record a separate author and committer for +each revision, nor a separate display name and email address for +each author. Like git-svn(1), 'svn-fe' will use the name + +--------- +user <user@UUID> +--------- + +as committer, where 'user' is the value of the `svn:author` property +and 'UUID' the repository's identifier. + +To support incremental imports, 'svn-fe' will put a `git-svn-id` +line at the end of each commit log message if passed an url on the +command line. This line has the form `git-svn-id: URL@REVNO UUID`. + +Empty directories and unknown properties are silently discarded. + +The resulting repository will generally require further processing +to put each project in its own repository and to separate the history +of each branch. The 'git filter-branch --subdirectory-filter' command +may be useful for this purpose. + +BUGS +---- +Litters the current working directory with .bin files for +persistence. Will be fixed when the svn-fe infrastructure is aware of +a Git working directory. + +SEE ALSO +-------- +git-svn(1), svn2git(1), svk(1), git-filter-branch(1), git-fast-import(1), +https://svn.apache.org/repos/asf/subversion/trunk/notes/dump-load-format.txt diff --git a/contrib/workdir/git-new-workdir b/contrib/workdir/git-new-workdir index 993cacf324..3ad2c0cea5 100755 --- a/contrib/workdir/git-new-workdir +++ b/contrib/workdir/git-new-workdir @@ -54,13 +54,13 @@ then die "destination directory '$new_workdir' already exists." fi -# make sure the the links use full paths +# make sure the links use full paths git_dir=$(cd "$git_dir"; pwd) # create the workdir mkdir -p "$new_workdir/.git" || die "unable to create \"$new_workdir\"!" -# create the links to the original repo. explictly exclude index, HEAD and +# create the links to the original repo. explicitly exclude index, HEAD and # logs/HEAD from the list since they are purely related to the current working # directory, and should not be shared. for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn |