Compare commits

...

23 Commits

Author SHA1 Message Date
e156455ea4 Git 2.0 2014-05-28 11:04:19 -07:00
4a28f169ad Update draft release notes to 2.0
Hopefully for the last time ;-)

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-21 11:50:35 -07:00
8ced8e40ac Git 2.0-rc4
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-20 14:51:11 -07:00
3054c66bd4 RelNotes/2.0.0.txt: Fix several grammar issues, notably a lack of hyphens, double quotes, or articles
Signed-off-by: Jason St. John <jstjohn@purdue.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-20 14:51:06 -07:00
b2c851a8e6 Revert "Merge branch 'jc/graduate-remote-hg-bzr' (early part)"
Instead of showing a warning and working as before, fail and show
the message and force immediate upgrade from their upstream
repositories when these tools are run, per request from their
primary author.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-20 14:48:11 -07:00
00a5b79466 Merge branch 'jc/graduate-remote-hg-bzr' (early part)
* 'jc/graduate-remote-hg-bzr' (early part):
  remote-helpers: point at their upstream repositories
  contrib: remote-helpers: add move warnings (v2.0)
  Revert "Merge branch 'fc/transport-helper-sync-error-fix'"
2014-05-19 17:12:36 -07:00
896ba14d65 remote-helpers: point at their upstream repositories
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-19 17:10:03 -07:00
0311086351 contrib: remote-helpers: add move warnings (v2.0)
The tools are now maintained out-of-tree, and they have a regression
in v2.0. It's better to start warning the users as soon as possible.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-19 17:10:03 -07:00
10e1feebb4 Revert "Merge branch 'fc/transport-helper-sync-error-fix'"
This reverts commit d508e4a8e2,
reversing changes made to e42552135a.

The author of the original topic says he broke the upcoming 2.0
release with something that relates to "synchronization crash
regression" while refusing to give further specifics, so this would
unfortunately be the safest option for the upcoming release.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-19 17:09:57 -07:00
df43b41afc Merge branch 'rh/prompt-pcmode-avoid-eval-on-refname'
* rh/prompt-pcmode-avoid-eval-on-refname:
  git-prompt.sh: don't assume the shell expands the value of PS1
2014-05-19 16:10:10 -07:00
1e4119c81b git-prompt.sh: don't assume the shell expands the value of PS1
Not all shells subject the prompt string to parameter expansion.  Test
whether the shell will expand the value of PS1, and use the result to
control whether raw ref names are included directly in PS1.

This fixes a regression introduced in commit 8976500 ("git-prompt.sh:
don't put unsanitized branch names in $PS1"):  zsh does not expand PS1
by default, but that commit assumed it did.  The bug resulted in
prompts containing the literal string '${__git_ps1_branch_name}'
instead of the actual branch name.

Reported-by: Caleb Thompson <caleb@calebthompson.io>
Signed-off-by: Richard Hansen <rhansen@bbn.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-19 16:09:53 -07:00
7dde48ea7a Merge branch 'lt/request-pull'
* lt/request-pull:
  request-pull: resurrect for-linus -> tags/for-linus DWIM
2014-05-19 10:35:36 -07:00
5714722f71 Merge branch 'jl/use-vsatisfy-correctly-for-2.0'
* jl/use-vsatisfy-correctly-for-2.0:
  git-gui: tolerate major version changes when comparing the git version
2014-05-19 10:35:24 -07:00
c29bf4a556 Merge git://github.com/git-l10n/git-po
* git://github.com/git-l10n/git-po:
  fr: a lot of good fixups
2014-05-19 10:32:56 -07:00
3fc2aea770 Merge branch 'kb/fast-hashmap'
* kb/fast-hashmap:
  Documentation/technical/api-hashmap: remove source highlighting
2014-05-19 10:32:25 -07:00
c2538fd6ba Documentation/technical/api-hashmap: remove source highlighting
The highlighting was pretty, but unfortunately, the failure mode
when source-highlight is not installed was that the entire code
block disappears.

See https://bugs.debian.org/745591,
    https://bugs.launchpad.net/bugs/1316810.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-19 10:31:36 -07:00
b3f0c5c04e git-gui: tolerate major version changes when comparing the git version
Since git 2.0.0 starting git gui in a submodule using a gitfile fails with
the following error:

   No working directory ../../../<path>

   couldn't change working directory
   to "../../../<path>": no such file or
   directory

This is because "git rev-parse --show-toplevel" is only run when git gui
sees a git version of at least 1.7.0 (which is the version in which the
--show-toplevel option was introduced). But "package vsatisfies" returns
false when the major version changes, which is not what we want here.

Fix that for both places where the git version is checked using vsatisfies
by appending a '-' to the version number. This tells vsatisfies that a
change of the major version is not considered to be a problem, as long as
the new major version is larger. This is done for both the place that
caused the reported bug and another spot where the git version is tested
for another feature.

Reported-by: Chris Packham <judge.packham@gmail.com>
Reported-by: Yann Dirson <ydirson@free.fr>
Helped-by: Pat Thoyts <patthoyts@users.sourceforge.net>
Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
Tested-by: Chris Packham <judge.packham@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-19 10:12:45 -07:00
a6e888397c fr: a lot of good fixups
Signed-off-by: Grégoire Paris <postmaster@greg0ire.fr>
Acked-by: Jean-Noel Avila <jn.avila@free.fr>
2014-05-17 19:08:59 +02:00
d952cbb190 request-pull: resurrect for-linus -> tags/for-linus DWIM
Older versions of Git before v1.7.10 did not DWIM

    $ git pull $URL for-linus

to the tag "tags/for-linus" and the users were required to say

    $ git pull $URL tags/for-linus

instead.  Because newer versions of Git works either way,
request-pull used to show tags/for-linus when asked

    $ git request-pull origin/master $URL for-linus

The recent updates broke this and in the output we see "for-linus"
without the "tags/" prefix.

As v1.7.10 is more than 2 years old, this should matter very little
in practice, but resurrecting it is very simple.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-16 10:18:25 -07:00
6308767f0b Merge branch 'fc/prompt-zsh-read-from-file'
* fc/prompt-zsh-read-from-file:
  contrib: completion: fix 'eread()' namespace
2014-05-13 11:53:14 -07:00
66ab301c16 contrib: completion: fix 'eread()' namespace
Otherwise it might collide with a function of the same name in the
user's environment.

Suggested-by: SZEDER Gábor <szeder@ira.uka.de>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-13 11:52:51 -07:00
998f84075a Merge git://github.com/git-l10n/git-po
* git://github.com/git-l10n/git-po:
  l10n: Updated Bulgarian translation of git (1307t0f921u)
2014-05-12 10:12:05 -07:00
1c3c8410ef l10n: Updated Bulgarian translation of git (1307t0f921u)
Signed-off-by: Alexander Shopov <ash@kambanaria.org>
2014-05-11 17:09:01 +03:00
19 changed files with 3060 additions and 6830 deletions

View File

@ -44,7 +44,7 @@ with "git diff-files --diff-filter=d").
The default prefix for "git svn" has changed in Git 2.0. For a long
time, "git svn" created its remote-tracking branches directly under
refs/remotes, but it now places them under refs/remotes/origin/ unless
it is told otherwise with its --prefix option.
it is told otherwise with its "--prefix" option.
Updates since v1.9 series
@ -53,7 +53,11 @@ Updates since v1.9 series
UI, Workflows & Features
* The "multi-mail" post-receive hook (in contrib/) has been updated
to a more recent version from the upstream.
to a more recent version from upstream.
* The "remote-hg/bzr" remote-helper interfaces (used to be in
contrib/) are no more. They are now maintained separately as
third-party plug-ins in their own repositories.
* "git gc --aggressive" learned "--depth" option and
"gc.aggressiveDepth" configuration variable to allow use of a less
@ -63,12 +67,13 @@ UI, Workflows & Features
single strand-of-pearls is broken in its output.
* The "rev-parse --parseopt" mechanism used by scripted Porcelains to
parse command line options and to give help text learned to take
parse command-line options and to give help text learned to take
the argv-help (the placeholder string for an option parameter,
e.g. "key-id" in "--gpg-sign=<key-id>").
* The pattern to find where the function begins in C/C++ used in
"diff" and "grep -p" has been updated to help C++ source better.
"diff" and "grep -p" has been updated to improve viewing C++
sources.
* "git rebase" learned to interpret a lone "-" as "@{-1}", the
branch that we were previously on.
@ -79,7 +84,7 @@ UI, Workflows & Features
"--sort=version:refname".
* Discard the accumulated "heuristics" to guess from which branch the
result wants to be pulled from and make sure what the end user
result wants to be pulled from and make sure that what the end user
specified is not second-guessed by "git request-pull", to avoid
mistakes. When you pushed out your 'master' branch to your public
repository as 'for-linus', use the new "master:for-linus" syntax to
@ -88,9 +93,9 @@ UI, Workflows & Features
* "git grep" learned to behave in a way similar to native grep when
"-h" (no header) and "-c" (count) options are given.
* "git push" via transport-helper interface (e.g. remote-hg) has
been updated to allow forced ref updates in a way similar to the
natively supported transports.
* "git push" via transport-helper interface has been updated to
allow forced ref updates in a way similar to the natively
supported transports.
* The "simple" mode is the default for "git push".
@ -114,28 +119,28 @@ UI, Workflows & Features
* The progress indicators from various time-consuming commands have
been marked for i18n/l10n.
* "git notes -C <blob>" diagnoses an attempt to use an object that
is not a blob as an error.
* "git notes -C <blob>" diagnoses as an error an attempt to use an
object that is not a blob.
* "git config" learned to read from the standard input when "-" is
given as the value to its "--file" parameter (attempting an
operation to update the configuration in the standard input of
course is rejected).
operation to update the configuration in the standard input is
rejected, of course).
* Trailing whitespaces in .gitignore files, unless they are quoted
for fnmatch(3), e.g. "path\ ", are warned and ignored. Strictly
speaking, this is a backward incompatible change, but very unlikely
speaking, this is a backward-incompatible change, but very unlikely
to bite any sane user and adjusting should be obvious and easy.
* Many commands that create commits, e.g. "pull", "rebase",
learned to take the --gpg-sign option on the command line.
* Many commands that create commits, e.g. "pull" and "rebase",
learned to take the "--gpg-sign" option on the command line.
* "git commit" can be told to always GPG sign the resulting commit
by setting "commit.gpgsign" configuration variable to true (the
command line option --no-gpg-sign should override it).
by setting the "commit.gpgsign" configuration variable to "true"
(the command-line option "--no-gpg-sign" should override it).
* "git pull" can be told to only accept fast-forward by setting the
new "pull.ff" configuration.
new "pull.ff" configuration variable.
* "git reset" learned the "-N" option, which does not reset the index
fully for paths the index knows about but the tree-ish the command
@ -152,7 +157,7 @@ Performance, Internal Implementation, etc.
* Uses of curl's "multi" interface and "easy" interface do not mix
well when we attempt to reuse outgoing connections. Teach the RPC
over http code, used in the smart HTTP transport, not to use the
over HTTP code, used in the smart HTTP transport, not to use the
"easy" interface.
* The bitmap-index feature from JGit has been ported, which should
@ -186,24 +191,19 @@ notes for details).
* The shell prompt script (in contrib/), when using the PROMPT_COMMAND
interface, used an unsafe construct when showing the branch name in
$PS1.
(merge 8976500 rh/prompt-pcmode-avoid-eval-on-refname later to maint).
(merge 1e4119c8 rh/prompt-pcmode-avoid-eval-on-refname later to maint).
* The remote-helper interface to fast-import/fast-export via the
transport-helper has been tightened to avoid leaving the import
marks file from a failed/crashed run, as such a file that is out of
sync with the reality confuses a later invocation of itself.
* "git rebase" used a POSIX shell construct FreeBSD /bin/sh does not
* "git rebase" used a POSIX shell construct FreeBSD's /bin/sh does not
work well with.
(merge 8cd6596 km/avoid-non-function-return-in-rebase later to maint).
* zsh prompt (in contrib/) leaked unnecessary error messages.
* bash completion (in contrib/) did not complete the refs and remotes
* Bash completion (in contrib/) did not complete the refs and remotes
correctly given "git pu<TAB>" when "pu" is aliased to "push".
* Some more Unicode codepoints defined in Unicode 6.3 as having zero
width have been taught to our display column counting logic.
* Some more Unicode code points, defined in Unicode 6.3 as having zero
width, have been taught to our display column counting logic.
(merge d813ab9 tb/unicode-6.3-zero-width later to maint).
* Some tests used shell constructs that did not work well on FreeBSD
@ -217,7 +217,7 @@ notes for details).
* "git diff --no-index -Mq a b" fell into an infinite loop.
(merge ad1c3fb jc/fix-diff-no-index-diff-opt-parse later to maint).
* "git fetch --prune", when the right-hand-side of multiple fetch
* "git fetch --prune", when the right-hand side of multiple fetch
refspecs overlap (e.g. storing "refs/heads/*" to
"refs/remotes/origin/*", while storing "refs/frotz/*" to
"refs/remotes/origin/fr/*"), aggressively thought that lack of
@ -272,7 +272,7 @@ notes for details).
(merge 3c3e6f5 rr/doc-merge-strategies later to maint).
* Serving objects from a shallow repository needs to write a
new file to hold the temporary shallow boundaries but it was not
new file to hold the temporary shallow boundaries, but it was not
cleaned when we exit due to die() or a signal.
(merge 7839632 jk/shallow-update-fix later to maint).
@ -295,19 +295,19 @@ notes for details).
".git" tells us where it is.
(merge fcfec8b da/difftool-git-files later to maint).
* "git push" did not pay attention to branch.*.pushremote if it is
defined earlier than remote.pushdefault; the order of these two
* "git push" did not pay attention to "branch.*.pushremote" if it is
defined earlier than "remote.pushdefault"; the order of these two
variables in the configuration file should not matter, but it did
by mistake.
(merge 98b406f jk/remote-pushremote-config-reading later to maint).
* Codepaths that parse timestamps in commit objects have been
* Code paths that parse timestamps in commit objects have been
tightened.
(merge f80d1f9 jk/commit-dates-parsing-fix later to maint).
* "git diff --external-diff" incorrectly fed the submodule directory
in the working tree to the external diff driver when it knew it is
the same as one of the versions being compared.
in the working tree to the external diff driver when it knew that it
is the same as one of the versions being compared.
(merge aba4727 tr/diff-submodule-no-reuse-worktree later to maint).
* "git reset" needs to refresh the index when working in a working
@ -318,7 +318,7 @@ notes for details).
* "git check-attr" when working on a repository with a working tree
did not work well when the working tree was specified via the
--work-tree (and obviously with --git-dir) option.
"--work-tree" (and obviously with "--git-dir") option.
(merge cdbf623 jc/check-attr-honor-working-tree later to maint).
* "merge-recursive" was broken in 1.7.7 era and stopped working in
@ -326,12 +326,12 @@ notes for details).
involved. This has been corrected.
(merge 6e2068a bk/refresh-missing-ok-in-merge-recursive later to maint.)
* "git rev-parse" was loose in rejecting command line arguments
* "git rev-parse" was loose in rejecting command-line arguments
that do not make sense, e.g. "--default" without the required
value for that option.
(merge a43219f ds/rev-parse-required-args later to maint.)
* include.path variable (or any variable that expects a path that
* "include.path" variable (or any variable that expects a path that
can use ~username expansion) in the configuration file is not a
boolean, but the code failed to check it.
(merge 67beb60 jk/config-path-include-fix later to maint.)
@ -340,23 +340,23 @@ notes for details).
the pathspec is given as an absolute pathname (which is a
practice not particularly encouraged) that points at a symbolic
link in the working tree.
(merge later 655ee9e mw/symlinks to maint.)
(merge 6127ff6 mw/symlinks later to maint.)
* "git diff --quiet -- pathspec1 pathspec2" sometimes did not return
correct status value.
the correct status value.
(merge f34b205 nd/diff-quiet-stat-dirty later to maint.)
* Attempting to deepen a shallow repository by fetching over smart
HTTP transport failed in the protocol exchange, when no-done
HTTP transport failed in the protocol exchange, when the no-done
extension was used. The fetching side waited for the list of
shallow boundary commits after the sending end stopped talking to
shallow boundary commits after the sending side stopped talking to
it.
(merge 0232852 nd/http-fetch-shallow-fix later to maint.)
* Allow "git cmd path/", when the 'path' is where a submodule is
bound to the top-level working tree, to match 'path', despite the
extra and unnecessary trailing slash (such a slash is often
given by command line completion).
given by command-line completion).
(merge 2e70c01 nd/submodule-pathspec-ending-with-slash later to maint.)
* Documentation and in-code comments had many instances of mistaken

View File

@ -43,6 +43,11 @@ unreleased) version of Git, that is available from 'master'
branch of the `git.git` repository.
Documentation for older releases are available here:
* link:v2.0.0/git.html[documentation for release 2.0]
* release notes for
link:RelNotes/2.0.0.txt[2.0.0].
* link:v1.9.3/git.html[documentation for release 1.9.3]
* release notes for

View File

@ -166,7 +166,6 @@ Usage example
-------------
Here's a simple usage example that maps long keys to double values.
[source,c]
------------
struct hashmap map;

View File

@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
DEF_VER=v2.0.0-rc3
DEF_VER=v2.0.0
LF='
'

View File

@ -209,9 +209,7 @@ __git_ps1_show_upstream ()
if [[ -n "$count" && -n "$name" ]]; then
__git_ps1_upstream_name=$(git rev-parse \
--abbrev-ref "$upstream" 2>/dev/null)
if [ $pcmode = yes ]; then
# see the comments around the
# __git_ps1_branch_name variable below
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
p="$p \${__git_ps1_upstream_name}"
else
p="$p ${__git_ps1_upstream_name}"
@ -270,7 +268,7 @@ __git_ps1_colorize_gitstring ()
r="$c_clear$r"
}
eread ()
__git_eread ()
{
f="$1"
shift
@ -308,6 +306,43 @@ __git_ps1 ()
;;
esac
# ps1_expanded: This variable is set to 'yes' if the shell
# subjects the value of PS1 to parameter expansion:
#
# * bash does unless the promptvars option is disabled
# * zsh does not unless the PROMPT_SUBST option is set
# * POSIX shells always do
#
# If the shell would expand the contents of PS1 when drawing
# the prompt, a raw ref name must not be included in PS1.
# This protects the user from arbitrary code execution via
# specially crafted ref names. For example, a ref named
# 'refs/heads/$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' might cause the
# shell to execute 'sudo rm -rf /' when the prompt is drawn.
#
# Instead, the ref name should be placed in a separate global
# variable (in the __git_ps1_* namespace to avoid colliding
# with the user's environment) and that variable should be
# referenced from PS1. For example:
#
# __git_ps1_foo=$(do_something_to_get_ref_name)
# PS1="...stuff...\${__git_ps1_foo}...stuff..."
#
# If the shell does not expand the contents of PS1, the raw
# ref name must be included in PS1.
#
# The value of this variable is only relevant when in pcmode.
#
# Assume that the shell follows the POSIX specification and
# expands PS1 unless determined otherwise. (This is more
# likely to be correct if the user has a non-bash, non-zsh
# shell and safer than the alternative if the assumption is
# incorrect.)
#
local ps1_expanded=yes
[ -z "$ZSH_VERSION" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
[ -z "$BASH_VERSION" ] || shopt -q promptvars || ps1_expanded=no
local repo_info rev_parse_exit_code
repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
--is-bare-repository --is-inside-work-tree \
@ -339,9 +374,9 @@ __git_ps1 ()
local step=""
local total=""
if [ -d "$g/rebase-merge" ]; then
eread "$g/rebase-merge/head-name" b
eread "$g/rebase-merge/msgnum" step
eread "$g/rebase-merge/end" total
__git_eread "$g/rebase-merge/head-name" b
__git_eread "$g/rebase-merge/msgnum" step
__git_eread "$g/rebase-merge/end" total
if [ -f "$g/rebase-merge/interactive" ]; then
r="|REBASE-i"
else
@ -349,10 +384,10 @@ __git_ps1 ()
fi
else
if [ -d "$g/rebase-apply" ]; then
eread "$g/rebase-apply/next" step
eread "$g/rebase-apply/last" total
__git_eread "$g/rebase-apply/next" step
__git_eread "$g/rebase-apply/last" total
if [ -f "$g/rebase-apply/rebasing" ]; then
eread "$g/rebase-apply/head-name" b
__git_eread "$g/rebase-apply/head-name" b
r="|REBASE"
elif [ -f "$g/rebase-apply/applying" ]; then
r="|AM"
@ -376,7 +411,7 @@ __git_ps1 ()
b="$(git symbolic-ref HEAD 2>/dev/null)"
else
local head=""
if ! eread "$g/HEAD" head; then
if ! __git_eread "$g/HEAD" head; then
if [ $pcmode = yes ]; then
PS1="$ps1pc_start$ps1pc_end"
fi
@ -457,21 +492,8 @@ __git_ps1 ()
fi
b=${b##refs/heads/}
if [ $pcmode = yes ]; then
# In pcmode (and only pcmode) the contents of
# $gitstring are subject to expansion by the shell.
# Avoid putting the raw ref name in the prompt to
# protect the user from arbitrary code execution via
# specially crafted ref names (e.g., a ref named
# '$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' would execute
# 'sudo rm -rf /' when the prompt is drawn). Instead,
# put the ref name in a new global variable (in the
# __git_ps1_* namespace to avoid colliding with the
# user's environment) and reference that variable from
# PS1.
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
__git_ps1_branch_name=$b
# note that the $ is escaped -- the variable will be
# expanded later (when it's time to draw the prompt)
b="\${__git_ps1_branch_name}"
fi

View File

@ -1,14 +0,0 @@
TESTS := $(wildcard test*.sh)
export T := $(addprefix $(CURDIR)/,$(TESTS))
export MAKE := $(MAKE) -e
export PATH := $(CURDIR):$(PATH)
export TEST_LINT := test-lint-executable test-lint-shell-syntax
test:
$(MAKE) -C ../../t $@
$(TESTS):
$(MAKE) -C ../../t $(CURDIR)/$@
.PHONY: $(TESTS)

View File

@ -0,0 +1,15 @@
The remote-helper bridges to access data stored in Mercurial and
Bazaar are maintained outside the git.git tree in the repositories
of their primary author:
https://github.com/felipec/git-remote-hg (for Mercurial)
https://github.com/felipec/git-remote-bzr (for Bazaar)
You can pick a directory on your $PATH and download them from these
repositories, e.g.:
$ wget -O $HOME/bin/git-remote-hg \
https://raw.github.com/felipec/git-remote-hg/master/git-remote-hg
$ wget -O $HOME/bin/git-remote-bzr \
https://raw.github.com/felipec/git-remote-bzr/master/git-remote-bzr
$ chmod +x $HOME/bin/git-remote-hg $HOME/bin/git-remote-bzr

View File

@ -1,983 +1,13 @@
#!/usr/bin/env python
#
# Copyright (c) 2012 Felipe Contreras
#
#
# Just copy to your ~/bin, or anywhere in your $PATH.
# Then you can clone with:
# % git clone bzr::/path/to/bzr/repo/or/url
#
# For example:
# % git clone bzr::$HOME/myrepo
# or
# % git clone bzr::lp:myrepo
#
# 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
import bzrlib
if hasattr(bzrlib, "initialize"):
bzrlib.initialize()
import bzrlib.plugin
bzrlib.plugin.load_plugins()
import bzrlib.generate_ids
import bzrlib.transport
import bzrlib.errors
import bzrlib.ui
import bzrlib.urlutils
import bzrlib.branch
import sys
import os
import json
import re
import StringIO
import atexit, shutil, hashlib, urlparse, subprocess
NAME_RE = re.compile('^([^<>]+)')
AUTHOR_RE = re.compile('^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')
EMAIL_RE = re.compile(r'([^ \t<>]+@[^ \t<>]+)')
RAW_AUTHOR_RE = re.compile('^(\w+) (.+)? <(.*)> (\d+) ([+-]\d+)')
def die(msg, *args):
sys.stderr.write('ERROR: %s\n' % (msg % args))
sys.exit(1)
def warn(msg, *args):
sys.stderr.write('WARNING: %s\n' % (msg % args))
def gittz(tz):
return '%+03d%02d' % (tz / 3600, tz % 3600 / 60)
def get_config(config):
cmd = ['git', 'config', '--get', config]
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output, _ = process.communicate()
return output
class Marks:
def __init__(self, path):
self.path = path
self.tips = {}
self.marks = {}
self.rev_marks = {}
self.last_mark = 0
self.load()
def load(self):
if not os.path.exists(self.path):
return
tmp = json.load(open(self.path))
self.tips = tmp['tips']
self.marks = tmp['marks']
self.last_mark = tmp['last-mark']
for rev, mark in self.marks.iteritems():
self.rev_marks[mark] = rev
def dict(self):
return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark }
def store(self):
json.dump(self.dict(), open(self.path, 'w'))
def __str__(self):
return str(self.dict())
def from_rev(self, rev):
return self.marks[rev]
def to_rev(self, mark):
return str(self.rev_marks[mark])
def next_mark(self):
self.last_mark += 1
return self.last_mark
def get_mark(self, rev):
self.last_mark += 1
self.marks[rev] = self.last_mark
return self.last_mark
def is_marked(self, rev):
return rev in self.marks
def new_mark(self, rev, mark):
self.marks[rev] = mark
self.rev_marks[mark] = rev
self.last_mark = mark
def get_tip(self, branch):
try:
return str(self.tips[branch])
except KeyError:
return None
def set_tip(self, branch, tip):
self.tips[branch] = tip
class Parser:
def __init__(self, repo):
self.repo = repo
self.line = self.get_line()
def get_line(self):
return sys.stdin.readline().strip()
def __getitem__(self, i):
return self.line.split()[i]
def check(self, word):
return self.line.startswith(word)
def each_block(self, separator):
while self.line != separator:
yield self.line
self.line = self.get_line()
def __iter__(self):
return self.each_block('')
def next(self):
self.line = self.get_line()
if self.line == 'done':
self.line = None
def get_mark(self):
i = self.line.index(':') + 1
return int(self.line[i:])
def get_data(self):
if not self.check('data'):
return None
i = self.line.index(' ') + 1
size = int(self.line[i:])
return sys.stdin.read(size)
def get_author(self):
m = RAW_AUTHOR_RE.match(self.line)
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):
return marks.from_rev(rev)
def mark_to_rev(mark):
return marks.to_rev(mark)
def fixup_user(user):
name = mail = None
user = user.replace('"', '')
m = AUTHOR_RE.match(user)
if m:
name = m.group(1)
mail = m.group(2).strip()
else:
m = EMAIL_RE.match(user)
if m:
mail = m.group(1)
else:
m = NAME_RE.match(user)
if m:
name = m.group(1).strip()
if not name:
name = 'unknown'
if not mail:
mail = 'Unknown'
return '%s <%s>' % (name, mail)
def get_filechanges(cur, prev):
modified = {}
removed = {}
changes = cur.changes_from(prev)
def u(s):
return s.encode('utf-8')
for path, fid, kind in changes.added:
modified[u(path)] = fid
for path, fid, kind in changes.removed:
removed[u(path)] = None
for path, fid, kind, mod, _ in changes.modified:
modified[u(path)] = fid
for oldpath, newpath, fid, kind, mod, _ in changes.renamed:
removed[u(oldpath)] = None
if kind == 'directory':
lst = cur.list_files(from_dir=newpath, recursive=True)
for path, file_class, kind, fid, entry in lst:
if kind != 'directory':
modified[u(newpath + '/' + path)] = fid
else:
modified[u(newpath)] = fid
return modified, removed
def export_files(tree, files):
final = []
for path, fid in files.iteritems():
kind = tree.kind(fid)
h = tree.get_file_sha1(fid)
if kind == 'symlink':
d = tree.get_symlink_target(fid)
mode = '120000'
elif kind == 'file':
if tree.is_executable(fid):
mode = '100755'
else:
mode = '100644'
# is the blob already exported?
if h in filenodes:
mark = filenodes[h]
final.append((mode, mark, path))
continue
d = tree.get_file_text(fid)
elif kind == 'directory':
continue
else:
die("Unhandled kind '%s' for path '%s'" % (kind, path))
mark = marks.next_mark()
filenodes[h] = mark
print "blob"
print "mark :%u" % mark
print "data %d" % len(d)
print d
final.append((mode, mark, path))
return final
def export_branch(repo, name):
ref = '%s/heads/%s' % (prefix, name)
tip = marks.get_tip(name)
branch = get_remote_branch(name)
repo = branch.repository
branch.lock_read()
revs = branch.iter_merge_sorted_revisions(None, tip, 'exclude', 'forward')
try:
tip_revno = branch.revision_id_to_revno(tip)
last_revno, _ = branch.last_revision_info()
total = last_revno - tip_revno
except bzrlib.errors.NoSuchRevision:
tip_revno = 0
total = 0
for revid, _, seq, _ in revs:
if marks.is_marked(revid):
continue
rev = repo.get_revision(revid)
revno = seq[0]
parents = rev.parent_ids
time = rev.timestamp
tz = rev.timezone
committer = rev.committer.encode('utf-8')
committer = "%s %u %s" % (fixup_user(committer), time, gittz(tz))
authors = rev.get_apparent_authors()
if authors:
author = authors[0].encode('utf-8')
author = "%s %u %s" % (fixup_user(author), time, gittz(tz))
else:
author = committer
msg = rev.message.encode('utf-8')
msg += '\n'
if len(parents) == 0:
parent = bzrlib.revision.NULL_REVISION
else:
parent = parents[0]
cur_tree = repo.revision_tree(revid)
prev = repo.revision_tree(parent)
modified, removed = get_filechanges(cur_tree, prev)
modified_final = export_files(cur_tree, modified)
if len(parents) == 0:
print 'reset %s' % ref
print "commit %s" % ref
print "mark :%d" % (marks.get_mark(revid))
print "author %s" % (author)
print "committer %s" % (committer)
print "data %d" % (len(msg))
print msg
for i, p in enumerate(parents):
try:
m = rev_to_mark(p)
except KeyError:
# ghost?
continue
if i == 0:
print "from :%s" % m
else:
print "merge :%s" % m
for f in removed:
print "D %s" % (f,)
for f in modified_final:
print "M %s :%u %s" % f
print
if len(seq) > 1:
# let's skip branch revisions from the progress report
continue
progress = (revno - tip_revno)
if (progress % 100 == 0):
if total:
print "progress revision %d '%s' (%d/%d)" % (revno, name, progress, total)
else:
print "progress revision %d '%s' (%d)" % (revno, name, progress)
branch.unlock()
revid = branch.last_revision()
# make sure the ref is updated
print "reset %s" % ref
print "from :%u" % rev_to_mark(revid)
print
marks.set_tip(name, revid)
def export_tag(repo, name):
ref = '%s/tags/%s' % (prefix, name)
print "reset %s" % ref
print "from :%u" % rev_to_mark(tags[name])
print
def do_import(parser):
repo = parser.repo
path = os.path.join(dirname, 'marks-git')
print "feature done"
if os.path.exists(path):
print "feature import-marks=%s" % path
print "feature export-marks=%s" % path
print "feature force"
sys.stdout.flush()
while parser.check('import'):
ref = parser[1]
if ref.startswith('refs/heads/'):
name = ref[len('refs/heads/'):]
export_branch(repo, name)
if ref.startswith('refs/tags/'):
name = ref[len('refs/tags/'):]
export_tag(repo, name)
parser.next()
print 'done'
sys.stdout.flush()
def parse_blob(parser):
parser.next()
mark = parser.get_mark()
parser.next()
data = parser.get_data()
blob_marks[mark] = data
parser.next()
class CustomTree():
def __init__(self, branch, revid, parents, files):
self.updates = {}
self.branch = branch
def copy_tree(revid):
files = files_cache[revid] = {}
branch.lock_read()
tree = branch.repository.revision_tree(revid)
try:
for path, entry in tree.iter_entries_by_dir():
files[path] = [entry.file_id, None]
finally:
branch.unlock()
return files
if len(parents) == 0:
self.base_id = bzrlib.revision.NULL_REVISION
self.base_files = {}
else:
self.base_id = parents[0]
self.base_files = files_cache.get(self.base_id, None)
if not self.base_files:
self.base_files = copy_tree(self.base_id)
self.files = files_cache[revid] = self.base_files.copy()
self.rev_files = {}
for path, data in self.files.iteritems():
fid, mark = data
self.rev_files[fid] = [path, mark]
for path, f in files.iteritems():
fid, mark = self.files.get(path, [None, None])
if not fid:
fid = bzrlib.generate_ids.gen_file_id(path)
f['path'] = path
self.rev_files[fid] = [path, mark]
self.updates[fid] = f
def last_revision(self):
return self.base_id
def iter_changes(self):
changes = []
def get_parent(dirname, basename):
parent_fid, mark = self.base_files.get(dirname, [None, None])
if parent_fid:
return parent_fid
parent_fid, mark = self.files.get(dirname, [None, None])
if parent_fid:
return parent_fid
if basename == '':
return None
fid = bzrlib.generate_ids.gen_file_id(path)
add_entry(fid, dirname, 'directory')
return fid
def add_entry(fid, path, kind, mode=None):
dirname, basename = os.path.split(path)
parent_fid = get_parent(dirname, basename)
executable = False
if mode == '100755':
executable = True
elif mode == '120000':
kind = 'symlink'
change = (fid,
(None, path),
True,
(False, True),
(None, parent_fid),
(None, basename),
(None, kind),
(None, executable))
self.files[path] = [change[0], None]
changes.append(change)
def update_entry(fid, path, kind, mode=None):
dirname, basename = os.path.split(path)
parent_fid = get_parent(dirname, basename)
executable = False
if mode == '100755':
executable = True
elif mode == '120000':
kind = 'symlink'
change = (fid,
(path, path),
True,
(True, True),
(None, parent_fid),
(None, basename),
(None, kind),
(None, executable))
self.files[path] = [change[0], None]
changes.append(change)
def remove_entry(fid, path, kind):
dirname, basename = os.path.split(path)
parent_fid = get_parent(dirname, basename)
change = (fid,
(path, None),
True,
(True, False),
(parent_fid, None),
(None, None),
(None, None),
(None, None))
del self.files[path]
changes.append(change)
for fid, f in self.updates.iteritems():
path = f['path']
if 'deleted' in f:
remove_entry(fid, path, 'file')
continue
if path in self.base_files:
update_entry(fid, path, 'file', f['mode'])
else:
add_entry(fid, path, 'file', f['mode'])
self.files[path][1] = f['mark']
self.rev_files[fid][1] = f['mark']
return changes
def get_content(self, file_id):
path, mark = self.rev_files[file_id]
if mark:
return blob_marks[mark]
# last resort
tree = self.branch.repository.revision_tree(self.base_id)
return tree.get_file_text(file_id)
def get_file_with_stat(self, file_id, path=None):
content = self.get_content(file_id)
return (StringIO.StringIO(content), None)
def get_symlink_target(self, file_id):
return self.get_content(file_id)
def id2path(self, file_id):
path, mark = self.rev_files[file_id]
return path
def c_style_unescape(string):
if string[0] == string[-1] == '"':
return string.decode('string-escape')[1:-1]
return string
def parse_commit(parser):
parents = []
ref = parser[1]
parser.next()
if ref.startswith('refs/heads/'):
name = ref[len('refs/heads/'):]
branch = get_remote_branch(name)
else:
die('unknown ref')
commit_mark = parser.get_mark()
parser.next()
author = parser.get_author()
parser.next()
committer = parser.get_author()
parser.next()
data = parser.get_data()
parser.next()
if parser.check('from'):
parents.append(parser.get_mark())
parser.next()
while parser.check('merge'):
parents.append(parser.get_mark())
parser.next()
# fast-export adds an extra newline
if data[-1] == '\n':
data = data[:-1]
files = {}
for line in parser:
if parser.check('M'):
t, m, mark_ref, path = line.split(' ', 3)
mark = int(mark_ref[1:])
f = { 'mode' : m, 'mark' : mark }
elif parser.check('D'):
t, path = line.split(' ', 1)
f = { 'deleted' : True }
else:
die('Unknown file command: %s' % line)
path = c_style_unescape(path).decode('utf-8')
files[path] = f
committer, date, tz = committer
author, _, _ = author
parents = [mark_to_rev(p) for p in parents]
revid = bzrlib.generate_ids.gen_revision_id(committer, date)
props = {}
props['branch-nick'] = branch.nick
props['authors'] = author
mtree = CustomTree(branch, revid, parents, files)
changes = mtree.iter_changes()
branch.lock_write()
try:
builder = branch.get_commit_builder(parents, None, date, tz, committer, props, revid)
try:
list(builder.record_iter_changes(mtree, mtree.last_revision(), changes))
builder.finish_inventory()
builder.commit(data.decode('utf-8', 'replace'))
except Exception, e:
builder.abort()
raise
finally:
branch.unlock()
parsed_refs[ref] = revid
marks.new_mark(revid, commit_mark)
def parse_reset(parser):
ref = parser[1]
parser.next()
# ugh
if parser.check('commit'):
parse_commit(parser)
return
if not parser.check('from'):
return
from_mark = parser.get_mark()
parser.next()
parsed_refs[ref] = mark_to_rev(from_mark)
def do_export(parser):
parser.next()
for line in parser.each_block('done'):
if parser.check('blob'):
parse_blob(parser)
elif parser.check('commit'):
parse_commit(parser)
elif parser.check('reset'):
parse_reset(parser)
elif parser.check('tag'):
pass
elif parser.check('feature'):
pass
else:
die('unhandled export command: %s' % line)
for ref, revid in parsed_refs.iteritems():
if ref.startswith('refs/heads/'):
name = ref[len('refs/heads/'):]
branch = get_remote_branch(name)
branch.generate_revision_history(revid, marks.get_tip(name))
if name in peers:
peer = bzrlib.branch.Branch.open(peers[name],
possible_transports=transports)
try:
peer.bzrdir.push_branch(branch, revision_id=revid,
overwrite=force)
except bzrlib.errors.DivergedBranches:
print "error %s non-fast forward" % ref
continue
try:
wt = branch.bzrdir.open_workingtree()
wt.update()
except bzrlib.errors.NoWorkingTree:
pass
elif ref.startswith('refs/tags/'):
# TODO: implement tag push
print "error %s pushing tags not supported" % ref
continue
else:
# transport-helper/fast-export bugs
continue
print "ok %s" % ref
print
def do_capabilities(parser):
print "import"
print "export"
print "refspec refs/heads/*:%s/heads/*" % prefix
print "refspec refs/tags/*:%s/tags/*" % prefix
path = os.path.join(dirname, 'marks-git')
if os.path.exists(path):
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):
master_branch = None
for name in branches:
if not master_branch:
master_branch = name
print "? refs/heads/%s" % name
branch = get_remote_branch(master_branch)
branch.lock_read()
for tag, revid in branch.tags.get_tag_dict().items():
try:
branch.revision_id_to_dotted_revno(revid)
except bzrlib.errors.NoSuchRevision:
continue
if not ref_is_valid(tag):
continue
print "? refs/tags/%s" % tag
tags[tag] = revid
branch.unlock()
print "@refs/heads/%s HEAD" % master_branch
print
def clone(path, remote_branch):
try:
bdir = bzrlib.bzrdir.BzrDir.create(path, possible_transports=transports)
except bzrlib.errors.AlreadyControlDirError:
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):
remote_branch = bzrlib.branch.Branch.open(branches[name],
possible_transports=transports)
if isinstance(remote_branch.bzrdir.root_transport, bzrlib.transport.local.LocalTransport):
return remote_branch
branch_path = os.path.join(dirname, 'clone', name)
try:
branch = bzrlib.branch.Branch.open(branch_path,
possible_transports=transports)
except bzrlib.errors.NotBranchError:
# clone
branch = clone(branch_path, remote_branch)
else:
# pull
try:
branch.pull(remote_branch, overwrite=True)
except bzrlib.errors.DivergedBranches:
# use remote branch for now
return remote_branch
return branch
def find_branches(repo):
transport = repo.bzrdir.root_transport
for fn in transport.iter_files_recursive():
if not fn.endswith('.bzr/branch-format'):
continue
name = subdir = fn[:-len('/.bzr/branch-format')]
name = name if name != '' else 'master'
name = name.replace('/', '+')
try:
cur = transport.clone(subdir)
branch = bzrlib.branch.Branch.open_from_transport(cur)
except bzrlib.errors.NotBranchError:
continue
else:
yield name, branch.base
def get_repo(url, alias):
normal_url = bzrlib.urlutils.normalize_url(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,
possible_transports=transports)
except bzrlib.errors.NotBranchError:
shared_dir = bzrlib.bzrdir.BzrDir.create(shared_path,
possible_transports=transports)
try:
shared_repo = shared_dir.open_repository()
except bzrlib.errors.NoRepositoryPresent:
shared_repo = shared_dir.create_repository(shared=True)
if not is_local:
clone_path = os.path.join(dirname, 'clone')
if not os.path.exists(clone_path):
os.mkdir(clone_path)
else:
# check and remove old organization
try:
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.%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:
repo = origin.open_repository()
if not repo.bzrdir.root_transport.listable():
# this repository is not usable for us
raise bzrlib.errors.NoRepositoryPresent(repo.bzrdir)
except bzrlib.errors.NoRepositoryPresent:
wanted = ['master']
if wanted:
def list_wanted(url, wanted):
for name in wanted:
subdir = name if name != 'master' else ''
yield name, bzrlib.urlutils.join(url, subdir)
branch_list = list_wanted(url, wanted)
else:
branch_list = find_branches(repo)
for name, url in branch_list:
if not is_local:
peers[name] = url
branches[name] = url
return origin
def fix_path(alias, orig_url):
url = urlparse.urlparse(orig_url, 'file')
if url.scheme != 'file' or os.path.isabs(url.path):
return
abs_url = urlparse.urljoin("%s/" % os.getcwd(), orig_url)
cmd = ['git', 'config', 'remote.%s.url' % alias, "bzr::%s" % abs_url]
subprocess.call(cmd)
def main(args):
global marks, prefix, gitdir, dirname
global tags, filenodes
global blob_marks
global parsed_refs
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]
tags = {}
filenodes = {}
blob_marks = {}
parsed_refs = {}
files_cache = {}
branches = {}
peers = {}
transports = []
force = False
if alias[5:] == url:
is_tmp = True
alias = hashlib.sha1(alias).hexdigest()
prefix = 'refs/bzr/%s' % alias
dirname = os.path.join(gitdir, 'bzr', alias)
if not is_tmp:
fix_path(alias, url)
if not os.path.exists(dirname):
os.makedirs(dirname)
if hasattr(bzrlib.ui.ui_factory, 'be_quiet'):
bzrlib.ui.ui_factory.be_quiet(True)
repo = get_repo(url, alias)
marks_path = os.path.join(dirname, 'marks-int')
marks = Marks(marks_path)
parser = Parser(repo)
for line in parser:
if parser.check('capabilities'):
do_capabilities(parser)
elif parser.check('list'):
do_list(parser)
elif parser.check('import'):
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()
def bye():
if not marks:
return
if not is_tmp:
marks.store()
else:
shutil.rmtree(dirname)
atexit.register(bye)
sys.exit(main(sys.argv))
sys.stderr.write('WARNING: git-remote-bzr is now maintained independently.\n')
sys.stderr.write('WARNING: For more information visit https://github.com/felipec/git-remote-bzr\n')
sys.stderr.write('''WARNING:
WARNING: You can pick a directory on your $PATH and download it, e.g.:
WARNING: $ wget -O $HOME/bin/git-remote-bzr \\
WARNING: https://raw.github.com/felipec/git-remote-bzr/master/git-remote-bzr
WARNING: $ chmod +x $HOME/bin/git-remote-bzr
''')

File diff suppressed because it is too large Load Diff

View File

@ -1,438 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2012 Felipe Contreras
#
test_description='Test remote-bzr'
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
. "$TEST_DIRECTORY"/test-lib.sh
if ! test_have_prereq PYTHON
then
skip_all='skipping remote-bzr tests; python not available'
test_done
fi
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
test_cmp expected actual
}
bzr whoami "A U Thor <author@example.com>"
test_expect_success 'cloning' '
(
bzr init bzrrepo &&
cd bzrrepo &&
echo one >content &&
bzr add content &&
bzr commit -m one
) &&
git clone "bzr::bzrrepo" gitrepo &&
check gitrepo HEAD one
'
test_expect_success 'pulling' '
(
cd bzrrepo &&
echo two >content &&
bzr commit -m two
) &&
(cd gitrepo && git pull) &&
check gitrepo HEAD two
'
test_expect_success 'pushing' '
(
cd gitrepo &&
echo three >content &&
git commit -a -m three &&
git push
) &&
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
'
test_expect_success 'roundtrip' '
(
cd gitrepo &&
git pull &&
git log --format="%s" -1 origin/master >actual
) &&
echo three-new >expected &&
test_cmp expected actual &&
(cd gitrepo && git push && git pull) &&
(
cd bzrrepo &&
echo four >content &&
bzr commit -m four
) &&
(cd gitrepo && git pull && git push) &&
check gitrepo HEAD four &&
(
cd gitrepo &&
echo five >content &&
git commit -a -m five &&
git push && git pull
) &&
(cd bzrrepo && bzr revert) &&
echo five >expected &&
cat bzrrepo/content >actual &&
test_cmp expected actual
'
cat >expected <<\EOF
100644 blob 54f9d6da5c91d556e6b54340b1327573073030af content
100755 blob 68769579c3eaadbe555379b9c3538e6628bae1eb executable
120000 blob 6b584e8ece562ebffc15d38808cd6b98fc3d97ea link
EOF
test_expect_success 'special modes' '
(
cd bzrrepo &&
echo exec >executable
chmod +x executable &&
bzr add executable
bzr commit -m exec &&
ln -s content link
bzr add link
bzr commit -m link &&
mkdir dir &&
bzr add dir &&
bzr commit -m dir
) &&
(
cd gitrepo &&
git pull
git ls-tree HEAD >../actual
) &&
test_cmp expected actual &&
(
cd gitrepo &&
git cat-file -p HEAD:link >../actual
) &&
printf content >expected &&
test_cmp expected actual
'
cat >expected <<\EOF
100644 blob 54f9d6da5c91d556e6b54340b1327573073030af content
100755 blob 68769579c3eaadbe555379b9c3538e6628bae1eb executable
120000 blob 6b584e8ece562ebffc15d38808cd6b98fc3d97ea link
040000 tree 35c0caa46693cef62247ac89a680f0c5ce32b37b movedir-new
EOF
test_expect_success 'moving directory' '
(
cd bzrrepo &&
mkdir movedir &&
echo one >movedir/one &&
echo two >movedir/two &&
bzr add movedir &&
bzr commit -m movedir &&
bzr mv movedir movedir-new &&
bzr commit -m movedir-new
) &&
(
cd gitrepo &&
git pull &&
git ls-tree HEAD >../actual
) &&
test_cmp expected actual
'
test_expect_success 'different authors' '
(
cd bzrrepo &&
echo john >>content &&
bzr commit -m john \
--author "Jane Rey <jrey@example.com>" \
--author "John Doe <jdoe@example.com>"
) &&
(
cd gitrepo &&
git pull &&
git show --format="%an <%ae>, %cn <%ce>" --quiet >../actual
) &&
echo "Jane Rey <jrey@example.com>, A U Thor <author@example.com>" >expected &&
test_cmp expected actual
'
# cleanup previous stuff
rm -rf bzrrepo gitrepo
test_expect_success 'fetch utf-8 filenames' '
test_when_finished "rm -rf bzrrepo gitrepo && LC_ALL=C" &&
LC_ALL=en_US.UTF-8
export LC_ALL
(
bzr init bzrrepo &&
cd bzrrepo &&
echo test >>"ærø" &&
bzr add "ærø" &&
echo test >>"ø~?" &&
bzr add "ø~?" &&
bzr commit -m add-utf-8 &&
echo test >>"ærø" &&
bzr commit -m test-utf-8 &&
bzr rm "ø~?" &&
bzr mv "ærø" "ø~?" &&
bzr commit -m bzr-mv-utf-8
) &&
(
git clone "bzr::bzrrepo" gitrepo &&
cd gitrepo &&
git -c core.quotepath=false ls-files >../actual
) &&
echo "ø~?" >expected &&
test_cmp expected actual
'
test_expect_success 'push utf-8 filenames' '
test_when_finished "rm -rf bzrrepo gitrepo && LC_ALL=C" &&
mkdir -p tmp && cd tmp &&
LC_ALL=en_US.UTF-8
export LC_ALL
(
bzr init bzrrepo &&
cd bzrrepo &&
echo one >>content &&
bzr add content &&
bzr commit -m one
) &&
(
git clone "bzr::bzrrepo" gitrepo &&
cd gitrepo &&
echo test >>"ærø" &&
git add "ærø" &&
git commit -m utf-8 &&
git push
) &&
(cd bzrrepo && bzr ls >../actual) &&
printf "content\nærø\n" >expected &&
test_cmp expected actual
'
test_expect_success 'pushing a merge' '
test_when_finished "rm -rf bzrrepo gitrepo" &&
(
bzr init bzrrepo &&
cd bzrrepo &&
echo one >content &&
bzr add content &&
bzr commit -m one
) &&
git clone "bzr::bzrrepo" gitrepo &&
(
cd bzrrepo &&
echo two >content &&
bzr commit -m two
) &&
(
cd gitrepo &&
echo three >content &&
git commit -a -m three &&
git fetch &&
git merge origin/master || true &&
echo three >content &&
git commit -a --no-edit &&
git push
) &&
echo three >expected &&
cat bzrrepo/content >actual &&
test_cmp expected actual
'
cat >expected <<\EOF
origin/HEAD
origin/branch
origin/trunk
EOF
test_expect_success 'proper bzr repo' '
test_when_finished "rm -rf bzrrepo gitrepo" &&
bzr init-repo bzrrepo &&
(
bzr init bzrrepo/trunk &&
cd bzrrepo/trunk &&
echo one >>content &&
bzr add content &&
bzr commit -m one
) &&
(
bzr branch bzrrepo/trunk bzrrepo/branch &&
cd bzrrepo/branch &&
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
) &&
test_cmp expected actual
'
test_expect_success 'strip' '
test_when_finished "rm -rf bzrrepo gitrepo" &&
(
bzr init bzrrepo &&
cd bzrrepo &&
echo one >>content &&
bzr add content &&
bzr commit -m one &&
echo two >>content &&
bzr commit -m two
) &&
git clone "bzr::bzrrepo" gitrepo &&
(
cd bzrrepo &&
bzr uncommit --force &&
echo three >>content &&
bzr commit -m three &&
echo four >>content &&
bzr commit -m four &&
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
) &&
test_cmp expected actual
'
test_expect_success 'export utf-8 authors' '
test_when_finished "rm -rf bzrrepo gitrepo && LC_ALL=C && GIT_COMMITTER_NAME=\"C O Mitter\""
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
'
test_expect_success 'push different author' '
test_when_finished "rm -rf bzrrepo gitrepo" &&
bzr init bzrrepo &&
(
git init gitrepo &&
cd gitrepo &&
echo john >> content &&
git add content &&
git commit -m john --author "John Doe <jdoe@example.com>" &&
git remote add bzr "bzr::../bzrrepo" &&
git push bzr master
) &&
(
cd bzrrepo &&
bzr log | grep "^author: " > ../actual
) &&
echo "author: John Doe <jdoe@example.com>" > expected &&
test_cmp expected actual
'
test_done

View File

@ -1,243 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2012 Felipe Contreras
#
# Base commands from hg-git tests:
# https://bitbucket.org/durin42/hg-git/src
#
test_description='Test bidirectionality of remote-hg'
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
. "$TEST_DIRECTORY"/test-lib.sh
if ! test_have_prereq PYTHON
then
skip_all='skipping remote-hg tests; python not available'
test_done
fi
if ! python -c 'import mercurial'
then
skip_all='skipping remote-hg tests; mercurial not available'
test_done
fi
# clone to a git repo
git_clone () {
git clone -q "hg::$1" $2
}
# clone to an hg repo
hg_clone () {
(
hg init $2 &&
cd $1 &&
git push -q "hg::../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'
) &&
(cd $2 && hg -q update)
}
# push an hg repo
hg_push () {
(
cd $2
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
)
}
hg_log () {
hg -R $1 log --graph --debug
}
setup () {
(
echo "[ui]"
echo "username = A U Thor <author@example.com>"
echo "[defaults]"
echo "backout = -d \"0 0\""
echo "commit = -d \"0 0\""
echo "debugrawcommit = -d \"0 0\""
echo "tag = -d \"0 0\""
echo "[extensions]"
echo "graphlog ="
) >>"$HOME"/.hgrc &&
git config --global remote-hg.hg-git-compat true
git config --global remote-hg.track-branches true
HGEDITOR=/usr/bin/true
GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230"
GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
export HGEDITOR GIT_AUTHOR_DATE GIT_COMMITTER_DATE
}
setup
test_expect_success 'encoding' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
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 &&
git add beta &&
git commit -m "add beta" &&
echo gamma >gamma &&
git add gamma &&
git commit -m "add gämmâ" &&
: TODO git config i18n.commitencoding latin-1 &&
echo delta >delta &&
git add delta &&
git commit -m "add déltà"
) &&
hg_clone gitrepo hgrepo &&
git_clone hgrepo gitrepo2 &&
hg_clone gitrepo2 hgrepo2 &&
HGENCODING=utf-8 hg_log hgrepo >expected &&
HGENCODING=utf-8 hg_log hgrepo2 >actual &&
test_cmp expected actual
'
test_expect_success 'file removal' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
echo beta >beta &&
git add beta &&
git commit -m "add beta"
mkdir foo &&
echo blah >foo/bar &&
git add foo &&
git commit -m "add foo" &&
git rm alpha &&
git commit -m "remove alpha" &&
git rm foo/bar &&
git commit -m "remove foo/bar"
) &&
hg_clone gitrepo hgrepo &&
git_clone hgrepo gitrepo2 &&
hg_clone gitrepo2 hgrepo2 &&
hg_log hgrepo >expected &&
hg_log hgrepo2 >actual &&
test_cmp expected actual
'
test_expect_success 'git tags' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
git config receive.denyCurrentBranch ignore &&
echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
git tag alpha &&
echo beta >beta &&
git add beta &&
git commit -m "add beta" &&
git tag -a -m "added tag beta" beta
) &&
hg_clone gitrepo hgrepo &&
git_clone hgrepo gitrepo2 &&
hg_clone gitrepo2 hgrepo2 &&
hg_log hgrepo >expected &&
hg_log hgrepo2 >actual &&
test_cmp expected actual
'
test_expect_success 'hg branch' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
git add alpha &&
git commit -q -m "add alpha" &&
git checkout -q -b not-master
) &&
(
hg_clone gitrepo hgrepo &&
cd hgrepo &&
hg -q co default &&
hg mv alpha beta &&
hg -q commit -m "rename alpha to beta" &&
hg branch gamma | grep -v "permanent and global" &&
hg -q commit -m "started branch gamma"
) &&
hg_push hgrepo gitrepo &&
hg_clone gitrepo hgrepo2 &&
: Back to the common revision &&
(cd hgrepo && hg checkout default) &&
hg_log hgrepo >expected &&
hg_log hgrepo2 >actual &&
test_cmp expected actual
'
test_expect_success 'hg tags' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
) &&
(
hg_clone gitrepo hgrepo &&
cd hgrepo &&
hg co default &&
hg tag alpha
) &&
hg_push hgrepo gitrepo &&
hg_clone gitrepo hgrepo2 &&
hg_log hgrepo >expected &&
hg_log hgrepo2 >actual &&
test_cmp expected actual
'
test_done

View File

@ -1,542 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2012 Felipe Contreras
#
# Base commands from hg-git tests:
# https://bitbucket.org/durin42/hg-git/src
#
test_description='Test remote-hg output compared to hg-git'
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
. "$TEST_DIRECTORY"/test-lib.sh
if ! test_have_prereq PYTHON
then
skip_all='skipping remote-hg tests; python not available'
test_done
fi
if ! python -c 'import mercurial'
then
skip_all='skipping remote-hg tests; mercurial not available'
test_done
fi
if ! python -c 'import hggit'
then
skip_all='skipping remote-hg tests; hg-git not available'
test_done
fi
# clone to a git repo with git
git_clone_git () {
git clone -q "hg::$1" $2 &&
(cd $2 && git checkout master && git branch -D default)
}
# clone to an hg repo with git
hg_clone_git () {
(
hg init $2 &&
hg -R $2 bookmark -i master &&
cd $1 &&
git push -q "hg::../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'
) &&
(cd $2 && hg -q update)
}
# clone to a git repo with hg
git_clone_hg () {
(
git init -q $2 &&
cd $1 &&
hg bookmark -i -f -r tip master &&
hg -q push -r master ../$2 || true
)
}
# clone to an hg repo with hg
hg_clone_hg () {
hg -q clone $1 $2
}
# push an hg repo with git
hg_push_git () {
(
cd $2
git checkout -q -b tmp &&
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
)
}
# push an hg git repo with hg
hg_push_hg () {
(
cd $1 &&
hg -q push ../$2 || true
)
}
hg_log () {
hg -R $1 log --graph --debug >log &&
grep -v 'tag: *default/' log
}
git_log () {
git --git-dir=$1/.git fast-export --branches
}
setup () {
(
echo "[ui]"
echo "username = A U Thor <author@example.com>"
echo "[defaults]"
echo "backout = -d \"0 0\""
echo "commit = -d \"0 0\""
echo "debugrawcommit = -d \"0 0\""
echo "tag = -d \"0 0\""
echo "[extensions]"
echo "hgext.bookmarks ="
echo "hggit ="
echo "graphlog ="
) >>"$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
HGEDITOR=true
HGMERGE=true
GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230"
GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
export HGEDITOR HGMERGE GIT_AUTHOR_DATE GIT_COMMITTER_DATE
}
setup
test_expect_success 'executable bit' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
chmod 0644 alpha &&
git add alpha &&
git commit -m "add alpha" &&
chmod 0755 alpha &&
git add alpha &&
git commit -m "set executable bit" &&
chmod 0644 alpha &&
git add alpha &&
git commit -m "clear executable bit"
) &&
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" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
git_log gitrepo2-$x >"log-$x"
done &&
test_cmp output-hg output-git &&
test_cmp log-hg log-git
'
test_expect_success 'symlink' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
ln -s alpha beta &&
git add beta &&
git commit -m "add beta"
) &&
for x in hg git
do
(
hg_clone_$x gitrepo hgrepo-$x &&
cd hgrepo-$x &&
hg_log . &&
hg manifest -v
) >"output-$x" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
git_log gitrepo2-$x >"log-$x"
done &&
test_cmp output-hg output-git &&
test_cmp log-hg log-git
'
test_expect_success 'merge conflict 1' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
hg init hgrepo1 &&
cd hgrepo1 &&
echo A >afile &&
hg add afile &&
hg ci -m "origin" &&
echo B >afile &&
hg ci -m "A->B" &&
hg up -r0 &&
echo C >afile &&
hg ci -m "A->C" &&
hg merge -r1 &&
echo C >afile &&
hg resolve -m afile &&
hg ci -m "merge to C"
) &&
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"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
'
test_expect_success 'merge conflict 2' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
hg init hgrepo1 &&
cd hgrepo1 &&
echo A >afile &&
hg add afile &&
hg ci -m "origin" &&
echo B >afile &&
hg ci -m "A->B" &&
hg up -r0 &&
echo C >afile &&
hg ci -m "A->C" &&
hg merge -r1 || true &&
echo B >afile &&
hg resolve -m afile &&
hg ci -m "merge to B"
) &&
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"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
'
test_expect_success 'converged merge' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
hg init hgrepo1 &&
cd hgrepo1 &&
echo A >afile &&
hg add afile &&
hg ci -m "origin" &&
echo B >afile &&
hg ci -m "A->B" &&
echo C >afile &&
hg ci -m "B->C" &&
hg up -r0 &&
echo C >afile &&
hg ci -m "A->C" &&
hg merge -r2 || true &&
hg ci -m "merge"
) &&
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"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
'
test_expect_success 'encoding' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
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 &&
git add beta &&
git commit -m "add beta" &&
echo gamma >gamma &&
git add gamma &&
git commit -m "add gämmâ" &&
: TODO git config i18n.commitencoding latin-1 &&
echo delta >delta &&
git add delta &&
git commit -m "add déltà"
) &&
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"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
'
test_expect_success 'file removal' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
echo beta >beta &&
git add beta &&
git commit -m "add beta"
mkdir foo &&
echo blah >foo/bar &&
git add foo &&
git commit -m "add foo" &&
git rm alpha &&
git commit -m "remove alpha" &&
git rm foo/bar &&
git commit -m "remove foo/bar"
) &&
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" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
git_log gitrepo2-$x >"log-$x"
done &&
test_cmp output-hg output-git &&
test_cmp log-hg log-git
'
test_expect_success 'git tags' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
git config receive.denyCurrentBranch ignore &&
echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
git tag alpha &&
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
hg_clone_$x gitrepo hgrepo-$x &&
hg_log hgrepo-$x >"log-$x"
done &&
test_cmp log-hg log-git
'
test_expect_success 'hg author' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
for x in hg git
do
(
git init -q gitrepo-$x &&
cd gitrepo-$x &&
echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
) &&
(
hg_clone_$x gitrepo-$x hgrepo-$x &&
cd hgrepo-$x &&
hg co master &&
echo beta >beta &&
hg add beta &&
hg commit -u "test" -m "add beta" &&
echo gamma >>beta &&
hg commit -u "test <test@example.com> (comment)" -m "modify beta" &&
echo gamma >gamma &&
hg add gamma &&
hg commit -u "<test@example.com>" -m "add gamma" &&
echo delta >delta &&
hg add delta &&
hg commit -u "name<test@example.com>" -m "add delta" &&
echo epsilon >epsilon &&
hg add epsilon &&
hg commit -u "name <test@example.com" -m "add epsilon" &&
echo zeta >zeta &&
hg add zeta &&
hg commit -u " test " -m "add zeta" &&
echo eta >eta &&
hg add eta &&
hg commit -u "test < test@example.com >" -m "add eta" &&
echo theta >theta &&
hg add theta &&
hg commit -u "test >test@example.com>" -m "add theta" &&
echo iota >iota &&
hg add iota &&
hg commit -u "test <test <at> example <dot> com>" -m "add iota"
) &&
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"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
'
test_expect_success 'hg branch' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
for x in hg git
do
(
git init -q gitrepo-$x &&
cd gitrepo-$x &&
echo alpha >alpha &&
git add alpha &&
git commit -q -m "add alpha" &&
git checkout -q -b not-master
) &&
(
hg_clone_$x gitrepo-$x hgrepo-$x &&
cd hgrepo-$x &&
hg -q co master &&
hg mv alpha beta &&
hg -q commit -m "rename alpha to beta" &&
hg branch gamma | grep -v "permanent and global" &&
hg -q commit -m "started branch gamma"
) &&
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"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
'
test_expect_success 'hg tags' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
for x in hg git
do
(
git init -q gitrepo-$x &&
cd gitrepo-$x &&
echo alpha >alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
) &&
(
hg_clone_$x gitrepo-$x hgrepo-$x &&
cd hgrepo-$x &&
hg co master &&
hg tag alpha
) &&
hg_push_$x hgrepo-$x gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
(
git --git-dir=gitrepo-$x/.git tag -l &&
hg_log hgrepo2-$x &&
cat hgrepo2-$x/.hgtags
) >"output-$x"
done &&
test_cmp output-hg output-git
'
test_done

View File

@ -1,848 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2012 Felipe Contreras
#
# Base commands from hg-git tests:
# https://bitbucket.org/durin42/hg-git/src
#
test_description='Test remote-hg'
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
. "$TEST_DIRECTORY"/test-lib.sh
if ! test_have_prereq PYTHON
then
skip_all='skipping remote-hg tests; python not available'
test_done
fi
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
test_cmp expected actual
}
check_branch () {
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 &&
! grep $2 out
fi
}
check_bookmark () {
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 &&
! grep $2 out
fi
}
check_push () {
expected_ret=$1 ret=0 ref_ret=0
shift
git push origin "$@" 2>error
ret=$?
cat error
while IFS=':' read branch kind
do
case "$kind" in
'new')
grep "^ \* \[new branch\] *${branch} -> ${branch}$" error || ref_ret=1
;;
'non-fast-forward')
grep "^ ! \[rejected\] *${branch} -> ${branch} (non-fast-forward)$" error || ref_ret=1
;;
'fetch-first')
grep "^ ! \[rejected\] *${branch} -> ${branch} (fetch first)$" error || ref_ret=1
;;
'forced-update')
grep "^ + [a-f0-9]*\.\.\.[a-f0-9]* *${branch} -> ${branch} (forced update)$" error || ref_ret=1
;;
'')
grep "^ [a-f0-9]*\.\.[a-f0-9]* *${branch} -> ${branch}$" error || ref_ret=1
;;
esac
test $ref_ret -ne 0 && echo "match for '$branch' failed" && break
done
if test $expected_ret -ne $ret || test $ref_ret -ne 0
then
return 1
fi
return 0
}
setup () {
(
echo "[ui]"
echo "username = H G Wells <wells@example.com>"
echo "[extensions]"
echo "mq ="
) >>"$HOME"/.hgrc &&
GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230" &&
GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" &&
export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
}
setup
test_expect_success 'cloning' '
test_when_finished "rm -rf gitrepo*" &&
(
hg init hgrepo &&
cd hgrepo &&
echo zero >content &&
hg add content &&
hg commit -m zero
) &&
git clone "hg::hgrepo" gitrepo &&
check gitrepo HEAD zero
'
test_expect_success 'cloning with branches' '
test_when_finished "rm -rf gitrepo*" &&
(
cd hgrepo &&
hg branch next &&
echo next >content &&
hg commit -m next
) &&
git clone "hg::hgrepo" gitrepo &&
check gitrepo origin/branches/next next
'
test_expect_success 'cloning with bookmarks' '
test_when_finished "rm -rf gitrepo*" &&
(
cd hgrepo &&
hg checkout default &&
hg bookmark feature-a &&
echo feature-a >content &&
hg commit -m feature-a
) &&
git clone "hg::hgrepo" gitrepo &&
check gitrepo origin/feature-a feature-a
'
test_expect_success 'update bookmark' '
test_when_finished "rm -rf gitrepo*" &&
(
cd hgrepo &&
hg bookmark devel
) &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet devel &&
echo devel >content &&
git commit -a -m devel &&
git push --quiet
) &&
check_bookmark hgrepo devel devel
'
test_expect_success 'new bookmark' '
test_when_finished "rm -rf gitrepo*" &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet -b feature-b &&
echo feature-b >content &&
git commit -a -m feature-b &&
git push --quiet origin feature-b
) &&
check_bookmark hgrepo feature-b feature-b
'
# cleanup previous stuff
rm -rf hgrepo
author_test () {
echo $1 >>content &&
hg commit -u "$2" -m "add $1" &&
echo "$3" >>../expected
}
test_expect_success 'authors' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
cd hgrepo &&
touch content &&
hg add content &&
>../expected &&
author_test alpha "" "H G Wells <wells@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 &&
test_cmp expected actual
'
test_expect_success 'strip' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
cd hgrepo &&
echo one >>content &&
hg add content &&
hg commit -m one &&
echo two >>content &&
hg commit -m two
) &&
git clone "hg::hgrepo" gitrepo &&
(
cd hgrepo &&
hg strip 1 &&
echo three >>content &&
hg commit -m three &&
echo four >>content &&
hg commit -m four
) &&
(
cd gitrepo &&
git fetch &&
git log --format="%s" origin/master >../actual
) &&
hg -R hgrepo log --template "{desc}\n" >expected &&
test_cmp actual expected
'
test_expect_success 'remote push with master bookmark' '
test_when_finished "rm -rf hgrepo gitrepo*" &&
(
hg init hgrepo &&
cd hgrepo &&
echo zero >content &&
hg add content &&
hg commit -m zero &&
hg bookmark master &&
echo one >content &&
hg commit -m one
) &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
echo two >content &&
git commit -a -m two &&
git push
) &&
check_branch hgrepo default two
'
cat >expected <<\EOF
changeset: 0:6e2126489d3d
tag: tip
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
summary: one
EOF
test_expect_success 'remote push from master branch' '
test_when_finished "rm -rf hgrepo gitrepo*" &&
hg init hgrepo &&
(
git init gitrepo &&
cd gitrepo &&
git remote add origin "hg::../hgrepo" &&
echo one >content &&
git add content &&
git commit -a -m one &&
git push origin master
) &&
hg -R hgrepo log >actual &&
cat actual &&
test_cmp expected actual &&
check_branch hgrepo default one
'
GIT_REMOTE_HG_TEST_REMOTE=1
export GIT_REMOTE_HG_TEST_REMOTE
test_expect_success 'remote cloning' '
test_when_finished "rm -rf gitrepo*" &&
(
hg init hgrepo &&
cd hgrepo &&
echo zero >content &&
hg add content &&
hg commit -m zero
) &&
git clone "hg::hgrepo" gitrepo &&
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*" &&
(
cd hgrepo &&
hg bookmark devel
) &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet devel &&
echo devel >content &&
git commit -a -m devel &&
git push --quiet
) &&
check_bookmark hgrepo devel devel
'
test_expect_success 'remote new bookmark' '
test_when_finished "rm -rf gitrepo*" &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet -b feature-b &&
echo feature-b >content &&
git commit -a -m feature-b &&
git push --quiet origin feature-b
) &&
check_bookmark hgrepo feature-b feature-b
'
test_expect_success 'remote push diverged' '
test_when_finished "rm -rf gitrepo*" &&
git clone "hg::hgrepo" gitrepo &&
(
cd hgrepo &&
hg checkout default &&
echo bump >content &&
hg commit -m bump
) &&
(
cd gitrepo &&
echo diverge >content &&
git commit -a -m diverged &&
check_push 1 <<-\EOF
master:non-fast-forward
EOF
) &&
check_branch hgrepo default bump
'
test_expect_success 'remote update bookmark diverge' '
test_when_finished "rm -rf gitrepo*" &&
(
cd hgrepo &&
hg checkout tip^ &&
hg bookmark diverge
) &&
git clone "hg::hgrepo" gitrepo &&
(
cd hgrepo &&
echo "bump bookmark" >content &&
hg commit -m "bump bookmark"
) &&
(
cd gitrepo &&
git checkout --quiet diverge &&
echo diverge >content &&
git commit -a -m diverge &&
check_push 1 <<-\EOF
diverge:fetch-first
EOF
) &&
check_bookmark hgrepo diverge "bump bookmark"
'
test_expect_success 'remote new bookmark multiple branch head' '
test_when_finished "rm -rf gitrepo*" &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet -b feature-c HEAD^ &&
echo feature-c >content &&
git commit -a -m feature-c &&
git push --quiet origin feature-c
) &&
check_bookmark hgrepo feature-c feature-c
'
# 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 &&
hg add content &&
hg commit -m zero &&
hg bookmark bad_bmark1 &&
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 &&
hg commit -m "good branch" &&
hg -q branch bad_branch &&
echo "bad branch" >content &&
hg commit -m "bad branch"
) &&
git clone "hg::hgrepo" gitrepo &&
(
cd gitrepo &&
echo two >content &&
git commit -q -a -m two &&
git checkout -q good_bmark &&
echo three >content &&
git commit -q -a -m three &&
git checkout -q bad_bmark1 &&
git reset --hard HEAD^ &&
echo four >content &&
git commit -q -a -m four &&
git checkout -q bad_bmark2 &&
git reset --hard HEAD^ &&
echo five >content &&
git commit -q -a -m five &&
git checkout -q -b new_bmark master &&
echo six >content &&
git commit -q -a -m six &&
git checkout -q branches/good_branch &&
echo seven >content &&
git commit -q -a -m seven &&
echo eight >content &&
git commit -q -a -m eight &&
git checkout -q branches/bad_branch &&
git reset --hard HEAD^ &&
echo nine >content &&
git commit -q -a -m nine &&
git checkout -q -b branches/new_branch master &&
echo ten >content &&
git commit -q -a -m ten
)
}
test_expect_success 'remote big push' '
test_when_finished "rm -rf hgrepo gitrepo*" &&
setup_big_push
(
cd gitrepo &&
check_push 1 --all <<-\EOF
master
good_bmark
branches/good_branch
new_bmark:new
branches/new_branch:new
bad_bmark1:non-fast-forward
bad_bmark2:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
) &&
check_branch hgrepo default one &&
check_branch hgrepo good_branch "good branch" &&
check_branch hgrepo bad_branch "bad branch" &&
check_branch hgrepo new_branch '' &&
check_bookmark hgrepo good_bmark one &&
check_bookmark hgrepo bad_bmark1 one &&
check_bookmark hgrepo bad_bmark2 one &&
check_bookmark hgrepo new_bmark ''
'
test_expect_success 'remote big push fetch first' '
test_when_finished "rm -rf hgrepo gitrepo*" &&
(
hg init hgrepo &&
cd hgrepo &&
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 &&
hg commit -m "good branch" &&
hg -q branch bad_branch &&
echo "bad branch" >content &&
hg commit -m "bad branch"
) &&
git clone "hg::hgrepo" gitrepo &&
(
cd hgrepo &&
hg bookmark -f bad_bmark &&
echo update_bmark >content &&
hg commit -m "update bmark"
) &&
(
cd gitrepo &&
echo two >content &&
git commit -q -a -m two &&
git checkout -q good_bmark &&
echo three >content &&
git commit -q -a -m three &&
git checkout -q bad_bmark &&
echo four >content &&
git commit -q -a -m four &&
git checkout -q branches/bad_branch &&
echo five >content &&
git commit -q -a -m five &&
check_push 1 --all <<-\EOF &&
master
good_bmark
bad_bmark:fetch-first
branches/bad_branch:festch-first
EOF
git fetch &&
check_push 1 --all <<-\EOF
master
good_bmark
bad_bmark:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
)
'
test_expect_success 'remote big push force' '
test_when_finished "rm -rf hgrepo gitrepo*" &&
setup_big_push
(
cd gitrepo &&
check_push 0 --force --all <<-\EOF
master
good_bmark
branches/good_branch
new_bmark:new
branches/new_branch:new
bad_bmark1:forced-update
bad_bmark2:forced-update
branches/bad_branch:forced-update
EOF
) &&
check_branch hgrepo default six &&
check_branch hgrepo good_branch eight &&
check_branch hgrepo bad_branch nine &&
check_branch hgrepo new_branch ten &&
check_bookmark hgrepo good_bmark three &&
check_bookmark hgrepo bad_bmark1 four &&
check_bookmark hgrepo bad_bmark2 five &&
check_bookmark hgrepo new_bmark six
'
test_expect_success 'remote big push dry-run' '
test_when_finished "rm -rf hgrepo gitrepo*" &&
setup_big_push
(
cd gitrepo &&
check_push 1 --dry-run --all <<-\EOF &&
master
good_bmark
branches/good_branch
new_bmark:new
branches/new_branch:new
bad_bmark1:non-fast-forward
bad_bmark2:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
check_push 0 --dry-run master good_bmark new_bmark branches/good_branch branches/new_branch <<-\EOF
master
good_bmark
branches/good_branch
new_bmark:new
branches/new_branch:new
EOF
) &&
check_branch hgrepo default one &&
check_branch hgrepo good_branch "good branch" &&
check_branch hgrepo bad_branch "bad branch" &&
check_branch hgrepo new_branch '' &&
check_bookmark hgrepo good_bmark one &&
check_bookmark hgrepo bad_bmark1 one &&
check_bookmark hgrepo bad_bmark2 one &&
check_bookmark hgrepo new_bmark ''
'
test_expect_success 'remote double failed push' '
test_when_finished "rm -rf hgrepo gitrepo*" &&
(
hg init hgrepo &&
cd hgrepo &&
echo zero >content &&
hg add content &&
hg commit -m zero &&
echo one >content &&
hg commit -m one
) &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git reset --hard HEAD^ &&
echo two >content &&
git commit -a -m two &&
test_expect_code 1 git push &&
test_expect_code 1 git push
)
'
test_expect_success 'clone remote with master null bookmark, then push to the bookmark' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
hg init hgrepo &&
(
cd hgrepo &&
echo a >a &&
hg add a &&
hg commit -m a &&
hg bookmark -r null master
) &&
git clone "hg::hgrepo" gitrepo &&
check gitrepo HEAD a &&
(
cd gitrepo &&
git checkout --quiet -b master &&
echo b >b &&
git add b &&
git commit -m b &&
git push origin master
)
'
test_expect_success 'clone remote with default null bookmark, then push to the bookmark' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
hg init hgrepo &&
(
cd hgrepo &&
echo a >a &&
hg add a &&
hg commit -m a &&
hg bookmark -r null -f default
) &&
git clone "hg::hgrepo" gitrepo &&
check gitrepo HEAD a &&
(
cd gitrepo &&
git checkout --quiet -b default &&
echo b >b &&
git add b &&
git commit -m b &&
git push origin default
)
'
test_expect_success 'clone remote with generic null bookmark, then push to the bookmark' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
hg init hgrepo &&
(
cd hgrepo &&
echo a >a &&
hg add a &&
hg commit -m a &&
hg bookmark -r null bmark
) &&
git clone "hg::hgrepo" gitrepo &&
check gitrepo HEAD a &&
(
cd gitrepo &&
git checkout --quiet -b bmark &&
git remote -v &&
echo b >b &&
git add b &&
git commit -m b &&
git push origin bmark
)
'
test_done

View File

@ -1283,7 +1283,7 @@ load_config 0
apply_config
# v1.7.0 introduced --show-toplevel to return the canonical work-tree
if {[package vsatisfies $_git_version 1.7.0]} {
if {[package vsatisfies $_git_version 1.7.0-]} {
if { [is_Cygwin] } {
catch {set _gitworktree [exec cygpath --windows [git rev-parse --show-toplevel]]}
} else {
@ -1539,7 +1539,7 @@ proc rescan_stage2 {fd after} {
close $fd
}
if {[package vsatisfies $::_git_version 1.6.3]} {
if {[package vsatisfies $::_git_version 1.6.3-]} {
set ls_others [list --exclude-standard]
} else {
set ls_others [list --exclude-per-directory=.gitignore]

View File

@ -119,6 +119,12 @@ then
status=1
fi
# Special case: turn "for_linus" to "tags/for_linus" when it is correct
if test "$ref" = "refs/tags/$pretty_remote"
then
pretty_remote=tags/$pretty_remote
fi
url=$(git ls-remote --get-url "$url")
git show -s --format='The following changes since commit %H:

5307
po/bg.po

File diff suppressed because it is too large Load Diff

View File

@ -296,11 +296,11 @@ msgid ""
msgstr ""
"\n"
"Si vous comptez baser votre travail sur une branche\n"
"amont qui existe déjà sur le serveur distant, vous pourriez\n"
"devoir lancer \"git fetch\" pour la récupérer.\n"
"amont qui existe déjà sur le serveur distant, vous pouvez\n"
"lancer \"git fetch\" pour la récupérer.\n"
"\n"
"Si vous comptez pousser une nouvelle branche locale qui suivra\n"
"sa jumelle distante, vous souhaiterez utiliser \"git push -u\"\n"
"sa jumelle distante, vous pouvez utiliser \"git push -u\"\n"
"pour paramétrer le suivi distant en même temps que vous poussez."
#: branch.c:260
@ -343,7 +343,7 @@ msgstr "impossible d'ouvrir '%s'"
#: bundle.c:138
msgid "Repository lacks these prerequisite commits:"
msgstr "Le dépôt ne dispose pas des commits prérequis :"
msgstr "Le dépôt ne dispose pas des commits prérequis suivants :"
#: bundle.c:162 sequencer.c:669 sequencer.c:1123 builtin/log.c:332
#: builtin/log.c:821 builtin/log.c:1418 builtin/log.c:1644 builtin/merge.c:357
@ -620,7 +620,7 @@ msgid ""
msgstr ""
"ATTENTION : vous avez invoqué une commande Git nommée '%s' qui n'existe "
"pas.\n"
"Poursuite en supposant que vous avez voulu dire '%s'"
"Continuons en supposant que vous avez voulu dire '%s'"
#: help.c:373
#, c-format
@ -3480,12 +3480,12 @@ msgid_plural ""
"\n"
"%s\n"
msgstr[0] ""
"Attention : vous laissez %d commit en retard, non connectés à\n"
"Attention : vous abandonnez %d commit, non connecté à\n"
"une branche :\n"
"\n"
"%s\n"
msgstr[1] ""
"Attention : vous laissez %d commits en retard, non connectés à\n"
"Attention : vous abandonnez %d commits, non connectés à\n"
"une branche :\n"
"\n"
"%s\n"
@ -3501,7 +3501,7 @@ msgid ""
msgstr ""
"Si vous souhaitez les garder en créant une nouvelle branche, c'est le bon "
"moment\n"
"de le faire avec :\n"
"pour le faire avec :\n"
"\n"
"git branch nouvelle_branche %s\n"
"\n"
@ -3576,7 +3576,7 @@ msgstr "détacher la HEAD à la validation nommée"
#: builtin/checkout.c:1096
msgid "set upstream info for new branch"
msgstr "paramétrer l'information de branche amont pour une nouvelle branche"
msgstr "paramétrer les coordonnées de branche amont pour une nouvelle branche"
#: builtin/checkout.c:1098
msgid "new-branch"
@ -3846,7 +3846,7 @@ msgstr "git clone [options] [--] <dépôt> [<répertoire>]"
#: builtin/clone.c:64 builtin/fetch.c:97 builtin/merge.c:222
#: builtin/push.c:504
msgid "force progress reporting"
msgstr "forcer l'état d'avancement"
msgstr "forcer l'affichage de l'état d'avancement"
#: builtin/clone.c:66
msgid "don't create a checkout"
@ -4156,7 +4156,7 @@ msgid ""
msgstr ""
"Votre nom et votre adresse e-mail ont été configurés automatiquement en se "
"fondant\n"
"sur votre nom d'utilisateur et votre nom d'ordinateur. Veuillez vérifier "
"sur votre nom d'utilisateur et le nom de votre machine. Veuillez vérifier "
"qu'ils sont corrects.\n"
"Vous pouvez supprimer ce message en les paramétrant explicitement :\n"
"\n"
@ -4565,12 +4565,12 @@ msgstr "réutiliser le message du commit spécifié"
#: builtin/commit.c:1496
msgid "use autosquash formatted message to fixup specified commit"
msgstr ""
"utiliser un message formaté par autosquash pour corriger le commit spécifié"
"utiliser un message au format autosquash pour corriger le commit spécifié"
#: builtin/commit.c:1497
msgid "use autosquash formatted message to squash specified commit"
msgstr ""
"utiliser un message formaté par autosquash pour compresser le commit spécifié"
"utiliser un message au format autosquash pour compresser le commit spécifié"
#: builtin/commit.c:1498
msgid "the commit is authored by me now (used with -C/-c/--amend)"
@ -6404,7 +6404,7 @@ msgstr "Exactement une plage nécessaire."
#: builtin/log.c:809
msgid "Not a range."
msgstr "Pas une plage."
msgstr "Ceci n'est pas une plage."
#: builtin/log.c:911
msgid "Cover letter needs email format"
@ -6527,7 +6527,7 @@ msgstr "répondre dans le premier message à <id-message>"
#: builtin/log.c:1221 builtin/log.c:1224
msgid "boundary"
msgstr "frontière"
msgstr "limite"
#: builtin/log.c:1222
msgid "attach the patch"
@ -8092,7 +8092,7 @@ msgstr ""
#: builtin/push.c:361
#, c-format
msgid "Pushing to %s\n"
msgstr "Poussage vers %s\n"
msgstr "Poussée vers %s\n"
#: builtin/push.c:365
#, c-format
@ -8185,7 +8185,7 @@ msgstr "check"
#: builtin/push.c:497
msgid "control recursive pushing of submodules"
msgstr "contrôler le poussage récursif des sous-modules"
msgstr "contrôler la poussée récursive des sous-modules"
#: builtin/push.c:499
msgid "use thin pack"
@ -8736,12 +8736,12 @@ msgstr "Impossible de paramétrer %s"
#: builtin/remote.c:1307
#, c-format
msgid " %s will become dangling!"
msgstr " %s deviendra en suspens !"
msgstr " %s se retrouvera en suspens !"
#: builtin/remote.c:1308
#, c-format
msgid " %s has become dangling!"
msgstr " %s est devenu en suspens !"
msgstr " %s se retrouve en suspens !"
#: builtin/remote.c:1314
#, c-format
@ -10643,7 +10643,7 @@ msgstr "Conflits dans l'index. Essayez sans --index."
#: git-stash.sh:457
msgid "Could not save index tree"
msgstr "Impossible de sauver l'arbre d'index"
msgstr "Impossible de sauvegarder l'arbre d'index"
#: git-stash.sh:491
msgid "Cannot unstage modified files"
@ -10799,7 +10799,7 @@ msgstr ""
#, sh-format
msgid "No url found for submodule path '$displaypath' in .gitmodules"
msgstr ""
"URL non trouvé pour le chemin de sous-module '$displaypath' dans .gitmodules"
"URL non trouvée pour le chemin de sous-module '$displaypath' dans .gitmodules"
#: git-submodule.sh:620
#, sh-format

View File

@ -223,7 +223,13 @@ test_expect_success 'pull request format' '
git request-pull initial "$downstream_url" tags/full:refs/tags/full
) >request &&
sed -nf fuzz.sed <request >request.fuzzy &&
test_i18ncmp expect request.fuzzy
test_i18ncmp expect request.fuzzy &&
(
cd local &&
git request-pull initial "$downstream_url" full
) >request &&
grep ' tags/full$'
'
test_expect_success 'request-pull ignores OPTIONS_KEEPDASHDASH poison' '

View File

@ -578,12 +578,12 @@ test_expect_success 'prompt - bash color pc mode - untracked files status indica
'
test_expect_success 'prompt - zsh color pc mode' '
printf "BEFORE: (%%F{green}\${__git_ps1_branch_name}%%f):AFTER\\nmaster" >expected &&
printf "BEFORE: (%%F{green}master%%f):AFTER" >expected &&
(
ZSH_VERSION=5.0.0 &&
GIT_PS1_SHOWCOLORHINTS=y &&
__git_ps1 "BEFORE:" ":AFTER" >"$actual"
printf "%s\\n%s" "$PS1" "${__git_ps1_branch_name}" >"$actual"
__git_ps1 "BEFORE:" ":AFTER" &&
printf "%s" "$PS1" >"$actual"
) &&
test_cmp expected "$actual"
'