summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rwxr-xr-x[-rw-r--r--]contrib/buildsystems/engine.pl0
-rwxr-xr-x[-rw-r--r--]contrib/buildsystems/generate0
-rwxr-xr-x[-rw-r--r--]contrib/buildsystems/parse.pl0
-rw-r--r--contrib/ciabot/INSTALL54
-rw-r--r--contrib/ciabot/README11
-rwxr-xr-xcontrib/ciabot/ciabot.py255
-rwxr-xr-xcontrib/ciabot/ciabot.sh233
-rw-r--r--contrib/completion/git-completion.bash64
-rw-r--r--contrib/completion/git-completion.tcsh2
-rw-r--r--contrib/completion/git-completion.zsh10
-rw-r--r--contrib/completion/git-prompt.sh7
-rwxr-xr-xcontrib/contacts/git-contacts37
-rw-r--r--contrib/credential/gnome-keyring/Makefile4
-rw-r--r--contrib/credential/gnome-keyring/git-credential-gnome-keyring.c340
-rwxr-xr-xcontrib/credential/netrc/git-credential-netrc4
-rwxr-xr-xcontrib/examples/git-log.sh15
-rwxr-xr-xcontrib/examples/git-merge.sh2
-rwxr-xr-xcontrib/examples/git-repack.sh194
-rwxr-xr-xcontrib/examples/git-whatchanged.sh28
-rwxr-xr-xcontrib/git-resurrect.sh1
-rwxr-xr-xcontrib/gitview/gitview2
-rwxr-xr-xcontrib/hooks/post-receive-email16
-rwxr-xr-x[-rw-r--r--]contrib/hooks/pre-auto-gc-battery1
-rwxr-xr-x[-rw-r--r--]contrib/hooks/setgitperms.perl0
-rwxr-xr-x[-rw-r--r--]contrib/hooks/update-paranoid0
-rw-r--r--contrib/mw-to-git/Makefile19
-rwxr-xr-xcontrib/mw-to-git/git-remote-mediawiki.perl6
-rwxr-xr-xcontrib/mw-to-git/t/test-gitmw-lib.sh2
-rw-r--r--contrib/mw-to-git/t/test.config2
-rw-r--r--contrib/p4import/README1
-rw-r--r--contrib/p4import/git-p4import.py365
-rw-r--r--contrib/p4import/git-p4import.txt167
-rwxr-xr-xcontrib/remote-helpers/git-remote-bzr125
-rwxr-xr-xcontrib/remote-helpers/git-remote-hg116
-rwxr-xr-xcontrib/remote-helpers/test-bzr.sh159
-rwxr-xr-xcontrib/remote-helpers/test-hg-bidi.sh52
-rwxr-xr-xcontrib/remote-helpers/test-hg-hg-git.sh156
-rwxr-xr-xcontrib/remote-helpers/test-hg.sh271
-rwxr-xr-xcontrib/subtree/git-subtree.sh22
-rw-r--r--contrib/subtree/git-subtree.txt14
40 files changed, 1112 insertions, 1645 deletions
diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl
index 23da787dc5..23da787dc5 100644..100755
--- a/contrib/buildsystems/engine.pl
+++ b/contrib/buildsystems/engine.pl
diff --git a/contrib/buildsystems/generate b/contrib/buildsystems/generate
index bc10f25ff2..bc10f25ff2 100644..100755
--- a/contrib/buildsystems/generate
+++ b/contrib/buildsystems/generate
diff --git a/contrib/buildsystems/parse.pl b/contrib/buildsystems/parse.pl
index c9656ece99..c9656ece99 100644..100755
--- a/contrib/buildsystems/parse.pl
+++ b/contrib/buildsystems/parse.pl
diff --git a/contrib/ciabot/INSTALL b/contrib/ciabot/INSTALL
deleted file mode 100644
index 7222961d35..0000000000
--- a/contrib/ciabot/INSTALL
+++ /dev/null
@@ -1,54 +0,0 @@
-= Installation instructions =
-
-Two scripts are included. The Python one (ciabot.py) is faster and
-more capable; the shell one (ciabot.sh) is a fallback in case Python
-gives your git hosting site indigestion. (I know of no such sites.)
-
-It is no longer necessary to modify the script in order to put it
-in place; in fact, this is now discouraged. It is entirely
-configurable with the following git config variables:
-
-ciabot.project = name of the project
-ciabot.repo = name of the project repo for gitweb/cgit purposes
-ciabot.xmlrpc = if true, ship notifications via XML-RPC
-ciabot.revformat = format in which the revision is shown
-
-The revformat variable may have the following values
-raw -> full hex ID of commit
-short -> first 12 chars of hex ID
-describe -> describe relative to last tag, falling back to short
-
-ciabot.project defaults to the directory name of the repository toplevel.
-ciabot.repo defaults to ciabot.project lowercased.
-ciabot.xmlrpc defaults to True
-ciabot.revformat defaults to 'describe'.
-
-This means that in the normal case you need not do any configuration at all,
-however setting ciabot.project will allow the hook to run slightly faster.
-
-Once you've set these variables, try your script with -n to see the
-notification message dumped to stdout and verify that it looks sane.
-
-To live-test these scripts, your project needs to have been registered with
-the CIA site. Here are the steps:
-
-1. Open an IRC window on irc://freenode/commits or your registered
- project IRC channel.
-
-2. Run ciabot.py and/or ciabot.sh from any directory under git
- control.
-
-You should see a notification on the channel for your most recent commit.
-
-After verifying correct function, install one of these scripts either
-in a post-commit hook or in an update hook.
-
-In post-commit, run it without arguments. 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 because it lists
-from most recent to oldest.
-
-/path/to/ciabot.py ${refname} $(git rev-list ${oldhead}..${newhead} | tac)
diff --git a/contrib/ciabot/README b/contrib/ciabot/README
deleted file mode 100644
index 2dfe1f91f5..0000000000
--- a/contrib/ciabot/README
+++ /dev/null
@@ -1,11 +0,0 @@
-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.
-
-See the file INSTALL for installation instructions.
diff --git a/contrib/ciabot/ciabot.py b/contrib/ciabot/ciabot.py
deleted file mode 100755
index befa0c3967..0000000000
--- a/contrib/ciabot/ciabot.py
+++ /dev/null
@@ -1,255 +0,0 @@
-#!/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. 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. 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 because it lists
-# from most recent to oldest.
-#
-# /path/to/ciabot.py ${refname} $(git rev-list ${oldhead}..${newhead} | tac)
-#
-# Configuration variables affecting this script:
-#
-# ciabot.project = name of the project
-# ciabot.repo = name of the project repo for gitweb/cgit purposes
-# ciabot.xmlrpc = if true (default), ship notifications via XML-RPC
-# ciabot.revformat = format in which the revision is shown
-#
-# ciabot.project defaults to the directory name of the repository toplevel.
-# ciabot.repo defaults to ciabot.project lowercased.
-#
-# This means that in the normal case you need not do any configuration at all,
-# but setting the project name will speed it up slightly.
-#
-# The revformat variable may have the following values
-# raw -> full hex ID of commit
-# short -> first 12 chars of hex ID
-# describe = -> describe relative to last tag, falling back to short
-# The default is 'describe'.
-#
-# Note: the CIA project now says only XML-RPC is reliable, so
-# we default to that.
-#
-
-import sys
-if sys.hexversion < 0x02000000:
- # The limiter is the xml.sax module
- sys.stderr.write("ciabot.py: requires Python 2.0.0 or later.\n")
- sys.exit(1)
-
-import os, commands, socket, urllib
-from xml.sax.saxutils import escape
-
-# 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 notification 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>%(version)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:
-#
-
-# Where to ship e-mail notifications.
-toaddr = "cia@cia.vc"
-
-# 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"
-version = "3.6"
-
-def do(command):
- return commands.getstatusoutput(command)[1]
-
-def report(refname, merged, xmlrpc=True):
- "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 description for the revision
- if revformat == 'raw':
- rev = merged
- elif revformat == 'short':
- rev = ''
- else: # revformat == 'describe'
- rev = do("git describe %s 2>/dev/null" % merged)
- if not rev:
- rev = merged[:12]
-
- # Extract the meta-information for the commit
- files=do("git diff-tree -r --name-only '"+ merged +"' | sed -e '1d' -e 's-.*-<file>&</file>-'")
- metainfo = do("git log -1 '--pretty=format:%an <%ae>%n%at%n%s' " + merged)
- (author, ts, logmsg) = metainfo.split("\n")
- logmsg = escape(logmsg)
-
- # This discards the part of the author's address after @.
- # Might be 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.
- author = escape(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
- mail = '''\
-Message-ID: <%(merged)s.%(author)s@%(project)s>
-From: %(fromaddr)s
-To: %(toaddr)s
-Content-type: text/xml
-Subject: DeliverXML
-
-%(out)s''' % locals()
-
- if xmlrpc:
- return out
- else:
- return mail
-
-if __name__ == "__main__":
- import getopt
-
- # Get all config variables
- revformat = do("git config --get ciabot.revformat")
- project = do("git config --get ciabot.project")
- repo = do("git config --get ciabot.repo")
- xmlrpc = do("git config --get ciabot.xmlrpc")
- xmlrpc = not (xmlrpc and xmlrpc == "false")
-
- host = socket.getfqdn()
- fromaddr = "CIABOT-NOREPLY@" + host
-
- try:
- (options, arguments) = getopt.getopt(sys.argv[1:], "np:xV")
- except getopt.GetoptError, msg:
- print "ciabot.py: " + str(msg)
- raise SystemExit, 1
-
- notify = True
- for (switch, val) in options:
- if switch == '-p':
- project = val
- elif switch == '-n':
- notify = False
- elif switch == '-x':
- xmlrpc = True
- elif switch == '-V':
- print "ciabot.py: version", version
- sys.exit(0)
-
- # The project variable defaults to the name of the repository toplevel.
- if not project:
- here = os.getcwd()
- while True:
- if os.path.exists(os.path.join(here, ".git")):
- project = os.path.basename(here)
- break
- elif here == '/':
- sys.stderr.write("ciabot.py: no .git below root!\n")
- sys.exit(1)
- here = os.path.dirname(here)
-
- if not repo:
- repo = project.lower()
-
- 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 notify:
- if xmlrpc:
- import xmlrpclib
- server = xmlrpclib.Server('http://cia.vc/RPC2');
- else:
- import smtplib
- server = smtplib.SMTP('localhost')
-
- for merged in merges:
- message = report(refname, merged, xmlrpc)
- if not notify:
- print message
- elif xmlrpc:
- try:
- # RPC server is flaky, this can fail due to timeout.
- server.hub.deliver(message)
- except socket.error, e:
- sys.stderr.write("%s\n" % e)
- else:
- server.sendmail(fromaddr, [toaddr], message)
-
- if notify:
- if not xmlrpc:
- server.quit()
-
-#End
diff --git a/contrib/ciabot/ciabot.sh b/contrib/ciabot/ciabot.sh
deleted file mode 100755
index dfb71a1a15..0000000000
--- a/contrib/ciabot/ciabot.sh
+++ /dev/null
@@ -1,233 +0,0 @@
-#!/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>
-# Assistance and review by Petr Baudis, author of ciabot.pl,
-# is gratefully acknowledged.
-#
-# 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.
-# It requires: git(1), hostname(1), cut(1), sendmail(1), and wget(1).
-#
-# 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. 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. 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.sh ${refname} ${merged}
-# done
-#
-# The reason for the tac call is that git rev-list emits commits from
-# most recent to least - better to ship notifications from oldest to newest.
-#
-# Configuration variables affecting this script:
-#
-# ciabot.project = name of the project
-# ciabot.repo = name of the project repo for gitweb/cgit purposes
-# ciabot.revformat = format in which the revision is shown
-#
-# ciabot.project defaults to the directory name of the repository toplevel.
-# ciabot.repo defaults to ciabot.project lowercased.
-#
-# This means that in the normal case you need not do any configuration at all,
-# but setting the project name will speed it up slightly.
-#
-# The revformat variable may have the following values
-# raw -> full hex ID of commit
-# short -> first 12 chars of hex ID
-# describe = -> describe relative to last tag, falling back to short
-# The default is 'describe'.
-#
-# Note: the shell ancestors of this script used mail, not XML-RPC, in
-# order to avoid stalling until timeout when the CIA XML-RPC server is
-# down. It is unknown whether this is still an issue in 2010, but
-# XML-RPC would be annoying to do from sh in any case. (XML-RPC does
-# have the advantage that it guarantees notification of multiple commits
-# shipped from an update in their actual order.)
-#
-
-# The project as known to CIA. You can set this with a -p option,
-# or let it default to the directory name of the repo toplevel.
-project=$(git config --get ciabot.project)
-
-if [ -z $project ]
-then
- here=`pwd`;
- while :; do
- if [ -d $here/.git ]
- then
- project=`basename $here`
- break
- elif [ $here = '/' ]
- then
- echo "ciabot.sh: no .git below root!"
- exit 1
- fi
- here=`dirname $here`
- done
-fi
-
-# Name of the repo for gitweb/cgit purposes
-repo=$(git config --get ciabot.repo)
-[ -z $repo] && repo=$(echo "${project}" | tr '[A-Z]' '[a-z]')
-
-# What revision format do we want in the summary?
-revformat=$(git config --get ciabot.revformat)
-
-# Fully qualified domain name of the repo host. You can hardwire this
-# to make the script faster. The -f option works under Linux and FreeBSD,
-# but not OpenBSD and NetBSD. But under OpenBSD and NetBSD,
-# hostname without options gives the FQDN.
-if hostname -f >/dev/null 2>&1
-then
- hostname=`hostname -f`
-else
- hostname=`hostname`
-fi
-
-# 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. The 'generator' variable should change only
-# when the script itself gets a new home and maintainer.
-generator="http://www.catb.org/~esr/ciabot/ciabot.sh"
-version=3.5
-
-# Addresses for the e-mail
-from="CIABOT-NOREPLY@${hostname}"
-to="cia@cia.vc"
-
-# 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 $version"; 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/}
-
-case $revformat in
-raw) rev=$merged ;;
-short) rev='' ;;
-*) rev=$(git describe ${merged} 2>/dev/null) ;;
-esac
-[ -z ${rev} ] && rev=$(echo "$merged" | cut -c 1-12)
-
-# We discard 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.
-author=$(git log -1 '--pretty=format:%an <%ae>' $merged)
-author=$(echo "$author" | sed -n -e '/^.*<\([^@]*\).*$/s--\1-p')
-
-logmessage=$(git log -1 '--pretty=format:%s' $merged)
-ts=$(git log -1 '--pretty=format:%at' $merged)
-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>${version}</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 e1b7313072..87de809d23 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1,5 +1,3 @@
-#!bash
-#
# bash/zsh completion support for core Git.
#
# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
@@ -180,9 +178,9 @@ _get_comp_words_by_ref ()
}
fi
-__gitcompadd ()
+__gitcompappend ()
{
- local i=0
+ local i=${#COMPREPLY[@]}
for x in $1; do
if [[ "$x" == "$3"* ]]; then
COMPREPLY[i++]="$2$x$4"
@@ -190,6 +188,12 @@ __gitcompadd ()
done
}
+__gitcompadd ()
+{
+ COMPREPLY=()
+ __gitcompappend "$@"
+}
+
# Generates completion reply, appending a space to possible completion words,
# if necessary.
# It accepts 1 to 4 arguments:
@@ -220,6 +224,14 @@ __gitcomp ()
esac
}
+# Variation of __gitcomp_nl () that appends to the existing list of
+# completion candidates, COMPREPLY.
+__gitcomp_nl_append ()
+{
+ local IFS=$'\n'
+ __gitcompappend "$1" "${2-}" "${3-$cur}" "${4- }"
+}
+
# Generates completion reply from newline-separated possible completion words
# by appending a space to all of them.
# It accepts 1 to 4 arguments:
@@ -231,8 +243,8 @@ __gitcomp ()
# appended.
__gitcomp_nl ()
{
- local IFS=$'\n'
- __gitcompadd "$1" "${2-}" "${3-$cur}" "${4- }"
+ COMPREPLY=()
+ __gitcomp_nl_append "$@"
}
# Generates completion reply with compgen from newline-separated possible
@@ -673,7 +685,6 @@ __git_list_porcelain_commands ()
index-pack) : plumbing;;
init-db) : deprecated;;
local-fetch) : plumbing;;
- lost-found) : infrequent;;
ls-files) : plumbing;;
ls-remote) : plumbing;;
ls-tree) : plumbing;;
@@ -687,14 +698,12 @@ __git_list_porcelain_commands ()
pack-refs) : plumbing;;
parse-remote) : plumbing;;
patch-id) : plumbing;;
- peek-remote) : plumbing;;
prune) : plumbing;;
prune-packed) : plumbing;;
quiltimport) : import;;
read-tree) : plumbing;;
receive-pack) : plumbing;;
remote-*) : transport;;
- repo-config) : deprecated;;
rerere) : plumbing;;
rev-list) : plumbing;;
rev-parse) : plumbing;;
@@ -707,7 +716,6 @@ __git_list_porcelain_commands ()
ssh-*) : transport;;
stripspace) : plumbing;;
symbolic-ref) : plumbing;;
- tar-tree) : deprecated;;
unpack-file) : plumbing;;
unpack-objects) : plumbing;;
update-index) : plumbing;;
@@ -901,7 +909,7 @@ _git_add ()
esac
# XXX should we check for --update and --all options ?
- __git_complete_index_file "--others --modified"
+ __git_complete_index_file "--others --modified --directory --no-empty-directory"
}
_git_archive ()
@@ -1063,7 +1071,7 @@ _git_clean ()
esac
# XXX should we check for -x option ?
- __git_complete_index_file "--others"
+ __git_complete_index_file "--others --directory"
}
_git_clone ()
@@ -1188,7 +1196,7 @@ _git_diff ()
__git_complete_revlist_file
}
-__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
+__git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff
tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3 codecompare
"
@@ -1213,14 +1221,20 @@ _git_difftool ()
__git_complete_revlist_file
}
+__git_fetch_recurse_submodules="yes on-demand no"
+
__git_fetch_options="
--quiet --verbose --append --upload-pack --force --keep --depth=
- --tags --no-tags --all --prune --dry-run
+ --tags --no-tags --all --prune --dry-run --recurse-submodules=
"
_git_fetch ()
{
case "$cur" in
+ --recurse-submodules=*)
+ __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
+ return
+ ;;
--*)
__gitcomp "$__git_fetch_options"
return
@@ -1491,6 +1505,12 @@ _git_mergetool ()
_git_merge_base ()
{
+ case "$cur" in
+ --*)
+ __gitcomp "--octopus --independent --is-ancestor --fork-point"
+ return
+ ;;
+ esac
__gitcomp_nl "$(__git_refs)"
}
@@ -1569,6 +1589,10 @@ _git_pull ()
__git_complete_strategy && return
case "$cur" in
+ --recurse-submodules=*)
+ __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
+ return
+ ;;
--*)
__gitcomp "
--rebase --no-rebase
@@ -1581,6 +1605,8 @@ _git_pull ()
__git_complete_remote_or_refspec
}
+__git_push_recurse_submodules="check on-demand"
+
_git_push ()
{
case "$prev" in
@@ -1593,10 +1619,15 @@ _git_push ()
__gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
return
;;
+ --recurse-submodules=*)
+ __gitcomp "$__git_push_recurse_submodules" "" "${cur##--recurse-submodules=}"
+ return
+ ;;
--*)
__gitcomp "
--all --mirror --tags --dry-run --force --verbose
--receive-pack= --repo= --set-upstream
+ --recurse-submodules=
"
return
;;
@@ -1623,7 +1654,7 @@ _git_rebase ()
--preserve-merges --stat --no-stat
--committer-date-is-author-date --ignore-date
--ignore-whitespace --whitespace=
- --autosquash
+ --autosquash --fork-point --no-fork-point
"
return
@@ -1833,6 +1864,7 @@ _git_config ()
branch.*)
local pfx="${cur%.*}." cur_="${cur#*.}"
__gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
+ __gitcomp_nl_append $'autosetupmerge\nautosetuprebase\n' "$pfx" "$cur_"
return
;;
guitool.*.*)
@@ -1875,6 +1907,7 @@ _git_config ()
remote.*)
local pfx="${cur%.*}." cur_="${cur#*.}"
__gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
+ __gitcomp_nl_append "pushdefault" "$pfx" "$cur_"
return
;;
url.*.*)
@@ -1997,6 +2030,7 @@ _git_config ()
fetch.unpackLimit
format.attach
format.cc
+ format.coverLetter
format.headers
format.numbered
format.pretty
diff --git a/contrib/completion/git-completion.tcsh b/contrib/completion/git-completion.tcsh
index eaacaf0c3e..6104a42a23 100644
--- a/contrib/completion/git-completion.tcsh
+++ b/contrib/completion/git-completion.tcsh
@@ -1,5 +1,3 @@
-#!tcsh
-#
# tcsh completion support for core Git.
#
# Copyright (C) 2012 Marc Khouzam <marc.khouzam@gmail.com>
diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
index fac5e711eb..6b77968572 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -30,10 +30,10 @@ if [ -z "$script" ]; then
local -a locations
local e
locations=(
+ $(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
'/etc/bash_completion.d/git' # fedora, old debian
'/usr/share/bash-completion/completions/git' # arch, ubuntu, new debian
'/usr/share/bash-completion/git' # gentoo
- $(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
)
for e in $locations; do
test -f $e && script="$e" && break
@@ -76,6 +76,14 @@ __gitcomp_nl ()
compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
}
+__gitcomp_nl_append ()
+{
+ emulate -L zsh
+
+ local IFS=$'\n'
+ compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
+}
+
__gitcomp_file ()
{
emulate -L zsh
diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index 998722cf7f..7b732d2aeb 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -60,6 +60,7 @@
# of values:
#
# verbose show number of commits ahead/behind (+/-) upstream
+# name if verbose, then also show the upstream abbrev name
# legacy don't use the '--count' option available in recent
# versions of git-rev-list
# git always compare HEAD to @{upstream}
@@ -94,7 +95,7 @@ __git_ps1_show_upstream ()
{
local key value
local svn_remote svn_url_pattern count n
- local upstream=git legacy="" verbose=""
+ local upstream=git legacy="" verbose="" name=""
svn_remote=()
# get some config options from git-config
@@ -122,6 +123,7 @@ __git_ps1_show_upstream ()
git|svn) upstream="$option" ;;
verbose) verbose=1 ;;
legacy) legacy=1 ;;
+ name) name=1 ;;
esac
done
@@ -204,6 +206,9 @@ __git_ps1_show_upstream ()
*) # diverged from upstream
p=" u+${count#* }-${count% *}" ;;
esac
+ if [[ -n "$count" && -n "$name" ]]; then
+ p="$p $(git rev-parse --abbrev-ref "$upstream" 2>/dev/null)"
+ fi
fi
}
diff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts
index d80f7d1b6e..dbe2abf277 100755
--- a/contrib/contacts/git-contacts
+++ b/contrib/contacts/git-contacts
@@ -59,11 +59,11 @@ sub import_commits {
}
sub get_blame {
- my ($commits, $source, $start, $len, $from) = @_;
- $len = 1 unless defined($len);
- return if $len == 0;
+ my ($commits, $source, $from, $ranges) = @_;
+ return unless @$ranges;
open my $f, '-|',
- qw(git blame --porcelain -C), '-L', "$start,+$len",
+ qw(git blame --porcelain -C),
+ map({"-L$_->[0],+$_->[1]"} @$ranges),
'--since', $since, "$from^", '--', $source or die;
while (<$f>) {
if (/^([0-9a-f]{40}) \d+ \d+ \d+$/) {
@@ -76,8 +76,17 @@ sub get_blame {
close $f;
}
+sub blame_sources {
+ my ($sources, $commits) = @_;
+ for my $s (keys %$sources) {
+ for my $id (keys %{$sources->{$s}}) {
+ get_blame($commits, $s, $id, $sources->{$s}{$id});
+ }
+ }
+}
+
sub scan_patches {
- my ($commits, $id, $f) = @_;
+ my ($sources, $id, $f) = @_;
my $source;
while (<$f>) {
if (/^From ([0-9a-f]{40}) Mon Sep 17 00:00:00 2001$/) {
@@ -87,10 +96,9 @@ sub scan_patches {
next unless $id;
if (m{^--- (?:a/(.+)|/dev/null)$}) {
$source = $1;
- } elsif (/^--- /) {
- die "Cannot parse hunk source: $_\n";
} elsif (/^@@ -(\d+)(?:,(\d+))?/ && $source) {
- get_blame($commits, $source, $1, $2, $id);
+ my $len = defined($2) ? $2 : 1;
+ push @{$sources->{$source}{$id}}, [$1, $len] if $len;
}
}
}
@@ -163,13 +171,20 @@ for (@ARGV) {
}
}
-my %commits;
+my %sources;
for (@files) {
- scan_patch_file(\%commits, $_);
+ scan_patch_file(\%sources, $_);
}
if (@rev_args) {
- scan_rev_args(\%commits, \@rev_args)
+ scan_rev_args(\%sources, \@rev_args)
}
+
+my $toplevel = `git rev-parse --show-toplevel`;
+chomp $toplevel;
+chdir($toplevel) or die "chdir failure: $toplevel: $!\n";
+
+my %commits;
+blame_sources(\%sources, \%commits);
import_commits(\%commits);
my $contacts = {};
diff --git a/contrib/credential/gnome-keyring/Makefile b/contrib/credential/gnome-keyring/Makefile
index e6561d8db6..c3c7c98aa1 100644
--- a/contrib/credential/gnome-keyring/Makefile
+++ b/contrib/credential/gnome-keyring/Makefile
@@ -8,8 +8,8 @@ CFLAGS = -g -O2 -Wall
-include ../../../config.mak.autogen
-include ../../../config.mak
-INCS:=$(shell pkg-config --cflags gnome-keyring-1)
-LIBS:=$(shell pkg-config --libs gnome-keyring-1)
+INCS:=$(shell pkg-config --cflags gnome-keyring-1 glib-2.0)
+LIBS:=$(shell pkg-config --libs gnome-keyring-1 glib-2.0)
SRCS:=$(MAIN).c
OBJS:=$(SRCS:.c=.o)
diff --git a/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c b/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c
index f2cdefee60..2a317fca44 100644
--- a/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c
+++ b/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c
@@ -25,135 +25,148 @@
#include <stdio.h>
#include <string.h>
-#include <stdarg.h>
#include <stdlib.h>
-#include <errno.h>
+#include <glib.h>
#include <gnome-keyring.h>
-/*
- * This credential struct and API is simplified from git's credential.{h,c}
- */
-struct credential
-{
- char *protocol;
- char *host;
- unsigned short port;
- char *path;
- char *username;
- char *password;
-};
+#ifdef GNOME_KEYRING_DEFAULT
-#define CREDENTIAL_INIT \
- { NULL,NULL,0,NULL,NULL,NULL }
+ /* Modern gnome-keyring */
-void credential_init(struct credential *c);
-void credential_clear(struct credential *c);
-int credential_read(struct credential *c);
-void credential_write(const struct credential *c);
+#include <gnome-keyring-memory.h>
-typedef int (*credential_op_cb)(struct credential*);
+#else
-struct credential_operation
-{
- char *name;
- credential_op_cb op;
-};
+ /*
+ * Support ancient gnome-keyring, circ. RHEL 5.X.
+ * GNOME_KEYRING_DEFAULT seems to have been introduced with Gnome 2.22,
+ * and the other features roughly around Gnome 2.20, 6 months before.
+ * Ubuntu 8.04 used Gnome 2.22 (I think). Not sure any distro used 2.20.
+ * So the existence/non-existence of GNOME_KEYRING_DEFAULT seems like
+ * a decent thing to use as an indicator.
+ */
-#define CREDENTIAL_OP_END \
- { NULL,NULL }
+#define GNOME_KEYRING_DEFAULT NULL
/*
- * Table with operation callbacks is defined in concrete
- * credential helper implementation and contains entries
- * like { "get", function_to_get_credential } terminated
- * by CREDENTIAL_OP_END.
+ * ancient gnome-keyring returns DENIED when an entry is not found.
+ * Setting NO_MATCH to DENIED will prevent us from reporting DENIED
+ * errors during get and erase operations, but we will still report
+ * DENIED errors during a store.
*/
-struct credential_operation const credential_helper_ops[];
+#define GNOME_KEYRING_RESULT_NO_MATCH GNOME_KEYRING_RESULT_DENIED
-/* ---------------- common helper functions ----------------- */
+#define gnome_keyring_memory_alloc g_malloc
+#define gnome_keyring_memory_free gnome_keyring_free_password
+#define gnome_keyring_memory_strdup g_strdup
-static inline void free_password(char *password)
+static const char *gnome_keyring_result_to_message(GnomeKeyringResult result)
{
- char *c = password;
- if (!password)
- return;
-
- while (*c) *c++ = '\0';
- free(password);
+ switch (result) {
+ case GNOME_KEYRING_RESULT_OK:
+ return "OK";
+ case GNOME_KEYRING_RESULT_DENIED:
+ return "Denied";
+ case GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON:
+ return "No Keyring Daemon";
+ case GNOME_KEYRING_RESULT_ALREADY_UNLOCKED:
+ return "Already UnLocked";
+ case GNOME_KEYRING_RESULT_NO_SUCH_KEYRING:
+ return "No Such Keyring";
+ case GNOME_KEYRING_RESULT_BAD_ARGUMENTS:
+ return "Bad Arguments";
+ case GNOME_KEYRING_RESULT_IO_ERROR:
+ return "IO Error";
+ case GNOME_KEYRING_RESULT_CANCELLED:
+ return "Cancelled";
+ case GNOME_KEYRING_RESULT_ALREADY_EXISTS:
+ return "Already Exists";
+ default:
+ return "Unknown Error";
+ }
}
-static inline void warning(const char *fmt, ...)
+/*
+ * Support really ancient gnome-keyring, circ. RHEL 4.X.
+ * Just a guess for the Glib version. Glib 2.8 was roughly Gnome 2.12 ?
+ * Which was released with gnome-keyring 0.4.3 ??
+ */
+#if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 8
+
+static void gnome_keyring_done_cb(GnomeKeyringResult result, gpointer user_data)
{
- va_list ap;
+ gpointer *data = (gpointer *)user_data;
+ int *done = (int *)data[0];
+ GnomeKeyringResult *r = (GnomeKeyringResult *)data[1];
- va_start(ap, fmt);
- fprintf(stderr, "warning: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n" );
- va_end(ap);
+ *r = result;
+ *done = 1;
}
-static inline void error(const char *fmt, ...)
+static void wait_for_request_completion(int *done)
{
- va_list ap;
-
- va_start(ap, fmt);
- fprintf(stderr, "error: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n" );
- va_end(ap);
+ GMainContext *mc = g_main_context_default();
+ while (!*done)
+ g_main_context_iteration(mc, TRUE);
}
-static inline void die(const char *fmt, ...)
+static GnomeKeyringResult gnome_keyring_item_delete_sync(const char *keyring, guint32 id)
{
- va_list ap;
+ int done = 0;
+ GnomeKeyringResult result;
+ gpointer data[] = { &done, &result };
- va_start(ap,fmt);
- error(fmt, ap);
- va_end(ap);
- exit(EXIT_FAILURE);
-}
+ gnome_keyring_item_delete(keyring, id, gnome_keyring_done_cb, data,
+ NULL);
-static inline void die_errno(int err)
-{
- error("%s", strerror(err));
- exit(EXIT_FAILURE);
+ wait_for_request_completion(&done);
+
+ return result;
}
-static inline char *xstrdup(const char *str)
-{
- char *ret = strdup(str);
- if (!ret)
- die_errno(errno);
+#endif
+#endif
- return ret;
-}
+/*
+ * This credential struct and API is simplified from git's credential.{h,c}
+ */
+struct credential {
+ char *protocol;
+ char *host;
+ unsigned short port;
+ char *path;
+ char *username;
+ char *password;
+};
+
+#define CREDENTIAL_INIT { NULL, NULL, 0, NULL, NULL, NULL }
+
+typedef int (*credential_op_cb)(struct credential *);
+
+struct credential_operation {
+ char *name;
+ credential_op_cb op;
+};
+
+#define CREDENTIAL_OP_END { NULL, NULL }
/* ----------------- GNOME Keyring functions ----------------- */
/* create a special keyring option string, if path is given */
-static char* keyring_object(struct credential *c)
+static char *keyring_object(struct credential *c)
{
- char* object = NULL;
-
if (!c->path)
- return object;
+ return NULL;
- object = (char*) malloc(strlen(c->host)+strlen(c->path)+8);
- if(!object)
- die_errno(errno);
+ if (c->port)
+ return g_strdup_printf("%s:%hd/%s", c->host, c->port, c->path);
- if(c->port)
- sprintf(object,"%s:%hd/%s",c->host,c->port,c->path);
- else
- sprintf(object,"%s/%s",c->host,c->path);
-
- return object;
+ return g_strdup_printf("%s/%s", c->host, c->path);
}
-int keyring_get(struct credential *c)
+static int keyring_get(struct credential *c)
{
- char* object = NULL;
+ char *object = NULL;
GList *entries;
GnomeKeyringNetworkPasswordData *password_data;
GnomeKeyringResult result;
@@ -173,7 +186,7 @@ int keyring_get(struct credential *c)
c->port,
&entries);
- free(object);
+ g_free(object);
if (result == GNOME_KEYRING_RESULT_NO_MATCH)
return EXIT_SUCCESS;
@@ -182,18 +195,18 @@ int keyring_get(struct credential *c)
return EXIT_SUCCESS;
if (result != GNOME_KEYRING_RESULT_OK) {
- error("%s",gnome_keyring_result_to_message(result));
+ g_critical("%s", gnome_keyring_result_to_message(result));
return EXIT_FAILURE;
}
/* pick the first one from the list */
- password_data = (GnomeKeyringNetworkPasswordData *) entries->data;
+ password_data = (GnomeKeyringNetworkPasswordData *)entries->data;
- free_password(c->password);
- c->password = xstrdup(password_data->password);
+ gnome_keyring_memory_free(c->password);
+ c->password = gnome_keyring_memory_strdup(password_data->password);
if (!c->username)
- c->username = xstrdup(password_data->user);
+ c->username = g_strdup(password_data->user);
gnome_keyring_network_password_list_free(entries);
@@ -201,10 +214,11 @@ int keyring_get(struct credential *c)
}
-int keyring_store(struct credential *c)
+static int keyring_store(struct credential *c)
{
guint32 item_id;
- char *object = NULL;
+ char *object = NULL;
+ GnomeKeyringResult result;
/*
* Sanity check that what we are storing is actually sensible.
@@ -219,7 +233,7 @@ int keyring_store(struct credential *c)
object = keyring_object(c);
- gnome_keyring_set_network_password_sync(
+ result = gnome_keyring_set_network_password_sync(
GNOME_KEYRING_DEFAULT,
c->username,
NULL /* domain */,
@@ -231,13 +245,20 @@ int keyring_store(struct credential *c)
c->password,
&item_id);
- free(object);
+ g_free(object);
+
+ if (result != GNOME_KEYRING_RESULT_OK &&
+ result != GNOME_KEYRING_RESULT_CANCELLED) {
+ g_critical("%s", gnome_keyring_result_to_message(result));
+ return EXIT_FAILURE;
+ }
+
return EXIT_SUCCESS;
}
-int keyring_erase(struct credential *c)
+static int keyring_erase(struct credential *c)
{
- char *object = NULL;
+ char *object = NULL;
GList *entries;
GnomeKeyringNetworkPasswordData *password_data;
GnomeKeyringResult result;
@@ -265,7 +286,7 @@ int keyring_erase(struct credential *c)
c->port,
&entries);
- free(object);
+ g_free(object);
if (result == GNOME_KEYRING_RESULT_NO_MATCH)
return EXIT_SUCCESS;
@@ -273,23 +294,21 @@ int keyring_erase(struct credential *c)
if (result == GNOME_KEYRING_RESULT_CANCELLED)
return EXIT_SUCCESS;
- if (result != GNOME_KEYRING_RESULT_OK)
- {
- error("%s",gnome_keyring_result_to_message(result));
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ g_critical("%s", gnome_keyring_result_to_message(result));
return EXIT_FAILURE;
}
/* pick the first one from the list (delete all matches?) */
- password_data = (GnomeKeyringNetworkPasswordData *) entries->data;
+ password_data = (GnomeKeyringNetworkPasswordData *)entries->data;
result = gnome_keyring_item_delete_sync(
password_data->keyring, password_data->item_id);
gnome_keyring_network_password_list_free(entries);
- if (result != GNOME_KEYRING_RESULT_OK)
- {
- error("%s",gnome_keyring_result_to_message(result));
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ g_critical("%s", gnome_keyring_result_to_message(result));
return EXIT_FAILURE;
}
@@ -300,9 +319,8 @@ int keyring_erase(struct credential *c)
* Table with helper operation callbacks, used by generic
* credential helper main function.
*/
-struct credential_operation const credential_helper_ops[] =
-{
- { "get", keyring_get },
+static struct credential_operation const credential_helper_ops[] = {
+ { "get", keyring_get },
{ "store", keyring_store },
{ "erase", keyring_erase },
CREDENTIAL_OP_END
@@ -310,67 +328,70 @@ struct credential_operation const credential_helper_ops[] =
/* ------------------ credential functions ------------------ */
-void credential_init(struct credential *c)
+static void credential_init(struct credential *c)
{
memset(c, 0, sizeof(*c));
}
-void credential_clear(struct credential *c)
+static void credential_clear(struct credential *c)
{
- free(c->protocol);
- free(c->host);
- free(c->path);
- free(c->username);
- free_password(c->password);
+ g_free(c->protocol);
+ g_free(c->host);
+ g_free(c->path);
+ g_free(c->username);
+ gnome_keyring_memory_free(c->password);
credential_init(c);
}
-int credential_read(struct credential *c)
+static int credential_read(struct credential *c)
{
- char buf[1024];
- ssize_t line_len = 0;
- char *key = buf;
- char *value;
+ char *buf;
+ size_t line_len;
+ char *key;
+ char *value;
- while (fgets(buf, sizeof(buf), stdin))
- {
+ key = buf = gnome_keyring_memory_alloc(1024);
+
+ while (fgets(buf, 1024, stdin)) {
line_len = strlen(buf);
- if(buf[line_len-1]=='\n')
- buf[--line_len]='\0';
+ if (line_len && buf[line_len-1] == '\n')
+ buf[--line_len] = '\0';
- if(!line_len)
+ if (!line_len)
break;
- value = strchr(buf,'=');
- if(!value) {
- warning("invalid credential line: %s", key);
+ value = strchr(buf, '=');
+ if (!value) {
+ g_warning("invalid credential line: %s", key);
+ gnome_keyring_memory_free(buf);
return -1;
}
*value++ = '\0';
if (!strcmp(key, "protocol")) {
- free(c->protocol);
- c->protocol = xstrdup(value);
+ g_free(c->protocol);
+ c->protocol = g_strdup(value);
} else if (!strcmp(key, "host")) {
- free(c->host);
- c->host = xstrdup(value);
- value = strrchr(c->host,':');
+ g_free(c->host);
+ c->host = g_strdup(value);
+ value = strrchr(c->host, ':');
if (value) {
*value++ = '\0';
c->port = atoi(value);
}
} else if (!strcmp(key, "path")) {
- free(c->path);
- c->path = xstrdup(value);
+ g_free(c->path);
+ c->path = g_strdup(value);
} else if (!strcmp(key, "username")) {
- free(c->username);
- c->username = xstrdup(value);
+ g_free(c->username);
+ c->username = g_strdup(value);
} else if (!strcmp(key, "password")) {
- free_password(c->password);
- c->password = xstrdup(value);
- while (*value) *value++ = '\0';
+ gnome_keyring_memory_free(c->password);
+ c->password = gnome_keyring_memory_strdup(value);
+ while (*value)
+ *value++ = '\0';
}
/*
* Ignore other lines; we don't know what they mean, but
@@ -378,17 +399,20 @@ int credential_read(struct credential *c)
* learn new lines, and the helpers are updated to match.
*/
}
+
+ gnome_keyring_memory_free(buf);
+
return 0;
}
-void credential_write_item(FILE *fp, const char *key, const char *value)
+static void credential_write_item(FILE *fp, const char *key, const char *value)
{
if (!value)
return;
fprintf(fp, "%s=%s\n", key, value);
}
-void credential_write(const struct credential *c)
+static void credential_write(const struct credential *c)
{
/* only write username/password, if set */
credential_write_item(stdout, "username", c->username);
@@ -398,16 +422,16 @@ void credential_write(const struct credential *c)
static void usage(const char *name)
{
struct credential_operation const *try_op = credential_helper_ops;
- const char *basename = strrchr(name,'/');
+ const char *basename = strrchr(name, '/');
basename = (basename) ? basename + 1 : name;
fprintf(stderr, "usage: %s <", basename);
- while(try_op->name) {
- fprintf(stderr,"%s",(try_op++)->name);
- if(try_op->name)
- fprintf(stderr,"%s","|");
+ while (try_op->name) {
+ fprintf(stderr, "%s", (try_op++)->name);
+ if (try_op->name)
+ fprintf(stderr, "%s", "|");
}
- fprintf(stderr,"%s",">\n");
+ fprintf(stderr, "%s", ">\n");
}
int main(int argc, char *argv[])
@@ -415,23 +439,25 @@ int main(int argc, char *argv[])
int ret = EXIT_SUCCESS;
struct credential_operation const *try_op = credential_helper_ops;
- struct credential cred = CREDENTIAL_INIT;
+ struct credential cred = CREDENTIAL_INIT;
if (!argv[1]) {
usage(argv[0]);
- goto out;
+ exit(EXIT_FAILURE);
}
+ g_set_application_name("Git Credential Helper");
+
/* lookup operation callback */
- while(try_op->name && strcmp(argv[1], try_op->name))
+ while (try_op->name && strcmp(argv[1], try_op->name))
try_op++;
/* unsupported operation given -- ignore silently */
- if(!try_op->name || !try_op->op)
+ if (!try_op->name || !try_op->op)
goto out;
ret = credential_read(&cred);
- if(ret)
+ if (ret)
goto out;
/* perform credential operation */
diff --git a/contrib/credential/netrc/git-credential-netrc b/contrib/credential/netrc/git-credential-netrc
index 6c51c43885..1571a7b269 100755
--- a/contrib/credential/netrc/git-credential-netrc
+++ b/contrib/credential/netrc/git-credential-netrc
@@ -369,7 +369,9 @@ sub find_netrc_entry {
{
my $entry_text = join ', ', map { "$_=$entry->{$_}" } keys %$entry;
foreach my $check (sort keys %$query) {
- if (defined $query->{$check}) {
+ if (!defined $entry->{$check}) {
+ log_debug("OK: entry has no $check token, so any value satisfies check $check");
+ } elsif (defined $query->{$check}) {
log_debug("compare %s [%s] to [%s] (entry: %s)",
$check,
$entry->{$check},
diff --git a/contrib/examples/git-log.sh b/contrib/examples/git-log.sh
new file mode 100755
index 0000000000..c2ea71cf14
--- /dev/null
+++ b/contrib/examples/git-log.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Linus Torvalds
+#
+
+USAGE='[--max-count=<n>] [<since>..<limit>] [--pretty=<format>] [git-rev-list options]'
+SUBDIRECTORY_OK='Yes'
+. git-sh-setup
+
+revs=$(git-rev-parse --revs-only --no-flags --default HEAD "$@") || exit
+[ "$revs" ] || {
+ die "No HEAD ref"
+}
+git-rev-list --pretty $(git-rev-parse --default HEAD "$@") |
+LESS=-S ${PAGER:-less}
diff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh
index 7b922c3948..a5e42a9f01 100755
--- a/contrib/examples/git-merge.sh
+++ b/contrib/examples/git-merge.sh
@@ -263,7 +263,7 @@ fi
# This could be traditional "merge <msg> HEAD <commit>..." and the
# way we can tell it is to see if the second token is HEAD, but some
-# people might have misused the interface and used a committish that
+# people might have misused the interface and used a commit-ish that
# is the same as HEAD there instead. Traditional format never would
# have "-m" so it is an additional safety measure to check for it.
diff --git a/contrib/examples/git-repack.sh b/contrib/examples/git-repack.sh
new file mode 100755
index 0000000000..757933174e
--- /dev/null
+++ b/contrib/examples/git-repack.sh
@@ -0,0 +1,194 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Linus Torvalds
+#
+
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git repack [options]
+--
+a pack everything in a single pack
+A same as -a, and turn unreachable objects loose
+d remove redundant packs, and run git-prune-packed
+f pass --no-reuse-delta to git-pack-objects
+F pass --no-reuse-object to git-pack-objects
+n do not run git-update-server-info
+q,quiet be quiet
+l pass --local to git-pack-objects
+unpack-unreachable= with -A, do not loosen objects older than this
+ Packing constraints
+window= size of the window used for delta compression
+window-memory= same as the above, but limit memory size instead of entries count
+depth= limits the maximum delta depth
+max-pack-size= maximum size of each packfile
+"
+SUBDIRECTORY_OK='Yes'
+. git-sh-setup
+
+no_update_info= all_into_one= remove_redundant= unpack_unreachable=
+local= no_reuse= extra=
+while test $# != 0
+do
+ case "$1" in
+ -n) no_update_info=t ;;
+ -a) all_into_one=t ;;
+ -A) all_into_one=t
+ unpack_unreachable=--unpack-unreachable ;;
+ --unpack-unreachable)
+ unpack_unreachable="--unpack-unreachable=$2"; shift ;;
+ -d) remove_redundant=t ;;
+ -q) GIT_QUIET=t ;;
+ -f) no_reuse=--no-reuse-delta ;;
+ -F) no_reuse=--no-reuse-object ;;
+ -l) local=--local ;;
+ --max-pack-size|--window|--window-memory|--depth)
+ extra="$extra $1=$2"; shift ;;
+ --) shift; break;;
+ *) usage ;;
+ esac
+ shift
+done
+
+case "`git config --bool repack.usedeltabaseoffset || echo true`" in
+true)
+ extra="$extra --delta-base-offset" ;;
+esac
+
+PACKDIR="$GIT_OBJECT_DIRECTORY/pack"
+PACKTMP="$PACKDIR/.tmp-$$-pack"
+rm -f "$PACKTMP"-*
+trap 'rm -f "$PACKTMP"-*' 0 1 2 3 15
+
+# There will be more repacking strategies to come...
+case ",$all_into_one," in
+,,)
+ args='--unpacked --incremental'
+ ;;
+,t,)
+ args= existing=
+ if [ -d "$PACKDIR" ]; then
+ for e in `cd "$PACKDIR" && find . -type f -name '*.pack' \
+ | sed -e 's/^\.\///' -e 's/\.pack$//'`
+ do
+ if [ -e "$PACKDIR/$e.keep" ]; then
+ : keep
+ else
+ existing="$existing $e"
+ fi
+ done
+ if test -n "$existing" -a -n "$unpack_unreachable" -a \
+ -n "$remove_redundant"
+ then
+ # This may have arbitrary user arguments, so we
+ # have to protect it against whitespace splitting
+ # when it gets run as "pack-objects $args" later.
+ # Fortunately, we know it's an approxidate, so we
+ # can just use dots instead.
+ args="$args $(echo "$unpack_unreachable" | tr ' ' .)"
+ fi
+ fi
+ ;;
+esac
+
+mkdir -p "$PACKDIR" || exit
+
+args="$args $local ${GIT_QUIET:+-q} $no_reuse$extra"
+names=$(git pack-objects --keep-true-parents --honor-pack-keep --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
+ exit 1
+if [ -z "$names" ]; then
+ say Nothing new to pack.
+fi
+
+# Ok we have prepared all new packfiles.
+
+# First see if there are packs of the same name and if so
+# if we can move them out of the way (this can happen if we
+# repacked immediately after packing fully.
+rollback=
+failed=
+for name in $names
+do
+ for sfx in pack idx
+ do
+ file=pack-$name.$sfx
+ test -f "$PACKDIR/$file" || continue
+ rm -f "$PACKDIR/old-$file" &&
+ mv "$PACKDIR/$file" "$PACKDIR/old-$file" || {
+ failed=t
+ break
+ }
+ rollback="$rollback $file"
+ done
+ test -z "$failed" || break
+done
+
+# If renaming failed for any of them, roll the ones we have
+# already renamed back to their original names.
+if test -n "$failed"
+then
+ rollback_failure=
+ for file in $rollback
+ do
+ mv "$PACKDIR/old-$file" "$PACKDIR/$file" ||
+ rollback_failure="$rollback_failure $file"
+ done
+ if test -n "$rollback_failure"
+ then
+ echo >&2 "WARNING: Some packs in use have been renamed by"
+ echo >&2 "WARNING: prefixing old- to their name, in order to"
+ echo >&2 "WARNING: replace them with the new version of the"
+ echo >&2 "WARNING: file. But the operation failed, and"
+ echo >&2 "WARNING: attempt to rename them back to their"
+ echo >&2 "WARNING: original names also failed."
+ echo >&2 "WARNING: Please rename them in $PACKDIR manually:"
+ for file in $rollback_failure
+ do
+ echo >&2 "WARNING: old-$file -> $file"
+ done
+ fi
+ exit 1
+fi
+
+# Now the ones with the same name are out of the way...
+fullbases=
+for name in $names
+do
+ fullbases="$fullbases pack-$name"
+ chmod a-w "$PACKTMP-$name.pack"
+ chmod a-w "$PACKTMP-$name.idx"
+ mv -f "$PACKTMP-$name.pack" "$PACKDIR/pack-$name.pack" &&
+ mv -f "$PACKTMP-$name.idx" "$PACKDIR/pack-$name.idx" ||
+ exit
+done
+
+# Remove the "old-" files
+for name in $names
+do
+ rm -f "$PACKDIR/old-pack-$name.idx"
+ rm -f "$PACKDIR/old-pack-$name.pack"
+done
+
+# End of pack replacement.
+
+if test "$remove_redundant" = t
+then
+ # We know $existing are all redundant.
+ if [ -n "$existing" ]
+ then
+ ( cd "$PACKDIR" &&
+ for e in $existing
+ do
+ case " $fullbases " in
+ *" $e "*) ;;
+ *) rm -f "$e.pack" "$e.idx" "$e.keep" ;;
+ esac
+ done
+ )
+ fi
+ git prune-packed ${GIT_QUIET:+-q}
+fi
+
+case "$no_update_info" in
+t) : ;;
+*) git update-server-info ;;
+esac
diff --git a/contrib/examples/git-whatchanged.sh b/contrib/examples/git-whatchanged.sh
new file mode 100755
index 0000000000..2edbdc6d99
--- /dev/null
+++ b/contrib/examples/git-whatchanged.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+USAGE='[-p] [--max-count=<n>] [<since>..<limit>] [--pretty=<format>] [-m] [git-diff-tree options] [git-rev-list options]'
+SUBDIRECTORY_OK='Yes'
+. git-sh-setup
+
+diff_tree_flags=$(git-rev-parse --sq --no-revs --flags "$@") || exit
+case "$0" in
+*whatchanged)
+ count=
+ test -z "$diff_tree_flags" &&
+ diff_tree_flags=$(git config --get whatchanged.difftree)
+ diff_tree_default_flags='-c -M --abbrev' ;;
+*show)
+ count=-n1
+ test -z "$diff_tree_flags" &&
+ diff_tree_flags=$(git config --get show.difftree)
+ diff_tree_default_flags='--cc --always' ;;
+esac
+test -z "$diff_tree_flags" &&
+ diff_tree_flags="$diff_tree_default_flags"
+
+rev_list_args=$(git-rev-parse --sq --default HEAD --revs-only "$@") &&
+diff_tree_args=$(git-rev-parse --sq --no-revs --no-flags "$@") &&
+
+eval "git-rev-list $count $rev_list_args" |
+eval "git-diff-tree --stdin --pretty -r $diff_tree_flags $diff_tree_args" |
+LESS="$LESS -S" ${PAGER:-less}
diff --git a/contrib/git-resurrect.sh b/contrib/git-resurrect.sh
index a4ed4c3c62..d7e97bbc76 100755
--- a/contrib/git-resurrect.sh
+++ b/contrib/git-resurrect.sh
@@ -10,6 +10,7 @@ is rather slow but allows you to resurrect other people's topic
branches."
OPTIONS_KEEPDASHDASH=
+OPTIONS_STUCKLONG=
OPTIONS_SPEC="\
git resurrect $USAGE
--
diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview
index 4c99dfb903..4e23c650fe 100755
--- a/contrib/gitview/gitview
+++ b/contrib/gitview/gitview
@@ -1205,7 +1205,7 @@ class GitView(object):
#The first parent always continue on the same line
try:
- # check we alreay have the value
+ # check we already have the value
tmp_node_pos = self.nodepos[commit.parent_sha1[0]]
except KeyError:
self.colours[commit.parent_sha1[0]] = colour
diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email
index 153115029d..8747b84334 100755
--- a/contrib/hooks/post-receive-email
+++ b/contrib/hooks/post-receive-email
@@ -22,7 +22,6 @@
# For example, on debian the hook is stored in
# /usr/share/git-core/contrib/hooks/post-receive-email:
#
-# chmod a+x post-receive-email
# cd /path/to/your/repository.git
# ln -sf /usr/share/git-core/contrib/hooks/post-receive-email hooks/post-receive
#
@@ -242,6 +241,9 @@ generate_email_header()
cat <<-EOF
To: $recipients
Subject: ${emailprefix}$projectdesc $refname_type $short_refname ${change_type}d. $describe
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset=utf-8
+ Content-Transfer-Encoding: 8bit
X-Git-Refname: $refname
X-Git-Reftype: $refname_type
X-Git-Oldrev: $oldrev
@@ -471,7 +473,7 @@ generate_delete_branch_email()
echo " was $oldrev"
echo ""
echo $LOGBEGIN
- git show -s --pretty=oneline $oldrev
+ git diff-tree -s --always --encoding=UTF-8 --pretty=oneline $oldrev
echo $LOGEND
}
@@ -547,11 +549,11 @@ generate_atag_email()
# performed on them
if [ -n "$prevtag" ]; then
# Show changes since the previous release
- git rev-list --pretty=short "$prevtag..$newrev" | git shortlog
+ git shortlog "$prevtag..$newrev"
else
# No previous tag, show all the changes since time
# began
- git rev-list --pretty=short $newrev | git shortlog
+ git shortlog $newrev
fi
;;
*)
@@ -571,7 +573,7 @@ generate_delete_atag_email()
echo " was $oldrev"
echo ""
echo $LOGBEGIN
- git show -s --pretty=oneline $oldrev
+ git diff-tree -s --always --encoding=UTF-8 --pretty=oneline $oldrev
echo $LOGEND
}
@@ -617,7 +619,7 @@ generate_general_email()
echo ""
if [ "$newrev_type" = "commit" ]; then
echo $LOGBEGIN
- git show --no-color --root -s --pretty=medium $newrev
+ git diff-tree -s --always --encoding=UTF-8 --pretty=medium $newrev
echo $LOGEND
else
# What can we do here? The tag marks an object that is not
@@ -636,7 +638,7 @@ generate_delete_general_email()
echo " was $oldrev"
echo ""
echo $LOGBEGIN
- git show -s --pretty=oneline $oldrev
+ git diff-tree -s --always --encoding=UTF-8 --pretty=oneline $oldrev
echo $LOGEND
}
diff --git a/contrib/hooks/pre-auto-gc-battery b/contrib/hooks/pre-auto-gc-battery
index 1f914c94aa..9d0c2d1990 100644..100755
--- a/contrib/hooks/pre-auto-gc-battery
+++ b/contrib/hooks/pre-auto-gc-battery
@@ -13,7 +13,6 @@
# For example, if the hook is stored in
# /usr/share/git-core/contrib/hooks/pre-auto-gc-battery:
#
-# chmod a+x pre-auto-gc-battery
# cd /path/to/your/repository.git
# ln -sf /usr/share/git-core/contrib/hooks/pre-auto-gc-battery \
# hooks/pre-auto-gc
diff --git a/contrib/hooks/setgitperms.perl b/contrib/hooks/setgitperms.perl
index 2770a1b1d2..2770a1b1d2 100644..100755
--- a/contrib/hooks/setgitperms.perl
+++ b/contrib/hooks/setgitperms.perl
diff --git a/contrib/hooks/update-paranoid b/contrib/hooks/update-paranoid
index d18b317b2f..d18b317b2f 100644..100755
--- a/contrib/hooks/update-paranoid
+++ b/contrib/hooks/update-paranoid
diff --git a/contrib/mw-to-git/Makefile b/contrib/mw-to-git/Makefile
index 76fcd4defc..a4b6f7a2cd 100644
--- a/contrib/mw-to-git/Makefile
+++ b/contrib/mw-to-git/Makefile
@@ -18,14 +18,25 @@ SCRIPT_PERL+=git-mw.perl
GIT_ROOT_DIR=../..
HERE=contrib/mw-to-git/
+INSTALL = install
+
SCRIPT_PERL_FULL=$(patsubst %,$(HERE)/%,$(SCRIPT_PERL))
INSTLIBDIR=$(shell $(MAKE) -C $(GIT_ROOT_DIR)/perl \
-s --no-print-directory instlibdir)
+DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
+INSTLIBDIR_SQ = $(subst ','\'',$(INSTLIBDIR))
all: build
+test: all
+ $(MAKE) -C t
+
+check: perlcritic test
+
install_pm:
- install $(GIT_MEDIAWIKI_PM) $(INSTLIBDIR)/$(GIT_MEDIAWIKI_PM)
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(INSTLIBDIR_SQ)/Git'
+ $(INSTALL) -m 644 $(GIT_MEDIAWIKI_PM) \
+ '$(DESTDIR_SQ)$(INSTLIBDIR_SQ)/$(GIT_MEDIAWIKI_PM)'
build:
$(MAKE) -C $(GIT_ROOT_DIR) SCRIPT_PERL="$(SCRIPT_PERL_FULL)" \
@@ -38,7 +49,9 @@ install: install_pm
clean:
$(MAKE) -C $(GIT_ROOT_DIR) SCRIPT_PERL="$(SCRIPT_PERL_FULL)" \
clean-perl-script
- rm $(INSTLIBDIR)/$(GIT_MEDIAWIKI_PM)
perlcritic:
- perlcritic -2 *.perl
+ perlcritic -5 $(SCRIPT_PERL)
+ -perlcritic -2 $(SCRIPT_PERL)
+
+.PHONY: all test check install_pm install clean perlcritic
diff --git a/contrib/mw-to-git/git-remote-mediawiki.perl b/contrib/mw-to-git/git-remote-mediawiki.perl
index 85d0c42296..3f8d993afa 100755
--- a/contrib/mw-to-git/git-remote-mediawiki.perl
+++ b/contrib/mw-to-git/git-remote-mediawiki.perl
@@ -590,6 +590,9 @@ sub mw_capabilities {
print {*STDOUT} "import\n";
print {*STDOUT} "list\n";
print {*STDOUT} "push\n";
+ if ($dumb_push) {
+ print {*STDOUT} "no-private-update\n";
+ }
print {*STDOUT} "\n";
return;
}
@@ -1221,7 +1224,6 @@ sub mw_push_revision {
}
if (!$dumb_push) {
run_git(qq(notes --ref=${remotename}/mediawiki add -f -m "mediawiki_revision: ${mw_revision}" ${sha1_commit}));
- run_git(qq(update-ref -m "Git-MediaWiki push" refs/mediawiki/${remotename}/master ${sha1_commit} ${sha1_child}));
}
}
@@ -1313,7 +1315,7 @@ sub get_mw_namespace_id {
# Store "notANameSpace" as special value for inexisting namespaces
my $store_id = ($id || 'notANameSpace');
- # Store explicitely requested namespaces on disk
+ # Store explicitly requested namespaces on disk
if (!exists $cached_mw_namespace_id{$name}) {
run_git(qq(config --add remote.${remotename}.namespaceCache "${name}:${store_id}"));
$cached_mw_namespace_id{$name} = 1;
diff --git a/contrib/mw-to-git/t/test-gitmw-lib.sh b/contrib/mw-to-git/t/test-gitmw-lib.sh
index ca6860ff30..3372b2af34 100755
--- a/contrib/mw-to-git/t/test-gitmw-lib.sh
+++ b/contrib/mw-to-git/t/test-gitmw-lib.sh
@@ -91,7 +91,7 @@ test_diff_directories () {
# Check that <dir> contains exactly <N> files
test_contains_N_files () {
if test `ls -- "$1" | wc -l` -ne "$2"; then
- echo "directory $1 sould contain $2 files"
+ echo "directory $1 should contain $2 files"
echo "it contains these files:"
ls "$1"
false
diff --git a/contrib/mw-to-git/t/test.config b/contrib/mw-to-git/t/test.config
index 4cfebe9c69..5ba0684162 100644
--- a/contrib/mw-to-git/t/test.config
+++ b/contrib/mw-to-git/t/test.config
@@ -12,7 +12,7 @@ SERVER_ADDR=localhost
TMP=/tmp
DB_FILE=wikidb.sqlite
-# If LIGHTTPD is not set to true, the script will use the defaut
+# If LIGHTTPD is not set to true, the script will use the default
# web server running in WIKI_DIR_INST.
WIKI_DIR_INST=/var/www
diff --git a/contrib/p4import/README b/contrib/p4import/README
deleted file mode 100644
index b9892b6793..0000000000
--- a/contrib/p4import/README
+++ /dev/null
@@ -1 +0,0 @@
-Please see contrib/fast-import/git-p4 for a better Perforce importer.
diff --git a/contrib/p4import/git-p4import.py b/contrib/p4import/git-p4import.py
deleted file mode 100644
index 593d6a0682..0000000000
--- a/contrib/p4import/git-p4import.py
+++ /dev/null
@@ -1,365 +0,0 @@
-#!/usr/bin/env python
-#
-# This tool is copyright (c) 2006, Sean Estabrooks.
-# It is released under the Gnu Public License, version 2.
-#
-# Import Perforce branches into Git repositories.
-# Checking out the files is done by calling the standard p4
-# client which you must have properly configured yourself
-#
-
-import marshal
-import os
-import sys
-import time
-import getopt
-
-if sys.hexversion < 0x02020000:
- # The behavior of the marshal module changed significantly in 2.2
- sys.stderr.write("git-p4import.py: requires Python 2.2 or later.\n")
- sys.exit(1)
-
-from signal import signal, \
- SIGPIPE, SIGINT, SIG_DFL, \
- default_int_handler
-
-signal(SIGPIPE, SIG_DFL)
-s = signal(SIGINT, SIG_DFL)
-if s != default_int_handler:
- signal(SIGINT, s)
-
-def die(msg, *args):
- for a in args:
- msg = "%s %s" % (msg, a)
- print "git-p4import fatal error:", msg
- sys.exit(1)
-
-def usage():
- print "USAGE: git-p4import [-q|-v] [--authors=<file>] [-t <timezone>] [//p4repo/path <branch>]"
- sys.exit(1)
-
-verbosity = 1
-logfile = "/dev/null"
-ignore_warnings = False
-stitch = 0
-tagall = True
-
-def report(level, msg, *args):
- global verbosity
- global logfile
- for a in args:
- msg = "%s %s" % (msg, a)
- fd = open(logfile, "a")
- fd.writelines(msg)
- fd.close()
- if level <= verbosity:
- print msg
-
-class p4_command:
- def __init__(self, _repopath):
- try:
- global logfile
- self.userlist = {}
- if _repopath[-1] == '/':
- self.repopath = _repopath[:-1]
- else:
- self.repopath = _repopath
- if self.repopath[-4:] != "/...":
- self.repopath= "%s/..." % self.repopath
- f=os.popen('p4 -V 2>>%s'%logfile, 'rb')
- a = f.readlines()
- if f.close():
- raise
- except:
- die("Could not find the \"p4\" command")
-
- def p4(self, cmd, *args):
- global logfile
- cmd = "%s %s" % (cmd, ' '.join(args))
- report(2, "P4:", cmd)
- f=os.popen('p4 -G %s 2>>%s' % (cmd,logfile), 'rb')
- list = []
- while 1:
- try:
- list.append(marshal.load(f))
- except EOFError:
- break
- self.ret = f.close()
- return list
-
- def sync(self, id, force=False, trick=False, test=False):
- if force:
- ret = self.p4("sync -f %s@%s"%(self.repopath, id))[0]
- elif trick:
- ret = self.p4("sync -k %s@%s"%(self.repopath, id))[0]
- elif test:
- ret = self.p4("sync -n %s@%s"%(self.repopath, id))[0]
- else:
- ret = self.p4("sync %s@%s"%(self.repopath, id))[0]
- if ret['code'] == "error":
- data = ret['data'].upper()
- if data.find('VIEW') > 0:
- die("Perforce reports %s is not in client view"% self.repopath)
- elif data.find('UP-TO-DATE') < 0:
- die("Could not sync files from perforce", self.repopath)
-
- def changes(self, since=0):
- try:
- list = []
- for rec in self.p4("changes %s@%s,#head" % (self.repopath, since+1)):
- list.append(rec['change'])
- list.reverse()
- return list
- except:
- return []
-
- def authors(self, filename):
- f=open(filename)
- for l in f.readlines():
- self.userlist[l[:l.find('=')].rstrip()] = \
- (l[l.find('=')+1:l.find('<')].rstrip(),l[l.find('<')+1:l.find('>')])
- f.close()
- for f,e in self.userlist.items():
- report(2, f, ":", e[0], " <", e[1], ">")
-
- def _get_user(self, id):
- if not self.userlist.has_key(id):
- try:
- user = self.p4("users", id)[0]
- self.userlist[id] = (user['FullName'], user['Email'])
- except:
- self.userlist[id] = (id, "")
- return self.userlist[id]
-
- def _format_date(self, ticks):
- symbol='+'
- name = time.tzname[0]
- offset = time.timezone
- if ticks[8]:
- name = time.tzname[1]
- offset = time.altzone
- if offset < 0:
- offset *= -1
- symbol = '-'
- localo = "%s%02d%02d %s" % (symbol, offset / 3600, offset % 3600, name)
- tickso = time.strftime("%a %b %d %H:%M:%S %Y", ticks)
- return "%s %s" % (tickso, localo)
-
- def where(self):
- try:
- return self.p4("where %s" % self.repopath)[-1]['path']
- except:
- return ""
-
- def describe(self, num):
- desc = self.p4("describe -s", num)[0]
- self.msg = desc['desc']
- self.author, self.email = self._get_user(desc['user'])
- self.date = self._format_date(time.localtime(long(desc['time'])))
- return self
-
-class git_command:
- def __init__(self):
- try:
- self.version = self.git("--version")[0][12:].rstrip()
- except:
- die("Could not find the \"git\" command")
- try:
- self.gitdir = self.get_single("rev-parse --git-dir")
- report(2, "gdir:", self.gitdir)
- except:
- die("Not a git repository... did you forget to \"git init\" ?")
- try:
- self.cdup = self.get_single("rev-parse --show-cdup")
- if self.cdup != "":
- os.chdir(self.cdup)
- self.topdir = os.getcwd()
- report(2, "topdir:", self.topdir)
- except:
- die("Could not find top git directory")
-
- def git(self, cmd):
- global logfile
- report(2, "GIT:", cmd)
- f=os.popen('git %s 2>>%s' % (cmd,logfile), 'rb')
- r=f.readlines()
- self.ret = f.close()
- return r
-
- def get_single(self, cmd):
- return self.git(cmd)[0].rstrip()
-
- def current_branch(self):
- try:
- testit = self.git("rev-parse --verify HEAD")[0]
- return self.git("symbolic-ref HEAD")[0][11:].rstrip()
- except:
- return None
-
- def get_config(self, variable):
- try:
- return self.git("config --get %s" % variable)[0].rstrip()
- except:
- return None
-
- def set_config(self, variable, value):
- try:
- self.git("config %s %s"%(variable, value) )
- except:
- die("Could not set %s to " % variable, value)
-
- def make_tag(self, name, head):
- self.git("tag -f %s %s"%(name,head))
-
- def top_change(self, branch):
- try:
- a=self.get_single("name-rev --tags refs/heads/%s" % branch)
- loc = a.find(' tags/') + 6
- if a[loc:loc+3] != "p4/":
- raise
- return int(a[loc+3:][:-2])
- except:
- return 0
-
- def update_index(self):
- self.git("ls-files -m -d -o -z | git update-index --add --remove -z --stdin")
-
- def checkout(self, branch):
- self.git("checkout %s" % branch)
-
- def repoint_head(self, branch):
- self.git("symbolic-ref HEAD refs/heads/%s" % branch)
-
- def remove_files(self):
- self.git("ls-files | xargs rm")
-
- def clean_directories(self):
- self.git("clean -d")
-
- def fresh_branch(self, branch):
- report(1, "Creating new branch", branch)
- self.git("ls-files | xargs rm")
- os.remove(".git/index")
- self.repoint_head(branch)
- self.git("clean -d")
-
- def basedir(self):
- return self.topdir
-
- def commit(self, author, email, date, msg, id):
- self.update_index()
- fd=open(".msg", "w")
- fd.writelines(msg)
- fd.close()
- try:
- current = self.get_single("rev-parse --verify HEAD")
- head = "-p HEAD"
- except:
- current = ""
- head = ""
- tree = self.get_single("write-tree")
- for r,l in [('DATE',date),('NAME',author),('EMAIL',email)]:
- os.environ['GIT_AUTHOR_%s'%r] = l
- os.environ['GIT_COMMITTER_%s'%r] = l
- commit = self.get_single("commit-tree %s %s < .msg" % (tree,head))
- os.remove(".msg")
- self.make_tag("p4/%s"%id, commit)
- self.git("update-ref HEAD %s %s" % (commit, current) )
-
-try:
- opts, args = getopt.getopt(sys.argv[1:], "qhvt:",
- ["authors=","help","stitch=","timezone=","log=","ignore","notags"])
-except getopt.GetoptError:
- usage()
-
-for o, a in opts:
- if o == "-q":
- verbosity = 0
- if o == "-v":
- verbosity += 1
- if o in ("--log"):
- logfile = a
- if o in ("--notags"):
- tagall = False
- if o in ("-h", "--help"):
- usage()
- if o in ("--ignore"):
- ignore_warnings = True
-
-git = git_command()
-branch=git.current_branch()
-
-for o, a in opts:
- if o in ("-t", "--timezone"):
- git.set_config("perforce.timezone", a)
- if o in ("--stitch"):
- git.set_config("perforce.%s.path" % branch, a)
- stitch = 1
-
-if len(args) == 2:
- branch = args[1]
- git.checkout(branch)
- if branch == git.current_branch():
- die("Branch %s already exists!" % branch)
- report(1, "Setting perforce to ", args[0])
- git.set_config("perforce.%s.path" % branch, args[0])
-elif len(args) != 0:
- die("You must specify the perforce //depot/path and git branch")
-
-p4path = git.get_config("perforce.%s.path" % branch)
-if p4path == None:
- die("Do not know Perforce //depot/path for git branch", branch)
-
-p4 = p4_command(p4path)
-
-for o, a in opts:
- if o in ("-a", "--authors"):
- p4.authors(a)
-
-localdir = git.basedir()
-if p4.where()[:len(localdir)] != localdir:
- report(1, "**WARNING** Appears p4 client is misconfigured")
- report(1, " for sync from %s to %s" % (p4.repopath, localdir))
- if ignore_warnings != True:
- die("Reconfigure or use \"--ignore\" on command line")
-
-if stitch == 0:
- top = git.top_change(branch)
-else:
- top = 0
-changes = p4.changes(top)
-count = len(changes)
-if count == 0:
- report(1, "Already up to date...")
- sys.exit(0)
-
-ptz = git.get_config("perforce.timezone")
-if ptz:
- report(1, "Setting timezone to", ptz)
- os.environ['TZ'] = ptz
- time.tzset()
-
-if stitch == 1:
- git.remove_files()
- git.clean_directories()
- p4.sync(changes[0], force=True)
-elif top == 0 and branch != git.current_branch():
- p4.sync(changes[0], test=True)
- report(1, "Creating new initial commit");
- git.fresh_branch(branch)
- p4.sync(changes[0], force=True)
-else:
- p4.sync(changes[0], trick=True)
-
-report(1, "processing %s changes from p4 (%s) to git (%s)" % (count, p4.repopath, branch))
-for id in changes:
- report(1, "Importing changeset", id)
- change = p4.describe(id)
- p4.sync(id)
- if tagall :
- git.commit(change.author, change.email, change.date, change.msg, id)
- else:
- git.commit(change.author, change.email, change.date, change.msg, "import")
- if stitch == 1:
- git.clean_directories()
- stitch = 0
diff --git a/contrib/p4import/git-p4import.txt b/contrib/p4import/git-p4import.txt
deleted file mode 100644
index 9967587fe6..0000000000
--- a/contrib/p4import/git-p4import.txt
+++ /dev/null
@@ -1,167 +0,0 @@
-git-p4import(1)
-===============
-
-NAME
-----
-git-p4import - Import a Perforce repository into git
-
-
-SYNOPSIS
---------
-[verse]
-`git-p4import` [-q|-v] [--notags] [--authors <file>] [-t <timezone>]
- <//p4repo/path> <branch>
-`git-p4import` --stitch <//p4repo/path>
-`git-p4import`
-
-
-DESCRIPTION
------------
-Import a Perforce repository into an existing git repository. When
-a <//p4repo/path> and <branch> are specified a new branch with the
-given name will be created and the initial import will begin.
-
-Once the initial import is complete you can do an incremental import
-of new commits from the Perforce repository. You do this by checking
-out the appropriate git branch and then running `git-p4import` without
-any options.
-
-The standard p4 client is used to communicate with the Perforce
-repository; it must be configured correctly in order for `git-p4import`
-to operate (see below).
-
-
-OPTIONS
--------
--q::
- Do not display any progress information.
-
--v::
- Give extra progress information.
-
-\--authors::
- Specify an authors file containing a mapping of Perforce user
- ids to full names and email addresses (see Notes below).
-
-\--notags::
- Do not create a tag for each imported commit.
-
-\--stitch::
- Import the contents of the given perforce branch into the
- currently checked out git branch.
-
-\--log::
- Store debugging information in the specified file.
-
--t::
- Specify that the remote repository is in the specified timezone.
- Timezone must be in the format "US/Pacific" or "Europe/London"
- etc. You only need to specify this once, it will be saved in
- the git config file for the repository.
-
-<//p4repo/path>::
- The Perforce path that will be imported into the specified branch.
-
-<branch>::
- The new branch that will be created to hold the Perforce imports.
-
-
-P4 Client
----------
-You must make the `p4` client command available in your $PATH and
-configure it to communicate with the target Perforce repository.
-Typically this means you must set the "$P4PORT" and "$P4CLIENT"
-environment variables.
-
-You must also configure a `p4` client "view" which maps the Perforce
-branch into the top level of your git repository, for example:
-
-------------
-Client: myhost
-
-Root: /home/sean/import
-
-Options: noallwrite clobber nocompress unlocked modtime rmdir
-
-View:
- //public/jam/... //myhost/jam/...
-------------
-
-With the above `p4` client setup, you could import the "jam"
-perforce branch into a branch named "jammy", like so:
-
-------------
-$ mkdir -p /home/sean/import/jam
-$ cd /home/sean/import/jam
-$ git init
-$ git p4import //public/jam jammy
-------------
-
-
-Multiple Branches
------------------
-Note that by creating multiple "views" you can use `git-p4import`
-to import additional branches into the same git repository.
-However, the `p4` client has a limitation in that it silently
-ignores all but the last "view" that maps into the same local
-directory. So the following will *not* work:
-
-------------
-View:
- //public/jam/... //myhost/jam/...
- //public/other/... //myhost/jam/...
- //public/guest/... //myhost/jam/...
-------------
-
-If you want more than one Perforce branch to be imported into the
-same directory you must employ a workaround. A simple option is
-to adjust your `p4` client before each import to only include a
-single view.
-
-Another option is to create multiple symlinks locally which all
-point to the same directory in your git repository and then use
-one per "view" instead of listing the actual directory.
-
-
-Tags
-----
-A git tag of the form p4/xx is created for every change imported from
-the Perforce repository where xx is the Perforce changeset number.
-Therefore after the import you can use git to access any commit by its
-Perforce number, e.g. git show p4/327.
-
-The tag associated with the HEAD commit is also how `git-p4import`
-determines if there are new changes to incrementally import from the
-Perforce repository.
-
-If you import from a repository with many thousands of changes
-you will have an equal number of p4/xxxx git tags. Git tags can
-be expensive in terms of disk space and repository operations.
-If you don't need to perform further incremental imports, you
-may delete the tags.
-
-
-Notes
------
-You can interrupt the import (e.g. ctrl-c) at any time and restart it
-without worry.
-
-Author information is automatically determined by querying the
-Perforce "users" table using the id associated with each change.
-However, if you want to manually supply these mappings you can do
-so with the "--authors" option. It accepts a file containing a list
-of mappings with each line containing one mapping in the format:
-
-------------
- perforce_id = Full Name <email@address.com>
-------------
-
-
-Author
-------
-Written by Sean Estabrooks <seanlkml@sympatico.ca>
-
-
-GIT
----
-Part of the gitlink:git[7] suite
diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr
index c3a3cac77b..5f4b2e3e16 100755
--- a/contrib/remote-helpers/git-remote-bzr
+++ b/contrib/remote-helpers/git-remote-bzr
@@ -13,8 +13,11 @@
# or
# % git clone bzr::lp:myrepo
#
-# If you want to specify which branches you want track (per repo):
-# git config remote-bzr.branches 'trunk, devel, test'
+# If you want to specify which branches you want to track (per repo):
+# % git config remote.origin.bzr-branches 'trunk, devel, test'
+#
+# Where 'origin' is the name of the repository you want to specify the
+# branches.
#
import sys
@@ -41,8 +44,8 @@ import StringIO
import atexit, shutil, hashlib, urlparse, subprocess
NAME_RE = re.compile('^([^<>]+)')
-AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]*)>$')
-EMAIL_RE = re.compile('^([^<>]+[^ \\\t<>])?\\b(?:[ \\t<>]*?)\\b([^ \\t<>]+@[^ \\t<>]+)')
+AUTHOR_RE = re.compile('^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')
+EMAIL_RE = re.compile(r'([^ \t<>]+@[^ \t<>]+)')
RAW_AUTHOR_RE = re.compile('^(\w+) (.+)? <(.*)> (\d+) ([+-]\d+)')
def die(msg, *args):
@@ -168,17 +171,16 @@ class Parser:
if not m:
return None
_, name, email, date, tz = m.groups()
+ name = name.decode('utf-8')
committer = '%s <%s>' % (name, email)
tz = int(tz)
tz = ((tz / 100) * 3600) + ((tz % 100) * 60)
return (committer, int(date), tz)
def rev_to_mark(rev):
- global marks
return marks.from_rev(rev)
def mark_to_rev(mark):
- global marks
return marks.to_rev(mark)
def fixup_user(user):
@@ -191,8 +193,7 @@ def fixup_user(user):
else:
m = EMAIL_RE.match(user)
if m:
- name = m.group(1)
- mail = m.group(2)
+ mail = m.group(1)
else:
m = NAME_RE.match(user)
if m:
@@ -233,8 +234,6 @@ def get_filechanges(cur, prev):
return modified, removed
def export_files(tree, files):
- global marks, filenodes
-
final = []
for path, fid in files.iteritems():
kind = tree.kind(fid)
@@ -276,8 +275,6 @@ def export_files(tree, files):
return final
def export_branch(repo, name):
- global prefix
-
ref = '%s/heads/%s' % (prefix, name)
tip = marks.get_tip(name)
@@ -378,16 +375,12 @@ def export_branch(repo, name):
marks.set_tip(name, revid)
def export_tag(repo, name):
- global tags, prefix
-
ref = '%s/tags/%s' % (prefix, name)
print "reset %s" % ref
print "from :%u" % rev_to_mark(tags[name])
print
def do_import(parser):
- global dirname
-
repo = parser.repo
path = os.path.join(dirname, 'marks-git')
@@ -413,8 +406,6 @@ def do_import(parser):
sys.stdout.flush()
def parse_blob(parser):
- global blob_marks
-
parser.next()
mark = parser.get_mark()
parser.next()
@@ -425,8 +416,6 @@ def parse_blob(parser):
class CustomTree():
def __init__(self, branch, revid, parents, files):
- global files_cache
-
self.updates = {}
self.branch = branch
@@ -484,7 +473,7 @@ class CustomTree():
add_entry(fid, dirname, 'directory')
return fid
- def add_entry(fid, path, kind, mode = None):
+ def add_entry(fid, path, kind, mode=None):
dirname, basename = os.path.split(path)
parent_fid = get_parent(dirname, basename)
@@ -505,7 +494,7 @@ class CustomTree():
self.files[path] = [change[0], None]
changes.append(change)
- def update_entry(fid, path, kind, mode = None):
+ def update_entry(fid, path, kind, mode=None):
dirname, basename = os.path.split(path)
parent_fid = get_parent(dirname, basename)
@@ -583,9 +572,6 @@ def c_style_unescape(string):
return string
def parse_commit(parser):
- global marks, blob_marks, parsed_refs
- global mode
-
parents = []
ref = parser[1]
@@ -657,8 +643,6 @@ def parse_commit(parser):
marks.new_mark(revid, commit_mark)
def parse_reset(parser):
- global parsed_refs
-
ref = parser[1]
parser.next()
@@ -674,8 +658,6 @@ def parse_reset(parser):
parsed_refs[ref] = mark_to_rev(from_mark)
def do_export(parser):
- global parsed_refs, dirname
-
parser.next()
for line in parser.each_block('done'):
@@ -699,9 +681,11 @@ def do_export(parser):
branch.generate_revision_history(revid, marks.get_tip(name))
if name in peers:
- peer = bzrlib.branch.Branch.open(peers[name])
+ peer = bzrlib.branch.Branch.open(peers[name],
+ possible_transports=transports)
try:
- peer.bzrdir.push_branch(branch, revision_id=revid)
+ peer.bzrdir.push_branch(branch, revision_id=revid,
+ overwrite=force)
except bzrlib.errors.DivergedBranches:
print "error %s non-fast forward" % ref
continue
@@ -724,8 +708,6 @@ def do_export(parser):
print
def do_capabilities(parser):
- global dirname
-
print "import"
print "export"
print "refspec refs/heads/*:%s/heads/*" % prefix
@@ -737,14 +719,36 @@ def do_capabilities(parser):
print "*import-marks %s" % path
print "*export-marks %s" % path
+ print "option"
print
+class InvalidOptionValue(Exception):
+ pass
+
+def get_bool_option(val):
+ if val == 'true':
+ return True
+ elif val == 'false':
+ return False
+ else:
+ raise InvalidOptionValue()
+
+def do_option(parser):
+ global force
+ opt, val = parser[1:3]
+ try:
+ if opt == 'force':
+ force = get_bool_option(val)
+ print 'ok'
+ else:
+ print 'unsupported'
+ except InvalidOptionValue:
+ print "error '%s' is not a valid value for option '%s'" % (val, opt)
+
def ref_is_valid(name):
return not True in [c in name for c in '~^: \\']
def do_list(parser):
- global tags
-
master_branch = None
for name in branches:
@@ -770,24 +774,24 @@ def do_list(parser):
def clone(path, remote_branch):
try:
- bdir = bzrlib.bzrdir.BzrDir.create(path)
+ bdir = bzrlib.bzrdir.BzrDir.create(path, possible_transports=transports)
except bzrlib.errors.AlreadyControlDirError:
- bdir = bzrlib.bzrdir.BzrDir.open(path)
+ bdir = bzrlib.bzrdir.BzrDir.open(path, possible_transports=transports)
repo = bdir.find_repository()
repo.fetch(remote_branch.repository)
return remote_branch.sprout(bdir, repository=repo)
def get_remote_branch(name):
- global dirname, branches
-
- remote_branch = bzrlib.branch.Branch.open(branches[name])
+ remote_branch = bzrlib.branch.Branch.open(branches[name],
+ possible_transports=transports)
if isinstance(remote_branch.user_transport, bzrlib.transport.local.LocalTransport):
return remote_branch
branch_path = os.path.join(dirname, 'clone', name)
try:
- branch = bzrlib.branch.Branch.open(branch_path)
+ branch = bzrlib.branch.Branch.open(branch_path,
+ possible_transports=transports)
except bzrlib.errors.NotBranchError:
# clone
branch = clone(branch_path, remote_branch)
@@ -821,17 +825,17 @@ def find_branches(repo):
yield name, branch.base
def get_repo(url, alias):
- global dirname, peer, branches
-
normal_url = bzrlib.urlutils.normalize_url(url)
- origin = bzrlib.bzrdir.BzrDir.open(url)
+ origin = bzrlib.bzrdir.BzrDir.open(url, possible_transports=transports)
is_local = isinstance(origin.transport, bzrlib.transport.local.LocalTransport)
shared_path = os.path.join(gitdir, 'bzr')
try:
- shared_dir = bzrlib.bzrdir.BzrDir.open(shared_path)
+ shared_dir = bzrlib.bzrdir.BzrDir.open(shared_path,
+ possible_transports=transports)
except bzrlib.errors.NotBranchError:
- shared_dir = bzrlib.bzrdir.BzrDir.create(shared_path)
+ shared_dir = bzrlib.bzrdir.BzrDir.create(shared_path,
+ possible_transports=transports)
try:
shared_repo = shared_dir.open_repository()
except bzrlib.errors.NoRepositoryPresent:
@@ -844,16 +848,21 @@ def get_repo(url, alias):
else:
# check and remove old organization
try:
- bdir = bzrlib.bzrdir.BzrDir.open(clone_path)
+ bdir = bzrlib.bzrdir.BzrDir.open(clone_path,
+ possible_transports=transports)
bdir.destroy_repository()
except bzrlib.errors.NotBranchError:
pass
except bzrlib.errors.NoRepositoryPresent:
pass
- wanted = get_config('remote-bzr.branches').rstrip().split(', ')
+ wanted = get_config('remote.%s.bzr-branches' % alias).rstrip().split(', ')
# stupid python
wanted = [e for e in wanted if e]
+ if not wanted:
+ wanted = get_config('remote-bzr.branches').rstrip().split(', ')
+ # stupid python
+ wanted = [e for e in wanted if e]
if not wanted:
try:
@@ -897,6 +906,18 @@ def main(args):
global files_cache
global is_tmp
global branches, peers
+ global transports
+ global force
+
+ marks = None
+ is_tmp = False
+ gitdir = os.environ.get('GIT_DIR', None)
+
+ if len(args) < 3:
+ die('Not enough arguments.')
+
+ if not gitdir:
+ die('GIT_DIR not set')
alias = args[1]
url = args[2]
@@ -906,18 +927,16 @@ def main(args):
blob_marks = {}
parsed_refs = {}
files_cache = {}
- marks = None
branches = {}
peers = {}
+ transports = []
+ force = False
if alias[5:] == url:
is_tmp = True
alias = hashlib.sha1(alias).hexdigest()
- else:
- is_tmp = False
prefix = 'refs/bzr/%s' % alias
- gitdir = os.environ['GIT_DIR']
dirname = os.path.join(gitdir, 'bzr', alias)
if not is_tmp:
@@ -944,6 +963,8 @@ def main(args):
do_import(parser)
elif parser.check('export'):
do_export(parser)
+ elif parser.check('option'):
+ do_option(parser)
else:
die('unhandled command: %s' % line)
sys.stdout.flush()
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index 1c713e0af1..eb89ef6779 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -23,8 +23,12 @@ import subprocess
import urllib
import atexit
import urlparse, hashlib
+import time as ptime
#
+# If you want to see Mercurial revisions as Git commit notes:
+# git config core.notesRef refs/notes/hg
+#
# If you are not in hg-git-compat mode and want to disable the tracking of
# named branches:
# git config --global remote-hg.track-branches false
@@ -47,8 +51,8 @@ import urlparse, hashlib
#
NAME_RE = re.compile('^([^<>]+)')
-AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]*)>$')
-EMAIL_RE = re.compile('^([^<>]+[^ \\\t<>])?\\b(?:[ \\t<>]*?)\\b([^ \\t<>]+@[^ \\t<>]+)')
+AUTHOR_RE = re.compile('^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')
+EMAIL_RE = re.compile(r'([^ \t<>]+@[^ \t<>]+)')
AUTHOR_HG_RE = re.compile('^(.*?) ?<(.*?)(?:>(.+)?)?$')
RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.*)> (\d+) ([+-]\d+)')
@@ -126,6 +130,7 @@ class Marks:
self.rev_marks = {}
self.last_mark = 0
self.version = 0
+ self.last_note = 0
def load(self):
if not os.path.exists(self.path):
@@ -137,6 +142,7 @@ class Marks:
self.marks = tmp['marks']
self.last_mark = tmp['last-mark']
self.version = tmp.get('version', 1)
+ self.last_note = tmp.get('last-note', 0)
for rev, mark in self.marks.iteritems():
self.rev_marks[mark] = rev
@@ -150,7 +156,7 @@ class Marks:
self.version = 2
def dict(self):
- return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark, 'version' : self.version }
+ return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark, 'version' : self.version, 'last-note' : self.last_note }
def store(self):
json.dump(self.dict(), open(self.path, 'w'))
@@ -227,8 +233,6 @@ class Parser:
return sys.stdin.read(size)
def get_author(self):
- global bad_mail
-
ex = None
m = RAW_AUTHOR_RE.match(self.line)
if not m:
@@ -261,8 +265,6 @@ def fix_file_path(path):
return os.path.relpath(path, '/')
def export_files(files):
- global marks, filenodes
-
final = []
for f in files:
fid = node.hex(f.filenode())
@@ -314,8 +316,7 @@ def fixup_user_git(user):
else:
m = EMAIL_RE.match(user)
if m:
- name = m.group(1)
- mail = m.group(2)
+ mail = m.group(1)
else:
m = NAME_RE.match(user)
if m:
@@ -344,8 +345,6 @@ def fixup_user_hg(user):
return (name, mail)
def fixup_user(user):
- global mode, bad_mail
-
if mode == 'git':
name, mail = fixup_user_git(user)
else:
@@ -374,7 +373,7 @@ def updatebookmarks(repo, peer):
bookmarks.write(repo)
def get_repo(url, alias):
- global dirname, peer
+ global peer
myui = ui.ui()
myui.setconfig('ui', 'interactive', 'off')
@@ -391,11 +390,24 @@ def get_repo(url, alias):
os.makedirs(dirname)
else:
shared_path = os.path.join(gitdir, 'hg')
- if not os.path.exists(shared_path):
- try:
- hg.clone(myui, {}, url, shared_path, update=False, pull=True)
- except:
- die('Repository error')
+
+ # check and upgrade old organization
+ hg_path = os.path.join(shared_path, '.hg')
+ if os.path.exists(shared_path) and not os.path.exists(hg_path):
+ repos = os.listdir(shared_path)
+ for x in repos:
+ local_hg = os.path.join(shared_path, x, 'clone', '.hg')
+ if not os.path.exists(local_hg):
+ continue
+ if not os.path.exists(hg_path):
+ shutil.move(local_hg, hg_path)
+ shutil.rmtree(os.path.join(shared_path, x, 'clone'))
+
+ # setup shared repo (if not there)
+ try:
+ hg.peer(myui, {}, shared_path, create=True)
+ except error.RepoError:
+ pass
if not os.path.exists(dirname):
os.makedirs(dirname)
@@ -403,6 +415,9 @@ def get_repo(url, alias):
local_path = os.path.join(dirname, 'clone')
if not os.path.exists(local_path):
hg.share(myui, shared_path, local_path, update=False)
+ else:
+ # make sure the shared path is always up-to-date
+ util.writefile(os.path.join(local_path, '.hg', 'sharedpath'), hg_path)
repo = hg.repository(myui, local_path)
try:
@@ -416,16 +431,12 @@ def get_repo(url, alias):
return repo
def rev_to_mark(rev):
- global marks
return marks.from_rev(rev.hex())
def mark_to_rev(mark):
- global marks
return marks.to_rev(mark)
def export_ref(repo, name, kind, head):
- global prefix, marks, mode
-
ename = '%s/%s' % (kind, name)
try:
tip = marks.get_tip(ename)
@@ -522,6 +533,31 @@ def export_ref(repo, name, kind, head):
print "from :%u" % rev_to_mark(head)
print
+ pending_revs = set(revs) - notes
+ if pending_revs:
+ note_mark = marks.next_mark()
+ ref = "refs/notes/hg"
+
+ print "commit %s" % ref
+ print "mark :%d" % (note_mark)
+ print "committer remote-hg <> %d %s" % (ptime.time(), gittz(ptime.timezone))
+ desc = "Notes for %s\n" % (name)
+ print "data %d" % (len(desc))
+ print desc
+ if marks.last_note:
+ print "from :%u" % marks.last_note
+
+ for rev in pending_revs:
+ notes.add(rev)
+ c = repo[rev]
+ print "N inline :%u" % rev_to_mark(c)
+ msg = c.hex()
+ print "data %d" % (len(msg))
+ print msg
+ print
+
+ marks.last_note = note_mark
+
marks.set_tip(ename, head.hex())
def export_tag(repo, tag):
@@ -537,12 +573,9 @@ def export_branch(repo, branch):
export_ref(repo, branch, 'branches', head)
def export_head(repo):
- global g_head
export_ref(repo, g_head[0], 'bookmarks', g_head[1])
def do_capabilities(parser):
- global prefix, dirname
-
print "import"
print "export"
print "refspec refs/heads/branches/*:%s/branches/*" % prefix
@@ -562,8 +595,6 @@ def branch_tip(branch):
return branches[branch][-1]
def get_branch_tip(repo, branch):
- global branches
-
heads = branches.get(hgref(branch), None)
if not heads:
return None
@@ -576,7 +607,7 @@ def get_branch_tip(repo, branch):
return heads[0]
def list_head(repo, cur):
- global g_head, bmarks, fake_bmark
+ global g_head, fake_bmark
if 'default' not in branches:
# empty repo
@@ -592,8 +623,6 @@ def list_head(repo, cur):
g_head = (head, node)
def do_list(parser):
- global branches, bmarks, track_branches
-
repo = parser.repo
for bmark, node in bookmarks.listbookmarks(repo).iteritems():
bmarks[bmark] = repo[node]
@@ -661,8 +690,6 @@ def do_import(parser):
print 'done'
def parse_blob(parser):
- global blob_marks
-
parser.next()
mark = parser.get_mark()
parser.next()
@@ -684,9 +711,6 @@ def c_style_unescape(string):
return string
def parse_commit(parser):
- global marks, blob_marks, parsed_refs
- global mode
-
from_mark = merge_mark = None
ref = parser[1]
@@ -805,8 +829,6 @@ def parse_commit(parser):
marks.new_mark(node, commit_mark)
def parse_reset(parser):
- global parsed_refs
-
ref = parser[1]
parser.next()
# ugh
@@ -999,8 +1021,6 @@ def check_tip(ref, kind, name, heads):
return tip in heads
def do_export(parser):
- global parsed_refs, bmarks, peer
-
p_bmarks = []
p_revs = {}
@@ -1072,7 +1092,7 @@ def do_export(parser):
author, msg = parsed_tags.get(tag, (None, None))
if mode == 'git':
if not msg:
- msg = 'Added tag %s for changeset %s' % (tag, node[:12]);
+ msg = 'Added tag %s for changeset %s' % (tag, node[:12])
tagnode, branch = write_tag(parser.repo, tag, node, msg, author)
p_revs[tagnode] = 'refs/heads/branches/' + gitref(branch)
else:
@@ -1130,7 +1150,7 @@ def do_option(parser):
def fix_path(alias, repo, orig_url):
url = urlparse.urlparse(orig_url, 'file')
- if url.scheme != 'file' or os.path.isabs(url.path):
+ if url.scheme != 'file' or os.path.isabs(os.path.expanduser(url.path)):
return
abs_url = urlparse.urljoin("%s/" % os.getcwd(), orig_url)
cmd = ['git', 'config', 'remote.%s.url' % alias, "hg::%s" % abs_url]
@@ -1145,6 +1165,17 @@ def main(args):
global filenodes
global fake_bmark, hg_version
global dry_run
+ global notes, alias
+
+ marks = None
+ is_tmp = False
+ gitdir = os.environ.get('GIT_DIR', None)
+
+ if len(args) < 3:
+ die('Not enough arguments.')
+
+ if not gitdir:
+ die('GIT_DIR not set')
alias = args[1]
url = args[2]
@@ -1166,16 +1197,12 @@ def main(args):
if alias[4:] == url:
is_tmp = True
alias = hashlib.sha1(alias).hexdigest()
- else:
- is_tmp = False
- gitdir = os.environ['GIT_DIR']
dirname = os.path.join(gitdir, 'hg', alias)
branches = {}
bmarks = {}
blob_marks = {}
parsed_refs = {}
- marks = None
parsed_tags = {}
filenodes = {}
fake_bmark = None
@@ -1184,6 +1211,7 @@ def main(args):
except:
hg_version = None
dry_run = False
+ notes = set()
repo = get_repo(url, alias)
prefix = 'refs/hg/%s' % alias
diff --git a/contrib/remote-helpers/test-bzr.sh b/contrib/remote-helpers/test-bzr.sh
index dce281f911..4f379c2ab4 100755
--- a/contrib/remote-helpers/test-bzr.sh
+++ b/contrib/remote-helpers/test-bzr.sh
@@ -5,21 +5,24 @@
test_description='Test remote-bzr'
-. ./test-lib.sh
+test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
+. "$TEST_DIRECTORY"/test-lib.sh
-if ! test_have_prereq PYTHON; then
+if ! test_have_prereq PYTHON
+then
skip_all='skipping remote-bzr tests; python not available'
test_done
fi
-if ! python -c 'import bzrlib'; then
+if ! python -c 'import bzrlib'
+then
skip_all='skipping remote-bzr tests; bzr not available'
test_done
fi
check () {
- echo $3 > expected &&
- git --git-dir=$1/.git log --format='%s' -1 $2 > actual
+ echo $3 >expected &&
+ git --git-dir=$1/.git log --format='%s' -1 $2 >actual
test_cmp expected actual
}
@@ -29,7 +32,7 @@ test_expect_success 'cloning' '
(
bzr init bzrrepo &&
cd bzrrepo &&
- echo one > content &&
+ echo one >content &&
bzr add content &&
bzr commit -m one
) &&
@@ -41,7 +44,7 @@ test_expect_success 'cloning' '
test_expect_success 'pulling' '
(
cd bzrrepo &&
- echo two > content &&
+ echo two >content &&
bzr commit -m two
) &&
@@ -53,13 +56,33 @@ test_expect_success 'pulling' '
test_expect_success 'pushing' '
(
cd gitrepo &&
- echo three > content &&
+ echo three >content &&
git commit -a -m three &&
git push
) &&
- echo three > expected &&
- cat bzrrepo/content > actual &&
+ echo three >expected &&
+ cat bzrrepo/content >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'forced pushing' '
+ (
+ cd gitrepo &&
+ echo three-new >content &&
+ git commit -a --amend -m three-new &&
+ git push -f
+ ) &&
+
+ (
+ cd bzrrepo &&
+ # the forced update overwrites the bzr branch but not the bzr
+ # working directory (it tries to merge instead)
+ bzr revert
+ ) &&
+
+ echo three-new >expected &&
+ cat bzrrepo/content >actual &&
test_cmp expected actual
'
@@ -67,16 +90,16 @@ test_expect_success 'roundtrip' '
(
cd gitrepo &&
git pull &&
- git log --format="%s" -1 origin/master > actual
+ git log --format="%s" -1 origin/master >actual
) &&
- echo three > expected &&
+ echo three-new >expected &&
test_cmp expected actual &&
(cd gitrepo && git push && git pull) &&
(
cd bzrrepo &&
- echo four > content &&
+ echo four >content &&
bzr commit -m four
) &&
@@ -86,19 +109,19 @@ test_expect_success 'roundtrip' '
(
cd gitrepo &&
- echo five > content &&
+ echo five >content &&
git commit -a -m five &&
git push && git pull
) &&
(cd bzrrepo && bzr revert) &&
- echo five > expected &&
- cat bzrrepo/content > actual &&
+ echo five >expected &&
+ cat bzrrepo/content >actual &&
test_cmp expected actual
'
-cat > expected <<EOF
+cat >expected <<\EOF
100644 blob 54f9d6da5c91d556e6b54340b1327573073030af content
100755 blob 68769579c3eaadbe555379b9c3538e6628bae1eb executable
120000 blob 6b584e8ece562ebffc15d38808cd6b98fc3d97ea link
@@ -107,7 +130,7 @@ EOF
test_expect_success 'special modes' '
(
cd bzrrepo &&
- echo exec > executable
+ echo exec >executable
chmod +x executable &&
bzr add executable
bzr commit -m exec &&
@@ -122,21 +145,21 @@ test_expect_success 'special modes' '
(
cd gitrepo &&
git pull
- git ls-tree HEAD > ../actual
+ git ls-tree HEAD >../actual
) &&
test_cmp expected actual &&
(
cd gitrepo &&
- git cat-file -p HEAD:link > ../actual
+ git cat-file -p HEAD:link >../actual
) &&
- printf content > expected &&
+ printf content >expected &&
test_cmp expected actual
'
-cat > expected <<EOF
+cat >expected <<\EOF
100644 blob 54f9d6da5c91d556e6b54340b1327573073030af content
100755 blob 68769579c3eaadbe555379b9c3538e6628bae1eb executable
120000 blob 6b584e8ece562ebffc15d38808cd6b98fc3d97ea link
@@ -147,8 +170,8 @@ test_expect_success 'moving directory' '
(
cd bzrrepo &&
mkdir movedir &&
- echo one > movedir/one &&
- echo two > movedir/two &&
+ echo one >movedir/one &&
+ echo two >movedir/two &&
bzr add movedir &&
bzr commit -m movedir &&
bzr mv movedir movedir-new &&
@@ -158,7 +181,7 @@ test_expect_success 'moving directory' '
(
cd gitrepo &&
git pull &&
- git ls-tree HEAD > ../actual
+ git ls-tree HEAD >../actual
) &&
test_cmp expected actual
@@ -167,7 +190,7 @@ test_expect_success 'moving directory' '
test_expect_success 'different authors' '
(
cd bzrrepo &&
- echo john >> content &&
+ echo john >>content &&
bzr commit -m john \
--author "Jane Rey <jrey@example.com>" \
--author "John Doe <jdoe@example.com>"
@@ -176,10 +199,10 @@ test_expect_success 'different authors' '
(
cd gitrepo &&
git pull &&
- git show --format="%an <%ae>, %cn <%ce>" --quiet > ../actual
+ git show --format="%an <%ae>, %cn <%ce>" --quiet >../actual
) &&
- echo "Jane Rey <jrey@example.com>, A U Thor <author@example.com>" > expected &&
+ echo "Jane Rey <jrey@example.com>, A U Thor <author@example.com>" >expected &&
test_cmp expected actual
'
@@ -196,12 +219,12 @@ test_expect_success 'fetch utf-8 filenames' '
bzr init bzrrepo &&
cd bzrrepo &&
- echo test >> "ærø" &&
+ echo test >>"ærø" &&
bzr add "ærø" &&
- echo test >> "ø~?" &&
+ echo test >>"ø~?" &&
bzr add "ø~?" &&
bzr commit -m add-utf-8 &&
- echo test >> "ærø" &&
+ echo test >>"ærø" &&
bzr commit -m test-utf-8 &&
bzr rm "ø~?" &&
bzr mv "ærø" "ø~?" &&
@@ -211,9 +234,9 @@ test_expect_success 'fetch utf-8 filenames' '
(
git clone "bzr::bzrrepo" gitrepo &&
cd gitrepo &&
- git -c core.quotepath=false ls-files > ../actual
+ git -c core.quotepath=false ls-files >../actual
) &&
- echo "ø~?" > expected &&
+ echo "ø~?" >expected &&
test_cmp expected actual
'
@@ -229,7 +252,7 @@ test_expect_success 'push utf-8 filenames' '
bzr init bzrrepo &&
cd bzrrepo &&
- echo one >> content &&
+ echo one >>content &&
bzr add content &&
bzr commit -m one
) &&
@@ -238,15 +261,15 @@ test_expect_success 'push utf-8 filenames' '
git clone "bzr::bzrrepo" gitrepo &&
cd gitrepo &&
- echo test >> "ærø" &&
+ echo test >>"ærø" &&
git add "ærø" &&
git commit -m utf-8 &&
git push
) &&
- (cd bzrrepo && bzr ls > ../actual) &&
- printf "content\nærø\n" > expected &&
+ (cd bzrrepo && bzr ls >../actual) &&
+ printf "content\nærø\n" >expected &&
test_cmp expected actual
'
@@ -256,7 +279,7 @@ test_expect_success 'pushing a merge' '
(
bzr init bzrrepo &&
cd bzrrepo &&
- echo one > content &&
+ echo one >content &&
bzr add content &&
bzr commit -m one
) &&
@@ -265,27 +288,27 @@ test_expect_success 'pushing a merge' '
(
cd bzrrepo &&
- echo two > content &&
+ echo two >content &&
bzr commit -m two
) &&
(
cd gitrepo &&
- echo three > content &&
+ echo three >content &&
git commit -a -m three &&
git fetch &&
git merge origin/master || true &&
- echo three > content &&
+ echo three >content &&
git commit -a --no-edit &&
git push
) &&
- echo three > expected &&
- cat bzrrepo/content > actual &&
+ echo three >expected &&
+ cat bzrrepo/content >actual &&
test_cmp expected actual
'
-cat > expected <<EOF
+cat >expected <<\EOF
origin/HEAD
origin/branch
origin/trunk
@@ -299,7 +322,7 @@ test_expect_success 'proper bzr repo' '
(
bzr init bzrrepo/trunk &&
cd bzrrepo/trunk &&
- echo one >> content &&
+ echo one >>content &&
bzr add content &&
bzr commit -m one
) &&
@@ -307,14 +330,14 @@ test_expect_success 'proper bzr repo' '
(
bzr branch bzrrepo/trunk bzrrepo/branch &&
cd bzrrepo/branch &&
- echo two >> content &&
+ echo two >>content &&
bzr commit -m one
) &&
(
git clone "bzr::bzrrepo" gitrepo &&
cd gitrepo &&
- git for-each-ref --format "%(refname:short)" refs/remotes/origin > ../actual
+ git for-each-ref --format "%(refname:short)" refs/remotes/origin >../actual
) &&
test_cmp expected actual
@@ -327,11 +350,11 @@ test_expect_success 'strip' '
bzr init bzrrepo &&
cd bzrrepo &&
- echo one >> content &&
+ echo one >>content &&
bzr add content &&
bzr commit -m one &&
- echo two >> content &&
+ echo two >>content &&
bzr commit -m two
) &&
@@ -341,20 +364,50 @@ test_expect_success 'strip' '
cd bzrrepo &&
bzr uncommit --force &&
- echo three >> content &&
+ echo three >>content &&
bzr commit -m three &&
- echo four >> content &&
+ echo four >>content &&
bzr commit -m four &&
- bzr log --line | sed -e "s/^[0-9][0-9]*: //" > ../expected
+ bzr log --line | sed -e "s/^[0-9][0-9]*: //" >../expected
) &&
(
cd gitrepo &&
git fetch &&
- git log --format="%an %ad %s" --date=short origin/master > ../actual
+ git log --format="%an %ad %s" --date=short origin/master >../actual
+ ) &&
+
+ test_cmp expected actual
+'
+
+test_expect_success 'export utf-8 authors' '
+ test_when_finished "rm -rf bzrrepo gitrepo && LC_ALL=C && unset GIT_COMMITTER_NAME" &&
+
+ LC_ALL=en_US.UTF-8
+ export LC_ALL
+
+ GIT_COMMITTER_NAME="Grégoire"
+ export GIT_COMMITTER_NAME
+
+ bzr init bzrrepo &&
+
+ (
+ git init gitrepo &&
+ cd gitrepo &&
+ echo greg >>content &&
+ git add content &&
+ git commit -m one &&
+ git remote add bzr "bzr::../bzrrepo" &&
+ git push bzr master
+ ) &&
+
+ (
+ cd bzrrepo &&
+ bzr log | grep "^committer: " >../actual
) &&
+ echo "committer: Grégoire <committer@example.com>" >expected &&
test_cmp expected actual
'
diff --git a/contrib/remote-helpers/test-hg-bidi.sh b/contrib/remote-helpers/test-hg-bidi.sh
index f83d67d74f..e24c51daad 100755
--- a/contrib/remote-helpers/test-hg-bidi.sh
+++ b/contrib/remote-helpers/test-hg-bidi.sh
@@ -10,12 +10,14 @@ test_description='Test bidirectionality of remote-hg'
. ./test-lib.sh
-if ! test_have_prereq PYTHON; then
+if ! test_have_prereq PYTHON
+then
skip_all='skipping remote-hg tests; python not available'
test_done
fi
-if ! python -c 'import mercurial'; then
+if ! python -c 'import mercurial'
+then
skip_all='skipping remote-hg tests; mercurial not available'
test_done
fi
@@ -43,7 +45,7 @@ hg_push () {
git checkout -q -b tmp &&
git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
git checkout -q @{-1} &&
- git branch -q -D tmp 2> /dev/null || true
+ git branch -q -D tmp 2>/dev/null || true
)
}
@@ -62,7 +64,7 @@ setup () {
echo "tag = -d \"0 0\""
echo "[extensions]"
echo "graphlog ="
- ) >> "$HOME"/.hgrc &&
+ ) >>"$HOME"/.hgrc &&
git config --global remote-hg.hg-git-compat true
git config --global remote-hg.track-branches true
@@ -81,22 +83,22 @@ test_expect_success 'encoding' '
git init -q gitrepo &&
cd gitrepo &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -m "add älphà" &&
GIT_AUTHOR_NAME="tést èncödîng" &&
export GIT_AUTHOR_NAME &&
- echo beta > beta &&
+ echo beta >beta &&
git add beta &&
git commit -m "add beta" &&
- echo gamma > gamma &&
+ echo gamma >gamma &&
git add gamma &&
git commit -m "add gämmâ" &&
: TODO git config i18n.commitencoding latin-1 &&
- echo delta > delta &&
+ echo delta >delta &&
git add delta &&
git commit -m "add déltà"
) &&
@@ -105,8 +107,8 @@ test_expect_success 'encoding' '
git_clone hgrepo gitrepo2 &&
hg_clone gitrepo2 hgrepo2 &&
- HGENCODING=utf-8 hg_log hgrepo > expected &&
- HGENCODING=utf-8 hg_log hgrepo2 > actual &&
+ HGENCODING=utf-8 hg_log hgrepo >expected &&
+ HGENCODING=utf-8 hg_log hgrepo2 >actual &&
test_cmp expected actual
'
@@ -117,14 +119,14 @@ test_expect_success 'file removal' '
(
git init -q gitrepo &&
cd gitrepo &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
- echo beta > beta &&
+ echo beta >beta &&
git add beta &&
git commit -m "add beta"
mkdir foo &&
- echo blah > foo/bar &&
+ echo blah >foo/bar &&
git add foo &&
git commit -m "add foo" &&
git rm alpha &&
@@ -137,8 +139,8 @@ test_expect_success 'file removal' '
git_clone hgrepo gitrepo2 &&
hg_clone gitrepo2 hgrepo2 &&
- hg_log hgrepo > expected &&
- hg_log hgrepo2 > actual &&
+ hg_log hgrepo >expected &&
+ hg_log hgrepo2 >actual &&
test_cmp expected actual
'
@@ -150,12 +152,12 @@ test_expect_success 'git tags' '
git init -q gitrepo &&
cd gitrepo &&
git config receive.denyCurrentBranch ignore &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
git tag alpha &&
- echo beta > beta &&
+ echo beta >beta &&
git add beta &&
git commit -m "add beta" &&
git tag -a -m "added tag beta" beta
@@ -165,8 +167,8 @@ test_expect_success 'git tags' '
git_clone hgrepo gitrepo2 &&
hg_clone gitrepo2 hgrepo2 &&
- hg_log hgrepo > expected &&
- hg_log hgrepo2 > actual &&
+ hg_log hgrepo >expected &&
+ hg_log hgrepo2 >actual &&
test_cmp expected actual
'
@@ -178,7 +180,7 @@ test_expect_success 'hg branch' '
git init -q gitrepo &&
cd gitrepo &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -q -m "add alpha" &&
git checkout -q -b not-master
@@ -201,8 +203,8 @@ test_expect_success 'hg branch' '
: Back to the common revision &&
(cd hgrepo && hg checkout default) &&
- hg_log hgrepo > expected &&
- hg_log hgrepo2 > actual &&
+ hg_log hgrepo >expected &&
+ hg_log hgrepo2 >actual &&
test_cmp expected actual
'
@@ -214,7 +216,7 @@ test_expect_success 'hg tags' '
git init -q gitrepo &&
cd gitrepo &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
@@ -231,8 +233,8 @@ test_expect_success 'hg tags' '
hg_push hgrepo gitrepo &&
hg_clone gitrepo hgrepo2 &&
- hg_log hgrepo > expected &&
- hg_log hgrepo2 > actual &&
+ hg_log hgrepo >expected &&
+ hg_log hgrepo2 >actual &&
test_cmp expected actual
'
diff --git a/contrib/remote-helpers/test-hg-hg-git.sh b/contrib/remote-helpers/test-hg-hg-git.sh
index 2219284382..6dcd95d10f 100755
--- a/contrib/remote-helpers/test-hg-hg-git.sh
+++ b/contrib/remote-helpers/test-hg-hg-git.sh
@@ -10,17 +10,20 @@ test_description='Test remote-hg output compared to hg-git'
. ./test-lib.sh
-if ! test_have_prereq PYTHON; then
+if ! test_have_prereq PYTHON
+then
skip_all='skipping remote-hg tests; python not available'
test_done
fi
-if ! python -c 'import mercurial'; then
+if ! python -c 'import mercurial'
+then
skip_all='skipping remote-hg tests; mercurial not available'
test_done
fi
-if ! python -c 'import hggit'; then
+if ! python -c 'import hggit'
+then
skip_all='skipping remote-hg tests; hg-git not available'
test_done
fi
@@ -66,7 +69,7 @@ hg_push_git () {
git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
git branch -D default &&
git checkout -q @{-1} &&
- git branch -q -D tmp 2> /dev/null || true
+ git branch -q -D tmp 2>/dev/null || true
)
}
@@ -100,7 +103,7 @@ setup () {
echo "hgext.bookmarks ="
echo "hggit ="
echo "graphlog ="
- ) >> "$HOME"/.hgrc &&
+ ) >>"$HOME"/.hgrc &&
git config --global receive.denycurrentbranch warn
git config --global remote-hg.hg-git-compat true
git config --global remote-hg.track-branches false
@@ -121,7 +124,7 @@ test_expect_success 'executable bit' '
(
git init -q gitrepo &&
cd gitrepo &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
chmod 0644 alpha &&
git add alpha &&
git commit -m "add alpha" &&
@@ -133,17 +136,18 @@ test_expect_success 'executable bit' '
git commit -m "clear executable bit"
) &&
- for x in hg git; do
+ for x in hg git
+ do
(
hg_clone_$x gitrepo hgrepo-$x &&
cd hgrepo-$x &&
hg_log . &&
hg manifest -r 1 -v &&
hg manifest -v
- ) > output-$x &&
+ ) >"output-$x" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
- git_log gitrepo2-$x > log-$x
+ git_log gitrepo2-$x >"log-$x"
done &&
test_cmp output-hg output-git &&
@@ -156,7 +160,7 @@ test_expect_success 'symlink' '
(
git init -q gitrepo &&
cd gitrepo &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
ln -s alpha beta &&
@@ -164,16 +168,17 @@ test_expect_success 'symlink' '
git commit -m "add beta"
) &&
- for x in hg git; do
+ for x in hg git
+ do
(
hg_clone_$x gitrepo hgrepo-$x &&
cd hgrepo-$x &&
hg_log . &&
hg manifest -v
- ) > output-$x &&
+ ) >"output-$x" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
- git_log gitrepo2-$x > log-$x
+ git_log gitrepo2-$x >"log-$x"
done &&
test_cmp output-hg output-git &&
@@ -186,28 +191,29 @@ test_expect_success 'merge conflict 1' '
(
hg init hgrepo1 &&
cd hgrepo1 &&
- echo A > afile &&
+ echo A >afile &&
hg add afile &&
hg ci -m "origin" &&
- echo B > afile &&
+ echo B >afile &&
hg ci -m "A->B" &&
hg up -r0 &&
- echo C > afile &&
+ echo C >afile &&
hg ci -m "A->C" &&
hg merge -r1 &&
- echo C > afile &&
+ echo C >afile &&
hg resolve -m afile &&
hg ci -m "merge to C"
) &&
- for x in hg git; do
+ for x in hg git
+ do
git_clone_$x hgrepo1 gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
- hg_log hgrepo2-$x > hg-log-$x &&
- git_log gitrepo-$x > git-log-$x
+ hg_log hgrepo2-$x >"hg-log-$x" &&
+ git_log gitrepo-$x >"git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -220,28 +226,29 @@ test_expect_success 'merge conflict 2' '
(
hg init hgrepo1 &&
cd hgrepo1 &&
- echo A > afile &&
+ echo A >afile &&
hg add afile &&
hg ci -m "origin" &&
- echo B > afile &&
+ echo B >afile &&
hg ci -m "A->B" &&
hg up -r0 &&
- echo C > afile &&
+ echo C >afile &&
hg ci -m "A->C" &&
hg merge -r1 || true &&
- echo B > afile &&
+ echo B >afile &&
hg resolve -m afile &&
hg ci -m "merge to B"
) &&
- for x in hg git; do
+ for x in hg git
+ do
git_clone_$x hgrepo1 gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
- hg_log hgrepo2-$x > hg-log-$x &&
- git_log gitrepo-$x > git-log-$x
+ hg_log hgrepo2-$x >"hg-log-$x" &&
+ git_log gitrepo-$x >"git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -254,29 +261,30 @@ test_expect_success 'converged merge' '
(
hg init hgrepo1 &&
cd hgrepo1 &&
- echo A > afile &&
+ echo A >afile &&
hg add afile &&
hg ci -m "origin" &&
- echo B > afile &&
+ echo B >afile &&
hg ci -m "A->B" &&
- echo C > afile &&
+ echo C >afile &&
hg ci -m "B->C" &&
hg up -r0 &&
- echo C > afile &&
+ echo C >afile &&
hg ci -m "A->C" &&
hg merge -r2 || true &&
hg ci -m "merge"
) &&
- for x in hg git; do
+ for x in hg git
+ do
git_clone_$x hgrepo1 gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
- hg_log hgrepo2-$x > hg-log-$x &&
- git_log gitrepo-$x > git-log-$x
+ hg_log hgrepo2-$x >"hg-log-$x" &&
+ git_log gitrepo-$x >"git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -290,32 +298,33 @@ test_expect_success 'encoding' '
git init -q gitrepo &&
cd gitrepo &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -m "add älphà" &&
GIT_AUTHOR_NAME="tést èncödîng" &&
export GIT_AUTHOR_NAME &&
- echo beta > beta &&
+ echo beta >beta &&
git add beta &&
git commit -m "add beta" &&
- echo gamma > gamma &&
+ echo gamma >gamma &&
git add gamma &&
git commit -m "add gämmâ" &&
: TODO git config i18n.commitencoding latin-1 &&
- echo delta > delta &&
+ echo delta >delta &&
git add delta &&
git commit -m "add déltà"
) &&
- for x in hg git; do
+ for x in hg git
+ do
hg_clone_$x gitrepo hgrepo-$x &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
- HGENCODING=utf-8 hg_log hgrepo-$x > hg-log-$x &&
- git_log gitrepo2-$x > git-log-$x
+ HGENCODING=utf-8 hg_log hgrepo-$x >"hg-log-$x" &&
+ git_log gitrepo2-$x >"git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -328,14 +337,14 @@ test_expect_success 'file removal' '
(
git init -q gitrepo &&
cd gitrepo &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
- echo beta > beta &&
+ echo beta >beta &&
git add beta &&
git commit -m "add beta"
mkdir foo &&
- echo blah > foo/bar &&
+ echo blah >foo/bar &&
git add foo &&
git commit -m "add foo" &&
git rm alpha &&
@@ -344,17 +353,18 @@ test_expect_success 'file removal' '
git commit -m "remove foo/bar"
) &&
- for x in hg git; do
+ for x in hg git
+ do
(
hg_clone_$x gitrepo hgrepo-$x &&
cd hgrepo-$x &&
hg_log . &&
hg manifest -r 3 &&
hg manifest
- ) > output-$x &&
+ ) >"output-$x" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
- git_log gitrepo2-$x > log-$x
+ git_log gitrepo2-$x >"log-$x"
done &&
test_cmp output-hg output-git &&
@@ -368,20 +378,21 @@ test_expect_success 'git tags' '
git init -q gitrepo &&
cd gitrepo &&
git config receive.denyCurrentBranch ignore &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
git tag alpha &&
- echo beta > beta &&
+ echo beta >beta &&
git add beta &&
git commit -m "add beta" &&
git tag -a -m "added tag beta" beta
) &&
- for x in hg git; do
+ for x in hg git
+ do
hg_clone_$x gitrepo hgrepo-$x &&
- hg_log hgrepo-$x > log-$x
+ hg_log hgrepo-$x >"log-$x"
done &&
test_cmp log-hg log-git
@@ -390,12 +401,13 @@ test_expect_success 'git tags' '
test_expect_success 'hg author' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
- for x in hg git; do
+ for x in hg git
+ do
(
git init -q gitrepo-$x &&
cd gitrepo-$x &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
@@ -406,38 +418,38 @@ test_expect_success 'hg author' '
cd hgrepo-$x &&
hg co master &&
- echo beta > beta &&
+ echo beta >beta &&
hg add beta &&
hg commit -u "test" -m "add beta" &&
- echo gamma >> beta &&
+ echo gamma >>beta &&
hg commit -u "test <test@example.com> (comment)" -m "modify beta" &&
- echo gamma > gamma &&
+ echo gamma >gamma &&
hg add gamma &&
hg commit -u "<test@example.com>" -m "add gamma" &&
- echo delta > delta &&
+ echo delta >delta &&
hg add delta &&
hg commit -u "name<test@example.com>" -m "add delta" &&
- echo epsilon > epsilon &&
+ echo epsilon >epsilon &&
hg add epsilon &&
hg commit -u "name <test@example.com" -m "add epsilon" &&
- echo zeta > zeta &&
+ echo zeta >zeta &&
hg add zeta &&
hg commit -u " test " -m "add zeta" &&
- echo eta > eta &&
+ echo eta >eta &&
hg add eta &&
hg commit -u "test < test@example.com >" -m "add eta" &&
- echo theta > theta &&
+ echo theta >theta &&
hg add theta &&
hg commit -u "test >test@example.com>" -m "add theta" &&
- echo iota > iota &&
+ echo iota >iota &&
hg add iota &&
hg commit -u "test <test <at> example <dot> com>" -m "add iota"
) &&
@@ -445,8 +457,8 @@ test_expect_success 'hg author' '
hg_push_$x hgrepo-$x gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
- hg_log hgrepo2-$x > hg-log-$x &&
- git_log gitrepo-$x > git-log-$x
+ hg_log hgrepo2-$x >"hg-log-$x" &&
+ git_log gitrepo-$x >"git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -456,12 +468,13 @@ test_expect_success 'hg author' '
test_expect_success 'hg branch' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
- for x in hg git; do
+ for x in hg git
+ do
(
git init -q gitrepo-$x &&
cd gitrepo-$x &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -q -m "add alpha" &&
git checkout -q -b not-master
@@ -481,8 +494,8 @@ test_expect_success 'hg branch' '
hg_push_$x hgrepo-$x gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
- hg_log hgrepo2-$x > hg-log-$x &&
- git_log gitrepo-$x > git-log-$x
+ hg_log hgrepo2-$x >"hg-log-$x" &&
+ git_log gitrepo-$x >"git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -492,12 +505,13 @@ test_expect_success 'hg branch' '
test_expect_success 'hg tags' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
- for x in hg git; do
+ for x in hg git
+ do
(
git init -q gitrepo-$x &&
cd gitrepo-$x &&
- echo alpha > alpha &&
+ echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
@@ -518,7 +532,7 @@ test_expect_success 'hg tags' '
git --git-dir=gitrepo-$x/.git tag -l &&
hg_log hgrepo2-$x &&
cat hgrepo2-$x/.hgtags
- ) > output-$x
+ ) >"output-$x"
done &&
test_cmp output-hg output-git
diff --git a/contrib/remote-helpers/test-hg.sh b/contrib/remote-helpers/test-hg.sh
index f7ce8aa853..a933b1e30c 100755
--- a/contrib/remote-helpers/test-hg.sh
+++ b/contrib/remote-helpers/test-hg.sh
@@ -8,55 +8,60 @@
test_description='Test remote-hg'
-. ./test-lib.sh
+test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
+. "$TEST_DIRECTORY"/test-lib.sh
-if ! test_have_prereq PYTHON; then
+if ! test_have_prereq PYTHON
+then
skip_all='skipping remote-hg tests; python not available'
test_done
fi
-if ! python -c 'import mercurial'; then
+if ! python -c 'import mercurial'
+then
skip_all='skipping remote-hg tests; mercurial not available'
test_done
fi
check () {
- echo $3 > expected &&
- git --git-dir=$1/.git log --format='%s' -1 $2 > actual
+ echo $3 >expected &&
+ git --git-dir=$1/.git log --format='%s' -1 $2 >actual
test_cmp expected actual
}
check_branch () {
- if [ -n "$3" ]; then
- echo $3 > expected &&
- hg -R $1 log -r $2 --template '{desc}\n' > actual &&
+ if test -n "$3"
+ then
+ echo $3 >expected &&
+ hg -R $1 log -r $2 --template '{desc}\n' >actual &&
test_cmp expected actual
else
- hg -R $1 branches > out &&
+ hg -R $1 branches >out &&
! grep $2 out
fi
}
check_bookmark () {
- if [ -n "$3" ]; then
- echo $3 > expected &&
- hg -R $1 log -r "bookmark('$2')" --template '{desc}\n' > actual &&
+ if test -n "$3"
+ then
+ echo $3 >expected &&
+ hg -R $1 log -r "bookmark('$2')" --template '{desc}\n' >actual &&
test_cmp expected actual
else
- hg -R $1 bookmarks > out &&
+ hg -R $1 bookmarks >out &&
! grep $2 out
fi
}
check_push () {
- local expected_ret=$1 ret=0 ref_ret=0 IFS=':'
+ expected_ret=$1 ret=0 ref_ret=0
shift
- git push origin "$@" 2> error
+ git push origin "$@" 2>error
ret=$?
cat error
- while read branch kind
+ while IFS=':' read branch kind
do
case "$kind" in
'new')
@@ -75,10 +80,10 @@ check_push () {
grep "^ [a-f0-9]*\.\.[a-f0-9]* *${branch} -> ${branch}$" error || ref_ret=1
;;
esac
- let 'ref_ret' && echo "match for '$branch' failed" && break
+ test $ref_ret -ne 0 && echo "match for '$branch' failed" && break
done
- if let 'expected_ret != ret || ref_ret'
+ if test $expected_ret -ne $ret || test $ref_ret -ne 0
then
return 1
fi
@@ -92,7 +97,7 @@ setup () {
echo "username = H G Wells <wells@example.com>"
echo "[extensions]"
echo "mq ="
- ) >> "$HOME"/.hgrc &&
+ ) >>"$HOME"/.hgrc &&
GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230" &&
GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" &&
@@ -107,7 +112,7 @@ test_expect_success 'cloning' '
(
hg init hgrepo &&
cd hgrepo &&
- echo zero > content &&
+ echo zero >content &&
hg add content &&
hg commit -m zero
) &&
@@ -122,7 +127,7 @@ test_expect_success 'cloning with branches' '
(
cd hgrepo &&
hg branch next &&
- echo next > content &&
+ echo next >content &&
hg commit -m next
) &&
@@ -137,7 +142,7 @@ test_expect_success 'cloning with bookmarks' '
cd hgrepo &&
hg checkout default &&
hg bookmark feature-a &&
- echo feature-a > content &&
+ echo feature-a >content &&
hg commit -m feature-a
) &&
@@ -157,7 +162,7 @@ test_expect_success 'update bookmark' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet devel &&
- echo devel > content &&
+ echo devel >content &&
git commit -a -m devel &&
git push --quiet
) &&
@@ -172,7 +177,7 @@ test_expect_success 'new bookmark' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet -b feature-b &&
- echo feature-b > content &&
+ echo feature-b >content &&
git commit -a -m feature-b &&
git push --quiet origin feature-b
) &&
@@ -184,9 +189,9 @@ test_expect_success 'new bookmark' '
rm -rf hgrepo
author_test () {
- echo $1 >> content &&
+ echo $1 >>content &&
hg commit -u "$2" -m "add $1" &&
- echo "$3" >> ../expected
+ echo "$3" >>../expected
}
test_expect_success 'authors' '
@@ -199,22 +204,23 @@ test_expect_success 'authors' '
touch content &&
hg add content &&
- > ../expected &&
+ >../expected &&
author_test alpha "" "H G Wells <wells@example.com>" &&
- author_test beta "test" "test <unknown>" &&
- author_test beta "test <test@example.com> (comment)" "test <test@example.com>" &&
- author_test gamma "<test@example.com>" "Unknown <test@example.com>" &&
- author_test delta "name<test@example.com>" "name <test@example.com>" &&
- author_test epsilon "name <test@example.com" "name <test@example.com>" &&
- author_test zeta " test " "test <unknown>" &&
- author_test eta "test < test@example.com >" "test <test@example.com>" &&
- author_test theta "test >test@example.com>" "test <test@example.com>" &&
- author_test iota "test < test <at> example <dot> com>" "test <unknown>" &&
- author_test kappa "test@example.com" "Unknown <test@example.com>"
+ author_test beta "beta" "beta <unknown>" &&
+ author_test gamma "gamma <test@example.com> (comment)" "gamma <test@example.com>" &&
+ author_test delta "<delta@example.com>" "Unknown <delta@example.com>" &&
+ author_test epsilon "epsilon<test@example.com>" "epsilon <test@example.com>" &&
+ author_test zeta "zeta <test@example.com" "zeta <test@example.com>" &&
+ author_test eta " eta " "eta <unknown>" &&
+ author_test theta "theta < test@example.com >" "theta <test@example.com>" &&
+ author_test iota "iota >test@example.com>" "iota <test@example.com>" &&
+ author_test kappa "kappa < test <at> example <dot> com>" "kappa <unknown>" &&
+ author_test lambda "lambda@example.com" "Unknown <lambda@example.com>" &&
+ author_test mu "mu.mu@example.com" "Unknown <mu.mu@example.com>"
) &&
git clone "hg::hgrepo" gitrepo &&
- git --git-dir=gitrepo/.git log --reverse --format="%an <%ae>" > actual &&
+ git --git-dir=gitrepo/.git log --reverse --format="%an <%ae>" >actual &&
test_cmp expected actual
'
@@ -226,11 +232,11 @@ test_expect_success 'strip' '
hg init hgrepo &&
cd hgrepo &&
- echo one >> content &&
+ echo one >>content &&
hg add content &&
hg commit -m one &&
- echo two >> content &&
+ echo two >>content &&
hg commit -m two
) &&
@@ -240,20 +246,20 @@ test_expect_success 'strip' '
cd hgrepo &&
hg strip 1 &&
- echo three >> content &&
+ echo three >>content &&
hg commit -m three &&
- echo four >> content &&
+ echo four >>content &&
hg commit -m four
) &&
(
cd gitrepo &&
git fetch &&
- git log --format="%s" origin/master > ../actual
+ git log --format="%s" origin/master >../actual
) &&
- hg -R hgrepo log --template "{desc}\n" > expected &&
+ hg -R hgrepo log --template "{desc}\n" >expected &&
test_cmp actual expected
'
@@ -263,18 +269,18 @@ test_expect_success 'remote push with master bookmark' '
(
hg init hgrepo &&
cd hgrepo &&
- echo zero > content &&
+ echo zero >content &&
hg add content &&
hg commit -m zero &&
hg bookmark master &&
- echo one > content &&
+ echo one >content &&
hg commit -m one
) &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
- echo two > content &&
+ echo two >content &&
git commit -a -m two &&
git push
) &&
@@ -282,7 +288,7 @@ test_expect_success 'remote push with master bookmark' '
check_branch hgrepo default two
'
-cat > expected <<EOF
+cat >expected <<\EOF
changeset: 0:6e2126489d3d
tag: tip
user: A U Thor <author@example.com>
@@ -300,13 +306,13 @@ test_expect_success 'remote push from master branch' '
git init gitrepo &&
cd gitrepo &&
git remote add origin "hg::../hgrepo" &&
- echo one > content &&
+ echo one >content &&
git add content &&
git commit -a -m one &&
git push origin master
) &&
- hg -R hgrepo log > actual &&
+ hg -R hgrepo log >actual &&
cat actual &&
test_cmp expected actual &&
@@ -322,7 +328,7 @@ test_expect_success 'remote cloning' '
(
hg init hgrepo &&
cd hgrepo &&
- echo zero > content &&
+ echo zero >content &&
hg add content &&
hg commit -m zero
) &&
@@ -331,6 +337,17 @@ test_expect_success 'remote cloning' '
check gitrepo HEAD zero
'
+test_expect_success 'moving remote clone' '
+ test_when_finished "rm -rf gitrepo*" &&
+
+ (
+ git clone "hg::hgrepo" gitrepo &&
+ mv gitrepo gitrepo2 &&
+ cd gitrepo2 &&
+ git fetch
+ )
+'
+
test_expect_success 'remote update bookmark' '
test_when_finished "rm -rf gitrepo*" &&
@@ -343,7 +360,7 @@ test_expect_success 'remote update bookmark' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet devel &&
- echo devel > content &&
+ echo devel >content &&
git commit -a -m devel &&
git push --quiet
) &&
@@ -358,7 +375,7 @@ test_expect_success 'remote new bookmark' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet -b feature-b &&
- echo feature-b > content &&
+ echo feature-b >content &&
git commit -a -m feature-b &&
git push --quiet origin feature-b
) &&
@@ -374,15 +391,15 @@ test_expect_success 'remote push diverged' '
(
cd hgrepo &&
hg checkout default &&
- echo bump > content &&
+ echo bump >content &&
hg commit -m bump
) &&
(
cd gitrepo &&
- echo diverge > content &&
+ echo diverge >content &&
git commit -a -m diverged &&
- check_push 1 <<-EOF
+ check_push 1 <<-\EOF
master:non-fast-forward
EOF
) &&
@@ -403,16 +420,16 @@ test_expect_success 'remote update bookmark diverge' '
(
cd hgrepo &&
- echo "bump bookmark" > content &&
+ echo "bump bookmark" >content &&
hg commit -m "bump bookmark"
) &&
(
cd gitrepo &&
git checkout --quiet diverge &&
- echo diverge > content &&
+ echo diverge >content &&
git commit -a -m diverge &&
- check_push 1 <<-EOF
+ check_push 1 <<-\EOF
diverge:fetch-first
EOF
) &&
@@ -427,7 +444,7 @@ test_expect_success 'remote new bookmark multiple branch head' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet -b feature-c HEAD^ &&
- echo feature-c > content &&
+ echo feature-c >content &&
git commit -a -m feature-c &&
git push --quiet origin feature-c
) &&
@@ -438,24 +455,92 @@ test_expect_success 'remote new bookmark multiple branch head' '
# cleanup previous stuff
rm -rf hgrepo
+test_expect_success 'fetch special filenames' '
+ test_when_finished "rm -rf hgrepo gitrepo && LC_ALL=C" &&
+
+ LC_ALL=en_US.UTF-8
+ export LC_ALL
+
+ (
+ hg init hgrepo &&
+ cd hgrepo &&
+
+ echo test >> "æ rø" &&
+ hg add "æ rø" &&
+ echo test >> "ø~?" &&
+ hg add "ø~?" &&
+ hg commit -m add-utf-8 &&
+ echo test >> "æ rø" &&
+ hg commit -m test-utf-8 &&
+ hg rm "ø~?" &&
+ hg mv "æ rø" "ø~?" &&
+ hg commit -m hg-mv-utf-8
+ ) &&
+
+ (
+ git clone "hg::hgrepo" gitrepo &&
+ cd gitrepo &&
+ git -c core.quotepath=false ls-files > ../actual
+ ) &&
+ echo "ø~?" > expected &&
+ test_cmp expected actual
+'
+
+test_expect_success 'push special filenames' '
+ test_when_finished "rm -rf hgrepo gitrepo && LC_ALL=C" &&
+
+ mkdir -p tmp && cd tmp &&
+
+ LC_ALL=en_US.UTF-8
+ export LC_ALL
+
+ (
+ hg init hgrepo &&
+ cd hgrepo &&
+
+ echo one >> content &&
+ hg add content &&
+ hg commit -m one
+ ) &&
+
+ (
+ git clone "hg::hgrepo" gitrepo &&
+ cd gitrepo &&
+
+ echo test >> "æ rø" &&
+ git add "æ rø" &&
+ git commit -m utf-8 &&
+
+ git push
+ ) &&
+
+ (cd hgrepo &&
+ hg update &&
+ hg manifest > ../actual
+ ) &&
+
+ printf "content\næ rø\n" > expected &&
+ test_cmp expected actual
+'
+
setup_big_push () {
(
hg init hgrepo &&
cd hgrepo &&
- echo zero > content &&
+ echo zero >content &&
hg add content &&
hg commit -m zero &&
hg bookmark bad_bmark1 &&
- echo one > content &&
+ echo one >content &&
hg commit -m one &&
hg bookmark bad_bmark2 &&
hg bookmark good_bmark &&
hg bookmark -i good_bmark &&
hg -q branch good_branch &&
- echo "good branch" > content &&
+ echo "good branch" >content &&
hg commit -m "good branch" &&
hg -q branch bad_branch &&
- echo "bad branch" > content &&
+ echo "bad branch" >content &&
hg commit -m "bad branch"
) &&
@@ -463,40 +548,40 @@ setup_big_push () {
(
cd gitrepo &&
- echo two > content &&
+ echo two >content &&
git commit -q -a -m two &&
git checkout -q good_bmark &&
- echo three > content &&
+ echo three >content &&
git commit -q -a -m three &&
git checkout -q bad_bmark1 &&
git reset --hard HEAD^ &&
- echo four > content &&
+ echo four >content &&
git commit -q -a -m four &&
git checkout -q bad_bmark2 &&
git reset --hard HEAD^ &&
- echo five > content &&
+ echo five >content &&
git commit -q -a -m five &&
git checkout -q -b new_bmark master &&
- echo six > content &&
+ echo six >content &&
git commit -q -a -m six &&
git checkout -q branches/good_branch &&
- echo seven > content &&
+ echo seven >content &&
git commit -q -a -m seven &&
- echo eight > content &&
+ echo eight >content &&
git commit -q -a -m eight &&
git checkout -q branches/bad_branch &&
git reset --hard HEAD^ &&
- echo nine > content &&
+ echo nine >content &&
git commit -q -a -m nine &&
git checkout -q -b branches/new_branch master &&
- echo ten > content &&
+ echo ten >content &&
git commit -q -a -m ten
)
}
@@ -509,7 +594,7 @@ test_expect_success 'remote big push' '
(
cd gitrepo &&
- check_push 1 --all <<-EOF
+ check_push 1 --all <<-\EOF
master
good_bmark
branches/good_branch
@@ -537,17 +622,17 @@ test_expect_success 'remote big push fetch first' '
(
hg init hgrepo &&
cd hgrepo &&
- echo zero > content &&
+ echo zero >content &&
hg add content &&
hg commit -m zero &&
hg bookmark bad_bmark &&
hg bookmark good_bmark &&
hg bookmark -i good_bmark &&
hg -q branch good_branch &&
- echo "good branch" > content &&
+ echo "good branch" >content &&
hg commit -m "good branch" &&
hg -q branch bad_branch &&
- echo "bad branch" > content &&
+ echo "bad branch" >content &&
hg commit -m "bad branch"
) &&
@@ -556,39 +641,37 @@ test_expect_success 'remote big push fetch first' '
(
cd hgrepo &&
hg bookmark -f bad_bmark &&
- echo update_bmark > content &&
+ echo update_bmark >content &&
hg commit -m "update bmark"
) &&
(
cd gitrepo &&
- echo two > content &&
+ echo two >content &&
git commit -q -a -m two &&
git checkout -q good_bmark &&
- echo three > content &&
+ echo three >content &&
git commit -q -a -m three &&
git checkout -q bad_bmark &&
- echo four > content &&
+ echo four >content &&
git commit -q -a -m four &&
git checkout -q branches/bad_branch &&
- echo five > content &&
+ echo five >content &&
git commit -q -a -m five &&
- check_push 1 --all <<-EOF
+ check_push 1 --all <<-\EOF &&
master
good_bmark
- new_bmark:new
- new_branch:new
bad_bmark:fetch-first
branches/bad_branch:festch-first
EOF
git fetch &&
- check_push 1 --all <<-EOF
+ check_push 1 --all <<-\EOF
master
good_bmark
bad_bmark:non-fast-forward
@@ -597,7 +680,7 @@ test_expect_success 'remote big push fetch first' '
)
'
-test_expect_failure 'remote big push force' '
+test_expect_success 'remote big push force' '
test_when_finished "rm -rf hgrepo gitrepo*" &&
setup_big_push
@@ -605,7 +688,7 @@ test_expect_failure 'remote big push force' '
(
cd gitrepo &&
- check_push 0 --force --all <<-EOF
+ check_push 0 --force --all <<-\EOF
master
good_bmark
branches/good_branch
@@ -627,7 +710,7 @@ test_expect_failure 'remote big push force' '
check_bookmark hgrepo new_bmark six
'
-test_expect_failure 'remote big push dry-run' '
+test_expect_success 'remote big push dry-run' '
test_when_finished "rm -rf hgrepo gitrepo*" &&
setup_big_push
@@ -635,7 +718,7 @@ test_expect_failure 'remote big push dry-run' '
(
cd gitrepo &&
- check_push 0 --dry-run --all <<-EOF
+ check_push 1 --dry-run --all <<-\EOF &&
master
good_bmark
branches/good_branch
@@ -646,7 +729,7 @@ test_expect_failure 'remote big push dry-run' '
branches/bad_branch:non-fast-forward
EOF
- check_push 0 --dry-run master good_bmark new_bmark branches/good_branch branches/new_branch <<-EOF
+ check_push 0 --dry-run master good_bmark new_bmark branches/good_branch branches/new_branch <<-\EOF
master
good_bmark
branches/good_branch
@@ -671,10 +754,10 @@ test_expect_success 'remote double failed push' '
(
hg init hgrepo &&
cd hgrepo &&
- echo zero > content &&
+ echo zero >content &&
hg add content &&
hg commit -m zero &&
- echo one > content &&
+ echo one >content &&
hg commit -m one
) &&
@@ -682,7 +765,7 @@ test_expect_success 'remote double failed push' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git reset --hard HEAD^ &&
- echo two > content &&
+ echo two >content &&
git commit -a -m two &&
test_expect_code 1 git push &&
test_expect_code 1 git push
diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 7d7af03274..dc59a91031 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -9,10 +9,10 @@ if [ $# -eq 0 ]; then
fi
OPTS_SPEC="\
git subtree add --prefix=<prefix> <commit>
-git subtree add --prefix=<prefix> <repository> <commit>
+git subtree add --prefix=<prefix> <repository> <ref>
git subtree merge --prefix=<prefix> <commit>
-git subtree pull --prefix=<prefix> <repository> <refspec...>
-git subtree push --prefix=<prefix> <repository> <refspec...>
+git subtree pull --prefix=<prefix> <repository> <ref>
+git subtree push --prefix=<prefix> <repository> <ref>
git subtree split --prefix=<prefix> <commit...>
--
h,help show the help
@@ -489,6 +489,12 @@ ensure_clean()
fi
}
+ensure_valid_ref_format()
+{
+ git check-ref-format "refs/heads/$1" ||
+ die "'$1' does not look like a ref"
+}
+
cmd_add()
{
if [ -e "$dir" ]; then
@@ -508,8 +514,7 @@ cmd_add()
# specified directory. Allowing a refspec might be
# misleading because we won't do anything with any other
# branches fetched via the refspec.
- git rev-parse -q --verify "$2^{commit}" >/dev/null ||
- die "'$2' does not refer to a commit"
+ ensure_valid_ref_format "$2"
"cmd_add_repository" "$@"
else
@@ -699,7 +704,11 @@ cmd_merge()
cmd_pull()
{
+ if [ $# -ne 2 ]; then
+ die "You must provide <repository> <ref>"
+ fi
ensure_clean
+ ensure_valid_ref_format "$2"
git fetch "$@" || exit $?
revs=FETCH_HEAD
set -- $revs
@@ -709,8 +718,9 @@ cmd_pull()
cmd_push()
{
if [ $# -ne 2 ]; then
- die "You must provide <repository> <refspec>"
+ die "You must provide <repository> <ref>"
fi
+ ensure_valid_ref_format "$2"
if [ -e "$dir" ]; then
repository=$1
refspec=$2
diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.txt
index e0957eee55..02669b1534 100644
--- a/contrib/subtree/git-subtree.txt
+++ b/contrib/subtree/git-subtree.txt
@@ -9,10 +9,10 @@ git-subtree - Merge subtrees together and split repository into subtrees
SYNOPSIS
--------
[verse]
-'git subtree' add -P <prefix> <refspec>
-'git subtree' add -P <prefix> <repository> <refspec>
-'git subtree' pull -P <prefix> <repository> <refspec...>
-'git subtree' push -P <prefix> <repository> <refspec...>
+'git subtree' add -P <prefix> <commit>
+'git subtree' add -P <prefix> <repository> <ref>
+'git subtree' pull -P <prefix> <repository> <ref>
+'git subtree' push -P <prefix> <repository> <ref>
'git subtree' merge -P <prefix> <commit>
'git subtree' split -P <prefix> [OPTIONS] [<commit>]
@@ -68,7 +68,7 @@ COMMANDS
--------
add::
Create the <prefix> subtree by importing its contents
- from the given <refspec> or <repository> and remote <refspec>.
+ from the given <commit> or <repository> and remote <ref>.
A new commit is created automatically, joining the imported
project's history with your own. With '--squash', imports
only a single commit from the subproject, rather than its
@@ -90,13 +90,13 @@ merge::
pull::
Exactly like 'merge', but parallels 'git pull' in that
- it fetches the given commit from the specified remote
+ it fetches the given ref from the specified remote
repository.
push::
Does a 'split' (see below) using the <prefix> supplied
and then does a 'git push' to push the result to the
- repository and refspec. This can be used to push your
+ repository and ref. This can be used to push your
subtree to different branches of the remote repository.
split::