/GIT-CFLAGS
/GIT-LDFLAGS
/GIT-GUI-VARS
+/GIT-PREFIX
+/GIT-SCRIPT-DEFINES
+/GIT-USER-AGENT
/GIT-VERSION-FILE
/bin-wrappers/
/git
/git-commit-tree
/git-config
/git-count-objects
+/git-credential
/git-credential-cache
/git-credential-cache--daemon
/git-credential-store
/gitweb/static/gitweb.js
/gitweb/static/gitweb.min.*
/test-chmtime
-/test-credential
/test-ctype
/test-date
/test-delta
-include ../config.mak.autogen
-include ../config.mak
-#
-# For asciidoc ...
-# -7.1.2, set ASCIIDOC7
-# 8.0-, no extra settings are needed
-#
-
#
# For docbook-xsl ...
# -1.68.1, no extra settings are needed?
# 1.73.0-, no extra settings are needed
#
-ifndef ASCIIDOC7
-ASCIIDOC_EXTRA += -a asciidoc7compatible
-endif
ifdef DOCBOOK_XSL_172
ASCIIDOC_EXTRA += -a git-asciidoc-no-roff
MANPAGE_XSL = manpage-1.72.xsl
ASCIIDOC_EXTRA += -a 'git-default-editor=$(DEFAULT_EDITOR_SQ)'
endif
-#
-# Please note that there is a minor bug in asciidoc.
-# The version after 6.0.3 _will_ include the patch found here:
-# http://marc.theaimsgroup.com/?l=git&m=111558757202243&w=2
-#
-# Until that version is released you may have to apply the patch
-# yourself - yes, all 6 characters of it!
-#
-
QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
QUIET_SUBDIR1 =
technical/api-index.sh $(patsubst %,%.txt,$(API_DOCS))
$(QUIET_GEN)cd technical && '$(SHELL_PATH_SQ)' ./api-index.sh
+technical/%.html: ASCIIDOC_EXTRA += -a git-relative-html-prefix=../
$(patsubst %,%.html,$(API_DOCS) technical/api-index): %.html : %.txt
$(QUIET_ASCIIDOC)$(ASCIIDOC) -b xhtml11 -f asciidoc.conf \
$(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) $*.txt
WEBDOC_DEST = /pub/software/scm/git/docs
+howto/%.html: ASCIIDOC_EXTRA += -a git-relative-html-prefix=../
$(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
sed -e '1,/^$$/d' $< | $(ASCIIDOC) $(ASCIIDOC_EXTRA) -b xhtml11 - >$@+ && \
--- /dev/null
+Git v1.7.10.5 Release Notes
+===========================
+
+Fixes since v1.7.10.4
+---------------------
+
+ * "git fast-export" did not give a readable error message when the
+ same mark erroneously appeared twice in the --import-marks input.
+
+ * "git rebase -p" used to pay attention to rebase.autosquash which
+ was wrong. "git rebase -p -i" should, but "git rebase -p" by
+ itself should not.
--- /dev/null
+Git v1.7.11.1 Release Notes
+===========================
+
+Fixes since v1.7.11
+-------------------
+
+ * The cross links in the HTML version of manual pages were broken.
+
+Also contains minor typofixes and documentation updates.
--- /dev/null
+Git v1.7.11.2 Release Notes
+===========================
+
+Fixes since v1.7.11.1
+---------------------
+
+ * On Cygwin, the platform pread(2) is not thread safe, just like our
+ own compat/ emulation, and cannot be used in the index-pack
+ program. Makefile variable NO_THREAD_SAFE_PREAD can be defined to
+ avoid use of this function in a threaded program.
+
+ * "git add" allows adding a regular file to the path where a
+ submodule used to exist, but "git update-index" does not allow an
+ equivalent operation to Porcelain writers.
+
+ * "git archive" incorrectly computed the header checksum; the symptom
+ was observed only when using pathnames with hi-bit set.
+
+ * "git blame" did not try to make sure that the abbreviated commit
+ object names in its output are unique.
+
+ * Running "git bundle verify" on a bundle that records a complete
+ history said "it requires these 0 commits".
+
+ * "git clone --single-branch" to clone a single branch did not limit
+ the cloning to the specified branch.
+
+ * "git diff --no-index" did not correctly handle relative paths and
+ did not correctly give exit codes when run under "--quiet" option.
+
+ * "git diff --no-index" did not work with pagers correctly.
+
+ * "git diff COPYING HEAD:COPYING" gave a nonsense error message that
+ claimed that the treeish HEAD did not have COPYING in it.
+
+ * When "git log" gets "--simplify-merges/by-decoration" together with
+ "--first-parent", the combination of these options makes the
+ simplification logic to use in-core commit objects that haven't
+ been examined for relevance, either producing incorrect result or
+ taking too long to produce any output. Teach the simplification
+ logic to ignore commits that the first-parent traversal logic
+ ignored when both are in effect to work around the issue.
+
+ * "git ls-files --exclude=t -i" did not consider anything under t/ as
+ excluded, as it did not pay attention to exclusion of leading paths
+ while walking the index. Other two users of excluded() are also
+ updated.
+
+ * "git request-pull $url dev" when the tip of "dev" branch was tagged
+ with "ext4-for-linus" used the contents from the tag in the output
+ but still asked the "dev" branch to be pulled, not the tag.
+
+Also contains minor typofixes and documentation updates.
* A third-party tool "git subtree" is distributed in contrib/
+ * A remote helper that acts as a proxy and caches ssl session for the
+ https:// transport is added to the contrib/ area.
+
* Error messages given when @{u} is used for a branch without its
- upstream configured have been clatified.
+ upstream configured have been clarified.
- * Even with "-q"uiet option, "checkout" used to report setting up
+ * Even with the "-q"uiet option, "checkout" used to report setting up
tracking. Also "branch" learned the "-q"uiet option to squelch
informational message.
* "git am" learned the "--include" option, which is an opposite of
existing the "--exclude" option.
- * When "git am -3" needs to fall back to an application to a
- synthesized preimage followed by a 3-way merge, the paths that
+ * When "git am -3" needs to fall back to an application of the patch
+ to a synthesized preimage followed by a 3-way merge, the paths that
needed such treatment are now reported to the end user, so that the
result in them can be eyeballed with extra care.
after populating two temporary directories, instead of running an
instance of the external tool once per a file pair.
- * The "fmt-merge-msg" command learns to list the primary contributors
- involved in the side topic you are merging.
+ * The "fmt-merge-msg" command learned to list the primary contributors
+ involved in the side topic you are merging in a comment in the merge
+ commit template.
* "git rebase" learned to optionally keep commits that do not
introduce any change in the original history.
Foreign Interface
- * "git svn" used to die with unwanted SIGPIPE when talking with HTTP
+ * "git svn" used to die with unwanted SIGPIPE when talking with an HTTP
server that uses keep-alive.
* "git svn" learned to use platform specific authentication
providers, e.g. gnome-keyring, kwallet, etc.
- * "git p4" has been moved out of contrib/ area and has seen more work
- on importing labels as tags from (and exporting tags as labels to)
- p4.
+ * "git p4" has been moved out of the contrib/ area and has seen more
+ work on importing labels as tags from (and exporting tags as labels
+ to) p4.
Performance and Internal Implementation (please report possible regressions)
systems, run-command API now uses SHELL_PATH, not /bin/sh, when
spawning an external command (not applicable to Windows port).
- * The API to iterate over refs/ hierarchy has been tweaked to allow
- walking only a subset of it more efficiently.
+ * The API to iterate over the refs/ hierarchy has been tweaked to
+ allow walking only a subset of it more efficiently.
Also contains minor documentation updates and code clean-ups.
releases are contained in this release (see release notes to them for
details).
- * "git rebase -p" used to pay attention to rebase.autosquash which
- was wrong. "git rebase -p -i" should, but "git rebase -p" by
- itself should not.
- (cherry-pick 8a6dae1 vr/rebase-autosquash-does-not-imply-i later to maint).
-
* "git submodule init" used to report "registered for path ..."
even for submodules that were registered earlier.
(cherry-pick c1c259e jl/submodule-report-new-path-once later to maint).
--- /dev/null
+Git v1.7.12 Release Notes
+=========================
+
+Updates since v1.7.11
+---------------------
+
+UI, Workflows & Features
+
+ * Git can be told to normalize pathnames it read from readdir(3) and
+ all arguments it got from the command line into precomposed UTF-8
+ (assuming that they come as decomposed UTF-8), in order to work
+ around issues on Mac OS.
+
+ I think there still are other places that need conversion
+ (e.g. paths that are read from stdin for some commands), but this
+ should be a good first step in the right direction.
+
+ * Per-user $HOME/.gitconfig file can optionally be stored in
+ $HOME/.config/git/config instead, which is in line with XDG.
+
+ * The value of core.attributesfile and core.excludesfile default to
+ $HOME/.config/attributes and $HOME/.config/ignore respectively when
+ these files exist.
+
+ * "git apply" learned to wiggle the base version and perform three-way
+ merge when a patch does not exactly apply to the version you have.
+
+ * Scripted Porcelain writers now have access to the credential API via
+ the "git credential" plumbing command.
+
+ * "git help" used to always default to "man" format even on platforms
+ where "man" viewer is not widely available.
+
+ * "git clone --local $path" started its life as an experiment to
+ optionally use link/copy when cloning a repository on the disk, but
+ we didn't deprecate it after we made the option a no-op to always
+ use the optimization. The command learned "--no-local" option to
+ turn this off, as a more explicit alternative over use of file://
+ URL.
+
+ * "git fetch" and friends used to say "remote side hung up
+ unexpectedly" when they failed to get response they expect from the
+ other side, but one common reason why they don't get expected
+ response is that the remote repository does not exist or cannot be
+ read. The error message in this case was updated to give better
+ hints to the user.
+
+ * git native protocol agents learned to show software version over
+ the wire, so that the server log can be examined to see the vintage
+ distribution of clients.
+
+ * "git help -w $cmd" can show HTML version of documentation for
+ "git-$cmd" by setting help.htmlpath to somewhere other than the
+ default location where the build procedure installs them locally;
+ the variable can even point at a http:// URL.
+
+ * "git rebase [-i] --root $tip" can now be used to rewrite all the
+ history leading to "$tip" down to the root commit.
+
+ * "git rebase -i" learned "-x <cmd>" to insert "exec <cmd>" after
+ each commit in the resulting history.
+
+ * "git status" gives finer classification to various states of paths
+ in conflicted state and offer advice messages in its output.
+
+ * "git submodule" learned to deal with nested submodule structure
+ where a module is contained within a module whose origin is
+ specified as a relative URL to its superproject's origin.
+
+ * A rather heavy-ish "git completion" script has been split to create
+ a separate "git prompting" script, to help lazy-autoloading of the
+ completion part while making prompting part always available.
+
+
+Foreign Interface
+
+ * "mediawiki" remote helper (in contrib/) learned to handle file
+ attachments.
+
+ * "git p4" now uses "Jobs:" and "p4 move" when appropriate.
+
+ * vcs-svn has been updated to clean-up compilation, lift 32-bit
+ limitations, etc.
+
+
+Performance, Internal Implementation, etc. (please report possible regressions)
+
+ * Some tests showed false failures caused by a bug in ecryptofs.
+
+ * We no longer use AsciiDoc7 syntax in our documentation and favor a
+ more modern style.
+
+ * "git am --rebasing" codepath was taught to grab authorship, log
+ message and the patch text directly out of existing commits. This
+ will help rebasing commits that have confusing "diff" output in
+ their log messages.
+
+ * "git index-pack" and "git pack-objects" use streaming API to read
+ from the object store to avoid having to hold a large blob object
+ in-core while they are doing their thing.
+
+ * Code to match paths with exclude patterns learned to avoid calling
+ fnmatch() by comparing fixed leading substring literally when
+ possible.
+
+
+Also contains minor documentation updates and code clean-ups.
+
+
+Fixes since v1.7.11
+-------------------
+
+Unless otherwise noted, all the fixes since v1.7.11 in the maintenance
+releases are contained in this release (see release notes to them for
+details).
+
+ * The error message from "git push $there :bogo" (and its equivalent
+ "git push $there --delete bogo") mentioned that we tried and failed
+ to guess what ref is being deleted based on the LHS of the refspec,
+ which we don't.
+ (merge 5742c82 jk/push-delete-ref-error-message later to maint).
+
+ * A handful of files and directories we create had tighter than
+ necessary permission bits when the user wanted to have group
+ writability (e.g. by setting "umask 002").
+ (merge 6ff2b72 ar/clone-honor-umask-at-top later to maint).
+
+ * "commit --amend" used to refuse amending a commit with an empty log
+ message, with or without "--allow-empty-message".
+ (merge d9a9357 cw/amend-commit-without-message later to maint).
+
+ * "git commit --amend --only --" was meant to allow "Clever" people to
+ rewrite the commit message without making any change even when they
+ have already changes for the next commit added to their index, but
+ it never worked as advertised since it was introduced in 1.3.0 era.
+ (merge ea2d4ed jk/maint-commit-amend-only-no-paths later to maint).
+
+ * Even though the index can record pathnames longer than 1<<12 bytes,
+ in some places we were not comparing them in full, potentially
+ replacing index entries instead of adding.
+ (merge d5f5333 tg/maint-cache-name-compare later to maint).
+
+ * "git show"'s auto-walking behaviour was an unreliable and
+ unpredictable hack; it now behaves just like "git log" does when it
+ walks.
+ (merge c5941f1 tr/maint-show-walk later to maint).
+
+ * "git diff", "git status" and anything that internally uses the
+ comparison machinery was utterly broken when the difference
+ involved a file with "-" as its name. This was due to the way "git
+ diff --no-index" was incorrectly bolted on to the system, making
+ any comparison that involves a file "-" at the root level
+ incorrectly read from the standard input.
+ (merge 4682d85 jc/refactor-diff-stdin later to maint).
+
+ * We did not have test to make sure "git rebase" without extra options
+ filters out an empty commit in the original history.
+ (merge 2b5ba7b mz/empty-rebase-test later to maint).
+
+ * "git fast-export" produced an input stream for fast-import without
+ properly quoting pathnames when they contain SPs in them.
+ (merge ff59f6d js/fast-export-paths-with-spaces later to maint).
+
+ * "git checkout --detach", when you are still on an unborn branch,
+ should be forbidden, but it wasn't.
+ (merge 8ced1aa cw/no-detaching-an-unborn later to maint).
+
+ * Some implementations of Perl terminates "lines" with CRLF even when
+ the script is operating on just a sequence of bytes. Make sure to
+ use "$PERL_PATH", the version of Perl the user told Git to use, in
+ our tests to avoid unnecessary breakages in tests.
+ (merge ad78585 vr/use-our-perl-in-tests later to maint).
endif::doctype-manpage[]
ifdef::backend-xhtml11[]
+[attributes]
+git-relative-html-prefix=
[linkgit-inlinemacro]
-<a href="{target}.html">{target}{0?({0})}</a>
+<a href="{git-relative-html-prefix}{target}.html">{target}{0?({0})}</a>
endif::backend-xhtml11[]
will probe and set core.ignorecase true if appropriate when the repository
is created.
+core.precomposeunicode::
+ This option is only used by Mac OS implementation of git.
+ When core.precomposeunicode=true, git reverts the unicode decomposition
+ of filenames done by Mac OS. This is useful when sharing a repository
+ between Mac OS and Linux or Windows.
+ (Git for Windows 1.7.10 or higher is needed, or git under cygwin 1.7).
+ When false, file names are handled fully transparent by git,
+ which is backward compatible with older versions of git.
+
core.trustctime::
If false, the ctime differences between the index and the
working tree are ignored; useful when the inode change time
'.git/info/exclude', git looks into this file for patterns
of files which are not meant to be tracked. "`~/`" is expanded
to the value of `$HOME` and "`~user/`" to the specified user's
- home directory. See linkgit:gitignore[5].
+ home directory. Its default value is $XDG_CONFIG_HOME/git/ignore.
+ If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/ignore
+ is used instead. See linkgit:gitignore[5].
core.askpass::
Some commands (e.g. svn and http interfaces) that interactively
In addition to '.gitattributes' (per-directory) and
'.git/info/attributes', git looks into this file for attributes
(see linkgit:gitattributes[5]). Path expansions are made the same
- way as for `core.excludesfile`.
+ way as for `core.excludesfile`. Its default value is
+ $XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME is either not
+ set or empty, $HOME/.config/git/attributes is used instead.
core.editor::
Commands such as `commit` and `tag` that lets you edit
make equal size columns
--
+
- This option defaults to 'never'.
+This option defaults to 'never'.
column.branch::
Specify whether to output branch listing in `git branch` in columns.
no refspec is implied by any of the options given on the command
line. Possible values are:
+
+--
* `nothing` - do not push anything.
* `matching` - push all branches having the same name in both ends.
This is for those who prepare all the branches into a publishable
option and is well-suited for beginners. It will become the default
in Git 2.0.
* `current` - push the current branch to a branch of the same name.
- +
- The `simple`, `current` and `upstream` modes are for those who want to
- push out a single branch after finishing work, even when the other
- branches are not yet ready to be pushed out. If you are working with
- other people to push into the same shared repository, you would want
- to use one of these.
+--
++
+The `simple`, `current` and `upstream` modes are for those who want to
+push out a single branch after finishing work, even when the other
+branches are not yet ready to be pushed out. If you are working with
+other people to push into the same shared repository, you would want
+to use one of these.
rebase.stat::
Whether to show a diffstat of what changed upstream since the last
diff.statGraphWidth::
Limit the width of the graph part in --stat output. If set, applies
- to all commands generating --stat outuput except format-patch.
+ to all commands generating --stat output except format-patch.
diff.external::
If this config variable is set, diff generation is not
Generate a diffstat. By default, as much space as necessary
will be used for the filename part, and the rest for the graph
part. Maximum width defaults to terminal width, or 80 columns
- if not connected to a terminal, and can be overriden by
+ if not connected to a terminal, and can be overridden by
`<width>`. The width of the filename part can be limited by
giving another width `<name-width>` after a comma. The width
of the graph part can be limited by using
SYNOPSIS
--------
[verse]
-'git apply' [--stat] [--numstat] [--summary] [--check] [--index]
+'git apply' [--stat] [--numstat] [--summary] [--check] [--index] [--3way]
[--apply] [--no-add] [--build-fake-ancestor=<file>] [-R | --reverse]
[--allow-binary-replacement | --binary] [--reject] [-z]
[-p<n>] [-C<n>] [--inaccurate-eof] [--recount] [--cached]
cached data, apply the patch, and store the result in the index
without using the working tree. This implies `--index`.
+-3::
+--3way::
+ When the patch does not apply cleanly, fall back on 3-way merge if
+ the patch records the identity of blobs it is supposed to apply to,
+ and we have those blobs available locally, possibly leaving the
+ conflict markers in the files in the working tree for the user to
+ resolve. This option implies the `--index` option, and is incompatible
+ with the `--reject` and the `--cached` options.
+
--build-fake-ancestor=<file>::
Newer 'git diff' output has embedded 'index information'
for each blob to help identify the original version that
linkgit:gitrevisions[7].
Sets of commits can be passed but no traversal is done by
default, as if the '--no-walk' option was specified, see
- linkgit:git-rev-list[1].
+ linkgit:git-rev-list[1]. Note that specifying a range will
+ feed all <commit>... arguments to a single revision walk
+ (see a later example that uses 'maint master..next').
-e::
--edit::
Apply the changes introduced by all commits that are ancestors
of master but not of HEAD to produce new commits.
+`git cherry-pick maint next ^master`::
+`git cherry-pick maint master..next`::
+
+ Apply the changes introduced by all commits that are
+ ancestors of maint or next, but not master or any of its
+ ancestors. Note that the latter does not mean `maint` and
+ everything between `master` and `next`; specifically,
+ `maint` will not be used if it is included in `master`.
+
`git cherry-pick master~4 master~2`::
Apply the changes introduced by the fifth and third last
mechanism and clones the repository by making a copy of
HEAD and everything under objects and refs directories.
The files under `.git/objects/` directory are hardlinked
- to save space when possible. This is now the default when
- the source repository is specified with `/path/to/repo`
- syntax, so it essentially is a no-op option. To force
- copying instead of hardlinking (which may be desirable
- if you are trying to make a back-up of your repository),
- but still avoid the usual "git aware" transport
- mechanism, `--no-hardlinks` can be used.
+ to save space when possible.
++
+If the repository is specified as a local path (e.g., `/path/to/repo`),
+this is the default, and --local is essentially a no-op. If the
+repository is specified as a URL, then this flag is ignored (and we
+never use the local optimizations). Specifying `--no-local` will
+override the default when `/path/to/repo` is given, using the regular
+git transport instead.
++
+To force copying instead of hardlinking (which may be desirable if you
+are trying to make a back-up of your repository), but still avoid the
+usual "git aware" transport mechanism, `--no-hardlinks` can be used.
--no-hardlinks::
Optimize the cloning process from a repository on a
--------
[verse]
'git column' [--command=<name>] [--[raw-]mode=<mode>] [--width=<width>]
- [--indent=<string>] [--nl=<string>] [--pading=<n>]
+ [--indent=<string>] [--nl=<string>] [--padding=<n>]
DESCRIPTION
-----------
--------
[verse]
'git commit-tree' <tree> [(-p <parent>)...] < changelog
-'git commit-tree' [(-p <parent>)...] [(-m <message>)...] [(-F <file>)...] <tree>
+'git commit-tree' <tree> [(-p <parent>)...] [(-m <message>)...] [(-F <file>)...]
DESCRIPTION
-----------
Each '-p' indicates the id of a parent commit object.
-m <message>::
- A paragraph in the commig log message. This can be given more than
+ A paragraph in the commit log message. This can be given more than
once and each <message> becomes its own paragraph.
-F <file>::
When doing a dry-run, give the output in the short-format. See
linkgit:git-status[1] for details. Implies `--dry-run`.
+--branch::
+ Show the branch and tracking info even in short-format.
+
--porcelain::
When doing a dry-run, give the output in a porcelain-ready
format. See linkgit:git-status[1] for details. Implies
`--dry-run`.
-z::
+--null::
When showing `short` or `porcelain` status output, terminate
entries in the status output with NUL, instead of LF. If no
format is given, implies the `--porcelain` output format.
current tip -- if it was a merge, it will have the parents of
the current tip as parents -- so the current top commit is
discarded.
+
+--no-post-rewrite::
+ Bypass the post-rewrite hook.
+
+
--
It is a rough equivalent for:
--global::
For writing options: write to global ~/.gitconfig file rather than
- the repository .git/config.
+ the repository .git/config, write to $XDG_CONFIG_HOME/git/config file
+ if this file exists and the ~/.gitconfig file doesn't.
+
-For reading options: read only from global ~/.gitconfig rather than
-from all available files.
+For reading options: read only from global ~/.gitconfig and from
+$XDG_CONFIG_HOME/git/config rather than from all available files.
+
See also <<FILES>>.
FILES
-----
-If not set explicitly with '--file', there are three files where
+If not set explicitly with '--file', there are four files where
'git config' will search for configuration options:
$GIT_DIR/config::
User-specific configuration file. Also called "global"
configuration file.
+$XDG_CONFIG_HOME/git/config::
+ Second user-specific configuration file. If $XDG_CONFIG_HOME is not set
+ or empty, $HOME/.config/git/config will be used. Any single-valued
+ variable set in this file will be overwritten by whatever is in
+ ~/.gitconfig. It is a good idea not to create this file if
+ you sometimes use older versions of Git, as support for this
+ file was added fairly recently.
+
$(prefix)/etc/gitconfig::
System-wide configuration file.
--- /dev/null
+git-credential(1)
+=================
+
+NAME
+----
+git-credential - retrieve and store user credentials
+
+SYNOPSIS
+--------
+------------------
+git credential <fill|approve|reject>
+------------------
+
+DESCRIPTION
+-----------
+
+Git has an internal interface for storing and retrieving credentials
+from system-specific helpers, as well as prompting the user for
+usernames and passwords. The git-credential command exposes this
+interface to scripts which may want to retrieve, store, or prompt for
+credentials in the same manner as git. The design of this scriptable
+interface models the internal C API; see
+link:technical/api-credentials.txt[the git credential API] for more
+background on the concepts.
+
+git-credential takes an "action" option on the command-line (one of
+`fill`, `approve`, or `reject`) and reads a credential description
+on stdin (see <<IOFMT,INPUT/OUTPUT FORMAT>>).
+
+If the action is `fill`, git-credential will attempt to add "username"
+and "password" attributes to the description by reading config files,
+by contacting any configured credential helpers, or by prompting the
+user. The username and password attributes of the credential
+description are then printed to stdout together with the attributes
+already provided.
+
+If the action is `approve`, git-credential will send the description
+to any configured credential helpers, which may store the credential
+for later use.
+
+If the action is `reject`, git-credential will send the description to
+any configured credential helpers, which may erase any stored
+credential matching the description.
+
+If the action is `approve` or `reject`, no output should be emitted.
+
+TYPICAL USE OF GIT CREDENTIAL
+-----------------------------
+
+An application using git-credential will typically use `git
+credential` following these steps:
+
+ 1. Generate a credential description based on the context.
++
+For example, if we want a password for
+`https://example.com/foo.git`, we might generate the following
+credential description (don't forget the blank line at the end; it
+tells `git credential` that the application finished feeding all the
+infomation it has):
+
+ protocol=https
+ host=example.com
+ path=foo.git
+
+ 2. Ask git-credential to give us a username and password for this
+ description. This is done by running `git credential fill`,
+ feeding the description from step (1) to its standard input. The complete
+ credential description (including the credential per se, i.e. the
+ login and password) will be produced on standard output, like:
+
+ protocol=https
+ host=example.com
+ username=bob
+ password=secr3t
++
+In most cases, this means the attributes given in the input will be
+repeated in the output, but git may also modify the credential
+description, for example by removing the `path` attribute when the
+protocol is HTTP(s) and `credential.useHttpPath` is false.
++
+If the `git credential` knew about the password, this step may
+not have involved the user actually typing this password (the
+user may have typed a password to unlock the keychain instead,
+or no user interaction was done if the keychain was already
+unlocked) before it returned `password=secr3t`.
+
+ 3. Use the credential (e.g., access the URL with the username and
+ password from step (2)), and see if it's accepted.
+
+ 4. Report on the success or failure of the password. If the
+ credential allowed the operation to complete successfully, then
+ it can be marked with an "approve" action to tell `git
+ credential` to reuse it in its next invocation. If the credential
+ was rejected during the operation, use the "reject" action so
+ that `git credential` will ask for a new password in its next
+ invocation. In either case, `git credential` should be fed with
+ the credential description obtained from step (2) (which also
+ contain the ones provided in step (1)).
+
+[[IOFMT]]
+INPUT/OUTPUT FORMAT
+-------------------
+
+`git credential` reads and/or writes (depending on the action used)
+credential information in its standard input/output. These information
+can correspond either to keys for which `git credential` will obtain
+the login/password information (e.g. host, protocol, path), or to the
+actual credential data to be obtained (login/password).
+
+The credential is split into a set of named attributes.
+Attributes are provided to the helper, one per line. Each attribute is
+specified by a key-value pair, separated by an `=` (equals) sign,
+followed by a newline. The key may contain any bytes except `=`,
+newline, or NUL. The value may contain any bytes except newline or NUL.
+In both cases, all bytes are treated as-is (i.e., there is no quoting,
+and one cannot transmit a value with newline or NUL in it). The list of
+attributes is terminated by a blank line or end-of-file.
+Git will send the following attributes (but may not send all of
+them for a given credential; for example, a `host` attribute makes no
+sense when dealing with a non-network protocol):
+
+`protocol`::
+
+ The protocol over which the credential will be used (e.g.,
+ `https`).
+
+`host`::
+
+ The remote hostname for a network credential.
+
+`path`::
+
+ The path with which the credential will be used. E.g., for
+ accessing a remote https repository, this will be the
+ repository's path on the server.
+
+`username`::
+
+ The credential's username, if we already have one (e.g., from a
+ URL, from the user, or from a previously run helper).
+
+`password`::
+
+ The credential's password, if we are asking it to be stored.
p4. By default, this is the most recent p4 commit reachable
from 'HEAD'.
--M[<n>]::
+-M::
Detect renames. See linkgit:git-diff[1]. Renames will be
represented in p4 using explicit 'move' operations. There
is no corresponding option to detect copies, but there are
Submit variables
~~~~~~~~~~~~~~~~
git-p4.detectRenames::
- Detect renames. See linkgit:git-diff[1].
+ Detect renames. See linkgit:git-diff[1]. This can be true,
+ false, or a score as expected by 'git diff -M'.
git-p4.detectCopies::
- Detect copies. See linkgit:git-diff[1].
+ Detect copies. See linkgit:git-diff[1]. This can be true,
+ false, or a score as expected by 'git diff -C'.
git-p4.detectCopiesHarder::
- Detect copies harder. See linkgit:git-diff[1].
+ Detect copies harder. See linkgit:git-diff[1]. A boolean.
git-p4.preserveUser::
On submit, re-author changes to reflect the git author,
SYNOPSIS
--------
[verse]
-'git rebase' [-i | --interactive] [options] [--onto <newbase>]
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
[<upstream>] [<branch>]
-'git rebase' [-i | --interactive] [options] --onto <newbase>
+'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
--root [<branch>]
'git rebase' --continue | --skip | --abort
OPTIONS
-------
-<newbase>::
+--onto <newbase>::
Starting point at which to create the new commits. If the
--onto option is not specified, the starting point is
<upstream>. May be any valid commit, and not just an
with the `--interactive` option explicitly is generally not a good
idea unless you know what you are doing (see BUGS below).
+-x <cmd>::
+--exec <cmd>::
+ Append "exec <cmd>" after each line creating a commit in the
+ final history. <cmd> will be interpreted as one or more shell
+ commands.
++
+This option can only be used with the `--interactive` option
+(see INTERACTIVE MODE below).
++
+You may execute several commands by either using one instance of `--exec`
+with several commands:
++
+ git rebase -i --exec "cmd1 && cmd2 && ..."
++
+or by giving more than one `--exec`:
++
+ git rebase -i --exec "cmd1" --exec "cmd2" --exec ...
++
+If `--autosquash` is used, "exec" lines will not be appended for
+the intermediate commits, and will only appear at the end of each
+squash/fixup series.
--root::
Rebase all commits reachable from <branch>, instead of
limiting them with an <upstream>. This allows you to rebase
- the root commit(s) on a branch. Must be used with --onto, and
+ the root commit(s) on a branch. When used with --onto, it
will skip changes already contained in <newbase> (instead of
- <upstream>). When used together with --preserve-merges, 'all'
- root commits will be rewritten to have <newbase> as parent
+ <upstream>) whereas without --onto it will operate on every change.
+ When used together with both --onto and --preserve-merges,
+ 'all' root commits will be rewritten to have <newbase> as parent
instead.
--autosquash::
use shell features (like "cd", ">", ";" ...). The command is run from
the root of the working tree.
+----------------------------------
+$ git rebase -i --exec "make test"
+----------------------------------
+
+This command lets you check that intermediate commits are compilable.
+The todo list becomes like that:
+
+--------------------
+pick 5928aea one
+exec make test
+pick 04d0fda two
+exec make test
+pick ba46169 three
+exec make test
+pick f4593f9 four
+exec make test
+--------------------
+
SPLITTING COMMITS
-----------------
The option core.warnAmbiguousRefs is used to select the strict
abbreviation mode.
+--disambiguate=<prefix>::
+ Show every object whose name begins with the given prefix.
+ The <prefix> must be at least 4 hexadecimal digits long to
+ avoid listing each and every object in the repository by
+ mistake.
+
--all::
Show all refs found in `refs/`.
checkout the commit specified in the index of the containing repository.
This will make the submodules HEAD be detached unless `--rebase` or
`--merge` is specified or the key `submodule.$name.update` is set to
- `rebase`, `merge` or `none`. `none` can be overriden by specifying
+ `rebase`, `merge` or `none`. `none` can be overridden by specifying
`--checkout`.
+
If the submodule is not yet initialized, and you just want to use the
branch of the `git.git` repository.
Documentation for older releases are available here:
-* link:v1.7.10.4/git.html[documentation for release 1.7.10.4]
+* link:v1.7.11.2/git.html[documentation for release 1.7.11.2]
* release notes for
+ link:RelNotes/1.7.11.2.txt[1.7.11.2],
+ link:RelNotes/1.7.11.1.txt[1.7.11.1],
+ link:RelNotes/1.7.11.txt[1.7.11].
+
+* link:v1.7.10.5/git.html[documentation for release 1.7.10.5]
+
+* release notes for
+ link:RelNotes/1.7.10.5.txt[1.7.10.5],
link:RelNotes/1.7.10.4.txt[1.7.10.4],
link:RelNotes/1.7.10.3.txt[1.7.10.3],
link:RelNotes/1.7.10.2.txt[1.7.10.2],
'GIT_EDITOR'::
This environment variable overrides `$EDITOR` and `$VISUAL`.
- It is used by several git comands when, on interactive mode,
+ It is used by several git commands when, on interactive mode,
an editor is to be launched. See also linkgit:git-var[1]
and the `core.editor` option in linkgit:git-config[1].
`.gitattributes` files. Attributes that should affect all repositories
for a single user should be placed in a file specified by the
`core.attributesfile` configuration option (see linkgit:git-config[1]).
+Its default value is $XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME
+is either not set or empty, $HOME/.config/git/attributes is used instead.
Attributes for all users on a system should be placed in the
`$(prefix)/etc/gitattributes` file.
the `$GIT_DIR/info/exclude` file. Patterns which a user wants git to
ignore in all situations (e.g., backup or temporary files generated by
the user's editor of choice) generally go into a file specified by
-`core.excludesfile` in the user's `~/.gitconfig`.
+`core.excludesfile` in the user's `~/.gitconfig`. Its default value is
+$XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is either not set or empty,
+$HOME/.config/git/ignore is used instead.
The underlying git plumbing tools, such as
'git ls-files' and 'git read-tree', read
By default set to 'highlight'; set it to full path to highlight
executable if it is not installed on your web server's PATH.
Note that 'highlight' feature must be set for gitweb to actually
- use syntax hightlighting.
+ use syntax highlighting.
+
*NOTE*: if you want to add support for new file type (supported by
"highlight" but not used by gitweb), you need to modify `%highlight_ext`
--no-walk::
Only show the given revs, but do not traverse their ancestors.
+ This has no effect if a range is specified.
--do-walk::
world can take many forms, in this document the word "credential" always
refers to a username and password pair).
+This document describes two interfaces: the C API that the credential
+subsystem provides to the rest of git, and the protocol that git uses to
+communicate with system-specific "credential helpers". If you are
+writing git code that wants to look up or prompt for credentials, see
+the section "C API" below. If you want to write your own helper, see
+the section on "Credential Helpers" below.
+
+Typical setup
+-------------
+
+------------
++-----------------------+
+| git code (C) |--- to server requiring --->
+| | authentication
+|.......................|
+| C credential API |--- prompt ---> User
++-----------------------+
+ ^ |
+ | pipe |
+ | v
++-----------------------+
+| git credential helper |
++-----------------------+
+------------
+
+The git code (typically a remote-helper) will call the C API to obtain
+credential data like a login/password pair (credential_fill). The
+API will itself call a remote helper (e.g. "git credential-cache" or
+"git credential-store") that may retrieve credential data from a
+store. If the credential helper cannot find the information, the C API
+will prompt the user. Then, the caller of the API takes care of
+contacting the server, and does the actual authentication.
+
+C API
+-----
+
+The credential C API is meant to be called by git code which needs to
+acquire or store a credential. It is centered around an object
+representing a single credential and provides three basic operations:
+fill (acquire credentials by calling helpers and/or prompting the user),
+approve (mark a credential as successfully used so that it can be stored
+for later use), and reject (mark a credential as unsuccessful so that it
+can be erased from any persistent storage).
+
Data Structures
----------------
+~~~~~~~~~~~~~~~
`struct credential`::
The `helpers` member of the struct is a `string_list` of helpers. Each
string specifies an external helper which will be run, in order, to
either acquire or store credentials. See the section on credential
-helpers below.
+helpers below. This list is filled-in by the API functions
+according to the corresponding configuration variables before
+consulting helpers, so there usually is no need for a caller to
+modify the helpers field at all.
+
This struct should always be initialized with `CREDENTIAL_INIT` or
`credential_init`.
Functions
----------
+~~~~~~~~~
`credential_init`::
Parse a URL into broken-down credential fields.
Example
--------
+~~~~~~~
The example below shows how the functions of the credential API could be
used to login to a fictitious "foo" service on a remote host:
longer than a single git process; e.g., credentials may be stored
in-memory for a few minutes, or indefinitely on disk).
-Each helper is specified by a single string. The string is transformed
-by git into a command to be executed using these rules:
+Each helper is specified by a single string in the configuration
+variable `credential.helper` (and others, see linkgit:git-config[1]).
+The string is transformed by git into a command to be executed using
+these rules:
1. If the helper string begins with "!", it is considered a shell
snippet, and everything after the "!" becomes the command.
Remove a matching credential, if any, from the helper's storage.
The details of the credential will be provided on the helper's stdin
-stream. The credential is split into a set of named attributes.
-Attributes are provided to the helper, one per line. Each attribute is
-specified by a key-value pair, separated by an `=` (equals) sign,
-followed by a newline. The key may contain any bytes except `=`,
-newline, or NUL. The value may contain any bytes except newline or NUL.
-In both cases, all bytes are treated as-is (i.e., there is no quoting,
-and one cannot transmit a value with newline or NUL in it). The list of
-attributes is terminated by a blank line or end-of-file.
-
-Git will send the following attributes (but may not send all of
-them for a given credential; for example, a `host` attribute makes no
-sense when dealing with a non-network protocol):
-
-`protocol`::
-
- The protocol over which the credential will be used (e.g.,
- `https`).
-
-`host`::
-
- The remote hostname for a network credential.
-
-`path`::
-
- The path with which the credential will be used. E.g., for
- accessing a remote https repository, this will be the
- repository's path on the server.
-
-`username`::
-
- The credential's username, if we already have one (e.g., from a
- URL, from the user, or from a previously run helper).
-
-`password`::
-
- The credential's password, if we are asking it to be stored.
+stream. The exact format is the same as the input/output format of the
+`git credential` plumbing command (see the section `INPUT/OUTPUT
+FORMAT` in linkgit:git-credential[7] for a detailed specification).
For a `get` operation, the helper should produce a list of attributes
on stdout in the same format. A helper is free to produce a subset, or
If a helper receives any other operation, it should silently ignore the
request. This leaves room for future operations to be added (older
helpers will just ignore the new requests).
+
+See also
+--------
+
+linkgit:gitcredentials[7]
+
+linkgit:git-config[5] (See configuration variables `credential.*`)
You will see informational messages on dangling objects. They are objects
that still exist in the repository but are no longer referenced by any of
your branches, and can (and will) be removed after a while with "gc".
-You can run `git fsck --no-dangling` to supress these messages, and still
+You can run `git fsck --no-dangling` to suppress these messages, and still
view real errors.
[[recovering-lost-changes]]
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.11-rc1
+DEF_VER=v1.7.11.GIT
LF='
'
# Define NO_PREAD if you have a problem with pread() system call (e.g.
# cygwin1.dll before v1.5.22).
#
+# Define NO_THREAD_SAFE_PREAD if your pread() implementation is not
+# thread-safe. (e.g. compat/pread.c or cygwin)
+#
# Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is
# generally faster on your platform than accessing the working directory.
#
# Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have st_blocks
# field that counts the on-disk footprint in 512-byte blocks.
#
-# Define ASCIIDOC7 if you want to format documentation with AsciiDoc 7
-#
# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72
# (not v1.73 or v1.71).
#
# the diff algorithm. It gives a nice speedup if your processor has
# fast unaligned word loads. Does NOT work on big-endian systems!
# Enabled by default on x86_64.
+#
+# Define GIT_USER_AGENT if you want to change how git identifies itself during
+# network interactions. The default is "git/$(GIT_VERSION)".
+#
+# Define DEFAULT_HELP_FORMAT to "man", "info" or "html"
+# (defaults to "man") if you want to have a different default when
+# "git help" is called without a parameter specifying the format.
GIT-VERSION-FILE: FORCE
@$(SHELL_PATH) ./GIT-VERSION-GEN
BUILT_INS =
COMPAT_CFLAGS =
COMPAT_OBJS =
-XDIFF_H =
XDIFF_OBJS =
-VCSSVN_H =
VCSSVN_OBJS =
-VCSSVN_TEST_OBJS =
-MISC_H =
+GENERATED_H =
EXTRA_CPPFLAGS =
LIB_H =
LIB_OBJS =
PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
TEST_PROGRAMS_NEED_X += test-chmtime
-TEST_PROGRAMS_NEED_X += test-credential
TEST_PROGRAMS_NEED_X += test-ctype
TEST_PROGRAMS_NEED_X += test-date
TEST_PROGRAMS_NEED_X += test-delta
XDIFF_LIB=xdiff/lib.a
VCSSVN_LIB=vcs-svn/lib.a
-XDIFF_H += xdiff/xinclude.h
-XDIFF_H += xdiff/xmacros.h
-XDIFF_H += xdiff/xdiff.h
-XDIFF_H += xdiff/xtypes.h
-XDIFF_H += xdiff/xutils.h
-XDIFF_H += xdiff/xprepare.h
-XDIFF_H += xdiff/xdiffi.h
-XDIFF_H += xdiff/xemit.h
-
-VCSSVN_H += vcs-svn/line_buffer.h
-VCSSVN_H += vcs-svn/sliding_window.h
-VCSSVN_H += vcs-svn/repo_tree.h
-VCSSVN_H += vcs-svn/fast_export.h
-VCSSVN_H += vcs-svn/svndiff.h
-VCSSVN_H += vcs-svn/svndump.h
-
-MISC_H += bisect.h
-MISC_H += branch.h
-MISC_H += bundle.h
-MISC_H += common-cmds.h
-MISC_H += fetch-pack.h
-MISC_H += reachable.h
-MISC_H += send-pack.h
-MISC_H += shortlog.h
-MISC_H += tar.h
-MISC_H += thread-utils.h
-MISC_H += url.h
-MISC_H += walker.h
-MISC_H += wt-status.h
+LIB_H += xdiff/xinclude.h
+LIB_H += xdiff/xmacros.h
+LIB_H += xdiff/xdiff.h
+LIB_H += xdiff/xtypes.h
+LIB_H += xdiff/xutils.h
+LIB_H += xdiff/xprepare.h
+LIB_H += xdiff/xdiffi.h
+LIB_H += xdiff/xemit.h
+
+LIB_H += vcs-svn/line_buffer.h
+LIB_H += vcs-svn/sliding_window.h
+LIB_H += vcs-svn/repo_tree.h
+LIB_H += vcs-svn/fast_export.h
+LIB_H += vcs-svn/svndiff.h
+LIB_H += vcs-svn/svndump.h
+
+GENERATED_H += common-cmds.h
LIB_H += advice.h
LIB_H += archive.h
LIB_H += argv-array.h
LIB_H += attr.h
+LIB_H += bisect.h
LIB_H += blob.h
+LIB_H += branch.h
LIB_H += builtin.h
LIB_H += bulk-checkin.h
-LIB_H += cache.h
+LIB_H += bundle.h
LIB_H += cache-tree.h
+LIB_H += cache.h
LIB_H += color.h
+LIB_H += column.h
LIB_H += commit.h
LIB_H += compat/bswap.h
LIB_H += compat/cygwin.h
LIB_H += compat/mingw.h
LIB_H += compat/obstack.h
+LIB_H += compat/precompose_utf8.h
LIB_H += compat/terminal.h
LIB_H += compat/win32/dirent.h
LIB_H += compat/win32/poll.h
LIB_H += diffcore.h
LIB_H += dir.h
LIB_H += exec_cmd.h
+LIB_H += fetch-pack.h
LIB_H += fmt-merge-msg.h
LIB_H += fsck.h
LIB_H += gettext.h
LIB_H += grep.h
LIB_H += hash.h
LIB_H += help.h
+LIB_H += http.h
LIB_H += kwset.h
LIB_H += levenshtein.h
LIB_H += list-objects.h
LIB_H += merge-file.h
LIB_H += merge-recursive.h
LIB_H += mergesort.h
-LIB_H += notes.h
LIB_H += notes-cache.h
LIB_H += notes-merge.h
+LIB_H += notes.h
LIB_H += object.h
-LIB_H += pack.h
LIB_H += pack-refs.h
LIB_H += pack-revindex.h
+LIB_H += pack.h
LIB_H += parse-options.h
LIB_H += patch-ids.h
LIB_H += pkt-line.h
LIB_H += progress.h
LIB_H += prompt.h
LIB_H += quote.h
+LIB_H += reachable.h
LIB_H += reflog-walk.h
LIB_H += refs.h
LIB_H += remote.h
LIB_H += resolve-undo.h
LIB_H += revision.h
LIB_H += run-command.h
+LIB_H += send-pack.h
LIB_H += sequencer.h
LIB_H += sha1-array.h
LIB_H += sha1-lookup.h
+LIB_H += shortlog.h
LIB_H += sideband.h
LIB_H += sigchain.h
LIB_H += strbuf.h
LIB_H += string-list.h
LIB_H += submodule.h
LIB_H += tag.h
+LIB_H += tar.h
LIB_H += thread-utils.h
LIB_H += transport.h
-LIB_H += tree.h
LIB_H += tree-walk.h
+LIB_H += tree.h
LIB_H += unpack-trees.h
+LIB_H += url.h
LIB_H += userdiff.h
LIB_H += utf8.h
LIB_H += varint.h
+LIB_H += walker.h
+LIB_H += wt-status.h
LIB_H += xdiff-interface.h
LIB_H += xdiff/xdiff.h
LIB_OBJS += userdiff.o
LIB_OBJS += utf8.o
LIB_OBJS += varint.o
+LIB_OBJS += version.o
LIB_OBJS += walker.o
LIB_OBJS += wrapper.o
LIB_OBJS += write_or_die.o
BUILTIN_OBJS += builtin/commit.o
BUILTIN_OBJS += builtin/config.o
BUILTIN_OBJS += builtin/count-objects.o
+BUILTIN_OBJS += builtin/credential.o
BUILTIN_OBJS += builtin/describe.o
BUILTIN_OBJS += builtin/diff-files.o
BUILTIN_OBJS += builtin/diff-index.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
EXTLIBS =
+GIT_USER_AGENT = git/$(GIT_VERSION)
+
#
# Platform specific tweaks
#
NO_MEMMEM = YesPlease
USE_ST_TIMESPEC = YesPlease
HAVE_DEV_TTY = YesPlease
+ COMPAT_OBJS += compat/precompose_utf8.o
+ BASIC_CFLAGS += -DPRECOMPOSE_UNICODE
endif
ifeq ($(uname_S),SunOS)
NEEDS_SOCKET = YesPlease
NO_IPV6 = YesPlease
OLD_ICONV = UnfortunatelyYes
endif
+ NO_THREAD_SAFE_PREAD = YesPlease
NEEDS_LIBICONV = YesPlease
NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
NO_TRUSTABLE_FILEMODE = UnfortunatelyYes
BLK_SHA1 = YesPlease
NO_POSIX_GOODIES = UnfortunatelyYes
NATIVE_CRLF = YesPlease
+ DEFAULT_HELP_FORMAT = html
CC = compat/vcbuild/scripts/clink.pl
AR = compat/vcbuild/scripts/lib.pl
ifdef NO_PREAD
COMPAT_CFLAGS += -DNO_PREAD
COMPAT_OBJS += compat/pread.o
+ NO_THREAD_SAFE_PREAD = YesPlease
+endif
+ifdef NO_THREAD_SAFE_PREAD
+ BASIC_CFLAGS += -DNO_THREAD_SAFE_PREAD
endif
ifdef NO_FAST_WORKING_DIRECTORY
BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY
endif
endif
-ifdef ASCIIDOC7
- export ASCIIDOC7
-endif
-
ifdef NO_INSTALL_HARDLINKS
export NO_INSTALL_HARDLINKS
endif
BASIC_CFLAGS += -DSHELL_PATH='$(SHELL_PATH_CQ_SQ)'
endif
+GIT_USER_AGENT_SQ = $(subst ','\'',$(GIT_USER_AGENT))
+GIT_USER_AGENT_CQ = "$(subst ",\",$(subst \,\\,$(GIT_USER_AGENT)))"
+GIT_USER_AGENT_CQ_SQ = $(subst ','\'',$(GIT_USER_AGENT_CQ))
+GIT-USER-AGENT: FORCE
+ @if test x'$(GIT_USER_AGENT_SQ)' != x"`cat GIT-USER-AGENT 2>/dev/null`"; then \
+ echo '$(GIT_USER_AGENT_SQ)' >GIT-USER-AGENT; \
+ fi
+
+ifdef DEFAULT_HELP_FORMAT
+BASIC_CFLAGS += -DDEFAULT_HELP_FORMAT='"$(DEFAULT_HELP_FORMAT)"'
+endif
+
ALL_CFLAGS += $(BASIC_CFLAGS)
ALL_LDFLAGS += $(BASIC_LDFLAGS)
strip: $(PROGRAMS) git$X
$(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X
-git.o: common-cmds.h
-git.sp git.s git.o: EXTRA_CPPFLAGS = -DGIT_VERSION='"$(GIT_VERSION)"' \
+### Target-specific flags and dependencies
+
+# The generic compilation pattern rule and automatically
+# computed header dependencies (falling back to a dependency on
+# LIB_H) are enough to describe how most targets should be built,
+# but some targets are special enough to need something a little
+# different.
+#
+# - When a source file "foo.c" #includes a generated header file,
+# we need to list that dependency for the "foo.o" target.
+#
+# We also list it from other targets that are built from foo.c
+# like "foo.sp" and "foo.s", even though that is easy to forget
+# to do because the generated header is already present around
+# after a regular build attempt.
+#
+# - Some code depends on configuration kept in makefile
+# variables. The target-specific variable EXTRA_CPPFLAGS can
+# be used to convey that information to the C preprocessor
+# using -D options.
+#
+# The "foo.o" target should have a corresponding dependency on
+# a file that changes when the value of the makefile variable
+# changes. For example, targets making use of the
+# $(GIT_VERSION) variable depend on GIT-VERSION-FILE.
+#
+# Technically the ".sp" and ".s" targets do not need this
+# dependency because they are force-built, but they get the
+# same dependency for consistency. This way, you do not have to
+# know how each target is implemented. And it means the
+# dependencies here will not need to change if the force-build
+# details change some day.
+
+git.sp git.s git.o: GIT-PREFIX
+git.sp git.s git.o: EXTRA_CPPFLAGS = \
'-DGIT_HTML_PATH="$(htmldir_SQ)"' \
'-DGIT_MAN_PATH="$(mandir_SQ)"' \
'-DGIT_INFO_PATH="$(infodir_SQ)"'
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
-help.sp help.o: common-cmds.h
+help.sp help.s help.o: common-cmds.h
-builtin/help.sp builtin/help.o: common-cmds.h
+builtin/help.sp builtin/help.s builtin/help.o: common-cmds.h GIT-PREFIX
builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \
'-DGIT_HTML_PATH="$(htmldir_SQ)"' \
'-DGIT_MAN_PATH="$(mandir_SQ)"' \
'-DGIT_INFO_PATH="$(infodir_SQ)"'
+version.sp version.s version.o: GIT-VERSION-FILE GIT-USER-AGENT
+version.sp version.s version.o: EXTRA_CPPFLAGS = \
+ '-DGIT_VERSION="$(GIT_VERSION)"' \
+ '-DGIT_USER_AGENT=$(GIT_USER_AGENT_CQ_SQ)'
+
$(BUILT_INS): git$X
$(QUIET_BUILT_IN)$(RM) $@ && \
ln git$X $@ 2>/dev/null || \
common-cmds.h: $(wildcard Documentation/git-*.txt)
$(QUIET_GEN)./generate-cmdlist.sh > $@+ && mv $@+ $@
+SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\
+ $(localedir_SQ):$(NO_CURL):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\
+ $(gitwebdir_SQ):$(PERL_PATH_SQ)
define cmd_munge_script
$(RM) $@ $@+ && \
sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \
-e 's|@@DIFF@@|$(DIFF_SQ)|' \
- -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
-e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' \
-e 's/@@NO_CURL@@/$(NO_CURL)/g' \
-e 's/@@USE_GETTEXT_SCHEME@@/$(USE_GETTEXT_SCHEME)/g' \
-e $(BROKEN_PATH_FIX) \
+ -e 's|@@GITWEBDIR@@|$(gitwebdir_SQ)|g' \
+ -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \
$@.sh >$@+
endef
-$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
+GIT-SCRIPT-DEFINES: FORCE
+ @FLAGS='$(SCRIPT_DEFINES)'; \
+ if test x"$$FLAGS" != x"`cat $@ 2>/dev/null`" ; then \
+ echo 1>&2 " * new script parameters"; \
+ echo "$$FLAGS" >$@; \
+ fi
+
+
+$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh GIT-SCRIPT-DEFINES
$(QUIET_GEN)$(cmd_munge_script) && \
chmod +x $@+ && \
mv $@+ $@
-$(SCRIPT_LIB) : % : %.sh
+$(SCRIPT_LIB) : % : %.sh GIT-SCRIPT-DEFINES
$(QUIET_GEN)$(cmd_munge_script) && \
mv $@+ $@
ifndef NO_PERL
$(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak
-perl/perl.mak: GIT-CFLAGS perl/Makefile perl/Makefile.PL
+perl/perl.mak: GIT-CFLAGS GIT-PREFIX perl/Makefile perl/Makefile.PL
$(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F)
-$(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
+$(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl GIT-VERSION-FILE
$(QUIET_GEN)$(RM) $@ $@+ && \
INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \
sed -e '1{' \
gitweb:
$(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) all
-git-instaweb: git-instaweb.sh gitweb
- $(QUIET_GEN)$(RM) $@ $@+ && \
- sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
- -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
- -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
- -e 's|@@GITWEBDIR@@|$(gitwebdir_SQ)|g' \
- -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \
- $@.sh > $@+ && \
+git-instaweb: git-instaweb.sh gitweb GIT-SCRIPT-DEFINES
+ $(QUIET_GEN)$(cmd_munge_script) && \
chmod +x $@+ && \
mv $@+ $@
else # NO_PERL
endif # NO_PERL
ifndef NO_PYTHON
-$(patsubst %.py,%,$(SCRIPT_PYTHON)): GIT-CFLAGS
+$(patsubst %.py,%,$(SCRIPT_PYTHON)): GIT-CFLAGS GIT-PREFIX
$(patsubst %.py,%,$(SCRIPT_PYTHON)): % : %.py
$(QUIET_GEN)$(RM) $@ $@+ && \
INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C git_remote_helpers -s \
mv $@+ $@
endif # NO_PYTHON
-configure: configure.ac
+configure: configure.ac GIT-VERSION-FILE
$(QUIET_GEN)$(RM) $@ $<+ && \
sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
$< > $<+ && \
autoconf -o $@ $<+ && \
$(RM) $<+
-# These can record GIT_VERSION
-git.o git.spec http.o \
- $(patsubst %.sh,%,$(SCRIPT_SH)) \
- $(patsubst %.perl,%,$(SCRIPT_PERL)) \
- : GIT-VERSION-FILE
-
-TEST_OBJS := $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS))
-GIT_OBJS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \
- git.o
-ifndef NO_CURL
- GIT_OBJS += http.o http-walker.o remote-curl.o
-endif
-
XDIFF_OBJS += xdiff/xdiffi.o
XDIFF_OBJS += xdiff/xprepare.o
XDIFF_OBJS += xdiff/xutils.o
VCSSVN_OBJS += vcs-svn/svndiff.o
VCSSVN_OBJS += vcs-svn/svndump.o
-VCSSVN_TEST_OBJS += test-line-buffer.o
-
-OBJECTS := $(GIT_OBJS) $(XDIFF_OBJS) $(VCSSVN_OBJS)
+TEST_OBJS := $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS))
+OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \
+ $(XDIFF_OBJS) \
+ $(VCSSVN_OBJS) \
+ git.o
+ifndef NO_CURL
+ OBJECTS += http.o http-walker.o remote-curl.o
+endif
dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d)
dep_dirs := $(addsuffix .depend,$(sort $(dir $(OBJECTS))))
# Dependencies on automatically generated headers such as common-cmds.h
# should _not_ be included here, since they are necessary even when
# building an object for the first time.
-#
-# XXX. Please check occasionally that these include all dependencies
-# gcc detects!
-
-$(GIT_OBJS): $(LIB_H)
-builtin/branch.o builtin/checkout.o builtin/clone.o builtin/reset.o branch.o transport.o: branch.h
-builtin/bundle.o bundle.o transport.o: bundle.h
-builtin/bisect--helper.o builtin/rev-list.o bisect.o: bisect.h
-builtin/clone.o builtin/fetch-pack.o transport.o: fetch-pack.h
-builtin/index-pack.o builtin/grep.o builtin/pack-objects.o transport-helper.o thread-utils.o: thread-utils.h
-builtin/send-pack.o transport.o: send-pack.h
-builtin/log.o builtin/shortlog.o: shortlog.h
-builtin/prune.o builtin/reflog.o reachable.o: reachable.h
-builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
-builtin/tar-tree.o archive-tar.o: tar.h
-connect.o transport.o url.o http-backend.o: url.h
-builtin/branch.o builtin/commit.o builtin/tag.o column.o help.o pager.o: column.h
-http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
-http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
-
-xdiff-interface.o $(XDIFF_OBJS): $(XDIFF_H)
-$(VCSSVN_OBJS) $(VCSSVN_TEST_OBJS): $(LIB_H) $(VCSSVN_H)
+$(OBJECTS): $(LIB_H)
endif
+exec_cmd.sp exec_cmd.s exec_cmd.o: GIT-PREFIX
exec_cmd.sp exec_cmd.s exec_cmd.o: EXTRA_CPPFLAGS = \
'-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \
'-DBINDIR="$(bindir_relative_SQ)"' \
'-DPREFIX="$(prefix_SQ)"'
+builtin/init-db.sp builtin/init-db.s builtin/init-db.o: GIT-PREFIX
builtin/init-db.sp builtin/init-db.s builtin/init-db.o: EXTRA_CPPFLAGS = \
-DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"'
+config.sp config.s config.o: GIT-PREFIX
config.sp config.s config.o: EXTRA_CPPFLAGS = \
-DETC_GITCONFIG='"$(ETC_GITCONFIG_SQ)"'
+attr.sp attr.s attr.o: GIT-PREFIX
attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \
-DETC_GITATTRIBUTES='"$(ETC_GITATTRIBUTES_SQ)"'
+gettext.sp gettext.s gettext.o: GIT-PREFIX
gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \
-DGIT_LOCALE_PATH='"$(localedir_SQ)"'
-http.sp http.s http.o: EXTRA_CPPFLAGS = \
- -DGIT_HTTP_USER_AGENT='"git/$(GIT_VERSION)"'
-
ifdef NO_EXPAT
http-walker.sp http-walker.s http-walker.o: EXTRA_CPPFLAGS = -DNO_EXPAT
endif
--keyword=_ --keyword=N_ --keyword="Q_:1,2"
XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell
XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl
-LOCALIZED_C := $(C_OBJ:o=c) $(LIB_H) $(XDIFF_H) $(VCSSVN_H) $(MISC_H)
+LOCALIZED_C := $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)
LOCALIZED_SH := $(SCRIPT_SH)
LOCALIZED_PERL := $(SCRIPT_PERL)
$(FIND_SOURCE_FILES) | xargs cscope -b
### Detect prefix changes
-TRACK_CFLAGS = $(CC):$(subst ','\'',$(ALL_CFLAGS)):\
- $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ):\
- $(localedir_SQ):$(USE_GETTEXT_SCHEME)
+TRACK_PREFIX = $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ):\
+ $(localedir_SQ)
+
+GIT-PREFIX: FORCE
+ @FLAGS='$(TRACK_PREFIX)'; \
+ if test x"$$FLAGS" != x"`cat GIT-PREFIX 2>/dev/null`" ; then \
+ echo 1>&2 " * new prefix flags"; \
+ echo "$$FLAGS" >GIT-PREFIX; \
+ fi
+
+TRACK_CFLAGS = $(CC):$(subst ','\'',$(ALL_CFLAGS)):$(USE_GETTEXT_SCHEME)
GIT-CFLAGS: FORCE
@FLAGS='$(TRACK_CFLAGS)'; \
if test x"$$FLAGS" != x"`cat GIT-CFLAGS 2>/dev/null`" ; then \
- echo 1>&2 " * new build flags or prefix"; \
+ echo 1>&2 " * new build flags"; \
echo "$$FLAGS" >GIT-CFLAGS; \
fi
### Maintainer's dist rules
-git.spec: git.spec.in
+git.spec: git.spec.in GIT-VERSION-FILE
sed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@+
mv $@+ $@
$(MAKE) -C git-gui clean
endif
$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-GUI-VARS GIT-BUILD-OPTIONS
+ $(RM) GIT-USER-AGENT GIT-PREFIX GIT-SCRIPT-DEFINES
.PHONY: all install profile-clean clean strip
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
-Documentation/RelNotes/1.7.11.txt
\ No newline at end of file
+Documentation/RelNotes/1.7.12.txt
\ No newline at end of file
static unsigned int ustar_header_chksum(const struct ustar_header *header)
{
- const char *p = (const char *)header;
+ const unsigned char *p = (const unsigned char *)header;
unsigned int chksum = 0;
- while (p < header->chksum)
+ while (p < (const unsigned char *)header->chksum)
chksum += *p++;
chksum += sizeof(header->chksum) * ' ';
p += sizeof(header->chksum);
- while (p < (const char *)header + sizeof(struct ustar_header))
+ while (p < (const unsigned char *)header + sizeof(struct ustar_header))
chksum += *p++;
return chksum;
}
static void bootstrap_attr_stack(void)
{
struct attr_stack *elem;
+ char *xdg_attributes_file;
if (attr_stack)
return;
}
}
- if (git_attributes_file) {
- elem = read_attr_from_file(git_attributes_file, 1);
- if (elem) {
- elem->origin = NULL;
- elem->prev = attr_stack;
- attr_stack = elem;
- }
+ if (!git_attributes_file) {
+ home_config_paths(NULL, &xdg_attributes_file, "attributes");
+ git_attributes_file = xdg_attributes_file;
+ }
+ elem = read_attr_from_file(git_attributes_file, 1);
+ if (elem) {
+ elem->origin = NULL;
+ elem->prev = attr_stack;
+ attr_stack = elem;
}
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
strbuf_addf(&key, "branch.%s.rebase", local);
git_config_set(key.buf, "true");
}
+ strbuf_release(&key);
if (flag & BRANCH_CONFIG_VERBOSE) {
- strbuf_reset(&key);
-
- strbuf_addstr(&key, origin ? "remote" : "local");
-
- /* Are we tracking a proper "branch"? */
- if (remote_is_branch) {
- strbuf_addf(&key, " branch %s", shortname);
- if (origin)
- strbuf_addf(&key, " from %s", origin);
- }
+ if (remote_is_branch && origin)
+ printf(rebasing ?
+ "Branch %s set up to track remote branch %s from %s by rebasing.\n" :
+ "Branch %s set up to track remote branch %s from %s.\n",
+ local, shortname, origin);
+ else if (remote_is_branch && !origin)
+ printf(rebasing ?
+ "Branch %s set up to track local branch %s by rebasing.\n" :
+ "Branch %s set up to track local branch %s.\n",
+ local, shortname);
+ else if (!remote_is_branch && origin)
+ printf(rebasing ?
+ "Branch %s set up to track remote ref %s by rebasing.\n" :
+ "Branch %s set up to track remote ref %s.\n",
+ local, remote);
+ else if (!remote_is_branch && !origin)
+ printf(rebasing ?
+ "Branch %s set up to track local ref %s by rebasing.\n" :
+ "Branch %s set up to track local ref %s.\n",
+ local, remote);
else
- strbuf_addf(&key, " ref %s", remote);
- printf("Branch %s set up to track %s%s.\n",
- local, key.buf,
- rebasing ? " by rebasing" : "");
+ die("BUG: impossible combination of %d and %p",
+ remote_is_branch, origin);
}
- strbuf_release(&key);
}
/*
#define DEFAULT_MERGE_LOG_LEN 20
-extern const char git_version_string[];
extern const char git_usage_string[];
extern const char git_more_info_string[];
void finish_copy_notes_for_rewrite(struct notes_rewrite_cfg *c);
extern int check_pager_config(const char *cmd);
+struct diff_options;
+extern void setup_diff_pager(struct diff_options *);
extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, char **buf, unsigned long *buf_size);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
extern int cmd_config(int argc, const char **argv, const char *prefix);
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
+extern int cmd_credential(int argc, const char **argv, const char *prefix);
extern int cmd_describe(int argc, const char **argv, const char *prefix);
extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
extern int cmd_diff_index(int argc, const char **argv, const char *prefix);
extern int cmd_grep(int argc, const char **argv, const char *prefix);
extern int cmd_hash_object(int argc, const char **argv, const char *prefix);
extern int cmd_help(int argc, const char **argv, const char *prefix);
-extern int cmd_http_fetch(int argc, const char **argv, const char *prefix);
extern int cmd_index_pack(int argc, const char **argv, const char *prefix);
extern int cmd_init_db(int argc, const char **argv, const char *prefix);
extern int cmd_log(int argc, const char **argv, const char *prefix);
extern int cmd_pack_objects(int argc, const char **argv, const char *prefix);
extern int cmd_pack_redundant(int argc, const char **argv, const char *prefix);
extern int cmd_patch_id(int argc, const char **argv, const char *prefix);
-extern int cmd_pickaxe(int argc, const char **argv, const char *prefix);
extern int cmd_prune(int argc, const char **argv, const char *prefix);
extern int cmd_prune_packed(int argc, const char **argv, const char *prefix);
extern int cmd_push(int argc, const char **argv, const char *prefix);
extern int cmd_update_server_info(int argc, const char **argv, const char *prefix);
extern int cmd_upload_archive(int argc, const char **argv, const char *prefix);
extern int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix);
-extern int cmd_upload_tar(int argc, const char **argv, const char *prefix);
extern int cmd_var(int argc, const char **argv, const char *prefix);
extern int cmd_verify_tag(int argc, const char **argv, const char *prefix);
extern int cmd_version(int argc, const char **argv, const char *prefix);
argc = setup_revisions(argc, argv, &rev, NULL);
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
- out = open(file, O_CREAT | O_WRONLY, 0644);
+ out = open(file, O_CREAT | O_WRONLY, 0666);
if (out < 0)
die (_("Could not open '%s' for writing."), file);
rev.diffopt.file = xfdopen(out, "w");
if (pathspec) {
int i;
+ struct path_exclude_check check;
+
+ path_exclude_check_init(&check, &dir);
if (!seen)
seen = find_used_pathspec(pathspec);
for (i = 0; pathspec[i]; i++) {
&& !file_exists(pathspec[i])) {
if (ignore_missing) {
int dtype = DT_UNKNOWN;
- if (excluded(&dir, pathspec[i], &dtype))
+ if (path_excluded(&check, pathspec[i], -1, &dtype))
dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
} else
die(_("pathspec '%s' did not match any files"),
}
}
free(seen);
+ path_exclude_check_clear(&check);
}
plug_bulk_checkin();
#include "dir.h"
#include "diff.h"
#include "parse-options.h"
+#include "xdiff-interface.h"
+#include "ll-merge.h"
+#include "rerere.h"
/*
* --check turns on checking that the working tree matches the
static int apply_verbosely;
static int allow_overlap;
static int no_add;
+static int threeway;
static const char *fake_ancestor;
static int line_termination = '\n';
static unsigned int p_context = UINT_MAX;
unsigned int is_copy:1;
unsigned int is_rename:1;
unsigned int recount:1;
+ unsigned int conflicted_threeway:1;
+ unsigned int direct_to_threeway:1;
struct fragment *fragments;
char *result;
size_t resultsize;
char old_sha1_prefix[41];
char new_sha1_prefix[41];
struct patch *next;
+
+ /* three-way fallback result */
+ unsigned char threeway_stage[3][20];
};
static void free_fragment_list(struct fragment *list)
static void clear_image(struct image *image)
{
free(image->buf);
- image->buf = NULL;
- image->len = 0;
+ free(image->line_allocated);
+ memset(image, 0, sizeof(*image));
}
/* fmt must contain _one_ %s and no other substitution */
return 0;
}
-static int read_file_or_gitlink(struct cache_entry *ce, struct strbuf *buf)
+static int read_blob_object(struct strbuf *buf, const unsigned char *sha1, unsigned mode)
{
- if (!ce)
- return 0;
-
- if (S_ISGITLINK(ce->ce_mode)) {
+ if (S_ISGITLINK(mode)) {
strbuf_grow(buf, 100);
- strbuf_addf(buf, "Subproject commit %s\n", sha1_to_hex(ce->sha1));
+ strbuf_addf(buf, "Subproject commit %s\n", sha1_to_hex(sha1));
} else {
enum object_type type;
unsigned long sz;
char *result;
- result = read_sha1_file(ce->sha1, &type, &sz);
+ result = read_sha1_file(sha1, &type, &sz);
if (!result)
return -1;
/* XXX read_sha1_file NUL-terminates */
return 0;
}
+static int read_file_or_gitlink(struct cache_entry *ce, struct strbuf *buf)
+{
+ if (!ce)
+ return 0;
+ return read_blob_object(buf, ce->sha1, ce->ce_mode);
+}
+
static struct patch *in_fn_table(const char *name)
{
struct string_list_item *item;
* item->util in the filename table records the status of the path.
* Usually it points at a patch (whose result records the contents
* of it after applying it), but it could be PATH_WAS_DELETED for a
- * path that a previously applied patch has already removed.
+ * path that a previously applied patch has already removed, or
+ * PATH_TO_BE_DELETED for a path that a later patch would remove.
+ *
+ * The latter is needed to deal with a case where two paths A and B
+ * are swapped by first renaming A to B and then renaming B to A;
+ * moving A to B should not be prevented due to presense of B as we
+ * will remove it in a later patch.
*/
- #define PATH_TO_BE_DELETED ((struct patch *) -2)
+#define PATH_TO_BE_DELETED ((struct patch *) -2)
#define PATH_WAS_DELETED ((struct patch *) -1)
static int to_be_deleted(struct patch *patch)
}
}
-static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *ce)
+static int checkout_target(struct cache_entry *ce, struct stat *st)
+{
+ struct checkout costate;
+
+ memset(&costate, 0, sizeof(costate));
+ costate.base_dir = "";
+ costate.refresh_cache = 1;
+ if (checkout_entry(ce, &costate, NULL) || lstat(ce->name, st))
+ return error(_("cannot checkout %s"), ce->name);
+ return 0;
+}
+
+static struct patch *previous_patch(struct patch *patch, int *gone)
+{
+ struct patch *previous;
+
+ *gone = 0;
+ if (patch->is_copy || patch->is_rename)
+ return NULL; /* "git" patches do not depend on the order */
+
+ previous = in_fn_table(patch->old_name);
+ if (!previous)
+ return NULL;
+
+ if (to_be_deleted(previous))
+ return NULL; /* the deletion hasn't happened yet */
+
+ if (was_deleted(previous))
+ *gone = 1;
+
+ return previous;
+}
+
+static int verify_index_match(struct cache_entry *ce, struct stat *st)
+{
+ if (S_ISGITLINK(ce->ce_mode)) {
+ if (!S_ISDIR(st->st_mode))
+ return -1;
+ return 0;
+ }
+ return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
+}
+
+#define SUBMODULE_PATCH_WITHOUT_INDEX 1
+
+static int load_patch_target(struct strbuf *buf,
+ struct cache_entry *ce,
+ struct stat *st,
+ const char *name,
+ unsigned expected_mode)
+{
+ if (cached) {
+ if (read_file_or_gitlink(ce, buf))
+ return error(_("read of %s failed"), name);
+ } else if (name) {
+ if (S_ISGITLINK(expected_mode)) {
+ if (ce)
+ return read_file_or_gitlink(ce, buf);
+ else
+ return SUBMODULE_PATCH_WITHOUT_INDEX;
+ } else {
+ if (read_old_data(st, name, buf))
+ return error(_("read of %s failed"), name);
+ }
+ }
+ return 0;
+}
+
+/*
+ * We are about to apply "patch"; populate the "image" with the
+ * current version we have, from the working tree or from the index,
+ * depending on the situation e.g. --cached/--index. If we are
+ * applying a non-git patch that incrementally updates the tree,
+ * we read from the result of a previous diff.
+ */
+static int load_preimage(struct image *image,
+ struct patch *patch, struct stat *st, struct cache_entry *ce)
{
struct strbuf buf = STRBUF_INIT;
- struct image image;
size_t len;
char *img;
- struct patch *tpatch;
+ struct patch *previous;
+ int status;
- if (!(patch->is_copy || patch->is_rename) &&
- (tpatch = in_fn_table(patch->old_name)) != NULL && !to_be_deleted(tpatch)) {
- if (was_deleted(tpatch)) {
- return error(_("patch %s has been renamed/deleted"),
- patch->old_name);
- }
+ previous = previous_patch(patch, &status);
+ if (status)
+ return error(_("path %s has been renamed/deleted"),
+ patch->old_name);
+ if (previous) {
/* We have a patched copy in memory; use that. */
- strbuf_add(&buf, tpatch->result, tpatch->resultsize);
- } else if (cached) {
- if (read_file_or_gitlink(ce, &buf))
+ strbuf_add(&buf, previous->result, previous->resultsize);
+ } else {
+ status = load_patch_target(&buf, ce, st,
+ patch->old_name, patch->old_mode);
+ if (status < 0)
+ return status;
+ else if (status == SUBMODULE_PATCH_WITHOUT_INDEX) {
+ /*
+ * There is no way to apply subproject
+ * patch without looking at the index.
+ * NEEDSWORK: shouldn't this be flagged
+ * as an error???
+ */
+ free_fragment_list(patch->fragments);
+ patch->fragments = NULL;
+ } else if (status) {
return error(_("read of %s failed"), patch->old_name);
- } else if (patch->old_name) {
- if (S_ISGITLINK(patch->old_mode)) {
- if (ce) {
- read_file_or_gitlink(ce, &buf);
- } else {
- /*
- * There is no way to apply subproject
- * patch without looking at the index.
- * NEEDSWORK: shouldn't this be flagged
- * as an error???
- */
- free_fragment_list(patch->fragments);
- patch->fragments = NULL;
- }
- } else {
- if (read_old_data(st, patch->old_name, &buf))
- return error(_("read of %s failed"), patch->old_name);
}
}
img = strbuf_detach(&buf, &len);
- prepare_image(&image, img, len, !patch->is_binary);
+ prepare_image(image, img, len, !patch->is_binary);
+ return 0;
+}
- if (apply_fragments(&image, patch) < 0)
- return -1; /* note with --reject this succeeds. */
- patch->result = image.buf;
- patch->resultsize = image.len;
- add_to_fn_table(patch);
- free(image.line_allocated);
+static int three_way_merge(struct image *image,
+ char *path,
+ const unsigned char *base,
+ const unsigned char *ours,
+ const unsigned char *theirs)
+{
+ mmfile_t base_file, our_file, their_file;
+ mmbuffer_t result = { NULL };
+ int status;
- if (0 < patch->is_delete && patch->resultsize)
- return error(_("removal patch leaves file contents"));
+ read_mmblob(&base_file, base);
+ read_mmblob(&our_file, ours);
+ read_mmblob(&their_file, theirs);
+ status = ll_merge(&result, path,
+ &base_file, "base",
+ &our_file, "ours",
+ &their_file, "theirs", NULL);
+ free(base_file.ptr);
+ free(our_file.ptr);
+ free(their_file.ptr);
+ if (status < 0 || !result.ptr) {
+ free(result.ptr);
+ return -1;
+ }
+ clear_image(image);
+ image->buf = result.ptr;
+ image->len = result.size;
+ return status;
+}
+
+/*
+ * When directly falling back to add/add three-way merge, we read from
+ * the current contents of the new_name. In no cases other than that
+ * this function will be called.
+ */
+static int load_current(struct image *image, struct patch *patch)
+{
+ struct strbuf buf = STRBUF_INIT;
+ int status, pos;
+ size_t len;
+ char *img;
+ struct stat st;
+ struct cache_entry *ce;
+ char *name = patch->new_name;
+ unsigned mode = patch->new_mode;
+
+ if (!patch->is_new)
+ die("BUG: patch to %s is not a creation", patch->old_name);
+
+ pos = cache_name_pos(name, strlen(name));
+ if (pos < 0)
+ return error(_("%s: does not exist in index"), name);
+ ce = active_cache[pos];
+ if (lstat(name, &st)) {
+ if (errno != ENOENT)
+ return error(_("%s: %s"), name, strerror(errno));
+ if (checkout_target(ce, &st))
+ return -1;
+ }
+ if (verify_index_match(ce, &st))
+ return error(_("%s: does not match index"), name);
+
+ status = load_patch_target(&buf, ce, &st, name, mode);
+ if (status < 0)
+ return status;
+ else if (status)
+ return -1;
+ img = strbuf_detach(&buf, &len);
+ prepare_image(image, img, len, !patch->is_binary);
return 0;
}
-static int check_to_create_blob(const char *new_name, int ok_if_exists)
+static int try_threeway(struct image *image, struct patch *patch,
+ struct stat *st, struct cache_entry *ce)
{
- struct stat nst;
- if (!lstat(new_name, &nst)) {
- if (S_ISDIR(nst.st_mode) || ok_if_exists)
- return 0;
- /*
- * A leading component of new_name might be a symlink
- * that is going to be removed with this patch, but
- * still pointing at somewhere that has the path.
- * In such a case, path "new_name" does not exist as
- * far as git is concerned.
- */
- if (has_symlink_leading_path(new_name, strlen(new_name)))
- return 0;
+ unsigned char pre_sha1[20], post_sha1[20], our_sha1[20];
+ struct strbuf buf = STRBUF_INIT;
+ size_t len;
+ int status;
+ char *img;
+ struct image tmp_image;
+
+ /* No point falling back to 3-way merge in these cases */
+ if (patch->is_delete ||
+ S_ISGITLINK(patch->old_mode) || S_ISGITLINK(patch->new_mode))
+ return -1;
- return error(_("%s: already exists in working directory"), new_name);
+ /* Preimage the patch was prepared for */
+ if (patch->is_new)
+ write_sha1_file("", 0, blob_type, pre_sha1);
+ else if (get_sha1(patch->old_sha1_prefix, pre_sha1) ||
+ read_blob_object(&buf, pre_sha1, patch->old_mode))
+ return error("repository lacks the necessary blob to fall back on 3-way merge.");
+
+ fprintf(stderr, "Falling back to three-way merge...\n");
+
+ img = strbuf_detach(&buf, &len);
+ prepare_image(&tmp_image, img, len, 1);
+ /* Apply the patch to get the post image */
+ if (apply_fragments(&tmp_image, patch) < 0) {
+ clear_image(&tmp_image);
+ return -1;
+ }
+ /* post_sha1[] is theirs */
+ write_sha1_file(tmp_image.buf, tmp_image.len, blob_type, post_sha1);
+ clear_image(&tmp_image);
+
+ /* our_sha1[] is ours */
+ if (patch->is_new) {
+ if (load_current(&tmp_image, patch))
+ return error("cannot read the current contents of '%s'",
+ patch->new_name);
+ } else {
+ if (load_preimage(&tmp_image, patch, st, ce))
+ return error("cannot read the current contents of '%s'",
+ patch->old_name);
+ }
+ write_sha1_file(tmp_image.buf, tmp_image.len, blob_type, our_sha1);
+ clear_image(&tmp_image);
+
+ /* in-core three-way merge between post and our using pre as base */
+ status = three_way_merge(image, patch->new_name,
+ pre_sha1, our_sha1, post_sha1);
+ if (status < 0) {
+ fprintf(stderr, "Failed to fall back on three-way merge...\n");
+ return status;
+ }
+
+ if (status) {
+ patch->conflicted_threeway = 1;
+ if (patch->is_new)
+ hashclr(patch->threeway_stage[0]);
+ else
+ hashcpy(patch->threeway_stage[0], pre_sha1);
+ hashcpy(patch->threeway_stage[1], our_sha1);
+ hashcpy(patch->threeway_stage[2], post_sha1);
+ fprintf(stderr, "Applied patch to '%s' with conflicts.\n", patch->new_name);
+ } else {
+ fprintf(stderr, "Applied patch to '%s' cleanly.\n", patch->new_name);
}
- else if ((errno != ENOENT) && (errno != ENOTDIR))
- return error("%s: %s", new_name, strerror(errno));
return 0;
}
-static int verify_index_match(struct cache_entry *ce, struct stat *st)
+static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *ce)
{
- if (S_ISGITLINK(ce->ce_mode)) {
- if (!S_ISDIR(st->st_mode))
+ struct image image;
+
+ if (load_preimage(&image, patch, st, ce) < 0)
+ return -1;
+
+ if (patch->direct_to_threeway ||
+ apply_fragments(&image, patch) < 0) {
+ /* Note: with --reject, apply_fragments() returns 0 */
+ if (!threeway || try_threeway(&image, patch, st, ce) < 0)
return -1;
- return 0;
}
- return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
+ patch->result = image.buf;
+ patch->resultsize = image.len;
+ add_to_fn_table(patch);
+ free(image.line_allocated);
+
+ if (0 < patch->is_delete && patch->resultsize)
+ return error(_("removal patch leaves file contents"));
+
+ return 0;
}
+/*
+ * If "patch" that we are looking at modifies or deletes what we have,
+ * we would want it not to lose any local modification we have, either
+ * in the working tree or in the index.
+ *
+ * This also decides if a non-git patch is a creation patch or a
+ * modification to an existing empty file. We do not check the state
+ * of the current tree for a creation patch in this function; the caller
+ * check_patch() separately makes sure (and errors out otherwise) that
+ * the path the patch creates does not exist in the current tree.
+ */
static int check_preimage(struct patch *patch, struct cache_entry **ce, struct stat *st)
{
const char *old_name = patch->old_name;
- struct patch *tpatch = NULL;
- int stat_ret = 0;
+ struct patch *previous = NULL;
+ int stat_ret = 0, status;
unsigned st_mode = 0;
- /*
- * Make sure that we do not have local modifications from the
- * index when we are looking at the index. Also make sure
- * we have the preimage file to be patched in the work tree,
- * unless --cached, which tells git to apply only in the index.
- */
if (!old_name)
return 0;
assert(patch->is_new <= 0);
+ previous = previous_patch(patch, &status);
- if (!(patch->is_copy || patch->is_rename) &&
- (tpatch = in_fn_table(old_name)) != NULL && !to_be_deleted(tpatch)) {
- if (was_deleted(tpatch))
- return error(_("%s: has been deleted/renamed"), old_name);
- st_mode = tpatch->new_mode;
+ if (status)
+ return error(_("path %s has been renamed/deleted"), old_name);
+ if (previous) {
+ st_mode = previous->new_mode;
} else if (!cached) {
stat_ret = lstat(old_name, st);
if (stat_ret && errno != ENOENT)
return error(_("%s: %s"), old_name, strerror(errno));
}
- if (to_be_deleted(tpatch))
- tpatch = NULL;
-
- if (check_index && !tpatch) {
+ if (check_index && !previous) {
int pos = cache_name_pos(old_name, strlen(old_name));
if (pos < 0) {
if (patch->is_new < 0)
}
*ce = active_cache[pos];
if (stat_ret < 0) {
- struct checkout costate;
- /* checkout */
- memset(&costate, 0, sizeof(costate));
- costate.base_dir = "";
- costate.refresh_cache = 1;
- if (checkout_entry(*ce, &costate, NULL) ||
- lstat(old_name, st))
+ if (checkout_target(*ce, st))
return -1;
}
if (!cached && verify_index_match(*ce, st))
return error(_("%s: %s"), old_name, strerror(errno));
}
- if (!cached && !tpatch)
+ if (!cached && !previous)
st_mode = ce_mode_from_stat(*ce, st->st_mode);
if (patch->is_new < 0)
return 0;
}
+
+#define EXISTS_IN_INDEX 1
+#define EXISTS_IN_WORKTREE 2
+
+static int check_to_create(const char *new_name, int ok_if_exists)
+{
+ struct stat nst;
+
+ if (check_index &&
+ cache_name_pos(new_name, strlen(new_name)) >= 0 &&
+ !ok_if_exists)
+ return EXISTS_IN_INDEX;
+ if (cached)
+ return 0;
+
+ if (!lstat(new_name, &nst)) {
+ if (S_ISDIR(nst.st_mode) || ok_if_exists)
+ return 0;
+ /*
+ * A leading component of new_name might be a symlink
+ * that is going to be removed with this patch, but
+ * still pointing at somewhere that has the path.
+ * In such a case, path "new_name" does not exist as
+ * far as git is concerned.
+ */
+ if (has_symlink_leading_path(new_name, strlen(new_name)))
+ return 0;
+
+ return EXISTS_IN_WORKTREE;
+ } else if ((errno != ENOENT) && (errno != ENOTDIR)) {
+ return error("%s: %s", new_name, strerror(errno));
+ }
+ return 0;
+}
+
/*
* Check and apply the patch in-core; leave the result in patch->result
* for the caller to write it out to the final destination.
return status;
old_name = patch->old_name;
+ /*
+ * A type-change diff is always split into a patch to delete
+ * old, immediately followed by a patch to create new (see
+ * diff.c::run_diff()); in such a case it is Ok that the entry
+ * to be deleted by the previous patch is still in the working
+ * tree and in the index.
+ *
+ * A patch to swap-rename between A and B would first rename A
+ * to B and then rename B to A. While applying the first one,
+ * the presense of B should not stop A from getting renamed to
+ * B; ask to_be_deleted() about the later rename. Removal of
+ * B and rename from A to B is handled the same way by asking
+ * was_deleted().
+ */
if ((tpatch = in_fn_table(new_name)) &&
- (was_deleted(tpatch) || to_be_deleted(tpatch)))
- /*
- * A type-change diff is always split into a patch to
- * delete old, immediately followed by a patch to
- * create new (see diff.c::run_diff()); in such a case
- * it is Ok that the entry to be deleted by the
- * previous patch is still in the working tree and in
- * the index.
- */
+ (was_deleted(tpatch) || to_be_deleted(tpatch)))
ok_if_exists = 1;
else
ok_if_exists = 0;
if (new_name &&
((0 < patch->is_new) | (0 < patch->is_rename) | patch->is_copy)) {
- if (check_index &&
- cache_name_pos(new_name, strlen(new_name)) >= 0 &&
- !ok_if_exists)
+ int err = check_to_create(new_name, ok_if_exists);
+
+ if (err && threeway) {
+ patch->direct_to_threeway = 1;
+ } else switch (err) {
+ case 0:
+ break; /* happy */
+ case EXISTS_IN_INDEX:
return error(_("%s: already exists in index"), new_name);
- if (!cached) {
- int err = check_to_create_blob(new_name, ok_if_exists);
- if (err)
- return err;
+ break;
+ case EXISTS_IN_WORKTREE:
+ return error(_("%s: already exists in working directory"),
+ new_name);
+ default:
+ return err;
}
+
if (!patch->new_mode) {
if (0 < patch->is_new)
patch->new_mode = S_IFREG | 0644;
name = patch->old_name ? patch->old_name : patch->new_name;
if (0 < patch->is_new)
continue;
- else if (get_sha1(patch->old_sha1_prefix, sha1))
+ else if (get_sha1_blob(patch->old_sha1_prefix, sha1))
/* git diff has no index line for mode/type changes */
if (!patch->lines_added && !patch->lines_deleted) {
if (get_current_sha1(patch->old_name, sha1))
die_errno(_("unable to write file '%s' mode %o"), path, mode);
}
+static void add_conflicted_stages_file(struct patch *patch)
+{
+ int stage, namelen;
+ unsigned ce_size, mode;
+ struct cache_entry *ce;
+
+ if (!update_index)
+ return;
+ namelen = strlen(patch->new_name);
+ ce_size = cache_entry_size(namelen);
+ mode = patch->new_mode ? patch->new_mode : (S_IFREG | 0644);
+
+ remove_file_from_cache(patch->new_name);
+ for (stage = 1; stage < 4; stage++) {
+ if (is_null_sha1(patch->threeway_stage[stage - 1]))
+ continue;
+ ce = xcalloc(1, ce_size);
+ memcpy(ce->name, patch->new_name, namelen);
+ ce->ce_mode = create_ce_mode(mode);
+ ce->ce_flags = create_ce_flags(namelen, stage);
+ hashcpy(ce->sha1, patch->threeway_stage[stage - 1]);
+ if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0)
+ die(_("unable to add cache entry for %s"), patch->new_name);
+ }
+}
+
static void create_file(struct patch *patch)
{
char *path = patch->new_name;
if (!mode)
mode = S_IFREG | 0644;
create_one_file(path, mode, buf, size);
- add_index_file(path, mode, buf, size);
+
+ if (patch->conflicted_threeway)
+ add_conflicted_stages_file(patch);
+ else
+ add_index_file(path, mode, buf, size);
}
/* phase zero is to remove, phase one is to create */
int phase;
int errs = 0;
struct patch *l;
+ struct string_list cpath = STRING_LIST_INIT_DUP;
for (phase = 0; phase < 2; phase++) {
l = list;
errs = 1;
else {
write_out_one_result(l, phase);
- if (phase == 1 && write_out_one_reject(l))
- errs = 1;
+ if (phase == 1) {
+ if (write_out_one_reject(l))
+ errs = 1;
+ if (l->conflicted_threeway) {
+ string_list_append(&cpath, l->new_name);
+ errs = 1;
+ }
+ }
}
l = l->next;
}
}
+
+ if (cpath.nr) {
+ struct string_list_item *item;
+
+ sort_string_list(&cpath);
+ for_each_string_list_item(item, &cpath)
+ fprintf(stderr, "U %s\n", item->string);
+ string_list_clear(&cpath, 0);
+
+ rerere(0);
+ }
+
return errs;
}
!apply_with_reject)
exit(1);
- if (apply && write_out_results(list))
- exit(1);
+ if (apply && write_out_results(list)) {
+ if (apply_with_reject)
+ exit(1);
+ /* with --3way, we still need to write the index out */
+ return 1;
+ }
if (fake_ancestor)
build_fake_ancestor(list, fake_ancestor);
N_("apply a patch without touching the working tree")),
OPT_BOOLEAN(0, "apply", &force_apply,
N_("also apply the patch (use with --stat/--summary/--check)")),
+ OPT_BOOL('3', "3way", &threeway,
+ N_( "attempt three-way merge if a patch does not apply")),
OPT_FILENAME(0, "build-fake-ancestor", &fake_ancestor,
N_("build a temporary index based on embedded index information")),
{ OPTION_CALLBACK, 'z', NULL, NULL, NULL,
argc = parse_options(argc, argv, prefix, builtin_apply_options,
apply_usage, 0);
+ if (apply_with_reject && threeway)
+ die("--reject and --3way cannot be used together.");
+ if (cached && threeway)
+ die("--cached and --3way cannot be used together.");
+ if (threeway) {
+ if (is_not_gitdir)
+ die(_("--3way outside a repository"));
+ check_index = 1;
+ }
if (apply_with_reject)
apply = apply_verbosely = 1;
if (!force_apply && (diffstat || numstat || summary || check || fake_ancestor))
return 0;
}
+static int update_auto_abbrev(int auto_abbrev, struct origin *suspect)
+{
+ const char *uniq = find_unique_abbrev(suspect->commit->object.sha1,
+ auto_abbrev);
+ int len = strlen(uniq);
+ if (auto_abbrev < len)
+ return len;
+ return auto_abbrev;
+}
+
/*
* How many columns do we need to show line numbers, authors,
* and filenames?
int longest_dst_lines = 0;
unsigned largest_score = 0;
struct blame_entry *e;
+ int compute_auto_abbrev = (abbrev < 0);
+ int auto_abbrev = default_abbrev;
for (e = sb->ent; e; e = e->next) {
struct origin *suspect = e->suspect;
struct commit_info ci;
int num;
+ if (compute_auto_abbrev)
+ auto_abbrev = update_auto_abbrev(auto_abbrev, suspect);
if (strcmp(suspect->path, sb->path))
*option |= OUTPUT_SHOW_NAME;
num = strlen(suspect->path);
max_orig_digits = decimal_width(longest_src_lines);
max_digits = decimal_width(longest_dst_lines);
max_score_digits = decimal_width(largest_score);
+
+ if (compute_auto_abbrev)
+ /* one more abbrev length is needed for the boundary commit */
+ abbrev = auto_abbrev + 1;
}
/*
parse_done:
argc = parse_options_end(&ctx);
- if (abbrev == -1)
- abbrev = default_abbrev;
- /* one more abbrev length is needed for the boundary commit */
- abbrev++;
+ if (0 < abbrev)
+ /* one more abbrev length is needed for the boundary commit */
+ abbrev++;
if (revs_file && read_ancestry(revs_file))
die_errno("reading graft file '%s' failed", revs_file);
unsigned long size;
struct object_context obj_context;
- if (get_sha1_with_context(obj_name, sha1, &obj_context))
+ if (get_sha1_with_context(obj_name, 0, sha1, &obj_context))
die("Not a valid object name %s", obj_name);
buf = NULL;
int status;
struct strbuf branch_ref = STRBUF_INIT;
+ if (!opts->new_branch)
+ die(_("You are on a branch yet to be born"));
strbuf_addf(&branch_ref, "refs/heads/%s", opts->new_branch);
status = create_symref("HEAD", branch_ref.buf, "checkout -b");
strbuf_release(&branch_ref);
};
static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1;
-static int option_local, option_no_hardlinks, option_shared, option_recursive;
+static int option_local = -1, option_no_hardlinks, option_shared, option_recursive;
static char *option_template, *option_depth;
static char *option_origin = NULL;
static char *option_branch = NULL;
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
OPT_BOOLEAN(0, "mirror", &option_mirror,
"create a mirror repository (implies bare)"),
- OPT_BOOLEAN('l', "local", &option_local,
- "to clone from a local repository"),
+ OPT_BOOL('l', "local", &option_local,
+ "to clone from a local repository"),
OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks,
"don't use local hardlinks, always copy"),
OPT_BOOLEAN('s', "shared", &option_shared,
if (!option_no_hardlinks) {
if (!link(src->buf, dest->buf))
continue;
- if (option_local)
+ if (option_local > 0)
die_errno(_("failed to create link '%s'"), dest->buf);
option_no_hardlinks = 1;
}
if (!option_branch)
remote_head = guess_remote_head(head, refs, 0);
- else
- remote_head = find_remote_branch(refs, option_branch);
+ else {
+ local_refs = NULL;
+ tail = &local_refs;
+ remote_head = copy_ref(find_remote_branch(refs, option_branch));
+ }
if (!remote_head && option_branch)
warning(_("Could not find remote branch %s to clone."),
die(_("repository '%s' does not exist"), repo_name);
else
repo = repo_name;
- is_local = path && !is_bundle;
+ is_local = option_local != 0 && path && !is_bundle;
if (is_local && option_depth)
warning(_("--depth is ignored in local clones; use file:// instead."));
if (safe_create_leading_directories_const(work_tree) < 0)
die_errno(_("could not create leading directories of '%s'"),
work_tree);
- if (!dest_exists && mkdir(work_tree, 0755))
+ if (!dest_exists && mkdir(work_tree, 0777))
die_errno(_("could not create work tree dir '%s'."),
work_tree);
set_git_work_tree(work_tree);
if (argc < 2 || !strcmp(argv[1], "-h"))
usage(commit_tree_usage);
- if (get_sha1(argv[1], tree_sha1))
- die("Not a valid object name %s", argv[1]);
+ if (get_sha1_tree(argv[1], tree_sha1))
+ die("Not a valid tree object name %s", argv[1]);
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
unsigned char sha1[20];
if (argc <= ++i)
usage(commit_tree_usage);
- if (get_sha1(argv[i], sha1))
+ if (get_sha1_commit(argv[i], sha1))
die("Not a valid object name %s", argv[i]);
assert_sha1_type(sha1, OBJ_COMMIT);
new_parent(lookup_commit(sha1), &parents);
continue;
}
- if (get_sha1(arg, tree_sha1))
+ if (get_sha1_tree(arg, tree_sha1))
die("Not a valid object name %s", arg);
if (got_tree)
die("Cannot give more than one trees");
int i;
char *m;
+ if (!pattern)
+ return 0;
+
for (i = 0; pattern[i]; i++)
;
m = xcalloc(1, i);
* and create commit from the_index.
* We still need to refresh the index here.
*/
- if (!pathspec || !*pathspec) {
+ if (!only && (!pathspec || !*pathspec)) {
fd = hold_locked_index(&index_lock, 1);
refresh_cache_or_die(refresh_flags);
if (active_cache_changed) {
hook_arg1 = "message";
} else if (use_message) {
buffer = strstr(use_message_buffer, "\n\n");
- if (!buffer || buffer[2] == '\0')
+ if (!use_editor && (!buffer || buffer[2] == '\0'))
die(_("commit has empty message"));
strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
hook_arg1 = "commit";
static int get_value(const char *key_, const char *regex_)
{
int ret = -1;
- char *global = NULL, *repo_config = NULL;
+ char *global = NULL, *xdg = NULL, *repo_config = NULL;
const char *system_wide = NULL, *local;
struct config_include_data inc = CONFIG_INCLUDE_INIT;
config_fn_t fn;
local = given_config_file;
if (!local) {
- const char *home = getenv("HOME");
local = repo_config = git_pathdup("config");
- if (home)
- global = xstrdup(mkpath("%s/.gitconfig", home));
if (git_config_system())
system_wide = git_etc_gitconfig();
+ home_config_paths(&global, &xdg, "config");
}
if (use_key_regexp) {
if (do_all && system_wide)
git_config_from_file(fn, system_wide, data);
+ if (do_all && xdg)
+ git_config_from_file(fn, xdg, data);
if (do_all && global)
git_config_from_file(fn, global, data);
if (do_all)
git_config_from_file(fn, local, data);
if (!do_all && !seen && global)
git_config_from_file(fn, global, data);
+ if (!do_all && !seen && xdg)
+ git_config_from_file(fn, xdg, data);
if (!do_all && !seen && system_wide)
git_config_from_file(fn, system_wide, data);
free_strings:
free(repo_config);
free(global);
+ free(xdg);
return ret;
}
}
if (use_global_config) {
- char *home = getenv("HOME");
- if (home) {
- char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
+ char *user_config = NULL;
+ char *xdg_config = NULL;
+
+ home_config_paths(&user_config, &xdg_config, "config");
+
+ if (access(user_config, R_OK) && !access(xdg_config, R_OK))
+ given_config_file = xdg_config;
+ else if (user_config)
given_config_file = user_config;
- } else {
+ else
die("$HOME not set");
- }
}
else if (use_system_config)
given_config_file = git_etc_gitconfig();
--- /dev/null
+#include "git-compat-util.h"
+#include "credential.h"
+#include "builtin.h"
+
+static const char usage_msg[] =
+ "git credential [fill|approve|reject]";
+
+int cmd_credential(int argc, const char **argv, const char *prefix)
+{
+ const char *op;
+ struct credential c = CREDENTIAL_INIT;
+
+ op = argv[1];
+ if (!op)
+ usage(usage_msg);
+
+ if (credential_read(&c, stdin) < 0)
+ die("unable to read credential from stdin");
+
+ if (!strcmp(op, "fill")) {
+ credential_fill(&c);
+ credential_write(&c, stdout);
+ } else if (!strcmp(op, "approve")) {
+ credential_approve(&c);
+ } else if (!strcmp(op, "reject")) {
+ credential_reject(&c);
+ } else {
+ usage(usage_msg);
+ }
+ return 0;
+}
DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
- /*
- * If the user asked for our exit code then don't start a
- * pager or we would end up reporting its exit code instead.
- */
- if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS) &&
- check_pager_config("diff") != 0)
- setup_pager();
+ setup_diff_pager(&rev.diffopt);
/*
* Do we have --cached and not have a pending object, then
refresh_index_quietly();
return result;
}
+
+void setup_diff_pager(struct diff_options *opt)
+{
+ /*
+ * If the user asked for our exit code, then either they want --quiet
+ * or --exit-code. We should definitely not bother with a pager in the
+ * former case, as we will generate no output. Since we still properly
+ * report our exit code even when a pager is run, we _could_ run a
+ * pager with --exit-code. But since we have not done so historically,
+ * and because it is easy to find people oneline advising "git diff
+ * --exit-code" in hooks and other scripts, we do not do so.
+ */
+ if (!DIFF_OPT_TST(opt, EXIT_WITH_STATUS) &&
+ check_pager_config("diff") != 0)
+ setup_pager();
+}
int need_quote = quote_c_style(path, NULL, NULL, 0);
if (need_quote)
quote_c_style(path, NULL, stdout, 0);
+ else if (strchr(path, ' '))
+ printf("\"%s\"", path);
else
printf("%s", path);
}
die ("Could not read blob %s", sha1_to_hex(sha1));
if (object->flags & SHOWN)
- error("Object %s already has a mark", sha1);
+ error("Object %s already has a mark", sha1_to_hex(sha1));
mark_object(object, mark);
if (last_idnum < mark)
const char *me;
if (kind == 'a') {
- label = "\nBy ";
+ label = "\n# By ";
me = git_author_info(IDENT_NO_DATE);
} else {
- label = "\nvia ";
+ label = "\n# Via ";
me = git_committer_info(IDENT_NO_DATE);
}
if (!seen_dashdash) {
int j;
for (j = i; j < argc; j++)
- verify_filename(prefix, argv[j]);
+ verify_filename(prefix, argv[j], j == i);
}
paths = get_pathspec(prefix, argv + i);
#include "column.h"
#include "help.h"
+#ifndef DEFAULT_HELP_FORMAT
+#define DEFAULT_HELP_FORMAT "man"
+#endif
+
static struct man_viewer_list {
struct man_viewer_list *next;
char name[FLEX_ARRAY];
HELP_FORMAT_WEB
};
+static const char *html_path;
+
static int show_all = 0;
static unsigned int colopts;
static enum help_format help_format = HELP_FORMAT_NONE;
help_format = parse_help_format(value);
return 0;
}
+ if (!strcmp(var, "help.htmlpath")) {
+ if (!value)
+ return config_error_nonbool(var);
+ html_path = xstrdup(value);
+ return 0;
+ }
if (!strcmp(var, "man.viewer")) {
if (!value)
return config_error_nonbool(var);
static void get_html_page_path(struct strbuf *page_path, const char *page)
{
struct stat st;
- const char *html_path = system_path(GIT_HTML_PATH);
+ if (!html_path)
+ html_path = system_path(GIT_HTML_PATH);
/* Check that we have a git documentation directory. */
- if (stat(mkpath("%s/git.html", html_path), &st)
- || !S_ISREG(st.st_mode))
- die(_("'%s': not a documentation directory."), html_path);
+ if (!strstr(html_path, "://")) {
+ if (stat(mkpath("%s/git.html", html_path), &st)
+ || !S_ISREG(st.st_mode))
+ die("'%s': not a documentation directory.", html_path);
+ }
strbuf_init(page_path, 0);
strbuf_addf(page_path, "%s/%s.html", html_path, page);
if (parsed_help_format != HELP_FORMAT_NONE)
help_format = parsed_help_format;
+ if (help_format == HELP_FORMAT_NONE)
+ help_format = parse_help_format(DEFAULT_HELP_FORMAT);
alias = alias_lookup(argv[0]);
if (alias && !is_git_command(argv[0])) {
#include "progress.h"
#include "fsck.h"
#include "exec_cmd.h"
+#include "streaming.h"
#include "thread-utils.h"
static const char index_pack_usage[] =
int ofs_first, ofs_last;
};
-#if !defined(NO_PTHREADS) && defined(NO_PREAD)
-/* NO_PREAD uses compat/pread.c, which is not thread-safe. Disable threading. */
+#if !defined(NO_PTHREADS) && defined(NO_THREAD_SAFE_PREAD)
+/* pread() emulation is not thread-safe. Disable threading. */
#define NO_PTHREADS
#endif
free_base_data(c);
}
-static void *unpack_entry_data(unsigned long offset, unsigned long size)
+static int is_delta_type(enum object_type type)
+{
+ return (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA);
+}
+
+static void *unpack_entry_data(unsigned long offset, unsigned long size,
+ enum object_type type, unsigned char *sha1)
{
+ static char fixed_buf[8192];
int status;
git_zstream stream;
- void *buf = xmalloc(size);
+ void *buf;
+ git_SHA_CTX c;
+ char hdr[32];
+ int hdrlen;
+
+ if (!is_delta_type(type)) {
+ hdrlen = sprintf(hdr, "%s %lu", typename(type), size) + 1;
+ git_SHA1_Init(&c);
+ git_SHA1_Update(&c, hdr, hdrlen);
+ } else
+ sha1 = NULL;
+ if (type == OBJ_BLOB && size > big_file_threshold)
+ buf = fixed_buf;
+ else
+ buf = xmalloc(size);
memset(&stream, 0, sizeof(stream));
git_inflate_init(&stream);
stream.next_out = buf;
- stream.avail_out = size;
+ stream.avail_out = buf == fixed_buf ? sizeof(fixed_buf) : size;
do {
+ unsigned char *last_out = stream.next_out;
stream.next_in = fill(1);
stream.avail_in = input_len;
status = git_inflate(&stream, 0);
use(input_len - stream.avail_in);
+ if (sha1)
+ git_SHA1_Update(&c, last_out, stream.next_out - last_out);
+ if (buf == fixed_buf) {
+ stream.next_out = buf;
+ stream.avail_out = sizeof(fixed_buf);
+ }
} while (status == Z_OK);
if (stream.total_out != size || status != Z_STREAM_END)
bad_object(offset, _("inflate returned %d"), status);
git_inflate_end(&stream);
- return buf;
+ if (sha1)
+ git_SHA1_Final(sha1, &c);
+ return buf == fixed_buf ? NULL : buf;
}
-static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_base)
+static void *unpack_raw_entry(struct object_entry *obj,
+ union delta_base *delta_base,
+ unsigned char *sha1)
{
unsigned char *p;
unsigned long size, c;
}
obj->hdr_size = consumed_bytes - obj->idx.offset;
- data = unpack_entry_data(obj->idx.offset, obj->size);
+ data = unpack_entry_data(obj->idx.offset, obj->size, obj->type, sha1);
obj->idx.crc32 = input_crc32;
return data;
}
-static void *get_data_from_pack(struct object_entry *obj)
+static void *unpack_data(struct object_entry *obj,
+ int (*consume)(const unsigned char *, unsigned long, void *),
+ void *cb_data)
{
off_t from = obj[0].idx.offset + obj[0].hdr_size;
unsigned long len = obj[1].idx.offset - from;
git_zstream stream;
int status;
- data = xmalloc(obj->size);
+ data = xmalloc(consume ? 64*1024 : obj->size);
inbuf = xmalloc((len < 64*1024) ? len : 64*1024);
memset(&stream, 0, sizeof(stream));
git_inflate_init(&stream);
stream.next_out = data;
- stream.avail_out = obj->size;
+ stream.avail_out = consume ? 64*1024 : obj->size;
do {
ssize_t n = (len < 64*1024) ? len : 64*1024;
len -= n;
stream.next_in = inbuf;
stream.avail_in = n;
- status = git_inflate(&stream, 0);
+ if (!consume)
+ status = git_inflate(&stream, 0);
+ else {
+ do {
+ status = git_inflate(&stream, 0);
+ if (consume(data, stream.next_out - data, cb_data)) {
+ free(inbuf);
+ free(data);
+ return NULL;
+ }
+ stream.next_out = data;
+ stream.avail_out = 64*1024;
+ } while (status == Z_OK && stream.avail_in);
+ }
} while (len && status == Z_OK && !stream.avail_in);
/* This has been inflated OK when first encountered, so... */
git_inflate_end(&stream);
free(inbuf);
+ if (consume) {
+ free(data);
+ data = NULL;
+ }
return data;
}
+static void *get_data_from_pack(struct object_entry *obj)
+{
+ return unpack_data(obj, NULL, NULL);
+}
+
static int compare_delta_bases(const union delta_base *base1,
const union delta_base *base2,
enum object_type type1,
*last_index = last;
}
-static void sha1_object(const void *data, unsigned long size,
- enum object_type type, unsigned char *sha1)
+struct compare_data {
+ struct object_entry *entry;
+ struct git_istream *st;
+ unsigned char *buf;
+ unsigned long buf_size;
+};
+
+static int compare_objects(const unsigned char *buf, unsigned long size,
+ void *cb_data)
+{
+ struct compare_data *data = cb_data;
+
+ if (data->buf_size < size) {
+ free(data->buf);
+ data->buf = xmalloc(size);
+ data->buf_size = size;
+ }
+
+ while (size) {
+ ssize_t len = read_istream(data->st, data->buf, size);
+ if (len == 0)
+ die(_("SHA1 COLLISION FOUND WITH %s !"),
+ sha1_to_hex(data->entry->idx.sha1));
+ if (len < 0)
+ die(_("unable to read %s"),
+ sha1_to_hex(data->entry->idx.sha1));
+ if (memcmp(buf, data->buf, len))
+ die(_("SHA1 COLLISION FOUND WITH %s !"),
+ sha1_to_hex(data->entry->idx.sha1));
+ size -= len;
+ buf += len;
+ }
+ return 0;
+}
+
+static int check_collison(struct object_entry *entry)
+{
+ struct compare_data data;
+ enum object_type type;
+ unsigned long size;
+
+ if (entry->size <= big_file_threshold || entry->type != OBJ_BLOB)
+ return -1;
+
+ memset(&data, 0, sizeof(data));
+ data.entry = entry;
+ data.st = open_istream(entry->idx.sha1, &type, &size, NULL);
+ if (!data.st)
+ return -1;
+ if (size != entry->size || type != entry->type)
+ die(_("SHA1 COLLISION FOUND WITH %s !"),
+ sha1_to_hex(entry->idx.sha1));
+ unpack_data(entry, compare_objects, &data);
+ close_istream(data.st);
+ free(data.buf);
+ return 0;
+}
+
+static void sha1_object(const void *data, struct object_entry *obj_entry,
+ unsigned long size, enum object_type type,
+ const unsigned char *sha1)
{
- hash_sha1_file(data, size, typename(type), sha1);
+ void *new_data = NULL;
+ int collision_test_needed;
+
+ assert(data || obj_entry);
+
read_lock();
- if (has_sha1_file(sha1)) {
+ collision_test_needed = has_sha1_file(sha1);
+ read_unlock();
+
+ if (collision_test_needed && !data) {
+ read_lock();
+ if (!check_collison(obj_entry))
+ collision_test_needed = 0;
+ read_unlock();
+ }
+ if (collision_test_needed) {
void *has_data;
enum object_type has_type;
unsigned long has_size;
+ read_lock();
+ has_type = sha1_object_info(sha1, &has_size);
+ if (has_type != type || has_size != size)
+ die(_("SHA1 COLLISION FOUND WITH %s !"), sha1_to_hex(sha1));
has_data = read_sha1_file(sha1, &has_type, &has_size);
read_unlock();
+ if (!data)
+ data = new_data = get_data_from_pack(obj_entry);
if (!has_data)
die(_("cannot read existing object %s"), sha1_to_hex(sha1));
if (size != has_size || type != has_type ||
memcmp(data, has_data, size) != 0)
die(_("SHA1 COLLISION FOUND WITH %s !"), sha1_to_hex(sha1));
free(has_data);
- } else
- read_unlock();
+ }
if (strict) {
read_lock();
int eaten;
void *buf = (void *) data;
+ if (!buf)
+ buf = new_data = get_data_from_pack(obj_entry);
+
/*
* we do not need to free the memory here, as the
* buf is deleted by the caller.
}
read_unlock();
}
-}
-static int is_delta_type(enum object_type type)
-{
- return (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA);
+ free(new_data);
}
/*
free(delta_data);
if (!result->data)
bad_object(delta_obj->idx.offset, _("failed to apply delta"));
- sha1_object(result->data, result->size, delta_obj->real_type,
+ hash_sha1_file(result->data, result->size,
+ typename(delta_obj->real_type), delta_obj->idx.sha1);
+ sha1_object(result->data, NULL, result->size, delta_obj->real_type,
delta_obj->idx.sha1);
counter_lock();
nr_resolved_deltas++;
*/
static void parse_pack_objects(unsigned char *sha1)
{
- int i;
+ int i, nr_delays = 0;
struct delta_entry *delta = deltas;
struct stat st;
nr_objects);
for (i = 0; i < nr_objects; i++) {
struct object_entry *obj = &objects[i];
- void *data = unpack_raw_entry(obj, &delta->base);
+ void *data = unpack_raw_entry(obj, &delta->base, obj->idx.sha1);
obj->real_type = obj->type;
if (is_delta_type(obj->type)) {
nr_deltas++;
delta->obj_no = i;
delta++;
+ } else if (!data) {
+ /* large blobs, check later */
+ obj->real_type = OBJ_BAD;
+ nr_delays++;
} else
- sha1_object(data, obj->size, obj->type, obj->idx.sha1);
+ sha1_object(data, NULL, obj->size, obj->type, obj->idx.sha1);
free(data);
display_progress(progress, i+1);
}
if (S_ISREG(st.st_mode) &&
lseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size)
die(_("pack has junk at the end"));
+
+ for (i = 0; i < nr_objects; i++) {
+ struct object_entry *obj = &objects[i];
+ if (obj->real_type != OBJ_BAD)
+ continue;
+ obj->real_type = obj->type;
+ sha1_object(NULL, obj, obj->size, obj->type, obj->idx.sha1);
+ nr_delays--;
+ }
+ if (nr_delays)
+ die(_("confusion beyond insanity in parse_pack_objects()"));
}
/*
strcpy(path + len, "CoNfIg");
if (!access(path, F_OK))
git_config_set("core.ignorecase", "true");
+ probe_utf8_pathname_composition(path, len);
}
return reinit;
#include "parse-options.h"
#include "branch.h"
#include "streaming.h"
+#include "version.h"
/* Set a default date-time format for git log ("log.date" config variable) */
static const char *default_date_mode = NULL;
rev.simplify_history = 0;
memset(&opt, 0, sizeof(opt));
opt.def = "HEAD";
+ opt.revarg_opt = REVARG_COMMITTISH;
cmd_log_init(argc, argv, prefix, &rev, &opt);
if (!rev.diffopt.output_format)
rev.diffopt.output_format = DIFF_FORMAT_RAW;
opt.tweak = show_rev_tweak_rev;
cmd_log_init(argc, argv, prefix, &rev, &opt);
+ if (!rev.no_walk)
+ return cmd_log_walk(&rev);
+
count = rev.pending.nr;
objects = rev.pending.objects;
for (i = 0; i < count && !ret; i++) {
rev.always_show_header = 1;
memset(&opt, 0, sizeof(opt));
opt.def = "HEAD";
+ opt.revarg_opt = REVARG_COMMITTISH;
cmd_log_init(argc, argv, prefix, &rev, &opt);
return cmd_log_walk(&rev);
}
rev.subject_prefix = fmt_patch_subject_prefix;
memset(&s_r_opt, 0, sizeof(s_r_opt));
s_r_opt.def = "HEAD";
+ s_r_opt.revarg_opt = REVARG_COMMITTISH;
if (default_attach) {
rev.mime_boundary = default_attach;
}
}
+static int ce_excluded(struct path_exclude_check *check, struct cache_entry *ce)
+{
+ int dtype = ce_to_dtype(ce);
+ return path_excluded(check, ce->name, ce_namelen(ce), &dtype);
+}
+
static void show_files(struct dir_struct *dir)
{
int i;
+ struct path_exclude_check check;
+
+ if ((dir->flags & DIR_SHOW_IGNORED))
+ path_exclude_check_init(&check, dir);
/* For cached/deleted files we don't need to even do the readdir */
if (show_others || show_killed) {
if (show_cached | show_stage) {
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
- int dtype = ce_to_dtype(ce);
- if (dir->flags & DIR_SHOW_IGNORED &&
- !excluded(dir, ce->name, &dtype))
+ if ((dir->flags & DIR_SHOW_IGNORED) &&
+ !ce_excluded(&check, ce))
continue;
if (show_unmerged && !ce_stage(ce))
continue;
struct cache_entry *ce = active_cache[i];
struct stat st;
int err;
- int dtype = ce_to_dtype(ce);
- if (dir->flags & DIR_SHOW_IGNORED &&
- !excluded(dir, ce->name, &dtype))
+ if ((dir->flags & DIR_SHOW_IGNORED) &&
+ !ce_excluded(&check, ce))
continue;
if (ce->ce_flags & CE_UPDATE)
continue;
show_ce_entry(tag_modified, ce);
}
}
+
+ if ((dir->flags & DIR_SHOW_IGNORED))
+ path_exclude_check_clear(&check);
}
/*
#include "list-objects.h"
#include "progress.h"
#include "refs.h"
+#include "streaming.h"
#include "thread-utils.h"
static const char *pack_usage[] = {
return stream.total_out;
}
+static unsigned long write_large_blob_data(struct git_istream *st, struct sha1file *f,
+ const unsigned char *sha1)
+{
+ git_zstream stream;
+ unsigned char ibuf[1024 * 16];
+ unsigned char obuf[1024 * 16];
+ unsigned long olen = 0;
+
+ memset(&stream, 0, sizeof(stream));
+ git_deflate_init(&stream, pack_compression_level);
+
+ for (;;) {
+ ssize_t readlen;
+ int zret = Z_OK;
+ readlen = read_istream(st, ibuf, sizeof(ibuf));
+ if (readlen == -1)
+ die(_("unable to read %s"), sha1_to_hex(sha1));
+
+ stream.next_in = ibuf;
+ stream.avail_in = readlen;
+ while ((stream.avail_in || readlen == 0) &&
+ (zret == Z_OK || zret == Z_BUF_ERROR)) {
+ stream.next_out = obuf;
+ stream.avail_out = sizeof(obuf);
+ zret = git_deflate(&stream, readlen ? 0 : Z_FINISH);
+ sha1write(f, obuf, stream.next_out - obuf);
+ olen += stream.next_out - obuf;
+ }
+ if (stream.avail_in)
+ die(_("deflate error (%d)"), zret);
+ if (readlen == 0) {
+ if (zret != Z_STREAM_END)
+ die(_("deflate error (%d)"), zret);
+ break;
+ }
+ }
+ git_deflate_end(&stream);
+ return olen;
+}
+
/*
* we are going to reuse the existing object data as is. make
* sure it is not corrupt.
unsigned hdrlen;
enum object_type type;
void *buf;
+ struct git_istream *st = NULL;
if (!usable_delta) {
- buf = read_sha1_file(entry->idx.sha1, &type, &size);
- if (!buf)
- die("unable to read %s", sha1_to_hex(entry->idx.sha1));
+ if (entry->type == OBJ_BLOB &&
+ entry->size > big_file_threshold &&
+ (st = open_istream(entry->idx.sha1, &type, &size, NULL)) != NULL)
+ buf = NULL;
+ else {
+ buf = read_sha1_file(entry->idx.sha1, &type, &size);
+ if (!buf)
+ die(_("unable to read %s"), sha1_to_hex(entry->idx.sha1));
+ }
/*
* make sure no cached delta data remains from a
* previous attempt before a pack split occurred.
OBJ_OFS_DELTA : OBJ_REF_DELTA;
}
- if (entry->z_delta_size)
+ if (st) /* large blob case, just assume we don't compress well */
+ datalen = size;
+ else if (entry->z_delta_size)
datalen = entry->z_delta_size;
else
datalen = do_compress(&buf, size);
while (ofs >>= 7)
dheader[--pos] = 128 | (--ofs & 127);
if (limit && hdrlen + sizeof(dheader) - pos + datalen + 20 >= limit) {
+ if (st)
+ close_istream(st);
free(buf);
return 0;
}
* an additional 20 bytes for the base sha1.
*/
if (limit && hdrlen + 20 + datalen + 20 >= limit) {
+ if (st)
+ close_istream(st);
free(buf);
return 0;
}
hdrlen += 20;
} else {
if (limit && hdrlen + datalen + 20 >= limit) {
+ if (st)
+ close_istream(st);
free(buf);
return 0;
}
sha1write(f, header, hdrlen);
}
- sha1write(f, buf, datalen);
- free(buf);
+ if (st) {
+ datalen = write_large_blob_data(st, f, entry->idx.sha1);
+ close_istream(st);
+ } else {
+ sha1write(f, buf, datalen);
+ free(buf);
+ }
return hdrlen + datalen;
}
}
die("not a rev '%s'", line);
}
- if (handle_revision_arg(line, &revs, flags, 1))
+ if (handle_revision_arg(line, &revs, flags, REVARG_CANNOT_BE_FILENAME))
die("bad revision '%s'", line);
}
printf("keep %s", message);
return 0;
prune:
- if (!cb->newlog || cb->cmd->verbose)
- printf("%sprune %s", cb->newlog ? "" : "would ", message);
+ if (!cb->newlog)
+ printf("would prune %s", message);
+ else if (cb->cmd->verbose)
+ printf("prune %s", message);
return 0;
}
* Otherwise, argv[i] could be either <rev> or <paths> and
* has to be unambiguous.
*/
- else if (!get_sha1(argv[i], sha1)) {
+ else if (!get_sha1_committish(argv[i], sha1)) {
/*
* Ok, argv[i] looks like a rev; it should not
* be a filename.
rev = argv[i++];
} else {
/* Otherwise we treat this as a filename */
- verify_filename(prefix, argv[i]);
+ verify_filename(prefix, argv[i], 1);
}
}
- if (get_sha1(rev, sha1))
+ if (get_sha1_committish(rev, sha1))
die(_("Failed to resolve '%s' as a valid ref."), rev);
+ /*
+ * NOTE: As "git reset $treeish -- $path" should be usable on
+ * any tree-ish, this is not strictly correct. We are not
+ * moving the HEAD to any commit; we are merely resetting the
+ * entries in the index to that of a treeish.
+ */
commit = lookup_commit_reference(sha1);
if (!commit)
die(_("Could not parse object '%s'."), rev);
return 0;
}
+static int show_abbrev(const unsigned char *sha1, void *cb_data)
+{
+ show_rev(NORMAL, sha1, NULL);
+ return 0;
+}
+
static void show_datestring(const char *flag, const char *datestr)
{
static char buffer[100];
next = "HEAD";
if (dotdot == arg)
this = "HEAD";
- if (!get_sha1(this, sha1) && !get_sha1(next, end)) {
+ if (!get_sha1_committish(this, sha1) && !get_sha1_committish(next, end)) {
show_rev(NORMAL, end, next);
show_rev(symmetric ? NORMAL : REVERSED, sha1, this);
if (symmetric) {
return 0;
*dotdot = 0;
- if (get_sha1(arg, sha1))
+ if (get_sha1_committish(arg, sha1))
return 0;
if (!parents_only)
if (as_is) {
if (show_file(arg) && as_is < 2)
- verify_filename(prefix, arg);
+ verify_filename(prefix, arg, 0);
continue;
}
if (!strcmp(arg,"-n")) {
for_each_ref(show_reference, NULL);
continue;
}
+ if (!prefixcmp(arg, "--disambiguate=")) {
+ for_each_abbrev(arg + 15, show_abbrev, NULL);
+ continue;
+ }
if (!strcmp(arg, "--bisect")) {
for_each_ref_in("refs/bisect/bad", show_reference, NULL);
for_each_ref_in("refs/bisect/good", anti_reference, NULL);
as_is = 1;
if (!show_file(arg))
continue;
- verify_filename(prefix, arg);
+ verify_filename(prefix, arg, 1);
}
if (verify) {
if (revs_count == 1) {
if (S_ISDIR(st.st_mode))
return process_directory(path, len, &st);
- /*
- * Process a regular file
- */
- if (ce && S_ISGITLINK(ce->ce_mode))
- return error("%s is already a gitlink, not replacing", path);
-
return add_one_path(ce, path, len, &st);
}
r->nr),
r->nr);
list_refs(r, 0, NULL);
- r = &header->prerequisites;
- printf_ln(Q_("The bundle requires this ref",
- "The bundle requires these %d refs",
- r->nr),
- r->nr);
- list_refs(r, 0, NULL);
+ if (!r->nr) {
+ printf_ln(_("The bundle records a complete history."));
+ } else {
+ r = &header->prerequisites;
+ printf_ln(Q_("The bundle requires this ref",
+ "The bundle requires these %d refs",
+ r->nr),
+ r->nr);
+ list_refs(r, 0, NULL);
+ }
}
return ret;
}
extern char *prefix_path(const char *prefix, int len, const char *path);
extern const char *prefix_filename(const char *prefix, int len, const char *path);
extern int check_filename(const char *prefix, const char *name);
-extern void verify_filename(const char *prefix, const char *name);
+extern void verify_filename(const char *prefix,
+ const char *name,
+ int diagnose_misspelt_rev);
extern void verify_non_filename(const char *prefix, const char *name);
+extern int path_inside_repo(const char *prefix, const char *path);
#define INIT_DB_QUIET 0x0001
extern int fsync_object_files;
extern int core_preload_index;
extern int core_apply_sparse_checkout;
+extern int precomposed_unicode;
enum branch_track {
BRANCH_TRACK_UNSPECIFIED = -1,
__attribute__((format (printf, 3, 4)));
extern char *git_pathdup(const char *fmt, ...)
__attribute__((format (printf, 1, 2)));
+extern char *mkpathdup(const char *fmt, ...)
+ __attribute__((format (printf, 1, 2)));
/* Return a statically allocated filename matching the sha1 signature */
extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
int safe_create_leading_directories(char *path);
int safe_create_leading_directories_const(const char *path);
int mkdir_in_gitdir(const char *path);
+extern void home_config_paths(char **global, char **xdg, char *file);
extern char *expand_user_path(const char *path);
const char *enter_repo(const char *path, int strict);
static inline int is_absolute_path(const char *path)
unsigned mode;
};
+#define GET_SHA1_QUIETLY 01
+#define GET_SHA1_COMMIT 02
+#define GET_SHA1_COMMITTISH 04
+#define GET_SHA1_TREE 010
+#define GET_SHA1_TREEISH 020
+#define GET_SHA1_BLOB 040
+#define GET_SHA1_ONLY_TO_DIE 04000
+
extern int get_sha1(const char *str, unsigned char *sha1);
-extern int get_sha1_with_mode_1(const char *str, unsigned char *sha1, unsigned *mode, int only_to_die, const char *prefix);
-static inline int get_sha1_with_mode(const char *str, unsigned char *sha1, unsigned *mode)
-{
- return get_sha1_with_mode_1(str, sha1, mode, 0, NULL);
-}
-extern int get_sha1_with_context_1(const char *name, unsigned char *sha1, struct object_context *orc, int only_to_die, const char *prefix);
-static inline int get_sha1_with_context(const char *str, unsigned char *sha1, struct object_context *orc)
-{
- return get_sha1_with_context_1(str, sha1, orc, 0, NULL);
-}
+extern int get_sha1_commit(const char *str, unsigned char *sha1);
+extern int get_sha1_committish(const char *str, unsigned char *sha1);
+extern int get_sha1_tree(const char *str, unsigned char *sha1);
+extern int get_sha1_treeish(const char *str, unsigned char *sha1);
+extern int get_sha1_blob(const char *str, unsigned char *sha1);
+extern void maybe_die_on_misspelt_object_name(const char *name, const char *prefix);
+extern int get_sha1_with_context(const char *str, unsigned flags, unsigned char *sha1, struct object_context *orc);
+
+typedef int each_abbrev_fn(const unsigned char *sha1, void *);
+extern int for_each_abbrev(const char *prefix, each_abbrev_fn, void *);
/*
* Try to read a SHA1 in hexadecimal format from the 40 characters
unsigned char sha1[20];
struct commit *commit;
- if (get_sha1(name, sha1))
+ if (get_sha1_committish(name, sha1))
return NULL;
commit = lookup_commit_reference(sha1);
if (!commit || parse_commit(commit))
Thanks to Dmitry Chichkov for reporting this. Futher thanks to Aleksey Sanin.
* Fixed realloc(0, <size>) segfaulting. Thanks to Dmitry Chichkov for
reporting this.
- * Made config defines #ifndef so they can be overriden by the build system.
+ * Made config defines #ifndef so they can be overridden by the build system.
Thanks to Aleksey Sanin for suggesting this.
* Fixed deadlock in nedprealloc() due to unnecessary locking of preferred
thread mspace when mspace_realloc() always uses the original block's mspace
--- /dev/null
+/*
+ * Converts filenames from decomposed unicode into precomposed unicode.
+ * Used on MacOS X.
+*/
+
+
+#define PRECOMPOSE_UNICODE_C
+
+#include "cache.h"
+#include "utf8.h"
+#include "precompose_utf8.h"
+
+typedef char *iconv_ibp;
+const static char *repo_encoding = "UTF-8";
+const static char *path_encoding = "UTF-8-MAC";
+
+
+static size_t has_utf8(const char *s, size_t maxlen, size_t *strlen_c)
+{
+ const uint8_t *utf8p = (const uint8_t*) s;
+ size_t strlen_chars = 0;
+ size_t ret = 0;
+
+ if ((!utf8p) || (!*utf8p)) {
+ return 0;
+ }
+
+ while((*utf8p) && maxlen) {
+ if (*utf8p & 0x80)
+ ret++;
+ strlen_chars++;
+ utf8p++;
+ maxlen--;
+ }
+ if (strlen_c)
+ *strlen_c = strlen_chars;
+
+ return ret;
+}
+
+
+void probe_utf8_pathname_composition(char *path, int len)
+{
+ const static char *auml_nfc = "\xc3\xa4";
+ const static char *auml_nfd = "\x61\xcc\x88";
+ int output_fd;
+ if (precomposed_unicode != -1)
+ return; /* We found it defined in the global config, respect it */
+ path[len] = 0;
+ strcpy(path + len, auml_nfc);
+ output_fd = open(path, O_CREAT|O_EXCL|O_RDWR, 0600);
+ if (output_fd >=0) {
+ close(output_fd);
+ path[len] = 0;
+ strcpy(path + len, auml_nfd);
+ /* Indicate to the user, that we can configure it to true */
+ if (0 == access(path, R_OK))
+ git_config_set("core.precomposeunicode", "false");
+ /* To be backward compatible, set precomposed_unicode to 0 */
+ precomposed_unicode = 0;
+ path[len] = 0;
+ strcpy(path + len, auml_nfc);
+ unlink(path);
+ }
+}
+
+
+void precompose_argv(int argc, const char **argv)
+{
+ int i = 0;
+ const char *oldarg;
+ char *newarg;
+ iconv_t ic_precompose;
+
+ if (precomposed_unicode != 1)
+ return;
+
+ ic_precompose = iconv_open(repo_encoding, path_encoding);
+ if (ic_precompose == (iconv_t) -1)
+ return;
+
+ while (i < argc) {
+ size_t namelen;
+ oldarg = argv[i];
+ if (has_utf8(oldarg, (size_t)-1, &namelen)) {
+ newarg = reencode_string_iconv(oldarg, namelen, ic_precompose);
+ if (newarg)
+ argv[i] = newarg;
+ }
+ i++;
+ }
+ iconv_close(ic_precompose);
+}
+
+
+PREC_DIR *precompose_utf8_opendir(const char *dirname)
+{
+ PREC_DIR *prec_dir = xmalloc(sizeof(PREC_DIR));
+ prec_dir->dirent_nfc = xmalloc(sizeof(dirent_prec_psx));
+ prec_dir->dirent_nfc->max_name_len = sizeof(prec_dir->dirent_nfc->d_name);
+
+ prec_dir->dirp = opendir(dirname);
+ if (!prec_dir->dirp) {
+ free(prec_dir->dirent_nfc);
+ free(prec_dir);
+ return NULL;
+ } else {
+ int ret_errno = errno;
+ prec_dir->ic_precompose = iconv_open(repo_encoding, path_encoding);
+ /* if iconv_open() fails, die() in readdir() if needed */
+ errno = ret_errno;
+ }
+
+ return prec_dir;
+}
+
+struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *prec_dir)
+{
+ struct dirent *res;
+ res = readdir(prec_dir->dirp);
+ if (res) {
+ size_t namelenz = strlen(res->d_name) + 1; /* \0 */
+ size_t new_maxlen = namelenz;
+
+ int ret_errno = errno;
+
+ if (new_maxlen > prec_dir->dirent_nfc->max_name_len) {
+ size_t new_len = sizeof(dirent_prec_psx) + new_maxlen -
+ sizeof(prec_dir->dirent_nfc->d_name);
+
+ prec_dir->dirent_nfc = xrealloc(prec_dir->dirent_nfc, new_len);
+ prec_dir->dirent_nfc->max_name_len = new_maxlen;
+ }
+
+ prec_dir->dirent_nfc->d_ino = res->d_ino;
+ prec_dir->dirent_nfc->d_type = res->d_type;
+
+ if ((precomposed_unicode == 1) && has_utf8(res->d_name, (size_t)-1, NULL)) {
+ if (prec_dir->ic_precompose == (iconv_t)-1) {
+ die("iconv_open(%s,%s) failed, but needed:\n"
+ " precomposed unicode is not supported.\n"
+ " If you wnat to use decomposed unicode, run\n"
+ " \"git config core.precomposeunicode false\"\n",
+ repo_encoding, path_encoding);
+ } else {
+ iconv_ibp cp = (iconv_ibp)res->d_name;
+ size_t inleft = namelenz;
+ char *outpos = &prec_dir->dirent_nfc->d_name[0];
+ size_t outsz = prec_dir->dirent_nfc->max_name_len;
+ size_t cnt;
+ errno = 0;
+ cnt = iconv(prec_dir->ic_precompose, &cp, &inleft, &outpos, &outsz);
+ if (errno || inleft) {
+ /*
+ * iconv() failed and errno could be E2BIG, EILSEQ, EINVAL, EBADF
+ * MacOS X avoids illegal byte sequemces.
+ * If they occur on a mounted drive (e.g. NFS) it is not worth to
+ * die() for that, but rather let the user see the original name
+ */
+ namelenz = 0; /* trigger strlcpy */
+ }
+ }
+ }
+ else
+ namelenz = 0;
+
+ if (!namelenz)
+ strlcpy(prec_dir->dirent_nfc->d_name, res->d_name,
+ prec_dir->dirent_nfc->max_name_len);
+
+ errno = ret_errno;
+ return prec_dir->dirent_nfc;
+ }
+ return NULL;
+}
+
+
+int precompose_utf8_closedir(PREC_DIR *prec_dir)
+{
+ int ret_value;
+ int ret_errno;
+ ret_value = closedir(prec_dir->dirp);
+ ret_errno = errno;
+ if (prec_dir->ic_precompose != (iconv_t)-1)
+ iconv_close(prec_dir->ic_precompose);
+ free(prec_dir->dirent_nfc);
+ free(prec_dir);
+ errno = ret_errno;
+ return ret_value;
+}
--- /dev/null
+#ifndef PRECOMPOSE_UNICODE_H
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <iconv.h>
+
+
+typedef struct dirent_prec_psx {
+ ino_t d_ino; /* Posix */
+ size_t max_name_len; /* See below */
+ unsigned char d_type; /* available on all systems git runs on */
+
+ /*
+ * See http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/dirent.h.html
+ * NAME_MAX + 1 should be enough, but some systems have
+ * NAME_MAX=255 and strlen(d_name) may return 508 or 510
+ * Solution: allocate more when needed, see precompose_utf8_readdir()
+ */
+ char d_name[NAME_MAX+1];
+} dirent_prec_psx;
+
+
+typedef struct {
+ iconv_t ic_precompose;
+ DIR *dirp;
+ struct dirent_prec_psx *dirent_nfc;
+} PREC_DIR;
+
+void precompose_argv(int argc, const char **argv);
+void probe_utf8_pathname_composition(char *, int);
+
+PREC_DIR *precompose_utf8_opendir(const char *dirname);
+struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *dirp);
+int precompose_utf8_closedir(PREC_DIR *dirp);
+
+#ifndef PRECOMPOSE_UNICODE_C
+#define dirent dirent_prec_psx
+#define opendir(n) precompose_utf8_opendir(n)
+#define readdir(d) precompose_utf8_readdir(d)
+#define closedir(d) precompose_utf8_closedir(d)
+#define DIR PREC_DIR
+#endif /* PRECOMPOSE_UNICODE_C */
+
+#define PRECOMPOSE_UNICODE_H
+#endif /* PRECOMPOSE_UNICODE_H */
return 0;
}
+ if (!strcmp(var, "core.precomposeunicode")) {
+ precomposed_unicode = git_config_bool(var, value);
+ return 0;
+ }
+
/* Add other config variables here and to Documentation/config.txt. */
return 0;
}
int git_config_early(config_fn_t fn, void *data, const char *repo_config)
{
int ret = 0, found = 0;
- const char *home = NULL;
+ char *xdg_config = NULL;
+ char *user_config = NULL;
+
+ home_config_paths(&user_config, &xdg_config, "config");
if (git_config_system() && !access(git_etc_gitconfig(), R_OK)) {
ret += git_config_from_file(fn, git_etc_gitconfig(),
found += 1;
}
- home = getenv("HOME");
- if (home) {
- char buf[PATH_MAX];
- char *user_config = mksnpath(buf, sizeof(buf), "%s/.gitconfig", home);
- if (!access(user_config, R_OK)) {
- ret += git_config_from_file(fn, user_config, data);
- found += 1;
- }
+ if (!access(xdg_config, R_OK)) {
+ ret += git_config_from_file(fn, xdg_config, data);
+ found += 1;
+ }
+
+ if (!access(user_config, R_OK)) {
+ ret += git_config_from_file(fn, user_config, data);
+ found += 1;
}
if (repo_config && !access(repo_config, R_OK)) {
break;
}
+ free(xdg_config);
+ free(user_config);
return ret == 0 ? found : ret;
}
export exec_prefix mandir
export srcdir VPATH
-ASCIIDOC7=@ASCIIDOC7@
NEEDS_SSL_WITH_CRYPTO=@NEEDS_SSL_WITH_CRYPTO@
NO_OPENSSL=@NO_OPENSSL@
NO_CURL=@NO_CURL@
AC_MSG_CHECKING([for asciidoc version])
asciidoc_version=`$ASCIIDOC --version 2>/dev/null`
case "${asciidoc_version}" in
- asciidoc' '7*)
- ASCIIDOC7=YesPlease
- AC_MSG_RESULT([${asciidoc_version} > 7])
- ;;
asciidoc' '8*)
- ASCIIDOC7=
AC_MSG_RESULT([${asciidoc_version}])
;;
*)
- ASCIIDOC7=
AC_MSG_RESULT([${asciidoc_version} (unknown)])
;;
esac
fi
-AC_SUBST(ASCIIDOC7)
## Checks for libraries.
extra->nr++;
}
+static void die_initial_contact(int got_at_least_one_head)
+{
+ if (got_at_least_one_head)
+ die("The remote end hung up upon initial contact");
+ else
+ die("Could not read from remote repository.\n\n"
+ "Please make sure you have the correct access rights\n"
+ "and the repository exists.");
+}
+
/*
* Read all the refs from the other end
*/
unsigned int flags,
struct extra_have_objects *extra_have)
{
+ int got_at_least_one_head = 0;
+
*list = NULL;
for (;;) {
struct ref *ref;
char *name;
int len, name_len;
- len = packet_read_line(in, buffer, sizeof(buffer));
+ len = packet_read(in, buffer, sizeof(buffer));
+ if (len < 0)
+ die_initial_contact(got_at_least_one_head);
+
if (!len)
break;
if (buffer[len-1] == '\n')
hashcpy(ref->old_sha1, old_sha1);
*list = ref;
list = &ref->next;
+ got_at_least_one_head = 1;
}
return list;
}
* Add support for ssh port: ssh://host.xy:<port>/...
*/
if (protocol == PROTO_SSH && host != url)
- port = get_port(host);
+ port = get_port(end);
if (protocol == PROTO_GIT) {
/* These underlying connection commands die() if they
# 1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
# 2) Add the following line to your .bashrc/.zshrc:
# source ~/.git-completion.sh
-#
-# 3) Consider changing your PS1 to also show the current branch:
-# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
-# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
-#
-# The argument to __git_ps1 will be displayed only if you
-# are currently in a git repository. The %s token will be
-# the name of the current branch.
-#
-# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty
-# value, unstaged (*) and staged (+) changes will be shown next
-# to the branch name. You can configure this per-repository
-# with the bash.showDirtyState variable, which defaults to true
-# once GIT_PS1_SHOWDIRTYSTATE is enabled.
-#
-# You can also see if currently something is stashed, by setting
-# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
-# then a '$' will be shown next to the branch name.
-#
-# If you would like to see if there're untracked files, then you can
-# set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're
-# untracked files, then a '%' will be shown next to the branch name.
-#
-# If you would like to see the difference between HEAD and its
-# upstream, set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates
-# you are behind, ">" indicates you are ahead, and "<>"
-# indicates you have diverged. You can further control
-# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated
-# list of values:
-# verbose show number of commits ahead/behind (+/-) upstream
-# legacy don't use the '--count' option available in recent
-# versions of git-rev-list
-# git always compare HEAD to @{upstream}
-# svn always compare HEAD to your SVN upstream
-# By default, __git_ps1 will compare HEAD to your SVN upstream
-# if it can find one, or @{upstream} otherwise. Once you have
-# set GIT_PS1_SHOWUPSTREAM, you can override it on a
-# per-repository basis by setting the bash.showUpstream config
-# variable.
-#
+# 3) Consider changing your PS1 to also show the current branch,
+# see git-prompt.sh for details.
if [[ -n ${ZSH_VERSION-} ]]; then
autoload -U +X bashcompinit && bashcompinit
# returns location of .git repo
__gitdir ()
{
+ # Note: this function is duplicated in git-prompt.sh
+ # When updating it, make sure you update the other one to match.
if [ -z "${1-}" ]; then
if [ -n "${__git_dir-}" ]; then
echo "$__git_dir"
+ elif [ -n "${GIT_DIR-}" ]; then
+ test -d "${GIT_DIR-}" || return 1
+ echo "$GIT_DIR"
elif [ -d .git ]; then
echo .git
else
fi
}
-# stores the divergence from upstream in $p
-# used by GIT_PS1_SHOWUPSTREAM
-__git_ps1_show_upstream ()
-{
- local key value
- local svn_remote svn_url_pattern count n
- local upstream=git legacy="" verbose=""
-
- svn_remote=()
- # get some config options from git-config
- local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
- while read -r key value; do
- case "$key" in
- bash.showupstream)
- GIT_PS1_SHOWUPSTREAM="$value"
- if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
- p=""
- return
- fi
- ;;
- svn-remote.*.url)
- svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value"
- svn_url_pattern+="\\|$value"
- upstream=svn+git # default upstream is SVN if available, else git
- ;;
- esac
- done <<< "$output"
-
- # parse configuration values
- for option in ${GIT_PS1_SHOWUPSTREAM}; do
- case "$option" in
- git|svn) upstream="$option" ;;
- verbose) verbose=1 ;;
- legacy) legacy=1 ;;
- esac
- done
-
- # Find our upstream
- case "$upstream" in
- git) upstream="@{upstream}" ;;
- svn*)
- # get the upstream from the "git-svn-id: ..." in a commit message
- # (git-svn uses essentially the same procedure internally)
- local svn_upstream=($(git log --first-parent -1 \
- --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
- if [[ 0 -ne ${#svn_upstream[@]} ]]; then
- svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
- svn_upstream=${svn_upstream%@*}
- local n_stop="${#svn_remote[@]}"
- for ((n=1; n <= n_stop; n++)); do
- svn_upstream=${svn_upstream#${svn_remote[$n]}}
- done
-
- if [[ -z "$svn_upstream" ]]; then
- # default branch name for checkouts with no layout:
- upstream=${GIT_SVN_ID:-git-svn}
- else
- upstream=${svn_upstream#/}
- fi
- elif [[ "svn+git" = "$upstream" ]]; then
- upstream="@{upstream}"
- fi
- ;;
- esac
-
- # Find how many commits we are ahead/behind our upstream
- if [[ -z "$legacy" ]]; then
- count="$(git rev-list --count --left-right \
- "$upstream"...HEAD 2>/dev/null)"
- else
- # produce equivalent output to --count for older versions of git
- local commits
- if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)"
- then
- local commit behind=0 ahead=0
- for commit in $commits
- do
- case "$commit" in
- "<"*) ((behind++)) ;;
- *) ((ahead++)) ;;
- esac
- done
- count="$behind $ahead"
- else
- count=""
- fi
- fi
-
- # calculate the result
- if [[ -z "$verbose" ]]; then
- case "$count" in
- "") # no upstream
- p="" ;;
- "0 0") # equal to upstream
- p="=" ;;
- "0 "*) # ahead of upstream
- p=">" ;;
- *" 0") # behind upstream
- p="<" ;;
- *) # diverged from upstream
- p="<>" ;;
- esac
- else
- case "$count" in
- "") # no upstream
- p="" ;;
- "0 0") # equal to upstream
- p=" u=" ;;
- "0 "*) # ahead of upstream
- p=" u+${count#0 }" ;;
- *" 0") # behind upstream
- p=" u-${count% 0}" ;;
- *) # diverged from upstream
- p=" u+${count#* }-${count% *}" ;;
- esac
- fi
-
-}
-
-
-# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
-# returns text to add to bash PS1 prompt (includes branch name)
-__git_ps1 ()
-{
- local g="$(__gitdir)"
- if [ -n "$g" ]; then
- local r=""
- local b=""
- if [ -f "$g/rebase-merge/interactive" ]; then
- r="|REBASE-i"
- b="$(cat "$g/rebase-merge/head-name")"
- elif [ -d "$g/rebase-merge" ]; then
- r="|REBASE-m"
- b="$(cat "$g/rebase-merge/head-name")"
- else
- if [ -d "$g/rebase-apply" ]; then
- if [ -f "$g/rebase-apply/rebasing" ]; then
- r="|REBASE"
- elif [ -f "$g/rebase-apply/applying" ]; then
- r="|AM"
- else
- r="|AM/REBASE"
- fi
- elif [ -f "$g/MERGE_HEAD" ]; then
- r="|MERGING"
- elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
- r="|CHERRY-PICKING"
- elif [ -f "$g/BISECT_LOG" ]; then
- r="|BISECTING"
- fi
-
- b="$(git symbolic-ref HEAD 2>/dev/null)" || {
-
- b="$(
- case "${GIT_PS1_DESCRIBE_STYLE-}" in
- (contains)
- git describe --contains HEAD ;;
- (branch)
- git describe --contains --all HEAD ;;
- (describe)
- git describe HEAD ;;
- (* | default)
- git describe --tags --exact-match HEAD ;;
- esac 2>/dev/null)" ||
-
- b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
- b="unknown"
- b="($b)"
- }
- fi
-
- local w=""
- local i=""
- local s=""
- local u=""
- local c=""
- local p=""
-
- if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
- if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then
- c="BARE:"
- else
- b="GIT_DIR!"
- fi
- elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
- if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then
- if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then
- git diff --no-ext-diff --quiet --exit-code || w="*"
- if git rev-parse --quiet --verify HEAD >/dev/null; then
- git diff-index --cached --quiet HEAD -- || i="+"
- else
- i="#"
- fi
- fi
- fi
- if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
- git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
- fi
-
- if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
- if [ -n "$(git ls-files --others --exclude-standard)" ]; then
- u="%"
- fi
- fi
-
- if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
- __git_ps1_show_upstream
- fi
- fi
-
- local f="$w$i$s$u"
- printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
- fi
-}
-
__gitcomp_1 ()
{
local c IFS=$' \t\n'
checkout-index) : plumbing;;
commit-tree) : plumbing;;
count-objects) : infrequent;;
+ credential-cache) : credentials helper;;
+ credential-store) : credentials helper;;
cvsexportcommit) : export;;
cvsimport) : import;;
cvsserver) : daemon;;
_git_log
}
-_main_git ()
+__git_main ()
{
local i c=1 command __git_dir
fi
}
-_main_gitk ()
+__gitk_main ()
{
__git_has_doubledash && return
# wrapper for backwards compatibility
_git ()
{
- __git_wrap_main_git
+ __git_wrap__git_main
}
# wrapper for backwards compatibility
_gitk ()
{
- __git_wrap_main_gitk
+ __git_wrap__gitk_main
}
-__git_complete git _main_git
-__git_complete gitk _main_gitk
+__git_complete git __git_main
+__git_complete gitk __gitk_main
# The following are necessary only for Cygwin, and only are needed
# when the user has tab-completed the executable name and consequently
# included the '.exe' suffix.
#
if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
-__git_complete git.exe _main_git
+__git_complete git.exe __git_main
fi
--- /dev/null
+# bash/zsh git prompt support
+#
+# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
+# Distributed under the GNU General Public License, version 2.0.
+#
+# This script allows you to see the current branch in your prompt.
+#
+# To enable:
+#
+# 1) Copy this file to somewhere (e.g. ~/.git-prompt.sh).
+# 2) Add the following line to your .bashrc/.zshrc:
+# source ~/.git-prompt.sh
+# 3) Change your PS1 to also show the current branch:
+# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
+# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
+#
+# The argument to __git_ps1 will be displayed only if you are currently
+# in a git repository. The %s token will be the name of the current
+# branch.
+#
+# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty value,
+# unstaged (*) and staged (+) changes will be shown next to the branch
+# name. You can configure this per-repository with the
+# bash.showDirtyState variable, which defaults to true once
+# GIT_PS1_SHOWDIRTYSTATE is enabled.
+#
+# You can also see if currently something is stashed, by setting
+# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
+# then a '$' will be shown next to the branch name.
+#
+# If you would like to see if there're untracked files, then you can set
+# GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're untracked
+# files, then a '%' will be shown next to the branch name.
+#
+# If you would like to see the difference between HEAD and its upstream,
+# set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates you are behind, ">"
+# indicates you are ahead, and "<>" indicates you have diverged. You
+# can further control behaviour by setting GIT_PS1_SHOWUPSTREAM to a
+# space-separated list of values:
+#
+# verbose show number of commits ahead/behind (+/-) upstream
+# legacy don't use the '--count' option available in recent
+# versions of git-rev-list
+# git always compare HEAD to @{upstream}
+# svn always compare HEAD to your SVN upstream
+#
+# By default, __git_ps1 will compare HEAD to your SVN upstream if it can
+# find one, or @{upstream} otherwise. Once you have set
+# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
+# setting the bash.showUpstream config variable.
+
+# __gitdir accepts 0 or 1 arguments (i.e., location)
+# returns location of .git repo
+__gitdir ()
+{
+ # Note: this function is duplicated in git-completion.bash
+ # When updating it, make sure you update the other one to match.
+ if [ -z "${1-}" ]; then
+ if [ -n "${__git_dir-}" ]; then
+ echo "$__git_dir"
+ elif [ -n "${GIT_DIR-}" ]; then
+ test -d "${GIT_DIR-}" || return 1
+ echo "$GIT_DIR"
+ elif [ -d .git ]; then
+ echo .git
+ else
+ git rev-parse --git-dir 2>/dev/null
+ fi
+ elif [ -d "$1/.git" ]; then
+ echo "$1/.git"
+ else
+ echo "$1"
+ fi
+}
+
+# stores the divergence from upstream in $p
+# used by GIT_PS1_SHOWUPSTREAM
+__git_ps1_show_upstream ()
+{
+ local key value
+ local svn_remote svn_url_pattern count n
+ local upstream=git legacy="" verbose=""
+
+ svn_remote=()
+ # get some config options from git-config
+ local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
+ while read -r key value; do
+ case "$key" in
+ bash.showupstream)
+ GIT_PS1_SHOWUPSTREAM="$value"
+ if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
+ p=""
+ return
+ fi
+ ;;
+ svn-remote.*.url)
+ svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value"
+ svn_url_pattern+="\\|$value"
+ upstream=svn+git # default upstream is SVN if available, else git
+ ;;
+ esac
+ done <<< "$output"
+
+ # parse configuration values
+ for option in ${GIT_PS1_SHOWUPSTREAM}; do
+ case "$option" in
+ git|svn) upstream="$option" ;;
+ verbose) verbose=1 ;;
+ legacy) legacy=1 ;;
+ esac
+ done
+
+ # Find our upstream
+ case "$upstream" in
+ git) upstream="@{upstream}" ;;
+ svn*)
+ # get the upstream from the "git-svn-id: ..." in a commit message
+ # (git-svn uses essentially the same procedure internally)
+ local svn_upstream=($(git log --first-parent -1 \
+ --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
+ if [[ 0 -ne ${#svn_upstream[@]} ]]; then
+ svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
+ svn_upstream=${svn_upstream%@*}
+ local n_stop="${#svn_remote[@]}"
+ for ((n=1; n <= n_stop; n++)); do
+ svn_upstream=${svn_upstream#${svn_remote[$n]}}
+ done
+
+ if [[ -z "$svn_upstream" ]]; then
+ # default branch name for checkouts with no layout:
+ upstream=${GIT_SVN_ID:-git-svn}
+ else
+ upstream=${svn_upstream#/}
+ fi
+ elif [[ "svn+git" = "$upstream" ]]; then
+ upstream="@{upstream}"
+ fi
+ ;;
+ esac
+
+ # Find how many commits we are ahead/behind our upstream
+ if [[ -z "$legacy" ]]; then
+ count="$(git rev-list --count --left-right \
+ "$upstream"...HEAD 2>/dev/null)"
+ else
+ # produce equivalent output to --count for older versions of git
+ local commits
+ if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)"
+ then
+ local commit behind=0 ahead=0
+ for commit in $commits
+ do
+ case "$commit" in
+ "<"*) ((behind++)) ;;
+ *) ((ahead++)) ;;
+ esac
+ done
+ count="$behind $ahead"
+ else
+ count=""
+ fi
+ fi
+
+ # calculate the result
+ if [[ -z "$verbose" ]]; then
+ case "$count" in
+ "") # no upstream
+ p="" ;;
+ "0 0") # equal to upstream
+ p="=" ;;
+ "0 "*) # ahead of upstream
+ p=">" ;;
+ *" 0") # behind upstream
+ p="<" ;;
+ *) # diverged from upstream
+ p="<>" ;;
+ esac
+ else
+ case "$count" in
+ "") # no upstream
+ p="" ;;
+ "0 0") # equal to upstream
+ p=" u=" ;;
+ "0 "*) # ahead of upstream
+ p=" u+${count#0 }" ;;
+ *" 0") # behind upstream
+ p=" u-${count% 0}" ;;
+ *) # diverged from upstream
+ p=" u+${count#* }-${count% *}" ;;
+ esac
+ fi
+
+}
+
+
+# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
+# returns text to add to bash PS1 prompt (includes branch name)
+__git_ps1 ()
+{
+ local g="$(__gitdir)"
+ if [ -n "$g" ]; then
+ local r=""
+ local b=""
+ if [ -f "$g/rebase-merge/interactive" ]; then
+ r="|REBASE-i"
+ b="$(cat "$g/rebase-merge/head-name")"
+ elif [ -d "$g/rebase-merge" ]; then
+ r="|REBASE-m"
+ b="$(cat "$g/rebase-merge/head-name")"
+ else
+ if [ -d "$g/rebase-apply" ]; then
+ if [ -f "$g/rebase-apply/rebasing" ]; then
+ r="|REBASE"
+ elif [ -f "$g/rebase-apply/applying" ]; then
+ r="|AM"
+ else
+ r="|AM/REBASE"
+ fi
+ elif [ -f "$g/MERGE_HEAD" ]; then
+ r="|MERGING"
+ elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
+ r="|CHERRY-PICKING"
+ elif [ -f "$g/BISECT_LOG" ]; then
+ r="|BISECTING"
+ fi
+
+ b="$(git symbolic-ref HEAD 2>/dev/null)" || {
+
+ b="$(
+ case "${GIT_PS1_DESCRIBE_STYLE-}" in
+ (contains)
+ git describe --contains HEAD ;;
+ (branch)
+ git describe --contains --all HEAD ;;
+ (describe)
+ git describe HEAD ;;
+ (* | default)
+ git describe --tags --exact-match HEAD ;;
+ esac 2>/dev/null)" ||
+
+ b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
+ b="unknown"
+ b="($b)"
+ }
+ fi
+
+ local w=""
+ local i=""
+ local s=""
+ local u=""
+ local c=""
+ local p=""
+
+ if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
+ if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then
+ c="BARE:"
+ else
+ b="GIT_DIR!"
+ fi
+ elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
+ if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then
+ if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then
+ git diff --no-ext-diff --quiet --exit-code || w="*"
+ if git rev-parse --quiet --verify HEAD >/dev/null; then
+ git diff-index --cached --quiet HEAD -- || i="+"
+ else
+ i="#"
+ fi
+ fi
+ fi
+ if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
+ git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
+ fi
+
+ if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
+ if [ -n "$(git ls-files --others --exclude-standard)" ]; then
+ u="%"
+ fi
+ fi
+
+ if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
+ __git_ps1_show_upstream
+ fi
+ fi
+
+ local f="$w$i$s$u"
+ printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
+ fi
+}
(defun git-blame-cleanup ()
"Remove all blame properties"
- (mapcar 'delete-overlay git-blame-overlays)
+ (mapc 'delete-overlay git-blame-overlays)
(setq git-blame-overlays nil)
(remove-git-blame-text-properties (point-min) (point-max)))
(defvar in-blame-filter nil)
(defun git-blame-filter (proc str)
- (save-excursion
- (set-buffer (process-buffer proc))
- (goto-char (process-mark proc))
- (insert-before-markers str)
- (goto-char 0)
- (unless in-blame-filter
- (let ((more t)
- (in-blame-filter t))
- (while more
- (setq more (git-blame-parse)))))))
+ (with-current-buffer (process-buffer proc)
+ (save-excursion
+ (goto-char (process-mark proc))
+ (insert-before-markers str)
+ (goto-char (point-min))
+ (unless in-blame-filter
+ (let ((more t)
+ (in-blame-filter t))
+ (while more
+ (setq more (git-blame-parse))))))))
(defun git-blame-parse ()
(cond ((looking-at "\\([0-9a-f]\\{40\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)\n")
info))))
(defun git-blame-create-overlay (info start-line num-lines)
- (save-excursion
- (set-buffer git-blame-file)
- (let ((inhibit-point-motion-hooks t)
- (inhibit-modification-hooks t))
- (goto-line start-line)
- (let* ((start (point))
- (end (progn (forward-line num-lines) (point)))
- (ovl (make-overlay start end))
- (hash (car info))
- (spec `((?h . ,(substring hash 0 6))
- (?H . ,hash)
- (?a . ,(git-blame-get-info info 'author))
- (?A . ,(git-blame-get-info info 'author-mail))
- (?c . ,(git-blame-get-info info 'committer))
- (?C . ,(git-blame-get-info info 'committer-mail))
- (?s . ,(git-blame-get-info info 'summary)))))
- (push ovl git-blame-overlays)
- (overlay-put ovl 'git-blame info)
- (overlay-put ovl 'help-echo
- (format-spec git-blame-mouseover-format spec))
- (if git-blame-use-colors
- (overlay-put ovl 'face (list :background
- (cdr (assq 'color (cdr info))))))
- (overlay-put ovl 'line-prefix
- (propertize (format-spec git-blame-prefix-format spec)
- 'face 'git-blame-prefix-face))))))
+ (with-current-buffer git-blame-file
+ (save-excursion
+ (let ((inhibit-point-motion-hooks t)
+ (inhibit-modification-hooks t))
+ (goto-char (point-min))
+ (forward-line (1- start-line))
+ (let* ((start (point))
+ (end (progn (forward-line num-lines) (point)))
+ (ovl (make-overlay start end))
+ (hash (car info))
+ (spec `((?h . ,(substring hash 0 6))
+ (?H . ,hash)
+ (?a . ,(git-blame-get-info info 'author))
+ (?A . ,(git-blame-get-info info 'author-mail))
+ (?c . ,(git-blame-get-info info 'committer))
+ (?C . ,(git-blame-get-info info 'committer-mail))
+ (?s . ,(git-blame-get-info info 'summary)))))
+ (push ovl git-blame-overlays)
+ (overlay-put ovl 'git-blame info)
+ (overlay-put ovl 'help-echo
+ (format-spec git-blame-mouseover-format spec))
+ (if git-blame-use-colors
+ (overlay-put ovl 'face (list :background
+ (cdr (assq 'color (cdr info))))))
+ (overlay-put ovl 'line-prefix
+ (propertize (format-spec git-blame-prefix-format spec)
+ 'face 'git-blame-prefix-face)))))))
(defun git-blame-add-info (info key value)
(nconc info (list (cons (intern key) value))))
--- /dev/null
+#
+# Copyright (C) 2012
+# Charles Roussel <charles.roussel@ensimag.imag.fr>
+# Simon Cathebras <simon.cathebras@ensimag.imag.fr>
+# Julien Khayat <julien.khayat@ensimag.imag.fr>
+# Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
+# Simon Perrat <simon.perrat@ensimag.imag.fr>
+#
+## Build git-remote-mediawiki
+
+-include ../../config.mak.autogen
+-include ../../config.mak
+
+ifndef PERL_PATH
+ PERL_PATH = /usr/bin/perl
+endif
+ifndef gitexecdir
+ gitexecdir = $(shell git --exec-path)
+endif
+
+PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
+gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
+SCRIPT = git-remote-mediawiki
+
+.PHONY: install help doc test clean
+
+help:
+ @echo 'This is the help target of the Makefile. Current configuration:'
+ @echo ' gitexecdir = $(gitexecdir_SQ)'
+ @echo ' PERL_PATH = $(PERL_PATH_SQ)'
+ @echo 'Run "$(MAKE) install" to install $(SCRIPT) in gitexecdir'
+ @echo 'Run "$(MAKE) test" to run the testsuite'
+
+install:
+ sed -e '1s|#!.*/perl|#!$(PERL_PATH_SQ)|' $(SCRIPT) \
+ > '$(gitexecdir_SQ)/$(SCRIPT)'
+ chmod +x '$(gitexecdir)/$(SCRIPT)'
+
+doc:
+ @echo 'Sorry, "make doc" is not implemented yet for $(SCRIPT)'
+
+test:
+ $(MAKE) -C t/ test
+
+clean:
+ $(RM) '$(gitexecdir)/$(SCRIPT)'
+ $(MAKE) -C t/ clean
#
# Known limitations:
#
-# - Only wiki pages are managed, no support for [[File:...]]
-# attachments.
-#
-# - Poor performance in the best case: it takes forever to check
-# whether we're up-to-date (on fetch or push) or to fetch a few
-# revisions from a large wiki, because we use exclusively a
-# page-based synchronization. We could switch to a wiki-wide
-# synchronization when the synchronization involves few revisions
-# but the wiki is large.
+# - Several strategies are provided to fetch modifications from the
+# wiki, but no automatic heuristics is provided, the user has
+# to understand and chose which strategy is appropriate for him.
#
# - Git renames could be turned into MediaWiki renames (see TODO
# below)
#
-# - login/password support requires the user to write the password
-# cleartext in a file (see TODO below).
-#
# - No way to import "one page, and all pages included in it"
#
# - Multiple remote MediaWikis have not been very well tested.
use strict;
use MediaWiki::API;
use DateTime::Format::ISO8601;
-use encoding 'utf8';
-# use encoding 'utf8' doesn't change STDERROR
-# but we're going to output UTF-8 filenames to STDERR
+# By default, use UTF-8 to communicate with Git and the user
binmode STDERR, ":utf8";
+binmode STDOUT, ":utf8";
use URI::Escape;
+use IPC::Open2;
+
use warnings;
# Mediawiki filenames can contain forward slashes. This variable decides by which pattern they should be replaced
my @tracked_categories = split(/[ \n]/, run_git("config --get-all remote.". $remotename .".categories"));
chomp(@tracked_categories);
+# Import media files too.
+my $import_media = run_git("config --get --bool remote.". $remotename .".mediaimport");
+chomp($import_media);
+$import_media = ($import_media eq "true");
+
my $wiki_login = run_git("config --get remote.". $remotename .".mwLogin");
-# TODO: ideally, this should be able to read from keyboard, but we're
-# inside a remote helper, so our stdin is connect to git, not to a
-# terminal.
+# Note: mwPassword is discourraged. Use the credential system instead.
my $wiki_passwd = run_git("config --get remote.". $remotename .".mwPassword");
my $wiki_domain = run_git("config --get remote.". $remotename .".mwDomain");
chomp($wiki_login);
chomp($shallow_import);
$shallow_import = ($shallow_import eq "true");
+# Fetch (clone and pull) by revisions instead of by pages. This behavior
+# is more efficient when we have a wiki with lots of pages and we fetch
+# the revisions quite often so that they concern only few pages.
+# Possible values:
+# - by_rev: perform one query per new revision on the remote wiki
+# - by_page: query each tracked page for new revision
+my $fetch_strategy = run_git("config --get remote.$remotename.fetchStrategy");
+unless ($fetch_strategy) {
+ $fetch_strategy = run_git("config --get mediawiki.fetchStrategy");
+}
+chomp($fetch_strategy);
+unless ($fetch_strategy) {
+ $fetch_strategy = "by_page";
+}
+
# Dumb push: don't update notes and mediawiki ref to reflect the last push.
#
# Configurable with mediawiki.dumbPush, or per-remote with
########################## Functions ##############################
+## credential API management (generic functions)
+
+sub credential_from_url {
+ my $url = shift;
+ my $parsed = URI->new($url);
+ my %credential;
+
+ if ($parsed->scheme) {
+ $credential{protocol} = $parsed->scheme;
+ }
+ if ($parsed->host) {
+ $credential{host} = $parsed->host;
+ }
+ if ($parsed->path) {
+ $credential{path} = $parsed->path;
+ }
+ if ($parsed->userinfo) {
+ if ($parsed->userinfo =~ /([^:]*):(.*)/) {
+ $credential{username} = $1;
+ $credential{password} = $2;
+ } else {
+ $credential{username} = $parsed->userinfo;
+ }
+ }
+
+ return %credential;
+}
+
+sub credential_read {
+ my %credential;
+ my $reader = shift;
+ my $op = shift;
+ while (<$reader>) {
+ my ($key, $value) = /([^=]*)=(.*)/;
+ if (not defined $key) {
+ die "ERROR receiving response from git credential $op:\n$_\n";
+ }
+ $credential{$key} = $value;
+ }
+ return %credential;
+}
+
+sub credential_write {
+ my $credential = shift;
+ my $writer = shift;
+ while (my ($key, $value) = each(%$credential) ) {
+ if ($value) {
+ print $writer "$key=$value\n";
+ }
+ }
+}
+
+sub credential_run {
+ my $op = shift;
+ my $credential = shift;
+ my $pid = open2(my $reader, my $writer, "git credential $op");
+ credential_write($credential, $writer);
+ print $writer "\n";
+ close($writer);
+
+ if ($op eq "fill") {
+ %$credential = credential_read($reader, $op);
+ } else {
+ if (<$reader>) {
+ die "ERROR while running git credential $op:\n$_";
+ }
+ }
+ close($reader);
+ waitpid($pid, 0);
+ my $child_exit_status = $? >> 8;
+ if ($child_exit_status != 0) {
+ die "'git credential $op' failed with code $child_exit_status.";
+ }
+}
+
# MediaWiki API instance, created lazily.
my $mediawiki;
sub mw_connect_maybe {
if ($mediawiki) {
- return;
+ return;
}
$mediawiki = MediaWiki::API->new;
$mediawiki->{config}->{api_url} = "$url/api.php";
if ($wiki_login) {
- if (!$mediawiki->login({
- lgname => $wiki_login,
- lgpassword => $wiki_passwd,
- lgdomain => $wiki_domain,
- })) {
- print STDERR "Failed to log in mediawiki user \"$wiki_login\" on $url\n";
- print STDERR "(error " .
- $mediawiki->{error}->{code} . ': ' .
- $mediawiki->{error}->{details} . ")\n";
- exit 1;
+ my %credential = credential_from_url($url);
+ $credential{username} = $wiki_login;
+ $credential{password} = $wiki_passwd;
+ credential_run("fill", \%credential);
+ my $request = {lgname => $credential{username},
+ lgpassword => $credential{password},
+ lgdomain => $wiki_domain};
+ if ($mediawiki->login($request)) {
+ credential_run("approve", \%credential);
+ print STDERR "Logged in mediawiki user \"$credential{username}\".\n";
} else {
- print STDERR "Logged in with user \"$wiki_login\".\n";
+ print STDERR "Failed to log in mediawiki user \"$credential{username}\" on $url\n";
+ print STDERR " (error " .
+ $mediawiki->{error}->{code} . ': ' .
+ $mediawiki->{error}->{details} . ")\n";
+ credential_run("reject", \%credential);
+ exit 1;
}
}
}
+## Functions for listing pages on the remote wiki
+sub get_mw_tracked_pages {
+ my $pages = shift;
+ get_mw_page_list(\@tracked_pages, $pages);
+}
+
+sub get_mw_page_list {
+ my $page_list = shift;
+ my $pages = shift;
+ my @some_pages = @$page_list;
+ while (@some_pages) {
+ my $last = 50;
+ if ($#some_pages < $last) {
+ $last = $#some_pages;
+ }
+ my @slice = @some_pages[0..$last];
+ get_mw_first_pages(\@slice, $pages);
+ @some_pages = @some_pages[51..$#some_pages];
+ }
+}
+
+sub get_mw_tracked_categories {
+ my $pages = shift;
+ foreach my $category (@tracked_categories) {
+ if (index($category, ':') < 0) {
+ # Mediawiki requires the Category
+ # prefix, but let's not force the user
+ # to specify it.
+ $category = "Category:" . $category;
+ }
+ my $mw_pages = $mediawiki->list( {
+ action => 'query',
+ list => 'categorymembers',
+ cmtitle => $category,
+ cmlimit => 'max' } )
+ || die $mediawiki->{error}->{code} . ': '
+ . $mediawiki->{error}->{details};
+ foreach my $page (@{$mw_pages}) {
+ $pages->{$page->{title}} = $page;
+ }
+ }
+}
+
+sub get_mw_all_pages {
+ my $pages = shift;
+ # No user-provided list, get the list of pages from the API.
+ my $mw_pages = $mediawiki->list({
+ action => 'query',
+ list => 'allpages',
+ aplimit => 'max'
+ });
+ if (!defined($mw_pages)) {
+ print STDERR "fatal: could not get the list of wiki pages.\n";
+ print STDERR "fatal: '$url' does not appear to be a mediawiki\n";
+ print STDERR "fatal: make sure '$url/api.php' is a valid page.\n";
+ exit 1;
+ }
+ foreach my $page (@{$mw_pages}) {
+ $pages->{$page->{title}} = $page;
+ }
+}
+
+# queries the wiki for a set of pages. Meant to be used within a loop
+# querying the wiki for slices of page list.
sub get_mw_first_pages {
my $some_pages = shift;
my @some_pages = @{$some_pages};
}
}
+# Get the list of pages to be fetched according to configuration.
sub get_mw_pages {
mw_connect_maybe();
$user_defined = 1;
# The user provided a list of pages titles, but we
# still need to query the API to get the page IDs.
-
- my @some_pages = @tracked_pages;
- while (@some_pages) {
- my $last = 50;
- if ($#some_pages < $last) {
- $last = $#some_pages;
- }
- my @slice = @some_pages[0..$last];
- get_mw_first_pages(\@slice, \%pages);
- @some_pages = @some_pages[51..$#some_pages];
- }
+ get_mw_tracked_pages(\%pages);
}
if (@tracked_categories) {
$user_defined = 1;
- foreach my $category (@tracked_categories) {
- if (index($category, ':') < 0) {
- # Mediawiki requires the Category
- # prefix, but let's not force the user
- # to specify it.
- $category = "Category:" . $category;
- }
- my $mw_pages = $mediawiki->list( {
- action => 'query',
- list => 'categorymembers',
- cmtitle => $category,
- cmlimit => 'max' } )
- || die $mediawiki->{error}->{code} . ': ' . $mediawiki->{error}->{details};
- foreach my $page (@{$mw_pages}) {
- $pages{$page->{title}} = $page;
- }
- }
+ get_mw_tracked_categories(\%pages);
}
if (!$user_defined) {
- # No user-provided list, get the list of pages from
- # the API.
- my $mw_pages = $mediawiki->list({
- action => 'query',
- list => 'allpages',
- aplimit => 500,
- });
- if (!defined($mw_pages)) {
- print STDERR "fatal: could not get the list of wiki pages.\n";
- print STDERR "fatal: '$url' does not appear to be a mediawiki\n";
- print STDERR "fatal: make sure '$url/api.php' is a valid page.\n";
- exit 1;
- }
- foreach my $page (@{$mw_pages}) {
- $pages{$page->{title}} = $page;
+ get_mw_all_pages(\%pages);
+ }
+ if ($import_media) {
+ print STDERR "Getting media files for selected pages...\n";
+ if ($user_defined) {
+ get_linked_mediafiles(\%pages);
+ } else {
+ get_all_mediafiles(\%pages);
}
}
- return values(%pages);
+ return %pages;
}
+# usage: $out = run_git("command args");
+# $out = run_git("command args", "raw"); # don't interpret output as UTF-8.
sub run_git {
- open(my $git, "-|:encoding(UTF-8)", "git " . $_[0]);
+ my $args = shift;
+ my $encoding = (shift || "encoding(UTF-8)");
+ open(my $git, "-|:$encoding", "git " . $args);
my $res = do { local $/; <$git> };
close($git);
}
+sub get_all_mediafiles {
+ my $pages = shift;
+ # Attach list of all pages for media files from the API,
+ # they are in a different namespace, only one namespace
+ # can be queried at the same moment
+ my $mw_pages = $mediawiki->list({
+ action => 'query',
+ list => 'allpages',
+ apnamespace => get_mw_namespace_id("File"),
+ aplimit => 'max'
+ });
+ if (!defined($mw_pages)) {
+ print STDERR "fatal: could not get the list of pages for media files.\n";
+ print STDERR "fatal: '$url' does not appear to be a mediawiki\n";
+ print STDERR "fatal: make sure '$url/api.php' is a valid page.\n";
+ exit 1;
+ }
+ foreach my $page (@{$mw_pages}) {
+ $pages->{$page->{title}} = $page;
+ }
+}
+
+sub get_linked_mediafiles {
+ my $pages = shift;
+ my @titles = map $_->{title}, values(%{$pages});
+
+ # The query is split in small batches because of the MW API limit of
+ # the number of links to be returned (500 links max).
+ my $batch = 10;
+ while (@titles) {
+ if ($#titles < $batch) {
+ $batch = $#titles;
+ }
+ my @slice = @titles[0..$batch];
+
+ # pattern 'page1|page2|...' required by the API
+ my $mw_titles = join('|', @slice);
+
+ # Media files could be included or linked from
+ # a page, get all related
+ my $query = {
+ action => 'query',
+ prop => 'links|images',
+ titles => $mw_titles,
+ plnamespace => get_mw_namespace_id("File"),
+ pllimit => 'max'
+ };
+ my $result = $mediawiki->api($query);
+
+ while (my ($id, $page) = each(%{$result->{query}->{pages}})) {
+ my @media_titles;
+ if (defined($page->{links})) {
+ my @link_titles = map $_->{title}, @{$page->{links}};
+ push(@media_titles, @link_titles);
+ }
+ if (defined($page->{images})) {
+ my @image_titles = map $_->{title}, @{$page->{images}};
+ push(@media_titles, @image_titles);
+ }
+ if (@media_titles) {
+ get_mw_page_list(\@media_titles, $pages);
+ }
+ }
+
+ @titles = @titles[($batch+1)..$#titles];
+ }
+}
+
+sub get_mw_mediafile_for_page_revision {
+ # Name of the file on Wiki, with the prefix.
+ my $filename = shift;
+ my $timestamp = shift;
+ my %mediafile;
+
+ # Search if on a media file with given timestamp exists on
+ # MediaWiki. In that case download the file.
+ my $query = {
+ action => 'query',
+ prop => 'imageinfo',
+ titles => "File:" . $filename,
+ iistart => $timestamp,
+ iiend => $timestamp,
+ iiprop => 'timestamp|archivename|url',
+ iilimit => 1
+ };
+ my $result = $mediawiki->api($query);
+
+ my ($fileid, $file) = each( %{$result->{query}->{pages}} );
+ # If not defined it means there is no revision of the file for
+ # given timestamp.
+ if (defined($file->{imageinfo})) {
+ $mediafile{title} = $filename;
+
+ my $fileinfo = pop(@{$file->{imageinfo}});
+ $mediafile{timestamp} = $fileinfo->{timestamp};
+ # Mediawiki::API's download function doesn't support https URLs
+ # and can't download old versions of files.
+ print STDERR "\tDownloading file $mediafile{title}, version $mediafile{timestamp}\n";
+ $mediafile{content} = download_mw_mediafile($fileinfo->{url});
+ }
+ return %mediafile;
+}
+
+sub download_mw_mediafile {
+ my $url = shift;
+
+ my $response = $mediawiki->{ua}->get($url);
+ if ($response->code == 200) {
+ return $response->decoded_content;
+ } else {
+ print STDERR "Error downloading mediafile from :\n";
+ print STDERR "URL: $url\n";
+ print STDERR "Server response: " . $response->code . " " . $response->message . "\n";
+ exit 1;
+ }
+}
+
sub get_last_local_revision {
# Get note regarding last mediawiki revision
my $note = run_git("notes --ref=$remotename/mediawiki show refs/mediawiki/$remotename/master 2>/dev/null");
# Remember the timestamp corresponding to a revision id.
my %basetimestamps;
+# Get the last remote revision without taking in account which pages are
+# tracked or not. This function makes a single request to the wiki thus
+# avoid a loop onto all tracked pages. This is useful for the fetch-by-rev
+# option.
+sub get_last_global_remote_rev {
+ mw_connect_maybe();
+
+ my $query = {
+ action => 'query',
+ list => 'recentchanges',
+ prop => 'revisions',
+ rclimit => '1',
+ rcdir => 'older',
+ };
+ my $result = $mediawiki->api($query);
+ return $result->{query}->{recentchanges}[0]->{revid};
+}
+
+# Get the last remote revision concerning the tracked pages and the tracked
+# categories.
sub get_last_remote_revision {
mw_connect_maybe();
- my @pages = get_mw_pages();
+ my %pages_hash = get_mw_pages();
+ my @pages = values(%pages_hash);
my $max_rev_num = 0;
print STDOUT "data ", bytes::length($content), "\n", $content;
}
+sub literal_data_raw {
+ # Output possibly binary content.
+ my ($content) = @_;
+ # Avoid confusion between size in bytes and in characters
+ utf8::downgrade($content);
+ binmode STDOUT, ":raw";
+ print STDOUT "data ", bytes::length($content), "\n", $content;
+ binmode STDOUT, ":utf8";
+}
+
sub mw_capabilities {
# Revisions are imported to the private namespace
# refs/mediawiki/$remotename/ by the helper and fetched into
my %commit = %{$commit};
my $full_import = shift;
my $n = shift;
+ my $mediafile = shift;
+ my %mediafile;
+ if ($mediafile) {
+ %mediafile = %{$mediafile};
+ }
my $title = $commit{title};
my $comment = $commit{comment};
if ($content ne DELETED_CONTENT) {
print STDOUT "M 644 inline $title.mw\n";
literal_data($content);
+ if (%mediafile) {
+ print STDOUT "M 644 inline $mediafile{title}\n";
+ literal_data_raw($mediafile{content});
+ }
print STDOUT "\n\n";
} else {
print STDOUT "D $title.mw\n";
mw_connect_maybe();
- my @pages = get_mw_pages();
-
print STDERR "Searching revisions...\n";
my $last_local = get_last_local_revision();
my $fetch_from = $last_local + 1;
} else {
print STDERR ", fetching from here.\n";
}
+
+ my $n = 0;
+ if ($fetch_strategy eq "by_rev") {
+ print STDERR "Fetching & writing export data by revs...\n";
+ $n = mw_import_ref_by_revs($fetch_from);
+ } elsif ($fetch_strategy eq "by_page") {
+ print STDERR "Fetching & writing export data by pages...\n";
+ $n = mw_import_ref_by_pages($fetch_from);
+ } else {
+ print STDERR "fatal: invalid fetch strategy \"$fetch_strategy\".\n";
+ print STDERR "Check your configuration variables remote.$remotename.fetchStrategy and mediawiki.fetchStrategy\n";
+ exit 1;
+ }
+
+ if ($fetch_from == 1 && $n == 0) {
+ print STDERR "You appear to have cloned an empty MediaWiki.\n";
+ # Something has to be done remote-helper side. If nothing is done, an error is
+ # thrown saying that HEAD is refering to unknown object 0000000000000000000
+ # and the clone fails.
+ }
+}
+
+sub mw_import_ref_by_pages {
+
+ my $fetch_from = shift;
+ my %pages_hash = get_mw_pages();
+ my @pages = values(%pages_hash);
+
my ($n, @revisions) = fetch_mw_revisions(\@pages, $fetch_from);
- # Creation of the fast-import stream
- print STDERR "Fetching & writing export data...\n";
+ @revisions = sort {$a->{revid} <=> $b->{revid}} @revisions;
+ my @revision_ids = map $_->{revid}, @revisions;
- $n = 0;
+ return mw_import_revids($fetch_from, \@revision_ids, \%pages_hash);
+}
+
+sub mw_import_ref_by_revs {
+
+ my $fetch_from = shift;
+ my %pages_hash = get_mw_pages();
+
+ my $last_remote = get_last_global_remote_rev();
+ my @revision_ids = $fetch_from..$last_remote;
+ return mw_import_revids($fetch_from, \@revision_ids, \%pages_hash);
+}
+
+# Import revisions given in second argument (array of integers).
+# Only pages appearing in the third argument (hash indexed by page titles)
+# will be imported.
+sub mw_import_revids {
+ my $fetch_from = shift;
+ my $revision_ids = shift;
+ my $pages = shift;
+
+ my $n = 0;
+ my $n_actual = 0;
my $last_timestamp = 0; # Placeholer in case $rev->timestamp is undefined
- foreach my $pagerevid (sort {$a->{revid} <=> $b->{revid}} @revisions) {
+ foreach my $pagerevid (@$revision_ids) {
# fetch the content of the pages
my $query = {
action => 'query',
prop => 'revisions',
rvprop => 'content|timestamp|comment|user|ids',
- revids => $pagerevid->{revid},
+ revids => $pagerevid,
};
my $result = $mediawiki->api($query);
- my $rev = pop(@{$result->{query}->{pages}->{$pagerevid->{pageid}}->{revisions}});
+ if (!$result) {
+ die "Failed to retrieve modified page for revision $pagerevid";
+ }
+
+ if (!defined($result->{query}->{pages})) {
+ die "Invalid revision $pagerevid.";
+ }
+
+ my @result_pages = values(%{$result->{query}->{pages}});
+ my $result_page = $result_pages[0];
+ my $rev = $result_pages[0]->{revisions}->[0];
+ # Count page even if we skip it, since we display
+ # $n/$total and $total includes skipped pages.
$n++;
+ my $page_title = $result_page->{title};
+
+ if (!exists($pages->{$page_title})) {
+ print STDERR "$n/", scalar(@$revision_ids),
+ ": Skipping revision #$rev->{revid} of $page_title\n";
+ next;
+ }
+
+ $n_actual++;
+
my %commit;
$commit{author} = $rev->{user} || 'Anonymous';
$commit{comment} = $rev->{comment} || '*Empty MediaWiki Message*';
- $commit{title} = mediawiki_smudge_filename(
- $result->{query}->{pages}->{$pagerevid->{pageid}}->{title}
- );
- $commit{mw_revision} = $pagerevid->{revid};
+ $commit{title} = mediawiki_smudge_filename($page_title);
+ $commit{mw_revision} = $rev->{revid};
$commit{content} = mediawiki_smudge($rev->{'*'});
if (!defined($rev->{timestamp})) {
}
$commit{date} = DateTime::Format::ISO8601->parse_datetime($last_timestamp);
- print STDERR "$n/", scalar(@revisions), ": Revision #$pagerevid->{revid} of $commit{title}\n";
-
- import_file_revision(\%commit, ($fetch_from == 1), $n);
+ # Differentiates classic pages and media files.
+ my ($namespace, $filename) = $page_title =~ /^([^:]*):(.*)$/;
+ my %mediafile;
+ if ($namespace && get_mw_namespace_id($namespace) == get_mw_namespace_id("File")) {
+ %mediafile = get_mw_mediafile_for_page_revision($filename, $rev->{timestamp});
+ }
+ # If this is a revision of the media page for new version
+ # of a file do one common commit for both file and media page.
+ # Else do commit only for that page.
+ print STDERR "$n/", scalar(@$revision_ids), ": Revision #$rev->{revid} of $commit{title}\n";
+ import_file_revision(\%commit, ($fetch_from == 1), $n_actual, \%mediafile);
}
- if ($fetch_from == 1 && $n == 0) {
- print STDERR "You appear to have cloned an empty MediaWiki.\n";
- # Something has to be done remote-helper side. If nothing is done, an error is
- # thrown saying that HEAD is refering to unknown object 0000000000000000000
- # and the clone fails.
- }
+ return $n_actual;
}
sub error_non_fast_forward {
return 0;
}
+sub mw_upload_file {
+ my $complete_file_name = shift;
+ my $new_sha1 = shift;
+ my $extension = shift;
+ my $file_deleted = shift;
+ my $summary = shift;
+ my $newrevid;
+ my $path = "File:" . $complete_file_name;
+ my %hashFiles = get_allowed_file_extensions();
+ if (!exists($hashFiles{$extension})) {
+ print STDERR "$complete_file_name is not a permitted file on this wiki.\n";
+ print STDERR "Check the configuration of file uploads in your mediawiki.\n";
+ return $newrevid;
+ }
+ # Deleting and uploading a file requires a priviledged user
+ if ($file_deleted) {
+ mw_connect_maybe();
+ my $query = {
+ action => 'delete',
+ title => $path,
+ reason => $summary
+ };
+ if (!$mediawiki->edit($query)) {
+ print STDERR "Failed to delete file on remote wiki\n";
+ print STDERR "Check your permissions on the remote site. Error code:\n";
+ print STDERR $mediawiki->{error}->{code} . ':' . $mediawiki->{error}->{details};
+ exit 1;
+ }
+ } else {
+ # Don't let perl try to interpret file content as UTF-8 => use "raw"
+ my $content = run_git("cat-file blob $new_sha1", "raw");
+ if ($content ne "") {
+ mw_connect_maybe();
+ $mediawiki->{config}->{upload_url} =
+ "$url/index.php/Special:Upload";
+ $mediawiki->edit({
+ action => 'upload',
+ filename => $complete_file_name,
+ comment => $summary,
+ file => [undef,
+ $complete_file_name,
+ Content => $content],
+ ignorewarnings => 1,
+ }, {
+ skip_encoding => 1
+ } ) || die $mediawiki->{error}->{code} . ':'
+ . $mediawiki->{error}->{details};
+ my $last_file_page = $mediawiki->get_page({title => $path});
+ $newrevid = $last_file_page->{revid};
+ print STDERR "Pushed file: $new_sha1 - $complete_file_name.\n";
+ } else {
+ print STDERR "Empty file $complete_file_name not pushed.\n";
+ }
+ }
+ return $newrevid;
+}
+
sub mw_push_file {
my $diff_info = shift;
# $diff_info contains a string in this format:
my $summary = shift;
# MediaWiki revision number. Keep the previous one by default,
# in case there's no edit to perform.
- my $newrevid = shift;
+ my $oldrevid = shift;
+ my $newrevid;
my $new_sha1 = $diff_info_split[3];
my $old_sha1 = $diff_info_split[2];
my $page_deleted = ($new_sha1 eq NULL_SHA1);
$complete_file_name = mediawiki_clean_filename($complete_file_name);
- if (substr($complete_file_name,-3) eq ".mw") {
- my $title = substr($complete_file_name,0,-3);
-
+ my ($title, $extension) = $complete_file_name =~ /^(.*)\.([^\.]*)$/;
+ if (!defined($extension)) {
+ $extension = "";
+ }
+ if ($extension eq "mw") {
my $file_content;
if ($page_deleted) {
# Deleting a page usually requires
action => 'edit',
summary => $summary,
title => $title,
- basetimestamp => $basetimestamps{$newrevid},
+ basetimestamp => $basetimestamps{$oldrevid},
text => mediawiki_clean($file_content, $page_created),
}, {
skip_encoding => 1 # Helps with names with accentuated characters
$mediawiki->{error}->{code} .
' from mediwiki: ' . $mediawiki->{error}->{details} .
".\n";
- return ($newrevid, "non-fast-forward");
+ return ($oldrevid, "non-fast-forward");
} else {
# Other errors. Shouldn't happen => just die()
die 'Fatal: Error ' .
$newrevid = $result->{edit}->{newrevid};
print STDERR "Pushed file: $new_sha1 - $title\n";
} else {
- print STDERR "$complete_file_name not a mediawiki file (Not pushable on this version of git-remote-mediawiki).\n"
+ $newrevid = mw_upload_file($complete_file_name, $new_sha1,
+ $extension, $page_deleted,
+ $summary);
}
+ $newrevid = ($newrevid or $oldrevid);
return ($newrevid, "ok");
}
# TODO: we could detect rename, and encode them with a #redirect on the wiki.
# TODO: for now, it's just a delete+add
my @diff_info_list = split(/\0/, $diff_infos);
- # Keep the first line of the commit message as mediawiki comment for the revision
- my $commit_msg = (split(/\n/, run_git("show --pretty=format:\"%s\" $sha1_commit")))[0];
+ # Keep the subject line of the commit message as mediawiki comment for the revision
+ my $commit_msg = run_git("log --no-walk --format=\"%s\" $sha1_commit");
chomp($commit_msg);
# Push every blob
while (@diff_info_list) {
print STDOUT "ok $remote\n";
return 1;
}
+
+sub get_allowed_file_extensions {
+ mw_connect_maybe();
+
+ my $query = {
+ action => 'query',
+ meta => 'siteinfo',
+ siprop => 'fileextensions'
+ };
+ my $result = $mediawiki->api($query);
+ my @file_extensions= map $_->{ext},@{$result->{query}->{fileextensions}};
+ my %hashFile = map {$_ => 1}@file_extensions;
+
+ return %hashFile;
+}
+
+# In memory cache for MediaWiki namespace ids.
+my %namespace_id;
+
+# Namespaces whose id is cached in the configuration file
+# (to avoid duplicates)
+my %cached_mw_namespace_id;
+
+# Return MediaWiki id for a canonical namespace name.
+# Ex.: "File", "Project".
+sub get_mw_namespace_id {
+ mw_connect_maybe();
+ my $name = shift;
+
+ if (!exists $namespace_id{$name}) {
+ # Look at configuration file, if the record for that namespace is
+ # already cached. Namespaces are stored in form:
+ # "Name_of_namespace:Id_namespace", ex.: "File:6".
+ my @temp = split(/[ \n]/, run_git("config --get-all remote."
+ . $remotename .".namespaceCache"));
+ chomp(@temp);
+ foreach my $ns (@temp) {
+ my ($n, $id) = split(/:/, $ns);
+ $namespace_id{$n} = $id;
+ $cached_mw_namespace_id{$n} = 1;
+ }
+ }
+
+ if (!exists $namespace_id{$name}) {
+ print STDERR "Namespace $name not found in cache, querying the wiki ...\n";
+ # NS not found => get namespace id from MW and store it in
+ # configuration file.
+ my $query = {
+ action => 'query',
+ meta => 'siteinfo',
+ siprop => 'namespaces'
+ };
+ my $result = $mediawiki->api($query);
+
+ while (my ($id, $ns) = each(%{$result->{query}->{namespaces}})) {
+ if (defined($ns->{id}) && defined($ns->{canonical})) {
+ $namespace_id{$ns->{canonical}} = $ns->{id};
+ if ($ns->{'*'}) {
+ # alias (e.g. french Fichier: as alias for canonical File:)
+ $namespace_id{$ns->{'*'}} = $ns->{id};
+ }
+ }
+ }
+ }
+
+ my $id = $namespace_id{$name};
+
+ if (defined $id) {
+ # Store explicitely requested namespaces on disk
+ if (!exists $cached_mw_namespace_id{$name}) {
+ run_git("config --add remote.". $remotename
+ .".namespaceCache \"". $name .":". $id ."\"");
+ $cached_mw_namespace_id{$name} = 1;
+ }
+ return $id;
+ } else {
+ die "No such namespace $name on MediaWiki.";
+ }
+}
--- /dev/null
+WEB/
+wiki/
+trash directory.t*/
+test-results/
--- /dev/null
+#
+# Copyright (C) 2012
+# Charles Roussel <charles.roussel@ensimag.imag.fr>
+# Simon Cathebras <simon.cathebras@ensimag.imag.fr>
+# Julien Khayat <julien.khayat@ensimag.imag.fr>
+# Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
+# Simon Perrat <simon.perrat@ensimag.imag.fr>
+#
+## Test git-remote-mediawiki
+
+all: test
+
+-include ../../../config.mak.autogen
+-include ../../../config.mak
+
+T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
+
+.PHONY: help test clean all
+
+help:
+ @echo 'Run "$(MAKE) test" to launch test scripts'
+ @echo 'Run "$(MAKE) clean" to remove trash folders'
+
+test:
+ @for t in $(T); do \
+ echo "$$t"; \
+ "./$$t" || exit 1; \
+ done
+
+clean:
+ $(RM) -r 'trash directory'.*
--- /dev/null
+Tests for Mediawiki-to-Git
+==========================
+
+Introduction
+------------
+This manual describes how to install the git-remote-mediawiki test
+environment on a machine with git installed on it.
+
+Prerequisite
+------------
+
+In order to run this test environment correctly, you will need to
+install the following packages (Debian/Ubuntu names, may need to be
+adapted for another distribution):
+
+* lighttpd
+* php5
+* php5-cgi
+* php5-cli
+* php5-curl
+* php5-sqlite
+
+Principles and Technical Choices
+--------------------------------
+
+The test environment makes it easy to install and manipulate one or
+several MediaWiki instances. To allow developers to run the testsuite
+easily, the environment does not require root priviledge (except to
+install the required packages if needed). It starts a webserver
+instance on the user's account (using lighttpd greatly helps for
+that), and does not need a separate database daemon (thanks to the use
+of sqlite).
+
+Run the test environment
+------------------------
+
+Install a new wiki
+~~~~~~~~~~~~~~~~~~
+
+Once you have all the prerequisite, you need to install a MediaWiki
+instance on your machine. If you already have one, it is still
+strongly recommended to install one with the script provided. Here's
+how to work it:
+
+a. change directory to contrib/mw-to-git/t/
+b. if needed, edit test.config to choose your installation parameters
+c. run `./install-wiki.sh install`
+d. check on your favourite web browser if your wiki is correctly
+ installed.
+
+Remove an existing wiki
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Edit the file test.config to fit the wiki you want to delete, and then
+execute the command `./install-wiki.sh delete` from the
+contrib/mw-to-git/t directory.
+
+Run the existing tests
+~~~~~~~~~~~~~~~~~~~~~~
+
+The provided tests are currently in the `contrib/mw-to-git/t` directory.
+The files are all the t936[0-9]-*.sh shell scripts.
+
+a. Run all tests:
+To do so, run "make test" from the contrib/mw-to-git/ directory.
+
+b. Run a specific test:
+To run a given test <test_name>, run ./<test_name> from the
+contrib/mw-to-git/t directory.
+
+How to create new tests
+-----------------------
+
+Available functions
+~~~~~~~~~~~~~~~~~~~
+
+The test environment of git-remote-mediawiki provides some functions
+useful to test its behaviour. for more details about the functions'
+parameters, please refer to the `test-gitmw-lib.sh` and
+`test-gitmw.pl` files.
+
+** `test_check_wiki_precond`:
+Check if the tests must be skipped or not. Please use this function
+at the beggining of each new test file.
+
+** `wiki_getpage`:
+Fetch a given page from the wiki and puts its content in the
+directory in parameter.
+
+** `wiki_delete_page`:
+Delete a given page from the wiki.
+
+** `wiki_edit_page`:
+Create or modify a given page in the wiki. You can specify several
+parameters like a summary for the page edition, or add the page to a
+given category.
+See test-gitmw.pl for more details.
+
+** `wiki_getallpage`:
+Fetch all pages from the wiki into a given directory. The directory
+is created if it does not exists.
+
+** `test_diff_directories`:
+Compare the content of two directories. The content must be the same.
+Use this function to compare the content of a git directory and a wiki
+one created by wiki_getallpage.
+
+** `test_contains_N_files`:
+Check if the given directory contains a given number of file.
+
+** `wiki_page_exists`:
+Tests if a given page exists on the wiki.
+
+** `wiki_reset`:
+Reset the wiki, i.e. flush the database. Use this function at the
+begining of each new test, except if the test re-uses the same wiki
+(and history) as the previous test.
+
+How to write a new test
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Please, follow the standards given by git. See git/t/README.
+New file should be named as t936[0-9]-*.sh.
+Be sure to reset your wiki regulary with the function `wiki_reset`.
--- /dev/null
+#!/bin/sh
+
+# This script installs or deletes a MediaWiki on your computer.
+# It requires a web server with PHP and SQLite running. In addition, if you
+# do not have MediaWiki sources on your computer, the option 'install'
+# downloads them for you.
+# Please set the CONFIGURATION VARIABLES in ./test-gitmw-lib.sh
+
+WIKI_TEST_DIR=$(cd "$(dirname "$0")" && pwd)
+
+if test -z "$WIKI_TEST_DIR"
+then
+ WIKI_TEST_DIR=.
+fi
+
+. "$WIKI_TEST_DIR"/test-gitmw-lib.sh
+usage () {
+ echo "Usage: "
+ echo " ./install-wiki.sh <install | delete | --help>"
+ echo " install | -i : Install a wiki on your computer."
+ echo " delete | -d : Delete the wiki and all its pages and "
+ echo " content."
+}
+
+
+# Argument: install, delete, --help | -h
+case "$1" in
+ "install" | "-i")
+ wiki_install
+ exit 0
+ ;;
+ "delete" | "-d")
+ wiki_delete
+ exit 0
+ ;;
+ "--help" | "-h")
+ usage
+ exit 0
+ ;;
+ *)
+ echo "Invalid argument: $1"
+ usage
+ exit 1
+ ;;
+esac
--- /dev/null
+wikidb.sqlite
--- /dev/null
+<?php
+# This file was automatically generated by the MediaWiki 1.19.0
+# installer. If you make manual changes, please keep track in case you
+# need to recreate them later.
+#
+# See includes/DefaultSettings.php for all configurable settings
+# and their default values, but don't forget to make changes in _this_
+# file, not there.
+#
+# Further documentation for configuration settings may be found at:
+# http://www.mediawiki.org/wiki/Manual:Configuration_settings
+
+# Protect against web entry
+if ( !defined( 'MEDIAWIKI' ) ) {
+ exit;
+}
+
+## Uncomment this to disable output compression
+# $wgDisableOutputCompression = true;
+
+$wgSitename = "Git-MediaWiki-Test";
+$wgMetaNamespace = "Git-MediaWiki-Test";
+
+## The URL base path to the directory containing the wiki;
+## defaults for all runtime URL paths are based off of this.
+## For more information on customizing the URLs please see:
+## http://www.mediawiki.org/wiki/Manual:Short_URL
+$wgScriptPath = "@WG_SCRIPT_PATH@";
+$wgScriptExtension = ".php";
+
+## The protocol and server name to use in fully-qualified URLs
+$wgServer = "@WG_SERVER@";
+
+## The relative URL path to the skins directory
+$wgStylePath = "$wgScriptPath/skins";
+
+## The relative URL path to the logo. Make sure you change this from the default,
+## or else you'll overwrite your logo when you upgrade!
+$wgLogo = "$wgStylePath/common/images/wiki.png";
+
+## UPO means: this is also a user preference option
+
+$wgEnableEmail = true;
+$wgEnableUserEmail = true; # UPO
+
+$wgEmergencyContact = "apache@localhost";
+$wgPasswordSender = "apache@localhost";
+
+$wgEnotifUserTalk = false; # UPO
+$wgEnotifWatchlist = false; # UPO
+$wgEmailAuthentication = true;
+
+## Database settings
+$wgDBtype = "sqlite";
+$wgDBserver = "";
+$wgDBname = "@WG_SQLITE_DATAFILE@";
+$wgDBuser = "";
+$wgDBpassword = "";
+
+# SQLite-specific settings
+$wgSQLiteDataDir = "@WG_SQLITE_DATADIR@";
+
+
+## Shared memory settings
+$wgMainCacheType = CACHE_NONE;
+$wgMemCachedServers = array();
+
+## To enable image uploads, make sure the 'images' directory
+## is writable, then set this to true:
+$wgEnableUploads = true;
+$wgUseImageMagick = true;
+$wgImageMagickConvertCommand ="@CONVERT@";
+$wgFileExtensions[] = 'txt';
+
+# InstantCommons allows wiki to use images from http://commons.wikimedia.org
+$wgUseInstantCommons = false;
+
+## If you use ImageMagick (or any other shell command) on a
+## Linux server, this will need to be set to the name of an
+## available UTF-8 locale
+$wgShellLocale = "en_US.utf8";
+
+## If you want to use image uploads under safe mode,
+## create the directories images/archive, images/thumb and
+## images/temp, and make them all writable. Then uncomment
+## this, if it's not already uncommented:
+#$wgHashedUploadDirectory = false;
+
+## Set $wgCacheDirectory to a writable directory on the web server
+## to make your wiki go slightly faster. The directory should not
+## be publically accessible from the web.
+#$wgCacheDirectory = "$IP/cache";
+
+# Site language code, should be one of the list in ./languages/Names.php
+$wgLanguageCode = "en";
+
+$wgSecretKey = "1c912bfe3519fb70f5dc523ecc698111cd43d81a11c585b3eefb28f29c2699b7";
+#$wgSecretKey = "@SECRETKEY@";
+
+
+# Site upgrade key. Must be set to a string (default provided) to turn on the
+# web installer while LocalSettings.php is in place
+$wgUpgradeKey = "ddae7dc87cd0a645";
+
+## Default skin: you can change the default skin. Use the internal symbolic
+## names, ie 'standard', 'nostalgia', 'cologneblue', 'monobook', 'vector':
+$wgDefaultSkin = "vector";
+
+## For attaching licensing metadata to pages, and displaying an
+## appropriate copyright notice / icon. GNU Free Documentation
+## License and Creative Commons licenses are supported so far.
+$wgRightsPage = ""; # Set to the title of a wiki page that describes your license/copyright
+$wgRightsUrl = "";
+$wgRightsText = "";
+$wgRightsIcon = "";
+
+# Path to the GNU diff3 utility. Used for conflict resolution.
+$wgDiff3 = "/usr/bin/diff3";
+
+# Query string length limit for ResourceLoader. You should only set this if
+# your web server has a query string length limit (then set it to that limit),
+# or if you have suhosin.get.max_value_length set in php.ini (then set it to
+# that value)
+$wgResourceLoaderMaxQueryLength = -1;
+
+
+
+# End of automatically generated settings.
+# Add more configuration options below.
--- /dev/null
+<?php
+/**
+ * This script generates a SQLite database for a MediaWiki version 1.19.0
+ * You must specify the login of the admin (argument 1) and its
+ * password (argument 2) and the folder where the database file
+ * is located (absolute path in argument 3).
+ * It is used by the script install-wiki.sh in order to make easy the
+ * installation of a MediaWiki.
+ *
+ * In order to generate a SQLite database file, MediaWiki ask the user
+ * to submit some forms in its web browser. This script simulates this
+ * behavior though the functions <get> and <submit>
+ *
+ */
+$argc = $_SERVER['argc'];
+$argv = $_SERVER['argv'];
+
+$login = $argv[2];
+$pass = $argv[3];
+$tmp = $argv[4];
+$port = $argv[5];
+
+$url = 'http://localhost:'.$port.'/wiki/mw-config/index.php';
+$db_dir = urlencode($tmp);
+$tmp_cookie = tempnam($tmp, "COOKIE_");
+/*
+ * Fetchs a page with cURL.
+ */
+function get($page_name = "") {
+ $curl = curl_init();
+ $page_name_add = "";
+ if ($page_name != "") {
+ $page_name_add = '?page='.$page_name;
+ }
+ $url = $GLOBALS['url'].$page_name_add;
+ $tmp_cookie = $GLOBALS['tmp_cookie'];
+ curl_setopt($curl, CURLOPT_COOKIEJAR, $tmp_cookie);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($curl, CURLOPT_COOKIEFILE, $tmp_cookie);
+ curl_setopt($curl, CURLOPT_HEADER, true);
+ curl_setopt($curl, CURLOPT_URL, $url);
+
+ $page = curl_exec($curl);
+ if (!$page) {
+ die("Could not get page: $url\n");
+ }
+ curl_close($curl);
+ return $page;
+}
+
+/*
+ * Submits a form with cURL.
+ */
+function submit($page_name, $option = "") {
+ $curl = curl_init();
+ $datapost = 'submit-continue=Continue+%E2%86%92';
+ if ($option != "") {
+ $datapost = $option.'&'.$datapost;
+ }
+ $url = $GLOBALS['url'].'?page='.$page_name;
+ $tmp_cookie = $GLOBALS['tmp_cookie'];
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_POST, true);
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $datapost);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_COOKIEJAR, $tmp_cookie);
+ curl_setopt($curl, CURLOPT_COOKIEFILE, $tmp_cookie);
+
+ $page = curl_exec($curl);
+ if (!$page) {
+ die("Could not get page: $url\n");
+ }
+ curl_close($curl);
+ return "$page";
+}
+
+/*
+ * Here starts this script: simulates the behavior of the user
+ * submitting forms to generates the database file.
+ * Note this simulation was made for the MediaWiki version 1.19.0,
+ * we can't assume it works with other versions.
+ *
+ */
+
+$page = get();
+if (!preg_match('/input type="hidden" value="([0-9]+)" name="LanguageRequestTime"/',
+ $page, $matches)) {
+ echo "Unexpected content for page downloaded:\n";
+ echo "$page";
+ die;
+};
+$timestamp = $matches[1];
+$language = "LanguageRequestTime=$timestamp&uselang=en&ContLang=en";
+$page = submit('Language', $language);
+
+submit('Welcome');
+
+$db_config = 'DBType=sqlite';
+$db_config = $db_config.'&sqlite_wgSQLiteDataDir='.$db_dir;
+$db_config = $db_config.'&sqlite_wgDBname='.$argv[1];
+submit('DBConnect', $db_config);
+
+$wiki_config = 'config_wgSitename=TEST';
+$wiki_config = $wiki_config.'&config__NamespaceType=site-name';
+$wiki_config = $wiki_config.'&config_wgMetaNamespace=MyWiki';
+$wiki_config = $wiki_config.'&config__AdminName='.$login;
+
+$wiki_config = $wiki_config.'&config__AdminPassword='.$pass;
+$wiki_config = $wiki_config.'&config__AdminPassword2='.$pass;
+
+$wiki_config = $wiki_config.'&wiki__configEmail=email%40email.org';
+$wiki_config = $wiki_config.'&config__SkipOptional=skip';
+submit('Name', $wiki_config);
+submit('Install');
+submit('Install');
+
+unlink($tmp_cookie);
+?>
--- /dev/null
+test_push_pull () {
+
+ test_expect_success 'Git pull works after adding a new wiki page' '
+ wiki_reset &&
+
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_1 &&
+ wiki_editpage Foo "page created after the git clone" false &&
+
+ (
+ cd mw_dir_1 &&
+ git pull
+ ) &&
+
+ wiki_getallpage ref_page_1 &&
+ test_diff_directories mw_dir_1 ref_page_1
+ '
+
+ test_expect_success 'Git pull works after editing a wiki page' '
+ wiki_reset &&
+
+ wiki_editpage Foo "page created before the git clone" false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_2 &&
+ wiki_editpage Foo "new line added on the wiki" true &&
+
+ (
+ cd mw_dir_2 &&
+ git pull
+ ) &&
+
+ wiki_getallpage ref_page_2 &&
+ test_diff_directories mw_dir_2 ref_page_2
+ '
+
+ test_expect_success 'git pull works on conflict handled by auto-merge' '
+ wiki_reset &&
+
+ wiki_editpage Foo "1 init
+3
+5
+ " false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_3 &&
+
+ wiki_editpage Foo "1 init
+2 content added on wiki after clone
+3
+5
+ " false &&
+
+ (
+ cd mw_dir_3 &&
+ echo "1 init
+3
+4 content added on git after clone
+5
+" >Foo.mw &&
+ git commit -am "conflicting change on foo" &&
+ git pull &&
+ git push
+ )
+ '
+
+ test_expect_success 'Git push works after adding a file .mw' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_4 &&
+ wiki_getallpage ref_page_4 &&
+ (
+ cd mw_dir_4 &&
+ test_path_is_missing Foo.mw &&
+ touch Foo.mw &&
+ echo "hello world" >>Foo.mw &&
+ git add Foo.mw &&
+ git commit -m "Foo" &&
+ git push
+ ) &&
+ wiki_getallpage ref_page_4 &&
+ test_diff_directories mw_dir_4 ref_page_4
+ '
+
+ test_expect_success 'Git push works after editing a file .mw' '
+ wiki_reset &&
+ wiki_editpage "Foo" "page created before the git clone" false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_5 &&
+
+ (
+ cd mw_dir_5 &&
+ echo "new line added in the file Foo.mw" >>Foo.mw &&
+ git commit -am "edit file Foo.mw" &&
+ git push
+ ) &&
+
+ wiki_getallpage ref_page_5 &&
+ test_diff_directories mw_dir_5 ref_page_5
+ '
+
+ test_expect_failure 'Git push works after deleting a file' '
+ wiki_reset &&
+ wiki_editpage Foo "wiki page added before git clone" false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_6 &&
+
+ (
+ cd mw_dir_6 &&
+ git rm Foo.mw &&
+ git commit -am "page Foo.mw deleted" &&
+ git push
+ ) &&
+
+ test ! wiki_page_exist Foo
+ '
+
+ test_expect_success 'Merge conflict expected and solving it' '
+ wiki_reset &&
+
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_7 &&
+ wiki_editpage Foo "1 conflict
+3 wiki
+4" false &&
+
+ (
+ cd mw_dir_7 &&
+ echo "1 conflict
+2 git
+4" >Foo.mw &&
+ git add Foo.mw &&
+ git commit -m "conflict created" &&
+ test_must_fail git pull &&
+ "$PERL_PATH" -pi -e "s/[<=>].*//g" Foo.mw &&
+ git commit -am "merge conflict solved" &&
+ git push
+ )
+ '
+
+ test_expect_failure 'git pull works after deleting a wiki page' '
+ wiki_reset &&
+ wiki_editpage Foo "wiki page added before the git clone" false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_8 &&
+
+ wiki_delete_page Foo &&
+ (
+ cd mw_dir_8 &&
+ git pull &&
+ test_path_is_missing Foo.mw
+ )
+ '
+}
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2012
+# Charles Roussel <charles.roussel@ensimag.imag.fr>
+# Simon Cathebras <simon.cathebras@ensimag.imag.fr>
+# Julien Khayat <julien.khayat@ensimag.imag.fr>
+# Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
+# Simon Perrat <simon.perrat@ensimag.imag.fr>
+#
+# License: GPL v2 or later
+
+
+test_description='Test the Git Mediawiki remote helper: git clone'
+
+. ./test-gitmw-lib.sh
+. $TEST_DIRECTORY/test-lib.sh
+
+
+test_check_precond
+
+
+test_expect_success 'Git clone creates the expected git log with one file' '
+ wiki_reset &&
+ wiki_editpage foo "this is not important" false -c cat -s "this must be the same" &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_1 &&
+ (
+ cd mw_dir_1 &&
+ git log --format=%s HEAD^..HEAD >log.tmp
+ ) &&
+ echo "this must be the same" >msg.tmp &&
+ diff -b mw_dir_1/log.tmp msg.tmp
+'
+
+
+test_expect_success 'Git clone creates the expected git log with multiple files' '
+ wiki_reset &&
+ wiki_editpage daddy "this is not important" false -s="this must be the same" &&
+ wiki_editpage daddy "neither is this" true -s="this must also be the same" &&
+ wiki_editpage daddy "neither is this" true -s="same same same" &&
+ wiki_editpage dj "dont care" false -s="identical" &&
+ wiki_editpage dj "dont care either" true -s="identical too" &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_2 &&
+ (
+ cd mw_dir_2 &&
+ git log --format=%s Daddy.mw >logDaddy.tmp &&
+ git log --format=%s Dj.mw >logDj.tmp
+ ) &&
+ echo "same same same" >msgDaddy.tmp &&
+ echo "this must also be the same" >>msgDaddy.tmp &&
+ echo "this must be the same" >>msgDaddy.tmp &&
+ echo "identical too" >msgDj.tmp &&
+ echo "identical" >>msgDj.tmp &&
+ diff -b mw_dir_2/logDaddy.tmp msgDaddy.tmp &&
+ diff -b mw_dir_2/logDj.tmp msgDj.tmp
+'
+
+
+test_expect_success 'Git clone creates only Main_Page.mw with an empty wiki' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_3 &&
+ test_contains_N_files mw_dir_3 1 &&
+ test_path_is_file mw_dir_3/Main_Page.mw
+'
+
+test_expect_success 'Git clone does not fetch a deleted page' '
+ wiki_reset &&
+ wiki_editpage foo "this page must be deleted before the clone" false &&
+ wiki_delete_page foo &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_4 &&
+ test_contains_N_files mw_dir_4 1 &&
+ test_path_is_file mw_dir_4/Main_Page.mw &&
+ test_path_is_missing mw_dir_4/Foo.mw
+'
+
+test_expect_success 'Git clone works with page added' '
+ wiki_reset &&
+ wiki_editpage foo " I will be cloned" false &&
+ wiki_editpage bar "I will be cloned" false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_5 &&
+ wiki_getallpage ref_page_5 &&
+ test_diff_directories mw_dir_5 ref_page_5 &&
+ wiki_delete_page foo &&
+ wiki_delete_page bar
+'
+
+test_expect_success 'Git clone works with an edited page ' '
+ wiki_reset &&
+ wiki_editpage foo "this page will be edited" \
+ false -s "first edition of page foo"&&
+ wiki_editpage foo "this page has been edited and must be on the clone " true &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_6 &&
+ test_path_is_file mw_dir_6/Foo.mw &&
+ test_path_is_file mw_dir_6/Main_Page.mw &&
+ wiki_getallpage mw_dir_6/page_ref_6 &&
+ test_diff_directories mw_dir_6 mw_dir_6/page_ref_6 &&
+ (
+ cd mw_dir_6 &&
+ git log --format=%s HEAD^ Foo.mw > ../Foo.log
+ ) &&
+ echo "first edition of page foo" > FooExpect.log &&
+ diff FooExpect.log Foo.log
+'
+
+
+test_expect_success 'Git clone works with several pages and some deleted ' '
+ wiki_reset &&
+ wiki_editpage foo "this page will not be deleted" false &&
+ wiki_editpage bar "I must not be erased" false &&
+ wiki_editpage namnam "I will not be there at the end" false &&
+ wiki_editpage nyancat "nyan nyan nyan delete me" false &&
+ wiki_delete_page namnam &&
+ wiki_delete_page nyancat &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_7 &&
+ test_path_is_file mw_dir_7/Foo.mw &&
+ test_path_is_file mw_dir_7/Bar.mw &&
+ test_path_is_missing mw_dir_7/Namnam.mw &&
+ test_path_is_missing mw_dir_7/Nyancat.mw &&
+ wiki_getallpage mw_dir_7/page_ref_7 &&
+ test_diff_directories mw_dir_7 mw_dir_7/page_ref_7
+'
+
+
+test_expect_success 'Git clone works with one specific page cloned ' '
+ wiki_reset &&
+ wiki_editpage foo "I will not be cloned" false &&
+ wiki_editpage bar "Do not clone me" false &&
+ wiki_editpage namnam "I will be cloned :)" false -s="this log must stay" &&
+ wiki_editpage nyancat "nyan nyan nyan you cant clone me" false &&
+ git clone -c remote.origin.pages=namnam \
+ mediawiki::'"$WIKI_URL"' mw_dir_8 &&
+ test_contains_N_files mw_dir_8 1 &&
+ test_path_is_file mw_dir_8/Namnam.mw &&
+ test_path_is_missing mw_dir_8/Main_Page.mw &&
+ (
+ cd mw_dir_8 &&
+ echo "this log must stay" >msg.tmp &&
+ git log --format=%s >log.tmp &&
+ diff -b msg.tmp log.tmp
+ ) &&
+ wiki_check_content mw_dir_8/Namnam.mw Namnam
+'
+
+test_expect_success 'Git clone works with multiple specific page cloned ' '
+ wiki_reset &&
+ wiki_editpage foo "I will be there" false &&
+ wiki_editpage bar "I will not disapear" false &&
+ wiki_editpage namnam "I be erased" false &&
+ wiki_editpage nyancat "nyan nyan nyan you will not erase me" false &&
+ wiki_delete_page namnam &&
+ git clone -c remote.origin.pages="foo bar nyancat namnam" \
+ mediawiki::'"$WIKI_URL"' mw_dir_9 &&
+ test_contains_N_files mw_dir_9 3 &&
+ test_path_is_missing mw_dir_9/Namnam.mw &&
+ test_path_is_file mw_dir_9/Foo.mw &&
+ test_path_is_file mw_dir_9/Nyancat.mw &&
+ test_path_is_file mw_dir_9/Bar.mw &&
+ wiki_check_content mw_dir_9/Foo.mw Foo &&
+ wiki_check_content mw_dir_9/Bar.mw Bar &&
+ wiki_check_content mw_dir_9/Nyancat.mw Nyancat
+'
+
+test_expect_success 'Mediawiki-clone of several specific pages on wiki' '
+ wiki_reset &&
+ wiki_editpage foo "foo 1" false &&
+ wiki_editpage bar "bar 1" false &&
+ wiki_editpage dummy "dummy 1" false &&
+ wiki_editpage cloned_1 "cloned_1 1" false &&
+ wiki_editpage cloned_2 "cloned_2 2" false &&
+ wiki_editpage cloned_3 "cloned_3 3" false &&
+ mkdir -p ref_page_10 &&
+ wiki_getpage cloned_1 ref_page_10 &&
+ wiki_getpage cloned_2 ref_page_10 &&
+ wiki_getpage cloned_3 ref_page_10 &&
+ git clone -c remote.origin.pages="cloned_1 cloned_2 cloned_3" \
+ mediawiki::'"$WIKI_URL"' mw_dir_10 &&
+ test_diff_directories mw_dir_10 ref_page_10
+'
+
+test_expect_success 'Git clone works with the shallow option' '
+ wiki_reset &&
+ wiki_editpage foo "1st revision, should be cloned" false &&
+ wiki_editpage bar "1st revision, should be cloned" false &&
+ wiki_editpage nyan "1st revision, should not be cloned" false &&
+ wiki_editpage nyan "2nd revision, should be cloned" false &&
+ git -c remote.origin.shallow=true clone \
+ mediawiki::'"$WIKI_URL"' mw_dir_11 &&
+ test_contains_N_files mw_dir_11 4 &&
+ test_path_is_file mw_dir_11/Nyan.mw &&
+ test_path_is_file mw_dir_11/Foo.mw &&
+ test_path_is_file mw_dir_11/Bar.mw &&
+ test_path_is_file mw_dir_11/Main_Page.mw &&
+ (
+ cd mw_dir_11 &&
+ test `git log --oneline Nyan.mw | wc -l` -eq 1 &&
+ test `git log --oneline Foo.mw | wc -l` -eq 1 &&
+ test `git log --oneline Bar.mw | wc -l` -eq 1 &&
+ test `git log --oneline Main_Page.mw | wc -l ` -eq 1
+ ) &&
+ wiki_check_content mw_dir_11/Nyan.mw Nyan &&
+ wiki_check_content mw_dir_11/Foo.mw Foo &&
+ wiki_check_content mw_dir_11/Bar.mw Bar &&
+ wiki_check_content mw_dir_11/Main_Page.mw Main_Page
+'
+
+test_expect_success 'Git clone works with the shallow option with a delete page' '
+ wiki_reset &&
+ wiki_editpage foo "1st revision, will be deleted" false &&
+ wiki_editpage bar "1st revision, should be cloned" false &&
+ wiki_editpage nyan "1st revision, should not be cloned" false &&
+ wiki_editpage nyan "2nd revision, should be cloned" false &&
+ wiki_delete_page foo &&
+ git -c remote.origin.shallow=true clone \
+ mediawiki::'"$WIKI_URL"' mw_dir_12 &&
+ test_contains_N_files mw_dir_12 3 &&
+ test_path_is_file mw_dir_12/Nyan.mw &&
+ test_path_is_missing mw_dir_12/Foo.mw &&
+ test_path_is_file mw_dir_12/Bar.mw &&
+ test_path_is_file mw_dir_12/Main_Page.mw &&
+ (
+ cd mw_dir_12 &&
+ test `git log --oneline Nyan.mw | wc -l` -eq 1 &&
+ test `git log --oneline Bar.mw | wc -l` -eq 1 &&
+ test `git log --oneline Main_Page.mw | wc -l ` -eq 1
+ ) &&
+ wiki_check_content mw_dir_12/Nyan.mw Nyan &&
+ wiki_check_content mw_dir_12/Bar.mw Bar &&
+ wiki_check_content mw_dir_12/Main_Page.mw Main_Page
+'
+
+test_expect_success 'Test of fetching a category' '
+ wiki_reset &&
+ wiki_editpage Foo "I will be cloned" false -c=Category &&
+ wiki_editpage Bar "Meet me on the repository" false -c=Category &&
+ wiki_editpage Dummy "I will not come" false &&
+ wiki_editpage BarWrong "I will stay online only" false -c=NotCategory &&
+ git clone -c remote.origin.categories="Category" \
+ mediawiki::'"$WIKI_URL"' mw_dir_13 &&
+ wiki_getallpage ref_page_13 Category &&
+ test_diff_directories mw_dir_13 ref_page_13
+'
+
+test_expect_success 'Test of resistance to modification of category on wiki for clone' '
+ wiki_reset &&
+ wiki_editpage Tobedeleted "this page will be deleted" false -c=Catone &&
+ wiki_editpage Tobeedited "this page will be modified" false -c=Catone &&
+ wiki_editpage Normalone "this page wont be modified and will be on git" false -c=Catone &&
+ wiki_editpage Notconsidered "this page will not appear on local" false &&
+ wiki_editpage Othercategory "this page will not appear on local" false -c=Cattwo &&
+ wiki_editpage Tobeedited "this page have been modified" true -c=Catone &&
+ wiki_delete_page Tobedeleted
+ git clone -c remote.origin.categories="Catone" \
+ mediawiki::'"$WIKI_URL"' mw_dir_14 &&
+ wiki_getallpage ref_page_14 Catone &&
+ test_diff_directories mw_dir_14 ref_page_14
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2012
+# Charles Roussel <charles.roussel@ensimag.imag.fr>
+# Simon Cathebras <simon.cathebras@ensimag.imag.fr>
+# Julien Khayat <julien.khayat@ensimag.imag.fr>
+# Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
+# Simon Perrat <simon.perrat@ensimag.imag.fr>
+#
+# License: GPL v2 or later
+
+# tests for git-remote-mediawiki
+
+test_description='Test the Git Mediawiki remote helper: git push and git pull simple test cases'
+
+. ./test-gitmw-lib.sh
+. ./push-pull-tests.sh
+. $TEST_DIRECTORY/test-lib.sh
+
+test_check_precond
+
+test_push_pull
+
+test_done
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2012
+# Charles Roussel <charles.roussel@ensimag.imag.fr>
+# Simon Cathebras <simon.cathebras@ensimag.imag.fr>
+# Julien Khayat <julien.khayat@ensimag.imag.fr>
+# Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
+# Simon Perrat <simon.perrat@ensimag.imag.fr>
+#
+# License: GPL v2 or later
+
+# tests for git-remote-mediawiki
+
+test_description='Test git-mediawiki with special characters in filenames'
+
+. ./test-gitmw-lib.sh
+. $TEST_DIRECTORY/test-lib.sh
+
+
+test_check_precond
+
+
+test_expect_success 'Git clone works for a wiki with accents in the page names' '
+ wiki_reset &&
+ wiki_editpage féé "This page must be délétéd before clone" false &&
+ wiki_editpage kèè "This page must be deleted before clone" false &&
+ wiki_editpage hàà "This page must be deleted before clone" false &&
+ wiki_editpage kîî "This page must be deleted before clone" false &&
+ wiki_editpage foo "This page must be deleted before clone" false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_1 &&
+ wiki_getallpage ref_page_1 &&
+ test_diff_directories mw_dir_1 ref_page_1
+'
+
+
+test_expect_success 'Git pull works with a wiki with accents in the pages names' '
+ wiki_reset &&
+ wiki_editpage kîî "this page must be cloned" false &&
+ wiki_editpage foo "this page must be cloned" false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_2 &&
+ wiki_editpage éàîôû "This page must be pulled" false &&
+ (
+ cd mw_dir_2 &&
+ git pull
+ ) &&
+ wiki_getallpage ref_page_2 &&
+ test_diff_directories mw_dir_2 ref_page_2
+'
+
+
+test_expect_success 'Cloning a chosen page works with accents' '
+ wiki_reset &&
+ wiki_editpage kîî "this page must be cloned" false &&
+ git clone -c remote.origin.pages=kîî \
+ mediawiki::'"$WIKI_URL"' mw_dir_3 &&
+ wiki_check_content mw_dir_3/Kîî.mw Kîî &&
+ test_path_is_file mw_dir_3/Kîî.mw &&
+ rm -rf mw_dir_3
+'
+
+
+test_expect_success 'The shallow option works with accents' '
+ wiki_reset &&
+ wiki_editpage néoà "1st revision, should not be cloned" false &&
+ wiki_editpage néoà "2nd revision, should be cloned" false &&
+ git -c remote.origin.shallow=true clone \
+ mediawiki::'"$WIKI_URL"' mw_dir_4 &&
+ test_contains_N_files mw_dir_4 2 &&
+ test_path_is_file mw_dir_4/Néoà.mw &&
+ test_path_is_file mw_dir_4/Main_Page.mw &&
+ (
+ cd mw_dir_4 &&
+ test `git log --oneline Néoà.mw | wc -l` -eq 1 &&
+ test `git log --oneline Main_Page.mw | wc -l ` -eq 1
+ ) &&
+ wiki_check_content mw_dir_4/Néoà.mw Néoà &&
+ wiki_check_content mw_dir_4/Main_Page.mw Main_Page
+'
+
+
+test_expect_success 'Cloning works when page name first letter has an accent' '
+ wiki_reset &&
+ wiki_editpage îî "this page must be cloned" false &&
+ git clone -c remote.origin.pages=îî \
+ mediawiki::'"$WIKI_URL"' mw_dir_5 &&
+ test_path_is_file mw_dir_5/Îî.mw &&
+ wiki_check_content mw_dir_5/Îî.mw Îî
+'
+
+
+test_expect_success 'Git push works with a wiki with accents' '
+ wiki_reset &&
+ wiki_editpage féé "lots of accents : éèàÖ" false &&
+ wiki_editpage foo "this page must be cloned" false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_6 &&
+ (
+ cd mw_dir_6 &&
+ echo "A wild Pîkächû appears on the wiki" >Pîkächû.mw &&
+ git add Pîkächû.mw &&
+ git commit -m "A new page appears" &&
+ git push
+ ) &&
+ wiki_getallpage ref_page_6 &&
+ test_diff_directories mw_dir_6 ref_page_6
+'
+
+test_expect_success 'Git clone works with accentsand spaces' '
+ wiki_reset &&
+ wiki_editpage "é à î" "this page must be délété before the clone" false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_7 &&
+ wiki_getallpage ref_page_7 &&
+ test_diff_directories mw_dir_7 ref_page_7
+'
+
+test_expect_success 'character $ in page name (mw -> git)' '
+ wiki_reset &&
+ wiki_editpage file_\$_foo "expect to be called file_$_foo" false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_8 &&
+ test_path_is_file mw_dir_8/File_\$_foo.mw &&
+ wiki_getallpage ref_page_8 &&
+ test_diff_directories mw_dir_8 ref_page_8
+'
+
+
+
+test_expect_success 'character $ in file name (git -> mw) ' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_9 &&
+ (
+ cd mw_dir_9 &&
+ echo "this file is called File_\$_foo.mw" >File_\$_foo.mw &&
+ git add . &&
+ git commit -am "file File_\$_foo.mw" &&
+ git pull &&
+ git push
+ ) &&
+ wiki_getallpage ref_page_9 &&
+ test_diff_directories mw_dir_9 ref_page_9
+'
+
+
+test_expect_failure 'capital at the begining of file names' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_10 &&
+ (
+ cd mw_dir_10 &&
+ echo "my new file foo" >foo.mw &&
+ echo "my new file Foo... Finger crossed" >Foo.mw &&
+ git add . &&
+ git commit -am "file foo.mw" &&
+ git pull &&
+ git push
+ ) &&
+ wiki_getallpage ref_page_10 &&
+ test_diff_directories mw_dir_10 ref_page_10
+'
+
+
+test_expect_failure 'special character at the begining of file name from mw to git' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_11 &&
+ wiki_editpage {char_1 "expect to be renamed {char_1" false &&
+ wiki_editpage [char_2 "expect to be renamed [char_2" false &&
+ (
+ cd mw_dir_11 &&
+ git pull
+ ) &&
+ test_path_is_file mw_dir_11/{char_1 &&
+ test_path_is_file mw_dir_11/[char_2
+'
+
+test_expect_success 'test of correct formating for file name from mw to git' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_12 &&
+ wiki_editpage char_%_7b_1 "expect to be renamed char{_1" false &&
+ wiki_editpage char_%_5b_2 "expect to be renamed char{_2" false &&
+ (
+ cd mw_dir_12 &&
+ git pull
+ ) &&
+ test_path_is_file mw_dir_12/Char\{_1.mw &&
+ test_path_is_file mw_dir_12/Char\[_2.mw &&
+ wiki_getallpage ref_page_12 &&
+ mv ref_page_12/Char_%_7b_1.mw ref_page_12/Char\{_1.mw &&
+ mv ref_page_12/Char_%_5b_2.mw ref_page_12/Char\[_2.mw &&
+ test_diff_directories mw_dir_12 ref_page_12
+'
+
+
+test_expect_failure 'test of correct formating for file name begining with special character' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_13 &&
+ (
+ cd mw_dir_13 &&
+ echo "my new file {char_1" >\{char_1.mw &&
+ echo "my new file [char_2" >\[char_2.mw &&
+ git add . &&
+ git commit -am "commiting some exotic file name..." &&
+ git push &&
+ git pull
+ ) &&
+ wiki_getallpage ref_page_13 &&
+ test_path_is_file ref_page_13/{char_1.mw &&
+ test_path_is_file ref_page_13/[char_2.mw &&
+ test_diff_directories mw_dir_13 ref_page_13
+'
+
+
+test_expect_success 'test of correct formating for file name from git to mw' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_14 &&
+ (
+ cd mw_dir_14 &&
+ echo "my new file char{_1" >Char\{_1.mw &&
+ echo "my new file char[_2" >Char\[_2.mw &&
+ git add . &&
+ git commit -m "commiting some exotic file name..." &&
+ git push
+ ) &&
+ wiki_getallpage ref_page_14 &&
+ mv mw_dir_14/Char\{_1.mw mw_dir_14/Char_%_7b_1.mw &&
+ mv mw_dir_14/Char\[_2.mw mw_dir_14/Char_%_5b_2.mw &&
+ test_diff_directories mw_dir_14 ref_page_14
+'
+
+
+test_expect_success 'git clone with /' '
+ wiki_reset &&
+ wiki_editpage \/fo\/o "this is not important" false -c=Deleted &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_15 &&
+ test_path_is_file mw_dir_15/%2Ffo%2Fo.mw &&
+ wiki_check_content mw_dir_15/%2Ffo%2Fo.mw \/fo\/o
+'
+
+
+test_expect_success 'git push with /' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_16 &&
+ echo "I will be on the wiki" >mw_dir_16/%2Ffo%2Fo.mw &&
+ (
+ cd mw_dir_16 &&
+ git add %2Ffo%2Fo.mw &&
+ git commit -m " %2Ffo%2Fo added" &&
+ git push
+ ) &&
+ wiki_page_exist \/fo\/o &&
+ wiki_check_content mw_dir_16/%2Ffo%2Fo.mw \/fo\/o
+
+'
+
+
+test_expect_success 'git clone with \' '
+ wiki_reset &&
+ wiki_editpage \\ko\\o "this is not important" false -c=Deleted &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_17 &&
+ test_path_is_file mw_dir_17/\\ko\\o.mw &&
+ wiki_check_content mw_dir_17/\\ko\\o.mw \\ko\\o
+'
+
+
+test_expect_success 'git push with \' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_18 &&
+ echo "I will be on the wiki" >mw_dir_18/\\ko\\o.mw &&
+ (
+ cd mw_dir_18 &&
+ git add \\ko\\o.mw &&
+ git commit -m " \\ko\\o added" &&
+ git push
+ )&&
+ wiki_page_exist \\ko\\o &&
+ wiki_check_content mw_dir_18/\\ko\\o.mw \\ko\\o
+
+'
+
+test_expect_success 'git clone with \ in format control' '
+ wiki_reset &&
+ wiki_editpage \\no\\o "this is not important" false &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_19 &&
+ test_path_is_file mw_dir_19/\\no\\o.mw &&
+ wiki_check_content mw_dir_19/\\no\\o.mw \\no\\o
+'
+
+
+test_expect_success 'git push with \ in format control' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir_20 &&
+ echo "I will be on the wiki" >mw_dir_20/\\fo\\o.mw &&
+ (
+ cd mw_dir_20 &&
+ git add \\fo\\o.mw &&
+ git commit -m " \\fo\\o added" &&
+ git push
+ )&&
+ wiki_page_exist \\fo\\o &&
+ wiki_check_content mw_dir_20/\\fo\\o.mw \\fo\\o
+
+'
+
+
+test_done
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2012
+# Charles Roussel <charles.roussel@ensimag.imag.fr>
+# Simon Cathebras <simon.cathebras@ensimag.imag.fr>
+# Julien Khayat <julien.khayat@ensimag.imag.fr>
+# Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
+# Simon Perrat <simon.perrat@ensimag.imag.fr>
+#
+# License: GPL v2 or later
+
+# tests for git-remote-mediawiki
+
+test_description='Test the Git Mediawiki remote helper: git push and git pull simple test cases'
+
+. ./test-gitmw-lib.sh
+. $TEST_DIRECTORY/test-lib.sh
+
+
+test_check_precond
+
+
+test_git_reimport () {
+ git -c remote.origin.dumbPush=true push &&
+ git -c remote.origin.mediaImport=true pull --rebase
+}
+
+# Don't bother with permissions, be administrator by default
+test_expect_success 'setup config' '
+ git config --global remote.origin.mwLogin WikiAdmin &&
+ git config --global remote.origin.mwPassword AdminPass &&
+ test_might_fail git config --global --unset remote.origin.mediaImport
+'
+
+test_expect_success 'git push can upload media (File:) files' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir &&
+ (
+ cd mw_dir &&
+ echo "hello world" >Foo.txt &&
+ git add Foo.txt &&
+ git commit -m "add a text file" &&
+ git push &&
+ "$PERL_PATH" -e "print STDOUT \"binary content: \".chr(255);" >Foo.txt &&
+ git add Foo.txt &&
+ git commit -m "add a text file with binary content" &&
+ git push
+ )
+'
+
+test_expect_success 'git clone works on previously created wiki with media files' '
+ test_when_finished "rm -rf mw_dir mw_dir_clone" &&
+ git clone -c remote.origin.mediaimport=true \
+ mediawiki::'"$WIKI_URL"' mw_dir_clone &&
+ test_cmp mw_dir_clone/Foo.txt mw_dir/Foo.txt &&
+ (cd mw_dir_clone && git checkout HEAD^) &&
+ (cd mw_dir && git checkout HEAD^) &&
+ test_cmp mw_dir_clone/Foo.txt mw_dir/Foo.txt
+'
+
+test_expect_success 'git push & pull work with locally renamed media files' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir &&
+ test_when_finished "rm -fr mw_dir" &&
+ (
+ cd mw_dir &&
+ echo "A File" >Foo.txt &&
+ git add Foo.txt &&
+ git commit -m "add a file" &&
+ git mv Foo.txt Bar.txt &&
+ git commit -m "Rename a file" &&
+ test_git_reimport &&
+ echo "A File" >expect &&
+ test_cmp expect Bar.txt &&
+ test_path_is_missing Foo.txt
+ )
+'
+
+test_expect_success 'git push can propagate local page deletion' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir &&
+ test_when_finished "rm -fr mw_dir" &&
+ (
+ cd mw_dir &&
+ test_path_is_missing Foo.mw &&
+ echo "hello world" >Foo.mw &&
+ git add Foo.mw &&
+ git commit -m "Add the page Foo" &&
+ git push &&
+ rm -f Foo.mw &&
+ git commit -am "Delete the page Foo" &&
+ test_git_reimport &&
+ test_path_is_missing Foo.mw
+ )
+'
+
+test_expect_success 'git push can propagate local media file deletion' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir &&
+ test_when_finished "rm -fr mw_dir" &&
+ (
+ cd mw_dir &&
+ echo "hello world" >Foo.txt &&
+ git add Foo.txt &&
+ git commit -m "Add the text file Foo" &&
+ git rm Foo.txt &&
+ git commit -m "Delete the file Foo" &&
+ test_git_reimport &&
+ test_path_is_missing Foo.txt
+ )
+'
+
+# test failure: the file is correctly uploaded, and then deleted but
+# as no page link to it, the import (which looks at page revisions)
+# doesn't notice the file deletion on the wiki. We fetch the list of
+# files from the wiki, but as the file is deleted, it doesn't appear.
+test_expect_failure 'git pull correctly imports media file deletion when no page link to it' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir &&
+ test_when_finished "rm -fr mw_dir" &&
+ (
+ cd mw_dir &&
+ echo "hello world" >Foo.txt &&
+ git add Foo.txt &&
+ git commit -m "Add the text file Foo" &&
+ git push &&
+ git rm Foo.txt &&
+ git commit -m "Delete the file Foo" &&
+ test_git_reimport &&
+ test_path_is_missing Foo.txt
+ )
+'
+
+test_expect_success 'git push properly warns about insufficient permissions' '
+ wiki_reset &&
+ git clone mediawiki::'"$WIKI_URL"' mw_dir &&
+ test_when_finished "rm -fr mw_dir" &&
+ (
+ cd mw_dir &&
+ echo "A File" >foo.forbidden &&
+ git add foo.forbidden &&
+ git commit -m "add a file" &&
+ git push 2>actual &&
+ test_i18ngrep "foo.forbidden is not a permitted file" actual
+ )
+'
+
+test_expect_success 'setup a repository with media files' '
+ wiki_reset &&
+ wiki_editpage testpage "I am linking a file [[File:File.txt]]" false &&
+ echo "File content" >File.txt &&
+ wiki_upload_file File.txt &&
+ echo "Another file content" >AnotherFile.txt &&
+ wiki_upload_file AnotherFile.txt
+'
+
+test_expect_success 'git clone works with one specific page cloned and mediaimport=true' '
+ git clone -c remote.origin.pages=testpage \
+ -c remote.origin.mediaimport=true \
+ mediawiki::'"$WIKI_URL"' mw_dir_15 &&
+ test_when_finished "rm -rf mw_dir_15" &&
+ test_contains_N_files mw_dir_15 3 &&
+ test_path_is_file mw_dir_15/Testpage.mw &&
+ test_path_is_file mw_dir_15/File:File.txt.mw &&
+ test_path_is_file mw_dir_15/File.txt &&
+ test_path_is_missing mw_dir_15/Main_Page.mw &&
+ test_path_is_missing mw_dir_15/File:AnotherFile.txt.mw &&
+ test_path_is_missing mw_dir_15/AnothetFile.txt &&
+ wiki_check_content mw_dir_15/Testpage.mw Testpage &&
+ test_cmp mw_dir_15/File.txt File.txt
+'
+
+test_expect_success 'git clone works with one specific page cloned and mediaimport=false' '
+ test_when_finished "rm -rf mw_dir_16" &&
+ git clone -c remote.origin.pages=testpage \
+ mediawiki::'"$WIKI_URL"' mw_dir_16 &&
+ test_contains_N_files mw_dir_16 1 &&
+ test_path_is_file mw_dir_16/Testpage.mw &&
+ test_path_is_missing mw_dir_16/File:File.txt.mw &&
+ test_path_is_missing mw_dir_16/File.txt &&
+ test_path_is_missing mw_dir_16/Main_Page.mw &&
+ wiki_check_content mw_dir_16/Testpage.mw Testpage
+'
+
+# should behave like mediaimport=false
+test_expect_success 'git clone works with one specific page cloned and mediaimport unset' '
+ test_when_finished "rm -fr mw_dir_17" &&
+ git clone -c remote.origin.pages=testpage \
+ mediawiki::'"$WIKI_URL"' mw_dir_17 &&
+ test_contains_N_files mw_dir_17 1 &&
+ test_path_is_file mw_dir_17/Testpage.mw &&
+ test_path_is_missing mw_dir_17/File:File.txt.mw &&
+ test_path_is_missing mw_dir_17/File.txt &&
+ test_path_is_missing mw_dir_17/Main_Page.mw &&
+ wiki_check_content mw_dir_17/Testpage.mw Testpage
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='Test the Git Mediawiki remote helper: git pull by revision'
+
+. ./test-gitmw-lib.sh
+. ./push-pull-tests.sh
+. $TEST_DIRECTORY/test-lib.sh
+
+test_check_precond
+
+test_expect_success 'configuration' '
+ git config --global mediawiki.fetchStrategy by_rev
+'
+
+test_push_pull
+
+test_done
--- /dev/null
+# Copyright (C) 2012
+# Charles Roussel <charles.roussel@ensimag.imag.fr>
+# Simon Cathebras <simon.cathebras@ensimag.imag.fr>
+# Julien Khayat <julien.khayat@ensimag.imag.fr>
+# Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
+# Simon Perrat <simon.perrat@ensimag.imag.fr>
+# License: GPL v2 or later
+
+#
+# CONFIGURATION VARIABLES
+# You might want to change these ones
+#
+
+. ./test.config
+
+WIKI_URL=http://"$SERVER_ADDR:$PORT/$WIKI_DIR_NAME"
+CURR_DIR=$(pwd)
+TEST_OUTPUT_DIRECTORY=$(pwd)
+TEST_DIRECTORY="$CURR_DIR"/../../../t
+
+export TEST_OUTPUT_DIRECTORY TEST_DIRECTORY CURR_DIR
+
+if test "$LIGHTTPD" = "false" ; then
+ PORT=80
+else
+ WIKI_DIR_INST="$CURR_DIR/$WEB_WWW"
+fi
+
+wiki_upload_file () {
+ "$CURR_DIR"/test-gitmw.pl upload_file "$@"
+}
+
+wiki_getpage () {
+ "$CURR_DIR"/test-gitmw.pl get_page "$@"
+}
+
+wiki_delete_page () {
+ "$CURR_DIR"/test-gitmw.pl delete_page "$@"
+}
+
+wiki_editpage () {
+ "$CURR_DIR"/test-gitmw.pl edit_page "$@"
+}
+
+die () {
+ die_with_status 1 "$@"
+}
+
+die_with_status () {
+ status=$1
+ shift
+ echo >&2 "$*"
+ exit "$status"
+}
+
+
+# Check the preconditions to run git-remote-mediawiki's tests
+test_check_precond () {
+ if ! test_have_prereq PERL
+ then
+ skip_all='skipping gateway git-mw tests, perl not available'
+ test_done
+ fi
+
+ if [ ! -f "$GIT_BUILD_DIR"/git-remote-mediawiki ];
+ then
+ echo "No remote mediawiki for git found. Copying it in git"
+ echo "cp $GIT_BUILD_DIR/contrib/mw-to-git/git-remote-mediawiki $GIT_BUILD_DIR/"
+ ln -s "$GIT_BUILD_DIR"/contrib/mw-to-git/git-remote-mediawiki "$GIT_BUILD_DIR"
+ fi
+
+ if [ ! -d "$WIKI_DIR_INST/$WIKI_DIR_NAME" ];
+ then
+ skip_all='skipping gateway git-mw tests, no mediawiki found'
+ test_done
+ fi
+}
+
+# test_diff_directories <dir_git> <dir_wiki>
+#
+# Compare the contents of directories <dir_git> and <dir_wiki> with diff
+# and errors if they do not match. The program will
+# not look into .git in the process.
+# Warning: the first argument MUST be the directory containing the git data
+test_diff_directories () {
+ rm -rf "$1_tmp"
+ mkdir -p "$1_tmp"
+ cp "$1"/*.mw "$1_tmp"
+ diff -r -b "$1_tmp" "$2"
+}
+
+# $1=<dir>
+# $2=<N>
+#
+# 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 "it contains these files:"
+ ls "$1"
+ false
+ fi
+}
+
+
+# wiki_check_content <file_name> <page_name>
+#
+# Compares the contents of the file <file_name> and the wiki page
+# <page_name> and exits with error 1 if they do not match.
+wiki_check_content () {
+ mkdir -p wiki_tmp
+ wiki_getpage "$2" wiki_tmp
+ # replacement of forbidden character in file name
+ page_name=$(printf "%s\n" "$2" | sed -e "s/\//%2F/g")
+
+ diff -b "$1" wiki_tmp/"$page_name".mw
+ if test $? -ne 0
+ then
+ rm -rf wiki_tmp
+ error "ERROR: file $2 not found on wiki"
+ fi
+ rm -rf wiki_tmp
+}
+
+# wiki_page_exist <page_name>
+#
+# Check the existence of the page <page_name> on the wiki and exits
+# with error if it is absent from it.
+wiki_page_exist () {
+ mkdir -p wiki_tmp
+ wiki_getpage "$1" wiki_tmp
+ page_name=$(printf "%s\n" "$1" | sed "s/\//%2F/g")
+ if test -f wiki_tmp/"$page_name".mw ; then
+ rm -rf wiki_tmp
+ else
+ rm -rf wiki_tmp
+ error "test failed: file $1 not found on wiki"
+ fi
+}
+
+# wiki_getallpagename
+#
+# Fetch the name of each page on the wiki.
+wiki_getallpagename () {
+ "$CURR_DIR"/test-gitmw.pl getallpagename
+}
+
+# wiki_getallpagecategory <category>
+#
+# Fetch the name of each page belonging to <category> on the wiki.
+wiki_getallpagecategory () {
+ "$CURR_DIR"/test-gitmw.pl getallpagename "$@"
+}
+
+# wiki_getallpage <dest_dir> [<category>]
+#
+# Fetch all the pages from the wiki and place them in the directory
+# <dest_dir>.
+# If <category> is define, then wiki_getallpage fetch the pages included
+# in <category>.
+wiki_getallpage () {
+ if test -z "$2";
+ then
+ wiki_getallpagename
+ else
+ wiki_getallpagecategory "$2"
+ fi
+ mkdir -p "$1"
+ while read -r line; do
+ wiki_getpage "$line" $1;
+ done < all.txt
+}
+
+# ================= Install part =================
+
+error () {
+ echo "$@" >&2
+ exit 1
+}
+
+# config_lighttpd
+#
+# Create the configuration files and the folders necessary to start lighttpd.
+# Overwrite any existing file.
+config_lighttpd () {
+ mkdir -p $WEB
+ mkdir -p $WEB_TMP
+ mkdir -p $WEB_WWW
+ cat > $WEB/lighttpd.conf <<EOF
+ server.document-root = "$CURR_DIR/$WEB_WWW"
+ server.port = $PORT
+ server.pid-file = "$CURR_DIR/$WEB_TMP/pid"
+
+ server.modules = (
+ "mod_rewrite",
+ "mod_redirect",
+ "mod_access",
+ "mod_accesslog",
+ "mod_fastcgi"
+ )
+
+ index-file.names = ("index.php" , "index.html")
+
+ mimetype.assign = (
+ ".pdf" => "application/pdf",
+ ".sig" => "application/pgp-signature",
+ ".spl" => "application/futuresplash",
+ ".class" => "application/octet-stream",
+ ".ps" => "application/postscript",
+ ".torrent" => "application/x-bittorrent",
+ ".dvi" => "application/x-dvi",
+ ".gz" => "application/x-gzip",
+ ".pac" => "application/x-ns-proxy-autoconfig",
+ ".swf" => "application/x-shockwave-flash",
+ ".tar.gz" => "application/x-tgz",
+ ".tgz" => "application/x-tgz",
+ ".tar" => "application/x-tar",
+ ".zip" => "application/zip",
+ ".mp3" => "audio/mpeg",
+ ".m3u" => "audio/x-mpegurl",
+ ".wma" => "audio/x-ms-wma",
+ ".wax" => "audio/x-ms-wax",
+ ".ogg" => "application/ogg",
+ ".wav" => "audio/x-wav",
+ ".gif" => "image/gif",
+ ".jpg" => "image/jpeg",
+ ".jpeg" => "image/jpeg",
+ ".png" => "image/png",
+ ".xbm" => "image/x-xbitmap",
+ ".xpm" => "image/x-xpixmap",
+ ".xwd" => "image/x-xwindowdump",
+ ".css" => "text/css",
+ ".html" => "text/html",
+ ".htm" => "text/html",
+ ".js" => "text/javascript",
+ ".asc" => "text/plain",
+ ".c" => "text/plain",
+ ".cpp" => "text/plain",
+ ".log" => "text/plain",
+ ".conf" => "text/plain",
+ ".text" => "text/plain",
+ ".txt" => "text/plain",
+ ".dtd" => "text/xml",
+ ".xml" => "text/xml",
+ ".mpeg" => "video/mpeg",
+ ".mpg" => "video/mpeg",
+ ".mov" => "video/quicktime",
+ ".qt" => "video/quicktime",
+ ".avi" => "video/x-msvideo",
+ ".asf" => "video/x-ms-asf",
+ ".asx" => "video/x-ms-asf",
+ ".wmv" => "video/x-ms-wmv",
+ ".bz2" => "application/x-bzip",
+ ".tbz" => "application/x-bzip-compressed-tar",
+ ".tar.bz2" => "application/x-bzip-compressed-tar",
+ "" => "text/plain"
+ )
+
+ fastcgi.server = ( ".php" =>
+ ("localhost" =>
+ ( "socket" => "$CURR_DIR/$WEB_TMP/php.socket",
+ "bin-path" => "$PHP_DIR/php-cgi -c $CURR_DIR/$WEB/php.ini"
+
+ )
+ )
+ )
+EOF
+
+ cat > $WEB/php.ini <<EOF
+ session.save_path ='$CURR_DIR/$WEB_TMP'
+EOF
+}
+
+# start_lighttpd
+#
+# Start or restart daemon lighttpd. If restart, rewrite configuration files.
+start_lighttpd () {
+ if test -f "$WEB_TMP/pid"; then
+ echo "Instance already running. Restarting..."
+ stop_lighttpd
+ fi
+ config_lighttpd
+ "$LIGHTTPD_DIR"/lighttpd -f "$WEB"/lighttpd.conf
+
+ if test $? -ne 0 ; then
+ echo "Could not execute http deamon lighttpd"
+ exit 1
+ fi
+}
+
+# stop_lighttpd
+#
+# Kill daemon lighttpd and removes files and folders associated.
+stop_lighttpd () {
+ test -f "$WEB_TMP/pid" && kill $(cat "$WEB_TMP/pid")
+ rm -rf "$WEB"
+}
+
+# Create the SQLite database of the MediaWiki. If the database file already
+# exists, it will be deleted.
+# This script should be runned from the directory where $FILES_FOLDER is
+# located.
+create_db () {
+ rm -f "$TMP/$DB_FILE"
+
+ echo "Generating the SQLite database file. It can take some time ..."
+ # Run the php script to generate the SQLite database file
+ # with cURL calls.
+ php "$FILES_FOLDER/$DB_INSTALL_SCRIPT" $(basename "$DB_FILE" .sqlite) \
+ "$WIKI_ADMIN" "$WIKI_PASSW" "$TMP" "$PORT"
+
+ if [ ! -f "$TMP/$DB_FILE" ] ; then
+ error "Can't create database file $TMP/$DB_FILE. Try to run ./install-wiki.sh delete first."
+ fi
+
+ # Copy the generated database file into the directory the
+ # user indicated.
+ cp "$TMP/$DB_FILE" "$FILES_FOLDER" ||
+ error "Unable to copy $TMP/$DB_FILE to $FILES_FOLDER"
+}
+
+# Install a wiki in your web server directory.
+wiki_install () {
+ if test $LIGHTTPD = "true" ; then
+ start_lighttpd
+ fi
+
+ SERVER_ADDR=$SERVER_ADDR:$PORT
+ # In this part, we change directory to $TMP in order to download,
+ # unpack and copy the files of MediaWiki
+ (
+ mkdir -p "$WIKI_DIR_INST/$WIKI_DIR_NAME"
+ if [ ! -d "$WIKI_DIR_INST/$WIKI_DIR_NAME" ] ; then
+ error "Folder $WIKI_DIR_INST/$WIKI_DIR_NAME doesn't exist.
+ Please create it and launch the script again."
+ fi
+
+ # Fetch MediaWiki's archive if not already present in the TMP directory
+ cd "$TMP"
+ if [ ! -f "$MW_VERSION.tar.gz" ] ; then
+ echo "Downloading $MW_VERSION sources ..."
+ wget "http://download.wikimedia.org/mediawiki/1.19/mediawiki-1.19.0.tar.gz" ||
+ error "Unable to download "\
+ "http://download.wikimedia.org/mediawiki/1.19/"\
+ "mediawiki-1.19.0.tar.gz. "\
+ "Please fix your connection and launch the script again."
+ echo "$MW_VERSION.tar.gz downloaded in `pwd`. "\
+ "You can delete it later if you want."
+ else
+ echo "Reusing existing $MW_VERSION.tar.gz downloaded in `pwd`."
+ fi
+ archive_abs_path=$(pwd)/"$MW_VERSION.tar.gz"
+ cd "$WIKI_DIR_INST/$WIKI_DIR_NAME/" ||
+ error "can't cd to $WIKI_DIR_INST/$WIKI_DIR_NAME/"
+ tar xzf "$archive_abs_path" --strip-components=1 ||
+ error "Unable to extract WikiMedia's files from $archive_abs_path to "\
+ "$WIKI_DIR_INST/$WIKI_DIR_NAME"
+ ) || exit 1
+
+ create_db
+
+ # Copy the generic LocalSettings.php in the web server's directory
+ # And modify parameters according to the ones set at the top
+ # of this script.
+ # Note that LocalSettings.php is never modified.
+ if [ ! -f "$FILES_FOLDER/LocalSettings.php" ] ; then
+ error "Can't find $FILES_FOLDER/LocalSettings.php " \
+ "in the current folder. "\
+ "Please run the script inside its folder."
+ fi
+ cp "$FILES_FOLDER/LocalSettings.php" \
+ "$FILES_FOLDER/LocalSettings-tmp.php" ||
+ error "Unable to copy $FILES_FOLDER/LocalSettings.php " \
+ "to $FILES_FOLDER/LocalSettings-tmp.php"
+
+ # Parse and set the LocalSettings file of the user according to the
+ # CONFIGURATION VARIABLES section at the beginning of this script
+ file_swap="$FILES_FOLDER/LocalSettings-swap.php"
+ sed "s,@WG_SCRIPT_PATH@,/$WIKI_DIR_NAME," \
+ "$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
+ mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
+ sed "s,@WG_SERVER@,http://$SERVER_ADDR," \
+ "$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
+ mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
+ sed "s,@WG_SQLITE_DATADIR@,$TMP," \
+ "$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
+ mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
+ sed "s,@WG_SQLITE_DATAFILE@,$( basename $DB_FILE .sqlite)," \
+ "$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
+ mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
+
+ mv "$FILES_FOLDER/LocalSettings-tmp.php" \
+ "$WIKI_DIR_INST/$WIKI_DIR_NAME/LocalSettings.php" ||
+ error "Unable to move $FILES_FOLDER/LocalSettings-tmp.php" \
+ "in $WIKI_DIR_INST/$WIKI_DIR_NAME"
+ echo "File $FILES_FOLDER/LocalSettings.php is set in" \
+ " $WIKI_DIR_INST/$WIKI_DIR_NAME"
+
+ echo "Your wiki has been installed. You can check it at
+ http://$SERVER_ADDR/$WIKI_DIR_NAME"
+}
+
+# Reset the database of the wiki and the password of the admin
+#
+# Warning: This function must be called only in a subdirectory of t/ directory
+wiki_reset () {
+ # Copy initial database of the wiki
+ if [ ! -f "../$FILES_FOLDER/$DB_FILE" ] ; then
+ error "Can't find ../$FILES_FOLDER/$DB_FILE in the current folder."
+ fi
+ cp "../$FILES_FOLDER/$DB_FILE" "$TMP" ||
+ error "Can't copy ../$FILES_FOLDER/$DB_FILE in $TMP"
+ echo "File $FILES_FOLDER/$DB_FILE is set in $TMP"
+}
+
+# Delete the wiki created in the web server's directory and all its content
+# saved in the database.
+wiki_delete () {
+ if test $LIGHTTPD = "true"; then
+ stop_lighttpd
+ else
+ # Delete the wiki's directory.
+ rm -rf "$WIKI_DIR_INST/$WIKI_DIR_NAME" ||
+ error "Wiki's directory $WIKI_DIR_INST/" \
+ "$WIKI_DIR_NAME could not be deleted"
+ # Delete the wiki's SQLite database.
+ rm -f "$TMP/$DB_FILE" ||
+ error "Database $TMP/$DB_FILE could not be deleted."
+ fi
+
+ # Delete the wiki's SQLite database
+ rm -f "$TMP/$DB_FILE" || error "Database $TMP/$DB_FILE could not be deleted."
+ rm -f "$FILES_FOLDER/$DB_FILE"
+ rm -rf "$TMP/$MW_VERSION"
+}
--- /dev/null
+#!/usr/bin/perl -w -s
+# Copyright (C) 2012
+# Charles Roussel <charles.roussel@ensimag.imag.fr>
+# Simon Cathebras <simon.cathebras@ensimag.imag.fr>
+# Julien Khayat <julien.khayat@ensimag.imag.fr>
+# Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
+# Simon Perrat <simon.perrat@ensimag.imag.fr>
+# License: GPL v2 or later
+
+# Usage:
+# ./test-gitmw.pl <command> [argument]*
+# Execute in terminal using the name of the function to call as first
+# parameter, and the function's arguments as following parameters
+#
+# Example:
+# ./test-gitmw.pl "get_page" foo .
+# will call <wiki_getpage> with arguments <foo> and <.>
+#
+# Available functions are:
+# "get_page"
+# "delete_page"
+# "edit_page"
+# "getallpagename"
+
+use MediaWiki::API;
+use Getopt::Long;
+use encoding 'utf8';
+use DateTime::Format::ISO8601;
+use open ':encoding(utf8)';
+use constant SLASH_REPLACEMENT => "%2F";
+
+#Parsing of the config file
+
+my $configfile = "$ENV{'CURR_DIR'}/test.config";
+my %config;
+open my $CONFIG, "<", $configfile or die "can't open $configfile: $!";
+while (<$CONFIG>)
+{
+ chomp;
+ s/#.*//;
+ s/^\s+//;
+ s/\s+$//;
+ next unless length;
+ my ($key, $value) = split (/\s*=\s*/,$_, 2);
+ $config{$key} = $value;
+ last if ($key eq 'LIGHTTPD' and $value eq 'false');
+ last if ($key eq 'PORT');
+}
+close $CONFIG or die "can't close $configfile: $!";
+
+my $wiki_address = "http://$config{'SERVER_ADDR'}".":"."$config{'PORT'}";
+my $wiki_url = "$wiki_address/$config{'WIKI_DIR_NAME'}/api.php";
+my $wiki_admin = "$config{'WIKI_ADMIN'}";
+my $wiki_admin_pass = "$config{'WIKI_PASSW'}";
+my $mw = MediaWiki::API->new;
+$mw->{config}->{api_url} = $wiki_url;
+
+
+# wiki_login <name> <password>
+#
+# Logs the user with <name> and <password> in the global variable
+# of the mediawiki $mw
+sub wiki_login {
+ $mw->login( { lgname => "$_[0]",lgpassword => "$_[1]" } )
+ || die "getpage: login failed";
+}
+
+# wiki_getpage <wiki_page> <dest_path>
+#
+# fetch a page <wiki_page> from the wiki referenced in the global variable
+# $mw and copies its content in directory dest_path
+sub wiki_getpage {
+ my $pagename = $_[0];
+ my $destdir = $_[1];
+
+ my $page = $mw->get_page( { title => $pagename } );
+ if (!defined($page)) {
+ die "getpage: wiki does not exist";
+ }
+
+ my $content = $page->{'*'};
+ if (!defined($content)) {
+ die "getpage: page does not exist";
+ }
+
+ $pagename=$page->{'title'};
+ # Replace spaces by underscore in the page name
+ $pagename =~ s/ /_/g;
+ $pagename =~ s/\//%2F/g;
+ open(my $file, ">$destdir/$pagename.mw");
+ print $file "$content";
+ close ($file);
+
+}
+
+# wiki_delete_page <page_name>
+#
+# delete the page with name <page_name> from the wiki referenced
+# in the global variable $mw
+sub wiki_delete_page {
+ my $pagename = $_[0];
+
+ my $exist=$mw->get_page({title => $pagename});
+
+ if (defined($exist->{'*'})){
+ $mw->edit({ action => 'delete',
+ title => $pagename})
+ || die $mw->{error}->{code} . ": " . $mw->{error}->{details};
+ } else {
+ die "no page with such name found: $pagename\n";
+ }
+}
+
+# wiki_editpage <wiki_page> <wiki_content> <wiki_append> [-c=<category>] [-s=<summary>]
+#
+# Edit a page named <wiki_page> with content <wiki_content> on the wiki
+# referenced with the global variable $mw
+# If <wiki_append> == true : append <wiki_content> at the end of the actual
+# content of the page <wiki_page>
+# If <wik_page> doesn't exist, that page is created with the <wiki_content>
+sub wiki_editpage {
+ my $wiki_page = $_[0];
+ my $wiki_content = $_[1];
+ my $wiki_append = $_[2];
+ my $summary = "";
+ my ($summ, $cat) = ();
+ GetOptions('s=s' => \$summ, 'c=s' => \$cat);
+
+ my $append = 0;
+ if (defined($wiki_append) && $wiki_append eq 'true') {
+ $append=1;
+ }
+
+ my $previous_text ="";
+
+ if ($append) {
+ my $ref = $mw->get_page( { title => $wiki_page } );
+ $previous_text = $ref->{'*'};
+ }
+
+ my $text = $wiki_content;
+ if (defined($previous_text)) {
+ $text="$previous_text$text";
+ }
+
+ # Eventually, add this page to a category.
+ if (defined($cat)) {
+ my $category_name="[[Category:$cat]]";
+ $text="$text\n $category_name";
+ }
+ if(defined($summ)){
+ $summary=$summ;
+ }
+
+ $mw->edit( { action => 'edit', title => $wiki_page, summary => $summary, text => "$text"} );
+}
+
+# wiki_getallpagename [<category>]
+#
+# Fetch all pages of the wiki referenced by the global variable $mw
+# and print the names of each one in the file all.txt with a new line
+# ("\n") between these.
+# If the argument <category> is defined, then this function get only the pages
+# belonging to <category>.
+sub wiki_getallpagename {
+ # fetch the pages of the wiki
+ if (defined($_[0])) {
+ my $mw_pages = $mw->list ( { action => 'query',
+ list => 'categorymembers',
+ cmtitle => "Category:$_[0]",
+ cmnamespace => 0,
+ cmlimit => 500 },
+ )
+ || die $mw->{error}->{code}.": ".$mw->{error}->{details};
+ open(my $file, ">all.txt");
+ foreach my $page (@{$mw_pages}) {
+ print $file "$page->{title}\n";
+ }
+ close ($file);
+
+ } else {
+ my $mw_pages = $mw->list({
+ action => 'query',
+ list => 'allpages',
+ aplimit => 500,
+ })
+ || die $mw->{error}->{code}.": ".$mw->{error}->{details};
+ open(my $file, ">all.txt");
+ foreach my $page (@{$mw_pages}) {
+ print $file "$page->{title}\n";
+ }
+ close ($file);
+ }
+}
+
+sub wiki_upload_file {
+ my $file_name = $_[0];
+ my $resultat = $mw->edit ( {
+ action => 'upload',
+ filename => $file_name,
+ comment => 'upload a file',
+ file => [ $file_name ],
+ ignorewarnings=>1,
+ }, {
+ skip_encoding => 1
+ } ) || die $mw->{error}->{code} . ' : ' . $mw->{error}->{details};
+}
+
+
+
+# Main part of this script: parse the command line arguments
+# and select which function to execute
+my $fct_to_call = shift;
+
+wiki_login($wiki_admin, $wiki_admin_pass);
+
+my %functions_to_call = qw(
+ upload_file wiki_upload_file
+ get_page wiki_getpage
+ delete_page wiki_delete_page
+ edit_page wiki_editpage
+ getallpagename wiki_getallpagename
+);
+die "$0 ERROR: wrong argument" unless exists $functions_to_call{$fct_to_call};
+&{$functions_to_call{$fct_to_call}}(@ARGV);
--- /dev/null
+# Name of the web server's directory dedicated to the wiki is WIKI_DIR_NAME
+WIKI_DIR_NAME=wiki
+
+# Login and password of the wiki's admin
+WIKI_ADMIN=WikiAdmin
+WIKI_PASSW=AdminPass
+
+# Address of the web server
+SERVER_ADDR=localhost
+
+# SQLite database of the wiki, named DB_FILE, is located in TMP
+TMP=/tmp
+DB_FILE=wikidb.sqlite
+
+# If LIGHTTPD is not set to true, the script will use the defaut
+# web server running in WIKI_DIR_INST.
+WIKI_DIR_INST=/var/www
+
+# If LIGHTTPD is set to true, the script will use Lighttpd to run
+# the wiki.
+LIGHTTPD=true
+
+# The variables below are useful only if LIGHTTPD is set to true.
+PORT=1234
+PHP_DIR=/usr/bin
+LIGHTTPD_DIR=/usr/sbin
+WEB=WEB
+WEB_TMP=$WEB/tmp
+WEB_WWW=$WEB/www
+
+# The variables below are used by the script to install a wiki.
+# You should not modify these unless you are modifying the script itself.
+MW_VERSION=mediawiki-1.19.0
+FILES_FOLDER=install-wiki
+DB_INSTALL_SCRIPT=db_install.php
--- /dev/null
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
--- /dev/null
+# Copyright 2012 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+BUILD_LABEL=$(shell date +"%s")
+TAR_OUT=$(shell go env GOOS)_$(shell go env GOARCH).tar.gz
+
+all: git-remote-persistent-https git-remote-persistent-https--proxy \
+ git-remote-persistent-http
+
+git-remote-persistent-https--proxy: git-remote-persistent-https
+ ln -f -s git-remote-persistent-https git-remote-persistent-https--proxy
+
+git-remote-persistent-http: git-remote-persistent-https
+ ln -f -s git-remote-persistent-https git-remote-persistent-http
+
+git-remote-persistent-https:
+ go build -o git-remote-persistent-https \
+ -ldflags "-X main._BUILD_EMBED_LABEL $(BUILD_LABEL)"
+
+clean:
+ rm -f git-remote-persistent-http* *.tar.gz
+
+tar: clean all
+ @chmod 555 git-remote-persistent-https
+ @tar -czf $(TAR_OUT) git-remote-persistent-http* README LICENSE
+ @echo
+ @echo "Created $(TAR_OUT)"
--- /dev/null
+git-remote-persistent-https
+
+The git-remote-persistent-https binary speeds up SSL operations
+by running a daemon job (git-remote-persistent-https--proxy) that
+keeps a connection open to a server.
+
+
+PRE-BUILT BINARIES
+
+Darwin amd64:
+https://commondatastorage.googleapis.com/git-remote-persistent-https/darwin_amd64.tar.gz
+
+Linux amd64:
+https://commondatastorage.googleapis.com/git-remote-persistent-https/linux_amd64.tar.gz
+
+
+INSTALLING
+
+Move all of the git-remote-persistent-http* binaries to a directory
+in PATH.
+
+
+USAGE
+
+HTTPS requests can be delegated to the proxy by using the
+"persistent-https" scheme, e.g.
+
+git clone persistent-https://kernel.googlesource.com/pub/scm/git/git
+
+Likewise, .gitconfig can be updated as follows to rewrite https urls
+to use persistent-https:
+
+[url "persistent-https"]
+ insteadof = https
+[url "persistent-http"]
+ insteadof = http
+
+
+#####################################################################
+# BUILDING FROM SOURCE
+#####################################################################
+
+LOCATION
+
+The source is available in the contrib/persistent-https directory of
+the Git source repository. The Git source repository is available at
+git://git.kernel.org/pub/scm/git/git.git/
+https://kernel.googlesource.com/pub/scm/git/git
+
+
+PREREQUISITES
+
+The code is written in Go (http://golang.org/) and the Go compiler is
+required. Currently, the compiler must be built and installed from tip
+of source, in order to include a fix in the reverse http proxy:
+http://code.google.com/p/go/source/detail?r=a615b796570a2cd8591884767a7d67ede74f6648
+
+
+BUILDING
+
+Run "make" to build the binaries. See the section on
+INSTALLING above.
--- /dev/null
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "net"
+ "net/url"
+ "os"
+ "os/exec"
+ "strings"
+ "syscall"
+ "time"
+)
+
+type Client struct {
+ ProxyBin string
+ Args []string
+
+ insecure bool
+}
+
+func (c *Client) Run() error {
+ if err := c.resolveArgs(); err != nil {
+ return fmt.Errorf("resolveArgs() got error: %v", err)
+ }
+
+ // Connect to the proxy.
+ uconn, hconn, addr, err := c.connect()
+ if err != nil {
+ return fmt.Errorf("connect() got error: %v", err)
+ }
+ // Keep the unix socket connection open for the duration of the request.
+ defer uconn.Close()
+ // Keep a connection to the HTTP server open, so no other user can
+ // bind on the same address so long as the process is running.
+ defer hconn.Close()
+
+ // Start the git-remote-http subprocess.
+ cargs := []string{"-c", fmt.Sprintf("http.proxy=%v", addr), "remote-http"}
+ cargs = append(cargs, c.Args...)
+ cmd := exec.Command("git", cargs...)
+
+ for _, v := range os.Environ() {
+ if !strings.HasPrefix(v, "GIT_PERSISTENT_HTTPS_SECURE=") {
+ cmd.Env = append(cmd.Env, v)
+ }
+ }
+ // Set the GIT_PERSISTENT_HTTPS_SECURE environment variable when
+ // the proxy is using a SSL connection. This allows credential helpers
+ // to identify secure proxy connections, despite being passed an HTTP
+ // scheme.
+ if !c.insecure {
+ cmd.Env = append(cmd.Env, "GIT_PERSISTENT_HTTPS_SECURE=1")
+ }
+
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if err := cmd.Run(); err != nil {
+ if eerr, ok := err.(*exec.ExitError); ok {
+ if stat, ok := eerr.ProcessState.Sys().(syscall.WaitStatus); ok && stat.ExitStatus() != 0 {
+ os.Exit(stat.ExitStatus())
+ }
+ }
+ return fmt.Errorf("git-remote-http subprocess got error: %v", err)
+ }
+ return nil
+}
+
+func (c *Client) connect() (uconn net.Conn, hconn net.Conn, addr string, err error) {
+ uconn, err = DefaultSocket.Dial()
+ if err != nil {
+ if e, ok := err.(*net.OpError); ok && (os.IsNotExist(e.Err) || e.Err == syscall.ECONNREFUSED) {
+ if err = c.startProxy(); err == nil {
+ uconn, err = DefaultSocket.Dial()
+ }
+ }
+ if err != nil {
+ return
+ }
+ }
+
+ if addr, err = c.readAddr(uconn); err != nil {
+ return
+ }
+
+ // Open a tcp connection to the proxy.
+ if hconn, err = net.Dial("tcp", addr); err != nil {
+ return
+ }
+
+ // Verify the address hasn't changed ownership.
+ var addr2 string
+ if addr2, err = c.readAddr(uconn); err != nil {
+ return
+ } else if addr != addr2 {
+ err = fmt.Errorf("address changed after connect. got %q, want %q", addr2, addr)
+ return
+ }
+ return
+}
+
+func (c *Client) readAddr(conn net.Conn) (string, error) {
+ conn.SetDeadline(time.Now().Add(5 * time.Second))
+ data := make([]byte, 100)
+ n, err := conn.Read(data)
+ if err != nil {
+ return "", fmt.Errorf("error reading unix socket: %v", err)
+ } else if n == 0 {
+ return "", errors.New("empty data response")
+ }
+ conn.Write([]byte{1}) // Ack
+
+ var addr string
+ if addrs := strings.Split(string(data[:n]), "\n"); len(addrs) != 2 {
+ return "", fmt.Errorf("got %q, wanted 2 addresses", data[:n])
+ } else if c.insecure {
+ addr = addrs[1]
+ } else {
+ addr = addrs[0]
+ }
+ return addr, nil
+}
+
+func (c *Client) startProxy() error {
+ cmd := exec.Command(c.ProxyBin)
+ cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
+ stdout, err := cmd.StdoutPipe()
+ if err != nil {
+ return err
+ }
+ defer stdout.Close()
+ if err := cmd.Start(); err != nil {
+ return err
+ }
+ result := make(chan error)
+ go func() {
+ bytes, _, err := bufio.NewReader(stdout).ReadLine()
+ if line := string(bytes); err == nil && line != "OK" {
+ err = fmt.Errorf("proxy returned %q, want \"OK\"", line)
+ }
+ result <- err
+ }()
+ select {
+ case err := <-result:
+ return err
+ case <-time.After(5 * time.Second):
+ return errors.New("timeout waiting for proxy to start")
+ }
+ panic("not reachable")
+}
+
+func (c *Client) resolveArgs() error {
+ if nargs := len(c.Args); nargs == 0 {
+ return errors.New("remote needed")
+ } else if nargs > 2 {
+ return fmt.Errorf("want at most 2 args, got %v", c.Args)
+ }
+
+ // Rewrite the url scheme to be http.
+ idx := len(c.Args) - 1
+ rawurl := c.Args[idx]
+ rurl, err := url.Parse(rawurl)
+ if err != nil {
+ return fmt.Errorf("invalid remote: %v", err)
+ }
+ c.insecure = rurl.Scheme == "persistent-http"
+ rurl.Scheme = "http"
+ c.Args[idx] = rurl.String()
+ if idx != 0 && c.Args[0] == rawurl {
+ c.Args[0] = c.Args[idx]
+ }
+ return nil
+}
--- /dev/null
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// The git-remote-persistent-https binary speeds up SSL operations by running
+// a daemon job that keeps a connection open to a Git server. This ensures the
+// git-remote-persistent-https--proxy is running and delegating execution
+// to the git-remote-http binary with the http_proxy set to the daemon job.
+// A unix socket is used to authenticate the proxy and discover the
+// HTTP address. Note, both the client and proxy are included in the same
+// binary.
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "strings"
+ "time"
+)
+
+var (
+ forceProxy = flag.Bool("proxy", false, "Whether to start the binary in proxy mode")
+ proxyBin = flag.String("proxy_bin", "git-remote-persistent-https--proxy", "Path to the proxy binary")
+ printLabel = flag.Bool("print_label", false, "Prints the build label for the binary")
+
+ // Variable that should be defined through the -X linker flag.
+ _BUILD_EMBED_LABEL string
+)
+
+const (
+ defaultMaxIdleDuration = 24 * time.Hour
+ defaultPollUpdateInterval = 15 * time.Minute
+)
+
+func main() {
+ flag.Parse()
+ if *printLabel {
+ // Short circuit execution to print the build label
+ fmt.Println(buildLabel())
+ return
+ }
+
+ var err error
+ if *forceProxy || strings.HasSuffix(os.Args[0], "--proxy") {
+ log.SetPrefix("git-remote-persistent-https--proxy: ")
+ proxy := &Proxy{
+ BuildLabel: buildLabel(),
+ MaxIdleDuration: defaultMaxIdleDuration,
+ PollUpdateInterval: defaultPollUpdateInterval,
+ }
+ err = proxy.Run()
+ } else {
+ log.SetPrefix("git-remote-persistent-https: ")
+ client := &Client{
+ ProxyBin: *proxyBin,
+ Args: flag.Args(),
+ }
+ err = client.Run()
+ }
+ if err != nil {
+ log.Fatalln(err)
+ }
+}
+
+func buildLabel() string {
+ if _BUILD_EMBED_LABEL == "" {
+ log.Println(`unlabeled build; build with "make" to label`)
+ }
+ return _BUILD_EMBED_LABEL
+}
--- /dev/null
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "fmt"
+ "log"
+ "net"
+ "net/http"
+ "net/http/httputil"
+ "os"
+ "os/exec"
+ "os/signal"
+ "sync"
+ "syscall"
+ "time"
+)
+
+type Proxy struct {
+ BuildLabel string
+ MaxIdleDuration time.Duration
+ PollUpdateInterval time.Duration
+
+ ul net.Listener
+ httpAddr string
+ httpsAddr string
+}
+
+func (p *Proxy) Run() error {
+ hl, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ return fmt.Errorf("http listen failed: %v", err)
+ }
+ defer hl.Close()
+
+ hsl, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ return fmt.Errorf("https listen failed: %v", err)
+ }
+ defer hsl.Close()
+
+ p.ul, err = DefaultSocket.Listen()
+ if err != nil {
+ c, derr := DefaultSocket.Dial()
+ if derr == nil {
+ c.Close()
+ fmt.Println("OK\nA proxy is already running... exiting")
+ return nil
+ } else if e, ok := derr.(*net.OpError); ok && e.Err == syscall.ECONNREFUSED {
+ // Nothing is listening on the socket, unlink it and try again.
+ syscall.Unlink(DefaultSocket.Path())
+ p.ul, err = DefaultSocket.Listen()
+ }
+ if err != nil {
+ return fmt.Errorf("unix listen failed on %v: %v", DefaultSocket.Path(), err)
+ }
+ }
+ defer p.ul.Close()
+ go p.closeOnSignal()
+ go p.closeOnUpdate()
+
+ p.httpAddr = hl.Addr().String()
+ p.httpsAddr = hsl.Addr().String()
+ fmt.Printf("OK\nListening on unix socket=%v http=%v https=%v\n",
+ p.ul.Addr(), p.httpAddr, p.httpsAddr)
+
+ result := make(chan error, 2)
+ go p.serveUnix(result)
+ go func() {
+ result <- http.Serve(hl, &httputil.ReverseProxy{
+ FlushInterval: 500 * time.Millisecond,
+ Director: func(r *http.Request) {},
+ })
+ }()
+ go func() {
+ result <- http.Serve(hsl, &httputil.ReverseProxy{
+ FlushInterval: 500 * time.Millisecond,
+ Director: func(r *http.Request) {
+ r.URL.Scheme = "https"
+ },
+ })
+ }()
+ return <-result
+}
+
+type socketContext struct {
+ sync.WaitGroup
+ mutex sync.Mutex
+ last time.Time
+}
+
+func (sc *socketContext) Done() {
+ sc.mutex.Lock()
+ defer sc.mutex.Unlock()
+ sc.last = time.Now()
+ sc.WaitGroup.Done()
+}
+
+func (p *Proxy) serveUnix(result chan<- error) {
+ sockCtx := &socketContext{}
+ go p.closeOnIdle(sockCtx)
+
+ var err error
+ for {
+ var uconn net.Conn
+ uconn, err = p.ul.Accept()
+ if err != nil {
+ err = fmt.Errorf("accept failed: %v", err)
+ break
+ }
+ sockCtx.Add(1)
+ go p.handleUnixConn(sockCtx, uconn)
+ }
+ sockCtx.Wait()
+ result <- err
+}
+
+func (p *Proxy) handleUnixConn(sockCtx *socketContext, uconn net.Conn) {
+ defer sockCtx.Done()
+ defer uconn.Close()
+ data := []byte(fmt.Sprintf("%v\n%v", p.httpsAddr, p.httpAddr))
+ uconn.SetDeadline(time.Now().Add(5 * time.Second))
+ for i := 0; i < 2; i++ {
+ if n, err := uconn.Write(data); err != nil {
+ log.Printf("error sending http addresses: %+v\n", err)
+ return
+ } else if n != len(data) {
+ log.Printf("sent %d data bytes, wanted %d\n", n, len(data))
+ return
+ }
+ if _, err := uconn.Read([]byte{0, 0, 0, 0}); err != nil {
+ log.Printf("error waiting for Ack: %+v\n", err)
+ return
+ }
+ }
+ // Wait without a deadline for the client to finish via EOF
+ uconn.SetDeadline(time.Time{})
+ uconn.Read([]byte{0, 0, 0, 0})
+}
+
+func (p *Proxy) closeOnIdle(sockCtx *socketContext) {
+ for d := p.MaxIdleDuration; d > 0; {
+ time.Sleep(d)
+ sockCtx.Wait()
+ sockCtx.mutex.Lock()
+ if d = sockCtx.last.Add(p.MaxIdleDuration).Sub(time.Now()); d <= 0 {
+ log.Println("graceful shutdown from idle timeout")
+ p.ul.Close()
+ }
+ sockCtx.mutex.Unlock()
+ }
+}
+
+func (p *Proxy) closeOnUpdate() {
+ for {
+ time.Sleep(p.PollUpdateInterval)
+ if out, err := exec.Command(os.Args[0], "--print_label").Output(); err != nil {
+ log.Printf("error polling for updated binary: %v\n", err)
+ } else if s := string(out[:len(out)-1]); p.BuildLabel != s {
+ log.Printf("graceful shutdown from updated binary: %q --> %q\n", p.BuildLabel, s)
+ p.ul.Close()
+ break
+ }
+ }
+}
+
+func (p *Proxy) closeOnSignal() {
+ ch := make(chan os.Signal, 10)
+ signal.Notify(ch, os.Interrupt, os.Kill, os.Signal(syscall.SIGTERM), os.Signal(syscall.SIGHUP))
+ sig := <-ch
+ p.ul.Close()
+ switch sig {
+ case os.Signal(syscall.SIGHUP):
+ log.Printf("graceful shutdown from signal: %v\n", sig)
+ default:
+ log.Fatalf("exiting from signal: %v\n", sig)
+ }
+}
--- /dev/null
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "fmt"
+ "log"
+ "net"
+ "os"
+ "path/filepath"
+ "syscall"
+)
+
+// A Socket is a wrapper around a Unix socket that verifies directory
+// permissions.
+type Socket struct {
+ Dir string
+}
+
+func defaultDir() string {
+ sockPath := ".git-credential-cache"
+ if home := os.Getenv("HOME"); home != "" {
+ return filepath.Join(home, sockPath)
+ }
+ log.Printf("socket: cannot find HOME path. using relative directory %q for socket", sockPath)
+ return sockPath
+}
+
+// DefaultSocket is a Socket in the $HOME/.git-credential-cache directory.
+var DefaultSocket = Socket{Dir: defaultDir()}
+
+// Listen announces the local network address of the unix socket. The
+// permissions on the socket directory are verified before attempting
+// the actual listen.
+func (s Socket) Listen() (net.Listener, error) {
+ network, addr := "unix", s.Path()
+ if err := s.mkdir(); err != nil {
+ return nil, &net.OpError{Op: "listen", Net: network, Addr: &net.UnixAddr{Name: addr, Net: network}, Err: err}
+ }
+ return net.Listen(network, addr)
+}
+
+// Dial connects to the unix socket. The permissions on the socket directory
+// are verified before attempting the actual dial.
+func (s Socket) Dial() (net.Conn, error) {
+ network, addr := "unix", s.Path()
+ if err := s.checkPermissions(); err != nil {
+ return nil, &net.OpError{Op: "dial", Net: network, Addr: &net.UnixAddr{Name: addr, Net: network}, Err: err}
+ }
+ return net.Dial(network, addr)
+}
+
+// Path returns the fully specified file name of the unix socket.
+func (s Socket) Path() string {
+ return filepath.Join(s.Dir, "persistent-https-proxy-socket")
+}
+
+func (s Socket) mkdir() error {
+ if err := s.checkPermissions(); err == nil {
+ return nil
+ } else if !os.IsNotExist(err) {
+ return err
+ }
+ if err := os.MkdirAll(s.Dir, 0700); err != nil {
+ return err
+ }
+ return s.checkPermissions()
+}
+
+func (s Socket) checkPermissions() error {
+ fi, err := os.Stat(s.Dir)
+ if err != nil {
+ return err
+ }
+ if !fi.IsDir() {
+ return fmt.Errorf("socket: got file, want directory for %q", s.Dir)
+ }
+ if fi.Mode().Perm() != 0700 {
+ return fmt.Errorf("socket: got perm %o, want 700 for %q", fi.Mode().Perm(), s.Dir)
+ }
+ if st := fi.Sys().(*syscall.Stat_t); int(st.Uid) != os.Getuid() {
+ return fmt.Errorf("socket: got uid %d, want %d for %q", st.Uid, os.Getuid(), s.Dir)
+ }
+ return nil
+}
fprintf(fp, "%s=%s\n", key, value);
}
-static void credential_write(const struct credential *c, FILE *fp)
+void credential_write(const struct credential *c, FILE *fp)
{
credential_write_item(fp, "protocol", c->protocol);
credential_write_item(fp, "host", c->host);
void credential_reject(struct credential *);
int credential_read(struct credential *, FILE *);
+void credential_write(const struct credential *, FILE *);
void credential_from_url(struct credential *, const char *url);
int credential_match(const struct credential *have,
const struct credential *want);
unsigned long stamp;
int ofs;
- if (*date < '0' || '9' <= *date)
+ if (*date < '0' || '9' < *date)
return -1;
stamp = strtoul(date, &end, 10);
if (*end != ' ' || stamp == ULONG_MAX || (end[1] != '+' && end[1] != '-'))
return 0;
}
+/*
+ * This should be "(standard input)" or something, but it will
+ * probably expose many more breakages in the way no-index code
+ * is bolted onto the diff callchain.
+ */
+static const char file_from_standard_input[] = "-";
+
static int get_mode(const char *path, int *mode)
{
struct stat st;
else if (!strcasecmp(path, "nul"))
*mode = 0;
#endif
- else if (!strcmp(path, "-"))
+ else if (path == file_from_standard_input)
*mode = create_ce_mode(0666);
else if (lstat(path, &st))
return error("Could not access '%s'", path);
return 0;
}
+static int populate_from_stdin(struct diff_filespec *s)
+{
+ struct strbuf buf = STRBUF_INIT;
+ size_t size = 0;
+
+ if (strbuf_read(&buf, 0, 0) < 0)
+ return error("error while reading from stdin %s",
+ strerror(errno));
+
+ s->should_munmap = 0;
+ s->data = strbuf_detach(&buf, &size);
+ s->size = size;
+ s->should_free = 1;
+ s->is_stdin = 1;
+ return 0;
+}
+
+static struct diff_filespec *noindex_filespec(const char *name, int mode)
+{
+ struct diff_filespec *s;
+
+ if (!name)
+ name = "/dev/null";
+ s = alloc_filespec(name);
+ fill_filespec(s, null_sha1, mode);
+ if (name == file_from_standard_input)
+ populate_from_stdin(s);
+ return s;
+}
+
static int queue_diff(struct diff_options *o,
const char *name1, const char *name2)
{
tmp_c = name1; name1 = name2; name2 = tmp_c;
}
- if (!name1)
- name1 = "/dev/null";
- if (!name2)
- name2 = "/dev/null";
- d1 = alloc_filespec(name1);
- d2 = alloc_filespec(name2);
- fill_filespec(d1, null_sha1, mode1);
- fill_filespec(d2, null_sha1, mode2);
-
+ d1 = noindex_filespec(name1, mode1);
+ d2 = noindex_filespec(name2, mode2);
diff_queue(&diff_queued_diff, d1, d2);
return 0;
}
}
-static int path_outside_repo(const char *path)
-{
- const char *work_tree;
- size_t len;
-
- if (!is_absolute_path(path))
- return 0;
- work_tree = get_git_work_tree();
- if (!work_tree)
- return 1;
- len = strlen(work_tree);
- if (strncmp(path, work_tree, len) ||
- (path[len] != '\0' && path[len] != '/'))
- return 1;
- return 0;
-}
-
void diff_no_index(struct rev_info *revs,
int argc, const char **argv,
int nongit, const char *prefix)
{
- int i;
+ int i, prefixlen;
int no_index = 0;
unsigned options = 0;
+ const char *paths[2];
/* Were we asked to do --no-index explicitly? */
for (i = 1; i < argc; i++) {
* a colourful "diff" replacement.
*/
if ((argc != i + 2) ||
- (!path_outside_repo(argv[i]) &&
- !path_outside_repo(argv[i+1])))
+ (path_inside_repo(prefix, argv[i]) &&
+ path_inside_repo(prefix, argv[i+1])))
return;
}
if (argc != i + 2)
}
}
- /*
- * If the user asked for our exit code then don't start a
- * pager or we would end up reporting its exit code instead.
- */
- if (!DIFF_OPT_TST(&revs->diffopt, EXIT_WITH_STATUS))
- setup_pager();
-
- if (prefix) {
- int len = strlen(prefix);
- const char *paths[3];
- memset(paths, 0, sizeof(paths));
-
- for (i = 0; i < 2; i++) {
- const char *p = argv[argc - 2 + i];
+ prefixlen = prefix ? strlen(prefix) : 0;
+ for (i = 0; i < 2; i++) {
+ const char *p = argv[argc - 2 + i];
+ if (!strcmp(p, "-"))
/*
- * stdin should be spelled as '-'; if you have
- * path that is '-', spell it as ./-.
+ * stdin should be spelled as "-"; if you have
+ * path that is "-", spell it as "./-".
*/
- p = (strcmp(p, "-")
- ? xstrdup(prefix_filename(prefix, len, p))
- : p);
- paths[i] = p;
- }
- diff_tree_setup_paths(paths, &revs->diffopt);
+ p = file_from_standard_input;
+ else if (prefixlen)
+ p = xstrdup(prefix_filename(prefix, prefixlen, p));
+ paths[i] = p;
}
- else
- diff_tree_setup_paths(argv + argc - 2, &revs->diffopt);
revs->diffopt.skip_stat_unmatch = 1;
if (!revs->diffopt.output_format)
revs->diffopt.output_format = DIFF_FORMAT_PATCH;
- DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
revs->max_count = -2;
if (diff_setup_done(&revs->diffopt) < 0)
die("diff_setup_done failed");
- if (queue_diff(&revs->diffopt, revs->diffopt.pathspec.raw[0],
- revs->diffopt.pathspec.raw[1]))
+ setup_diff_pager(&revs->diffopt);
+ DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
+
+ if (queue_diff(&revs->diffopt, paths[0], paths[1]))
exit(1);
diff_set_mnemonic_prefix(&revs->diffopt, "1/", "2/");
diffcore_std(&revs->diffopt);
* The return code for --no-index imitates diff(1):
* 0 = no changes, 1 = changes, else error
*/
- exit(revs->diffopt.found_changes);
+ exit(diff_result_code(&revs->diffopt, 0));
}
continue;
if (!data->files[i]->is_renamed && (added + deleted == 0)) {
total_files--;
- } else {
+ } else if (!data->files[i]->is_binary) { /* don't count bytes */
adds += added;
dels += deleted;
}
return 0;
}
-static int populate_from_stdin(struct diff_filespec *s)
-{
- struct strbuf buf = STRBUF_INIT;
- size_t size = 0;
-
- if (strbuf_read(&buf, 0, 0) < 0)
- return error("error while reading from stdin %s",
- strerror(errno));
-
- s->should_munmap = 0;
- s->data = strbuf_detach(&buf, &size);
- s->size = size;
- s->should_free = 1;
- return 0;
-}
-
static int diff_populate_gitlink(struct diff_filespec *s, int size_only)
{
int len;
struct stat st;
int fd;
- if (!strcmp(s->path, "-"))
- return populate_from_stdin(s);
-
if (lstat(s->path, &st) < 0) {
if (errno == ENOENT) {
err_empty:
if (DIFF_FILE_VALID(one)) {
if (!one->sha1_valid) {
struct stat st;
- if (!strcmp(one->path, "-")) {
+ if (one->is_stdin) {
hashcpy(one->sha1, null_sha1);
return;
}
unsigned should_free : 1; /* data should be free()'ed */
unsigned should_munmap : 1; /* data should be munmap()'ed */
unsigned dirty_submodule : 2; /* For submodules: its work tree is dirty */
+ unsigned is_stdin : 1;
#define DIRTY_SUBMODULE_UNTRACKED 1
#define DIRTY_SUBMODULE_MODIFIED 2
unsigned has_more_entries : 1; /* only appear in combined diff */
return retval;
}
+/*
+ * Return the length of the "simple" part of a path match limiter.
+ */
+static int simple_length(const char *match)
+{
+ int len = -1;
+
+ for (;;) {
+ unsigned char c = *match++;
+ len++;
+ if (c == '\0' || is_glob_special(c))
+ return len;
+ }
+}
+
static int no_wildcard(const char *string)
{
- return string[strcspn(string, "*?[{\\")] == '\0';
+ return string[simple_length(string)] == '\0';
}
void add_exclude(const char *string, const char *base,
x->flags = flags;
if (!strchr(string, '/'))
x->flags |= EXC_FLAG_NODIR;
- if (no_wildcard(string))
- x->flags |= EXC_FLAG_NOWILDCARD;
+ x->nowildcardlen = simple_length(string);
if (*string == '*' && no_wildcard(string+1))
x->flags |= EXC_FLAG_ENDSWITH;
ALLOC_GROW(which->excludes, which->nr + 1, which->alloc);
{
int i;
- if (el->nr) {
- for (i = el->nr - 1; 0 <= i; i--) {
- struct exclude *x = el->excludes[i];
- const char *exclude = x->pattern;
- int to_exclude = x->to_exclude;
-
- if (x->flags & EXC_FLAG_MUSTBEDIR) {
- if (*dtype == DT_UNKNOWN)
- *dtype = get_dtype(NULL, pathname, pathlen);
- if (*dtype != DT_DIR)
- continue;
- }
+ if (!el->nr)
+ return -1; /* undefined */
- if (x->flags & EXC_FLAG_NODIR) {
- /* match basename */
- if (x->flags & EXC_FLAG_NOWILDCARD) {
- if (!strcmp_icase(exclude, basename))
- return to_exclude;
- } else if (x->flags & EXC_FLAG_ENDSWITH) {
- if (x->patternlen - 1 <= pathlen &&
- !strcmp_icase(exclude + 1, pathname + pathlen - x->patternlen + 1))
- return to_exclude;
- } else {
- if (fnmatch_icase(exclude, basename, 0) == 0)
- return to_exclude;
- }
- }
- else {
- /* match with FNM_PATHNAME:
- * exclude has base (baselen long) implicitly
- * in front of it.
- */
- int baselen = x->baselen;
- if (*exclude == '/')
- exclude++;
-
- if (pathlen < baselen ||
- (baselen && pathname[baselen-1] != '/') ||
- strncmp_icase(pathname, x->base, baselen))
- continue;
-
- if (x->flags & EXC_FLAG_NOWILDCARD) {
- if (!strcmp_icase(exclude, pathname + baselen))
- return to_exclude;
- } else {
- if (fnmatch_icase(exclude, pathname+baselen,
- FNM_PATHNAME) == 0)
- return to_exclude;
- }
+ for (i = el->nr - 1; 0 <= i; i--) {
+ struct exclude *x = el->excludes[i];
+ const char *name, *exclude = x->pattern;
+ int to_exclude = x->to_exclude;
+ int namelen, prefix = x->nowildcardlen;
+
+ if (x->flags & EXC_FLAG_MUSTBEDIR) {
+ if (*dtype == DT_UNKNOWN)
+ *dtype = get_dtype(NULL, pathname, pathlen);
+ if (*dtype != DT_DIR)
+ continue;
+ }
+
+ if (x->flags & EXC_FLAG_NODIR) {
+ /* match basename */
+ if (prefix == x->patternlen) {
+ if (!strcmp_icase(exclude, basename))
+ return to_exclude;
+ } else if (x->flags & EXC_FLAG_ENDSWITH) {
+ if (x->patternlen - 1 <= pathlen &&
+ !strcmp_icase(exclude + 1, pathname + pathlen - x->patternlen + 1))
+ return to_exclude;
+ } else {
+ if (fnmatch_icase(exclude, basename, 0) == 0)
+ return to_exclude;
}
+ continue;
+ }
+
+ /* match with FNM_PATHNAME:
+ * exclude has base (baselen long) implicitly in front of it.
+ */
+ if (*exclude == '/') {
+ exclude++;
+ prefix--;
+ }
+
+ if (pathlen < x->baselen ||
+ (x->baselen && pathname[x->baselen-1] != '/') ||
+ strncmp_icase(pathname, x->base, x->baselen))
+ continue;
+
+ namelen = x->baselen ? pathlen - x->baselen : pathlen;
+ name = pathname + pathlen - namelen;
+
+ /* if the non-wildcard part is longer than the
+ remaining pathname, surely it cannot match */
+ if (prefix > namelen)
+ continue;
+
+ if (prefix) {
+ if (strncmp_icase(exclude, name, prefix))
+ continue;
+ exclude += prefix;
+ name += prefix;
+ namelen -= prefix;
}
+
+ if (!namelen || !fnmatch_icase(exclude, name, FNM_PATHNAME))
+ return to_exclude;
}
return -1; /* undecided */
}
-int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)
+static int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)
{
int pathlen = strlen(pathname);
int st;
return 0;
}
+void path_exclude_check_init(struct path_exclude_check *check,
+ struct dir_struct *dir)
+{
+ check->dir = dir;
+ strbuf_init(&check->path, 256);
+}
+
+void path_exclude_check_clear(struct path_exclude_check *check)
+{
+ strbuf_release(&check->path);
+}
+
+/*
+ * Is this name excluded? This is for a caller like show_files() that
+ * do not honor directory hierarchy and iterate through paths that are
+ * possibly in an ignored directory.
+ *
+ * A path to a directory known to be excluded is left in check->path to
+ * optimize for repeated checks for files in the same excluded directory.
+ */
+int path_excluded(struct path_exclude_check *check,
+ const char *name, int namelen, int *dtype)
+{
+ int i;
+ struct strbuf *path = &check->path;
+
+ /*
+ * we allow the caller to pass namelen as an optimization; it
+ * must match the length of the name, as we eventually call
+ * excluded() on the whole name string.
+ */
+ if (namelen < 0)
+ namelen = strlen(name);
+
+ if (path->len &&
+ path->len <= namelen &&
+ !memcmp(name, path->buf, path->len) &&
+ (!name[path->len] || name[path->len] == '/'))
+ return 1;
+
+ strbuf_setlen(path, 0);
+ for (i = 0; name[i]; i++) {
+ int ch = name[i];
+
+ if (ch == '/') {
+ int dt = DT_DIR;
+ if (excluded(check->dir, path->buf, &dt))
+ return 1;
+ }
+ strbuf_addch(path, ch);
+ }
+
+ /* An entry in the index; cannot be a directory with subentries */
+ strbuf_setlen(path, 0);
+
+ return excluded(check->dir, name, dtype);
+}
+
static struct dir_entry *dir_entry_new(const char *pathname, int len)
{
struct dir_entry *ent;
e2->name, e2->len);
}
-/*
- * Return the length of the "simple" part of a path match limiter.
- */
-static int simple_length(const char *match)
-{
- int len = -1;
-
- for (;;) {
- unsigned char c = *match++;
- len++;
- if (c == '\0' || is_glob_special(c))
- return len;
- }
-}
-
static struct path_simplify *create_simplify(const char **pathspec)
{
int nr, alloc = 0;
void setup_standard_excludes(struct dir_struct *dir)
{
const char *path;
+ char *xdg_path;
dir->exclude_per_dir = ".gitignore";
path = git_path("info/exclude");
+ if (!excludes_file) {
+ home_config_paths(NULL, &xdg_path, "ignore");
+ excludes_file = xdg_path;
+ }
if (!access(path, R_OK))
add_excludes_from_file(dir, path);
- if (excludes_file && !access(excludes_file, R_OK))
+ if (!access(excludes_file, R_OK))
add_excludes_from_file(dir, excludes_file);
}
#ifndef DIR_H
#define DIR_H
+#include "strbuf.h"
+
struct dir_entry {
unsigned int len;
char name[FLEX_ARRAY]; /* more */
};
#define EXC_FLAG_NODIR 1
-#define EXC_FLAG_NOWILDCARD 2
#define EXC_FLAG_ENDSWITH 4
#define EXC_FLAG_MUSTBEDIR 8
struct exclude {
const char *pattern;
int patternlen;
+ int nowildcardlen;
const char *base;
int baselen;
int to_exclude;
extern int excluded_from_list(const char *pathname, int pathlen, const char *basename,
int *dtype, struct exclude_list *el);
-extern int excluded(struct dir_struct *, const char *, int *);
struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len);
+
+/*
+ * The excluded() API is meant for callers that check each level of leading
+ * directory hierarchies with excluded() to avoid recursing into excluded
+ * directories. Callers that do not do so should use this API instead.
+ */
+struct path_exclude_check {
+ struct dir_struct *dir;
+ struct strbuf path;
+};
+extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *);
+extern void path_exclude_check_clear(struct path_exclude_check *);
+extern int path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype);
+
+
extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,
char **buf_p, struct exclude_list *which, int check_index);
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
int grafts_replace_parents = 1;
int core_apply_sparse_checkout;
int merge_log_config = -1;
+int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
struct startup_info *startup_info;
unsigned long pack_size_limit_cfg;
}
sub diff_applies {
- my $fh;
return run_git_apply($patch_mode_flavour{APPLY_CHECK} . ' --check',
map { @{$_->{TEXT}} } @_);
}
}
if (@result) {
- my $fh;
my @patch = reassemble_patch($head->{TEXT}, @result);
my $apply_routine = $patch_mode_flavour{APPLY};
&$apply_routine(@patch);
split_patches () {
case "$patch_format" in
mbox)
- if test -n "$rebasing" || test t = "$keepcr"
+ if test t = "$keepcr"
then
keep_cr=--keep-cr
else
--abort)
abort=t ;;
--rebasing)
- rebasing=t threeway=t keep=t scissors=f no_inbody_headers=t ;;
+ rebasing=t threeway=t ;;
-d|--dotest)
die "$(gettext "-d option is no longer supported. Do not use.")"
;;
# by the user, or the user can tell us to do so by --resolved flag.
case "$resume" in
'')
- git mailinfo $keep $no_inbody_headers $scissors $utf8 "$dotest/msg" "$dotest/patch" \
- <"$dotest/$msgnum" >"$dotest/info" ||
- stop_here $this
-
- # skip pine's internal folder data
- sane_grep '^Author: Mail System Internal Data$' \
- <"$dotest"/info >/dev/null &&
- go_next && continue
-
- test -s "$dotest/patch" || {
- eval_gettextln "Patch is empty. Was it split wrong?
-If you would prefer to skip this patch, instead run \"\$cmdline --skip\".
-To restore the original branch and stop patching run \"\$cmdline --abort\"."
- stop_here $this
- }
- rm -f "$dotest/original-commit" "$dotest/author-script"
- if test -f "$dotest/rebasing" &&
+ if test -f "$dotest/rebasing"
+ then
commit=$(sed -e 's/^From \([0-9a-f]*\) .*/\1/' \
-e q "$dotest/$msgnum") &&
- test "$(git cat-file -t "$commit")" = commit
- then
+ test "$(git cat-file -t "$commit")" = commit ||
+ stop_here $this
git cat-file commit "$commit" |
sed -e '1,/^$/d' >"$dotest/msg-clean"
- echo "$commit" > "$dotest/original-commit"
- get_author_ident_from_commit "$commit" > "$dotest/author-script"
+ echo "$commit" >"$dotest/original-commit"
+ get_author_ident_from_commit "$commit" >"$dotest/author-script"
+ git diff-tree --root --binary "$commit" >"$dotest/patch"
else
+ git mailinfo $keep $no_inbody_headers $scissors $utf8 "$dotest/msg" "$dotest/patch" \
+ <"$dotest/$msgnum" >"$dotest/info" ||
+ stop_here $this
+
+ # skip pine's internal folder data
+ sane_grep '^Author: Mail System Internal Data$' \
+ <"$dotest"/info >/dev/null &&
+ go_next && continue
+
+ test -s "$dotest/patch" || {
+ eval_gettextln "Patch is empty. Was it split wrong?
+If you would prefer to skip this patch, instead run \"\$cmdline --skip\".
+To restore the original branch and stop patching run \"\$cmdline --abort\"."
+ stop_here $this
+ }
+ rm -f "$dotest/original-commit" "$dotest/author-script"
{
sed -n '/^Subject/ s/Subject: //p' "$dotest/info"
echo
#endif
#endif
+/* used on Mac OS X */
+#ifdef PRECOMPOSE_UNICODE
+#include "compat/precompose_utf8.h"
+#else
+#define precompose_str(in,i_nfd2nfc)
+#define precompose_argv(c,v)
+#define probe_utf8_pathname_composition(a,b)
+#endif
+
#ifndef NO_LIBGEN_H
#include <libgen.h>
#else
s/.*/GIT_'$uid'_EMAIL='\''&'\''; export GIT_'$uid'_EMAIL/p
g
- s/^'$lid' [^<]* <[^>]*> \(.*\)$/\1/
+ s/^'$lid' [^<]* <[^>]*> \(.*\)$/@\1/
s/'\''/'\''\'\'\''/g
s/.*/GIT_'$uid'_DATE='\''&'\''; export GIT_'$uid'_DATE/p
real_cmd = p4_build_cmd(c)
return read_pipe_lines(real_cmd)
+def p4_has_command(cmd):
+ """Ask p4 for help on this command. If it returns an error, the
+ command does not exist in this version of p4."""
+ real_cmd = p4_build_cmd(["help", cmd])
+ p = subprocess.Popen(real_cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ p.communicate()
+ return p.returncode == 0
+
def system(cmd):
expand = isinstance(cmd,basestring)
if verbose:
def p4_reopen(type, f):
p4_system(["reopen", "-t", type, wildcard_encode(f)])
+def p4_move(src, dest):
+ p4_system(["move", "-k", wildcard_encode(src), wildcard_encode(dest)])
+
#
# Canonicalize the p4 type and return a tuple of the
# base type, plus any modifiers. See "p4 help filetypes"
]
self.description = "Submit changes from git to the perforce depot."
self.usage += " [name of git branch to submit into perforce depot]"
- self.interactive = True
self.origin = ""
self.detectRenames = False
self.preserveUser = gitConfig("git-p4.preserveUser").lower() == "true"
self.isWindows = (platform.system() == "Windows")
self.exportLabels = False
+ self.p4HasMoveCommand = p4_has_command("move")
def check(self):
if len(p4CmdList("opened ...")) > 0:
die("You have files opened with perforce! Close them before starting the sync.")
- # replaces everything between 'Description:' and the next P4 submit template field with the
- # commit message
- def prepareLogMessage(self, template, message):
+ def separate_jobs_from_description(self, message):
+ """Extract and return a possible Jobs field in the commit
+ message. It goes into a separate section in the p4 change
+ specification.
+
+ A jobs line starts with "Jobs:" and looks like a new field
+ in a form. Values are white-space separated on the same
+ line or on following lines that start with a tab.
+
+ This does not parse and extract the full git commit message
+ like a p4 form. It just sees the Jobs: line as a marker
+ to pass everything from then on directly into the p4 form,
+ but outside the description section.
+
+ Return a tuple (stripped log message, jobs string)."""
+
+ m = re.search(r'^Jobs:', message, re.MULTILINE)
+ if m is None:
+ return (message, None)
+
+ jobtext = message[m.start():]
+ stripped_message = message[:m.start()].rstrip()
+ return (stripped_message, jobtext)
+
+ def prepareLogMessage(self, template, message, jobs):
+ """Edits the template returned from "p4 change -o" to insert
+ the message in the Description field, and the jobs text in
+ the Jobs field."""
result = ""
inDescriptionSection = False
if inDescriptionSection:
if line.startswith("Files:") or line.startswith("Jobs:"):
inDescriptionSection = False
+ # insert Jobs section
+ if jobs:
+ result += jobs + "\n"
else:
continue
else:
return 0
def prepareSubmitTemplate(self):
- # remove lines in the Files section that show changes to files outside the depot path we're committing into
+ """Run "p4 change -o" to grab a change specification template.
+ This does not use "p4 -G", as it is nice to keep the submission
+ template in original order, since a human might edit it.
+
+ Remove lines in the Files section that show changes to files
+ outside the depot path we're committing into."""
+
template = ""
inFilesSection = False
for line in p4_read_pipe_lines(['change', '-o']):
(p4User, gitEmail) = self.p4UserForCommit(id)
- if not self.detectRenames:
- # If not explicitly set check the config variable
- self.detectRenames = gitConfig("git-p4.detectRenames")
-
- if self.detectRenames.lower() == "false" or self.detectRenames == "":
- diffOpts = ""
- elif self.detectRenames.lower() == "true":
- diffOpts = "-M"
- else:
- diffOpts = "-M%s" % self.detectRenames
-
- detectCopies = gitConfig("git-p4.detectCopies")
- if detectCopies.lower() == "true":
- diffOpts += " -C"
- elif detectCopies != "" and detectCopies.lower() != "false":
- diffOpts += " -C%s" % detectCopies
-
- if gitConfig("git-p4.detectCopiesHarder", "--bool") == "true":
- diffOpts += " --find-copies-harder"
-
- diff = read_pipe_lines("git diff-tree -r %s \"%s^\" \"%s\"" % (diffOpts, id, id))
+ diff = read_pipe_lines("git diff-tree -r %s \"%s^\" \"%s\"" % (self.diffOpts, id, id))
filesToAdd = set()
filesToDelete = set()
editedFiles = set()
editedFiles.add(dest)
elif modifier == "R":
src, dest = diff['src'], diff['dst']
- p4_integrate(src, dest)
- if diff['src_sha1'] != diff['dst_sha1']:
- p4_edit(dest)
+ if self.p4HasMoveCommand:
+ p4_edit(src) # src must be open before move
+ p4_move(src, dest) # opens for (move/delete, move/add)
else:
- pureRenameCopy.add(dest)
+ p4_integrate(src, dest)
+ if diff['src_sha1'] != diff['dst_sha1']:
+ p4_edit(dest)
+ else:
+ pureRenameCopy.add(dest)
if isModeExecChanged(diff['src_mode'], diff['dst_mode']):
- p4_edit(dest)
+ if not self.p4HasMoveCommand:
+ p4_edit(dest) # with move: already open, writable
filesToChangeExecBit[dest] = diff['dst_mode']
- os.unlink(dest)
+ if not self.p4HasMoveCommand:
+ os.unlink(dest)
+ filesToDelete.add(src)
editedFiles.add(dest)
- filesToDelete.add(src)
else:
die("unknown modifier %s for %s" % (modifier, path))
logMessage = extractLogMessageFromGitCommit(id)
logMessage = logMessage.strip()
+ (logMessage, jobs) = self.separate_jobs_from_description(logMessage)
template = self.prepareSubmitTemplate()
+ submitTemplate = self.prepareLogMessage(template, logMessage, jobs)
- if self.interactive:
- submitTemplate = self.prepareLogMessage(template, logMessage)
-
- if self.preserveUser:
- submitTemplate = submitTemplate + ("\n######## Actual user %s, modified after commit\n" % p4User)
-
- if os.environ.has_key("P4DIFF"):
- del(os.environ["P4DIFF"])
- diff = ""
- for editedFile in editedFiles:
- diff += p4_read_pipe(['diff', '-du',
- wildcard_encode(editedFile)])
-
- newdiff = ""
- for newFile in filesToAdd:
- newdiff += "==== new file ====\n"
- newdiff += "--- /dev/null\n"
- newdiff += "+++ %s\n" % newFile
- f = open(newFile, "r")
- for line in f.readlines():
- newdiff += "+" + line
- f.close()
-
- if self.checkAuthorship and not self.p4UserIsMe(p4User):
- submitTemplate += "######## git author %s does not match your p4 account.\n" % gitEmail
- submitTemplate += "######## Use option --preserve-user to modify authorship.\n"
- submitTemplate += "######## Variable git-p4.skipUserNameCheck hides this message.\n"
-
- separatorLine = "######## everything below this line is just the diff #######\n"
-
- (handle, fileName) = tempfile.mkstemp()
- tmpFile = os.fdopen(handle, "w+")
- if self.isWindows:
- submitTemplate = submitTemplate.replace("\n", "\r\n")
- separatorLine = separatorLine.replace("\n", "\r\n")
- newdiff = newdiff.replace("\n", "\r\n")
- tmpFile.write(submitTemplate + separatorLine + diff + newdiff)
+ if self.preserveUser:
+ submitTemplate = submitTemplate + ("\n######## Actual user %s, modified after commit\n" % p4User)
+
+ if os.environ.has_key("P4DIFF"):
+ del(os.environ["P4DIFF"])
+ diff = ""
+ for editedFile in editedFiles:
+ diff += p4_read_pipe(['diff', '-du',
+ wildcard_encode(editedFile)])
+
+ newdiff = ""
+ for newFile in filesToAdd:
+ newdiff += "==== new file ====\n"
+ newdiff += "--- /dev/null\n"
+ newdiff += "+++ %s\n" % newFile
+ f = open(newFile, "r")
+ for line in f.readlines():
+ newdiff += "+" + line
+ f.close()
+
+ if self.checkAuthorship and not self.p4UserIsMe(p4User):
+ submitTemplate += "######## git author %s does not match your p4 account.\n" % gitEmail
+ submitTemplate += "######## Use option --preserve-user to modify authorship.\n"
+ submitTemplate += "######## Variable git-p4.skipUserNameCheck hides this message.\n"
+
+ separatorLine = "######## everything below this line is just the diff #######\n"
+
+ (handle, fileName) = tempfile.mkstemp()
+ tmpFile = os.fdopen(handle, "w+")
+ if self.isWindows:
+ submitTemplate = submitTemplate.replace("\n", "\r\n")
+ separatorLine = separatorLine.replace("\n", "\r\n")
+ newdiff = newdiff.replace("\n", "\r\n")
+ tmpFile.write(submitTemplate + separatorLine + diff + newdiff)
+ tmpFile.close()
+
+ if self.edit_template(fileName):
+ # read the edited message and submit
+ tmpFile = open(fileName, "rb")
+ message = tmpFile.read()
tmpFile.close()
+ submitTemplate = message[:message.index(separatorLine)]
+ if self.isWindows:
+ submitTemplate = submitTemplate.replace("\r\n", "\n")
+ p4_write_pipe(['submit', '-i'], submitTemplate)
- if self.edit_template(fileName):
- # read the edited message and submit
- tmpFile = open(fileName, "rb")
- message = tmpFile.read()
- tmpFile.close()
- submitTemplate = message[:message.index(separatorLine)]
- if self.isWindows:
- submitTemplate = submitTemplate.replace("\r\n", "\n")
- p4_write_pipe(['submit', '-i'], submitTemplate)
-
- if self.preserveUser:
- if p4User:
- # Get last changelist number. Cannot easily get it from
- # the submit command output as the output is
- # unmarshalled.
- changelist = self.lastP4Changelist()
- self.modifyChangelistUser(changelist, p4User)
-
- # The rename/copy happened by applying a patch that created a
- # new file. This leaves it writable, which confuses p4.
- for f in pureRenameCopy:
- p4_sync(f, "-f")
-
- else:
- # skip this patch
- print "Submission cancelled, undoing p4 changes."
- for f in editedFiles:
- p4_revert(f)
- for f in filesToAdd:
- p4_revert(f)
- os.remove(f)
+ if self.preserveUser:
+ if p4User:
+ # Get last changelist number. Cannot easily get it from
+ # the submit command output as the output is
+ # unmarshalled.
+ changelist = self.lastP4Changelist()
+ self.modifyChangelistUser(changelist, p4User)
+
+ # The rename/copy happened by applying a patch that created a
+ # new file. This leaves it writable, which confuses p4.
+ for f in pureRenameCopy:
+ p4_sync(f, "-f")
- os.remove(fileName)
else:
- fileName = "submit.txt"
- file = open(fileName, "w+")
- file.write(self.prepareLogMessage(template, logMessage))
- file.close()
- print ("Perforce submit template written as %s. "
- + "Please review/edit and then use p4 submit -i < %s to submit directly!"
- % (fileName, fileName))
+ # skip this patch
+ print "Submission cancelled, undoing p4 changes."
+ for f in editedFiles:
+ p4_revert(f)
+ for f in filesToAdd:
+ p4_revert(f)
+ os.remove(f)
+
+ os.remove(fileName)
# Export git tags as p4 labels. Create a p4 label and then tag
# with that.
if self.preserveUser:
self.checkValidP4Users(commits)
+ #
+ # Build up a set of options to be passed to diff when
+ # submitting each commit to p4.
+ #
+ if self.detectRenames:
+ # command-line -M arg
+ self.diffOpts = "-M"
+ else:
+ # If not explicitly set check the config variable
+ detectRenames = gitConfig("git-p4.detectRenames")
+
+ if detectRenames.lower() == "false" or detectRenames == "":
+ self.diffOpts = ""
+ elif detectRenames.lower() == "true":
+ self.diffOpts = "-M"
+ else:
+ self.diffOpts = "-M%s" % detectRenames
+
+ # no command-line arg for -C or --find-copies-harder, just
+ # config variables
+ detectCopies = gitConfig("git-p4.detectCopies")
+ if detectCopies.lower() == "false" or detectCopies == "":
+ pass
+ elif detectCopies.lower() == "true":
+ self.diffOpts += " -C"
+ else:
+ self.diffOpts += " -C%s" % detectCopies
+
+ if gitConfig("git-p4.detectCopiesHarder", "--bool") == "true":
+ self.diffOpts += " --find-copies-harder"
+
while len(commits) > 0:
commit = commits[0]
commits = commits[1:]
self.applyCommit(commit)
- if not self.interactive:
- break
if len(commits) == 0:
print "All changes applied!"
# Copyright (c) 2010 Junio C Hamano.
#
-. git-sh-setup
-
case "$action" in
continue)
git am --resolved --resolvemsg="$resolvemsg" &&
#
# The original idea comes from Eric W. Biederman, in
# http://article.gmane.org/gmane.comp.version-control.git/22407
-
-. git-sh-setup
-
+#
# The file containing rebase commands, comments, and empty lines.
# This file is created by "git rebase -i" then edited by the user. As
# the lines are processed, they are removed from the front of this
esac
}
+do_pick () {
+ if test "$(git rev-parse HEAD)" = "$squash_onto"
+ then
+ # Set the correct commit message and author info on the
+ # sentinel root before cherry-picking the original changes
+ # without committing (-n). Finally, update the sentinel again
+ # to include these changes. If the cherry-pick results in a
+ # conflict, this means our behaviour is similar to a standard
+ # failed cherry-pick during rebase, with a dirty index to
+ # resolve before manually running git commit --amend then git
+ # rebase --continue.
+ git commit --allow-empty --allow-empty-message --amend \
+ --no-post-rewrite -n -q -C $1 &&
+ pick_one -n $1 &&
+ git commit --allow-empty --allow-empty-message \
+ --amend --no-post-rewrite -n -q -C $1 ||
+ die_with_patch $1 "Could not apply $1... $2"
+ else
+ pick_one $1 ||
+ die_with_patch $1 "Could not apply $1... $2"
+ fi
+}
+
do_next () {
rm -f "$msg" "$author_script" "$amend" || exit
read -r command sha1 rest < "$todo"
comment_for_reflog pick
mark_action_done
- pick_one $sha1 ||
- die_with_patch $sha1 "Could not apply $sha1... $rest"
+ do_pick $sha1 "$rest"
record_in_rewritten $sha1
;;
reword|r)
comment_for_reflog reword
mark_action_done
- pick_one $sha1 ||
- die_with_patch $sha1 "Could not apply $sha1... $rest"
+ do_pick $sha1 "$rest"
git commit --amend --no-post-rewrite || {
warn "Could not amend commit after successfully picking $sha1... $rest"
warn "This is most likely due to an empty commit message, or the pre-commit hook"
comment_for_reflog edit
mark_action_done
- pick_one $sha1 ||
- die_with_patch $sha1 "Could not apply $sha1... $rest"
+ do_pick $sha1 "$rest"
warn "Stopped at $sha1... $rest"
exit_with_patch $sha1 0
;;
rm -f "$1.sq" "$1.rearranged"
}
+# Add commands after a pick or after a squash/fixup serie
+# in the todo list.
+add_exec_commands () {
+ {
+ first=t
+ while read -r insn rest
+ do
+ case $insn in
+ pick)
+ test -n "$first" ||
+ printf "%s" "$cmd"
+ ;;
+ esac
+ printf "%s %s\n" "$insn" "$rest"
+ first=
+ done
+ printf "%s" "$cmd"
+ } <"$1" >"$1.new" &&
+ mv "$1.new" "$1"
+}
+
case "$action" in
continue)
# do we have anything to commit?
test -s "$todo" || echo noop >> "$todo"
test -n "$autosquash" && rearrange_squash "$todo"
+test -n "$cmd" && add_exec_commands "$todo"
+
cat >> "$todo" << EOF
# Rebase $shortrevisions onto $shortonto
# Copyright (c) 2010 Junio C Hamano.
#
-. git-sh-setup
-
prec=4
read_state () {
# Copyright (c) 2005 Junio C Hamano.
#
-USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
+USAGE='[--interactive | -i] [--exec | -x <cmd>] [-v] [--force-rebase | -f]
+ [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
LONG_USAGE='git-rebase replaces <branch> with a new branch of the
same name. When the --onto option is provided the new branch starts
out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
SUBDIRECTORY_OK=Yes
OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
-git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
-git rebase [-i] [options] --onto <newbase> --root [<branch>]
+git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
+git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
git-rebase [-i] --continue | --abort | --skip
--
Available options are
no-ff! cherry-pick all commits, even if unchanged
m,merge! use merging strategies to rebase
i,interactive! let the user edit the list of commits to rebase
+x,exec=! add exec lines after each commit of the editable list
k,keep-empty preserve empty commits during rebase
f,force-rebase! force rebase even if branch is up to date
X,strategy-option=! pass the argument through to the merge strategy
To check out the original branch and stop rebasing run \"git rebase --abort\".
"
unset onto
+cmd=
strategy=
strategy_opts=
do_merge=
onto="$2"
shift
;;
+ -x)
+ test 2 -le "$#" || usage
+ cmd="${cmd}exec $2${LF}"
+ shift
+ ;;
-i)
interactive_rebase=explicit
;;
done
test $# -gt 2 && usage
+if test -n "$cmd" &&
+ test "$interactive_rebase" != explicit
+then
+ die "--exec option must be used with --interactive option"
+fi
+
if test -n "$action"
then
test -z "$in_progress" && die "No rebase in progress?"
valuable there.'
fi
+if test -n "$rebase_root" && test -z "$onto"
+then
+ test -z "$interactive_rebase" && interactive_rebase=implied
+fi
+
if test -n "$interactive_rebase"
then
type=interactive
die "invalid upstream $upstream_name"
upstream_arg="$upstream_name"
else
- test -z "$onto" && die "You must specify --onto when using --root"
+ if test -z "$onto"
+ then
+ empty_tree=`git hash-object -t tree /dev/null`
+ onto=`git commit-tree $empty_tree </dev/null`
+ squash_onto="$onto"
+ fi
unset upstream_name
unset upstream
+ test $# -gt 1 && usage
upstream_arg=--root
fi
die "fatal: no such branch: $1"
fi
;;
-*)
+0)
# Do not need to switch branches, we are already on it.
if branch_name=`git symbolic-ref -q HEAD`
then
fi
orig_head=$(git rev-parse --verify "${branch_name}^0") || exit
;;
+*)
+ die "BUG: unexpected number of arguments left to parse"
+ ;;
esac
require_clean_work_tree "rebase" "Please commit or stash them."
merge_base=$(git merge-base $baserev $headrev) ||
die "fatal: No commits in common between $base and $head"
-# $head is the token given from the command line. If a ref with that
-# name exists at the remote and their values match, we should use it.
-# Otherwise find a ref that matches $headrev.
+# $head is the token given from the command line, and $tag_name, if
+# exists, is the tag we are going to show the commit information for.
+# If that tag exists at the remote and it points at the commit, use it.
+# Otherwise, if a branch with the same name as $head exists at the remote
+# and their values match, use that instead.
+#
+# Otherwise find a random ref that matches $headrev.
find_matching_ref='
sub abbr {
my $ref = shift;
}
}
- my ($exact, $found);
+ my ($tagged, $branch, $found);
while (<STDIN>) {
my ($sha1, $ref, $deref) = /^(\S+)\s+(\S+?)(\^\{\})?$/;
next unless ($sha1 eq $ARGV[1]);
$found = abbr($ref);
+ if ($deref && $ref eq "tags/$ARGV[2]") {
+ $tagged = $found;
+ last;
+ }
if ($ref =~ m|/\Q$ARGV[0]\E$|) {
$exact = $found;
- last;
}
}
- if ($exact) {
+ if ($tagged) {
+ print "$tagged\n";
+ } elsif ($exact) {
print "$exact\n";
} elsif ($found) {
print "$found\n";
}
'
-ref=$(git ls-remote "$url" | perl -e "$find_matching_ref" "$head" "$headrev")
+ref=$(git ls-remote "$url" | perl -e "$find_matching_ref" "$head" "$headrev" "$tag_name")
url=$(git ls-remote --get-url "$url")
if test -n "$tag_name"
then
+ if test -z "$ref" || test "$ref" != "tags/$tag_name"
+ then
+ echo >&2 "warn: You locally have $tag_name but it does not (yet)"
+ echo >&2 "warn: appear to be at $url"
+ echo >&2 "warn: Do you want to push it there, perhaps?"
+ fi
git cat-file tag "$tag_name" |
sed -n -e '1,/^$/d' -e '/^-----BEGIN PGP /q' -e p
echo
#!/bin/sh
#
-# git-submodules.sh: add, init, update or list git submodules
+# git-submodule.sh: add, init, update or list git submodules
#
# Copyright (c) 2007 Lars Hjemli
update=
prefix=
-# Resolve relative url by appending to parent's url
+# The function takes at most 2 arguments. The first argument is the
+# URL that navigates to the submodule origin repo. When relative, this URL
+# is relative to the superproject origin URL repo. The second up_path
+# argument, if specified, is the relative path that navigates
+# from the submodule working tree to the superproject working tree.
+#
+# The output of the function is the origin URL of the submodule.
+#
+# The output will either be an absolute URL or filesystem path (if the
+# superproject origin URL is an absolute URL or filesystem path,
+# respectively) or a relative file system path (if the superproject
+# origin URL is a relative file system path).
+#
+# When the output is a relative file system path, the path is either
+# relative to the submodule working tree, if up_path is specified, or to
+# the superproject working tree otherwise.
resolve_relative_url ()
{
remote=$(get_default_remote)
url="$1"
remoteurl=${remoteurl%/}
sep=/
+ up_path="$2"
+
+ case "$remoteurl" in
+ *:*|/*)
+ is_relative=
+ ;;
+ ./*|../*)
+ is_relative=t
+ ;;
+ *)
+ is_relative=t
+ remoteurl="./$remoteurl"
+ ;;
+ esac
+
while test -n "$url"
do
case "$url" in
sep=:
;;
*)
- die "$(eval_gettext "cannot strip one component off url '\$remoteurl'")"
+ if test -z "$is_relative" || test "." = "$remoteurl"
+ then
+ die "$(eval_gettext "cannot strip one component off url '\$remoteurl'")"
+ else
+ remoteurl=.
+ fi
;;
esac
;;
break;;
esac
done
- echo "$remoteurl$sep${url%/}"
+ remoteurl="$remoteurl$sep${url%/}"
+ echo "${is_relative:+${up_path}}${remoteurl#./}"
}
#
# Possibly a url relative to parent
case "$url" in
./*|../*)
- url=$(resolve_relative_url "$url") || exit
+ # rewrite foo/bar as ../.. to find path from
+ # submodule work tree to superproject work tree
+ up_path="$(echo "$sm_path" | sed "s/[^/][^/]*/../g")" &&
+ # guarantee a trailing /
+ up_path=${up_path%/}/ &&
+ # path from submodule work tree to submodule origin repo
+ sub_origin_url=$(resolve_relative_url "$url" "$up_path") &&
+ # path from superproject work tree to submodule origin repo
+ super_config_url=$(resolve_relative_url "$url") || exit
+ ;;
+ *)
+ sub_origin_url="$url"
+ super_config_url="$url"
;;
esac
if git config "submodule.$name.url" >/dev/null 2>/dev/null
then
say "$(eval_gettext "Synchronizing submodule url for '\$name'")"
- git config submodule."$name".url "$url"
+ git config submodule."$name".url "$super_config_url"
if test -e "$sm_path"/.git
then
clear_local_git_env
cd "$sm_path"
remote=$(get_default_remote)
- git config remote."$remote".url "$url"
+ git config remote."$remote".url "$sub_origin_url"
)
fi
fi
}
}
my $can_compress = eval { require Compress::Zlib; 1};
-push @Git::SVN::Ra::ISA, 'SVN::Ra';
-push @Git::SVN::Editor::ISA, 'SVN::Delta::Editor';
use Carp qw/croak/;
use Digest::MD5;
use IO::File qw//;
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
use IPC::Open3;
use Git;
+use Git::SVN::Editor qw//;
use Git::SVN::Fetcher qw//;
+use Git::SVN::Ra qw//;
use Git::SVN::Prompt qw//;
use Memoize; # core since 5.8.0, Jul 2002
foreach (qw/command command_oneline command_noisy command_output_pipe
command_input_pipe command_close_pipe
command_bidi_pipe command_close_bidi_pipe/) {
- for my $package ( qw(Git::SVN::Editor
- Git::SVN::Migration Git::SVN::Log Git::SVN),
+ for my $package ( qw(Git::SVN::Migration Git::SVN::Log Git::SVN),
__PACKAGE__) {
*{"${package}::$_"} = \&{"Git::$_"};
}
" with the --destination argument.\n";
}
foreach my $g (@{$allglobs}) {
- # Git::SVN::Editor could probably be moved to Git.pm..
my $re = Git::SVN::Editor::glob2pat($g->{path}->{left});
if ($_branch_dest =~ /$re/) {
$glob = $g;
use Memoize; # core since 5.8.0, Jul 2002
use Memoize::Storable;
use POSIX qw(:signal_h);
+my $can_use_yaml;
+BEGIN {
+ $can_use_yaml = eval { require Git::SVN::Memoize::YAML; 1};
+}
my ($_gc_nr, $_gc_period);
command_oneline("rev-parse", "$commit~1^{tree}"));
}
+sub tie_for_persistent_memoization {
+ my $hash = shift;
+ my $path = shift;
+
+ if ($can_use_yaml) {
+ tie %$hash => 'Git::SVN::Memoize::YAML', "$path.yaml";
+ } else {
+ tie %$hash => 'Memoize::Storable', "$path.db", 'nstore';
+ }
+}
+
# The GIT_DIR environment variable is not always set until after the command
# line arguments are processed, so we can't memoize in a BEGIN block.
{
my $cache_path = "$ENV{GIT_DIR}/svn/.caches/";
mkpath([$cache_path]) unless -d $cache_path;
- tie my %lookup_svn_merge_cache => 'Memoize::Storable',
- "$cache_path/lookup_svn_merge.db", 'nstore';
+ my %lookup_svn_merge_cache;
+ my %check_cherry_pick_cache;
+ my %has_no_changes_cache;
+
+ tie_for_persistent_memoization(\%lookup_svn_merge_cache,
+ "$cache_path/lookup_svn_merge");
memoize 'lookup_svn_merge',
SCALAR_CACHE => 'FAULT',
LIST_CACHE => ['HASH' => \%lookup_svn_merge_cache],
;
- tie my %check_cherry_pick_cache => 'Memoize::Storable',
- "$cache_path/check_cherry_pick.db", 'nstore';
+ tie_for_persistent_memoization(\%check_cherry_pick_cache,
+ "$cache_path/check_cherry_pick");
memoize 'check_cherry_pick',
SCALAR_CACHE => 'FAULT',
LIST_CACHE => ['HASH' => \%check_cherry_pick_cache],
;
- tie my %has_no_changes_cache => 'Memoize::Storable',
- "$cache_path/has_no_changes.db", 'nstore';
+ tie_for_persistent_memoization(\%has_no_changes_cache,
+ "$cache_path/has_no_changes");
memoize 'has_no_changes',
SCALAR_CACHE => ['HASH' => \%has_no_changes_cache],
LIST_CACHE => 'FAULT',
$_[0] =~ s{^([^:]*://)[^@]+@}{$1};
}
-package Git::SVN::Editor;
-use vars qw/@ISA $_rmdir $_cp_similarity $_find_copies_harder $_rename_limit/;
-use strict;
-use warnings;
-use Carp qw/croak/;
-use IO::File;
-
-sub new {
- my ($class, $opts) = @_;
- foreach (qw/svn_path r ra tree_a tree_b log editor_cb/) {
- die "$_ required!\n" unless (defined $opts->{$_});
- }
-
- my $pool = SVN::Pool->new;
- my $mods = generate_diff($opts->{tree_a}, $opts->{tree_b});
- my $types = check_diff_paths($opts->{ra}, $opts->{svn_path},
- $opts->{r}, $mods);
-
- # $opts->{ra} functions should not be used after this:
- my @ce = $opts->{ra}->get_commit_editor($opts->{log},
- $opts->{editor_cb}, $pool);
- my $self = SVN::Delta::Editor->new(@ce, $pool);
- bless $self, $class;
- foreach (qw/svn_path r tree_a tree_b/) {
- $self->{$_} = $opts->{$_};
- }
- $self->{url} = $opts->{ra}->{url};
- $self->{mods} = $mods;
- $self->{types} = $types;
- $self->{pool} = $pool;
- $self->{bat} = { '' => $self->open_root($self->{r}, $self->{pool}) };
- $self->{rm} = { };
- $self->{path_prefix} = length $self->{svn_path} ?
- "$self->{svn_path}/" : '';
- $self->{config} = $opts->{config};
- $self->{mergeinfo} = $opts->{mergeinfo};
- return $self;
-}
-
-sub generate_diff {
- my ($tree_a, $tree_b) = @_;
- my @diff_tree = qw(diff-tree -z -r);
- if ($_cp_similarity) {
- push @diff_tree, "-C$_cp_similarity";
- } else {
- push @diff_tree, '-C';
- }
- push @diff_tree, '--find-copies-harder' if $_find_copies_harder;
- push @diff_tree, "-l$_rename_limit" if defined $_rename_limit;
- push @diff_tree, $tree_a, $tree_b;
- my ($diff_fh, $ctx) = command_output_pipe(@diff_tree);
- local $/ = "\0";
- my $state = 'meta';
- my @mods;
- while (<$diff_fh>) {
- chomp $_; # this gets rid of the trailing "\0"
- if ($state eq 'meta' && /^:(\d{6})\s(\d{6})\s
- ($::sha1)\s($::sha1)\s
- ([MTCRAD])\d*$/xo) {
- push @mods, { mode_a => $1, mode_b => $2,
- sha1_a => $3, sha1_b => $4,
- chg => $5 };
- if ($5 =~ /^(?:C|R)$/) {
- $state = 'file_a';
- } else {
- $state = 'file_b';
- }
- } elsif ($state eq 'file_a') {
- my $x = $mods[$#mods] or croak "Empty array\n";
- if ($x->{chg} !~ /^(?:C|R)$/) {
- croak "Error parsing $_, $x->{chg}\n";
- }
- $x->{file_a} = $_;
- $state = 'file_b';
- } elsif ($state eq 'file_b') {
- my $x = $mods[$#mods] or croak "Empty array\n";
- if (exists $x->{file_a} && $x->{chg} !~ /^(?:C|R)$/) {
- croak "Error parsing $_, $x->{chg}\n";
- }
- if (!exists $x->{file_a} && $x->{chg} =~ /^(?:C|R)$/) {
- croak "Error parsing $_, $x->{chg}\n";
- }
- $x->{file_b} = $_;
- $state = 'meta';
- } else {
- croak "Error parsing $_\n";
- }
- }
- command_close_pipe($diff_fh, $ctx);
- \@mods;
-}
-
-sub check_diff_paths {
- my ($ra, $pfx, $rev, $mods) = @_;
- my %types;
- $pfx .= '/' if length $pfx;
-
- sub type_diff_paths {
- my ($ra, $types, $path, $rev) = @_;
- my @p = split m#/+#, $path;
- my $c = shift @p;
- unless (defined $types->{$c}) {
- $types->{$c} = $ra->check_path($c, $rev);
- }
- while (@p) {
- $c .= '/' . shift @p;
- next if defined $types->{$c};
- $types->{$c} = $ra->check_path($c, $rev);
- }
- }
-
- foreach my $m (@$mods) {
- foreach my $f (qw/file_a file_b/) {
- next unless defined $m->{$f};
- my ($dir) = ($m->{$f} =~ m#^(.*?)/?(?:[^/]+)$#);
- if (length $pfx.$dir && ! defined $types{$dir}) {
- type_diff_paths($ra, \%types, $pfx.$dir, $rev);
- }
- }
- }
- \%types;
-}
-
-sub split_path {
- return ($_[0] =~ m#^(.*?)/?([^/]+)$#);
-}
-
-sub repo_path {
- my ($self, $path) = @_;
- if (my $enc = $self->{pathnameencoding}) {
- require Encode;
- Encode::from_to($path, $enc, 'UTF-8');
- }
- $self->{path_prefix}.(defined $path ? $path : '');
-}
-
-sub url_path {
- my ($self, $path) = @_;
- if ($self->{url} =~ m#^https?://#) {
- $path =~ s!([^~a-zA-Z0-9_./-])!uc sprintf("%%%02x",ord($1))!eg;
- }
- $self->{url} . '/' . $self->repo_path($path);
-}
-
-sub rmdirs {
- my ($self) = @_;
- my $rm = $self->{rm};
- delete $rm->{''}; # we never delete the url we're tracking
- return unless %$rm;
-
- foreach (keys %$rm) {
- my @d = split m#/#, $_;
- my $c = shift @d;
- $rm->{$c} = 1;
- while (@d) {
- $c .= '/' . shift @d;
- $rm->{$c} = 1;
- }
- }
- delete $rm->{$self->{svn_path}};
- delete $rm->{''}; # we never delete the url we're tracking
- return unless %$rm;
-
- my ($fh, $ctx) = command_output_pipe(qw/ls-tree --name-only -r -z/,
- $self->{tree_b});
- local $/ = "\0";
- while (<$fh>) {
- chomp;
- my @dn = split m#/#, $_;
- while (pop @dn) {
- delete $rm->{join '/', @dn};
- }
- unless (%$rm) {
- close $fh;
- return;
- }
- }
- command_close_pipe($fh, $ctx);
-
- my ($r, $p, $bat) = ($self->{r}, $self->{pool}, $self->{bat});
- foreach my $d (sort { $b =~ tr#/#/# <=> $a =~ tr#/#/# } keys %$rm) {
- $self->close_directory($bat->{$d}, $p);
- my ($dn) = ($d =~ m#^(.*?)/?(?:[^/]+)$#);
- print "\tD+\t$d/\n" unless $::_q;
- $self->SUPER::delete_entry($d, $r, $bat->{$dn}, $p);
- delete $bat->{$d};
- }
-}
-
-sub open_or_add_dir {
- my ($self, $full_path, $baton, $deletions) = @_;
- my $t = $self->{types}->{$full_path};
- if (!defined $t) {
- die "$full_path not known in r$self->{r} or we have a bug!\n";
- }
- {
- no warnings 'once';
- # SVN::Node::none and SVN::Node::file are used only once,
- # so we're shutting up Perl's warnings about them.
- if ($t == $SVN::Node::none || defined($deletions->{$full_path})) {
- return $self->add_directory($full_path, $baton,
- undef, -1, $self->{pool});
- } elsif ($t == $SVN::Node::dir) {
- return $self->open_directory($full_path, $baton,
- $self->{r}, $self->{pool});
- } # no warnings 'once'
- print STDERR "$full_path already exists in repository at ",
- "r$self->{r} and it is not a directory (",
- ($t == $SVN::Node::file ? 'file' : 'unknown'),"/$t)\n";
- } # no warnings 'once'
- exit 1;
-}
-
-sub ensure_path {
- my ($self, $path, $deletions) = @_;
- my $bat = $self->{bat};
- my $repo_path = $self->repo_path($path);
- return $bat->{''} unless (length $repo_path);
-
- my @p = split m#/+#, $repo_path;
- my $c = shift @p;
- $bat->{$c} ||= $self->open_or_add_dir($c, $bat->{''}, $deletions);
- while (@p) {
- my $c0 = $c;
- $c .= '/' . shift @p;
- $bat->{$c} ||= $self->open_or_add_dir($c, $bat->{$c0}, $deletions);
- }
- return $bat->{$c};
-}
-
-# Subroutine to convert a globbing pattern to a regular expression.
-# From perl cookbook.
-sub glob2pat {
- my $globstr = shift;
- my %patmap = ('*' => '.*', '?' => '.', '[' => '[', ']' => ']');
- $globstr =~ s{(.)} { $patmap{$1} || "\Q$1" }ge;
- return '^' . $globstr . '$';
-}
-
-sub check_autoprop {
- my ($self, $pattern, $properties, $file, $fbat) = @_;
- # Convert the globbing pattern to a regular expression.
- my $regex = glob2pat($pattern);
- # Check if the pattern matches the file name.
- if($file =~ m/($regex)/) {
- # Parse the list of properties to set.
- my @props = split(/;/, $properties);
- foreach my $prop (@props) {
- # Parse 'name=value' syntax and set the property.
- if ($prop =~ /([^=]+)=(.*)/) {
- my ($n,$v) = ($1,$2);
- for ($n, $v) {
- s/^\s+//; s/\s+$//;
- }
- $self->change_file_prop($fbat, $n, $v);
- }
- }
- }
-}
-
-sub apply_autoprops {
- my ($self, $file, $fbat) = @_;
- my $conf_t = ${$self->{config}}{'config'};
- no warnings 'once';
- # Check [miscellany]/enable-auto-props in svn configuration.
- if (SVN::_Core::svn_config_get_bool(
- $conf_t,
- $SVN::_Core::SVN_CONFIG_SECTION_MISCELLANY,
- $SVN::_Core::SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS,
- 0)) {
- # Auto-props are enabled. Enumerate them to look for matches.
- my $callback = sub {
- $self->check_autoprop($_[0], $_[1], $file, $fbat);
- };
- SVN::_Core::svn_config_enumerate(
- $conf_t,
- $SVN::_Core::SVN_CONFIG_SECTION_AUTO_PROPS,
- $callback);
- }
-}
-
-sub A {
- my ($self, $m, $deletions) = @_;
- my ($dir, $file) = split_path($m->{file_b});
- my $pbat = $self->ensure_path($dir, $deletions);
- my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
- undef, -1);
- print "\tA\t$m->{file_b}\n" unless $::_q;
- $self->apply_autoprops($file, $fbat);
- $self->chg_file($fbat, $m);
- $self->close_file($fbat,undef,$self->{pool});
-}
-
-sub C {
- my ($self, $m, $deletions) = @_;
- my ($dir, $file) = split_path($m->{file_b});
- my $pbat = $self->ensure_path($dir, $deletions);
- my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
- $self->url_path($m->{file_a}), $self->{r});
- print "\tC\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
- $self->chg_file($fbat, $m);
- $self->close_file($fbat,undef,$self->{pool});
-}
-
-sub delete_entry {
- my ($self, $path, $pbat) = @_;
- my $rpath = $self->repo_path($path);
- my ($dir, $file) = split_path($rpath);
- $self->{rm}->{$dir} = 1;
- $self->SUPER::delete_entry($rpath, $self->{r}, $pbat, $self->{pool});
-}
-
-sub R {
- my ($self, $m, $deletions) = @_;
- my ($dir, $file) = split_path($m->{file_b});
- my $pbat = $self->ensure_path($dir, $deletions);
- my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
- $self->url_path($m->{file_a}), $self->{r});
- print "\tR\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
- $self->apply_autoprops($file, $fbat);
- $self->chg_file($fbat, $m);
- $self->close_file($fbat,undef,$self->{pool});
-
- ($dir, $file) = split_path($m->{file_a});
- $pbat = $self->ensure_path($dir, $deletions);
- $self->delete_entry($m->{file_a}, $pbat);
-}
-
-sub M {
- my ($self, $m, $deletions) = @_;
- my ($dir, $file) = split_path($m->{file_b});
- my $pbat = $self->ensure_path($dir, $deletions);
- my $fbat = $self->open_file($self->repo_path($m->{file_b}),
- $pbat,$self->{r},$self->{pool});
- print "\t$m->{chg}\t$m->{file_b}\n" unless $::_q;
- $self->chg_file($fbat, $m);
- $self->close_file($fbat,undef,$self->{pool});
-}
-
-sub T { shift->M(@_) }
-
-sub change_file_prop {
- my ($self, $fbat, $pname, $pval) = @_;
- $self->SUPER::change_file_prop($fbat, $pname, $pval, $self->{pool});
-}
-
-sub change_dir_prop {
- my ($self, $pbat, $pname, $pval) = @_;
- $self->SUPER::change_dir_prop($pbat, $pname, $pval, $self->{pool});
-}
-
-sub _chg_file_get_blob ($$$$) {
- my ($self, $fbat, $m, $which) = @_;
- my $fh = $::_repository->temp_acquire("git_blob_$which");
- if ($m->{"mode_$which"} =~ /^120/) {
- print $fh 'link ' or croak $!;
- $self->change_file_prop($fbat,'svn:special','*');
- } elsif ($m->{mode_a} =~ /^120/ && $m->{"mode_$which"} !~ /^120/) {
- $self->change_file_prop($fbat,'svn:special',undef);
- }
- my $blob = $m->{"sha1_$which"};
- return ($fh,) if ($blob =~ /^0{40}$/);
- my $size = $::_repository->cat_blob($blob, $fh);
- croak "Failed to read object $blob" if ($size < 0);
- $fh->flush == 0 or croak $!;
- seek $fh, 0, 0 or croak $!;
-
- my $exp = ::md5sum($fh);
- seek $fh, 0, 0 or croak $!;
- return ($fh, $exp);
-}
-
-sub chg_file {
- my ($self, $fbat, $m) = @_;
- if ($m->{mode_b} =~ /755$/ && $m->{mode_a} !~ /755$/) {
- $self->change_file_prop($fbat,'svn:executable','*');
- } elsif ($m->{mode_b} !~ /755$/ && $m->{mode_a} =~ /755$/) {
- $self->change_file_prop($fbat,'svn:executable',undef);
- }
- my ($fh_a, $exp_a) = _chg_file_get_blob $self, $fbat, $m, 'a';
- my ($fh_b, $exp_b) = _chg_file_get_blob $self, $fbat, $m, 'b';
- my $pool = SVN::Pool->new;
- my $atd = $self->apply_textdelta($fbat, $exp_a, $pool);
- if (-s $fh_a) {
- my $txstream = SVN::TxDelta::new ($fh_a, $fh_b, $pool);
- my $res = SVN::TxDelta::send_txstream($txstream, @$atd, $pool);
- if (defined $res) {
- die "Unexpected result from send_txstream: $res\n",
- "(SVN::Core::VERSION: $SVN::Core::VERSION)\n";
- }
- } else {
- my $got = SVN::TxDelta::send_stream($fh_b, @$atd, $pool);
- die "Checksum mismatch\nexpected: $exp_b\ngot: $got\n"
- if ($got ne $exp_b);
- }
- Git::temp_release($fh_b, 1);
- Git::temp_release($fh_a, 1);
- $pool->clear;
-}
-
-sub D {
- my ($self, $m, $deletions) = @_;
- my ($dir, $file) = split_path($m->{file_b});
- my $pbat = $self->ensure_path($dir, $deletions);
- print "\tD\t$m->{file_b}\n" unless $::_q;
- $self->delete_entry($m->{file_b}, $pbat);
-}
-
-sub close_edit {
- my ($self) = @_;
- my ($p,$bat) = ($self->{pool}, $self->{bat});
- foreach (sort { $b =~ tr#/#/# <=> $a =~ tr#/#/# } keys %$bat) {
- next if $_ eq '';
- $self->close_directory($bat->{$_}, $p);
- }
- $self->close_directory($bat->{''}, $p);
- $self->SUPER::close_edit($p);
- $p->clear;
-}
-
-sub abort_edit {
- my ($self) = @_;
- $self->SUPER::abort_edit($self->{pool});
-}
-
-sub DESTROY {
- my $self = shift;
- $self->SUPER::DESTROY(@_);
- $self->{pool}->clear;
-}
-
-# this drives the editor
-sub apply_diff {
- my ($self) = @_;
- my $mods = $self->{mods};
- my %o = ( D => 0, C => 1, R => 2, A => 3, M => 4, T => 5 );
- my %deletions;
-
- foreach my $m (@$mods) {
- if ($m->{chg} eq "D") {
- $deletions{$m->{file_b}} = 1;
- }
- }
-
- foreach my $m (sort { $o{$a->{chg}} <=> $o{$b->{chg}} } @$mods) {
- my $f = $m->{chg};
- if (defined $o{$f}) {
- $self->$f($m, \%deletions);
- } else {
- fatal("Invalid change type: $f");
- }
- }
-
- if (defined($self->{mergeinfo})) {
- $self->change_dir_prop($self->{bat}{''}, "svn:mergeinfo",
- $self->{mergeinfo});
- }
- $self->rmdirs if $_rmdir;
- if (@$mods == 0 && !defined($self->{mergeinfo})) {
- $self->abort_edit;
- } else {
- $self->close_edit;
- }
- return scalar @$mods;
-}
-
-package Git::SVN::Ra;
-use vars qw/@ISA $config_dir $_ignore_refs_regex $_log_window_size/;
-use strict;
-use warnings;
-my ($ra_invalid, $can_do_switch, %ignored_err, $RA);
-
-BEGIN {
- # enforce temporary pool usage for some simple functions
- no strict 'refs';
- for my $f (qw/rev_proplist get_latest_revnum get_uuid get_repos_root
- get_file/) {
- my $SUPER = "SUPER::$f";
- *$f = sub {
- my $self = shift;
- my $pool = SVN::Pool->new;
- my @ret = $self->$SUPER(@_,$pool);
- $pool->clear;
- wantarray ? @ret : $ret[0];
- };
- }
-}
-
-sub _auth_providers () {
- my @rv = (
- SVN::Client::get_simple_provider(),
- SVN::Client::get_ssl_server_trust_file_provider(),
- SVN::Client::get_simple_prompt_provider(
- \&Git::SVN::Prompt::simple, 2),
- SVN::Client::get_ssl_client_cert_file_provider(),
- SVN::Client::get_ssl_client_cert_prompt_provider(
- \&Git::SVN::Prompt::ssl_client_cert, 2),
- SVN::Client::get_ssl_client_cert_pw_file_provider(),
- SVN::Client::get_ssl_client_cert_pw_prompt_provider(
- \&Git::SVN::Prompt::ssl_client_cert_pw, 2),
- SVN::Client::get_username_provider(),
- SVN::Client::get_ssl_server_trust_prompt_provider(
- \&Git::SVN::Prompt::ssl_server_trust),
- SVN::Client::get_username_prompt_provider(
- \&Git::SVN::Prompt::username, 2)
- );
-
- # earlier 1.6.x versions would segfault, and <= 1.5.x didn't have
- # this function
- if (::compare_svn_version('1.6.12') > 0) {
- my $config = SVN::Core::config_get_config($config_dir);
- my ($p, @a);
- # config_get_config returns all config files from
- # ~/.subversion, auth_get_platform_specific_client_providers
- # just wants the config "file".
- @a = ($config->{'config'}, undef);
- $p = SVN::Core::auth_get_platform_specific_client_providers(@a);
- # Insert the return value from
- # auth_get_platform_specific_providers
- unshift @rv, @$p;
- }
- \@rv;
-}
-
-sub escape_uri_only {
- my ($uri) = @_;
- my @tmp;
- foreach (split m{/}, $uri) {
- s/([^~\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
- push @tmp, $_;
- }
- join('/', @tmp);
-}
-
-sub escape_url {
- my ($url) = @_;
- if ($url =~ m#^(https?)://([^/]+)(.*)$#) {
- my ($scheme, $domain, $uri) = ($1, $2, escape_uri_only($3));
- $url = "$scheme://$domain$uri";
- }
- $url;
-}
-
-sub new {
- my ($class, $url) = @_;
- $url =~ s!/+$!!;
- return $RA if ($RA && $RA->{url} eq $url);
-
- ::_req_svn();
-
- SVN::_Core::svn_config_ensure($config_dir, undef);
- my ($baton, $callbacks) = SVN::Core::auth_open_helper(_auth_providers);
- my $config = SVN::Core::config_get_config($config_dir);
- $RA = undef;
- my $dont_store_passwords = 1;
- my $conf_t = ${$config}{'config'};
- {
- no warnings 'once';
- # The usage of $SVN::_Core::SVN_CONFIG_* variables
- # produces warnings that variables are used only once.
- # I had not found the better way to shut them up, so
- # the warnings of type 'once' are disabled in this block.
- if (SVN::_Core::svn_config_get_bool($conf_t,
- $SVN::_Core::SVN_CONFIG_SECTION_AUTH,
- $SVN::_Core::SVN_CONFIG_OPTION_STORE_PASSWORDS,
- 1) == 0) {
- SVN::_Core::svn_auth_set_parameter($baton,
- $SVN::_Core::SVN_AUTH_PARAM_DONT_STORE_PASSWORDS,
- bless (\$dont_store_passwords, "_p_void"));
- }
- if (SVN::_Core::svn_config_get_bool($conf_t,
- $SVN::_Core::SVN_CONFIG_SECTION_AUTH,
- $SVN::_Core::SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
- 1) == 0) {
- $Git::SVN::Prompt::_no_auth_cache = 1;
- }
- } # no warnings 'once'
- my $self = SVN::Ra->new(url => escape_url($url), auth => $baton,
- config => $config,
- pool => SVN::Pool->new,
- auth_provider_callbacks => $callbacks);
- $self->{url} = $url;
- $self->{svn_path} = $url;
- $self->{repos_root} = $self->get_repos_root;
- $self->{svn_path} =~ s#^\Q$self->{repos_root}\E(/|$)##;
- $self->{cache} = { check_path => { r => 0, data => {} },
- get_dir => { r => 0, data => {} } };
- $RA = bless $self, $class;
-}
-
-sub check_path {
- my ($self, $path, $r) = @_;
- my $cache = $self->{cache}->{check_path};
- if ($r == $cache->{r} && exists $cache->{data}->{$path}) {
- return $cache->{data}->{$path};
- }
- my $pool = SVN::Pool->new;
- my $t = $self->SUPER::check_path($path, $r, $pool);
- $pool->clear;
- if ($r != $cache->{r}) {
- %{$cache->{data}} = ();
- $cache->{r} = $r;
- }
- $cache->{data}->{$path} = $t;
-}
-
-sub get_dir {
- my ($self, $dir, $r) = @_;
- my $cache = $self->{cache}->{get_dir};
- if ($r == $cache->{r}) {
- if (my $x = $cache->{data}->{$dir}) {
- return wantarray ? @$x : $x->[0];
- }
- }
- my $pool = SVN::Pool->new;
- my ($d, undef, $props) = $self->SUPER::get_dir($dir, $r, $pool);
- my %dirents = map { $_ => { kind => $d->{$_}->kind } } keys %$d;
- $pool->clear;
- if ($r != $cache->{r}) {
- %{$cache->{data}} = ();
- $cache->{r} = $r;
- }
- $cache->{data}->{$dir} = [ \%dirents, $r, $props ];
- wantarray ? (\%dirents, $r, $props) : \%dirents;
-}
-
-sub DESTROY {
- # do not call the real DESTROY since we store ourselves in $RA
-}
-
-# get_log(paths, start, end, limit,
-# discover_changed_paths, strict_node_history, receiver)
-sub get_log {
- my ($self, @args) = @_;
- my $pool = SVN::Pool->new;
-
- # svn_log_changed_path_t objects passed to get_log are likely to be
- # overwritten even if only the refs are copied to an external variable,
- # so we should dup the structures in their entirety. Using an
- # externally passed pool (instead of our temporary and quickly cleared
- # pool in Git::SVN::Ra) does not help matters at all...
- my $receiver = pop @args;
- my $prefix = "/".$self->{svn_path};
- $prefix =~ s#/+($)##;
- my $prefix_regex = qr#^\Q$prefix\E#;
- push(@args, sub {
- my ($paths) = $_[0];
- return &$receiver(@_) unless $paths;
- $_[0] = ();
- foreach my $p (keys %$paths) {
- my $i = $paths->{$p};
- # Make path relative to our url, not repos_root
- $p =~ s/$prefix_regex//;
- my %s = map { $_ => $i->$_; }
- qw/copyfrom_path copyfrom_rev action/;
- if ($s{'copyfrom_path'}) {
- $s{'copyfrom_path'} =~ s/$prefix_regex//;
- }
- $_[0]{$p} = \%s;
- }
- &$receiver(@_);
- });
-
-
- # the limit parameter was not supported in SVN 1.1.x, so we
- # drop it. Therefore, the receiver callback passed to it
- # is made aware of this limitation by being wrapped if
- # the limit passed to is being wrapped.
- if (::compare_svn_version('1.2.0') <= 0) {
- my $limit = splice(@args, 3, 1);
- if ($limit > 0) {
- my $receiver = pop @args;
- push(@args, sub { &$receiver(@_) if (--$limit >= 0) });
- }
- }
- my $ret = $self->SUPER::get_log(@args, $pool);
- $pool->clear;
- $ret;
-}
-
-sub trees_match {
- my ($self, $url1, $rev1, $url2, $rev2) = @_;
- my $ctx = SVN::Client->new(auth => _auth_providers);
- my $out = IO::File->new_tmpfile;
-
- # older SVN (1.1.x) doesn't take $pool as the last parameter for
- # $ctx->diff(), so we'll create a default one
- my $pool = SVN::Pool->new_default_sub;
-
- $ra_invalid = 1; # this will open a new SVN::Ra connection to $url1
- $ctx->diff([], $url1, $rev1, $url2, $rev2, 1, 1, 0, $out, $out);
- $out->flush;
- my $ret = (($out->stat)[7] == 0);
- close $out or croak $!;
-
- $ret;
-}
-
-sub get_commit_editor {
- my ($self, $log, $cb, $pool) = @_;
-
- my @lock = (::compare_svn_version('1.2.0') >= 0) ? (undef, 0) : ();
- $self->SUPER::get_commit_editor($log, $cb, @lock, $pool);
-}
-
-sub gs_do_update {
- my ($self, $rev_a, $rev_b, $gs, $editor) = @_;
- my $new = ($rev_a == $rev_b);
- my $path = $gs->{path};
-
- if ($new && -e $gs->{index}) {
- unlink $gs->{index} or die
- "Couldn't unlink index: $gs->{index}: $!\n";
- }
- my $pool = SVN::Pool->new;
- $editor->set_path_strip($path);
- my (@pc) = split m#/#, $path;
- my $reporter = $self->do_update($rev_b, (@pc ? shift @pc : ''),
- 1, $editor, $pool);
- my @lock = (::compare_svn_version('1.2.0') >= 0) ? (undef) : ();
-
- # Since we can't rely on svn_ra_reparent being available, we'll
- # just have to do some magic with set_path to make it so
- # we only want a partial path.
- my $sp = '';
- my $final = join('/', @pc);
- while (@pc) {
- $reporter->set_path($sp, $rev_b, 0, @lock, $pool);
- $sp .= '/' if length $sp;
- $sp .= shift @pc;
- }
- die "BUG: '$sp' != '$final'\n" if ($sp ne $final);
-
- $reporter->set_path($sp, $rev_a, $new, @lock, $pool);
-
- $reporter->finish_report($pool);
- $pool->clear;
- $editor->{git_commit_ok};
-}
-
-# this requires SVN 1.4.3 or later (do_switch didn't work before 1.4.3, and
-# svn_ra_reparent didn't work before 1.4)
-sub gs_do_switch {
- my ($self, $rev_a, $rev_b, $gs, $url_b, $editor) = @_;
- my $path = $gs->{path};
- my $pool = SVN::Pool->new;
-
- my $full_url = $self->{url};
- my $old_url = $full_url;
- $full_url .= '/' . $path if length $path;
- my ($ra, $reparented);
-
- if ($old_url =~ m#^svn(\+ssh)?://# ||
- ($full_url =~ m#^https?://# &&
- escape_url($full_url) ne $full_url)) {
- $_[0] = undef;
- $self = undef;
- $RA = undef;
- $ra = Git::SVN::Ra->new($full_url);
- $ra_invalid = 1;
- } elsif ($old_url ne $full_url) {
- SVN::_Ra::svn_ra_reparent($self->{session}, $full_url, $pool);
- $self->{url} = $full_url;
- $reparented = 1;
- }
-
- $ra ||= $self;
- $url_b = escape_url($url_b);
- my $reporter = $ra->do_switch($rev_b, '', 1, $url_b, $editor, $pool);
- my @lock = (::compare_svn_version('1.2.0') >= 0) ? (undef) : ();
- $reporter->set_path('', $rev_a, 0, @lock, $pool);
- $reporter->finish_report($pool);
-
- if ($reparented) {
- SVN::_Ra::svn_ra_reparent($self->{session}, $old_url, $pool);
- $self->{url} = $old_url;
- }
-
- $pool->clear;
- $editor->{git_commit_ok};
-}
-
-sub longest_common_path {
- my ($gsv, $globs) = @_;
- my %common;
- my $common_max = scalar @$gsv;
-
- foreach my $gs (@$gsv) {
- my @tmp = split m#/#, $gs->{path};
- my $p = '';
- foreach (@tmp) {
- $p .= length($p) ? "/$_" : $_;
- $common{$p} ||= 0;
- $common{$p}++;
- }
- }
- $globs ||= [];
- $common_max += scalar @$globs;
- foreach my $glob (@$globs) {
- my @tmp = split m#/#, $glob->{path}->{left};
- my $p = '';
- foreach (@tmp) {
- $p .= length($p) ? "/$_" : $_;
- $common{$p} ||= 0;
- $common{$p}++;
- }
- }
-
- my $longest_path = '';
- foreach (sort {length $b <=> length $a} keys %common) {
- if ($common{$_} == $common_max) {
- $longest_path = $_;
- last;
- }
- }
- $longest_path;
-}
-
-sub gs_fetch_loop_common {
- my ($self, $base, $head, $gsv, $globs) = @_;
- return if ($base > $head);
- my $inc = $_log_window_size;
- my ($min, $max) = ($base, $head < $base + $inc ? $head : $base + $inc);
- my $longest_path = longest_common_path($gsv, $globs);
- my $ra_url = $self->{url};
- my $find_trailing_edge;
- while (1) {
- my %revs;
- my $err;
- my $err_handler = $SVN::Error::handler;
- $SVN::Error::handler = sub {
- ($err) = @_;
- skip_unknown_revs($err);
- };
- sub _cb {
- my ($paths, $r, $author, $date, $log) = @_;
- [ $paths,
- { author => $author, date => $date, log => $log } ];
- }
- $self->get_log([$longest_path], $min, $max, 0, 1, 1,
- sub { $revs{$_[1]} = _cb(@_) });
- if ($err) {
- print "Checked through r$max\r";
- } else {
- $find_trailing_edge = 1;
- }
- if ($err and $find_trailing_edge) {
- print STDERR "Path '$longest_path' ",
- "was probably deleted:\n",
- $err->expanded_message,
- "\nWill attempt to follow ",
- "revisions r$min .. r$max ",
- "committed before the deletion\n";
- my $hi = $max;
- while (--$hi >= $min) {
- my $ok;
- $self->get_log([$longest_path], $min, $hi,
- 0, 1, 1, sub {
- $ok = $_[1];
- $revs{$_[1]} = _cb(@_) });
- if ($ok) {
- print STDERR "r$min .. r$ok OK\n";
- last;
- }
- }
- $find_trailing_edge = 0;
- }
- $SVN::Error::handler = $err_handler;
-
- my %exists = map { $_->{path} => $_ } @$gsv;
- foreach my $r (sort {$a <=> $b} keys %revs) {
- my ($paths, $logged) = @{$revs{$r}};
-
- foreach my $gs ($self->match_globs(\%exists, $paths,
- $globs, $r)) {
- if ($gs->rev_map_max >= $r) {
- next;
- }
- next unless $gs->match_paths($paths, $r);
- $gs->{logged_rev_props} = $logged;
- if (my $last_commit = $gs->last_commit) {
- $gs->assert_index_clean($last_commit);
- }
- my $log_entry = $gs->do_fetch($paths, $r);
- if ($log_entry) {
- $gs->do_git_commit($log_entry);
- }
- $INDEX_FILES{$gs->{index}} = 1;
- }
- foreach my $g (@$globs) {
- my $k = "svn-remote.$g->{remote}." .
- "$g->{t}-maxRev";
- Git::SVN::tmp_config($k, $r);
- }
- if ($ra_invalid) {
- $_[0] = undef;
- $self = undef;
- $RA = undef;
- $self = Git::SVN::Ra->new($ra_url);
- $ra_invalid = undef;
- }
- }
- # pre-fill the .rev_db since it'll eventually get filled in
- # with '0' x40 if something new gets committed
- foreach my $gs (@$gsv) {
- next if $gs->rev_map_max >= $max;
- next if defined $gs->rev_map_get($max);
- $gs->rev_map_set($max, 0 x40);
- }
- foreach my $g (@$globs) {
- my $k = "svn-remote.$g->{remote}.$g->{t}-maxRev";
- Git::SVN::tmp_config($k, $max);
- }
- last if $max >= $head;
- $min = $max + 1;
- $max += $inc;
- $max = $head if ($max > $head);
- }
- Git::SVN::gc();
-}
-
-sub get_dir_globbed {
- my ($self, $left, $depth, $r) = @_;
-
- my @x = eval { $self->get_dir($left, $r) };
- return unless scalar @x == 3;
- my $dirents = $x[0];
- my @finalents;
- foreach my $de (keys %$dirents) {
- next if $dirents->{$de}->{kind} != $SVN::Node::dir;
- if ($depth > 1) {
- my @args = ("$left/$de", $depth - 1, $r);
- foreach my $dir ($self->get_dir_globbed(@args)) {
- push @finalents, "$de/$dir";
- }
- } else {
- push @finalents, $de;
- }
- }
- @finalents;
-}
-
-# return value: 0 -- don't ignore, 1 -- ignore
-sub is_ref_ignored {
- my ($g, $p) = @_;
- my $refname = $g->{ref}->full_path($p);
- return 1 if defined($g->{ignore_refs_regex}) &&
- $refname =~ m!$g->{ignore_refs_regex}!;
- return 0 unless defined($_ignore_refs_regex);
- return 1 if $refname =~ m!$_ignore_refs_regex!o;
- return 0;
-}
-
-sub match_globs {
- my ($self, $exists, $paths, $globs, $r) = @_;
-
- sub get_dir_check {
- my ($self, $exists, $g, $r) = @_;
-
- my @dirs = $self->get_dir_globbed($g->{path}->{left},
- $g->{path}->{depth},
- $r);
-
- foreach my $de (@dirs) {
- my $p = $g->{path}->full_path($de);
- next if $exists->{$p};
- next if (length $g->{path}->{right} &&
- ($self->check_path($p, $r) !=
- $SVN::Node::dir));
- next unless $p =~ /$g->{path}->{regex}/;
- $exists->{$p} = Git::SVN->init($self->{url}, $p, undef,
- $g->{ref}->full_path($de), 1);
- }
- }
- foreach my $g (@$globs) {
- if (my $path = $paths->{"/$g->{path}->{left}"}) {
- if ($path->{action} =~ /^[AR]$/) {
- get_dir_check($self, $exists, $g, $r);
- }
- }
- foreach (keys %$paths) {
- if (/$g->{path}->{left_regex}/ &&
- !/$g->{path}->{regex}/) {
- next if $paths->{$_}->{action} !~ /^[AR]$/;
- get_dir_check($self, $exists, $g, $r);
- }
- next unless /$g->{path}->{regex}/;
- my $p = $1;
- my $pathname = $g->{path}->full_path($p);
- next if is_ref_ignored($g, $p);
- next if $exists->{$pathname};
- next if ($self->check_path($pathname, $r) !=
- $SVN::Node::dir);
- $exists->{$pathname} = Git::SVN->init(
- $self->{url}, $pathname, undef,
- $g->{ref}->full_path($p), 1);
- }
- my $c = '';
- foreach (split m#/#, $g->{path}->{left}) {
- $c .= "/$_";
- next unless ($paths->{$c} &&
- ($paths->{$c}->{action} =~ /^[AR]$/));
- get_dir_check($self, $exists, $g, $r);
- }
- }
- values %$exists;
-}
-
-sub minimize_url {
- my ($self) = @_;
- return $self->{url} if ($self->{url} eq $self->{repos_root});
- my $url = $self->{repos_root};
- my @components = split(m!/!, $self->{svn_path});
- my $c = '';
- do {
- $url .= "/$c" if length $c;
- eval {
- my $ra = (ref $self)->new($url);
- my $latest = $ra->get_latest_revnum;
- $ra->get_log("", $latest, 0, 1, 0, 1, sub {});
- };
- } while ($@ && ($c = shift @components));
- $url;
-}
-
-sub can_do_switch {
- my $self = shift;
- unless (defined $can_do_switch) {
- my $pool = SVN::Pool->new;
- my $rep = eval {
- $self->do_switch(1, '', 0, $self->{url},
- SVN::Delta::Editor->new, $pool);
- };
- if ($@) {
- $can_do_switch = 0;
- } else {
- $rep->abort_report($pool);
- $can_do_switch = 1;
- }
- $pool->clear;
- }
- $can_do_switch;
-}
-
-sub skip_unknown_revs {
- my ($err) = @_;
- my $errno = $err->apr_err();
- # Maybe the branch we're tracking didn't
- # exist when the repo started, so it's
- # not an error if it doesn't, just continue
- #
- # Wonderfully consistent library, eh?
- # 160013 - svn:// and file://
- # 175002 - http(s)://
- # 175007 - http(s):// (this repo required authorization, too...)
- # More codes may be discovered later...
- if ($errno == 175007 || $errno == 175002 || $errno == 160013) {
- my $err_key = $err->expanded_message;
- # revision numbers change every time, filter them out
- $err_key =~ s/\d+/\0/g;
- $err_key = "$errno\0$err_key";
- unless ($ignored_err{$err_key}) {
- warn "W: Ignoring error from SVN, path probably ",
- "does not exist: ($errno): ",
- $err->expanded_message,"\n";
- warn "W: Do not be alarmed at the above message ",
- "git-svn is just searching aggressively for ",
- "old history.\n",
- "This may take a while on large repositories\n";
- $ignored_err{$err_key} = 1;
- }
- return;
- }
- die "Error from SVN, ($errno): ", $err->expanded_message,"\n";
-}
-
package Git::SVN::Log;
use strict;
use warnings;
return ret;
}
-const char git_version_string[] = GIT_VERSION;
-
#define RUN_SETUP (1<<0)
#define RUN_SETUP_GENTLY (1<<1)
#define USE_PAGER (1<<2)
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config, RUN_SETUP_GENTLY },
{ "count-objects", cmd_count_objects, RUN_SETUP },
+ { "credential", cmd_credential, RUN_SETUP_GENTLY },
{ "describe", cmd_describe, RUN_SETUP },
{ "diff", cmd_diff },
{ "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE },
#include "common-cmds.h"
#include "string-list.h"
#include "column.h"
+#include "version.h"
void add_cmdname(struct cmdnames *cmds, const char *name, int len)
{
#include "run-command.h"
#include "url.h"
#include "credential.h"
+#include "version.h"
int active_requests;
int http_is_verbose;
curl_easy_setopt(result, CURLOPT_VERBOSE, 1);
curl_easy_setopt(result, CURLOPT_USERAGENT,
- user_agent ? user_agent : GIT_HTTP_USER_AGENT);
+ user_agent ? user_agent : git_user_agent());
if (curl_ftp_no_epsv)
curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0);
free(changes);
if (o->verbosity >= 4)
- printf("Merge result: %i unmerged notes and a %s notes tree\n",
- conflicts, t->dirty ? "dirty" : "clean");
+ printf(t->dirty ?
+ "Merge result: %i unmerged notes and a dirty notes tree\n" :
+ "Merge result: %i unmerged notes and a clean notes tree\n",
+ conflicts);
return conflicts ? -1 : 1;
}
usage_with_options(usagestr, options);
}
+ precompose_argv(argc, argv);
return parse_options_end(&ctx);
}
return xstrdup(path);
}
+char *mkpathdup(const char *fmt, ...)
+{
+ char *path;
+ struct strbuf sb = STRBUF_INIT;
+ va_list args;
+
+ va_start(args, fmt);
+ strbuf_vaddf(&sb, fmt, args);
+ va_end(args);
+ path = xstrdup(cleanup_path(sb.buf));
+
+ strbuf_release(&sb);
+ return path;
+}
+
char *mkpath(const char *fmt, ...)
{
va_list args;
return cleanup_path(pathname);
}
+void home_config_paths(char **global, char **xdg, char *file)
+{
+ char *xdg_home = getenv("XDG_CONFIG_HOME");
+ char *home = getenv("HOME");
+ char *to_free = NULL;
+
+ if (!home) {
+ if (global)
+ *global = NULL;
+ } else {
+ if (!xdg_home) {
+ to_free = mkpathdup("%s/.config", home);
+ xdg_home = to_free;
+ }
+ if (global)
+ *global = mkpathdup("%s/.gitconfig", home);
+ }
+
+ if (!xdg_home)
+ *xdg = NULL;
+ else
+ *xdg = mkpathdup("%s/git/%s", xdg_home, file);
+
+ free(to_free);
+}
+
char *git_path_submodule(const char *path, const char *fmt, ...)
{
char *pathname = get_pathname();
--- /dev/null
+package Git::SVN::Editor;
+use vars qw/@ISA $_rmdir $_cp_similarity $_find_copies_harder $_rename_limit/;
+use strict;
+use warnings;
+use SVN::Core;
+use SVN::Delta;
+use Carp qw/croak/;
+use IO::File;
+use Git qw/command command_oneline command_noisy command_output_pipe
+ command_input_pipe command_close_pipe
+ command_bidi_pipe command_close_bidi_pipe/;
+BEGIN {
+ @ISA = qw(SVN::Delta::Editor);
+}
+
+sub new {
+ my ($class, $opts) = @_;
+ foreach (qw/svn_path r ra tree_a tree_b log editor_cb/) {
+ die "$_ required!\n" unless (defined $opts->{$_});
+ }
+
+ my $pool = SVN::Pool->new;
+ my $mods = generate_diff($opts->{tree_a}, $opts->{tree_b});
+ my $types = check_diff_paths($opts->{ra}, $opts->{svn_path},
+ $opts->{r}, $mods);
+
+ # $opts->{ra} functions should not be used after this:
+ my @ce = $opts->{ra}->get_commit_editor($opts->{log},
+ $opts->{editor_cb}, $pool);
+ my $self = SVN::Delta::Editor->new(@ce, $pool);
+ bless $self, $class;
+ foreach (qw/svn_path r tree_a tree_b/) {
+ $self->{$_} = $opts->{$_};
+ }
+ $self->{url} = $opts->{ra}->{url};
+ $self->{mods} = $mods;
+ $self->{types} = $types;
+ $self->{pool} = $pool;
+ $self->{bat} = { '' => $self->open_root($self->{r}, $self->{pool}) };
+ $self->{rm} = { };
+ $self->{path_prefix} = length $self->{svn_path} ?
+ "$self->{svn_path}/" : '';
+ $self->{config} = $opts->{config};
+ $self->{mergeinfo} = $opts->{mergeinfo};
+ return $self;
+}
+
+sub generate_diff {
+ my ($tree_a, $tree_b) = @_;
+ my @diff_tree = qw(diff-tree -z -r);
+ if ($_cp_similarity) {
+ push @diff_tree, "-C$_cp_similarity";
+ } else {
+ push @diff_tree, '-C';
+ }
+ push @diff_tree, '--find-copies-harder' if $_find_copies_harder;
+ push @diff_tree, "-l$_rename_limit" if defined $_rename_limit;
+ push @diff_tree, $tree_a, $tree_b;
+ my ($diff_fh, $ctx) = command_output_pipe(@diff_tree);
+ local $/ = "\0";
+ my $state = 'meta';
+ my @mods;
+ while (<$diff_fh>) {
+ chomp $_; # this gets rid of the trailing "\0"
+ if ($state eq 'meta' && /^:(\d{6})\s(\d{6})\s
+ ($::sha1)\s($::sha1)\s
+ ([MTCRAD])\d*$/xo) {
+ push @mods, { mode_a => $1, mode_b => $2,
+ sha1_a => $3, sha1_b => $4,
+ chg => $5 };
+ if ($5 =~ /^(?:C|R)$/) {
+ $state = 'file_a';
+ } else {
+ $state = 'file_b';
+ }
+ } elsif ($state eq 'file_a') {
+ my $x = $mods[$#mods] or croak "Empty array\n";
+ if ($x->{chg} !~ /^(?:C|R)$/) {
+ croak "Error parsing $_, $x->{chg}\n";
+ }
+ $x->{file_a} = $_;
+ $state = 'file_b';
+ } elsif ($state eq 'file_b') {
+ my $x = $mods[$#mods] or croak "Empty array\n";
+ if (exists $x->{file_a} && $x->{chg} !~ /^(?:C|R)$/) {
+ croak "Error parsing $_, $x->{chg}\n";
+ }
+ if (!exists $x->{file_a} && $x->{chg} =~ /^(?:C|R)$/) {
+ croak "Error parsing $_, $x->{chg}\n";
+ }
+ $x->{file_b} = $_;
+ $state = 'meta';
+ } else {
+ croak "Error parsing $_\n";
+ }
+ }
+ command_close_pipe($diff_fh, $ctx);
+ \@mods;
+}
+
+sub check_diff_paths {
+ my ($ra, $pfx, $rev, $mods) = @_;
+ my %types;
+ $pfx .= '/' if length $pfx;
+
+ sub type_diff_paths {
+ my ($ra, $types, $path, $rev) = @_;
+ my @p = split m#/+#, $path;
+ my $c = shift @p;
+ unless (defined $types->{$c}) {
+ $types->{$c} = $ra->check_path($c, $rev);
+ }
+ while (@p) {
+ $c .= '/' . shift @p;
+ next if defined $types->{$c};
+ $types->{$c} = $ra->check_path($c, $rev);
+ }
+ }
+
+ foreach my $m (@$mods) {
+ foreach my $f (qw/file_a file_b/) {
+ next unless defined $m->{$f};
+ my ($dir) = ($m->{$f} =~ m#^(.*?)/?(?:[^/]+)$#);
+ if (length $pfx.$dir && ! defined $types{$dir}) {
+ type_diff_paths($ra, \%types, $pfx.$dir, $rev);
+ }
+ }
+ }
+ \%types;
+}
+
+sub split_path {
+ return ($_[0] =~ m#^(.*?)/?([^/]+)$#);
+}
+
+sub repo_path {
+ my ($self, $path) = @_;
+ if (my $enc = $self->{pathnameencoding}) {
+ require Encode;
+ Encode::from_to($path, $enc, 'UTF-8');
+ }
+ $self->{path_prefix}.(defined $path ? $path : '');
+}
+
+sub url_path {
+ my ($self, $path) = @_;
+ if ($self->{url} =~ m#^https?://#) {
+ $path =~ s!([^~a-zA-Z0-9_./-])!uc sprintf("%%%02x",ord($1))!eg;
+ }
+ $self->{url} . '/' . $self->repo_path($path);
+}
+
+sub rmdirs {
+ my ($self) = @_;
+ my $rm = $self->{rm};
+ delete $rm->{''}; # we never delete the url we're tracking
+ return unless %$rm;
+
+ foreach (keys %$rm) {
+ my @d = split m#/#, $_;
+ my $c = shift @d;
+ $rm->{$c} = 1;
+ while (@d) {
+ $c .= '/' . shift @d;
+ $rm->{$c} = 1;
+ }
+ }
+ delete $rm->{$self->{svn_path}};
+ delete $rm->{''}; # we never delete the url we're tracking
+ return unless %$rm;
+
+ my ($fh, $ctx) = command_output_pipe(qw/ls-tree --name-only -r -z/,
+ $self->{tree_b});
+ local $/ = "\0";
+ while (<$fh>) {
+ chomp;
+ my @dn = split m#/#, $_;
+ while (pop @dn) {
+ delete $rm->{join '/', @dn};
+ }
+ unless (%$rm) {
+ close $fh;
+ return;
+ }
+ }
+ command_close_pipe($fh, $ctx);
+
+ my ($r, $p, $bat) = ($self->{r}, $self->{pool}, $self->{bat});
+ foreach my $d (sort { $b =~ tr#/#/# <=> $a =~ tr#/#/# } keys %$rm) {
+ $self->close_directory($bat->{$d}, $p);
+ my ($dn) = ($d =~ m#^(.*?)/?(?:[^/]+)$#);
+ print "\tD+\t$d/\n" unless $::_q;
+ $self->SUPER::delete_entry($d, $r, $bat->{$dn}, $p);
+ delete $bat->{$d};
+ }
+}
+
+sub open_or_add_dir {
+ my ($self, $full_path, $baton, $deletions) = @_;
+ my $t = $self->{types}->{$full_path};
+ if (!defined $t) {
+ die "$full_path not known in r$self->{r} or we have a bug!\n";
+ }
+ {
+ no warnings 'once';
+ # SVN::Node::none and SVN::Node::file are used only once,
+ # so we're shutting up Perl's warnings about them.
+ if ($t == $SVN::Node::none || defined($deletions->{$full_path})) {
+ return $self->add_directory($full_path, $baton,
+ undef, -1, $self->{pool});
+ } elsif ($t == $SVN::Node::dir) {
+ return $self->open_directory($full_path, $baton,
+ $self->{r}, $self->{pool});
+ } # no warnings 'once'
+ print STDERR "$full_path already exists in repository at ",
+ "r$self->{r} and it is not a directory (",
+ ($t == $SVN::Node::file ? 'file' : 'unknown'),"/$t)\n";
+ } # no warnings 'once'
+ exit 1;
+}
+
+sub ensure_path {
+ my ($self, $path, $deletions) = @_;
+ my $bat = $self->{bat};
+ my $repo_path = $self->repo_path($path);
+ return $bat->{''} unless (length $repo_path);
+
+ my @p = split m#/+#, $repo_path;
+ my $c = shift @p;
+ $bat->{$c} ||= $self->open_or_add_dir($c, $bat->{''}, $deletions);
+ while (@p) {
+ my $c0 = $c;
+ $c .= '/' . shift @p;
+ $bat->{$c} ||= $self->open_or_add_dir($c, $bat->{$c0}, $deletions);
+ }
+ return $bat->{$c};
+}
+
+# Subroutine to convert a globbing pattern to a regular expression.
+# From perl cookbook.
+sub glob2pat {
+ my $globstr = shift;
+ my %patmap = ('*' => '.*', '?' => '.', '[' => '[', ']' => ']');
+ $globstr =~ s{(.)} { $patmap{$1} || "\Q$1" }ge;
+ return '^' . $globstr . '$';
+}
+
+sub check_autoprop {
+ my ($self, $pattern, $properties, $file, $fbat) = @_;
+ # Convert the globbing pattern to a regular expression.
+ my $regex = glob2pat($pattern);
+ # Check if the pattern matches the file name.
+ if($file =~ m/($regex)/) {
+ # Parse the list of properties to set.
+ my @props = split(/;/, $properties);
+ foreach my $prop (@props) {
+ # Parse 'name=value' syntax and set the property.
+ if ($prop =~ /([^=]+)=(.*)/) {
+ my ($n,$v) = ($1,$2);
+ for ($n, $v) {
+ s/^\s+//; s/\s+$//;
+ }
+ $self->change_file_prop($fbat, $n, $v);
+ }
+ }
+ }
+}
+
+sub apply_autoprops {
+ my ($self, $file, $fbat) = @_;
+ my $conf_t = ${$self->{config}}{'config'};
+ no warnings 'once';
+ # Check [miscellany]/enable-auto-props in svn configuration.
+ if (SVN::_Core::svn_config_get_bool(
+ $conf_t,
+ $SVN::_Core::SVN_CONFIG_SECTION_MISCELLANY,
+ $SVN::_Core::SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS,
+ 0)) {
+ # Auto-props are enabled. Enumerate them to look for matches.
+ my $callback = sub {
+ $self->check_autoprop($_[0], $_[1], $file, $fbat);
+ };
+ SVN::_Core::svn_config_enumerate(
+ $conf_t,
+ $SVN::_Core::SVN_CONFIG_SECTION_AUTO_PROPS,
+ $callback);
+ }
+}
+
+sub A {
+ my ($self, $m, $deletions) = @_;
+ my ($dir, $file) = split_path($m->{file_b});
+ my $pbat = $self->ensure_path($dir, $deletions);
+ my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
+ undef, -1);
+ print "\tA\t$m->{file_b}\n" unless $::_q;
+ $self->apply_autoprops($file, $fbat);
+ $self->chg_file($fbat, $m);
+ $self->close_file($fbat,undef,$self->{pool});
+}
+
+sub C {
+ my ($self, $m, $deletions) = @_;
+ my ($dir, $file) = split_path($m->{file_b});
+ my $pbat = $self->ensure_path($dir, $deletions);
+ my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
+ $self->url_path($m->{file_a}), $self->{r});
+ print "\tC\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
+ $self->chg_file($fbat, $m);
+ $self->close_file($fbat,undef,$self->{pool});
+}
+
+sub delete_entry {
+ my ($self, $path, $pbat) = @_;
+ my $rpath = $self->repo_path($path);
+ my ($dir, $file) = split_path($rpath);
+ $self->{rm}->{$dir} = 1;
+ $self->SUPER::delete_entry($rpath, $self->{r}, $pbat, $self->{pool});
+}
+
+sub R {
+ my ($self, $m, $deletions) = @_;
+ my ($dir, $file) = split_path($m->{file_b});
+ my $pbat = $self->ensure_path($dir, $deletions);
+ my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
+ $self->url_path($m->{file_a}), $self->{r});
+ print "\tR\t$m->{file_a} => $m->{file_b}\n" unless $::_q;
+ $self->apply_autoprops($file, $fbat);
+ $self->chg_file($fbat, $m);
+ $self->close_file($fbat,undef,$self->{pool});
+
+ ($dir, $file) = split_path($m->{file_a});
+ $pbat = $self->ensure_path($dir, $deletions);
+ $self->delete_entry($m->{file_a}, $pbat);
+}
+
+sub M {
+ my ($self, $m, $deletions) = @_;
+ my ($dir, $file) = split_path($m->{file_b});
+ my $pbat = $self->ensure_path($dir, $deletions);
+ my $fbat = $self->open_file($self->repo_path($m->{file_b}),
+ $pbat,$self->{r},$self->{pool});
+ print "\t$m->{chg}\t$m->{file_b}\n" unless $::_q;
+ $self->chg_file($fbat, $m);
+ $self->close_file($fbat,undef,$self->{pool});
+}
+
+sub T { shift->M(@_) }
+
+sub change_file_prop {
+ my ($self, $fbat, $pname, $pval) = @_;
+ $self->SUPER::change_file_prop($fbat, $pname, $pval, $self->{pool});
+}
+
+sub change_dir_prop {
+ my ($self, $pbat, $pname, $pval) = @_;
+ $self->SUPER::change_dir_prop($pbat, $pname, $pval, $self->{pool});
+}
+
+sub _chg_file_get_blob ($$$$) {
+ my ($self, $fbat, $m, $which) = @_;
+ my $fh = $::_repository->temp_acquire("git_blob_$which");
+ if ($m->{"mode_$which"} =~ /^120/) {
+ print $fh 'link ' or croak $!;
+ $self->change_file_prop($fbat,'svn:special','*');
+ } elsif ($m->{mode_a} =~ /^120/ && $m->{"mode_$which"} !~ /^120/) {
+ $self->change_file_prop($fbat,'svn:special',undef);
+ }
+ my $blob = $m->{"sha1_$which"};
+ return ($fh,) if ($blob =~ /^0{40}$/);
+ my $size = $::_repository->cat_blob($blob, $fh);
+ croak "Failed to read object $blob" if ($size < 0);
+ $fh->flush == 0 or croak $!;
+ seek $fh, 0, 0 or croak $!;
+
+ my $exp = ::md5sum($fh);
+ seek $fh, 0, 0 or croak $!;
+ return ($fh, $exp);
+}
+
+sub chg_file {
+ my ($self, $fbat, $m) = @_;
+ if ($m->{mode_b} =~ /755$/ && $m->{mode_a} !~ /755$/) {
+ $self->change_file_prop($fbat,'svn:executable','*');
+ } elsif ($m->{mode_b} !~ /755$/ && $m->{mode_a} =~ /755$/) {
+ $self->change_file_prop($fbat,'svn:executable',undef);
+ }
+ my ($fh_a, $exp_a) = _chg_file_get_blob $self, $fbat, $m, 'a';
+ my ($fh_b, $exp_b) = _chg_file_get_blob $self, $fbat, $m, 'b';
+ my $pool = SVN::Pool->new;
+ my $atd = $self->apply_textdelta($fbat, $exp_a, $pool);
+ if (-s $fh_a) {
+ my $txstream = SVN::TxDelta::new ($fh_a, $fh_b, $pool);
+ my $res = SVN::TxDelta::send_txstream($txstream, @$atd, $pool);
+ if (defined $res) {
+ die "Unexpected result from send_txstream: $res\n",
+ "(SVN::Core::VERSION: $SVN::Core::VERSION)\n";
+ }
+ } else {
+ my $got = SVN::TxDelta::send_stream($fh_b, @$atd, $pool);
+ die "Checksum mismatch\nexpected: $exp_b\ngot: $got\n"
+ if ($got ne $exp_b);
+ }
+ Git::temp_release($fh_b, 1);
+ Git::temp_release($fh_a, 1);
+ $pool->clear;
+}
+
+sub D {
+ my ($self, $m, $deletions) = @_;
+ my ($dir, $file) = split_path($m->{file_b});
+ my $pbat = $self->ensure_path($dir, $deletions);
+ print "\tD\t$m->{file_b}\n" unless $::_q;
+ $self->delete_entry($m->{file_b}, $pbat);
+}
+
+sub close_edit {
+ my ($self) = @_;
+ my ($p,$bat) = ($self->{pool}, $self->{bat});
+ foreach (sort { $b =~ tr#/#/# <=> $a =~ tr#/#/# } keys %$bat) {
+ next if $_ eq '';
+ $self->close_directory($bat->{$_}, $p);
+ }
+ $self->close_directory($bat->{''}, $p);
+ $self->SUPER::close_edit($p);
+ $p->clear;
+}
+
+sub abort_edit {
+ my ($self) = @_;
+ $self->SUPER::abort_edit($self->{pool});
+}
+
+sub DESTROY {
+ my $self = shift;
+ $self->SUPER::DESTROY(@_);
+ $self->{pool}->clear;
+}
+
+# this drives the editor
+sub apply_diff {
+ my ($self) = @_;
+ my $mods = $self->{mods};
+ my %o = ( D => 0, C => 1, R => 2, A => 3, M => 4, T => 5 );
+ my %deletions;
+
+ foreach my $m (@$mods) {
+ if ($m->{chg} eq "D") {
+ $deletions{$m->{file_b}} = 1;
+ }
+ }
+
+ foreach my $m (sort { $o{$a->{chg}} <=> $o{$b->{chg}} } @$mods) {
+ my $f = $m->{chg};
+ if (defined $o{$f}) {
+ $self->$f($m, \%deletions);
+ } else {
+ fatal("Invalid change type: $f");
+ }
+ }
+
+ if (defined($self->{mergeinfo})) {
+ $self->change_dir_prop($self->{bat}{''}, "svn:mergeinfo",
+ $self->{mergeinfo});
+ }
+ $self->rmdirs if $_rmdir;
+ if (@$mods == 0 && !defined($self->{mergeinfo})) {
+ $self->abort_edit;
+ } else {
+ $self->close_edit;
+ }
+ return scalar @$mods;
+}
+
+1;
+__END__
+
+Git::SVN::Editor - commit driver for "git svn set-tree" and dcommit
+
+=head1 SYNOPSIS
+
+ use Git::SVN::Editor;
+ use Git::SVN::Ra;
+
+ my $ra = Git::SVN::Ra->new($url);
+ my %opts = (
+ r => 19,
+ log => "log message",
+ ra => $ra,
+ config => SVN::Core::config_get_config($svn_config_dir),
+ tree_a => "$commit^",
+ tree_b => "$commit",
+ editor_cb => sub { print "Committed r$_[0]\n"; },
+ mergeinfo => "/branches/foo:1-10",
+ svn_path => "trunk"
+ );
+ Git::SVN::Editor->new(\%opts)->apply_diff or print "No changes\n";
+
+ my $re = Git::SVN::Editor::glob2pat("trunk/*");
+ if ($branchname =~ /$re/) {
+ print "matched!\n";
+ }
+
+=head1 DESCRIPTION
+
+This module is an implementation detail of the "git svn" command.
+Do not use it unless you are developing git-svn.
+
+This module adapts the C<SVN::Delta::Editor> object returned by
+C<SVN::Delta::get_commit_editor> and drives it to convey the
+difference between two git tree objects to a remote Subversion
+repository.
+
+The interface will change as git-svn evolves.
+
+=head1 DEPENDENCIES
+
+Subversion perl bindings,
+the core L<Carp> and L<IO::File> modules,
+and git's L<Git> helper module.
+
+C<Git::SVN::Editor> has not been tested using callers other than
+B<git-svn> itself.
+
+=head1 SEE ALSO
+
+L<SVN::Delta>,
+L<Git::SVN::Fetcher>.
+
+=head1 INCOMPATIBILITIES
+
+None reported.
+
+=head1 BUGS
+
+None.
=head1 SEE ALSO
-L<SVN::Delta>.
+L<SVN::Delta>,
+L<Git::SVN::Editor>.
=head1 INCOMPATIBILITIES
--- /dev/null
+package Git::SVN::Memoize::YAML;
+use warnings;
+use strict;
+use YAML::Any ();
+
+# based on Memoize::Storable.
+
+sub TIEHASH {
+ my $package = shift;
+ my $filename = shift;
+ my $truehash = (-e $filename) ? YAML::Any::LoadFile($filename) : {};
+ my $self = {FILENAME => $filename, H => $truehash};
+ bless $self => $package;
+}
+
+sub STORE {
+ my $self = shift;
+ $self->{H}{$_[0]} = $_[1];
+}
+
+sub FETCH {
+ my $self = shift;
+ $self->{H}{$_[0]};
+}
+
+sub EXISTS {
+ my $self = shift;
+ exists $self->{H}{$_[0]};
+}
+
+sub DESTROY {
+ my $self = shift;
+ YAML::Any::DumpFile($self->{FILENAME}, $self->{H});
+}
+
+sub SCALAR {
+ my $self = shift;
+ scalar(%{$self->{H}});
+}
+
+sub FIRSTKEY {
+ 'Fake hash from Git::SVN::Memoize::YAML';
+}
+
+sub NEXTKEY {
+ undef;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Git::SVN::Memoize::YAML - store Memoized data in YAML format
+
+=head1 SYNOPSIS
+
+ use Memoize;
+ use Git::SVN::Memoize::YAML;
+
+ tie my %cache => 'Git::SVN::Memoize::YAML', $filename;
+ memoize('slow_function', SCALAR_CACHE => [HASH => \%cache]);
+ slow_function(arguments);
+
+=head1 DESCRIPTION
+
+This module provides a class that can be used to tie a hash to a
+YAML file. The file is read when the hash is initialized and
+rewritten when the hash is destroyed.
+
+The intent is to allow L<Memoize> to back its cache with a file in
+YAML format, just like L<Memoize::Storable> allows L<Memoize> to
+back its cache with a file in Storable format. Unlike the Storable
+format, the YAML format is platform-independent and fairly stable.
+
+Carps on error.
+
+=head1 DIAGNOSTICS
+
+See L<YAML::Any>.
+
+=head1 DEPENDENCIES
+
+L<YAML::Any> from CPAN.
+
+=head1 INCOMPATIBILITIES
+
+None reported.
+
+=head1 BUGS
+
+The entire cache is read into a Perl hash when loading the file,
+so this is not very scalable.
--- /dev/null
+package Git::SVN::Ra;
+use vars qw/@ISA $config_dir $_ignore_refs_regex $_log_window_size/;
+use strict;
+use warnings;
+use SVN::Client;
+use SVN::Ra;
+BEGIN {
+ @ISA = qw(SVN::Ra);
+}
+
+my ($ra_invalid, $can_do_switch, %ignored_err, $RA);
+
+BEGIN {
+ # enforce temporary pool usage for some simple functions
+ no strict 'refs';
+ for my $f (qw/rev_proplist get_latest_revnum get_uuid get_repos_root
+ get_file/) {
+ my $SUPER = "SUPER::$f";
+ *$f = sub {
+ my $self = shift;
+ my $pool = SVN::Pool->new;
+ my @ret = $self->$SUPER(@_,$pool);
+ $pool->clear;
+ wantarray ? @ret : $ret[0];
+ };
+ }
+}
+
+sub _auth_providers () {
+ my @rv = (
+ SVN::Client::get_simple_provider(),
+ SVN::Client::get_ssl_server_trust_file_provider(),
+ SVN::Client::get_simple_prompt_provider(
+ \&Git::SVN::Prompt::simple, 2),
+ SVN::Client::get_ssl_client_cert_file_provider(),
+ SVN::Client::get_ssl_client_cert_prompt_provider(
+ \&Git::SVN::Prompt::ssl_client_cert, 2),
+ SVN::Client::get_ssl_client_cert_pw_file_provider(),
+ SVN::Client::get_ssl_client_cert_pw_prompt_provider(
+ \&Git::SVN::Prompt::ssl_client_cert_pw, 2),
+ SVN::Client::get_username_provider(),
+ SVN::Client::get_ssl_server_trust_prompt_provider(
+ \&Git::SVN::Prompt::ssl_server_trust),
+ SVN::Client::get_username_prompt_provider(
+ \&Git::SVN::Prompt::username, 2)
+ );
+
+ # earlier 1.6.x versions would segfault, and <= 1.5.x didn't have
+ # this function
+ if (::compare_svn_version('1.6.15') >= 0) {
+ my $config = SVN::Core::config_get_config($config_dir);
+ my ($p, @a);
+ # config_get_config returns all config files from
+ # ~/.subversion, auth_get_platform_specific_client_providers
+ # just wants the config "file".
+ @a = ($config->{'config'}, undef);
+ $p = SVN::Core::auth_get_platform_specific_client_providers(@a);
+ # Insert the return value from
+ # auth_get_platform_specific_providers
+ unshift @rv, @$p;
+ }
+ \@rv;
+}
+
+sub escape_uri_only {
+ my ($uri) = @_;
+ my @tmp;
+ foreach (split m{/}, $uri) {
+ s/([^~\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
+ push @tmp, $_;
+ }
+ join('/', @tmp);
+}
+
+sub escape_url {
+ my ($url) = @_;
+ if ($url =~ m#^(https?)://([^/]+)(.*)$#) {
+ my ($scheme, $domain, $uri) = ($1, $2, escape_uri_only($3));
+ $url = "$scheme://$domain$uri";
+ }
+ $url;
+}
+
+sub new {
+ my ($class, $url) = @_;
+ $url =~ s!/+$!!;
+ return $RA if ($RA && $RA->{url} eq $url);
+
+ ::_req_svn();
+
+ SVN::_Core::svn_config_ensure($config_dir, undef);
+ my ($baton, $callbacks) = SVN::Core::auth_open_helper(_auth_providers);
+ my $config = SVN::Core::config_get_config($config_dir);
+ $RA = undef;
+ my $dont_store_passwords = 1;
+ my $conf_t = ${$config}{'config'};
+ {
+ no warnings 'once';
+ # The usage of $SVN::_Core::SVN_CONFIG_* variables
+ # produces warnings that variables are used only once.
+ # I had not found the better way to shut them up, so
+ # the warnings of type 'once' are disabled in this block.
+ if (SVN::_Core::svn_config_get_bool($conf_t,
+ $SVN::_Core::SVN_CONFIG_SECTION_AUTH,
+ $SVN::_Core::SVN_CONFIG_OPTION_STORE_PASSWORDS,
+ 1) == 0) {
+ SVN::_Core::svn_auth_set_parameter($baton,
+ $SVN::_Core::SVN_AUTH_PARAM_DONT_STORE_PASSWORDS,
+ bless (\$dont_store_passwords, "_p_void"));
+ }
+ if (SVN::_Core::svn_config_get_bool($conf_t,
+ $SVN::_Core::SVN_CONFIG_SECTION_AUTH,
+ $SVN::_Core::SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
+ 1) == 0) {
+ $Git::SVN::Prompt::_no_auth_cache = 1;
+ }
+ } # no warnings 'once'
+ my $self = SVN::Ra->new(url => escape_url($url), auth => $baton,
+ config => $config,
+ pool => SVN::Pool->new,
+ auth_provider_callbacks => $callbacks);
+ $self->{url} = $url;
+ $self->{svn_path} = $url;
+ $self->{repos_root} = $self->get_repos_root;
+ $self->{svn_path} =~ s#^\Q$self->{repos_root}\E(/|$)##;
+ $self->{cache} = { check_path => { r => 0, data => {} },
+ get_dir => { r => 0, data => {} } };
+ $RA = bless $self, $class;
+}
+
+sub check_path {
+ my ($self, $path, $r) = @_;
+ my $cache = $self->{cache}->{check_path};
+ if ($r == $cache->{r} && exists $cache->{data}->{$path}) {
+ return $cache->{data}->{$path};
+ }
+ my $pool = SVN::Pool->new;
+ my $t = $self->SUPER::check_path($path, $r, $pool);
+ $pool->clear;
+ if ($r != $cache->{r}) {
+ %{$cache->{data}} = ();
+ $cache->{r} = $r;
+ }
+ $cache->{data}->{$path} = $t;
+}
+
+sub get_dir {
+ my ($self, $dir, $r) = @_;
+ my $cache = $self->{cache}->{get_dir};
+ if ($r == $cache->{r}) {
+ if (my $x = $cache->{data}->{$dir}) {
+ return wantarray ? @$x : $x->[0];
+ }
+ }
+ my $pool = SVN::Pool->new;
+ my ($d, undef, $props) = $self->SUPER::get_dir($dir, $r, $pool);
+ my %dirents = map { $_ => { kind => $d->{$_}->kind } } keys %$d;
+ $pool->clear;
+ if ($r != $cache->{r}) {
+ %{$cache->{data}} = ();
+ $cache->{r} = $r;
+ }
+ $cache->{data}->{$dir} = [ \%dirents, $r, $props ];
+ wantarray ? (\%dirents, $r, $props) : \%dirents;
+}
+
+sub DESTROY {
+ # do not call the real DESTROY since we store ourselves in $RA
+}
+
+# get_log(paths, start, end, limit,
+# discover_changed_paths, strict_node_history, receiver)
+sub get_log {
+ my ($self, @args) = @_;
+ my $pool = SVN::Pool->new;
+
+ # svn_log_changed_path_t objects passed to get_log are likely to be
+ # overwritten even if only the refs are copied to an external variable,
+ # so we should dup the structures in their entirety. Using an
+ # externally passed pool (instead of our temporary and quickly cleared
+ # pool in Git::SVN::Ra) does not help matters at all...
+ my $receiver = pop @args;
+ my $prefix = "/".$self->{svn_path};
+ $prefix =~ s#/+($)##;
+ my $prefix_regex = qr#^\Q$prefix\E#;
+ push(@args, sub {
+ my ($paths) = $_[0];
+ return &$receiver(@_) unless $paths;
+ $_[0] = ();
+ foreach my $p (keys %$paths) {
+ my $i = $paths->{$p};
+ # Make path relative to our url, not repos_root
+ $p =~ s/$prefix_regex//;
+ my %s = map { $_ => $i->$_; }
+ qw/copyfrom_path copyfrom_rev action/;
+ if ($s{'copyfrom_path'}) {
+ $s{'copyfrom_path'} =~ s/$prefix_regex//;
+ }
+ $_[0]{$p} = \%s;
+ }
+ &$receiver(@_);
+ });
+
+
+ # the limit parameter was not supported in SVN 1.1.x, so we
+ # drop it. Therefore, the receiver callback passed to it
+ # is made aware of this limitation by being wrapped if
+ # the limit passed to is being wrapped.
+ if (::compare_svn_version('1.2.0') <= 0) {
+ my $limit = splice(@args, 3, 1);
+ if ($limit > 0) {
+ my $receiver = pop @args;
+ push(@args, sub { &$receiver(@_) if (--$limit >= 0) });
+ }
+ }
+ my $ret = $self->SUPER::get_log(@args, $pool);
+ $pool->clear;
+ $ret;
+}
+
+sub trees_match {
+ my ($self, $url1, $rev1, $url2, $rev2) = @_;
+ my $ctx = SVN::Client->new(auth => _auth_providers);
+ my $out = IO::File->new_tmpfile;
+
+ # older SVN (1.1.x) doesn't take $pool as the last parameter for
+ # $ctx->diff(), so we'll create a default one
+ my $pool = SVN::Pool->new_default_sub;
+
+ $ra_invalid = 1; # this will open a new SVN::Ra connection to $url1
+ $ctx->diff([], $url1, $rev1, $url2, $rev2, 1, 1, 0, $out, $out);
+ $out->flush;
+ my $ret = (($out->stat)[7] == 0);
+ close $out or croak $!;
+
+ $ret;
+}
+
+sub get_commit_editor {
+ my ($self, $log, $cb, $pool) = @_;
+
+ my @lock = (::compare_svn_version('1.2.0') >= 0) ? (undef, 0) : ();
+ $self->SUPER::get_commit_editor($log, $cb, @lock, $pool);
+}
+
+sub gs_do_update {
+ my ($self, $rev_a, $rev_b, $gs, $editor) = @_;
+ my $new = ($rev_a == $rev_b);
+ my $path = $gs->{path};
+
+ if ($new && -e $gs->{index}) {
+ unlink $gs->{index} or die
+ "Couldn't unlink index: $gs->{index}: $!\n";
+ }
+ my $pool = SVN::Pool->new;
+ $editor->set_path_strip($path);
+ my (@pc) = split m#/#, $path;
+ my $reporter = $self->do_update($rev_b, (@pc ? shift @pc : ''),
+ 1, $editor, $pool);
+ my @lock = (::compare_svn_version('1.2.0') >= 0) ? (undef) : ();
+
+ # Since we can't rely on svn_ra_reparent being available, we'll
+ # just have to do some magic with set_path to make it so
+ # we only want a partial path.
+ my $sp = '';
+ my $final = join('/', @pc);
+ while (@pc) {
+ $reporter->set_path($sp, $rev_b, 0, @lock, $pool);
+ $sp .= '/' if length $sp;
+ $sp .= shift @pc;
+ }
+ die "BUG: '$sp' != '$final'\n" if ($sp ne $final);
+
+ $reporter->set_path($sp, $rev_a, $new, @lock, $pool);
+
+ $reporter->finish_report($pool);
+ $pool->clear;
+ $editor->{git_commit_ok};
+}
+
+# this requires SVN 1.4.3 or later (do_switch didn't work before 1.4.3, and
+# svn_ra_reparent didn't work before 1.4)
+sub gs_do_switch {
+ my ($self, $rev_a, $rev_b, $gs, $url_b, $editor) = @_;
+ my $path = $gs->{path};
+ my $pool = SVN::Pool->new;
+
+ my $full_url = $self->{url};
+ my $old_url = $full_url;
+ $full_url .= '/' . $path if length $path;
+ my ($ra, $reparented);
+
+ if ($old_url =~ m#^svn(\+ssh)?://# ||
+ ($full_url =~ m#^https?://# &&
+ escape_url($full_url) ne $full_url)) {
+ $_[0] = undef;
+ $self = undef;
+ $RA = undef;
+ $ra = Git::SVN::Ra->new($full_url);
+ $ra_invalid = 1;
+ } elsif ($old_url ne $full_url) {
+ SVN::_Ra::svn_ra_reparent($self->{session}, $full_url, $pool);
+ $self->{url} = $full_url;
+ $reparented = 1;
+ }
+
+ $ra ||= $self;
+ $url_b = escape_url($url_b);
+ my $reporter = $ra->do_switch($rev_b, '', 1, $url_b, $editor, $pool);
+ my @lock = (::compare_svn_version('1.2.0') >= 0) ? (undef) : ();
+ $reporter->set_path('', $rev_a, 0, @lock, $pool);
+ $reporter->finish_report($pool);
+
+ if ($reparented) {
+ SVN::_Ra::svn_ra_reparent($self->{session}, $old_url, $pool);
+ $self->{url} = $old_url;
+ }
+
+ $pool->clear;
+ $editor->{git_commit_ok};
+}
+
+sub longest_common_path {
+ my ($gsv, $globs) = @_;
+ my %common;
+ my $common_max = scalar @$gsv;
+
+ foreach my $gs (@$gsv) {
+ my @tmp = split m#/#, $gs->{path};
+ my $p = '';
+ foreach (@tmp) {
+ $p .= length($p) ? "/$_" : $_;
+ $common{$p} ||= 0;
+ $common{$p}++;
+ }
+ }
+ $globs ||= [];
+ $common_max += scalar @$globs;
+ foreach my $glob (@$globs) {
+ my @tmp = split m#/#, $glob->{path}->{left};
+ my $p = '';
+ foreach (@tmp) {
+ $p .= length($p) ? "/$_" : $_;
+ $common{$p} ||= 0;
+ $common{$p}++;
+ }
+ }
+
+ my $longest_path = '';
+ foreach (sort {length $b <=> length $a} keys %common) {
+ if ($common{$_} == $common_max) {
+ $longest_path = $_;
+ last;
+ }
+ }
+ $longest_path;
+}
+
+sub gs_fetch_loop_common {
+ my ($self, $base, $head, $gsv, $globs) = @_;
+ return if ($base > $head);
+ my $inc = $_log_window_size;
+ my ($min, $max) = ($base, $head < $base + $inc ? $head : $base + $inc);
+ my $longest_path = longest_common_path($gsv, $globs);
+ my $ra_url = $self->{url};
+ my $find_trailing_edge;
+ while (1) {
+ my %revs;
+ my $err;
+ my $err_handler = $SVN::Error::handler;
+ $SVN::Error::handler = sub {
+ ($err) = @_;
+ skip_unknown_revs($err);
+ };
+ sub _cb {
+ my ($paths, $r, $author, $date, $log) = @_;
+ [ $paths,
+ { author => $author, date => $date, log => $log } ];
+ }
+ $self->get_log([$longest_path], $min, $max, 0, 1, 1,
+ sub { $revs{$_[1]} = _cb(@_) });
+ if ($err) {
+ print "Checked through r$max\r";
+ } else {
+ $find_trailing_edge = 1;
+ }
+ if ($err and $find_trailing_edge) {
+ print STDERR "Path '$longest_path' ",
+ "was probably deleted:\n",
+ $err->expanded_message,
+ "\nWill attempt to follow ",
+ "revisions r$min .. r$max ",
+ "committed before the deletion\n";
+ my $hi = $max;
+ while (--$hi >= $min) {
+ my $ok;
+ $self->get_log([$longest_path], $min, $hi,
+ 0, 1, 1, sub {
+ $ok = $_[1];
+ $revs{$_[1]} = _cb(@_) });
+ if ($ok) {
+ print STDERR "r$min .. r$ok OK\n";
+ last;
+ }
+ }
+ $find_trailing_edge = 0;
+ }
+ $SVN::Error::handler = $err_handler;
+
+ my %exists = map { $_->{path} => $_ } @$gsv;
+ foreach my $r (sort {$a <=> $b} keys %revs) {
+ my ($paths, $logged) = @{$revs{$r}};
+
+ foreach my $gs ($self->match_globs(\%exists, $paths,
+ $globs, $r)) {
+ if ($gs->rev_map_max >= $r) {
+ next;
+ }
+ next unless $gs->match_paths($paths, $r);
+ $gs->{logged_rev_props} = $logged;
+ if (my $last_commit = $gs->last_commit) {
+ $gs->assert_index_clean($last_commit);
+ }
+ my $log_entry = $gs->do_fetch($paths, $r);
+ if ($log_entry) {
+ $gs->do_git_commit($log_entry);
+ }
+ $Git::SVN::INDEX_FILES{$gs->{index}} = 1;
+ }
+ foreach my $g (@$globs) {
+ my $k = "svn-remote.$g->{remote}." .
+ "$g->{t}-maxRev";
+ Git::SVN::tmp_config($k, $r);
+ }
+ if ($ra_invalid) {
+ $_[0] = undef;
+ $self = undef;
+ $RA = undef;
+ $self = Git::SVN::Ra->new($ra_url);
+ $ra_invalid = undef;
+ }
+ }
+ # pre-fill the .rev_db since it'll eventually get filled in
+ # with '0' x40 if something new gets committed
+ foreach my $gs (@$gsv) {
+ next if $gs->rev_map_max >= $max;
+ next if defined $gs->rev_map_get($max);
+ $gs->rev_map_set($max, 0 x40);
+ }
+ foreach my $g (@$globs) {
+ my $k = "svn-remote.$g->{remote}.$g->{t}-maxRev";
+ Git::SVN::tmp_config($k, $max);
+ }
+ last if $max >= $head;
+ $min = $max + 1;
+ $max += $inc;
+ $max = $head if ($max > $head);
+ }
+ Git::SVN::gc();
+}
+
+sub get_dir_globbed {
+ my ($self, $left, $depth, $r) = @_;
+
+ my @x = eval { $self->get_dir($left, $r) };
+ return unless scalar @x == 3;
+ my $dirents = $x[0];
+ my @finalents;
+ foreach my $de (keys %$dirents) {
+ next if $dirents->{$de}->{kind} != $SVN::Node::dir;
+ if ($depth > 1) {
+ my @args = ("$left/$de", $depth - 1, $r);
+ foreach my $dir ($self->get_dir_globbed(@args)) {
+ push @finalents, "$de/$dir";
+ }
+ } else {
+ push @finalents, $de;
+ }
+ }
+ @finalents;
+}
+
+# return value: 0 -- don't ignore, 1 -- ignore
+sub is_ref_ignored {
+ my ($g, $p) = @_;
+ my $refname = $g->{ref}->full_path($p);
+ return 1 if defined($g->{ignore_refs_regex}) &&
+ $refname =~ m!$g->{ignore_refs_regex}!;
+ return 0 unless defined($_ignore_refs_regex);
+ return 1 if $refname =~ m!$_ignore_refs_regex!o;
+ return 0;
+}
+
+sub match_globs {
+ my ($self, $exists, $paths, $globs, $r) = @_;
+
+ sub get_dir_check {
+ my ($self, $exists, $g, $r) = @_;
+
+ my @dirs = $self->get_dir_globbed($g->{path}->{left},
+ $g->{path}->{depth},
+ $r);
+
+ foreach my $de (@dirs) {
+ my $p = $g->{path}->full_path($de);
+ next if $exists->{$p};
+ next if (length $g->{path}->{right} &&
+ ($self->check_path($p, $r) !=
+ $SVN::Node::dir));
+ next unless $p =~ /$g->{path}->{regex}/;
+ $exists->{$p} = Git::SVN->init($self->{url}, $p, undef,
+ $g->{ref}->full_path($de), 1);
+ }
+ }
+ foreach my $g (@$globs) {
+ if (my $path = $paths->{"/$g->{path}->{left}"}) {
+ if ($path->{action} =~ /^[AR]$/) {
+ get_dir_check($self, $exists, $g, $r);
+ }
+ }
+ foreach (keys %$paths) {
+ if (/$g->{path}->{left_regex}/ &&
+ !/$g->{path}->{regex}/) {
+ next if $paths->{$_}->{action} !~ /^[AR]$/;
+ get_dir_check($self, $exists, $g, $r);
+ }
+ next unless /$g->{path}->{regex}/;
+ my $p = $1;
+ my $pathname = $g->{path}->full_path($p);
+ next if is_ref_ignored($g, $p);
+ next if $exists->{$pathname};
+ next if ($self->check_path($pathname, $r) !=
+ $SVN::Node::dir);
+ $exists->{$pathname} = Git::SVN->init(
+ $self->{url}, $pathname, undef,
+ $g->{ref}->full_path($p), 1);
+ }
+ my $c = '';
+ foreach (split m#/#, $g->{path}->{left}) {
+ $c .= "/$_";
+ next unless ($paths->{$c} &&
+ ($paths->{$c}->{action} =~ /^[AR]$/));
+ get_dir_check($self, $exists, $g, $r);
+ }
+ }
+ values %$exists;
+}
+
+sub minimize_url {
+ my ($self) = @_;
+ return $self->{url} if ($self->{url} eq $self->{repos_root});
+ my $url = $self->{repos_root};
+ my @components = split(m!/!, $self->{svn_path});
+ my $c = '';
+ do {
+ $url .= "/$c" if length $c;
+ eval {
+ my $ra = (ref $self)->new($url);
+ my $latest = $ra->get_latest_revnum;
+ $ra->get_log("", $latest, 0, 1, 0, 1, sub {});
+ };
+ } while ($@ && ($c = shift @components));
+ $url;
+}
+
+sub can_do_switch {
+ my $self = shift;
+ unless (defined $can_do_switch) {
+ my $pool = SVN::Pool->new;
+ my $rep = eval {
+ $self->do_switch(1, '', 0, $self->{url},
+ SVN::Delta::Editor->new, $pool);
+ };
+ if ($@) {
+ $can_do_switch = 0;
+ } else {
+ $rep->abort_report($pool);
+ $can_do_switch = 1;
+ }
+ $pool->clear;
+ }
+ $can_do_switch;
+}
+
+sub skip_unknown_revs {
+ my ($err) = @_;
+ my $errno = $err->apr_err();
+ # Maybe the branch we're tracking didn't
+ # exist when the repo started, so it's
+ # not an error if it doesn't, just continue
+ #
+ # Wonderfully consistent library, eh?
+ # 160013 - svn:// and file://
+ # 175002 - http(s)://
+ # 175007 - http(s):// (this repo required authorization, too...)
+ # More codes may be discovered later...
+ if ($errno == 175007 || $errno == 175002 || $errno == 160013) {
+ my $err_key = $err->expanded_message;
+ # revision numbers change every time, filter them out
+ $err_key =~ s/\d+/\0/g;
+ $err_key = "$errno\0$err_key";
+ unless ($ignored_err{$err_key}) {
+ warn "W: Ignoring error from SVN, path probably ",
+ "does not exist: ($errno): ",
+ $err->expanded_message,"\n";
+ warn "W: Do not be alarmed at the above message ",
+ "git-svn is just searching aggressively for ",
+ "old history.\n",
+ "This may take a while on large repositories\n";
+ $ignored_err{$err_key} = 1;
+ }
+ return;
+ }
+ die "Error from SVN, ($errno): ", $err->expanded_message,"\n";
+}
+
+1;
+__END__
+
+Git::SVN::Ra - Subversion remote access functions for git-svn
+
+=head1 SYNOPSIS
+
+ use Git::SVN::Ra;
+
+ my $ra = Git::SVN::Ra->new($branchurl);
+ my ($dirents, $fetched_revnum, $props) =
+ $ra->get_dir('.', $SVN::Core::INVALID_REVNUM);
+
+=head1 DESCRIPTION
+
+This is a wrapper around the L<SVN::Ra> module for use by B<git-svn>.
+It fills in some default parameters (such as the authentication
+scheme), smooths over incompatibilities between libsvn versions, adds
+caching, and implements some functions specific to B<git-svn>.
+
+Do not use it unless you are developing git-svn. The interface will
+change as git-svn evolves.
+
+=head1 DEPENDENCIES
+
+Subversion perl bindings,
+L<Git::SVN>.
+
+C<Git::SVN::Ra> has not been tested using callers other than
+B<git-svn> itself.
+
+=head1 SEE ALSO
+
+L<SVN::Ra>.
+
+=head1 INCOMPATIBILITIES
+
+None reported.
+
+=head1 BUGS
+
+None.
# Makefile for perl support modules and routine
#
makfile:=perl.mak
+modules =
PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
prefix_SQ = $(subst ','\'',$(prefix))
ifdef NO_PERL_MAKEMAKER
instdir_SQ = $(subst ','\'',$(prefix)/lib)
+
+modules += Git
+modules += Git/I18N
+modules += Git/SVN/Memoize/YAML
+modules += Git/SVN/Fetcher
+modules += Git/SVN/Editor
+modules += Git/SVN/Prompt
+modules += Git/SVN/Ra
+
$(makfile): ../GIT-CFLAGS Makefile
echo all: private-Error.pm Git.pm Git/I18N.pm > $@
- echo ' mkdir -p blib/lib/Git' >> $@
- echo ' $(RM) blib/lib/Git.pm; cp Git.pm blib/lib/' >> $@
- echo ' $(RM) blib/lib/Git/I18N.pm; cp Git/I18N.pm blib/lib/Git/' >> $@
+ set -e; \
+ for i in $(modules); \
+ do \
+ if test $$i = $${i%/*}; \
+ then \
+ subdir=; \
+ else \
+ subdir=/$${i%/*}; \
+ fi; \
+ echo ' $(RM) blib/lib/'$$i'.pm' >> $@; \
+ echo ' mkdir -p blib/lib'$$subdir >> $@; \
+ echo ' cp '$$i'.pm blib/lib/'$$i'.pm' >> $@; \
+ done
echo ' $(RM) blib/lib/Error.pm' >> $@
'$(PERL_PATH_SQ)' -MError -e 'exit($$Error::VERSION < 0.15009)' || \
echo ' cp private-Error.pm blib/lib/Error.pm' >> $@
echo install: >> $@
- echo ' mkdir -p "$$(DESTDIR)$(instdir_SQ)"' >> $@
- echo ' mkdir -p "$$(DESTDIR)$(instdir_SQ)/Git"' >> $@
- echo ' $(RM) "$$(DESTDIR)$(instdir_SQ)/Git.pm"; cp Git.pm "$$(DESTDIR)$(instdir_SQ)"' >> $@
- echo ' $(RM) "$$(DESTDIR)$(instdir_SQ)/Git/I18N.pm"; cp Git/I18N.pm "$$(DESTDIR)$(instdir_SQ)/Git"' >> $@
+ set -e; \
+ for i in $(modules); \
+ do \
+ if test $$i = $${i%/*}; \
+ then \
+ subdir=; \
+ else \
+ subdir=/$${i%/*}; \
+ fi; \
+ echo ' $(RM) "$$(DESTDIR)$(instdir_SQ)/'$$i'.pm"' >> $@; \
+ echo ' mkdir -p "$$(DESTDIR)$(instdir_SQ)'$$subdir'"' >> $@; \
+ echo ' cp '$$i'.pm "$$(DESTDIR)$(instdir_SQ)/'$$i'.pm"' >> $@; \
+ done
echo ' $(RM) "$$(DESTDIR)$(instdir_SQ)/Error.pm"' >> $@
'$(PERL_PATH_SQ)' -MError -e 'exit($$Error::VERSION < 0.15009)' || \
echo ' cp private-Error.pm "$$(DESTDIR)$(instdir_SQ)/Error.pm"' >> $@
MAKE_FRAG
}
+# XXX. When editing this list:
+#
+# * Please update perl/Makefile, too.
+# * Don't forget to test with NO_PERL_MAKEMAKER=YesPlease
my %pm = (
'Git.pm' => '$(INST_LIBDIR)/Git.pm',
'Git/I18N.pm' => '$(INST_LIBDIR)/Git/I18N.pm',
+ 'Git/SVN/Memoize/YAML.pm' => '$(INST_LIBDIR)/Git/SVN/Memoize/YAML.pm',
'Git/SVN/Fetcher.pm' => '$(INST_LIBDIR)/Git/SVN/Fetcher.pm',
+ 'Git/SVN/Editor.pm' => '$(INST_LIBDIR)/Git/SVN/Editor.pm',
'Git/SVN/Prompt.pm' => '$(INST_LIBDIR)/Git/SVN/Prompt.pm',
+ 'Git/SVN/Ra.pm' => '$(INST_LIBDIR)/Git/SVN/Ra.pm',
);
# We come with our own bundled Error.pm. It's not in the set of default
strbuf_add(buf, buffer, n);
}
-static void safe_read(int fd, void *buffer, unsigned size)
+static int safe_read(int fd, void *buffer, unsigned size, int return_line_fail)
{
ssize_t ret = read_in_full(fd, buffer, size);
if (ret < 0)
die_errno("read error");
- else if (ret < size)
+ else if (ret < size) {
+ if (return_line_fail)
+ return -1;
+
die("The remote end hung up unexpectedly");
+ }
+
+ return ret;
}
static int packet_length(const char *linelen)
return len;
}
-int packet_read_line(int fd, char *buffer, unsigned size)
+static int packet_read_internal(int fd, char *buffer, unsigned size, int return_line_fail)
{
- int len;
+ int len, ret;
char linelen[4];
- safe_read(fd, linelen, 4);
+ ret = safe_read(fd, linelen, 4, return_line_fail);
+ if (return_line_fail && ret < 0)
+ return ret;
len = packet_length(linelen);
if (len < 0)
die("protocol error: bad line length character: %.4s", linelen);
len -= 4;
if (len >= size)
die("protocol error: bad line length %d", len);
- safe_read(fd, buffer, len);
+ ret = safe_read(fd, buffer, len, return_line_fail);
+ if (return_line_fail && ret < 0)
+ return ret;
buffer[len] = 0;
packet_trace(buffer, len, 0);
return len;
}
+int packet_read(int fd, char *buffer, unsigned size)
+{
+ return packet_read_internal(fd, buffer, size, 1);
+}
+
+int packet_read_line(int fd, char *buffer, unsigned size)
+{
+ return packet_read_internal(fd, buffer, size, 0);
+}
+
int packet_get_line(struct strbuf *out,
char **src_buf, size_t *src_len)
{
void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
int packet_read_line(int fd, char *buffer, unsigned size);
+int packet_read(int fd, char *buffer, unsigned size);
int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len);
ssize_t safe_write(int, const void *, ssize_t);
Language: it (Italian)
Repository: https://github.com/quizzlo/git-po-it/
-Leader: Marco Paolone <marcopaolone@gmail.com>
+Leader: Marco Paolone <marcopaolone AT gmail.com>
+Members: Stefano Lattarini <stefano.lattarini AT gmail.com>
Language: nl (Dutch)
Repository: https://github.com/vfr-nl/git-po/
#
msgid ""
msgstr ""
-"Project-Id-Version: git 1.7.10\n"
+"Project-Id-Version: git 1.7.11\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-05-15 06:31+0800\n"
+"POT-Creation-Date: 2012-07-03 10:23+0800\n"
"PO-Revision-Date: 2012-03-28 18:46+0200\n"
"Last-Translator: Ralf Thielow <ralf.thielow@googlemail.com>\n"
"Language-Team: German\n"
"um die Auflösung entsprechend zu markieren und einzutragen,\n"
"oder benutze 'git commit -a'."
+#: bundle.c:36
+#, c-format
+msgid "'%s' does not look like a v2 bundle file"
+msgstr "'%s' sieht nicht wie eine v2 Paketdatei aus"
+
+#: bundle.c:63
+#, c-format
+msgid "unrecognized header: %s%s (%d)"
+msgstr "nicht erkannter Kopfbereich: %s%s (%d)"
+
+#: bundle.c:89 builtin/commit.c:696
+#, c-format
+msgid "could not open '%s'"
+msgstr "Konnte '%s' nicht öffnen"
+
+#: bundle.c:140
+msgid "Repository lacks these prerequisite commits:"
+msgstr "Dem Projektarchiv fehlen folgende vorrausgesetzte Versionen:"
+
+#: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
+#: builtin/log.c:721 builtin/log.c:1310 builtin/log.c:1529 builtin/merge.c:347
+#: builtin/shortlog.c:181
+msgid "revision walk setup failed"
+msgstr "Einrichtung des Revisionsgangs fehlgeschlagen"
+
+#: bundle.c:186
+#, c-format
+msgid "The bundle contains %d ref"
+msgid_plural "The bundle contains %d refs"
+msgstr[0] "Das Paket enthält %d Referenz"
+msgstr[1] "Das Paket enthält %d Referenzen"
+
+#: bundle.c:192
+msgid "The bundle records a complete history."
+msgstr "Das Paket speichert eine komplette Historie."
+
+#: bundle.c:195
+#, c-format
+msgid "The bundle requires this ref"
+msgid_plural "The bundle requires these %d refs"
+msgstr[0] "Das Paket benötigt diese Referenz"
+msgstr[1] "Das Paket benötigt diese %d Referenzen"
+
+#: bundle.c:294
+msgid "rev-list died"
+msgstr "\"rev-list\" abgebrochen"
+
+#: bundle.c:300 builtin/log.c:1206 builtin/shortlog.c:284
+#, c-format
+msgid "unrecognized argument: %s"
+msgstr "nicht erkanntes Argument: %s"
+
+#: bundle.c:335
+#, c-format
+msgid "ref '%s' is excluded by the rev-list options"
+msgstr "Referenz '%s' wird durch \"rev-list\" Optionen ausgeschlossen"
+
+#: bundle.c:380
+msgid "Refusing to create empty bundle."
+msgstr "Erstellung eines leeren Pakets zurückgewiesen."
+
+#: bundle.c:398
+msgid "Could not spawn pack-objects"
+msgstr "Konnte Paketobjekte nicht erstellen"
+
+#: bundle.c:416
+msgid "pack-objects died"
+msgstr "Erstellung der Paketobjekte abgebrochen"
+
+#: bundle.c:419
+#, c-format
+msgid "cannot create '%s'"
+msgstr "kann '%s' nicht erstellen"
+
+#: bundle.c:441
+msgid "index-pack died"
+msgstr "Erstellung der Paketindexdatei abgebrochen"
+
#: commit.c:48
#, c-format
msgid "could not parse %s"
msgid "failed to close rev-list's stdin: %s"
msgstr "Fehler beim Schließen von rev-list's Standard-Eingabe: %s"
+#: date.c:95
+msgid "in the future"
+msgstr "in der Zukunft"
+
+#: date.c:101
+#, c-format
+msgid "%lu second ago"
+msgid_plural "%lu seconds ago"
+msgstr[0] "vor %lu Sekunde"
+msgstr[1] "vor %lu Sekunden"
+
+#: date.c:108
+#, c-format
+msgid "%lu minute ago"
+msgid_plural "%lu minutes ago"
+msgstr[0] "vor %lu Minute"
+msgstr[1] "vor %lu Minuten"
+
+#: date.c:115
+#, c-format
+msgid "%lu hour ago"
+msgid_plural "%lu hours ago"
+msgstr[0] "vor %lu Stunde"
+msgstr[1] "vor %lu Stunden"
+
+#: date.c:122
+#, c-format
+msgid "%lu day ago"
+msgid_plural "%lu days ago"
+msgstr[0] "vor %lu Tag"
+msgstr[1] "vor %lu Tagen"
+
+#: date.c:128
+#, c-format
+msgid "%lu week ago"
+msgid_plural "%lu weeks ago"
+msgstr[0] "vor %lu Woche"
+msgstr[1] "vor %lu Wochen"
+
+#: date.c:135
+#, c-format
+msgid "%lu month ago"
+msgid_plural "%lu months ago"
+msgstr[0] "vor %lu Monat"
+msgstr[1] "vor %lu Monaten"
+
+#: date.c:146
+#, c-format
+msgid "%lu year"
+msgid_plural "%lu years"
+msgstr[0] "vor %lu Jahr"
+msgstr[1] "vor %lu Jahren"
+
+#: date.c:149
+#, c-format
+msgid "%s, %lu month ago"
+msgid_plural "%s, %lu months ago"
+msgstr[0] "%s, und %lu Monat"
+msgstr[1] "%s, und %lu Monaten"
+
+#: date.c:154 date.c:159
+#, c-format
+msgid "%lu year ago"
+msgid_plural "%lu years ago"
+msgstr[0] "vor %lu Jahr"
+msgstr[1] "vor %lu Jahren"
+
#: diff.c:105
#, c-format
msgid " Failed to parse dirstat cut-off percentage '%.*s'\n"
msgstr[0] ", %d Zeile entfernt(-)"
msgstr[1] ", %d Zeilen entfernt(-)"
-#: diff.c:3439
+#: diff.c:3478
#, c-format
msgid ""
"Failed to parse --dirstat/-X option parameter:\n"
msgid "gpg failed to sign the data"
msgstr "gpg beim Signieren der Daten fehlgeschlagen"
-#: grep.c:1280
+#: grep.c:1320
#, c-format
msgid "'%s': unable to read %s"
msgstr "'%s': konnte nicht lesen %s"
-#: grep.c:1297
+#: grep.c:1337
#, c-format
msgid "'%s': %s"
msgstr "'%s': %s"
-#: grep.c:1308
+#: grep.c:1348
#, c-format
msgid "'%s': short read %s"
msgstr "'%s': read() zu kurz %s"
-#: help.c:287
+#: help.c:208
+#, c-format
+msgid "available git commands in '%s'"
+msgstr "Vorhandene Git-Kommandos in '%s'"
+
+#: help.c:215
+msgid "git commands available from elsewhere on your $PATH"
+msgstr "Vorhandene Git-Kommandos irgendwo in deinem $PATH"
+
+#: help.c:271
#, c-format
msgid ""
"'%s' appears to be a git command, but we were not\n"
"'%s' scheint ein git-Kommando zu sein, konnte aber\n"
"nicht ausgeführt werden. Vielleicht ist git-%s fehlerhaft?"
-#: remote.c:1607
+#: help.c:328
+msgid "Uh oh. Your system reports no Git commands at all."
+msgstr "Uh oh. Keine Git-Kommandos auf deinem System vorhanden."
+
+#: help.c:350
+#, c-format
+msgid ""
+"WARNING: You called a Git command named '%s', which does not exist.\n"
+"Continuing under the assumption that you meant '%s'"
+msgstr ""
+"Warnung: Du hast das nicht existierende Git-Kommando '%s' ausgeführt.\n"
+"Setze fort unter der Annahme das du '%s' gemeint hast"
+
+#: help.c:355
+#, c-format
+msgid "in %0.1f seconds automatically..."
+msgstr "automatisch in %0.1f Sekunden..."
+
+#: help.c:362
+#, c-format
+msgid "git: '%s' is not a git command. See 'git --help'."
+msgstr "git: '%s' ist kein Git-Kommando. Siehe 'git --help'."
+
+#: help.c:366
+msgid ""
+"\n"
+"Did you mean this?"
+msgid_plural ""
+"\n"
+"Did you mean one of these?"
+msgstr[0] ""
+"\n"
+"Hast du das gemeint?"
+msgstr[1] ""
+"\n"
+"Hast du eines von diesen gemeint?"
+
+#: parse-options.c:493
+msgid "..."
+msgstr "..."
+
+#: parse-options.c:511
+#, c-format
+msgid "usage: %s"
+msgstr "Verwendung: %s"
+
+#. TRANSLATORS: the colon here should align with the
+#. one in "usage: %s" translation
+#: parse-options.c:515
+#, c-format
+msgid " or: %s"
+msgstr " oder: %s"
+
+#: parse-options.c:518
+#, c-format
+msgid " %s"
+msgstr " %s"
+
+#: remote.c:1629
#, c-format
msgid "Your branch is ahead of '%s' by %d commit.\n"
msgid_plural "Your branch is ahead of '%s' by %d commits.\n"
msgstr[0] "Dein Zweig ist vor '%s' um %d Version.\n"
msgstr[1] "Dein Zweig ist vor '%s' um %d Versionen.\n"
-#: remote.c:1613
+#: remote.c:1635
#, c-format
msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
msgid_plural ""
"Dein Zweig ist zu '%s' um %d Versionen hinterher, und kann vorgespult "
"werden.\n"
-#: remote.c:1621
+#: remote.c:1643
#, c-format
msgid ""
"Your branch and '%s' have diverged,\n"
"Dein Zweig und '%s' sind divergiert,\n"
"und haben jeweils %d und %d unterschiedliche Versionen.\n"
-#: sequencer.c:120 builtin/merge.c:865 builtin/merge.c:978
+#: sequencer.c:121 builtin/merge.c:865 builtin/merge.c:978
#: builtin/merge.c:1088 builtin/merge.c:1098
#, c-format
msgid "Could not open '%s' for writing"
msgstr "Konnte '%s' nicht zum Schreiben öffnen."
-#: sequencer.c:122 builtin/merge.c:333 builtin/merge.c:868
+#: sequencer.c:123 builtin/merge.c:333 builtin/merge.c:868
#: builtin/merge.c:1090 builtin/merge.c:1103
#, c-format
msgid "Could not write to '%s'"
msgstr "Konnte nicht nach '%s' schreiben."
-#: sequencer.c:143
+#: sequencer.c:144
msgid ""
"after resolving the conflicts, mark the corrected paths\n"
"with 'git add <paths>' or 'git rm <paths>'"
"nach Auflösung der Konflikte, markiere die korrigierten Pfade\n"
"mit 'git add <Pfade>' oder 'git rm <Pfade>'"
-#: sequencer.c:146
+#: sequencer.c:147
msgid ""
"after resolving the conflicts, mark the corrected paths\n"
"with 'git add <paths>' or 'git rm <paths>'\n"
"mit 'git add <Pfade>' oder 'git rm <Pfade>'und trage das Ergebnis ein mit "
"'git commit'"
-#: sequencer.c:159 sequencer.c:685 sequencer.c:768
+#: sequencer.c:160 sequencer.c:758 sequencer.c:841
#, c-format
msgid "Could not write to %s"
msgstr "Konnte nicht nach %s schreiben"
-#: sequencer.c:162
+#: sequencer.c:163
#, c-format
msgid "Error wrapping up %s"
msgstr "Fehler bei Nachbereitung von %s"
-#: sequencer.c:177
+#: sequencer.c:178
msgid "Your local changes would be overwritten by cherry-pick."
msgstr ""
"Deine lokalen Änderungen würden von \"cherry-pick\" überschrieben werden."
-#: sequencer.c:179
+#: sequencer.c:180
msgid "Your local changes would be overwritten by revert."
msgstr "Deine lokalen Änderungen würden von \"revert\" überschrieben werden."
-#: sequencer.c:182
+#: sequencer.c:183
msgid "Commit your changes or stash them to proceed."
msgstr "Trage deine Änderungen ein oder benutze \"stash\" um fortzufahren."
#. TRANSLATORS: %s will be "revert" or "cherry-pick"
-#: sequencer.c:232
+#: sequencer.c:233
#, c-format
msgid "%s: Unable to write new index file"
msgstr "%s: Konnte neue Bereitstellungsdatei nicht schreiben"
-#: sequencer.c:298
+#: sequencer.c:261
+msgid "Could not resolve HEAD commit\n"
+msgstr "Konnte Version der Zweigspitze (HEAD) nicht auflösen\n"
+
+#: sequencer.c:282
+msgid "Unable to update cache tree\n"
+msgstr "Konnte zwischengespeicherten Baum nicht aktualisieren\n"
+
+#: sequencer.c:324
+#, c-format
+msgid "Could not parse commit %s\n"
+msgstr "Konnte Version %s nicht parsen\n"
+
+#: sequencer.c:329
+#, c-format
+msgid "Could not parse parent commit %s\n"
+msgstr "Konnte Elternversion %s nicht parsen\n"
+
+#: sequencer.c:395
msgid "Your index file is unmerged."
msgstr "Deine Bereitstellungsdatei ist nicht zusammengeführt."
-#: sequencer.c:301
+#: sequencer.c:398
msgid "You do not have a valid HEAD"
msgstr "Du hast keine gültige Zweigspitze (HEAD)"
-#: sequencer.c:316
+#: sequencer.c:413
#, c-format
msgid "Commit %s is a merge but no -m option was given."
msgstr ""
"Version %s ist eine Zusammenführung, aber die Option -m wurde nicht "
"angegeben."
-#: sequencer.c:324
+#: sequencer.c:421
#, c-format
msgid "Commit %s does not have parent %d"
msgstr "Version %s hat keinen Elternteil %d"
-#: sequencer.c:328
+#: sequencer.c:425
#, c-format
msgid "Mainline was specified but commit %s is not a merge."
msgstr ""
#. TRANSLATORS: The first %s will be "revert" or
#. "cherry-pick", the second %s a SHA1
-#: sequencer.c:339
+#: sequencer.c:436
#, c-format
msgid "%s: cannot parse parent commit %s"
msgstr "%s: kann Elternversion %s nicht parsen"
-#: sequencer.c:343
+#: sequencer.c:440
#, c-format
msgid "Cannot get commit message for %s"
msgstr "Kann keine Versionsbeschreibung für %s bekommen"
-#: sequencer.c:427
+#: sequencer.c:524
#, c-format
msgid "could not revert %s... %s"
msgstr "Konnte %s nicht zurücksetzen... %s"
-#: sequencer.c:428
+#: sequencer.c:525
#, c-format
msgid "could not apply %s... %s"
msgstr "Konnte %s nicht anwenden... %s"
-#: sequencer.c:450 sequencer.c:909 builtin/log.c:288 builtin/log.c:713
-#: builtin/log.c:1329 builtin/log.c:1548 builtin/merge.c:347
-#: builtin/shortlog.c:181
-msgid "revision walk setup failed"
-msgstr "Einrichtung des Revisionsgangs fehlgeschlagen"
-
-#: sequencer.c:453
+#: sequencer.c:553
msgid "empty commit set passed"
msgstr "leere Menge von Versionen übergeben"
-#: sequencer.c:461
+#: sequencer.c:561
#, c-format
msgid "git %s: failed to read the index"
msgstr "git %s: Fehler beim Lesen der Bereitstellung"
-#: sequencer.c:466
+#: sequencer.c:566
#, c-format
msgid "git %s: failed to refresh the index"
msgstr "git %s: Fehler beim Aktualisieren der Bereitstellung"
-#: sequencer.c:551
+#: sequencer.c:624
#, c-format
msgid "Cannot %s during a %s"
msgstr "Kann %s nicht während eines %s durchführen"
-#: sequencer.c:573
+#: sequencer.c:646
#, c-format
msgid "Could not parse line %d."
msgstr "Konnte Zeile %d nicht parsen."
-#: sequencer.c:578
+#: sequencer.c:651
msgid "No commits parsed."
msgstr "Keine Versionen geparst."
-#: sequencer.c:591
+#: sequencer.c:664
#, c-format
msgid "Could not open %s"
msgstr "Konnte %s nicht öffnen"
-#: sequencer.c:595
+#: sequencer.c:668
#, c-format
msgid "Could not read %s."
msgstr "Konnte %s nicht lesen."
-#: sequencer.c:602
+#: sequencer.c:675
#, c-format
msgid "Unusable instruction sheet: %s"
msgstr "Unbenutzbares Instruktionsblatt: %s"
-#: sequencer.c:630
+#: sequencer.c:703
#, c-format
msgid "Invalid key: %s"
msgstr "Ungültiger Schlüssel: %s"
-#: sequencer.c:633
+#: sequencer.c:706
#, c-format
msgid "Invalid value for %s: %s"
msgstr "Ungültiger Wert für %s: %s"
-#: sequencer.c:645
+#: sequencer.c:718
#, c-format
msgid "Malformed options sheet: %s"
msgstr "Fehlerhaftes Optionsblatt: %s"
-#: sequencer.c:666
+#: sequencer.c:739
msgid "a cherry-pick or revert is already in progress"
msgstr "\"cherry-pick\" oder \"revert\" ist bereits im Gang"
-#: sequencer.c:667
+#: sequencer.c:740
msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
msgstr "versuche \"git cherry-pick (--continue | --quit | --abort)\""
-#: sequencer.c:671
+#: sequencer.c:744
#, c-format
msgid "Could not create sequencer directory %s"
msgstr "Konnte \"sequencer\"-Verzeichnis %s nicht erstellen"
-#: sequencer.c:687 sequencer.c:772
+#: sequencer.c:760 sequencer.c:845
#, c-format
msgid "Error wrapping up %s."
msgstr "Fehler beim Einpacken von %s."
-#: sequencer.c:706 sequencer.c:840
+#: sequencer.c:779 sequencer.c:913
msgid "no cherry-pick or revert in progress"
msgstr "kein \"cherry-pick\" oder \"revert\" im Gang"
-#: sequencer.c:708
+#: sequencer.c:781
msgid "cannot resolve HEAD"
msgstr "kann Zweigspitze (HEAD) nicht auflösen"
-#: sequencer.c:710
+#: sequencer.c:783
msgid "cannot abort from a branch yet to be born"
msgstr "kann nicht abbrechen: bin auf einem Zweig, der noch geboren wird"
-#: sequencer.c:732
+#: sequencer.c:805 builtin/apply.c:3697
#, c-format
msgid "cannot open %s: %s"
msgstr "Kann %s nicht öffnen: %s"
-#: sequencer.c:735
+#: sequencer.c:808
#, c-format
msgid "cannot read %s: %s"
msgstr "Kann %s nicht lesen: %s"
-#: sequencer.c:736
+#: sequencer.c:809
msgid "unexpected end of file"
msgstr "Unerwartetes Dateiende"
-#: sequencer.c:742
+#: sequencer.c:815
#, c-format
msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
msgstr ""
"gespeicherte \"pre-cherry-pick\" Datei der Zweigspitze (HEAD) '%s' ist "
"beschädigt"
-#: sequencer.c:765
+#: sequencer.c:838
#, c-format
msgid "Could not format %s."
msgstr "Konnte %s nicht formatieren."
-#: sequencer.c:927
+#: sequencer.c:1000
msgid "Can't revert as initial commit"
msgstr "Kann nicht zu initialer Version zurücksetzen."
-#: sequencer.c:928
+#: sequencer.c:1001
msgid "Can't cherry-pick into empty head"
msgstr "Kann \"cherry-pick\" nicht in einem leerem Kopf ausführen."
#: sha1_name.c:872
#, c-format
msgid "Upstream branch '%s' not stored as a remote-tracking branch"
-msgstr "Zweig '%s' des entfernten Projektarchivs ist nicht als entfernter "
-"Übernahmezweig gespeichert"
+msgstr ""
+"Zweig '%s' des entfernten Projektarchivs ist kein gefolgter Übernahmezweig"
+
+#: wrapper.c:413
+#, c-format
+msgid "unable to look up current user in the passwd file: %s"
+msgstr "konnte aktuellen Benutzer nicht in Passwort-Datei finden: %s"
+
+#: wrapper.c:414
+msgid "no such user"
+msgstr "kein solcher Benutzer"
-#: wt-status.c:134
+#: wt-status.c:141
msgid "Unmerged paths:"
msgstr "Nicht zusammengeführte Pfade:"
-#: wt-status.c:140 wt-status.c:157
+#: wt-status.c:168 wt-status.c:195
#, c-format
msgid " (use \"git reset %s <file>...\" to unstage)"
msgstr ""
" (benutze \"git reset %s <Datei>...\" zum Herausnehmen aus der "
"Bereitstellung)"
-#: wt-status.c:142 wt-status.c:159
+#: wt-status.c:170 wt-status.c:197
msgid " (use \"git rm --cached <file>...\" to unstage)"
msgstr ""
" (benutze \"git rm --cached <Datei>...\" zum Herausnehmen aus der "
"Bereitstellung)"
-#: wt-status.c:143
+#: wt-status.c:174
+msgid " (use \"git add <file>...\" to mark resolution)"
+msgstr " (benutze \"git add/rm <Datei>...\" um die Auflösung zu markieren)"
+
+#: wt-status.c:176 wt-status.c:180
msgid " (use \"git add/rm <file>...\" as appropriate to mark resolution)"
msgstr ""
" (benutze \"git add/rm <Datei>...\" um die Auflösung entsprechend zu "
"markieren)"
-#: wt-status.c:151
+#: wt-status.c:178
+msgid " (use \"git rm <file>...\" to mark resolution)"
+msgstr " (benutze \"git add/rm <Datei>...\" um die Auflösung zu markieren)"
+
+#: wt-status.c:189
msgid "Changes to be committed:"
msgstr "zum Eintragen bereitgestellte Änderungen:"
-#: wt-status.c:169
+#: wt-status.c:207
msgid "Changes not staged for commit:"
msgstr "Änderungen, die nicht zum Eintragen bereitgestellt sind:"
-#: wt-status.c:173
+#: wt-status.c:211
msgid " (use \"git add <file>...\" to update what will be committed)"
msgstr " (benutze \"git add <Datei>...\" zum Bereitstellen)"
-#: wt-status.c:175
+#: wt-status.c:213
msgid " (use \"git add/rm <file>...\" to update what will be committed)"
msgstr " (benutze \"git add/rm <Datei>...\" zum Bereitstellen)"
-#: wt-status.c:176
+#: wt-status.c:214
msgid ""
" (use \"git checkout -- <file>...\" to discard changes in working directory)"
msgstr ""
" (benutze \"git checkout -- <Datei>...\" um die Änderungen im "
"Arbeitsverzeichnis zu verwerfen)"
-#: wt-status.c:178
+#: wt-status.c:216
msgid " (commit or discard the untracked or modified content in submodules)"
msgstr ""
" (trage ein oder verwerfe den unbeobachteten oder geänderten Inhalt in den "
"Unterprojekten)"
-#: wt-status.c:187
+#: wt-status.c:225
#, c-format
msgid "%s files:"
msgstr "%s Dateien:"
-#: wt-status.c:190
+#: wt-status.c:228
#, c-format
msgid " (use \"git %s <file>...\" to include in what will be committed)"
msgstr " (benutze \"git %s <Datei>...\" zum Einfügen in die Eintragung)"
-#: wt-status.c:207
+#: wt-status.c:245
msgid "bug"
msgstr "Fehler"
-#: wt-status.c:212
+#: wt-status.c:250
msgid "both deleted:"
msgstr "beide gelöscht:"
-#: wt-status.c:213
+#: wt-status.c:251
msgid "added by us:"
msgstr "von uns hinzugefügt:"
-#: wt-status.c:214
+#: wt-status.c:252
msgid "deleted by them:"
msgstr "von denen gelöscht:"
-#: wt-status.c:215
+#: wt-status.c:253
msgid "added by them:"
msgstr "von denen hinzugefügt:"
-#: wt-status.c:216
+#: wt-status.c:254
msgid "deleted by us:"
msgstr "von uns gelöscht:"
-#: wt-status.c:217
+#: wt-status.c:255
msgid "both added:"
msgstr "von beiden hinzugefügt:"
-#: wt-status.c:218
+#: wt-status.c:256
msgid "both modified:"
msgstr "von beiden geändert:"
-#: wt-status.c:248
+#: wt-status.c:286
msgid "new commits, "
msgstr "neue Versionen, "
-#: wt-status.c:250
+#: wt-status.c:288
msgid "modified content, "
msgstr "geänderter Inhalt, "
-#: wt-status.c:252
+#: wt-status.c:290
msgid "untracked content, "
msgstr "unbeobachteter Inhalt, "
-#: wt-status.c:266
+#: wt-status.c:304
#, c-format
msgid "new file: %s"
msgstr "neue Datei: %s"
-#: wt-status.c:269
+#: wt-status.c:307
#, c-format
msgid "copied: %s -> %s"
msgstr "kopiert: %s -> %s"
-#: wt-status.c:272
+#: wt-status.c:310
#, c-format
msgid "deleted: %s"
msgstr "gelöscht: %s"
-#: wt-status.c:275
+#: wt-status.c:313
#, c-format
msgid "modified: %s"
msgstr "geändert: %s"
-#: wt-status.c:278
+#: wt-status.c:316
#, c-format
msgid "renamed: %s -> %s"
msgstr "umbenannt: %s -> %s"
-#: wt-status.c:281
+#: wt-status.c:319
#, c-format
msgid "typechange: %s"
msgstr "Typänderung: %s"
-#: wt-status.c:284
+#: wt-status.c:322
#, c-format
msgid "unknown: %s"
msgstr "unbekannt: %s"
-#: wt-status.c:287
+#: wt-status.c:325
#, c-format
msgid "unmerged: %s"
msgstr "nicht zusammengeführt: %s"
-#: wt-status.c:290
+#: wt-status.c:328
#, c-format
msgid "bug: unhandled diff status %c"
msgstr "Fehler: unbehandelter Differenz-Status %c"
-#: wt-status.c:713
+#: wt-status.c:786
+msgid "You have unmerged paths."
+msgstr "Du hast nicht zusammengeführte Pfade."
+
+#: wt-status.c:789 wt-status.c:913
+msgid " (fix conflicts and run \"git commit\")"
+msgstr " (behebe die Konflikte und führe \"git commit\" aus)"
+
+#: wt-status.c:792
+msgid "All conflicts fixed but you are still merging."
+msgstr "Alle Konflikte sind behoben, aber du bist immer noch beim "
+"Zusammenführen."
+
+#: wt-status.c:795
+msgid " (use \"git commit\" to conclude merge)"
+msgstr " (benutze \"git commit\" um die Zusammenführung abzuschließen)"
+
+#: wt-status.c:805
+msgid "You are in the middle of an am session."
+msgstr "Eine \"am\"-Sitzung ist im Gange."
+
+#: wt-status.c:808
+msgid "The current patch is empty."
+msgstr "Der aktuelle Patch ist leer."
+
+#: wt-status.c:812
+msgid " (fix conflicts and then run \"git am --resolved\")"
+msgstr " (behebe die Konflikte und führe dann \"git am --resolved\" aus)"
+
+#: wt-status.c:814
+msgid " (use \"git am --skip\" to skip this patch)"
+msgstr " (benutze \"git am --skip\" um diesen Patch auszulassen)"
+
+#: wt-status.c:816
+msgid " (use \"git am --abort\" to restore the original branch)"
+msgstr " (benutze \"git am --abort\" um den ursprünglichen Zweig "
+"wiederherzustellen)"
+
+#: wt-status.c:874 wt-status.c:884
+msgid "You are currently rebasing."
+msgstr "Du bist gerade beim Neuaufbau."
+
+#: wt-status.c:877
+msgid " (fix conflicts and then run \"git rebase --continue\")"
+msgstr " (behebe die Konflikte und führe dann \"git rebase --continue\" aus)"
+
+#: wt-status.c:879
+msgid " (use \"git rebase --skip\" to skip this patch)"
+msgstr " (benutze \"git rebase --skip\" um diesen Patch auszulassen)"
+
+#: wt-status.c:881
+msgid " (use \"git rebase --abort\" to check out the original branch)"
+msgstr " (benutze \"git rebase --abort\" um den ursprünglichen Zweig "
+"auszuchecken)"
+
+#: wt-status.c:887
+msgid " (all conflicts fixed: run \"git rebase --continue\")"
+msgstr " (alle Konflikte behoben: führe \"git rebase --continue\" aus)"
+
+#: wt-status.c:889
+msgid "You are currently splitting a commit during a rebase."
+msgstr "Du teilst gerade eine Version während eines Neuaufbaus auf."
+
+#: wt-status.c:892
+msgid " (Once your working directory is clean, run \"git rebase --continue\")"
+msgstr " (Sobald dein Arbeitsverzeichnis sauber ist, führe "
+"\"git rebase --continue\" aus)"
+
+#: wt-status.c:894
+msgid "You are currently editing a commit during a rebase."
+msgstr "Du editierst gerade eine Version während eines Neuaufbaus."
+
+#: wt-status.c:897
+msgid " (use \"git commit --amend\" to amend the current commit)"
+msgstr " (benutze \"git commit --amend\" um die aktuelle Version "
+"nachzubessern)"
+
+#: wt-status.c:899
+msgid ""
+" (use \"git rebase --continue\" once you are satisfied with your changes)"
+msgstr " (benutze \"git rebase --continue\" sobald deine Änderungen "
+"abgeschlossen sind)"
+
+#: wt-status.c:909
+msgid "You are currently cherry-picking."
+msgstr "Du führst gerade \"cherry-pick\" aus."
+
+#: wt-status.c:916
+msgid " (all conflicts fixed: run \"git commit\")"
+msgstr " (alle Konflikte behoben: führe \"git commit\" aus)"
+
+#: wt-status.c:925
+msgid "You are currently bisecting."
+msgstr "Du bist gerade beim Halbieren."
+
+#: wt-status.c:928
+msgid " (use \"git bisect reset\" to get back to the original branch)"
+msgstr " (benutze \"git bisect reset\" um zum ursprünglichen Zweig "
+"zurückzukehren)"
+
+#: wt-status.c:979
msgid "On branch "
msgstr "Auf Zweig "
-#: wt-status.c:720
+#: wt-status.c:986
msgid "Not currently on any branch."
msgstr "Im Moment auf keinem Zweig."
-#: wt-status.c:731
+#: wt-status.c:998
msgid "Initial commit"
msgstr "Initiale Version"
-#: wt-status.c:745
+#: wt-status.c:1012
msgid "Untracked"
msgstr "Unbeobachtete"
-#: wt-status.c:747
+#: wt-status.c:1014
msgid "Ignored"
msgstr "Ignorierte"
-#: wt-status.c:749
+#: wt-status.c:1016
#, c-format
msgid "Untracked files not listed%s"
msgstr "Unbeobachtete Dateien nicht aufgelistet%s"
-#: wt-status.c:751
+#: wt-status.c:1018
msgid " (use -u option to show untracked files)"
msgstr " (benutze die Option -u um unbeobachteten Dateien anzuzeigen)"
-#: wt-status.c:757
+#: wt-status.c:1024
msgid "No changes"
msgstr "Keine Änderungen"
-#: wt-status.c:761
+#: wt-status.c:1028
#, c-format
msgid "no changes added to commit%s\n"
msgstr "keine Änderungen zum Eintragen hinzugefügt%s\n"
-#: wt-status.c:763
+#: wt-status.c:1030
msgid " (use \"git add\" and/or \"git commit -a\")"
msgstr " (benutze \"git add\" und/oder \"git commit -a\")"
-#: wt-status.c:765
+#: wt-status.c:1032
#, c-format
msgid "nothing added to commit but untracked files present%s\n"
msgstr ""
"nichts zum Eintragen hinzugefügt, aber es gibt unbeobachtete Dateien%s\n"
-#: wt-status.c:767
+#: wt-status.c:1034
msgid " (use \"git add\" to track)"
msgstr " (benutze \"git add\" zum Beobachten)"
-#: wt-status.c:769 wt-status.c:772 wt-status.c:775
+#: wt-status.c:1036 wt-status.c:1039 wt-status.c:1042
#, c-format
msgid "nothing to commit%s\n"
msgstr "nichts zum Eintragen%s\n"
-#: wt-status.c:770
+#: wt-status.c:1037
msgid " (create/copy files and use \"git add\" to track)"
msgstr " (Erstelle/Kopiere Dateien und benutze \"git add\" zum Beobachten)"
-#: wt-status.c:773
+#: wt-status.c:1040
msgid " (use -u to show untracked files)"
msgstr " (benutze die Option -u um unbeobachtete Dateien anzuzeigen)"
-#: wt-status.c:776
+#: wt-status.c:1043
msgid " (working directory clean)"
msgstr " (Arbeitsverzeichnis sauber)"
-#: wt-status.c:884
+#: wt-status.c:1151
msgid "HEAD (no branch)"
msgstr "HEAD (kein Zweig)"
-#: wt-status.c:890
+#: wt-status.c:1157
msgid "Initial commit on "
msgstr "Initiale Version auf "
-#: wt-status.c:905
+#: wt-status.c:1172
msgid "behind "
msgstr "hinterher "
-#: wt-status.c:908 wt-status.c:911
+#: wt-status.c:1175 wt-status.c:1178
msgid "ahead "
msgstr "voraus "
-#: wt-status.c:913
+#: wt-status.c:1180
msgid ", behind "
msgstr ", hinterher "
msgid "unexpected diff status %c"
msgstr "unerwarteter Differenz-Status %c"
-#: builtin/add.c:67 builtin/commit.c:298
+#: builtin/add.c:67 builtin/commit.c:226
msgid "updating files failed"
msgstr "Aktualisierung der Dateien fehlgeschlagen"
msgstr ""
"Nicht bereitgestellte Änderungen nach Aktualisierung der Bereitstellung:"
-#: builtin/add.c:195 builtin/add.c:456 builtin/rm.c:186
+#: builtin/add.c:195 builtin/add.c:459 builtin/rm.c:186
#, c-format
msgid "pathspec '%s' did not match any files"
msgstr "Pfadspezifikation '%s' stimmt mit keinen Dateien überein"
msgid "Maybe you wanted to say 'git add .'?\n"
msgstr "Wolltest du vielleicht 'git add .' sagen?\n"
-#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:358 builtin/mv.c:82
+#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:286 builtin/mv.c:82
#: builtin/rm.c:162
msgid "index file corrupt"
msgstr "Bereitstellungsdatei beschädigt"
-#: builtin/add.c:476 builtin/mv.c:229 builtin/rm.c:260
+#: builtin/add.c:480 builtin/apply.c:4108 builtin/mv.c:229 builtin/rm.c:260
msgid "Unable to write new index file"
msgstr "Konnte neue Bereitstellungsdatei nicht schreiben."
-#: builtin/archive.c:17
-#, c-format
-msgid "could not create archive file '%s'"
-msgstr "Konnte Archiv-Datei '%s' nicht erstellen."
-
-#: builtin/archive.c:20
-msgid "could not redirect output"
-msgstr "Konnte Ausgabe nicht umleiten."
-
-#: builtin/archive.c:37
-msgid "git archive: Remote with no URL"
-msgstr "git archive: Externes Archiv ohne URL"
+#: builtin/apply.c:53
+msgid "git apply [options] [<patch>...]"
+msgstr "git apply [Optionen] [<Patch>...]"
-#: builtin/archive.c:58
-msgid "git archive: expected ACK/NAK, got EOF"
-msgstr "git archive: habe ACK/NAK erwartet, aber EOF bekommen"
+#: builtin/apply.c:106
+#, c-format
+msgid "unrecognized whitespace option '%s'"
+msgstr "nicht erkannte Option für Leerzeichen: '%s'"
-#: builtin/archive.c:63
+#: builtin/apply.c:121
#, c-format
-msgid "git archive: NACK %s"
-msgstr "git archive: NACK %s"
+msgid "unrecognized whitespace ignore option '%s'"
+msgstr "nicht erkannte Option zum Ignorieren von Leerzeichen: '%s'"
-#: builtin/archive.c:65
+#: builtin/apply.c:815
#, c-format
-msgid "remote error: %s"
-msgstr "Fehler am anderen Ende: %s"
+msgid "Cannot prepare timestamp regexp %s"
+msgstr "Kann regulären Ausdruck für Zeitstempel %s nicht verarbeiten"
-#: builtin/archive.c:66
-msgid "git archive: protocol error"
-msgstr "git archive: Protokollfehler"
+#: builtin/apply.c:824
+#, c-format
+msgid "regexec returned %d for input: %s"
+msgstr "Ausführung des regulären Ausdrucks gab %d zurück. Eingabe: %s"
-#: builtin/archive.c:71
-msgid "git archive: expected a flush"
-msgstr "git archive: erwartete eine Spülung (flush)"
+#: builtin/apply.c:905
+#, c-format
+msgid "unable to find filename in patch at line %d"
+msgstr "Konnte keinen Dateinamen in Zeile %d des Patches finden."
-#: builtin/branch.c:137
+#: builtin/apply.c:937
#, c-format
-msgid ""
-"deleting branch '%s' that has been merged to\n"
-" '%s', but not yet merged to HEAD."
+msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
msgstr ""
-"entferne Zweig '%s', der zusammengeführt wurde mit\n"
-" '%s', aber noch nicht mit der Zweigspitze (HEAD) zusammengeführt "
-"wurde."
+"git apply: ungültiges 'git-diff' - erwartete /dev/null, erhielt %s in Zeile "
+"%d"
-#: builtin/branch.c:141
+#: builtin/apply.c:941
#, c-format
-msgid ""
-"not deleting branch '%s' that is not yet merged to\n"
-" '%s', even though it is merged to HEAD."
+msgid "git apply: bad git-diff - inconsistent new filename on line %d"
msgstr ""
-"entferne Zweig '%s' nicht, der noch nicht zusammengeführt wurde mit\n"
-" '%s', obwohl er mit der Zweigspitze (HEAD) zusammengeführt wurde."
+"git apply: ungültiges 'git-diff' - Inkonsistenter neuer Dateiname in Zeile %d"
-#. TRANSLATORS: This is "remote " in "remote branch '%s' not found"
-#: builtin/branch.c:164
-msgid "remote "
-msgstr "externer "
+#: builtin/apply.c:942
+#, c-format
+msgid "git apply: bad git-diff - inconsistent old filename on line %d"
+msgstr ""
+"git apply: ungültiges 'git-diff' - Inkonsistenter alter Dateiname in Zeile %d"
-#: builtin/branch.c:172
-msgid "cannot use -a with -d"
-msgstr "kann -a nicht mit -d benutzen"
+#: builtin/apply.c:949
+#, c-format
+msgid "git apply: bad git-diff - expected /dev/null on line %d"
+msgstr "git apply: ungültiges 'git-diff' - erwartete /dev/null in Zeile %d"
-#: builtin/branch.c:178
-msgid "Couldn't look up commit object for HEAD"
-msgstr "Konnte Versionsobjekt für Zweigspitze (HEAD) nicht nachschlagen."
+#: builtin/apply.c:1394
+#, c-format
+msgid "recount: unexpected line: %.*s"
+msgstr "recount: unerwartete Zeile: %.*s"
-#: builtin/branch.c:183
+#: builtin/apply.c:1451
#, c-format
-msgid "Cannot delete the branch '%s' which you are currently on."
-msgstr ""
-"Kann Zweig '%s' nicht entfernen, da du dich gerade auf diesem befindest."
+msgid "patch fragment without header at line %d: %.*s"
+msgstr "Patch-Fragment ohne Kopfbereich bei Zeile %d: %.*s"
-#: builtin/branch.c:193
+#: builtin/apply.c:1468
#, c-format
-msgid "%sbranch '%s' not found."
-msgstr "%sZweig '%s' nicht gefunden."
+msgid ""
+"git diff header lacks filename information when removing %d leading pathname "
+"component (line %d)"
+msgid_plural ""
+"git diff header lacks filename information when removing %d leading pathname "
+"components (line %d)"
+msgstr[0] ""
+"Dem Kopfbereich von \"git diff\" fehlen Informationen zum Dateinamen, wenn "
+"%d vorangestellter Teil des Pfades entfernt wird (Zeile %d)"
+msgstr[1] ""
+"Dem Kopfbereich von \"git diff\" fehlen Informationen zum Dateinamen, wenn "
+"%d vorangestellte Teile des Pfades entfernt werden (Zeile %d)"
-#: builtin/branch.c:201
+#: builtin/apply.c:1628
+msgid "new file depends on old contents"
+msgstr "neue Datei hängt von alten Inhalten ab"
+
+#: builtin/apply.c:1630
+msgid "deleted file still has contents"
+msgstr "entfernte Datei hat noch Inhalte"
+
+#: builtin/apply.c:1656
#, c-format
-msgid "Couldn't look up commit object for '%s'"
-msgstr "Konnte Versionsobjekt für '%s' nicht nachschlagen."
+msgid "corrupt patch at line %d"
+msgstr "fehlerhafter Patch bei Zeile %d"
-#: builtin/branch.c:207
+#: builtin/apply.c:1692
#, c-format
-msgid ""
-"The branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'."
-msgstr ""
-"Der Zweig '%s' ist nicht vollständig zusammengeführt.\n"
-"Wenn du sicher bist diesen Zweig zu entfernen, führe 'git branch -D %s' aus."
+msgid "new file %s depends on old contents"
+msgstr "neue Datei %s hängt von alten Inhalten ab"
-#: builtin/branch.c:215
+#: builtin/apply.c:1694
#, c-format
-msgid "Error deleting %sbranch '%s'"
-msgstr "Fehler beim Löschen von %sZweig '%s'"
+msgid "deleted file %s still has contents"
+msgstr "entfernte Datei %s hat noch Inhalte"
-#: builtin/branch.c:221
+#: builtin/apply.c:1697
#, c-format
-msgid "Deleted %sbranch %s (was %s).\n"
-msgstr "Entferne %sZweig %s (war %s).\n"
+msgid "** warning: file %s becomes empty but is not deleted"
+msgstr "** Warnung: Datei %s wird leer, aber nicht entfernt."
-#: builtin/branch.c:226
-msgid "Update of config-file failed"
-msgstr "Aktualisierung der Konfigurationsdatei fehlgeschlagen."
+#: builtin/apply.c:1843
+#, c-format
+msgid "corrupt binary patch at line %d: %.*s"
+msgstr "fehlerhafter Binär-Patch bei Zeile %d: %.*s"
-#: builtin/branch.c:324
+#. there has to be one hunk (forward hunk)
+#: builtin/apply.c:1872
#, c-format
-msgid "branch '%s' does not point at a commit"
-msgstr "Zweig '%s' zeigt auf keine Version"
+msgid "unrecognized binary patch at line %d"
+msgstr "nicht erkannter Binär-Patch bei Zeile %d"
-#: builtin/branch.c:396
+#: builtin/apply.c:1958
#, c-format
-msgid "behind %d] "
-msgstr "%d hinterher] "
+msgid "patch with only garbage at line %d"
+msgstr "Patch mit nutzlosen Informationen bei Zeile %d"
-#: builtin/branch.c:398
+#: builtin/apply.c:2048
#, c-format
-msgid "ahead %d] "
-msgstr "%d voraus] "
+msgid "unable to read symlink %s"
+msgstr "konnte symbolische Verknüpfung %s nicht lesen"
-#: builtin/branch.c:400
+#: builtin/apply.c:2052
#, c-format
-msgid "ahead %d, behind %d] "
-msgstr "%d voraus, %d hinterher] "
+msgid "unable to open or read %s"
+msgstr "konnte %s nicht öffnen oder lesen"
-#: builtin/branch.c:503
-msgid "(no branch)"
-msgstr "(kein Zweig)"
+#: builtin/apply.c:2123
+msgid "oops"
+msgstr "Ups"
-#: builtin/branch.c:568
-msgid "some refs could not be read"
-msgstr "Konnte einige Referenzen nicht lesen"
+#: builtin/apply.c:2645
+#, c-format
+msgid "invalid start of line: '%c'"
+msgstr "Ungültiger Zeilenanfang: '%c'"
-#: builtin/branch.c:581
-msgid "cannot rename the current branch while not on any."
-msgstr ""
-"Kann aktuellen Zweig nicht umbennen, solange du dich auf keinem befindest."
+#: builtin/apply.c:2763
+#, c-format
+msgid "Hunk #%d succeeded at %d (offset %d line)."
+msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
+msgstr[0] "Patch-Bereich #%d erfolgreich angewendet bei %d (%d Zeile versetzt)"
+msgstr[1] ""
+"Patch-Bereich #%d erfolgreich angewendet bei %d (%d Zeilen versetzt)"
-#: builtin/branch.c:591
+#: builtin/apply.c:2775
#, c-format
-msgid "Invalid branch name: '%s'"
-msgstr "Ungültiger Zweig-Name: '%s'"
+msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
+msgstr "Kontext reduziert zu (%ld/%ld) um Patch-Bereich bei %d anzuwenden"
-#: builtin/branch.c:606
-msgid "Branch rename failed"
-msgstr "Umbenennung des Zweiges fehlgeschlagen"
+#: builtin/apply.c:2781
+#, c-format
+msgid ""
+"while searching for:\n"
+"%.*s"
+msgstr ""
+"bei der Suche nach:\n"
+"%.*s"
-#: builtin/branch.c:610
+#: builtin/apply.c:2800
#, c-format
-msgid "Renamed a misnamed branch '%s' away"
-msgstr "falsch benannten Zweig '%s' umbenannt"
+msgid "missing binary patch data for '%s'"
+msgstr "keine Daten in Binär-Patch für '%s'"
-#: builtin/branch.c:614
+#: builtin/apply.c:2903
#, c-format
-msgid "Branch renamed to %s, but HEAD is not updated!"
-msgstr "Zweig umbenannt zu %s, aber Zweigspitze (HEAD) ist nicht aktualisiert!"
+msgid "binary patch does not apply to '%s'"
+msgstr "Konnte Binär-Patch nicht auf '%s' anwenden"
-#: builtin/branch.c:621
-msgid "Branch is renamed, but update of config-file failed"
+#: builtin/apply.c:2909
+#, c-format
+msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
msgstr ""
-"Zweig ist umbenannt, aber die Aktualisierung der Konfigurationsdatei ist "
-"fehlgeschlagen."
+"Binär-Patch für '%s' erzeugt falsches Ergebnis (erwartete %s, bekam %s)"
-#: builtin/branch.c:636
+#: builtin/apply.c:2930
#, c-format
-msgid "malformed object name %s"
-msgstr "Missgebildeter Objektname %s"
+msgid "patch failed: %s:%ld"
+msgstr "Anwendung des Patches fehlgeschlagen: %s:%ld"
-#: builtin/branch.c:660
+#: builtin/apply.c:3045
#, c-format
-msgid "could not write branch description template: %s\n"
-msgstr "Konnte Beschreibungsvorlage für Zweig nicht schreiben: %s\n"
+msgid "patch %s has been renamed/deleted"
+msgstr "Patch %s wurde umbenannt/gelöscht"
-#: builtin/branch.c:750
-msgid "Failed to resolve HEAD as a valid ref."
-msgstr "Konnte Zweigspitze (HEAD) nicht als gültige Referenz auflösen."
+#: builtin/apply.c:3052 builtin/apply.c:3069
+#, c-format
+msgid "read of %s failed"
+msgstr "Konnte %s nicht lesen"
-#: builtin/branch.c:755 builtin/clone.c:558
-msgid "HEAD not found below refs/heads!"
-msgstr "Zweigspitze (HEAD) wurde nicht unter \"refs/heads\" gefunden!"
+#: builtin/apply.c:3084
+msgid "removal patch leaves file contents"
+msgstr "Lösch-Patch hinterlässt Dateiinhalte"
-#: builtin/branch.c:813
-msgid "-a and -r options to 'git branch' do not make sense with a branch name"
-msgstr ""
-"Die Optionen -a und -r bei 'git branch' machen mit einem Zweignamen keinen "
-"Sinn."
+#: builtin/apply.c:3105
+#, c-format
+msgid "%s: already exists in working directory"
+msgstr "%s existiert bereits im Arbeitsverzeichnis"
-#: builtin/bundle.c:47
+#: builtin/apply.c:3143
#, c-format
-msgid "%s is okay\n"
-msgstr "%s ist in Ordnung\n"
+msgid "%s: has been deleted/renamed"
+msgstr "%s wurde gelöscht/umbenannt"
-#: builtin/bundle.c:56
-msgid "Need a repository to create a bundle."
-msgstr "Um ein Paket zu erstellen wird ein Projektarchiv benötigt."
+#: builtin/apply.c:3148 builtin/apply.c:3179
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
-#: builtin/bundle.c:60
-msgid "Need a repository to unbundle."
-msgstr "Zum Entpacken wird ein Projektarchiv benötigt."
+#: builtin/apply.c:3159
+#, c-format
+msgid "%s: does not exist in index"
+msgstr "%s ist nicht bereitgestellt"
+
+#: builtin/apply.c:3173
+#, c-format
+msgid "%s: does not match index"
+msgstr "%s entspricht nicht der Bereitstellung"
+
+#: builtin/apply.c:3190
+#, c-format
+msgid "%s: wrong type"
+msgstr "%s: falscher Typ"
+
+#: builtin/apply.c:3192
+#, c-format
+msgid "%s has type %o, expected %o"
+msgstr "%s ist vom Typ %o, erwartete %o"
+
+#: builtin/apply.c:3247
+#, c-format
+msgid "%s: already exists in index"
+msgstr "%s ist bereits bereitgestellt"
+
+#: builtin/apply.c:3267
+#, c-format
+msgid "new mode (%o) of %s does not match old mode (%o)"
+msgstr "neuer Modus (%o) von %s entspricht nicht dem alten Modus (%o)"
+
+#: builtin/apply.c:3272
+#, c-format
+msgid "new mode (%o) of %s does not match old mode (%o) of %s"
+msgstr "neuer Modus (%o) von %s entspricht nicht dem alten Modus (%o) von %s"
+
+#: builtin/apply.c:3280
+#, c-format
+msgid "%s: patch does not apply"
+msgstr "%s: Patch konnte nicht angewendet werden"
+
+#: builtin/apply.c:3293
+#, c-format
+msgid "Checking patch %s..."
+msgstr "Prüfe Patch %s..."
+
+#: builtin/apply.c:3348 builtin/checkout.c:212 builtin/reset.c:158
+#, c-format
+msgid "make_cache_entry failed for path '%s'"
+msgstr "make_cache_entry für Pfad '%s' fehlgeschlagen"
+
+#: builtin/apply.c:3491
+#, c-format
+msgid "unable to remove %s from index"
+msgstr "konnte %s nicht aus der Bereitstellung entfernen"
+
+#: builtin/apply.c:3518
+#, c-format
+msgid "corrupt patch for subproject %s"
+msgstr "fehlerhafter Patch für Unterprojekt %s"
+
+#: builtin/apply.c:3522
+#, c-format
+msgid "unable to stat newly created file '%s'"
+msgstr "konnte neu erstellte Datei '%s' nicht lesen"
+
+#: builtin/apply.c:3527
+#, c-format
+msgid "unable to create backing store for newly created file %s"
+msgstr "kann internen Speicher für eben erstellte Datei %s nicht erzeugen"
+
+#: builtin/apply.c:3530
+#, c-format
+msgid "unable to add cache entry for %s"
+msgstr "kann für %s keinen Eintrag in den Zwischenspeicher hinzufügen"
+
+#: builtin/apply.c:3563
+#, c-format
+msgid "closing file '%s'"
+msgstr "schließe Datei '%s'"
+
+#: builtin/apply.c:3612
+#, c-format
+msgid "unable to write file '%s' mode %o"
+msgstr "konnte Datei '%s' mit Modus %o nicht schreiben"
+
+#: builtin/apply.c:3668
+#, c-format
+msgid "Applied patch %s cleanly."
+msgstr "Patch %s sauber angewendet"
+
+#: builtin/apply.c:3676
+msgid "internal error"
+msgstr "interner Fehler"
+
+#. Say this even without --verbose
+#: builtin/apply.c:3679
+#, c-format
+msgid "Applying patch %%s with %d reject..."
+msgid_plural "Applying patch %%s with %d rejects..."
+msgstr[0] "Wende Patch %%s mit %d Zurückweisung an..."
+msgstr[1] "Wende Patch %%s mit %d Zurückweisungen an..."
+
+#: builtin/apply.c:3689
+#, c-format
+msgid "truncating .rej filename to %.*s.rej"
+msgstr "Verkürze Name von .rej Datei zu %.*s.rej"
+
+#: builtin/apply.c:3710
+#, c-format
+msgid "Hunk #%d applied cleanly."
+msgstr "Patch-Bereich #%d sauber angewendet."
+
+#: builtin/apply.c:3713
+#, c-format
+msgid "Rejected hunk #%d."
+msgstr "Patch-Bereich #%d zurückgewiesen."
+
+#: builtin/apply.c:3844
+msgid "unrecognized input"
+msgstr "nicht erkannte Eingabe"
+
+#: builtin/apply.c:3855
+msgid "unable to read index file"
+msgstr "Konnte Bereitstellungsdatei nicht lesen"
+
+#: builtin/apply.c:3970 builtin/apply.c:3973
+msgid "path"
+msgstr "Pfad"
+
+#: builtin/apply.c:3971
+msgid "don't apply changes matching the given path"
+msgstr "wendet keine Änderungen im angegebenen Pfad an"
+
+#: builtin/apply.c:3974
+msgid "apply changes matching the given path"
+msgstr "wendet Änderungen nur im angegebenen Pfad an"
+
+#: builtin/apply.c:3976
+msgid "num"
+msgstr "Anzahl"
+
+#: builtin/apply.c:3977
+msgid "remove <num> leading slashes from traditional diff paths"
+msgstr ""
+"entfernt <Anzahl> vorrangestellte Schrägstriche von herkömmlichen "
+"Differenzpfaden"
+
+#: builtin/apply.c:3980
+msgid "ignore additions made by the patch"
+msgstr "ignoriert hinzugefügte Zeilen des Patches"
+
+#: builtin/apply.c:3982
+msgid "instead of applying the patch, output diffstat for the input"
+msgstr ""
+"anstatt der Anwendung des Patches, wird der \"diffstat\" für die Eingabe "
+"ausgegeben"
+
+#: builtin/apply.c:3986
+msgid "shows number of added and deleted lines in decimal notation"
+msgstr ""
+"zeigt die Anzahl von hinzugefügten/entfernten Zeilen in Dezimalnotation"
+
+#: builtin/apply.c:3988
+msgid "instead of applying the patch, output a summary for the input"
+msgstr ""
+"anstatt der Anwendung des Patches, wird eine Zusammenfassung für die Eingabe "
+"ausgegeben"
+
+#: builtin/apply.c:3990
+msgid "instead of applying the patch, see if the patch is applicable"
+msgstr ""
+"anstatt der Anwendung des Patches, zeige ob Patch angewendet werden kann"
+
+#: builtin/apply.c:3992
+msgid "make sure the patch is applicable to the current index"
+msgstr ""
+"stellt sicher, dass der Patch in der aktuellen Bereitstellung angewendet "
+"werden kann"
+
+#: builtin/apply.c:3994
+msgid "apply a patch without touching the working tree"
+msgstr "wendet einen Patch an, ohne Änderungen im Arbeitszweig vorzunehmen"
+
+#: builtin/apply.c:3996
+msgid "also apply the patch (use with --stat/--summary/--check)"
+msgstr "wendet den Patch an (Benutzung mit --stat/--summary/--check)"
+
+#: builtin/apply.c:3998
+msgid "build a temporary index based on embedded index information"
+msgstr ""
+"erstellt eine temporäre Bereitstellung basierend auf den integrierten "
+"Bereitstellungsinformationen"
+
+#: builtin/apply.c:4000
+msgid "paths are separated with NUL character"
+msgstr "Pfade sind getrennt durch NUL Zeichen"
+
+#: builtin/apply.c:4003
+msgid "ensure at least <n> lines of context match"
+msgstr ""
+"stellt sicher, dass mindestens <Anzahl> Zeilen des Kontextes übereinstimmen"
+
+#: builtin/apply.c:4004
+msgid "action"
+msgstr "Aktion"
+
+#: builtin/apply.c:4005
+msgid "detect new or modified lines that have whitespace errors"
+msgstr "ermittelt neue oder geänderte Zeilen die Fehler in Leerzeichen haben"
+
+#: builtin/apply.c:4008 builtin/apply.c:4011
+msgid "ignore changes in whitespace when finding context"
+msgstr "ignoriert Änderungen in Leerzeichen bei der Suche des Kontextes"
+
+#: builtin/apply.c:4014
+msgid "apply the patch in reverse"
+msgstr "wendet den Patch in umgekehrter Reihenfolge an"
+
+#: builtin/apply.c:4016
+msgid "don't expect at least one line of context"
+msgstr "erwartet keinen Kontext"
+
+#: builtin/apply.c:4018
+msgid "leave the rejected hunks in corresponding *.rej files"
+msgstr ""
+"hinterlässt zurückgewiesene Patch-Bereiche in den entsprechenden *.rej "
+"Dateien"
+
+#: builtin/apply.c:4020
+msgid "allow overlapping hunks"
+msgstr "erlaubt sich überlappende Patch-Bereiche"
+
+#: builtin/apply.c:4021
+msgid "be verbose"
+msgstr "erweiterte Ausgaben"
+
+#: builtin/apply.c:4023
+msgid "tolerate incorrectly detected missing new-line at the end of file"
+msgstr "toleriert fehlerhaft erkannten fehlenden Zeilenumbruch am Dateiende"
+
+#: builtin/apply.c:4026
+msgid "do not trust the line counts in the hunk headers"
+msgstr "vertraut nicht den Zeilennummern im Kopf des Patch-Bereiches"
+
+#: builtin/apply.c:4028
+msgid "root"
+msgstr "Wurzelverzeichnis"
+
+#: builtin/apply.c:4029
+msgid "prepend <root> to all filenames"
+msgstr "stellt <Wurzelverzeichnis> vor alle Dateinamen"
+
+#: builtin/apply.c:4050
+msgid "--index outside a repository"
+msgstr "--index außerhalb eines Projektarchivs"
+
+#: builtin/apply.c:4053
+msgid "--cached outside a repository"
+msgstr "--cached außerhalb eines Projektarchivs"
+
+#: builtin/apply.c:4069
+#, c-format
+msgid "can't open patch '%s'"
+msgstr "kann Patch '%s' nicht öffnen"
+
+#: builtin/apply.c:4083
+#, c-format
+msgid "squelched %d whitespace error"
+msgid_plural "squelched %d whitespace errors"
+msgstr[0] "unterdrückte %d Fehler in Leerzeichen"
+msgstr[1] "unterdrückte %d Fehler in Leerzeichen"
+
+#: builtin/apply.c:4089 builtin/apply.c:4099
+#, c-format
+msgid "%d line adds whitespace errors."
+msgid_plural "%d lines add whitespace errors."
+msgstr[0] "%d Zeile fügt Fehler in Leerzeichen hinzu."
+msgstr[1] "%d Zeilen fügen Fehler in Leerzeichen hinzu."
+
+#: builtin/archive.c:17
+#, c-format
+msgid "could not create archive file '%s'"
+msgstr "Konnte Archiv-Datei '%s' nicht erstellen."
+
+#: builtin/archive.c:20
+msgid "could not redirect output"
+msgstr "Konnte Ausgabe nicht umleiten."
+
+#: builtin/archive.c:37
+msgid "git archive: Remote with no URL"
+msgstr "git archive: Externes Archiv ohne URL"
+
+#: builtin/archive.c:58
+msgid "git archive: expected ACK/NAK, got EOF"
+msgstr "git archive: habe ACK/NAK erwartet, aber EOF bekommen"
+
+#: builtin/archive.c:63
+#, c-format
+msgid "git archive: NACK %s"
+msgstr "git archive: NACK %s"
+
+#: builtin/archive.c:65
+#, c-format
+msgid "remote error: %s"
+msgstr "Fehler am anderen Ende: %s"
+
+#: builtin/archive.c:66
+msgid "git archive: protocol error"
+msgstr "git archive: Protokollfehler"
+
+#: builtin/archive.c:71
+msgid "git archive: expected a flush"
+msgstr "git archive: erwartete eine Spülung (flush)"
+
+#: builtin/branch.c:144
+#, c-format
+msgid ""
+"deleting branch '%s' that has been merged to\n"
+" '%s', but not yet merged to HEAD."
+msgstr ""
+"entferne Zweig '%s', der zusammengeführt wurde mit\n"
+" '%s', aber noch nicht mit der Zweigspitze (HEAD) zusammengeführt "
+"wurde."
+
+#: builtin/branch.c:148
+#, c-format
+msgid ""
+"not deleting branch '%s' that is not yet merged to\n"
+" '%s', even though it is merged to HEAD."
+msgstr ""
+"entferne Zweig '%s' nicht, der noch nicht zusammengeführt wurde mit\n"
+" '%s', obwohl er mit der Zweigspitze (HEAD) zusammengeführt wurde."
+
+#: builtin/branch.c:180
+msgid "cannot use -a with -d"
+msgstr "kann -a nicht mit -d benutzen"
+
+#: builtin/branch.c:186
+msgid "Couldn't look up commit object for HEAD"
+msgstr "Konnte Versionsobjekt für Zweigspitze (HEAD) nicht nachschlagen."
+
+#: builtin/branch.c:191
+#, c-format
+msgid "Cannot delete the branch '%s' which you are currently on."
+msgstr ""
+"Kann Zweig '%s' nicht entfernen, da du dich gerade auf diesem befindest."
+
+#: builtin/branch.c:202
+#, c-format
+msgid "remote branch '%s' not found."
+msgstr "externer Zweig '%s' nicht gefunden"
+
+#: builtin/branch.c:203
+#, c-format
+msgid "branch '%s' not found."
+msgstr "Zweig '%s' nicht gefunden."
+
+#: builtin/branch.c:210
+#, c-format
+msgid "Couldn't look up commit object for '%s'"
+msgstr "Konnte Versionsobjekt für '%s' nicht nachschlagen."
+
+#: builtin/branch.c:216
+#, c-format
+msgid ""
+"The branch '%s' is not fully merged.\n"
+"If you are sure you want to delete it, run 'git branch -D %s'."
+msgstr ""
+"Der Zweig '%s' ist nicht vollständig zusammengeführt.\n"
+"Wenn du sicher bist diesen Zweig zu entfernen, führe 'git branch -D %s' aus."
+
+#: builtin/branch.c:225
+#, c-format
+msgid "Error deleting remote branch '%s'"
+msgstr "Fehler beim Entfernen des externen Zweiges '%s'"
+
+#: builtin/branch.c:226
+#, c-format
+msgid "Error deleting branch '%s'"
+msgstr "Fehler beim Entfernen des Zweiges '%s'"
+
+#: builtin/branch.c:233
+#, c-format
+msgid "Deleted remote branch %s (was %s).\n"
+msgstr "Externer Zweig %s entfernt (war %s).\n"
+
+#: builtin/branch.c:234
+#, c-format
+msgid "Deleted branch %s (was %s).\n"
+msgstr "Zweig %s entfernt (war %s).\n"
+
+#: builtin/branch.c:239
+msgid "Update of config-file failed"
+msgstr "Aktualisierung der Konfigurationsdatei fehlgeschlagen."
+
+#: builtin/branch.c:337
+#, c-format
+msgid "branch '%s' does not point at a commit"
+msgstr "Zweig '%s' zeigt auf keine Version"
+
+#: builtin/branch.c:409
+#, c-format
+msgid "[%s: behind %d]"
+msgstr "[%s: %d hinterher]"
+
+#: builtin/branch.c:411
+#, c-format
+msgid "[behind %d]"
+msgstr "[%d hinterher]"
+
+#: builtin/branch.c:415
+#, c-format
+msgid "[%s: ahead %d]"
+msgstr "[%s: %d voraus]"
+
+#: builtin/branch.c:417
+#, c-format
+msgid "[ahead %d]"
+msgstr "[%d voraus]"
+
+#: builtin/branch.c:420
+#, c-format
+msgid "[%s: ahead %d, behind %d]"
+msgstr "[%s: %d voraus, %d hinterher]"
+
+#: builtin/branch.c:423
+#, c-format
+msgid "[ahead %d, behind %d]"
+msgstr "[%d voraus, %d hinterher]"
+
+#: builtin/branch.c:535
+msgid "(no branch)"
+msgstr "(kein Zweig)"
+
+#: builtin/branch.c:600
+msgid "some refs could not be read"
+msgstr "Konnte einige Referenzen nicht lesen"
+
+#: builtin/branch.c:613
+msgid "cannot rename the current branch while not on any."
+msgstr ""
+"Kann aktuellen Zweig nicht umbennen, solange du dich auf keinem befindest."
+
+#: builtin/branch.c:623
+#, c-format
+msgid "Invalid branch name: '%s'"
+msgstr "Ungültiger Zweig-Name: '%s'"
+
+#: builtin/branch.c:638
+msgid "Branch rename failed"
+msgstr "Umbenennung des Zweiges fehlgeschlagen"
+
+#: builtin/branch.c:642
+#, c-format
+msgid "Renamed a misnamed branch '%s' away"
+msgstr "falsch benannten Zweig '%s' umbenannt"
+
+#: builtin/branch.c:646
+#, c-format
+msgid "Branch renamed to %s, but HEAD is not updated!"
+msgstr "Zweig umbenannt zu %s, aber Zweigspitze (HEAD) ist nicht aktualisiert!"
+
+#: builtin/branch.c:653
+msgid "Branch is renamed, but update of config-file failed"
+msgstr ""
+"Zweig ist umbenannt, aber die Aktualisierung der Konfigurationsdatei ist "
+"fehlgeschlagen."
+
+#: builtin/branch.c:668
+#, c-format
+msgid "malformed object name %s"
+msgstr "Missgebildeter Objektname %s"
+
+#: builtin/branch.c:692
+#, c-format
+msgid "could not write branch description template: %s"
+msgstr "Konnte Beschreibungsvorlage für Zweig nicht schreiben: %s"
+
+#: builtin/branch.c:783
+msgid "Failed to resolve HEAD as a valid ref."
+msgstr "Konnte Zweigspitze (HEAD) nicht als gültige Referenz auflösen."
+
+#: builtin/branch.c:788 builtin/clone.c:558
+msgid "HEAD not found below refs/heads!"
+msgstr "Zweigspitze (HEAD) wurde nicht unter \"refs/heads\" gefunden!"
+
+#: builtin/branch.c:808
+msgid "--column and --verbose are incompatible"
+msgstr "--column und --verbose sind inkompatibel"
+
+#: builtin/branch.c:857
+msgid "-a and -r options to 'git branch' do not make sense with a branch name"
+msgstr ""
+"Die Optionen -a und -r bei 'git branch' machen mit einem Zweignamen keinen "
+"Sinn."
+
+#: builtin/bundle.c:47
+#, c-format
+msgid "%s is okay\n"
+msgstr "%s ist in Ordnung\n"
+
+#: builtin/bundle.c:56
+msgid "Need a repository to create a bundle."
+msgstr "Um ein Paket zu erstellen wird ein Projektarchiv benötigt."
+
+#: builtin/bundle.c:60
+msgid "Need a repository to unbundle."
+msgstr "Zum Entpacken wird ein Projektarchiv benötigt."
#: builtin/checkout.c:113 builtin/checkout.c:146
#, c-format
msgid "Unable to add merge result for '%s'"
msgstr "Konnte Ergebnis der Zusammenführung von '%s' nicht hinzufügen."
-#: builtin/checkout.c:212 builtin/reset.c:158
-#, c-format
-msgid "make_cache_entry failed for path '%s'"
-msgstr "make_cache_entry für Pfad '%s' fehlgeschlagen"
-
#: builtin/checkout.c:234 builtin/checkout.c:392
msgid "corrupt index file"
msgstr "beschädigte Bereitstellungsdatei"
" git branch neuer_zweig_name %s\n"
"\n"
-#: builtin/checkout.c:693
+#: builtin/checkout.c:694
msgid "internal error in revision walk"
msgstr "interner Fehler im Revisionsgang"
-#: builtin/checkout.c:697
+#: builtin/checkout.c:698
msgid "Previous HEAD position was"
msgstr "Vorherige Position der Zweigspitze (HEAD) war"
-#: builtin/checkout.c:723
+#: builtin/checkout.c:724
msgid "You are on a branch yet to be born"
msgstr "du bist auf einem Zweig, der noch geboren wird"
#. case (1)
-#: builtin/checkout.c:854
+#: builtin/checkout.c:855
#, c-format
msgid "invalid reference: %s"
msgstr "Ungültige Referenz: %s"
#. case (1): want a tree
-#: builtin/checkout.c:893
+#: builtin/checkout.c:894
#, c-format
msgid "reference is not a tree: %s"
msgstr "Referenz ist kein Baum: %s"
-#: builtin/checkout.c:973
+#: builtin/checkout.c:974
msgid "-B cannot be used with -b"
msgstr "-B kann nicht mit -b benutzt werden"
-#: builtin/checkout.c:982
+#: builtin/checkout.c:983
msgid "--patch is incompatible with all other options"
msgstr "--patch ist inkompatibel mit allen anderen Optionen"
-#: builtin/checkout.c:985
+#: builtin/checkout.c:986
msgid "--detach cannot be used with -b/-B/--orphan"
msgstr "--detach kann nicht mit -b/-B/--orphan benutzt werden"
-#: builtin/checkout.c:987
+#: builtin/checkout.c:988
msgid "--detach cannot be used with -t"
msgstr "--detach kann nicht mit -t benutzt werden"
-#: builtin/checkout.c:993
+#: builtin/checkout.c:994
msgid "--track needs a branch name"
msgstr "--track benötigt einen Zweignamen"
-#: builtin/checkout.c:1000
+#: builtin/checkout.c:1001
msgid "Missing branch name; try -b"
msgstr "Vermisse Zweignamen; versuche -b"
-#: builtin/checkout.c:1006
+#: builtin/checkout.c:1007
msgid "--orphan and -b|-B are mutually exclusive"
msgstr "--orphan und -b|-B sind gegenseitig exklusiv"
-#: builtin/checkout.c:1008
+#: builtin/checkout.c:1009
msgid "--orphan cannot be used with -t"
msgstr "--orphan kann nicht mit -t benutzt werden"
-#: builtin/checkout.c:1018
+#: builtin/checkout.c:1019
msgid "git checkout: -f and -m are incompatible"
msgstr "git checkout: -f und -m sind inkompatibel"
-#: builtin/checkout.c:1052
+#: builtin/checkout.c:1053
msgid "invalid path specification"
msgstr "ungültige Pfadspezifikation"
-#: builtin/checkout.c:1060
+#: builtin/checkout.c:1061
#, c-format
msgid ""
"git checkout: updating paths is incompatible with switching branches.\n"
"Hast du beabsichtigt '%s' auszuchecken, welcher nicht als Version aufgelöst "
"werden kann?"
-#: builtin/checkout.c:1062
+#: builtin/checkout.c:1063
msgid "git checkout: updating paths is incompatible with switching branches."
msgstr ""
"git checkout: Die Aktualisierung von Pfaden ist inkompatibel mit dem Wechsel "
"von Zweigen."
-#: builtin/checkout.c:1067
+#: builtin/checkout.c:1068
msgid "git checkout: --detach does not take a path argument"
msgstr "git checkout: --detach nimmt kein Pfad-Argument"
-#: builtin/checkout.c:1070
+#: builtin/checkout.c:1071
msgid ""
"git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
"checking out of the index."
"git checkout: --ours/--theirs, --force and --merge sind inkompatibel wenn\n"
"du aus der Bereitstellung auscheckst."
-#: builtin/checkout.c:1089
+#: builtin/checkout.c:1090
msgid "Cannot switch branch to a non-commit."
msgstr "Kann Zweig nur zu einer Version wechseln."
-#: builtin/checkout.c:1092
+#: builtin/checkout.c:1093
msgid "--ours/--theirs is incompatible with switching branches."
msgstr "--ours/--theirs ist inkompatibel mit den Wechseln von Zweigen."
msgid "You appear to have cloned an empty repository."
msgstr "Du scheinst ein leeres Projektarchiv geklont zu haben."
-#: builtin/commit.c:42
+#: builtin/column.c:51
+msgid "--command must be the first argument"
+msgstr "Option --command muss zuerst angegeben werden"
+
+#: builtin/commit.c:43
msgid ""
"Your name and email address were configured automatically based\n"
"on your username and hostname. Please check that they are accurate.\n"
"\n"
" git commit --amend --reset-author\n"
-#: builtin/commit.c:54
+#: builtin/commit.c:55
msgid ""
"You asked to amend the most recent commit, but doing so would make\n"
"it empty. You can repeat your command with --allow-empty, or you can\n"
"machen. Du kannst Dein Kommando mit --allow-empty wiederholen, oder die\n"
"Version mit \"git reset HEAD^\" vollständig entfernen.\n"
-#: builtin/commit.c:59
+#: builtin/commit.c:60
msgid ""
"The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
"If you wish to commit it anyway, use:\n"
"\n"
"Andernfalls benutze bitte 'git reset'\n"
-#: builtin/commit.c:205 builtin/reset.c:33
-msgid "merge"
-msgstr "zusammenführen"
-
-#: builtin/commit.c:208
-msgid "cherry-pick"
-msgstr "cherry-pick"
-
-#: builtin/commit.c:325
+#: builtin/commit.c:253
msgid "failed to unpack HEAD tree object"
msgstr "Fehler beim Entpacken des Baum-Objektes der Zweigspitze (HEAD)."
-#: builtin/commit.c:367
+#: builtin/commit.c:295
msgid "unable to create temporary index"
msgstr "Konnte temporäre Bereitstellung nicht erstellen."
-#: builtin/commit.c:373
+#: builtin/commit.c:301
msgid "interactive add failed"
msgstr "interaktives Hinzufügen fehlgeschlagen"
-#: builtin/commit.c:406 builtin/commit.c:427 builtin/commit.c:473
+#: builtin/commit.c:334 builtin/commit.c:355 builtin/commit.c:405
msgid "unable to write new_index file"
msgstr "Konnte new_index Datei nicht schreiben"
-#: builtin/commit.c:457
-#, c-format
-msgid "cannot do a partial commit during a %s."
-msgstr "Kann keine partielle Eintragung durchführen, während %s im Gange ist."
+#: builtin/commit.c:386
+msgid "cannot do a partial commit during a merge."
+msgstr ""
+"Kann keine partielle Eintragung durchführen, während eine Zusammenführung im "
+"Gange ist."
+
+#: builtin/commit.c:388
+msgid "cannot do a partial commit during a cherry-pick."
+msgstr ""
+"Kann keine partielle Eintragung durchführen, während \"cherry-pick\" im "
+"Gange ist."
-#: builtin/commit.c:466
+#: builtin/commit.c:398
msgid "cannot read the index"
msgstr "Kann Bereitstellung nicht lesen"
-#: builtin/commit.c:486
+#: builtin/commit.c:418
msgid "unable to write temporary index file"
msgstr "Konnte temporäre Bereitstellungsdatei nicht schreiben."
-#: builtin/commit.c:561 builtin/commit.c:567
+#: builtin/commit.c:493 builtin/commit.c:499
#, c-format
msgid "invalid commit: %s"
msgstr "Ungültige Version: %s"
-#: builtin/commit.c:590
+#: builtin/commit.c:522
msgid "malformed --author parameter"
msgstr "Fehlerhafter --author Parameter"
-#: builtin/commit.c:651
+#: builtin/commit.c:582
#, c-format
msgid "Malformed ident string: '%s'"
msgstr "Fehlerhafte Identifikations-String: '%s'"
-#: builtin/commit.c:689 builtin/commit.c:722 builtin/commit.c:1033
+#: builtin/commit.c:620 builtin/commit.c:653 builtin/commit.c:967
#, c-format
msgid "could not lookup commit %s"
msgstr "Konnte Version %s nicht nachschlagen"
-#: builtin/commit.c:701 builtin/shortlog.c:296
+#: builtin/commit.c:632 builtin/shortlog.c:296
#, c-format
msgid "(reading log message from standard input)\n"
msgstr "(lese Log-Nachricht von Standard-Eingabe)\n"
-#: builtin/commit.c:703
+#: builtin/commit.c:634
msgid "could not read log from standard input"
msgstr "Konnte Log nicht von Standard-Eingabe lesen."
-#: builtin/commit.c:707
+#: builtin/commit.c:638
#, c-format
msgid "could not read log file '%s'"
msgstr "Konnte Log-Datei '%s' nicht lesen"
-#: builtin/commit.c:713
+#: builtin/commit.c:644
msgid "commit has empty message"
msgstr "Version hat eine leere Beschreibung"
-#: builtin/commit.c:729
+#: builtin/commit.c:660
msgid "could not read MERGE_MSG"
msgstr "Konnte MERGE_MSG nicht lesen"
-#: builtin/commit.c:733
+#: builtin/commit.c:664
msgid "could not read SQUASH_MSG"
msgstr "Konnte SQUASH_MSG nicht lesen"
-#: builtin/commit.c:737
+#: builtin/commit.c:668
#, c-format
msgid "could not read '%s'"
msgstr "Konnte '%s' nicht lesen"
-#: builtin/commit.c:765
-#, c-format
-msgid "could not open '%s'"
-msgstr "Konnte '%s' nicht öffnen"
-
-#: builtin/commit.c:789
+#: builtin/commit.c:720
msgid "could not write commit template"
msgstr "Konnte Versionsvorlage nicht schreiben"
-#: builtin/commit.c:799
+#: builtin/commit.c:731
#, c-format
msgid ""
"\n"
-"It looks like you may be committing a %s.\n"
+"It looks like you may be committing a merge.\n"
"If this is not correct, please remove the file\n"
"\t%s\n"
"and try again.\n"
msgstr ""
"\n"
-"Es sieht so aus, als trägst du ein '%s' ein.\n"
+"Es sieht so aus, als trägst du eine Zusammenführung ein.\n"
"Falls das nicht korrekt ist, entferne bitte die Datei\n"
"\t%s\n"
"und versuche es erneut.\n"
-#: builtin/commit.c:812
-msgid "Please enter the commit message for your changes."
-msgstr "Bitte gebe die Versionsbeschreibung für deine Änderungen ein."
+#: builtin/commit.c:736
+#, c-format
+msgid ""
+"\n"
+"It looks like you may be committing a cherry-pick.\n"
+"If this is not correct, please remove the file\n"
+"\t%s\n"
+"and try again.\n"
+msgstr ""
+"\n"
+"Es sieht so aus, als trägst du ein \"cherry-pick\" ein.\n"
+"Falls das nicht korrekt ist, entferne bitte die Datei\n"
+"\t%s\n"
+"und versuche es erneut.\n"
-#: builtin/commit.c:815
+#: builtin/commit.c:748
msgid ""
-" Lines starting\n"
+"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be ignored, and an empty message aborts the commit.\n"
msgstr ""
-" Zeilen, die mit '#'\n"
-"beginnen, werden ignoriert, und eine leere Versionsbeschreibung bricht die "
-"Eintragung ab.\n"
+"Bitte gebe eine Versionsbeschreibung für deine Änderungen ein. Zeilen,\n"
+"die mit '#' beginnen, werden ignoriert, und eine leere Versionsbeschreibung\n"
+"bricht die Eintragung ab.\n"
-#: builtin/commit.c:820
+#: builtin/commit.c:753
msgid ""
-" Lines starting\n"
+"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be kept; you may remove them yourself if you want to.\n"
"An empty message aborts the commit.\n"
msgstr ""
-" Zeilen, die mit '#'\n"
-"beginnen, werden beibehalten; wenn du möchtest, kannst du diese entfernen.\n"
+"Bitte gebe eine Versionsbeschreibung für deine Änderungen ein. Zeilen, die\n"
+"mit '#' beginnen, werden beibehalten; wenn du möchtest, kannst du diese "
+"entfernen.\n"
"Eine leere Versionsbeschreibung bricht die Eintragung ab.\n"
-#: builtin/commit.c:832
+#: builtin/commit.c:766
#, c-format
msgid "%sAuthor: %s"
msgstr "%sAutor: %s"
-#: builtin/commit.c:839
+#: builtin/commit.c:773
#, c-format
msgid "%sCommitter: %s"
msgstr "%sEintragender: %s"
-#: builtin/commit.c:859
+#: builtin/commit.c:793
msgid "Cannot read index"
msgstr "Kann Bereitstellung nicht lesen"
-#: builtin/commit.c:896
+#: builtin/commit.c:830
msgid "Error building trees"
msgstr "Fehler beim Erzeugen der Zweige"
-#: builtin/commit.c:911 builtin/tag.c:357
+#: builtin/commit.c:845 builtin/tag.c:361
#, c-format
msgid "Please supply the message using either -m or -F option.\n"
-msgstr "Bitte liefere die Beschreibung entweder mit der Option -m oder -F.\n"
+msgstr "Bitte liefere eine Beschreibung entweder mit der Option -m oder -F.\n"
-#: builtin/commit.c:1008
+#: builtin/commit.c:942
#, c-format
msgid "No existing author found with '%s'"
msgstr "Kein existierender Autor mit '%s' gefunden."
-#: builtin/commit.c:1023 builtin/commit.c:1217
+#: builtin/commit.c:957 builtin/commit.c:1157
#, c-format
msgid "Invalid untracked files mode '%s'"
msgstr "Ungültiger Modus '%s' für unbeobachtete Dateien"
-#: builtin/commit.c:1063
+#: builtin/commit.c:997
msgid "Using both --reset-author and --author does not make sense"
msgstr "Verwendung von --reset-author und --author macht keinen Sinn."
-#: builtin/commit.c:1074
+#: builtin/commit.c:1008
msgid "You have nothing to amend."
msgstr "Du hast nichts zum nachbessern."
-#: builtin/commit.c:1076
-#, c-format
-msgid "You are in the middle of a %s -- cannot amend."
-msgstr "%s ist im Gange -- kann nicht nachbessern."
+#: builtin/commit.c:1011
+msgid "You are in the middle of a merge -- cannot amend."
+msgstr "Eine Zusammenführung ist im Gange -- kann nicht nachbessern."
-#: builtin/commit.c:1078
+#: builtin/commit.c:1013
+msgid "You are in the middle of a cherry-pick -- cannot amend."
+msgstr "\"cherry-pick\" ist im Gange -- kann nicht nachbessern."
+
+#: builtin/commit.c:1016
msgid "Options --squash and --fixup cannot be used together"
msgstr ""
"Die Optionen --squash und --fixup können nicht gemeinsam benutzt werden."
-#: builtin/commit.c:1088
+#: builtin/commit.c:1026
msgid "Only one of -c/-C/-F/--fixup can be used."
msgstr "Nur eines von -c/-C/-F/--fixup kann benutzt werden."
-#: builtin/commit.c:1090
+#: builtin/commit.c:1028
msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
msgstr "Option -m kann nicht mit -c/-C/-F/--fixup kombiniert werden"
-#: builtin/commit.c:1098
+#: builtin/commit.c:1036
msgid "--reset-author can be used only with -C, -c or --amend."
msgstr "--reset--author kann nur mit -C, -c oder --amend benutzt werden"
-#: builtin/commit.c:1115
+#: builtin/commit.c:1053
msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
msgstr ""
"Nur eines von --include/--only/--all/--interactive/--patch kann benutzt "
"werden."
-#: builtin/commit.c:1117
+#: builtin/commit.c:1055
msgid "No paths with --include/--only does not make sense."
msgstr "--include/--only machen ohne Pfade keinen Sinn."
-#: builtin/commit.c:1119
+#: builtin/commit.c:1057
msgid "Clever... amending the last one with dirty index."
msgstr ""
"Klug... die letzte Version mit einer unsauberen Bereitstellung nachbessern."
-#: builtin/commit.c:1121
+#: builtin/commit.c:1059
msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
msgstr ""
"Explizite Pfade ohne -i oder -o angegeben; unter der Annahme von --only "
"Pfaden..."
-#: builtin/commit.c:1131 builtin/tag.c:556
+#: builtin/commit.c:1069 builtin/tag.c:577
#, c-format
msgid "Invalid cleanup mode %s"
msgstr "Ungültiger \"cleanup\" Modus %s"
-#: builtin/commit.c:1136
+#: builtin/commit.c:1074
msgid "Paths with -a does not make sense."
msgstr "Pfade mit -a machen keinen Sinn."
-#: builtin/commit.c:1315
+#: builtin/commit.c:1257
msgid "couldn't look up newly created commit"
msgstr "Konnte neu erstellte Version nicht nachschlagen."
-#: builtin/commit.c:1317
+#: builtin/commit.c:1259
msgid "could not parse newly created commit"
msgstr "Konnte neulich erstellte Version nicht analysieren."
-#: builtin/commit.c:1358
+#: builtin/commit.c:1300
msgid "detached HEAD"
msgstr "losgelöste Zweigspitze (HEAD)"
-#: builtin/commit.c:1360
+#: builtin/commit.c:1302
msgid " (root-commit)"
msgstr " (Basis-Version)"
-#: builtin/commit.c:1450
+#: builtin/commit.c:1446
msgid "could not parse HEAD commit"
msgstr "Konnte Version der Zweigspitze (HEAD) nicht analysieren."
-#: builtin/commit.c:1487 builtin/merge.c:509
+#: builtin/commit.c:1484 builtin/merge.c:509
#, c-format
msgid "could not open '%s' for reading"
msgstr "Konnte '%s' nicht zum Lesen öffnen."
-#: builtin/commit.c:1494
+#: builtin/commit.c:1491
#, c-format
msgid "Corrupt MERGE_HEAD file (%s)"
msgstr "Beschädigte MERGE_HEAD-Datei (%s)"
-#: builtin/commit.c:1501
+#: builtin/commit.c:1498
msgid "could not read MERGE_MODE"
msgstr "Konnte MERGE_MODE nicht lesen"
-#: builtin/commit.c:1520
+#: builtin/commit.c:1517
#, c-format
msgid "could not read commit message: %s"
msgstr "Konnte Versionsbeschreibung nicht lesen: %s"
-#: builtin/commit.c:1534
+#: builtin/commit.c:1531
#, c-format
msgid "Aborting commit; you did not edit the message.\n"
msgstr "Eintragung abgebrochen; du hast die Beschreibung nicht editiert.\n"
-#: builtin/commit.c:1539
+#: builtin/commit.c:1536
#, c-format
msgid "Aborting commit due to empty commit message.\n"
msgstr "Eintragung aufgrund leerer Versionsbeschreibung abgebrochen.\n"
-#: builtin/commit.c:1554 builtin/merge.c:936 builtin/merge.c:961
+#: builtin/commit.c:1551 builtin/merge.c:936 builtin/merge.c:961
msgid "failed to write commit object"
msgstr "Fehler beim Schreiben des Versionsobjektes."
-#: builtin/commit.c:1575
+#: builtin/commit.c:1572
msgid "cannot lock HEAD ref"
msgstr "Kann Referenz der Zweigspitze (HEAD) nicht sperren."
-#: builtin/commit.c:1579
+#: builtin/commit.c:1576
msgid "cannot update HEAD ref"
msgstr "Kann Referenz der Zweigspitze (HEAD) nicht aktualisieren."
-#: builtin/commit.c:1590
+#: builtin/commit.c:1587
msgid ""
"Repository has been updated, but unable to write\n"
"new_index file. Check that disk is not full or quota is\n"
msgid "Not a git repository"
msgstr "Kein Git-Projektarchiv"
-#: builtin/diff.c:347
+#: builtin/diff.c:341
#, c-format
msgid "invalid object '%s' given."
msgstr "Objekt '%s' ist ungültig."
-#: builtin/diff.c:352
+#: builtin/diff.c:346
#, c-format
msgid "more than %d trees given: '%s'"
msgstr "Mehr als %d Zweige angegeben: '%s'"
-#: builtin/diff.c:362
+#: builtin/diff.c:356
#, c-format
msgid "more than two blobs given: '%s'"
msgstr "Mehr als zwei Blobs angegeben: '%s'"
-#: builtin/diff.c:370
+#: builtin/diff.c:364
#, c-format
msgid "unhandled object '%s' given."
msgstr "unbehandeltes Objekt '%s' angegeben"
#: builtin/fetch.c:549
#, c-format
-msgid " (%s will become dangling)\n"
-msgstr " (%s wird unreferenziert)\n"
+msgid " (%s will become dangling)"
+msgstr " (%s wird unreferenziert)"
#: builtin/fetch.c:550
#, c-format
-msgid " (%s has become dangling)\n"
-msgstr " (%s wurde unreferenziert)\n"
+msgid " (%s has become dangling)"
+msgstr " (%s wurde unreferenziert)"
#: builtin/fetch.c:557
msgid "[deleted]"
msgstr "[gelöscht]"
-#: builtin/fetch.c:558
+#: builtin/fetch.c:558 builtin/remote.c:1055
msgid "(none)"
msgstr "(nichts)"
#, c-format
msgid "Refusing to fetch into current branch %s of non-bare repository"
msgstr ""
-"Das Anfordern in den aktuellen Zweig %s von einem nicht-bloßen"
-"\"Projektarchiv wurde verweigert."
+"Das Anfordern in den aktuellen Zweig %s von einem nicht-bloßen Projektarchiv "
+"wurde verweigert."
#: builtin/fetch.c:709
#, c-format
msgid "Fetching %s\n"
msgstr "Fordere an von %s\n"
-#: builtin/fetch.c:890
+#: builtin/fetch.c:890 builtin/remote.c:100
#, c-format
msgid "Could not fetch %s"
msgstr "Konnte nicht von %s anfordern"
#: builtin/fetch.c:1000
msgid "Fetching a group and specifying refspecs does not make sense"
msgstr ""
-"Abholen einer Gruppe und Spezifizieren von Referenzspezifikationen macht "
-"keinen Sinn."
+"Abholen einer Gruppe mit Angabe von Referenzspezifikationen macht keinen "
+"Sinn."
#: builtin/gc.c:63
#, c-format
"run \"git gc\" manually. See \"git help gc\" for more information.\n"
msgstr ""
"Die Datenbank des Projektarchivs wird für eine optimale Performance\n"
-"komprimiert. Du kannst auch \"git gc\" manuell ausführen. Siehe \"git help gc"
-"\" für weitere Informationen.\n"
+"komprimiert. Du kannst auch \"git gc\" manuell ausführen.\n"
+"Siehe \"git help gc\" für weitere Informationen.\n"
#: builtin/gc.c:251
msgid ""
#: builtin/grep.c:526
#, c-format
msgid "unable to grep from object of type %s"
-msgstr "kann \"grep\" nicht mit Objekten des Typs \"%s\" durchführen"
+msgstr "kann \"grep\" nicht mit Objekten des Typs %s durchführen"
#: builtin/grep.c:584
#, c-format
msgid "cannot open '%s'"
msgstr "kann '%s' nicht öffnen"
-#: builtin/grep.c:888
+#: builtin/grep.c:885
msgid "no pattern given."
-msgstr "keine Muster gegeben"
+msgstr "keine Muster angegeben"
-#: builtin/grep.c:902
+#: builtin/grep.c:899
#, c-format
msgid "bad object %s"
msgstr "ungültiges Objekt %s"
-#: builtin/grep.c:943
+#: builtin/grep.c:940
msgid "--open-files-in-pager only works on the worktree"
-msgstr "--open-files-in-pager arbeitet nur auf dem Arbeitsbaum"
+msgstr "--open-files-in-pager arbeitet nur innerhalb des Arbeitsbaums"
-#: builtin/grep.c:966
+#: builtin/grep.c:963
msgid "--cached or --untracked cannot be used with --no-index."
msgstr "--cached oder --untracked kann nicht mit --no-index benutzt werden"
-#: builtin/grep.c:971
+#: builtin/grep.c:968
msgid "--no-index or --untracked cannot be used with revs."
-msgstr "--no-index oder --untracked kann nicht mit Revisionen benutzt werden"
+msgstr "--no-index oder --untracked kann nicht mit Versionen benutzt werden"
-#: builtin/grep.c:974
+#: builtin/grep.c:971
msgid "--[no-]exclude-standard cannot be used for tracked contents."
msgstr ""
"--[no-]exlude-standard kann nicht mit beobachteten Inhalten benutzt werden"
-#: builtin/grep.c:982
+#: builtin/grep.c:979
msgid "both --cached and trees are given."
msgstr "sowohl --cached als auch Zweige gegeben"
+#: builtin/help.c:63
+#, c-format
+msgid "unrecognized help format '%s'"
+msgstr "nicht erkanntes Hilfeformat: %s"
+
+#: builtin/help.c:91
+msgid "Failed to start emacsclient."
+msgstr "Konnte emacsclient nicht starten."
+
+#: builtin/help.c:104
+msgid "Failed to parse emacsclient version."
+msgstr "Konnte Version des emacsclient nicht parsen."
+
+#: builtin/help.c:112
+#, c-format
+msgid "emacsclient version '%d' too old (< 22)."
+msgstr "Version des emacsclient '%d' ist zu alt (< 22)."
+
+#: builtin/help.c:130 builtin/help.c:158 builtin/help.c:167 builtin/help.c:175
+#, c-format
+msgid "failed to exec '%s': %s"
+msgstr "Fehler beim Ausführen von '%s': %s"
+
+#: builtin/help.c:215
+#, c-format
+msgid ""
+"'%s': path for unsupported man viewer.\n"
+"Please consider using 'man.<tool>.cmd' instead."
+msgstr ""
+"'%s': Pfad für nicht unterstützten Handbuchbetrachter.\n"
+"Du könntest stattdessen 'man.<Werkzeug>.cmd' benutzen."
+
+#: builtin/help.c:227
+#, c-format
+msgid ""
+"'%s': cmd for supported man viewer.\n"
+"Please consider using 'man.<tool>.path' instead."
+msgstr ""
+"'%s': Kommando für unterstützten Handbuchbetrachter.\n"
+"Du könntest stattdessen 'man.<Werkzeug>.path' benutzen."
+
+#: builtin/help.c:291
+msgid "The most commonly used git commands are:"
+msgstr "Die allgemein verwendeten Git-Kommandos sind:"
+
+#: builtin/help.c:359
+#, c-format
+msgid "'%s': unknown man viewer."
+msgstr "'%s': unbekannter Handbuch-Betrachter."
+
+#: builtin/help.c:376
+msgid "no man viewer handled the request"
+msgstr "kein Handbuch-Betrachter konnte mit dieser Anfrage umgehen"
+
+#: builtin/help.c:384
+msgid "no info viewer handled the request"
+msgstr "kein Informations-Betrachter konnte mit dieser Anfrage umgehen"
+
+#: builtin/help.c:395
+#, c-format
+msgid "'%s': not a documentation directory."
+msgstr "'%s' ist kein Dokumentationsverzeichnis"
+
+#: builtin/help.c:436 builtin/help.c:443
+#, c-format
+msgid "usage: %s%s"
+msgstr "Verwendung: %s%s"
+
+#: builtin/help.c:459
+#, c-format
+msgid "`git %s' is aliased to `%s'"
+msgstr "für `git %s' wurde der Alias `%s' angelegt"
+
+#: builtin/index-pack.c:170
+#, c-format
+msgid "object type mismatch at %s"
+msgstr "Objekt-Typen passen bei %s nicht zusammen"
+
+#: builtin/index-pack.c:190
+msgid "object of unexpected type"
+msgstr "Objekt hat unerwarteten Typ"
+
+#: builtin/index-pack.c:227
+#, c-format
+msgid "cannot fill %d byte"
+msgid_plural "cannot fill %d bytes"
+msgstr[0] "kann %d Byte nicht lesen"
+msgstr[1] "kann %d Bytes nicht lesen"
+
+#: builtin/index-pack.c:237
+msgid "early EOF"
+msgstr "zu frühes Dateiende"
+
+#: builtin/index-pack.c:238
+msgid "read error on input"
+msgstr "Fehler beim Lesen der Eingabe"
+
+#: builtin/index-pack.c:250
+msgid "used more bytes than were available"
+msgstr "verwendete mehr Bytes als verfügbar waren"
+
+#: builtin/index-pack.c:257
+msgid "pack too large for current definition of off_t"
+msgstr "Paket ist zu groß für die aktuelle Definition von off_t"
+
+#: builtin/index-pack.c:273
+#, c-format
+msgid "unable to create '%s'"
+msgstr "konnte '%s' nicht erstellen"
+
+#: builtin/index-pack.c:278
+#, c-format
+msgid "cannot open packfile '%s'"
+msgstr "Kann Paketdatei '%s' nicht öffnen"
+
+#: builtin/index-pack.c:292
+msgid "pack signature mismatch"
+msgstr "Paketsignatur stimmt nicht überein"
+
+#: builtin/index-pack.c:312
+#, c-format
+msgid "pack has bad object at offset %lu: %s"
+msgstr "Paket hat ein ungültiges Objekt bei Versatz %lu: %s"
+
+#: builtin/index-pack.c:434
+#, c-format
+msgid "inflate returned %d"
+msgstr "Dekomprimierung gab %d zurück"
+
+#: builtin/index-pack.c:483
+msgid "offset value overflow for delta base object"
+msgstr "Wert für Versatz bei Differenzobjekt übergelaufen"
+
+#: builtin/index-pack.c:491
+msgid "delta base offset is out of bound"
+msgstr ""
+"Wert für Versatz bei Differenzobjekt liegt außerhalb des gültigen Bereichs"
+
+#: builtin/index-pack.c:499
+#, c-format
+msgid "unknown object type %d"
+msgstr "Unbekannter Objekt-Typ %d"
+
+#: builtin/index-pack.c:531
+msgid "cannot pread pack file"
+msgstr "Kann Paketdatei %s nicht lesen"
+
+#: builtin/index-pack.c:533
+#, c-format
+msgid "premature end of pack file, %lu byte missing"
+msgid_plural "premature end of pack file, %lu bytes missing"
+msgstr[0] "frühzeitiges Ende der Paketdatei, vermisse %lu Byte"
+msgstr[1] "frühzeitiges Ende der Paketdatei, vermisse %lu Bytes"
+
+#: builtin/index-pack.c:555
+msgid "serious inflate inconsistency"
+msgstr "ernsthafte Inkonsistenz nach Dekomprimierung"
+
+#: builtin/index-pack.c:646 builtin/index-pack.c:652 builtin/index-pack.c:675
+#: builtin/index-pack.c:709 builtin/index-pack.c:718
+#, c-format
+msgid "SHA1 COLLISION FOUND WITH %s !"
+msgstr "SHA1 KOLLISION MIT %s GEFUNDEN !"
+
+#: builtin/index-pack.c:649 builtin/pack-objects.c:170
+#: builtin/pack-objects.c:262
+#, c-format
+msgid "unable to read %s"
+msgstr "kann %s nicht lesen"
+
+#: builtin/index-pack.c:715
+#, c-format
+msgid "cannot read existing object %s"
+msgstr "Kann existierendes Objekt %s nicht lesen."
+
+#: builtin/index-pack.c:729
+#, c-format
+msgid "invalid blob object %s"
+msgstr "ungültiges Blob-Objekt %s"
+
+#: builtin/index-pack.c:744
+#, c-format
+msgid "invalid %s"
+msgstr "Ungültiger Objekt-Typ %s"
+
+#: builtin/index-pack.c:746
+msgid "Error in object"
+msgstr "Fehler in Objekt"
+
+#: builtin/index-pack.c:748
+#, c-format
+msgid "Not all child objects of %s are reachable"
+msgstr "Nicht alle Kind-Objekte von %s sind erreichbar"
+
+#: builtin/index-pack.c:818 builtin/index-pack.c:844
+msgid "failed to apply delta"
+msgstr "Konnte Dateiunterschied nicht anwenden"
+
+#: builtin/index-pack.c:983
+msgid "Receiving objects"
+msgstr "Empfange Objekte"
+
+#: builtin/index-pack.c:983
+msgid "Indexing objects"
+msgstr "Indiziere Objekte"
+
+#: builtin/index-pack.c:1009
+msgid "pack is corrupted (SHA1 mismatch)"
+msgstr "Paket ist beschädigt (SHA1 unterschiedlich)"
+
+#: builtin/index-pack.c:1014
+msgid "cannot fstat packfile"
+msgstr "kann Paketdatei nicht lesen"
+
+#: builtin/index-pack.c:1017
+msgid "pack has junk at the end"
+msgstr "Paketende enthält nicht verwendbaren Inhalt"
+
+#: builtin/index-pack.c:1028
+msgid "confusion beyond insanity in parse_pack_objects()"
+msgstr "Fehler beim Ausführen von \"parse_pack_objects()\""
+
+#: builtin/index-pack.c:1051
+msgid "Resolving deltas"
+msgstr "Löse Unterschiede auf"
+
+#: builtin/index-pack.c:1102
+msgid "confusion beyond insanity"
+msgstr "Fehler beim Auflösen der Unterschiede"
+
+#: builtin/index-pack.c:1121
+#, c-format
+msgid "pack has %d unresolved delta"
+msgid_plural "pack has %d unresolved deltas"
+msgstr[0] "Paket hat %d unaufgelöste Unterschied"
+msgstr[1] "Paket hat %d unaufgelöste Unterschiede"
+
+#: builtin/index-pack.c:1146
+#, c-format
+msgid "unable to deflate appended object (%d)"
+msgstr "Konnte angehängtes Objekt (%d) nicht komprimieren"
+
+#: builtin/index-pack.c:1225
+#, c-format
+msgid "local object %s is corrupt"
+msgstr "lokales Objekt %s ist beschädigt"
+
+#: builtin/index-pack.c:1249
+msgid "error while closing pack file"
+msgstr "Fehler beim Schließen der Paketdatei"
+
+#: builtin/index-pack.c:1262
+#, c-format
+msgid "cannot write keep file '%s'"
+msgstr "Kann Paketbeschreibungsdatei '%s' nicht schreiben"
+
+#: builtin/index-pack.c:1270
+#, c-format
+msgid "cannot close written keep file '%s'"
+msgstr "Kann eben erstellte Paketbeschreibungsdatei '%s' nicht schließen"
+
+#: builtin/index-pack.c:1283
+msgid "cannot store pack file"
+msgstr "Kann Paketdatei nicht speichern"
+
+#: builtin/index-pack.c:1294
+msgid "cannot store index file"
+msgstr "Kann Indexdatei nicht speichern"
+
+#: builtin/index-pack.c:1395
+#, c-format
+msgid "Cannot open existing pack file '%s'"
+msgstr "Kann existierende Paketdatei '%s' nicht öffnen"
+
+#: builtin/index-pack.c:1397
+#, c-format
+msgid "Cannot open existing pack idx file for '%s'"
+msgstr "Kann existierende Indexdatei für Paket '%s' nicht öffnen"
+
+#: builtin/index-pack.c:1444
+#, c-format
+msgid "non delta: %d object"
+msgid_plural "non delta: %d objects"
+msgstr[0] "kein Unterschied: %d Objekt"
+msgstr[1] "kein Unterschied: %d Objekte"
+
+#: builtin/index-pack.c:1451
+#, c-format
+msgid "chain length = %d: %lu object"
+msgid_plural "chain length = %d: %lu objects"
+msgstr[0] "Länge der Objekt-Liste = %d: %lu Objekt"
+msgstr[1] "Länge der Objekt-Liste = %d: %lu Objekte"
+
+#: builtin/index-pack.c:1478
+msgid "Cannot come back to cwd"
+msgstr "Kann nicht zurück zu Arbeitsverzeichnis wechseln"
+
+#: builtin/index-pack.c:1522 builtin/index-pack.c:1525
+#: builtin/index-pack.c:1537 builtin/index-pack.c:1541
+#, c-format
+msgid "bad %s"
+msgstr "%s ist ungültig"
+
+#: builtin/index-pack.c:1555
+msgid "--fix-thin cannot be used without --stdin"
+msgstr "--fix-thin kann nicht ohne --stdin benutzt werden"
+
+#: builtin/index-pack.c:1559 builtin/index-pack.c:1569
+#, c-format
+msgid "packfile name '%s' does not end with '.pack'"
+msgstr "Name der Paketdatei '%s' endet nicht mit '.pack'"
+
+#: builtin/index-pack.c:1578
+msgid "--verify with no packfile name given"
+msgstr "--verify ohne Name der Paketdatei angegeben"
+
#: builtin/init-db.c:35
#, c-format
msgid "Could not make %s writable by group"
-msgstr "Konnte %s nicht schreibbar für Gruppen machen"
+msgstr "Konnte Gruppenschreibrecht für %s nicht setzen."
#: builtin/init-db.c:62
#, c-format
#: builtin/init-db.c:97
#, c-format
msgid "cannot readlink '%s'"
-msgstr "kann Verknüfpung '%s' nicht lesen"
+msgstr "kann Verknüpfung '%s' nicht lesen"
#: builtin/init-db.c:99
#, c-format
#: builtin/init-db.c:192
#, c-format
msgid "insane git directory %s"
-msgstr "ungültiges git Verzeichnis %s"
+msgstr "ungültiges Git-Verzeichnis %s"
#: builtin/init-db.c:322 builtin/init-db.c:325
#, c-format
#: builtin/init-db.c:421
msgid " shared"
-msgstr " geteiltes"
+msgstr " gemeinsames"
#: builtin/init-db.c:440
msgid "cannot tell cwd"
-msgstr "kann aktuelles Verzeichnis nicht bestimmen"
+msgstr "kann aktuelles Arbeitsverzeichnis nicht ermitteln"
#: builtin/init-db.c:521 builtin/init-db.c:528
#, c-format
msgid "Cannot access work tree '%s'"
msgstr "Kann nicht auf Arbeitsbaum '%s' zugreifen."
-#: builtin/log.c:188
+#: builtin/log.c:189
#, c-format
msgid "Final output: %d %s\n"
msgstr "letzte Ausgabe: %d %s\n"
-#: builtin/log.c:401 builtin/log.c:489
+#: builtin/log.c:402 builtin/log.c:490
#, c-format
msgid "Could not read object %s"
msgstr "Kann Objekt %s nicht lesen."
-#: builtin/log.c:513
+#: builtin/log.c:514
#, c-format
msgid "Unknown type: %d"
msgstr "Unbekannter Typ: %d"
-#: builtin/log.c:602
+#: builtin/log.c:603
msgid "format.headers without value"
msgstr "format.headers ohne Wert"
-#: builtin/log.c:675
+#: builtin/log.c:677
msgid "name of output directory is too long"
msgstr "Name des Ausgabeverzeichnisses ist zu lang."
-#: builtin/log.c:686
+#: builtin/log.c:688
#, c-format
msgid "Cannot open patch file %s"
msgstr "Kann Patch-Datei %s nicht öffnen"
-#: builtin/log.c:700
+#: builtin/log.c:702
msgid "Need exactly one range."
msgstr "Brauche genau einen Versionsbereich."
-#: builtin/log.c:708
+#: builtin/log.c:710
msgid "Not a range."
msgstr "Kein Versionsbereich."
-#: builtin/log.c:745
-msgid "Could not extract email from committer identity."
-msgstr "Konnte E-Mail-Adresse des Einreichers nicht extrahieren."
-
-#: builtin/log.c:791
+#: builtin/log.c:787
msgid "Cover letter needs email format"
msgstr "Anschreiben benötigt E-Mail-Format"
-#: builtin/log.c:885
+#: builtin/log.c:860
#, c-format
msgid "insane in-reply-to: %s"
msgstr "ungültiges in-reply-to: %s"
-#: builtin/log.c:958
+#: builtin/log.c:933
msgid "Two output directories?"
msgstr "Zwei Ausgabeverzeichnisse?"
-#: builtin/log.c:1179
+#: builtin/log.c:1154
#, c-format
msgid "bogus committer info %s"
msgstr "unechte Einreicher-Informationen %s"
-#: builtin/log.c:1224
+#: builtin/log.c:1199
msgid "-n and -k are mutually exclusive."
msgstr "-n und -k schliessen sich gegenseitig aus"
-#: builtin/log.c:1226
+#: builtin/log.c:1201
msgid "--subject-prefix and -k are mutually exclusive."
msgstr "--subject-prefix und -k schliessen sich gegenseitig aus"
-#: builtin/log.c:1231 builtin/shortlog.c:284
-#, c-format
-msgid "unrecognized argument: %s"
-msgstr "nicht erkanntes Argument: %s"
-
-#: builtin/log.c:1234
+#: builtin/log.c:1209
msgid "--name-only does not make sense"
msgstr "--name-only macht keinen Sinn"
-#: builtin/log.c:1236
+#: builtin/log.c:1211
msgid "--name-status does not make sense"
msgstr "--name-status macht keinen Sinn"
-#: builtin/log.c:1238
+#: builtin/log.c:1213
msgid "--check does not make sense"
msgstr "--check macht keinen Sinn"
-#: builtin/log.c:1261
+#: builtin/log.c:1236
msgid "standard output, or directory, which one?"
msgstr "Standard-Ausgabe oder Verzeichnis, welches von beidem?"
-#: builtin/log.c:1263
+#: builtin/log.c:1238
#, c-format
msgid "Could not create directory '%s'"
msgstr "Konnte Verzeichnis '%s' nicht erstellen."
-#: builtin/log.c:1416
+#: builtin/log.c:1391
msgid "Failed to create output files"
msgstr "Fehler beim Erstellen der Ausgabedateien."
-#: builtin/log.c:1520
+#: builtin/log.c:1495
#, c-format
msgid ""
"Could not find a tracked remote branch, please specify <upstream> manually.\n"
"Konnte gefolgten, externen Zweig nicht finden, bitte gebe <upstream> manuell "
"an.\n"
-#: builtin/log.c:1536 builtin/log.c:1538 builtin/log.c:1550
+#: builtin/log.c:1511 builtin/log.c:1513 builtin/log.c:1525
#, c-format
msgid "Unknown commit %s"
msgstr "Unbekannte Version %s"
msgid "Renaming %s to %s\n"
msgstr "Benenne %s nach %s um\n"
-#: builtin/mv.c:215
+#: builtin/mv.c:215 builtin/remote.c:731
#, c-format
msgid "renaming '%s' failed"
msgstr "Umbenennung von '%s' fehlgeschlagen"
msgid "failed to finish 'show' for object '%s'"
msgstr "konnte 'show' für Objekt '%s' nicht abschließen"
-#: builtin/notes.c:175 builtin/tag.c:343
+#: builtin/notes.c:175 builtin/tag.c:347
#, c-format
msgid "could not create file '%s'"
msgstr "konnte Datei '%s' nicht erstellen"
msgid "The note contents has been left in %s"
msgstr "Die Notiz-Inhalte wurden in %s belassen"
-#: builtin/notes.c:251 builtin/tag.c:521
+#: builtin/notes.c:251 builtin/tag.c:542
#, c-format
msgid "cannot read '%s'"
msgstr "kann '%s' nicht lesen"
-#: builtin/notes.c:253 builtin/tag.c:524
+#: builtin/notes.c:253 builtin/tag.c:545
#, c-format
msgid "could not open or read '%s'"
msgstr "konnte '%s' nicht öffnen oder lesen"
#: builtin/notes.c:272 builtin/notes.c:445 builtin/notes.c:447
#: builtin/notes.c:507 builtin/notes.c:561 builtin/notes.c:644
#: builtin/notes.c:649 builtin/notes.c:724 builtin/notes.c:766
-#: builtin/notes.c:968 builtin/reset.c:293 builtin/tag.c:537
+#: builtin/notes.c:968 builtin/reset.c:293 builtin/tag.c:558
#, c-format
msgid "Failed to resolve '%s' as a valid ref."
msgstr "Konnte '%s' nicht als gültige Referenz auflösen."
msgid "Object %s has no note\n"
msgstr "Objekt %s hat keine Notiz\n"
-#: builtin/notes.c:1103
+#: builtin/notes.c:1103 builtin/remote.c:1598
#, c-format
msgid "Unknown subcommand: %s"
msgstr "Unbekanntes Unterkommando: %s"
-#: builtin/pack-objects.c:2315
+#: builtin/pack-objects.c:183 builtin/pack-objects.c:186
+#, c-format
+msgid "deflate error (%d)"
+msgstr "Fehler beim Komprimieren (%d)"
+
+#: builtin/pack-objects.c:2398
#, c-format
msgid "unsupported index version %s"
msgstr "Nicht unterstützte Bereitstellungsversion %s"
-#: builtin/pack-objects.c:2319
+#: builtin/pack-objects.c:2402
#, c-format
msgid "bad index version '%s'"
msgstr "Ungültige Bereitstellungsversion '%s'"
-#: builtin/pack-objects.c:2342
+#: builtin/pack-objects.c:2425
#, c-format
msgid "option %s does not accept negative form"
msgstr "Option %s akzeptiert keine negative Form"
-#: builtin/pack-objects.c:2346
+#: builtin/pack-objects.c:2429
+#, c-format
+msgid "unable to parse value '%s' for option %s"
+msgstr "konnte Wert '%s' für Option %s nicht parsen"
+
+#: builtin/push.c:45
+msgid "tag shorthand without <tag>"
+msgstr "Kurzschrift für Markierung ohne <Markierung>"
+
+#: builtin/push.c:64
+msgid "--delete only accepts plain target ref names"
+msgstr "--delete akzeptiert nur reine Referenz-Namen als Ziel"
+
+#: builtin/push.c:99
+msgid ""
+"\n"
+"To choose either option permanently, see push.default in 'git help config'."
+msgstr ""
+"\n"
+"Um eine Variante permanent zu verwenden, siehe push.default in 'git help "
+"config'."
+
+#: builtin/push.c:102
+#, c-format
+msgid ""
+"The upstream branch of your current branch does not match\n"
+"the name of your current branch. To push to the upstream branch\n"
+"on the remote, use\n"
+"\n"
+" git push %s HEAD:%s\n"
+"\n"
+"To push to the branch of the same name on the remote, use\n"
+"\n"
+" git push %s %s\n"
+"%s"
+msgstr ""
+"Der Name des externen Übernahmezweiges stimmt nicht mit dem Namen deines\n"
+"aktuellen Zweiges überein. Um auf den Übernahmezweig in dem externen\n"
+"Projektarchiv zu versenden, benutze:\n"
+"\n"
+" git push %s HEAD:%s\n"
+"\n"
+"Um auf den Zweig mit dem selben Namen in dem externen Projekarchiv\n"
+"zu versenden, benutze:\n"
+"\n"
+" git push %s %s\n"
+"%s"
+
+#: builtin/push.c:121
+#, c-format
+msgid ""
+"You are not currently on a branch.\n"
+"To push the history leading to the current (detached HEAD)\n"
+"state now, use\n"
+"\n"
+" git push %s HEAD:<name-of-remote-branch>\n"
+msgstr ""
+"Du befindest dich sich im Moment auf keinem Zweig.\n"
+"Um die Historie, führend zum aktuellen (freistehende Zweigspitze (HEAD))\n"
+"Status zu versenden, benutze\n"
+"\n"
+" git push %s HEAD:<Name-des-externen-Zweiges>\n"
+
+#: builtin/push.c:128
+#, c-format
+msgid ""
+"The current branch %s has no upstream branch.\n"
+"To push the current branch and set the remote as upstream, use\n"
+"\n"
+" git push --set-upstream %s %s\n"
+msgstr ""
+"Der aktuelle Zweig %s hat keinen Zweig im externen Projektarchiv.\n"
+"Um den aktuellen Zweig zu versenden und das Fernarchiv als externes\n"
+"Projektarchiv zu verwenden, benutze\n"
+"\n"
+" git push --set-upstream %s %s\n"
+
+#: builtin/push.c:136
+#, c-format
+msgid "The current branch %s has multiple upstream branches, refusing to push."
+msgstr "Der aktuelle Zweig %s hat mehrere externe Zweige, Versand verweigert."
+
+#: builtin/push.c:139
+#, c-format
+msgid ""
+"You are pushing to remote '%s', which is not the upstream of\n"
+"your current branch '%s', without telling me what to push\n"
+"to update which remote branch."
+msgstr ""
+"Du versendest nach '%s', welches kein externes Projektarchiv deines\n"
+"aktuellen Zweiges '%s' ist, ohne mir mitzuteilen, was ich versenden\n"
+"soll, um welchen externen Zweig zu aktualisieren."
+
+#: builtin/push.c:174
+msgid ""
+"You didn't specify any refspecs to push, and push.default is \"nothing\"."
+msgstr ""
+"Du hast keine Referenzspezifikationen zum Versenden angegeben, und push."
+"default ist \"nothing\"."
+
+#: builtin/push.c:181
+msgid ""
+"Updates were rejected because the tip of your current branch is behind\n"
+"its remote counterpart. Merge the remote changes (e.g. 'git pull')\n"
+"before pushing again.\n"
+"See the 'Note about fast-forwards' in 'git push --help' for details."
+msgstr ""
+"Aktualisierungen wurden zurückgewiesen, weil die Spitze deines aktuellen\n"
+"Zweiges hinter seinem externen Gegenstück zurückgefallen ist. Führe die\n"
+"externen Änderungen zusammen (z.B. 'git pull') bevor du erneut versendest.\n"
+"Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help'\n"
+"für weitere Details."
+
+#: builtin/push.c:187
+msgid ""
+"Updates were rejected because a pushed branch tip is behind its remote\n"
+"counterpart. If you did not intend to push that branch, you may want to\n"
+"specify branches to push or set the 'push.default' configuration\n"
+"variable to 'current' or 'upstream' to push only the current branch."
+msgstr ""
+"Aktualisierungen wurden zurückgewiesen, weil die Spitze eines versendeten\n"
+"Zweiges hinter seinem externen Gegenstück zurückgefallen ist. Wenn du nicht\n"
+"beabsichtigt hast, diesen Zweig zu versenden, kannst du auch den zu "
+"versendenden\n"
+"Zweig spezifizieren oder die Konfigurationsvariable 'push.default' zu "
+"'current'\n"
+"oder 'upstream' setzen, um nur den aktuellen Zweig zu versenden."
+
+#: builtin/push.c:193
+msgid ""
+"Updates were rejected because a pushed branch tip is behind its remote\n"
+"counterpart. Check out this branch and merge the remote changes\n"
+"(e.g. 'git pull') before pushing again.\n"
+"See the 'Note about fast-forwards' in 'git push --help' for details."
+msgstr ""
+"Aktualisierungen wurden zurückgewiesen, weil die Spitze eines versendeten\n"
+"Zweiges hinter seinem externen Gegenstück zurückgefallen ist. Checke diesen\n"
+"Zweig aus und führe die externen Änderungen zusammen (z.B. 'git pull')\n"
+"bevor du erneut versendest.\n"
+"Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help'\n"
+"für weitere Details."
+
+#: builtin/push.c:233
+#, c-format
+msgid "Pushing to %s\n"
+msgstr "Versende nach %s\n"
+
+#: builtin/push.c:237
+#, c-format
+msgid "failed to push some refs to '%s'"
+msgstr "Fehler beim Versenden einiger Referenzen nach '%s'"
+
+#: builtin/push.c:269
+#, c-format
+msgid "bad repository '%s'"
+msgstr "ungültiges Projektarchiv '%s'"
+
+#: builtin/push.c:270
+msgid ""
+"No configured push destination.\n"
+"Either specify the URL from the command-line or configure a remote "
+"repository using\n"
+"\n"
+" git remote add <name> <url>\n"
+"\n"
+"and then push using the remote name\n"
+"\n"
+" git push <name>\n"
+msgstr ""
+"Kein Ziel zum Versenden konfiguriert.\n"
+"Entweder spezifizierst du die URL von der Kommandozeile oder konfigurierst "
+"ein externes Projektarchiv unter Benutzung von\n"
+"\n"
+" git remote add <Name> <URL>\n"
+"\n"
+"und versendest dann unter Benutzung dieses Namens\n"
+"\n"
+" git push <Name>\n"
+
+#: builtin/push.c:285
+msgid "--all and --tags are incompatible"
+msgstr "--all und --tags sind inkompatibel"
+
+#: builtin/push.c:286
+msgid "--all can't be combined with refspecs"
+msgstr "--all kann nicht mit Referenzspezifikationen kombiniert werden"
+
+#: builtin/push.c:291
+msgid "--mirror and --tags are incompatible"
+msgstr "--mirror und --tags sind inkompatibel"
+
+#: builtin/push.c:292
+msgid "--mirror can't be combined with refspecs"
+msgstr "--mirror kann nicht mit Referenzspezifikationen kombiniert werden"
+
+#: builtin/push.c:297
+msgid "--all and --mirror are incompatible"
+msgstr "--all und --mirror sind inkompatibel"
+
+#: builtin/push.c:385
+msgid "--delete is incompatible with --all, --mirror and --tags"
+msgstr "--delete ist inkompatibel mit --all, --mirror und --tags"
+
+#: builtin/push.c:387
+msgid "--delete doesn't make sense without any refs"
+msgstr "--delete macht ohne irgendeine Referenz keinen Sinn"
+
+#: builtin/remote.c:98
+#, c-format
+msgid "Updating %s"
+msgstr "Aktualisiere %s"
+
+#: builtin/remote.c:130
+msgid ""
+"--mirror is dangerous and deprecated; please\n"
+"\t use --mirror=fetch or --mirror=push instead"
+msgstr ""
+"--mirror ist gefährlich und veraltet; bitte\n"
+"\t benutze stattdessen --mirror=fetch oder --mirror=push"
+
+#: builtin/remote.c:147
+#, c-format
+msgid "unknown mirror argument: %s"
+msgstr "unbekanntes Argument für Option --mirror: %s"
+
+#: builtin/remote.c:185
+msgid "specifying a master branch makes no sense with --mirror"
+msgstr "Angabe eines Hauptzweiges macht mit --mirror keinen Sinn"
+
+#: builtin/remote.c:187
+msgid "specifying branches to track makes sense only with fetch mirrors"
+msgstr ""
+"die Angabe von zu folgenden Zweigen macht nur mit dem Abholen von "
+"Spiegelarchiven Sinn"
+
+#: builtin/remote.c:195 builtin/remote.c:646
+#, c-format
+msgid "remote %s already exists."
+msgstr "externes Projektarchiv %s existiert bereits"
+
+#: builtin/remote.c:199 builtin/remote.c:650
+#, c-format
+msgid "'%s' is not a valid remote name"
+msgstr "'%s' ist kein gültiger Name für ein externes Projektarchiv"
+
+#: builtin/remote.c:243
+#, c-format
+msgid "Could not setup master '%s'"
+msgstr "Konnte symbolische Referenz für Hauptzweig von '%s' nicht einrichten"
+
+#: builtin/remote.c:299
+#, c-format
+msgid "more than one %s"
+msgstr "mehr als ein %s"
+
+#: builtin/remote.c:339
+#, c-format
+msgid "Could not get fetch map for refspec %s"
+msgstr "Konnte Abholungszuordnung für Referenzspezifikation %s nicht bekommen"
+
+#: builtin/remote.c:440 builtin/remote.c:448
+msgid "(matching)"
+msgstr "(übereinstimmend)"
+
+#: builtin/remote.c:452
+msgid "(delete)"
+msgstr "(lösche)"
+
+#: builtin/remote.c:595 builtin/remote.c:601 builtin/remote.c:607
+#, c-format
+msgid "Could not append '%s' to '%s'"
+msgstr "Konnte '%s' nicht an '%s' anhängen."
+
+#: builtin/remote.c:639 builtin/remote.c:792 builtin/remote.c:890
+#, c-format
+msgid "No such remote: %s"
+msgstr "Kein solches externes Archiv: %s"
+
+#: builtin/remote.c:656
+#, c-format
+msgid "Could not rename config section '%s' to '%s'"
+msgstr "Konnte Sektion '%s' in Konfiguration nicht nach '%s' umbenennen"
+
+#: builtin/remote.c:662 builtin/remote.c:799
+#, c-format
+msgid "Could not remove config section '%s'"
+msgstr "Konnte Sektion '%s' nicht aus Konfiguration entfernen"
+
+#: builtin/remote.c:677
+#, c-format
+msgid ""
+"Not updating non-default fetch refspec\n"
+"\t%s\n"
+"\tPlease update the configuration manually if necessary."
+msgstr ""
+"Keine Aktualisierung der nicht standardmäßigen Referenzspezifikation zum "
+"Abholen\n"
+"\t%s\n"
+"\tBitte aktualisiere, falls notwendig, die Konfiguration manuell."
+
+#: builtin/remote.c:683
+#, c-format
+msgid "Could not append '%s'"
+msgstr "Konnte '%s' nicht anhängen."
+
+#: builtin/remote.c:694
+#, c-format
+msgid "Could not set '%s'"
+msgstr "Konnte '%s' nicht setzen"
+
+#: builtin/remote.c:716
+#, c-format
+msgid "deleting '%s' failed"
+msgstr "Konnte '%s' nicht löschen"
+
+#: builtin/remote.c:750
+#, c-format
+msgid "creating '%s' failed"
+msgstr "Konnte '%s' nicht erstellen"
+
+#: builtin/remote.c:764
+#, c-format
+msgid "Could not remove branch %s"
+msgstr "Konnte Zweig %s nicht entfernen"
+
+#: builtin/remote.c:834
+msgid ""
+"Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
+"to delete it, use:"
+msgid_plural ""
+"Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n"
+"to delete them, use:"
+msgstr[0] ""
+"Hinweis: Ein Zweig außerhalb der /refs/remotes/ Hierachie wurde nicht "
+"entfernt;\n"
+"um diesen zu entfernen, benutze:"
+msgstr[1] ""
+"Hinweis: Einige Zweige außer der /refs/remotes/ Hierarchie wurden nicht "
+"entfernt;\n"
+"um diese zu entfernen, benutze:"
+
+#: builtin/remote.c:943
+#, c-format
+msgid " new (next fetch will store in remotes/%s)"
+msgstr " neu (wird bei nächster Abholung in remotes/%s gespeichert)"
+
+#: builtin/remote.c:946
+msgid " tracked"
+msgstr " gefolgt"
+
+#: builtin/remote.c:948
+msgid " stale (use 'git remote prune' to remove)"
+msgstr " veraltet (benutze 'git remote prune' zum Entfernen)"
+
+#: builtin/remote.c:950
+msgid " ???"
+msgstr " ???"
+
+#: builtin/remote.c:991
+#, c-format
+msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
+msgstr "ungültiges branch.%s.merge; kann nicht auf > 1 Zweig neu aufbauen"
+
+#: builtin/remote.c:998
+#, c-format
+msgid "rebases onto remote %s"
+msgstr "baut neu auf externen Zweig %s auf"
+
+#: builtin/remote.c:1001
+#, c-format
+msgid " merges with remote %s"
+msgstr " führt mit externem Zweig %s zusammen"
+
+#: builtin/remote.c:1002
+msgid " and with remote"
+msgstr " und mit externem Zweig"
+
+#: builtin/remote.c:1004
+#, c-format
+msgid "merges with remote %s"
+msgstr "führt mit externem Zweig %s zusammen"
+
+#: builtin/remote.c:1005
+msgid " and with remote"
+msgstr " und mit externem Zweig"
+
+#: builtin/remote.c:1051
+msgid "create"
+msgstr "erstellt"
+
+#: builtin/remote.c:1054
+msgid "delete"
+msgstr "gelöscht"
+
+#: builtin/remote.c:1058
+msgid "up to date"
+msgstr "aktuell"
+
+#: builtin/remote.c:1061
+msgid "fast-forwardable"
+msgstr "vorspulbar"
+
+#: builtin/remote.c:1064
+msgid "local out of date"
+msgstr "lokal nicht aktuell"
+
+#: builtin/remote.c:1071
+#, c-format
+msgid " %-*s forces to %-*s (%s)"
+msgstr " %-*s erzwingt Versandt nach %-*s (%s)"
+
+#: builtin/remote.c:1074
+#, c-format
+msgid " %-*s pushes to %-*s (%s)"
+msgstr " %-*s versendet nach %-*s (%s)"
+
+#: builtin/remote.c:1078
+#, c-format
+msgid " %-*s forces to %s"
+msgstr " %-*s erzwingt Versand nach %s"
+
+#: builtin/remote.c:1081
+#, c-format
+msgid " %-*s pushes to %s"
+msgstr " %-*s versendet nach %s"
+
+#: builtin/remote.c:1118
+#, c-format
+msgid "* remote %s"
+msgstr "* externes Projektarchiv %s"
+
+#: builtin/remote.c:1119
#, c-format
-msgid "unable to parse value '%s' for option %s"
-msgstr "konnte Wert '%s' für Option %s nicht parsen"
+msgid " Fetch URL: %s"
+msgstr " URL zum Abholen: %s"
-#: builtin/push.c:45
-msgid "tag shorthand without <tag>"
-msgstr "Kurzschrift für Markierung ohne <Markierung>"
+#: builtin/remote.c:1120 builtin/remote.c:1285
+msgid "(no URL)"
+msgstr "(keine URL)"
-#: builtin/push.c:64
-msgid "--delete only accepts plain target ref names"
-msgstr "--delete akzeptiert nur reine Referenz-Namen als Ziel"
+#: builtin/remote.c:1129 builtin/remote.c:1131
+#, c-format
+msgid " Push URL: %s"
+msgstr " URL zum Versenden: %s"
-#: builtin/push.c:84
+#: builtin/remote.c:1133 builtin/remote.c:1135 builtin/remote.c:1137
#, c-format
-msgid ""
-"You are not currently on a branch.\n"
-"To push the history leading to the current (detached HEAD)\n"
-"state now, use\n"
-"\n"
-" git push %s HEAD:<name-of-remote-branch>\n"
-msgstr ""
-"Du befindest dich sich im Moment auf keinem Zweig.\n"
-"Um die Historie, führend zum aktuellen (freistehende Zweigspitze (HEAD))\n"
-"Status zu versenden, benutze\n"
-"\n"
-" git push %s HEAD:<Name-des-externen-Zweiges>\n"
+msgid " HEAD branch: %s"
+msgstr " Hauptzweig: %s"
-#: builtin/push.c:91
+#: builtin/remote.c:1139
#, c-format
msgid ""
-"The current branch %s has no upstream branch.\n"
-"To push the current branch and set the remote as upstream, use\n"
-"\n"
-" git push --set-upstream %s %s\n"
+" HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
msgstr ""
-"Der aktuelle Zweig %s hat keinen Zweig im externen Projektarchiv.\n"
-"Um den aktuellen Zweig zu versenden und das Fernarchiv als externes\n"
-"Projektarchiv zu verwenden, benutze\n"
-"\n"
-" git push --set-upstream %s %s\n"
+" Hauptzweig (externer Hauptzweig ist mehrdeutig, könnte einer der folgenden "
+"sein):\n"
-#: builtin/push.c:99
+#: builtin/remote.c:1151
#, c-format
-msgid "The current branch %s has multiple upstream branches, refusing to push."
-msgstr "Der aktuelle Zweig %s hat mehrere externe Zweige, Versand verweigert."
+msgid " Remote branch:%s"
+msgid_plural " Remote branches:%s"
+msgstr[0] " externer Zweig:%s"
+msgstr[1] " externe Zweige:%s"
-#: builtin/push.c:102
+#: builtin/remote.c:1154 builtin/remote.c:1181
+msgid " (status not queried)"
+msgstr " (Zustand nicht abgefragt)"
+
+#: builtin/remote.c:1163
+msgid " Local branch configured for 'git pull':"
+msgid_plural " Local branches configured for 'git pull':"
+msgstr[0] " Lokaler Zweig konfiguriert für 'git pull':"
+msgstr[1] " Lokale Zweige konfiguriert für 'git pull':"
+
+#: builtin/remote.c:1171
+msgid " Local refs will be mirrored by 'git push'"
+msgstr " Lokale Referenzen werden von 'git push' gespiegelt"
+
+#: builtin/remote.c:1178
#, c-format
-msgid ""
-"You are pushing to remote '%s', which is not the upstream of\n"
-"your current branch '%s', without telling me what to push\n"
-"to update which remote branch."
-msgstr ""
-"Du versendest nach '%s', welches kein externes Projektarchiv deines\n"
-"aktuellen Zweiges '%s' ist, ohne mir mitzuteilen, was ich versenden\n"
-"soll, um welchen externen Zweig zu aktualisieren."
+msgid " Local ref configured for 'git push'%s:"
+msgid_plural " Local refs configured for 'git push'%s:"
+msgstr[0] " Lokale Referenz konfiguriert für 'git push'%s:"
+msgstr[1] " Lokale Referenzen konfiguriert für 'git push'%s:"
-#: builtin/push.c:131
-msgid ""
-"You didn't specify any refspecs to push, and push.default is \"nothing\"."
-msgstr ""
-"Du hast keine Referenzspezifikationen zum Versenden angegeben, und "
-"push.default ist \"nothing\"."
+#: builtin/remote.c:1216
+msgid "Cannot determine remote HEAD"
+msgstr "Kann Hauptzweig des externen Projektarchivs nicht bestimmen"
-#: builtin/push.c:138
-msgid ""
-"Updates were rejected because the tip of your current branch is behind\n"
-"its remote counterpart. Merge the remote changes (e.g. 'git pull')\n"
-"before pushing again.\n"
-"See the 'Note about fast-forwards' in 'git push --help' for details."
+#: builtin/remote.c:1218
+msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
msgstr ""
-"Aktualisierungen wurden zurückgewiesen, weil die Spitze deines aktuellen\n"
-"Zweiges hinter seinem externen Gegenstück zurückgefallen ist. Führe die\n"
-"externen Änderungen zusammen (z.B. 'git pull') bevor du erneut versendest.\n"
-"Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help' für\n"
-"weitere Details."
+"Mehrere Hauptzweige im externen Projektarchiv. Bitte wähle explizit einen "
+"aus mit:"
-#: builtin/push.c:144
-msgid ""
-"Updates were rejected because a pushed branch tip is behind its remote\n"
-"counterpart. If you did not intend to push that branch, you may want to\n"
-"specify branches to push or set the 'push.default' configuration\n"
-"variable to 'current' or 'upstream' to push only the current branch."
-msgstr ""
-"Aktualisierungen wurden zurückgewiesen, weil die Spitze eines versendeten\n"
-"Zweiges hinter seinem externen Gegenstück zurückgefallen ist. Wenn du nicht\n"
-"beabsichtigt hast, diesen Zweig zu versenden, kannst du auch den zu versendenden\n"
-"Zweig spezifizieren oder die Konfigurationsvariable 'push.default' zu 'current'\n"
-"oder 'upstream' setzen, um nur den aktuellen Zweig zu versenden."
+#: builtin/remote.c:1228
+#, c-format
+msgid "Could not delete %s"
+msgstr "Konnte %s nicht entfernen"
-#: builtin/push.c:150
-msgid ""
-"Updates were rejected because a pushed branch tip is behind its remote\n"
-"counterpart. Check out this branch and merge the remote changes\n"
-"(e.g. 'git pull') before pushing again.\n"
-"See the 'Note about fast-forwards' in 'git push --help' for details."
-msgstr ""
-"Aktualisierungen wurden zurückgewiesen, weil die Spitze eines versendeten\n"
-"Zweiges hinter seinem externen Gegenstück zurückgefallen ist. Checke diesen\n"
-"Zweig aus und führe die externen Änderungen zusammen (z.B. 'git pull')\n"
-"bevor du erneut versendest.\n"
-"Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help'\n"
-"für weitere Details."
+#: builtin/remote.c:1236
+#, c-format
+msgid "Not a valid ref: %s"
+msgstr "keine gültige Referenz: %s"
-#: builtin/push.c:190
+#: builtin/remote.c:1238
#, c-format
-msgid "Pushing to %s\n"
-msgstr "Versende nach %s\n"
+msgid "Could not setup %s"
+msgstr "Konnte %s nicht einrichten"
-#: builtin/push.c:194
+#: builtin/remote.c:1274
#, c-format
-msgid "failed to push some refs to '%s'"
-msgstr "Fehler beim Versenden einiger Referenzen nach '%s'"
+msgid " %s will become dangling!"
+msgstr " %s wird unreferenziert!"
-#: builtin/push.c:226
+#: builtin/remote.c:1275
#, c-format
-msgid "bad repository '%s'"
-msgstr "ungültiges Projektarchiv '%s'"
+msgid " %s has become dangling!"
+msgstr " %s wurde unreferenziert!"
-#: builtin/push.c:227
-msgid ""
-"No configured push destination.\n"
-"Either specify the URL from the command-line or configure a remote "
-"repository using\n"
-"\n"
-" git remote add <name> <url>\n"
-"\n"
-"and then push using the remote name\n"
-"\n"
-" git push <name>\n"
-msgstr ""
-"Kein Ziel zum Versenden konfiguriert.\n"
-"Entweder spezifizierst du die URL von der Kommandozeile oder konfigurierst "
-"ein externes Projektarchiv unter Benutzung von\n"
-"\n"
-" git remote add <Name> <URL>\n"
-"\n"
-"und versendest dann unter Benutzung dieses Namens\n"
-"\n"
-" git push <Name>\n"
+#: builtin/remote.c:1281
+#, c-format
+msgid "Pruning %s"
+msgstr "entferne veraltete Zweige von %s"
-#: builtin/push.c:242
-msgid "--all and --tags are incompatible"
-msgstr "--all und --tags sind inkompatibel"
+#: builtin/remote.c:1282
+#, c-format
+msgid "URL: %s"
+msgstr "URL: %s"
-#: builtin/push.c:243
-msgid "--all can't be combined with refspecs"
-msgstr "--all kann nicht mit Referenzspezifikationen kombiniert werden"
+#: builtin/remote.c:1295
+#, c-format
+msgid " * [would prune] %s"
+msgstr " * [würde veralteten Zweig entfernen] %s"
-#: builtin/push.c:248
-msgid "--mirror and --tags are incompatible"
-msgstr "--mirror und --tags sind inkompatibel"
+#: builtin/remote.c:1298
+#, c-format
+msgid " * [pruned] %s"
+msgstr "* [veralteten Zweig entfernt] %s"
-#: builtin/push.c:249
-msgid "--mirror can't be combined with refspecs"
-msgstr "--mirror kann nicht mit Referenzspezifikationen kombiniert werden"
+#: builtin/remote.c:1387 builtin/remote.c:1461
+#, c-format
+msgid "No such remote '%s'"
+msgstr "Kein solches externes Projektarchiv '%s'"
-#: builtin/push.c:254
-msgid "--all and --mirror are incompatible"
-msgstr "--all und --mirror sind inkompatibel"
+#: builtin/remote.c:1414
+msgid "no remote specified"
+msgstr "kein externes Projektarchiv angegeben"
-#: builtin/push.c:334
-msgid "--delete is incompatible with --all, --mirror and --tags"
-msgstr "--delete ist inkompatibel mit --all, --mirror und --tags"
+#: builtin/remote.c:1447
+msgid "--add --delete doesn't make sense"
+msgstr "--add --delete macht keinen Sinn"
-#: builtin/push.c:336
-msgid "--delete doesn't make sense without any refs"
-msgstr "--delete macht ohne irgendeine Referenz keinen Sinn"
+#: builtin/remote.c:1487
+#, c-format
+msgid "Invalid old URL pattern: %s"
+msgstr "ungültiges altes URL Format: %s"
+
+#: builtin/remote.c:1495
+#, c-format
+msgid "No such URL found: %s"
+msgstr "Keine solche URL gefunden: %s"
+
+#: builtin/remote.c:1497
+msgid "Will not delete all non-push URLs"
+msgstr "Werde keine URLs entfernen, die nicht für den Versand bestimmt sind"
#: builtin/reset.c:33
msgid "mixed"
msgid "hard"
msgstr "hard"
+#: builtin/reset.c:33
+msgid "merge"
+msgstr "zusammenführen"
+
#: builtin/reset.c:33
msgid "keep"
msgstr "keep"
msgid "%s: %s cannot be used with %s"
msgstr "%s: %s kann nicht mit %s benutzt werden"
-#: builtin/revert.c:127
+#: builtin/revert.c:131
msgid "program error"
msgstr "Programmfehler"
-#: builtin/revert.c:213
+#: builtin/revert.c:221
msgid "revert failed"
msgstr "\"revert\" fehlgeschlagen"
-#: builtin/revert.c:228
+#: builtin/revert.c:236
msgid "cherry-pick failed"
msgstr "\"cherry-pick\" fehlgeschlagen"
msgid "Missing author: %s"
msgstr "fehlender Autor: %s"
-#: builtin/tag.c:58
+#: builtin/tag.c:60
#, c-format
msgid "malformed object at '%s'"
msgstr "fehlerhaftes Objekt bei '%s'"
-#: builtin/tag.c:205
+#: builtin/tag.c:207
#, c-format
msgid "tag name too long: %.*s..."
msgstr "Markierungsname zu lang: %.*s..."
-#: builtin/tag.c:210
+#: builtin/tag.c:212
#, c-format
msgid "tag '%s' not found."
msgstr "Markierung '%s' nicht gefunden."
-#: builtin/tag.c:225
+#: builtin/tag.c:227
#, c-format
msgid "Deleted tag '%s' (was %s)\n"
msgstr "Gelöschte Markierung '%s' (war %s)\n"
-#: builtin/tag.c:237
+#: builtin/tag.c:239
#, c-format
msgid "could not verify the tag '%s'"
msgstr "Konnte Markierung '%s' nicht verifizieren"
-#: builtin/tag.c:247
+#: builtin/tag.c:249
msgid ""
"\n"
"#\n"
"# Zeilen, die mit '#' beginnen, werden ignoriert.\n"
"#\n"
-#: builtin/tag.c:254
+#: builtin/tag.c:256
msgid ""
"\n"
"#\n"
"# selbst entfernen wenn du möchtest.\n"
"#\n"
-#: builtin/tag.c:294
+#: builtin/tag.c:298
msgid "unable to sign the tag"
msgstr "konnte Markierung nicht signieren"
-#: builtin/tag.c:296
+#: builtin/tag.c:300
msgid "unable to write tag file"
msgstr "konnte Markierungsdatei nicht schreiben"
-#: builtin/tag.c:321
+#: builtin/tag.c:325
msgid "bad object type."
msgstr "ungültiger Objekt-Typ"
-#: builtin/tag.c:334
+#: builtin/tag.c:338
msgid "tag header too big."
msgstr "Markierungskopf zu groß."
-#: builtin/tag.c:366
+#: builtin/tag.c:370
msgid "no tag message?"
msgstr "keine Markierungsbeschreibung?"
-#: builtin/tag.c:372
+#: builtin/tag.c:376
#, c-format
msgid "The tag message has been left in %s\n"
msgstr "Die Markierungsbeschreibung wurde gelassen in %s\n"
-#: builtin/tag.c:421
+#: builtin/tag.c:425
msgid "switch 'points-at' requires an object"
msgstr "Option 'points-at' erfordert ein Objekt"
-#: builtin/tag.c:423
+#: builtin/tag.c:427
#, c-format
msgid "malformed object name '%s'"
msgstr "fehlerhafter Objekt-Name '%s'"
-#: builtin/tag.c:502
+#: builtin/tag.c:506
+msgid "--column and -n are incompatible"
+msgstr "--column und -n sind inkompatibel"
+
+#: builtin/tag.c:523
msgid "-n option is only allowed with -l."
msgstr "-n Option ist nur erlaubt mit -l."
-#: builtin/tag.c:504
+#: builtin/tag.c:525
msgid "--contains option is only allowed with -l."
msgstr "--contains Option ist nur erlaubt mit -l."
-#: builtin/tag.c:506
+#: builtin/tag.c:527
msgid "--points-at option is only allowed with -l."
msgstr "--points-at Option ist nur erlaubt mit -l."
-#: builtin/tag.c:514
+#: builtin/tag.c:535
msgid "only one -F or -m option is allowed."
msgstr "nur eine -F oder -m Option ist erlaubt."
-#: builtin/tag.c:534
+#: builtin/tag.c:555
msgid "too many params"
msgstr "zu viele Parameter"
-#: builtin/tag.c:540
+#: builtin/tag.c:561
#, c-format
msgid "'%s' is not a valid tag name."
msgstr "'%s' ist kein gültiger Markierungsname."
-#: builtin/tag.c:545
+#: builtin/tag.c:566
#, c-format
msgid "tag '%s' already exists"
msgstr "Markierung '%s' existiert bereits"
-#: builtin/tag.c:563
+#: builtin/tag.c:584
#, c-format
msgid "%s: cannot lock the ref"
msgstr "%s: kann Referenz nicht sperren"
-#: builtin/tag.c:565
+#: builtin/tag.c:586
#, c-format
msgid "%s: cannot update the ref"
msgstr "%s: kann Referenz nicht aktualisieren"
-#: builtin/tag.c:567
+#: builtin/tag.c:588
#, c-format
msgid "Updated tag '%s' (was %s)\n"
msgstr "Aktualisierte Markierung '%s' (war %s)\n"
+#: git.c:16
+msgid "See 'git help <command>' for more information on a specific command."
+msgstr ""
+"Siehe 'git help <Kommando>' für weitere Informationen zu einem spezifischen "
+"Kommando"
+
+#: parse-options.h:133 parse-options.h:235
+msgid "n"
+msgstr "Anzahl"
+
+#: parse-options.h:141
+msgid "time"
+msgstr "Zeit"
+
+#: parse-options.h:149
+msgid "file"
+msgstr "Datei"
+
+#: parse-options.h:151
+msgid "when"
+msgstr "wann"
+
+#: parse-options.h:156
+msgid "no-op (backward compatibility)"
+msgstr "Kein Effekt (Rückwärtskompatibilität)"
+
+#: parse-options.h:228
+msgid "be more verbose"
+msgstr "erweiterte Ausgaben"
+
+#: parse-options.h:230
+msgid "be more quiet"
+msgstr "weniger Ausgaben"
+
+#: parse-options.h:236
+msgid "use <n> digits to display SHA-1s"
+msgstr "benutze <n> Ziffern zur Anzeige von SHA-1s"
+
+#: common-cmds.h:8
+msgid "Add file contents to the index"
+msgstr "stellt Dateiinhalte zur Eintragung bereit"
+
+#: common-cmds.h:9
+msgid "Find by binary search the change that introduced a bug"
+msgstr ""
+"Findet über eine Binärsuche die Änderungen, die einen Fehler verursacht haben"
+
+#: common-cmds.h:10
+msgid "List, create, or delete branches"
+msgstr "Zeigt an, erstellt oder entfernt Zweige"
+
+#: common-cmds.h:11
+msgid "Checkout a branch or paths to the working tree"
+msgstr "Checkt Zweige oder Pfade im Arbeitszweig aus"
+
+#: common-cmds.h:12
+msgid "Clone a repository into a new directory"
+msgstr "Klont ein Projektarchiv in einem neuen Verzeichnis"
+
+#: common-cmds.h:13
+msgid "Record changes to the repository"
+msgstr "Trägt Änderungen in das Projektarchiv ein"
+
+#: common-cmds.h:14
+msgid "Show changes between commits, commit and working tree, etc"
+msgstr "Zeigt Änderungen zwischen Versionen, Version und Arbeitszweig, etc. an"
+
+#: common-cmds.h:15
+msgid "Download objects and refs from another repository"
+msgstr "Lädt Objekte und Referenzen von einem anderen Projektarchiv herunter"
+
+#: common-cmds.h:16
+msgid "Print lines matching a pattern"
+msgstr "Stellt Zeilen dar, die einem Muster entsprechen"
+
+#: common-cmds.h:17
+msgid "Create an empty git repository or reinitialize an existing one"
+msgstr ""
+"Erstellt ein leeres Git-Projektarchiv oder initialisiert ein bestehendes neu"
+
+#: common-cmds.h:18
+msgid "Show commit logs"
+msgstr "Zeigt Versionshistorie an"
+
+#: common-cmds.h:19
+msgid "Join two or more development histories together"
+msgstr "Führt zwei oder mehr Entwicklungszweige zusammen"
+
+#: common-cmds.h:20
+msgid "Move or rename a file, a directory, or a symlink"
+msgstr ""
+"Verschiebt oder benennt eine Datei, ein Verzeichnis, oder eine symbolische "
+"Verknüpfung um"
+
+#: common-cmds.h:21
+msgid "Fetch from and merge with another repository or a local branch"
+msgstr ""
+"Fordert Objekte von einem externen Projektarchiv an und führt sie mit einem "
+"anderen Projektarchiv oder einem lokalen Zweig zusammen"
+
+#: common-cmds.h:22
+msgid "Update remote refs along with associated objects"
+msgstr "Aktualisiert externe Referenzen mitsamt den verbundenen Objekten"
+
+#: common-cmds.h:23
+msgid "Forward-port local commits to the updated upstream head"
+msgstr "Baut lokale Versionen auf einem aktuellerem externen Zweig neu auf"
+
+#: common-cmds.h:24
+msgid "Reset current HEAD to the specified state"
+msgstr ""
+"Setzt die aktuelle Zweigspitze (HEAD) zu einem spezifizierten Zustand zurück"
+
+#: common-cmds.h:25
+msgid "Remove files from the working tree and from the index"
+msgstr "Löscht Dateien im Arbeitszweig und von der Bereitstellung"
+
+#: common-cmds.h:26
+msgid "Show various types of objects"
+msgstr "Zeigt verschiedene Arten von Objekten an"
+
+#: common-cmds.h:27
+msgid "Show the working tree status"
+msgstr "Zeigt den Zustand des Arbeitszweiges an"
+
+#: common-cmds.h:28
+msgid "Create, list, delete or verify a tag object signed with GPG"
+msgstr ""
+"Erzeugt, listet auf, löscht oder verifiziert ein mit GPG signiertes "
+"Markierungsobjekt"
+
#: git-am.sh:50
msgid "You need to set your committer info first"
msgstr "Du musst zuerst die Informationen des Eintragenden setzen."
+#: git-am.sh:95
+msgid ""
+"You seem to have moved HEAD since the last 'am' failure.\n"
+"Not rewinding to ORIG_HEAD"
+msgstr ""
+"Du scheinst seit dem letzten gescheiterten 'am' die Zweigspitze (HEAD)\n"
+"geändert zu haben.\n"
+"Keine Zurücksetzung zu ORIG_HEAD."
+
+#: git-am.sh:105
+#, sh-format
+msgid ""
+"When you have resolved this problem run \"$cmdline --resolved\".\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+"Wenn du das Problem aufgelöst hast, führe \"$cmdline --resolved\" aus.\n"
+"Falls du diesen Patch auslassen möchtest, führe stattdessen \"$cmdline --skip"
+"\" aus.\n"
+"Um den ursprünglichen Zweig wiederherzustellen und die Anwendung der "
+"Patches\n"
+"abzubrechen, führe \"$cmdline --abort\" aus."
+
+#: git-am.sh:121
+msgid "Cannot fall back to three-way merge."
+msgstr "Kann nicht zu 3-Wege-Zusammenführung zurückfallen."
+
#: git-am.sh:137
msgid "Repository lacks necessary blobs to fall back on 3-way merge."
msgstr ""
msgstr ""
"Unsaubere Bereitstellung: kann Patches nicht anwenden (unsauber: $files)"
+#: git-am.sh:671
+#, sh-format
+msgid ""
+"Patch is empty. Was it split wrong?\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+"Patch ist leer. Wurde er falsch aufgeteilt?\n"
+"Wenn du diesen Patch auslassen möchtest, führe stattdessen \"$cmdline --skip"
+"\" aus.\n"
+"Um den ursprünglichen Zweig wiederherzustellen und die Anwendung der "
+"Patches\n"
+"abzubrechen, führe \"$cmdline --abort\" aus."
+
+#: git-am.sh:708
+msgid "Patch does not have a valid e-mail address."
+msgstr "Patch enthält keine gültige eMail-Adresse."
+
#: git-am.sh:755
msgid "cannot be interactive without stdin connected to a terminal."
msgstr ""
"Kann nicht interaktiv sein, ohne dass die Standard-Eingabe mit einem "
"Terminal verbunden ist."
+#: git-am.sh:759
+msgid "Commit Body is:"
+msgstr "Beschreibung der Eintragung ist:"
+
#. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
#. in your translation. The program will only accept English
#. input at this point.
msgid "Applying: $FIRSTLINE"
msgstr "Wende an: $FIRSTLINE"
+#: git-am.sh:823
+msgid ""
+"No changes - did you forget to use 'git add'?\n"
+"If there is nothing left to stage, chances are that something else\n"
+"already introduced the same changes; you might want to skip this patch."
+msgstr ""
+"Keine Änderungen - hast du vergessen 'git add' zu benutzen?\n"
+"Wenn keine Änderungen mehr zum Bereitstellen vorhanden sind, könnten\n"
+"diese bereits anderweitig eingefügt worden sein; du könntest diesen Patch\n"
+"auslassen."
+
+#: git-am.sh:831
+msgid ""
+"You still have unmerged paths in your index\n"
+"did you forget to use 'git add'?"
+msgstr ""
+"Du hast immer noch nicht zusammengeführte Pfade in der Bereitstellung.\n"
+"Hast du vergessen 'git add' zu benutzen?"
+
#: git-am.sh:847
msgid "No changes -- Patch already applied."
msgstr "Keine Änderungen -- Patches bereits angewendet."
+#: git-am.sh:857
+#, sh-format
+msgid "Patch failed at $msgnum $FIRSTLINE"
+msgstr "Anwendung des Patches fehlgeschlagen bei $msgnum $FIRSTLINE"
+
#: git-am.sh:873
msgid "applying to an empty history"
msgstr "wende zu leerer Historie an"
+#: git-bisect.sh:48
+msgid "You need to start by \"git bisect start\""
+msgstr "Du musst mit \"git bisect start\" beginnen."
+
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
#. at this point.
msgid "'git bisect bad' can take only one argument."
msgstr "'git bisect bad' kann nur ein Argument entgegennehmen."
+#. have bad but not good. we could bisect although
+#. this is less optimum.
+#: git-bisect.sh:273
+msgid "Warning: bisecting only with a bad commit."
+msgstr "Warnung: halbiere nur mit einer fehlerhaften Version"
+
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
#. at this point.
msgid "Are you sure [Y/n]? "
msgstr "Bist du sicher [Y/n]? "
+#: git-bisect.sh:289
+msgid ""
+"You need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+"Du musst mindestens eine korrekte und eine fehlerhafte Version angeben.\n"
+"(Du kannst dafür \"git bisect bad\" und \"git bisect good\" benutzen.)"
+
+#: git-bisect.sh:292
+msgid ""
+"You need to start by \"git bisect start\".\n"
+"You then need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+"Du musst mit \"git bisect start\" beginnen.\n"
+"Danach musst du mindestens eine korrekte und eine fehlerhafte Version "
+"angeben.\n"
+"(Du kannst dafür \"git bisect bad\" und \"git bisect good\" benutzen.)"
+
+#: git-bisect.sh:347 git-bisect.sh:474
+msgid "We are not bisecting."
+msgstr "Wir sind nicht beim Halbieren."
+
#: git-bisect.sh:354
#, sh-format
msgid "'$invalid' is not a valid commit"
msgid "?? what are you talking about?"
msgstr "?? Was redest du da?"
-#: git-bisect.sh:474
-msgid "We are not bisecting."
-msgstr "Wir sind nicht beim Halbieren."
+#: git-bisect.sh:420
+#, sh-format
+msgid "running $command"
+msgstr "führe $command aus"
+
+#: git-bisect.sh:427
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"exit code $res from '$command' is < 0 or >= 128"
+msgstr ""
+"Ausführung der Halbierung fehlgeschlagen:\n"
+"Rückkehrwert $res von '$command' ist < 0 oder >= 128"
+
+#: git-bisect.sh:453
+msgid "bisect run cannot continue any more"
+msgstr "Ausführung der Halbierung kann nicht mehr fortgesetzt werden"
+
+#: git-bisect.sh:459
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"'bisect_state $state' exited with error code $res"
+msgstr ""
+"Ausführung der Halbierung fehlgeschlagen:\n"
+"'bisect_state $state' wurde mit Fehlerwert $res beendet"
+
+#: git-bisect.sh:466
+msgid "bisect run success"
+msgstr "Halbierung erfolgreich ausgeführt"
#: git-pull.sh:21
msgid ""
"Aktualisiere eine ungeborenen Zweig mit Änderungen, die zur Bereitstellung "
"hinzugefügt wurden"
+#. The fetch involved updating the current branch.
+#. The working tree and the index file is still based on the
+#. $orig_head commit, but we are merging into $curr_head.
+#. First update the working tree to match $curr_head.
+#: git-pull.sh:228
+#, sh-format
+msgid ""
+"Warning: fetch updated the current branch head.\n"
+"Warning: fast-forwarding your working tree from\n"
+"Warning: commit $orig_head."
+msgstr ""
+"Warnung: Die Anforderung aktualisierte die Spitze des aktuellen Zweiges.\n"
+"Warnung: Spule deinen Arbeitszweig von Version $orig_head vor."
+
#: git-pull.sh:253
msgid "Cannot merge multiple branches into empty head"
msgstr "Kann nicht mehrere Zweige in einen ungeborenen Zweig zusammenführen"
msgid "Cannot record working tree state"
msgstr "Kann Zustand des Arbeitsbaumes nicht aufzeichnen"
+#. TRANSLATORS: $option is an invalid option, like
+#. `--blah-blah'. The 7 spaces at the beginning of the
+#. second line correspond to "error: ". So you should line
+#. up the second line with however many characters the
+#. translation of "error: " takes in your language. E.g. in
+#. English this is:
+#.
+#. $ git stash save --blah-blah 2>&1 | head -n 2
+#. error: unknown option for 'stash save': --blah-blah
+#. To provide a message, use git stash save -- '--blah-blah'
+#: git-stash.sh:202
+#, sh-format
+msgid ""
+"error: unknown option for 'stash save': $option\n"
+" To provide a message, use git stash save -- '$option'"
+msgstr ""
+"Fehler: unbekannte Option für 'stash save': $option\n"
+" Um eine Beschreibung anzugeben, benutze \"git stash save -- "
+"'$option'\""
+
#: git-stash.sh:223
msgid "No local changes to save"
msgstr "Keine lokalen Änderungen zum Speichern"
msgid "Cannot unstage modified files"
msgstr "Kann geänderte Dateien nicht aus der Bereitstellung herausnehmen"
+#: git-stash.sh:474
+msgid "Index was not unstashed."
+msgstr "Bereitstellung wurde nicht ausgelagert."
+
#: git-stash.sh:491
#, sh-format
msgid "Dropped ${REV} ($s)"
msgid "(To restore them type \"git stash apply\")"
msgstr "(Zur Wiederherstellung gebe \"git stash apply\" ein)"
-#: git-submodule.sh:56
+#: git-submodule.sh:88
#, sh-format
msgid "cannot strip one component off url '$remoteurl'"
msgstr "Kann eine Komponente von URL '$remoteurl' nicht extrahieren"
-#: git-submodule.sh:109
+#: git-submodule.sh:145
#, sh-format
msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
-msgstr "Keine Unterprojekt-Zuordnung in .gitmodules für Pfad '$sm_path' gefunden"
+msgstr ""
+"Keine Unterprojekt-Zuordnung in .gitmodules für Pfad '$sm_path' gefunden"
-#: git-submodule.sh:150
+#: git-submodule.sh:186
#, sh-format
msgid "Clone of '$url' into submodule path '$sm_path' failed"
msgstr "Klonen von '$url' in Unterprojekt-Pfad '$sm_path' fehlgeschlagen"
-#: git-submodule.sh:160
+#: git-submodule.sh:196
#, sh-format
msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
msgstr ""
"Git-Verzeichnis '$a' ist Teil des Unterprojekt-Pfades '$b', oder umgekehrt"
-#: git-submodule.sh:248
+#: git-submodule.sh:285
#, sh-format
msgid "repo URL: '$repo' must be absolute or begin with ./|../"
msgstr "repo URL: '$repo' muss absolut sein oder mit ./|../ beginnen"
-#: git-submodule.sh:265
+#: git-submodule.sh:302
+#, sh-format
+msgid "'$sm_path' already exists in the index"
+msgstr "'$sm_path' existiert bereits in der Bereitstellung"
+
+#: git-submodule.sh:306
+#, sh-format
+msgid ""
+"The following path is ignored by one of your .gitignore files:\n"
+"$sm_path\n"
+"Use -f if you really want to add it."
+msgstr ""
+"Der folgende Pfad wird durch eine deiner \".gitignore\" Dateien ignoriert:\n"
+"$sm_path\n"
+"Benutze -f wenn du diesen wirklich hinzufügen möchtest."
+
+#: git-submodule.sh:317
#, sh-format
-msgid "'$path' already exists in the index"
-msgstr "'$path' existiert bereits in der Bereitstellung"
+msgid "Adding existing repo at '$sm_path' to the index"
+msgstr ""
+"Füge existierendes Projektarchiv in '$sm_path' der Bereitstellung hinzu."
-#: git-submodule.sh:282
+#: git-submodule.sh:319
#, sh-format
msgid "'$sm_path' already exists and is not a valid git repo"
msgstr "'$sm_path' existiert bereits und ist kein gültiges Git-Projektarchiv"
-#: git-submodule.sh:296
+#: git-submodule.sh:333
#, sh-format
msgid "Unable to checkout submodule '$sm_path'"
msgstr "Unfähig Unterprojekt '$sm_path' auszuchecken"
-#: git-submodule.sh:301
+#: git-submodule.sh:338
#, sh-format
msgid "Failed to add submodule '$sm_path'"
msgstr "Hinzufügen von Unterprojekt '$sm_path' fehlgeschlagen"
-#: git-submodule.sh:306
+#: git-submodule.sh:343
#, sh-format
msgid "Failed to register submodule '$sm_path'"
msgstr "Registierung von Unterprojekt '$sm_path' fehlgeschlagen"
-#: git-submodule.sh:348
+#: git-submodule.sh:385
#, sh-format
msgid "Entering '$prefix$sm_path'"
msgstr "Betrete '$prefix$sm_path'"
-#: git-submodule.sh:360
+#: git-submodule.sh:399
#, sh-format
msgid "Stopping at '$sm_path'; script returned non-zero status."
msgstr "Stoppe bei '$sm_path'; Skript gab nicht-Null Status zurück."
-#: git-submodule.sh:402
+#: git-submodule.sh:442
#, sh-format
msgid "No url found for submodule path '$sm_path' in .gitmodules"
msgstr "Keine URL für Unterprojekt-Pfad '$sm_path' in .gitmodules gefunden"
-#: git-submodule.sh:411
+#: git-submodule.sh:451
#, sh-format
msgid "Failed to register url for submodule path '$sm_path'"
msgstr "Registrierung der URL für Unterprojekt-Pfad '$sm_path' fehlgeschlagen"
-#: git-submodule.sh:419
-#, sh-format
-msgid "Failed to register update mode for submodule path '$sm_path'"
-msgstr "Registrierung des Aktualisierungsmodus für Unterprojekt-Pfad "
-"'$sm_path' fehlgeschlagen"
-
-#: git-submodule.sh:421
+#: git-submodule.sh:453
#, sh-format
msgid "Submodule '$name' ($url) registered for path '$sm_path'"
msgstr "Unterprojekt '$name' ($url) ist für Pfad '$sm_path' registriert"
-#: git-submodule.sh:520
+#: git-submodule.sh:461
+#, sh-format
+msgid "Failed to register update mode for submodule path '$sm_path'"
+msgstr ""
+"Registrierung des Aktualisierungsmodus für Unterprojekt-Pfad '$sm_path' "
+"fehlgeschlagen"
+
+#: git-submodule.sh:560
#, sh-format
msgid ""
"Submodule path '$sm_path' not initialized\n"
"Unterprojekt-Pfad '$sm_path' ist nicht initialisiert\n"
"Vielleicht möchtest du 'update --init' benutzen?"
-#: git-submodule.sh:533
+#: git-submodule.sh:573
#, sh-format
msgid "Unable to find current revision in submodule path '$sm_path'"
msgstr "Konnte aktuelle Version in Unterprojekt-Pfad '$sm_path' nicht finden"
-#: git-submodule.sh:552
+#: git-submodule.sh:592
#, sh-format
msgid "Unable to fetch in submodule path '$sm_path'"
msgstr "Konnte in Unterprojekt-Pfad '$sm_path' nicht anfordern"
-#: git-submodule.sh:566
+#: git-submodule.sh:606
#, sh-format
msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
msgstr "Neuaufbau von '$sha1' in Unterprojekt-Pfad '$sm_path' nicht möglich"
-#: git-submodule.sh:567
+#: git-submodule.sh:607
#, sh-format
msgid "Submodule path '$sm_path': rebased into '$sha1'"
msgstr "Unterprojekt-Pfad '$sm_path': neu aufgebaut in '$sha1'"
-#: git-submodule.sh:572
+#: git-submodule.sh:612
#, sh-format
msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
msgstr ""
"Zusammenführung von '$sha1' in Unterprojekt-Pfad '$sm_path' fehlgeschlagen"
-#: git-submodule.sh:573
+#: git-submodule.sh:613
#, sh-format
msgid "Submodule path '$sm_path': merged in '$sha1'"
msgstr "Unterprojekt-Pfad '$sm_path': zusammengeführt in '$sha1'"
-#: git-submodule.sh:578
+#: git-submodule.sh:618
#, sh-format
msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
msgstr "Konnte '$sha1' in Unterprojekt-Pfad '$sm_path' nicht auschecken."
-#: git-submodule.sh:579
+#: git-submodule.sh:619
#, sh-format
msgid "Submodule path '$sm_path': checked out '$sha1'"
msgstr "Unterprojekt-Pfad: '$sm_path': '$sha1' ausgecheckt"
-#: git-submodule.sh:601 git-submodule.sh:924
+#: git-submodule.sh:641 git-submodule.sh:964
#, sh-format
msgid "Failed to recurse into submodule path '$sm_path'"
msgstr "Fehler bei Rekursion in Unterprojekt-Pfad '$sm_path'"
-#: git-submodule.sh:709
-msgid "--"
-msgstr "--"
+#: git-submodule.sh:749
+msgid "--cached cannot be used with --files"
+msgstr "--cached kann nicht mit --files benutzt werden"
+
+#. unexpected type
+#: git-submodule.sh:789
+#, sh-format
+msgid "unexpected mode $mod_dst"
+msgstr "unerwarteter Modus $mod_dst"
-#: git-submodule.sh:767
+#: git-submodule.sh:807
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_src"
msgstr " Warnung: $name beinhaltet nicht Version $sha1_src"
-#: git-submodule.sh:770
+#: git-submodule.sh:810
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_dst"
msgstr " Warnung: $name beinhaltet nicht Version $sha1_dst"
-#: git-submodule.sh:773
+#: git-submodule.sh:813
#, sh-format
msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
msgstr ""
" Warnung: $name beinhaltet nicht die Versionen $sha1_src und $sha1_dst"
-#: git-submodule.sh:798
+#: git-submodule.sh:838
msgid "blob"
msgstr "Blob"
-#: git-submodule.sh:799
+#: git-submodule.sh:839
msgid "submodule"
msgstr "Unterprojekt"
-#: git-submodule.sh:970
+#: git-submodule.sh:876
+msgid "# Submodules changed but not updated:"
+msgstr "# Unterprojekte geändert, aber nicht aktualisiert:"
+
+#: git-submodule.sh:878
+msgid "# Submodule changes to be committed:"
+msgstr "# Änderungen in Unterprojekt zum Eintragen:"
+
+#: git-submodule.sh:1022
#, sh-format
msgid "Synchronizing submodule url for '$name'"
msgstr "Synchronisiere Unterprojekt-URL für '$name'"
+#~ msgid "--"
+#~ msgstr "--"
+
+#~ msgid "Could not extract email from committer identity."
+#~ msgstr "Konnte E-Mail-Adresse des Einreichers nicht extrahieren."
+
+#~ msgid "cherry-pick"
+#~ msgstr "cherry-pick"
+
+#~ msgid "Please enter the commit message for your changes."
+#~ msgstr "Bitte gebe die Versionsbeschreibung für deine Änderungen ein."
+
#~ msgid "Too many options specified"
#~ msgstr "Zu viele Optionen angegeben"
+
+#~ msgid ""
+#~ "To prevent you from losing history, non-fast-forward updates were "
+#~ "rejected\n"
+#~ "Merge the remote changes (e.g. 'git pull') before pushing again. See "
+#~ "the\n"
+#~ "'Note about fast-forwards' section of 'git push --help' for details.\n"
+#~ msgstr ""
+#~ "Um dich vor Verlust von Historie zu bewahren, wurden nicht vorzuspulende "
+#~ "Aktualisierungen zurückgewiesen.\n"
+#~ "Führe die externen Änderungen zusammen (z.B. 'git pull') bevor du erneut "
+#~ "versendest. Siehe auch die 'Note about fast-forwards' Sektion von \n"
+#~ "'git push --help' für weitere Details.\n"
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-05-21 08:57+0800\n"
+"POT-Creation-Date: 2012-07-03 10:23+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "unrecognized header: %s%s (%d)"
msgstr ""
-#: bundle.c:89 builtin/commit.c:697
+#: bundle.c:89 builtin/commit.c:696
#, c-format
msgid "could not open '%s'"
msgstr ""
msgid "Repository lacks these prerequisite commits:"
msgstr ""
-#: bundle.c:164 sequencer.c:533 sequencer.c:965 builtin/log.c:289
-#: builtin/log.c:719 builtin/log.c:1335 builtin/log.c:1554 builtin/merge.c:347
+#: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
+#: builtin/log.c:721 builtin/log.c:1310 builtin/log.c:1529 builtin/merge.c:347
#: builtin/shortlog.c:181
msgid "revision walk setup failed"
msgstr ""
msgstr[1] ""
#: bundle.c:192
+msgid "The bundle records a complete history."
+msgstr ""
+
+#: bundle.c:195
#, c-format
msgid "The bundle requires this ref"
msgid_plural "The bundle requires these %d refs"
msgstr[0] ""
msgstr[1] ""
-#: bundle.c:290
+#: bundle.c:294
msgid "rev-list died"
msgstr ""
-#: bundle.c:296 builtin/log.c:1231 builtin/shortlog.c:284
+#: bundle.c:300 builtin/log.c:1206 builtin/shortlog.c:284
#, c-format
msgid "unrecognized argument: %s"
msgstr ""
-#: bundle.c:331
+#: bundle.c:335
#, c-format
msgid "ref '%s' is excluded by the rev-list options"
msgstr ""
-#: bundle.c:376
+#: bundle.c:380
msgid "Refusing to create empty bundle."
msgstr ""
-#: bundle.c:394
+#: bundle.c:398
msgid "Could not spawn pack-objects"
msgstr ""
-#: bundle.c:412
+#: bundle.c:416
msgid "pack-objects died"
msgstr ""
-#: bundle.c:415
+#: bundle.c:419
#, c-format
msgid "cannot create '%s'"
msgstr ""
-#: bundle.c:437
+#: bundle.c:441
msgid "index-pack died"
msgstr ""
msgid "gpg failed to sign the data"
msgstr ""
-#: grep.c:1280
+#: grep.c:1320
#, c-format
msgid "'%s': unable to read %s"
msgstr ""
-#: grep.c:1297
+#: grep.c:1337
#, c-format
msgid "'%s': %s"
msgstr ""
-#: grep.c:1308
+#: grep.c:1348
#, c-format
msgid "'%s': short read %s"
msgstr ""
-#: help.c:207
+#: help.c:208
#, c-format
msgid "available git commands in '%s'"
msgstr ""
-#: help.c:214
+#: help.c:215
msgid "git commands available from elsewhere on your $PATH"
msgstr ""
-#: help.c:270
+#: help.c:271
#, c-format
msgid ""
"'%s' appears to be a git command, but we were not\n"
"able to execute it. Maybe git-%s is broken?"
msgstr ""
-#: help.c:327
+#: help.c:328
msgid "Uh oh. Your system reports no Git commands at all."
msgstr ""
-#: help.c:349
+#: help.c:350
#, c-format
msgid ""
"WARNING: You called a Git command named '%s', which does not exist.\n"
"Continuing under the assumption that you meant '%s'"
msgstr ""
-#: help.c:354
+#: help.c:355
#, c-format
msgid "in %0.1f seconds automatically..."
msgstr ""
-#: help.c:361
+#: help.c:362
#, c-format
msgid "git: '%s' is not a git command. See 'git --help'."
msgstr ""
-#: help.c:365
+#: help.c:366
msgid ""
"\n"
"Did you mean this?"
msgid " %s"
msgstr ""
-#: remote.c:1607
+#: remote.c:1629
#, c-format
msgid "Your branch is ahead of '%s' by %d commit.\n"
msgid_plural "Your branch is ahead of '%s' by %d commits.\n"
msgstr[0] ""
msgstr[1] ""
-#: remote.c:1613
+#: remote.c:1635
#, c-format
msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: remote.c:1621
+#: remote.c:1643
#, c-format
msgid ""
"Your branch and '%s' have diverged,\n"
"and commit the result with 'git commit'"
msgstr ""
-#: sequencer.c:160 sequencer.c:741 sequencer.c:824
+#: sequencer.c:160 sequencer.c:758 sequencer.c:841
#, c-format
msgid "Could not write to %s"
msgstr ""
msgid "Unable to update cache tree\n"
msgstr ""
-#: sequencer.c:323
+#: sequencer.c:324
#, c-format
msgid "Could not parse commit %s\n"
msgstr ""
-#: sequencer.c:328
+#: sequencer.c:329
#, c-format
msgid "Could not parse parent commit %s\n"
msgstr ""
-#: sequencer.c:358
+#: sequencer.c:395
msgid "Your index file is unmerged."
msgstr ""
-#: sequencer.c:361
+#: sequencer.c:398
msgid "You do not have a valid HEAD"
msgstr ""
-#: sequencer.c:376
+#: sequencer.c:413
#, c-format
msgid "Commit %s is a merge but no -m option was given."
msgstr ""
-#: sequencer.c:384
+#: sequencer.c:421
#, c-format
msgid "Commit %s does not have parent %d"
msgstr ""
-#: sequencer.c:388
+#: sequencer.c:425
#, c-format
msgid "Mainline was specified but commit %s is not a merge."
msgstr ""
#. TRANSLATORS: The first %s will be "revert" or
#. "cherry-pick", the second %s a SHA1
-#: sequencer.c:399
+#: sequencer.c:436
#, c-format
msgid "%s: cannot parse parent commit %s"
msgstr ""
-#: sequencer.c:403
+#: sequencer.c:440
#, c-format
msgid "Cannot get commit message for %s"
msgstr ""
-#: sequencer.c:491
+#: sequencer.c:524
#, c-format
msgid "could not revert %s... %s"
msgstr ""
-#: sequencer.c:492
+#: sequencer.c:525
#, c-format
msgid "could not apply %s... %s"
msgstr ""
-#: sequencer.c:536
+#: sequencer.c:553
msgid "empty commit set passed"
msgstr ""
-#: sequencer.c:544
+#: sequencer.c:561
#, c-format
msgid "git %s: failed to read the index"
msgstr ""
-#: sequencer.c:549
+#: sequencer.c:566
#, c-format
msgid "git %s: failed to refresh the index"
msgstr ""
-#: sequencer.c:607
+#: sequencer.c:624
#, c-format
msgid "Cannot %s during a %s"
msgstr ""
-#: sequencer.c:629
+#: sequencer.c:646
#, c-format
msgid "Could not parse line %d."
msgstr ""
-#: sequencer.c:634
+#: sequencer.c:651
msgid "No commits parsed."
msgstr ""
-#: sequencer.c:647
+#: sequencer.c:664
#, c-format
msgid "Could not open %s"
msgstr ""
-#: sequencer.c:651
+#: sequencer.c:668
#, c-format
msgid "Could not read %s."
msgstr ""
-#: sequencer.c:658
+#: sequencer.c:675
#, c-format
msgid "Unusable instruction sheet: %s"
msgstr ""
-#: sequencer.c:686
+#: sequencer.c:703
#, c-format
msgid "Invalid key: %s"
msgstr ""
-#: sequencer.c:689
+#: sequencer.c:706
#, c-format
msgid "Invalid value for %s: %s"
msgstr ""
-#: sequencer.c:701
+#: sequencer.c:718
#, c-format
msgid "Malformed options sheet: %s"
msgstr ""
-#: sequencer.c:722
+#: sequencer.c:739
msgid "a cherry-pick or revert is already in progress"
msgstr ""
-#: sequencer.c:723
+#: sequencer.c:740
msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
msgstr ""
-#: sequencer.c:727
+#: sequencer.c:744
#, c-format
msgid "Could not create sequencer directory %s"
msgstr ""
-#: sequencer.c:743 sequencer.c:828
+#: sequencer.c:760 sequencer.c:845
#, c-format
msgid "Error wrapping up %s."
msgstr ""
-#: sequencer.c:762 sequencer.c:896
+#: sequencer.c:779 sequencer.c:913
msgid "no cherry-pick or revert in progress"
msgstr ""
-#: sequencer.c:764
+#: sequencer.c:781
msgid "cannot resolve HEAD"
msgstr ""
-#: sequencer.c:766
+#: sequencer.c:783
msgid "cannot abort from a branch yet to be born"
msgstr ""
-#: sequencer.c:788 builtin/apply.c:3689
+#: sequencer.c:805 builtin/apply.c:3697
#, c-format
msgid "cannot open %s: %s"
msgstr ""
-#: sequencer.c:791
+#: sequencer.c:808
#, c-format
msgid "cannot read %s: %s"
msgstr ""
-#: sequencer.c:792
+#: sequencer.c:809
msgid "unexpected end of file"
msgstr ""
-#: sequencer.c:798
+#: sequencer.c:815
#, c-format
msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
msgstr ""
-#: sequencer.c:821
+#: sequencer.c:838
#, c-format
msgid "Could not format %s."
msgstr ""
-#: sequencer.c:983
+#: sequencer.c:1000
msgid "Can't revert as initial commit"
msgstr ""
-#: sequencer.c:984
+#: sequencer.c:1001
msgid "Can't cherry-pick into empty head"
msgstr ""
msgid "Upstream branch '%s' not stored as a remote-tracking branch"
msgstr ""
-#: wt-status.c:135
+#: wrapper.c:413
+#, c-format
+msgid "unable to look up current user in the passwd file: %s"
+msgstr ""
+
+#: wrapper.c:414
+msgid "no such user"
+msgstr ""
+
+#: wt-status.c:141
msgid "Unmerged paths:"
msgstr ""
-#: wt-status.c:141 wt-status.c:158
+#: wt-status.c:168 wt-status.c:195
#, c-format
msgid " (use \"git reset %s <file>...\" to unstage)"
msgstr ""
-#: wt-status.c:143 wt-status.c:160
+#: wt-status.c:170 wt-status.c:197
msgid " (use \"git rm --cached <file>...\" to unstage)"
msgstr ""
-#: wt-status.c:144
+#: wt-status.c:174
+msgid " (use \"git add <file>...\" to mark resolution)"
+msgstr ""
+
+#: wt-status.c:176 wt-status.c:180
msgid " (use \"git add/rm <file>...\" as appropriate to mark resolution)"
msgstr ""
-#: wt-status.c:152
+#: wt-status.c:178
+msgid " (use \"git rm <file>...\" to mark resolution)"
+msgstr ""
+
+#: wt-status.c:189
msgid "Changes to be committed:"
msgstr ""
-#: wt-status.c:170
+#: wt-status.c:207
msgid "Changes not staged for commit:"
msgstr ""
-#: wt-status.c:174
+#: wt-status.c:211
msgid " (use \"git add <file>...\" to update what will be committed)"
msgstr ""
-#: wt-status.c:176
+#: wt-status.c:213
msgid " (use \"git add/rm <file>...\" to update what will be committed)"
msgstr ""
-#: wt-status.c:177
+#: wt-status.c:214
msgid ""
" (use \"git checkout -- <file>...\" to discard changes in working directory)"
msgstr ""
-#: wt-status.c:179
+#: wt-status.c:216
msgid " (commit or discard the untracked or modified content in submodules)"
msgstr ""
-#: wt-status.c:188
+#: wt-status.c:225
#, c-format
msgid "%s files:"
msgstr ""
-#: wt-status.c:191
+#: wt-status.c:228
#, c-format
msgid " (use \"git %s <file>...\" to include in what will be committed)"
msgstr ""
-#: wt-status.c:208
+#: wt-status.c:245
msgid "bug"
msgstr ""
-#: wt-status.c:213
+#: wt-status.c:250
msgid "both deleted:"
msgstr ""
-#: wt-status.c:214
+#: wt-status.c:251
msgid "added by us:"
msgstr ""
-#: wt-status.c:215
+#: wt-status.c:252
msgid "deleted by them:"
msgstr ""
-#: wt-status.c:216
+#: wt-status.c:253
msgid "added by them:"
msgstr ""
-#: wt-status.c:217
+#: wt-status.c:254
msgid "deleted by us:"
msgstr ""
-#: wt-status.c:218
+#: wt-status.c:255
msgid "both added:"
msgstr ""
-#: wt-status.c:219
+#: wt-status.c:256
msgid "both modified:"
msgstr ""
-#: wt-status.c:249
+#: wt-status.c:286
msgid "new commits, "
msgstr ""
-#: wt-status.c:251
+#: wt-status.c:288
msgid "modified content, "
msgstr ""
-#: wt-status.c:253
+#: wt-status.c:290
msgid "untracked content, "
msgstr ""
-#: wt-status.c:267
+#: wt-status.c:304
#, c-format
msgid "new file: %s"
msgstr ""
-#: wt-status.c:270
+#: wt-status.c:307
#, c-format
msgid "copied: %s -> %s"
msgstr ""
-#: wt-status.c:273
+#: wt-status.c:310
#, c-format
msgid "deleted: %s"
msgstr ""
-#: wt-status.c:276
+#: wt-status.c:313
#, c-format
msgid "modified: %s"
msgstr ""
-#: wt-status.c:279
+#: wt-status.c:316
#, c-format
msgid "renamed: %s -> %s"
msgstr ""
-#: wt-status.c:282
+#: wt-status.c:319
#, c-format
msgid "typechange: %s"
msgstr ""
-#: wt-status.c:285
+#: wt-status.c:322
#, c-format
msgid "unknown: %s"
msgstr ""
-#: wt-status.c:288
+#: wt-status.c:325
#, c-format
msgid "unmerged: %s"
msgstr ""
-#: wt-status.c:291
+#: wt-status.c:328
#, c-format
msgid "bug: unhandled diff status %c"
msgstr ""
-#: wt-status.c:737
+#: wt-status.c:786
+msgid "You have unmerged paths."
+msgstr ""
+
+#: wt-status.c:789 wt-status.c:913
+msgid " (fix conflicts and run \"git commit\")"
+msgstr ""
+
+#: wt-status.c:792
+msgid "All conflicts fixed but you are still merging."
+msgstr ""
+
+#: wt-status.c:795
+msgid " (use \"git commit\" to conclude merge)"
+msgstr ""
+
+#: wt-status.c:805
+msgid "You are in the middle of an am session."
+msgstr ""
+
+#: wt-status.c:808
+msgid "The current patch is empty."
+msgstr ""
+
+#: wt-status.c:812
+msgid " (fix conflicts and then run \"git am --resolved\")"
+msgstr ""
+
+#: wt-status.c:814
+msgid " (use \"git am --skip\" to skip this patch)"
+msgstr ""
+
+#: wt-status.c:816
+msgid " (use \"git am --abort\" to restore the original branch)"
+msgstr ""
+
+#: wt-status.c:874 wt-status.c:884
+msgid "You are currently rebasing."
+msgstr ""
+
+#: wt-status.c:877
+msgid " (fix conflicts and then run \"git rebase --continue\")"
+msgstr ""
+
+#: wt-status.c:879
+msgid " (use \"git rebase --skip\" to skip this patch)"
+msgstr ""
+
+#: wt-status.c:881
+msgid " (use \"git rebase --abort\" to check out the original branch)"
+msgstr ""
+
+#: wt-status.c:887
+msgid " (all conflicts fixed: run \"git rebase --continue\")"
+msgstr ""
+
+#: wt-status.c:889
+msgid "You are currently splitting a commit during a rebase."
+msgstr ""
+
+#: wt-status.c:892
+msgid " (Once your working directory is clean, run \"git rebase --continue\")"
+msgstr ""
+
+#: wt-status.c:894
+msgid "You are currently editing a commit during a rebase."
+msgstr ""
+
+#: wt-status.c:897
+msgid " (use \"git commit --amend\" to amend the current commit)"
+msgstr ""
+
+#: wt-status.c:899
+msgid ""
+" (use \"git rebase --continue\" once you are satisfied with your changes)"
+msgstr ""
+
+#: wt-status.c:909
+msgid "You are currently cherry-picking."
+msgstr ""
+
+#: wt-status.c:916
+msgid " (all conflicts fixed: run \"git commit\")"
+msgstr ""
+
+#: wt-status.c:925
+msgid "You are currently bisecting."
+msgstr ""
+
+#: wt-status.c:928
+msgid " (use \"git bisect reset\" to get back to the original branch)"
+msgstr ""
+
+#: wt-status.c:979
msgid "On branch "
msgstr ""
-#: wt-status.c:744
+#: wt-status.c:986
msgid "Not currently on any branch."
msgstr ""
-#: wt-status.c:755
+#: wt-status.c:998
msgid "Initial commit"
msgstr ""
-#: wt-status.c:769
+#: wt-status.c:1012
msgid "Untracked"
msgstr ""
-#: wt-status.c:771
+#: wt-status.c:1014
msgid "Ignored"
msgstr ""
-#: wt-status.c:773
+#: wt-status.c:1016
#, c-format
msgid "Untracked files not listed%s"
msgstr ""
-#: wt-status.c:775
+#: wt-status.c:1018
msgid " (use -u option to show untracked files)"
msgstr ""
-#: wt-status.c:781
+#: wt-status.c:1024
msgid "No changes"
msgstr ""
-#: wt-status.c:785
+#: wt-status.c:1028
#, c-format
msgid "no changes added to commit%s\n"
msgstr ""
-#: wt-status.c:787
+#: wt-status.c:1030
msgid " (use \"git add\" and/or \"git commit -a\")"
msgstr ""
-#: wt-status.c:789
+#: wt-status.c:1032
#, c-format
msgid "nothing added to commit but untracked files present%s\n"
msgstr ""
-#: wt-status.c:791
+#: wt-status.c:1034
msgid " (use \"git add\" to track)"
msgstr ""
-#: wt-status.c:793 wt-status.c:796 wt-status.c:799
+#: wt-status.c:1036 wt-status.c:1039 wt-status.c:1042
#, c-format
msgid "nothing to commit%s\n"
msgstr ""
-#: wt-status.c:794
+#: wt-status.c:1037
msgid " (create/copy files and use \"git add\" to track)"
msgstr ""
-#: wt-status.c:797
+#: wt-status.c:1040
msgid " (use -u to show untracked files)"
msgstr ""
-#: wt-status.c:800
+#: wt-status.c:1043
msgid " (working directory clean)"
msgstr ""
-#: wt-status.c:908
+#: wt-status.c:1151
msgid "HEAD (no branch)"
msgstr ""
-#: wt-status.c:914
+#: wt-status.c:1157
msgid "Initial commit on "
msgstr ""
-#: wt-status.c:929
+#: wt-status.c:1172
msgid "behind "
msgstr ""
-#: wt-status.c:932 wt-status.c:935
+#: wt-status.c:1175 wt-status.c:1178
msgid "ahead "
msgstr ""
-#: wt-status.c:937
+#: wt-status.c:1180
msgid ", behind "
msgstr ""
msgid "Unstaged changes after refreshing the index:"
msgstr ""
-#: builtin/add.c:195 builtin/add.c:456 builtin/rm.c:186
+#: builtin/add.c:195 builtin/add.c:459 builtin/rm.c:186
#, c-format
msgid "pathspec '%s' did not match any files"
msgstr ""
msgid "index file corrupt"
msgstr ""
-#: builtin/add.c:476 builtin/apply.c:4100 builtin/mv.c:229 builtin/rm.c:260
+#: builtin/add.c:480 builtin/apply.c:4108 builtin/mv.c:229 builtin/rm.c:260
msgid "Unable to write new index file"
msgstr ""
msgid "%s: already exists in index"
msgstr ""
-#: builtin/apply.c:3266
+#: builtin/apply.c:3267
#, c-format
-msgid "new mode (%o) of %s does not match old mode (%o)%s%s"
+msgid "new mode (%o) of %s does not match old mode (%o)"
msgstr ""
#: builtin/apply.c:3272
#, c-format
+msgid "new mode (%o) of %s does not match old mode (%o) of %s"
+msgstr ""
+
+#: builtin/apply.c:3280
+#, c-format
msgid "%s: patch does not apply"
msgstr ""
-#: builtin/apply.c:3285
+#: builtin/apply.c:3293
#, c-format
msgid "Checking patch %s..."
msgstr ""
-#: builtin/apply.c:3340 builtin/checkout.c:212 builtin/reset.c:158
+#: builtin/apply.c:3348 builtin/checkout.c:212 builtin/reset.c:158
#, c-format
msgid "make_cache_entry failed for path '%s'"
msgstr ""
-#: builtin/apply.c:3483
+#: builtin/apply.c:3491
#, c-format
msgid "unable to remove %s from index"
msgstr ""
-#: builtin/apply.c:3510
+#: builtin/apply.c:3518
#, c-format
msgid "corrupt patch for subproject %s"
msgstr ""
-#: builtin/apply.c:3514
+#: builtin/apply.c:3522
#, c-format
msgid "unable to stat newly created file '%s'"
msgstr ""
-#: builtin/apply.c:3519
+#: builtin/apply.c:3527
#, c-format
msgid "unable to create backing store for newly created file %s"
msgstr ""
-#: builtin/apply.c:3522
+#: builtin/apply.c:3530
#, c-format
msgid "unable to add cache entry for %s"
msgstr ""
-#: builtin/apply.c:3555
+#: builtin/apply.c:3563
#, c-format
msgid "closing file '%s'"
msgstr ""
-#: builtin/apply.c:3604
+#: builtin/apply.c:3612
#, c-format
msgid "unable to write file '%s' mode %o"
msgstr ""
-#: builtin/apply.c:3660
+#: builtin/apply.c:3668
#, c-format
msgid "Applied patch %s cleanly."
msgstr ""
-#: builtin/apply.c:3668
+#: builtin/apply.c:3676
msgid "internal error"
msgstr ""
#. Say this even without --verbose
-#: builtin/apply.c:3671
+#: builtin/apply.c:3679
#, c-format
msgid "Applying patch %%s with %d reject..."
msgid_plural "Applying patch %%s with %d rejects..."
msgstr[0] ""
msgstr[1] ""
-#: builtin/apply.c:3681
+#: builtin/apply.c:3689
#, c-format
msgid "truncating .rej filename to %.*s.rej"
msgstr ""
-#: builtin/apply.c:3702
+#: builtin/apply.c:3710
#, c-format
msgid "Hunk #%d applied cleanly."
msgstr ""
-#: builtin/apply.c:3705
+#: builtin/apply.c:3713
#, c-format
msgid "Rejected hunk #%d."
msgstr ""
-#: builtin/apply.c:3836
+#: builtin/apply.c:3844
msgid "unrecognized input"
msgstr ""
-#: builtin/apply.c:3847
+#: builtin/apply.c:3855
msgid "unable to read index file"
msgstr ""
-#: builtin/apply.c:3962 builtin/apply.c:3965
+#: builtin/apply.c:3970 builtin/apply.c:3973
msgid "path"
msgstr ""
-#: builtin/apply.c:3963
+#: builtin/apply.c:3971
msgid "don't apply changes matching the given path"
msgstr ""
-#: builtin/apply.c:3966
+#: builtin/apply.c:3974
msgid "apply changes matching the given path"
msgstr ""
-#: builtin/apply.c:3968
+#: builtin/apply.c:3976
msgid "num"
msgstr ""
-#: builtin/apply.c:3969
+#: builtin/apply.c:3977
msgid "remove <num> leading slashes from traditional diff paths"
msgstr ""
-#: builtin/apply.c:3972
+#: builtin/apply.c:3980
msgid "ignore additions made by the patch"
msgstr ""
-#: builtin/apply.c:3974
+#: builtin/apply.c:3982
msgid "instead of applying the patch, output diffstat for the input"
msgstr ""
-#: builtin/apply.c:3978
+#: builtin/apply.c:3986
msgid "shows number of added and deleted lines in decimal notation"
msgstr ""
-#: builtin/apply.c:3980
+#: builtin/apply.c:3988
msgid "instead of applying the patch, output a summary for the input"
msgstr ""
-#: builtin/apply.c:3982
+#: builtin/apply.c:3990
msgid "instead of applying the patch, see if the patch is applicable"
msgstr ""
-#: builtin/apply.c:3984
+#: builtin/apply.c:3992
msgid "make sure the patch is applicable to the current index"
msgstr ""
-#: builtin/apply.c:3986
+#: builtin/apply.c:3994
msgid "apply a patch without touching the working tree"
msgstr ""
-#: builtin/apply.c:3988
+#: builtin/apply.c:3996
msgid "also apply the patch (use with --stat/--summary/--check)"
msgstr ""
-#: builtin/apply.c:3990
+#: builtin/apply.c:3998
msgid "build a temporary index based on embedded index information"
msgstr ""
-#: builtin/apply.c:3992
+#: builtin/apply.c:4000
msgid "paths are separated with NUL character"
msgstr ""
-#: builtin/apply.c:3995
+#: builtin/apply.c:4003
msgid "ensure at least <n> lines of context match"
msgstr ""
-#: builtin/apply.c:3996
+#: builtin/apply.c:4004
msgid "action"
msgstr ""
-#: builtin/apply.c:3997
+#: builtin/apply.c:4005
msgid "detect new or modified lines that have whitespace errors"
msgstr ""
-#: builtin/apply.c:4000 builtin/apply.c:4003
+#: builtin/apply.c:4008 builtin/apply.c:4011
msgid "ignore changes in whitespace when finding context"
msgstr ""
-#: builtin/apply.c:4006
+#: builtin/apply.c:4014
msgid "apply the patch in reverse"
msgstr ""
-#: builtin/apply.c:4008
+#: builtin/apply.c:4016
msgid "don't expect at least one line of context"
msgstr ""
-#: builtin/apply.c:4010
+#: builtin/apply.c:4018
msgid "leave the rejected hunks in corresponding *.rej files"
msgstr ""
-#: builtin/apply.c:4012
+#: builtin/apply.c:4020
msgid "allow overlapping hunks"
msgstr ""
-#: builtin/apply.c:4013
+#: builtin/apply.c:4021
msgid "be verbose"
msgstr ""
-#: builtin/apply.c:4015
+#: builtin/apply.c:4023
msgid "tolerate incorrectly detected missing new-line at the end of file"
msgstr ""
-#: builtin/apply.c:4018
+#: builtin/apply.c:4026
msgid "do not trust the line counts in the hunk headers"
msgstr ""
-#: builtin/apply.c:4020
+#: builtin/apply.c:4028
msgid "root"
msgstr ""
-#: builtin/apply.c:4021
+#: builtin/apply.c:4029
msgid "prepend <root> to all filenames"
msgstr ""
-#: builtin/apply.c:4042
+#: builtin/apply.c:4050
msgid "--index outside a repository"
msgstr ""
-#: builtin/apply.c:4045
+#: builtin/apply.c:4053
msgid "--cached outside a repository"
msgstr ""
-#: builtin/apply.c:4061
+#: builtin/apply.c:4069
#, c-format
msgid "can't open patch '%s'"
msgstr ""
-#: builtin/apply.c:4075
+#: builtin/apply.c:4083
#, c-format
msgid "squelched %d whitespace error"
msgid_plural "squelched %d whitespace errors"
msgstr[0] ""
msgstr[1] ""
-#: builtin/apply.c:4081 builtin/apply.c:4091
+#: builtin/apply.c:4089 builtin/apply.c:4099
#, c-format
msgid "%d line adds whitespace errors."
msgid_plural "%d lines add whitespace errors."
msgid "malformed --author parameter"
msgstr ""
-#: builtin/commit.c:583
+#: builtin/commit.c:582
#, c-format
msgid "Malformed ident string: '%s'"
msgstr ""
-#: builtin/commit.c:621 builtin/commit.c:654 builtin/commit.c:968
+#: builtin/commit.c:620 builtin/commit.c:653 builtin/commit.c:967
#, c-format
msgid "could not lookup commit %s"
msgstr ""
-#: builtin/commit.c:633 builtin/shortlog.c:296
+#: builtin/commit.c:632 builtin/shortlog.c:296
#, c-format
msgid "(reading log message from standard input)\n"
msgstr ""
-#: builtin/commit.c:635
+#: builtin/commit.c:634
msgid "could not read log from standard input"
msgstr ""
-#: builtin/commit.c:639
+#: builtin/commit.c:638
#, c-format
msgid "could not read log file '%s'"
msgstr ""
-#: builtin/commit.c:645
+#: builtin/commit.c:644
msgid "commit has empty message"
msgstr ""
-#: builtin/commit.c:661
+#: builtin/commit.c:660
msgid "could not read MERGE_MSG"
msgstr ""
-#: builtin/commit.c:665
+#: builtin/commit.c:664
msgid "could not read SQUASH_MSG"
msgstr ""
-#: builtin/commit.c:669
+#: builtin/commit.c:668
#, c-format
msgid "could not read '%s'"
msgstr ""
-#: builtin/commit.c:721
+#: builtin/commit.c:720
msgid "could not write commit template"
msgstr ""
-#: builtin/commit.c:732
+#: builtin/commit.c:731
#, c-format
msgid ""
"\n"
"and try again.\n"
msgstr ""
-#: builtin/commit.c:737
+#: builtin/commit.c:736
#, c-format
msgid ""
"\n"
"and try again.\n"
msgstr ""
-#: builtin/commit.c:749
+#: builtin/commit.c:748
msgid ""
"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be ignored, and an empty message aborts the commit.\n"
msgstr ""
-#: builtin/commit.c:754
+#: builtin/commit.c:753
msgid ""
"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be kept; you may remove them yourself if you want to.\n"
"An empty message aborts the commit.\n"
msgstr ""
-#: builtin/commit.c:767
+#: builtin/commit.c:766
#, c-format
msgid "%sAuthor: %s"
msgstr ""
-#: builtin/commit.c:774
+#: builtin/commit.c:773
#, c-format
msgid "%sCommitter: %s"
msgstr ""
-#: builtin/commit.c:794
+#: builtin/commit.c:793
msgid "Cannot read index"
msgstr ""
-#: builtin/commit.c:831
+#: builtin/commit.c:830
msgid "Error building trees"
msgstr ""
-#: builtin/commit.c:846 builtin/tag.c:361
+#: builtin/commit.c:845 builtin/tag.c:361
#, c-format
msgid "Please supply the message using either -m or -F option.\n"
msgstr ""
-#: builtin/commit.c:943
+#: builtin/commit.c:942
#, c-format
msgid "No existing author found with '%s'"
msgstr ""
-#: builtin/commit.c:958 builtin/commit.c:1158
+#: builtin/commit.c:957 builtin/commit.c:1157
#, c-format
msgid "Invalid untracked files mode '%s'"
msgstr ""
-#: builtin/commit.c:998
+#: builtin/commit.c:997
msgid "Using both --reset-author and --author does not make sense"
msgstr ""
-#: builtin/commit.c:1009
+#: builtin/commit.c:1008
msgid "You have nothing to amend."
msgstr ""
-#: builtin/commit.c:1012
+#: builtin/commit.c:1011
msgid "You are in the middle of a merge -- cannot amend."
msgstr ""
-#: builtin/commit.c:1014
+#: builtin/commit.c:1013
msgid "You are in the middle of a cherry-pick -- cannot amend."
msgstr ""
-#: builtin/commit.c:1017
+#: builtin/commit.c:1016
msgid "Options --squash and --fixup cannot be used together"
msgstr ""
-#: builtin/commit.c:1027
+#: builtin/commit.c:1026
msgid "Only one of -c/-C/-F/--fixup can be used."
msgstr ""
-#: builtin/commit.c:1029
+#: builtin/commit.c:1028
msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
msgstr ""
-#: builtin/commit.c:1037
+#: builtin/commit.c:1036
msgid "--reset-author can be used only with -C, -c or --amend."
msgstr ""
-#: builtin/commit.c:1054
+#: builtin/commit.c:1053
msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
msgstr ""
-#: builtin/commit.c:1056
+#: builtin/commit.c:1055
msgid "No paths with --include/--only does not make sense."
msgstr ""
-#: builtin/commit.c:1058
+#: builtin/commit.c:1057
msgid "Clever... amending the last one with dirty index."
msgstr ""
-#: builtin/commit.c:1060
+#: builtin/commit.c:1059
msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
msgstr ""
-#: builtin/commit.c:1070 builtin/tag.c:577
+#: builtin/commit.c:1069 builtin/tag.c:577
#, c-format
msgid "Invalid cleanup mode %s"
msgstr ""
-#: builtin/commit.c:1075
+#: builtin/commit.c:1074
msgid "Paths with -a does not make sense."
msgstr ""
-#: builtin/commit.c:1258
+#: builtin/commit.c:1257
msgid "couldn't look up newly created commit"
msgstr ""
-#: builtin/commit.c:1260
+#: builtin/commit.c:1259
msgid "could not parse newly created commit"
msgstr ""
-#: builtin/commit.c:1301
+#: builtin/commit.c:1300
msgid "detached HEAD"
msgstr ""
-#: builtin/commit.c:1303
+#: builtin/commit.c:1302
msgid " (root-commit)"
msgstr ""
-#: builtin/commit.c:1447
+#: builtin/commit.c:1446
msgid "could not parse HEAD commit"
msgstr ""
-#: builtin/commit.c:1485 builtin/merge.c:509
+#: builtin/commit.c:1484 builtin/merge.c:509
#, c-format
msgid "could not open '%s' for reading"
msgstr ""
-#: builtin/commit.c:1492
+#: builtin/commit.c:1491
#, c-format
msgid "Corrupt MERGE_HEAD file (%s)"
msgstr ""
-#: builtin/commit.c:1499
+#: builtin/commit.c:1498
msgid "could not read MERGE_MODE"
msgstr ""
-#: builtin/commit.c:1518
+#: builtin/commit.c:1517
#, c-format
msgid "could not read commit message: %s"
msgstr ""
-#: builtin/commit.c:1532
+#: builtin/commit.c:1531
#, c-format
msgid "Aborting commit; you did not edit the message.\n"
msgstr ""
-#: builtin/commit.c:1537
+#: builtin/commit.c:1536
#, c-format
msgid "Aborting commit due to empty commit message.\n"
msgstr ""
-#: builtin/commit.c:1552 builtin/merge.c:936 builtin/merge.c:961
+#: builtin/commit.c:1551 builtin/merge.c:936 builtin/merge.c:961
msgid "failed to write commit object"
msgstr ""
-#: builtin/commit.c:1573
+#: builtin/commit.c:1572
msgid "cannot lock HEAD ref"
msgstr ""
-#: builtin/commit.c:1577
+#: builtin/commit.c:1576
msgid "cannot update HEAD ref"
msgstr ""
-#: builtin/commit.c:1588
+#: builtin/commit.c:1587
msgid ""
"Repository has been updated, but unable to write\n"
"new_index file. Check that disk is not full or quota is\n"
msgid "Not a git repository"
msgstr ""
-#: builtin/diff.c:347
+#: builtin/diff.c:341
#, c-format
msgid "invalid object '%s' given."
msgstr ""
-#: builtin/diff.c:352
+#: builtin/diff.c:346
#, c-format
msgid "more than %d trees given: '%s'"
msgstr ""
-#: builtin/diff.c:362
+#: builtin/diff.c:356
#, c-format
msgid "more than two blobs given: '%s'"
msgstr ""
-#: builtin/diff.c:370
+#: builtin/diff.c:364
#, c-format
msgid "unhandled object '%s' given."
msgstr ""
msgid "cannot open '%s'"
msgstr ""
-#: builtin/grep.c:888
+#: builtin/grep.c:885
msgid "no pattern given."
msgstr ""
-#: builtin/grep.c:902
+#: builtin/grep.c:899
#, c-format
msgid "bad object %s"
msgstr ""
-#: builtin/grep.c:943
+#: builtin/grep.c:940
msgid "--open-files-in-pager only works on the worktree"
msgstr ""
-#: builtin/grep.c:966
+#: builtin/grep.c:963
msgid "--cached or --untracked cannot be used with --no-index."
msgstr ""
-#: builtin/grep.c:971
+#: builtin/grep.c:968
msgid "--no-index or --untracked cannot be used with revs."
msgstr ""
-#: builtin/grep.c:974
+#: builtin/grep.c:971
msgid "--[no-]exclude-standard cannot be used for tracked contents."
msgstr ""
-#: builtin/grep.c:982
+#: builtin/grep.c:979
msgid "both --cached and trees are given."
msgstr ""
-#: builtin/help.c:59
+#: builtin/help.c:63
#, c-format
msgid "unrecognized help format '%s'"
msgstr ""
-#: builtin/help.c:87
+#: builtin/help.c:91
msgid "Failed to start emacsclient."
msgstr ""
-#: builtin/help.c:100
+#: builtin/help.c:104
msgid "Failed to parse emacsclient version."
msgstr ""
-#: builtin/help.c:108
+#: builtin/help.c:112
#, c-format
msgid "emacsclient version '%d' too old (< 22)."
msgstr ""
-#: builtin/help.c:126 builtin/help.c:154 builtin/help.c:163 builtin/help.c:171
+#: builtin/help.c:130 builtin/help.c:158 builtin/help.c:167 builtin/help.c:175
#, c-format
msgid "failed to exec '%s': %s"
msgstr ""
-#: builtin/help.c:211
+#: builtin/help.c:215
#, c-format
msgid ""
"'%s': path for unsupported man viewer.\n"
"Please consider using 'man.<tool>.cmd' instead."
msgstr ""
-#: builtin/help.c:223
+#: builtin/help.c:227
#, c-format
msgid ""
"'%s': cmd for supported man viewer.\n"
"Please consider using 'man.<tool>.path' instead."
msgstr ""
-#: builtin/help.c:287
+#: builtin/help.c:291
msgid "The most commonly used git commands are:"
msgstr ""
-#: builtin/help.c:355
+#: builtin/help.c:359
#, c-format
msgid "'%s': unknown man viewer."
msgstr ""
-#: builtin/help.c:372
+#: builtin/help.c:376
msgid "no man viewer handled the request"
msgstr ""
-#: builtin/help.c:380
+#: builtin/help.c:384
msgid "no info viewer handled the request"
msgstr ""
-#: builtin/help.c:391
+#: builtin/help.c:395
#, c-format
msgid "'%s': not a documentation directory."
msgstr ""
-#: builtin/help.c:432 builtin/help.c:439
+#: builtin/help.c:436 builtin/help.c:443
#, c-format
msgid "usage: %s%s"
msgstr ""
-#: builtin/help.c:453
+#: builtin/help.c:459
#, c-format
msgid "`git %s' is aliased to `%s'"
msgstr ""
-#: builtin/index-pack.c:169
+#: builtin/index-pack.c:170
#, c-format
msgid "object type mismatch at %s"
msgstr ""
-#: builtin/index-pack.c:189
+#: builtin/index-pack.c:190
msgid "object of unexpected type"
msgstr ""
-#: builtin/index-pack.c:226
+#: builtin/index-pack.c:227
#, c-format
msgid "cannot fill %d byte"
msgid_plural "cannot fill %d bytes"
msgstr[0] ""
msgstr[1] ""
-#: builtin/index-pack.c:236
+#: builtin/index-pack.c:237
msgid "early EOF"
msgstr ""
-#: builtin/index-pack.c:237
+#: builtin/index-pack.c:238
msgid "read error on input"
msgstr ""
-#: builtin/index-pack.c:249
+#: builtin/index-pack.c:250
msgid "used more bytes than were available"
msgstr ""
-#: builtin/index-pack.c:256
+#: builtin/index-pack.c:257
msgid "pack too large for current definition of off_t"
msgstr ""
-#: builtin/index-pack.c:272
+#: builtin/index-pack.c:273
#, c-format
msgid "unable to create '%s'"
msgstr ""
-#: builtin/index-pack.c:277
+#: builtin/index-pack.c:278
#, c-format
msgid "cannot open packfile '%s'"
msgstr ""
-#: builtin/index-pack.c:291
+#: builtin/index-pack.c:292
msgid "pack signature mismatch"
msgstr ""
-#: builtin/index-pack.c:311
+#: builtin/index-pack.c:312
#, c-format
msgid "pack has bad object at offset %lu: %s"
msgstr ""
-#: builtin/index-pack.c:405
+#: builtin/index-pack.c:434
#, c-format
msgid "inflate returned %d"
msgstr ""
-#: builtin/index-pack.c:450
+#: builtin/index-pack.c:483
msgid "offset value overflow for delta base object"
msgstr ""
-#: builtin/index-pack.c:458
+#: builtin/index-pack.c:491
msgid "delta base offset is out of bound"
msgstr ""
-#: builtin/index-pack.c:466
+#: builtin/index-pack.c:499
#, c-format
msgid "unknown object type %d"
msgstr ""
-#: builtin/index-pack.c:495
+#: builtin/index-pack.c:531
msgid "cannot pread pack file"
msgstr ""
-#: builtin/index-pack.c:497
+#: builtin/index-pack.c:533
#, c-format
msgid "premature end of pack file, %lu byte missing"
msgid_plural "premature end of pack file, %lu bytes missing"
msgstr[0] ""
msgstr[1] ""
-#: builtin/index-pack.c:510
+#: builtin/index-pack.c:555
msgid "serious inflate inconsistency"
msgstr ""
-#: builtin/index-pack.c:583
+#: builtin/index-pack.c:646 builtin/index-pack.c:652 builtin/index-pack.c:675
+#: builtin/index-pack.c:709 builtin/index-pack.c:718
#, c-format
-msgid "cannot read existing object %s"
+msgid "SHA1 COLLISION FOUND WITH %s !"
msgstr ""
-#: builtin/index-pack.c:586
+#: builtin/index-pack.c:649 builtin/pack-objects.c:170
+#: builtin/pack-objects.c:262
#, c-format
-msgid "SHA1 COLLISION FOUND WITH %s !"
+msgid "unable to read %s"
+msgstr ""
+
+#: builtin/index-pack.c:715
+#, c-format
+msgid "cannot read existing object %s"
msgstr ""
-#: builtin/index-pack.c:598
+#: builtin/index-pack.c:729
#, c-format
msgid "invalid blob object %s"
msgstr ""
-#: builtin/index-pack.c:610
+#: builtin/index-pack.c:744
#, c-format
msgid "invalid %s"
msgstr ""
-#: builtin/index-pack.c:612
+#: builtin/index-pack.c:746
msgid "Error in object"
msgstr ""
-#: builtin/index-pack.c:614
+#: builtin/index-pack.c:748
#, c-format
msgid "Not all child objects of %s are reachable"
msgstr ""
-#: builtin/index-pack.c:687 builtin/index-pack.c:713
+#: builtin/index-pack.c:818 builtin/index-pack.c:844
msgid "failed to apply delta"
msgstr ""
-#: builtin/index-pack.c:850
+#: builtin/index-pack.c:983
msgid "Receiving objects"
msgstr ""
-#: builtin/index-pack.c:850
+#: builtin/index-pack.c:983
msgid "Indexing objects"
msgstr ""
-#: builtin/index-pack.c:872
+#: builtin/index-pack.c:1009
msgid "pack is corrupted (SHA1 mismatch)"
msgstr ""
-#: builtin/index-pack.c:877
+#: builtin/index-pack.c:1014
msgid "cannot fstat packfile"
msgstr ""
-#: builtin/index-pack.c:880
+#: builtin/index-pack.c:1017
msgid "pack has junk at the end"
msgstr ""
-#: builtin/index-pack.c:903
+#: builtin/index-pack.c:1028
+msgid "confusion beyond insanity in parse_pack_objects()"
+msgstr ""
+
+#: builtin/index-pack.c:1051
msgid "Resolving deltas"
msgstr ""
-#: builtin/index-pack.c:954
+#: builtin/index-pack.c:1102
msgid "confusion beyond insanity"
msgstr ""
-#: builtin/index-pack.c:973
+#: builtin/index-pack.c:1121
#, c-format
msgid "pack has %d unresolved delta"
msgid_plural "pack has %d unresolved deltas"
msgstr[0] ""
msgstr[1] ""
-#: builtin/index-pack.c:998
+#: builtin/index-pack.c:1146
#, c-format
msgid "unable to deflate appended object (%d)"
msgstr ""
-#: builtin/index-pack.c:1077
+#: builtin/index-pack.c:1225
#, c-format
msgid "local object %s is corrupt"
msgstr ""
-#: builtin/index-pack.c:1101
+#: builtin/index-pack.c:1249
msgid "error while closing pack file"
msgstr ""
-#: builtin/index-pack.c:1114
+#: builtin/index-pack.c:1262
#, c-format
msgid "cannot write keep file '%s'"
msgstr ""
-#: builtin/index-pack.c:1122
+#: builtin/index-pack.c:1270
#, c-format
msgid "cannot close written keep file '%s'"
msgstr ""
-#: builtin/index-pack.c:1135
+#: builtin/index-pack.c:1283
msgid "cannot store pack file"
msgstr ""
-#: builtin/index-pack.c:1146
+#: builtin/index-pack.c:1294
msgid "cannot store index file"
msgstr ""
-#: builtin/index-pack.c:1247
+#: builtin/index-pack.c:1395
#, c-format
msgid "Cannot open existing pack file '%s'"
msgstr ""
-#: builtin/index-pack.c:1249
+#: builtin/index-pack.c:1397
#, c-format
msgid "Cannot open existing pack idx file for '%s'"
msgstr ""
-#: builtin/index-pack.c:1296
+#: builtin/index-pack.c:1444
#, c-format
msgid "non delta: %d object"
msgid_plural "non delta: %d objects"
msgstr[0] ""
msgstr[1] ""
-#: builtin/index-pack.c:1303
+#: builtin/index-pack.c:1451
#, c-format
msgid "chain length = %d: %lu object"
msgid_plural "chain length = %d: %lu objects"
msgstr[0] ""
msgstr[1] ""
-#: builtin/index-pack.c:1330
+#: builtin/index-pack.c:1478
msgid "Cannot come back to cwd"
msgstr ""
-#: builtin/index-pack.c:1374 builtin/index-pack.c:1377
-#: builtin/index-pack.c:1389 builtin/index-pack.c:1393
+#: builtin/index-pack.c:1522 builtin/index-pack.c:1525
+#: builtin/index-pack.c:1537 builtin/index-pack.c:1541
#, c-format
msgid "bad %s"
msgstr ""
-#: builtin/index-pack.c:1407
+#: builtin/index-pack.c:1555
msgid "--fix-thin cannot be used without --stdin"
msgstr ""
-#: builtin/index-pack.c:1411 builtin/index-pack.c:1421
+#: builtin/index-pack.c:1559 builtin/index-pack.c:1569
#, c-format
msgid "packfile name '%s' does not end with '.pack'"
msgstr ""
-#: builtin/index-pack.c:1430
+#: builtin/index-pack.c:1578
msgid "--verify with no packfile name given"
msgstr ""
msgid "Cannot access work tree '%s'"
msgstr ""
-#: builtin/log.c:188
+#: builtin/log.c:189
#, c-format
msgid "Final output: %d %s\n"
msgstr ""
-#: builtin/log.c:401 builtin/log.c:489
+#: builtin/log.c:402 builtin/log.c:490
#, c-format
msgid "Could not read object %s"
msgstr ""
-#: builtin/log.c:513
+#: builtin/log.c:514
#, c-format
msgid "Unknown type: %d"
msgstr ""
-#: builtin/log.c:602
+#: builtin/log.c:603
msgid "format.headers without value"
msgstr ""
-#: builtin/log.c:675
+#: builtin/log.c:677
msgid "name of output directory is too long"
msgstr ""
-#: builtin/log.c:686
+#: builtin/log.c:688
#, c-format
msgid "Cannot open patch file %s"
msgstr ""
-#: builtin/log.c:700
+#: builtin/log.c:702
msgid "Need exactly one range."
msgstr ""
-#: builtin/log.c:708
+#: builtin/log.c:710
msgid "Not a range."
msgstr ""
-#: builtin/log.c:745
-msgid "Could not extract email from committer identity."
-msgstr ""
-
-#: builtin/log.c:791
+#: builtin/log.c:787
msgid "Cover letter needs email format"
msgstr ""
-#: builtin/log.c:885
+#: builtin/log.c:860
#, c-format
msgid "insane in-reply-to: %s"
msgstr ""
-#: builtin/log.c:958
+#: builtin/log.c:933
msgid "Two output directories?"
msgstr ""
-#: builtin/log.c:1179
+#: builtin/log.c:1154
#, c-format
msgid "bogus committer info %s"
msgstr ""
-#: builtin/log.c:1224
+#: builtin/log.c:1199
msgid "-n and -k are mutually exclusive."
msgstr ""
-#: builtin/log.c:1226
+#: builtin/log.c:1201
msgid "--subject-prefix and -k are mutually exclusive."
msgstr ""
-#: builtin/log.c:1234
+#: builtin/log.c:1209
msgid "--name-only does not make sense"
msgstr ""
-#: builtin/log.c:1236
+#: builtin/log.c:1211
msgid "--name-status does not make sense"
msgstr ""
-#: builtin/log.c:1238
+#: builtin/log.c:1213
msgid "--check does not make sense"
msgstr ""
-#: builtin/log.c:1261
+#: builtin/log.c:1236
msgid "standard output, or directory, which one?"
msgstr ""
-#: builtin/log.c:1263
+#: builtin/log.c:1238
#, c-format
msgid "Could not create directory '%s'"
msgstr ""
-#: builtin/log.c:1416
+#: builtin/log.c:1391
msgid "Failed to create output files"
msgstr ""
-#: builtin/log.c:1520
+#: builtin/log.c:1495
#, c-format
msgid ""
"Could not find a tracked remote branch, please specify <upstream> manually.\n"
msgstr ""
-#: builtin/log.c:1536 builtin/log.c:1538 builtin/log.c:1550
+#: builtin/log.c:1511 builtin/log.c:1513 builtin/log.c:1525
#, c-format
msgid "Unknown commit %s"
msgstr ""
msgid "Unknown subcommand: %s"
msgstr ""
-#: builtin/pack-objects.c:2315
+#: builtin/pack-objects.c:183 builtin/pack-objects.c:186
+#, c-format
+msgid "deflate error (%d)"
+msgstr ""
+
+#: builtin/pack-objects.c:2398
#, c-format
msgid "unsupported index version %s"
msgstr ""
-#: builtin/pack-objects.c:2319
+#: builtin/pack-objects.c:2402
#, c-format
msgid "bad index version '%s'"
msgstr ""
-#: builtin/pack-objects.c:2342
+#: builtin/pack-objects.c:2425
#, c-format
msgid "option %s does not accept negative form"
msgstr ""
-#: builtin/pack-objects.c:2346
+#: builtin/pack-objects.c:2429
#, c-format
msgid "unable to parse value '%s' for option %s"
msgstr ""
#: builtin/remote.c:677
#, c-format
msgid ""
-"Not updating non-default fetch respec\n"
+"Not updating non-default fetch refspec\n"
"\t%s\n"
"\tPlease update the configuration manually if necessary."
msgstr ""
msgid "You need to set your committer info first"
msgstr ""
+#: git-am.sh:95
+msgid ""
+"You seem to have moved HEAD since the last 'am' failure.\n"
+"Not rewinding to ORIG_HEAD"
+msgstr ""
+
+#: git-am.sh:105
+#, sh-format
+msgid ""
+"When you have resolved this problem run \"$cmdline --resolved\".\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+
+#: git-am.sh:121
+msgid "Cannot fall back to three-way merge."
+msgstr ""
+
#: git-am.sh:137
msgid "Repository lacks necessary blobs to fall back on 3-way merge."
msgstr ""
msgid "Dirty index: cannot apply patches (dirty: $files)"
msgstr ""
+#: git-am.sh:671
+#, sh-format
+msgid ""
+"Patch is empty. Was it split wrong?\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+
+#: git-am.sh:708
+msgid "Patch does not have a valid e-mail address."
+msgstr ""
+
#: git-am.sh:755
msgid "cannot be interactive without stdin connected to a terminal."
msgstr ""
+#: git-am.sh:759
+msgid "Commit Body is:"
+msgstr ""
+
#. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
#. in your translation. The program will only accept English
#. input at this point.
msgid "Applying: $FIRSTLINE"
msgstr ""
+#: git-am.sh:823
+msgid ""
+"No changes - did you forget to use 'git add'?\n"
+"If there is nothing left to stage, chances are that something else\n"
+"already introduced the same changes; you might want to skip this patch."
+msgstr ""
+
+#: git-am.sh:831
+msgid ""
+"You still have unmerged paths in your index\n"
+"did you forget to use 'git add'?"
+msgstr ""
+
#: git-am.sh:847
msgid "No changes -- Patch already applied."
msgstr ""
+#: git-am.sh:857
+#, sh-format
+msgid "Patch failed at $msgnum $FIRSTLINE"
+msgstr ""
+
#: git-am.sh:873
msgid "applying to an empty history"
msgstr ""
+#: git-bisect.sh:48
+msgid "You need to start by \"git bisect start\""
+msgstr ""
+
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
#. at this point.
msgid "'git bisect bad' can take only one argument."
msgstr ""
+#. have bad but not good. we could bisect although
+#. this is less optimum.
+#: git-bisect.sh:273
+msgid "Warning: bisecting only with a bad commit."
+msgstr ""
+
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
#. at this point.
msgid "Are you sure [Y/n]? "
msgstr ""
+#: git-bisect.sh:289
+msgid ""
+"You need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+
+#: git-bisect.sh:292
+msgid ""
+"You need to start by \"git bisect start\".\n"
+"You then need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+
+#: git-bisect.sh:347 git-bisect.sh:474
+msgid "We are not bisecting."
+msgstr ""
+
#: git-bisect.sh:354
#, sh-format
msgid "'$invalid' is not a valid commit"
msgid "?? what are you talking about?"
msgstr ""
-#: git-bisect.sh:474
-msgid "We are not bisecting."
+#: git-bisect.sh:420
+#, sh-format
+msgid "running $command"
+msgstr ""
+
+#: git-bisect.sh:427
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"exit code $res from '$command' is < 0 or >= 128"
+msgstr ""
+
+#: git-bisect.sh:453
+msgid "bisect run cannot continue any more"
+msgstr ""
+
+#: git-bisect.sh:459
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"'bisect_state $state' exited with error code $res"
+msgstr ""
+
+#: git-bisect.sh:466
+msgid "bisect run success"
msgstr ""
#: git-pull.sh:21
msgid "updating an unborn branch with changes added to the index"
msgstr ""
+#. The fetch involved updating the current branch.
+#. The working tree and the index file is still based on the
+#. $orig_head commit, but we are merging into $curr_head.
+#. First update the working tree to match $curr_head.
+#: git-pull.sh:228
+#, sh-format
+msgid ""
+"Warning: fetch updated the current branch head.\n"
+"Warning: fast-forwarding your working tree from\n"
+"Warning: commit $orig_head."
+msgstr ""
+
#: git-pull.sh:253
msgid "Cannot merge multiple branches into empty head"
msgstr ""
msgid "Cannot record working tree state"
msgstr ""
+#. TRANSLATORS: $option is an invalid option, like
+#. `--blah-blah'. The 7 spaces at the beginning of the
+#. second line correspond to "error: ". So you should line
+#. up the second line with however many characters the
+#. translation of "error: " takes in your language. E.g. in
+#. English this is:
+#.
+#. $ git stash save --blah-blah 2>&1 | head -n 2
+#. error: unknown option for 'stash save': --blah-blah
+#. To provide a message, use git stash save -- '--blah-blah'
+#: git-stash.sh:202
+#, sh-format
+msgid ""
+"error: unknown option for 'stash save': $option\n"
+" To provide a message, use git stash save -- '$option'"
+msgstr ""
+
#: git-stash.sh:223
msgid "No local changes to save"
msgstr ""
msgid "Cannot unstage modified files"
msgstr ""
+#: git-stash.sh:474
+msgid "Index was not unstashed."
+msgstr ""
+
#: git-stash.sh:491
#, sh-format
msgid "Dropped ${REV} ($s)"
msgid "(To restore them type \"git stash apply\")"
msgstr ""
-#: git-submodule.sh:56
+#: git-submodule.sh:88
#, sh-format
msgid "cannot strip one component off url '$remoteurl'"
msgstr ""
-#: git-submodule.sh:109
+#: git-submodule.sh:145
#, sh-format
msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
msgstr ""
-#: git-submodule.sh:150
+#: git-submodule.sh:186
#, sh-format
msgid "Clone of '$url' into submodule path '$sm_path' failed"
msgstr ""
-#: git-submodule.sh:160
+#: git-submodule.sh:196
#, sh-format
msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
msgstr ""
-#: git-submodule.sh:249
+#: git-submodule.sh:285
#, sh-format
msgid "repo URL: '$repo' must be absolute or begin with ./|../"
msgstr ""
-#: git-submodule.sh:266
+#: git-submodule.sh:302
#, sh-format
msgid "'$sm_path' already exists in the index"
msgstr ""
-#: git-submodule.sh:283
+#: git-submodule.sh:306
+#, sh-format
+msgid ""
+"The following path is ignored by one of your .gitignore files:\n"
+"$sm_path\n"
+"Use -f if you really want to add it."
+msgstr ""
+
+#: git-submodule.sh:317
+#, sh-format
+msgid "Adding existing repo at '$sm_path' to the index"
+msgstr ""
+
+#: git-submodule.sh:319
#, sh-format
msgid "'$sm_path' already exists and is not a valid git repo"
msgstr ""
-#: git-submodule.sh:297
+#: git-submodule.sh:333
#, sh-format
msgid "Unable to checkout submodule '$sm_path'"
msgstr ""
-#: git-submodule.sh:302
+#: git-submodule.sh:338
#, sh-format
msgid "Failed to add submodule '$sm_path'"
msgstr ""
-#: git-submodule.sh:307
+#: git-submodule.sh:343
#, sh-format
msgid "Failed to register submodule '$sm_path'"
msgstr ""
-#: git-submodule.sh:349
+#: git-submodule.sh:385
#, sh-format
msgid "Entering '$prefix$sm_path'"
msgstr ""
-#: git-submodule.sh:363
+#: git-submodule.sh:399
#, sh-format
msgid "Stopping at '$sm_path'; script returned non-zero status."
msgstr ""
-#: git-submodule.sh:405
+#: git-submodule.sh:442
#, sh-format
msgid "No url found for submodule path '$sm_path' in .gitmodules"
msgstr ""
-#: git-submodule.sh:414
+#: git-submodule.sh:451
#, sh-format
msgid "Failed to register url for submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:422
+#: git-submodule.sh:453
#, sh-format
-msgid "Failed to register update mode for submodule path '$sm_path'"
+msgid "Submodule '$name' ($url) registered for path '$sm_path'"
msgstr ""
-#: git-submodule.sh:424
+#: git-submodule.sh:461
#, sh-format
-msgid "Submodule '$name' ($url) registered for path '$sm_path'"
+msgid "Failed to register update mode for submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:523
+#: git-submodule.sh:560
#, sh-format
msgid ""
"Submodule path '$sm_path' not initialized\n"
"Maybe you want to use 'update --init'?"
msgstr ""
-#: git-submodule.sh:536
+#: git-submodule.sh:573
#, sh-format
msgid "Unable to find current revision in submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:555
+#: git-submodule.sh:592
#, sh-format
msgid "Unable to fetch in submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:569
+#: git-submodule.sh:606
#, sh-format
msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:570
+#: git-submodule.sh:607
#, sh-format
msgid "Submodule path '$sm_path': rebased into '$sha1'"
msgstr ""
-#: git-submodule.sh:575
+#: git-submodule.sh:612
#, sh-format
msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:576
+#: git-submodule.sh:613
#, sh-format
msgid "Submodule path '$sm_path': merged in '$sha1'"
msgstr ""
-#: git-submodule.sh:581
+#: git-submodule.sh:618
#, sh-format
msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:582
+#: git-submodule.sh:619
#, sh-format
msgid "Submodule path '$sm_path': checked out '$sha1'"
msgstr ""
-#: git-submodule.sh:604 git-submodule.sh:927
+#: git-submodule.sh:641 git-submodule.sh:964
#, sh-format
msgid "Failed to recurse into submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:712
-msgid "--"
+#: git-submodule.sh:749
+msgid "--cached cannot be used with --files"
msgstr ""
-#: git-submodule.sh:770
+#. unexpected type
+#: git-submodule.sh:789
+#, sh-format
+msgid "unexpected mode $mod_dst"
+msgstr ""
+
+#: git-submodule.sh:807
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_src"
msgstr ""
-#: git-submodule.sh:773
+#: git-submodule.sh:810
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_dst"
msgstr ""
-#: git-submodule.sh:776
+#: git-submodule.sh:813
#, sh-format
msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
msgstr ""
-#: git-submodule.sh:801
+#: git-submodule.sh:838
msgid "blob"
msgstr ""
-#: git-submodule.sh:802
+#: git-submodule.sh:839
msgid "submodule"
msgstr ""
-#: git-submodule.sh:973
+#: git-submodule.sh:876
+msgid "# Submodules changed but not updated:"
+msgstr ""
+
+#: git-submodule.sh:878
+msgid "# Submodule changes to be committed:"
+msgstr ""
+
+#: git-submodule.sh:1022
#, sh-format
msgid "Synchronizing submodule url for '$name'"
msgstr ""
# Italian translations for Git.
# Copyright (C) 2012 Marco Paolone <marcopaolone@gmail.com>
# This file is distributed under the same license as the Git package.
-
msgid ""
msgstr ""
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-05-21 08:57+0800\n"
-"PO-Revision-Date: 2012-05-29 22:58+0200\n"
+"POT-Creation-Date: 2012-06-08 10:20+0800\n"
+"PO-Revision-Date: 2012-06-14 14:13+0200\n"
"Last-Translator: Marco Paolone <marcopaolone@gmail.com>\n"
"Language-Team: Italian\n"
"Language: it\n"
msgstr ""
#: bundle.c:63
-#, c-format, fuzzy
+#, c-format
msgid "unrecognized header: %s%s (%d)"
msgstr "header non riconosciuto: %s%s (%d)"
-#: bundle.c:89 builtin/commit.c:697
+#: bundle.c:89 builtin/commit.c:696
#, c-format
msgid "could not open '%s'"
msgstr "non è stato possibile aprire '%s'"
msgid "Repository lacks these prerequisite commits:"
msgstr ""
-#: bundle.c:164 sequencer.c:533 sequencer.c:965 builtin/log.c:289
-#: builtin/log.c:719 builtin/log.c:1335 builtin/log.c:1554 builtin/merge.c:347
+#: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:289
+#: builtin/log.c:720 builtin/log.c:1309 builtin/log.c:1528 builtin/merge.c:347
#: builtin/shortlog.c:181
msgid "revision walk setup failed"
msgstr ""
msgid "rev-list died"
msgstr ""
-#: bundle.c:296 builtin/log.c:1231 builtin/shortlog.c:284
+#: bundle.c:296 builtin/log.c:1205 builtin/shortlog.c:284
#, c-format
msgid "unrecognized argument: %s"
msgstr "argomento non riconosciuto: %s"
#: bundle.c:331
#, c-format
msgid "ref '%s' is excluded by the rev-list options"
-msgstr ""
+msgstr "il ref '%s' è escluso dalle opzioni di rev-list"
#: bundle.c:376
msgid "Refusing to create empty bundle."
#: commit.c:48
#, c-format
msgid "could not parse %s"
-msgstr ""
+msgstr "non è stato possibile analizzare %s"
#: commit.c:50
#, c-format
#: compat/obstack.c:406 compat/obstack.c:408
msgid "memory exhausted"
-msgstr ""
+msgstr "memoria esaurita"
#: connected.c:39
msgid "Could not run 'git rev-list'"
-msgstr "Impossibile eseguire 'git-rev-list'"
+msgstr "Non è stato possibile eseguire 'git-rev-list'"
#: connected.c:48
-#, c-format, fuzzy
+#, c-format
msgid "failed write to rev-list: %s"
-msgstr "impossibile salvare nella rev-list: %s"
+msgstr "scrittura nella rev-list non riuscita: %s"
#: connected.c:56
#, c-format
"Found errors in 'diff.dirstat' config variable:\n"
"%s"
msgstr ""
-"Errori trovati nella variabile di configurazione 'diff.dirstat':\n"
+"Trovati errori nella variabile di configurazione 'diff.dirstat':\n"
"%s"
#: diff.c:1400
#, c-format
msgid ", %d insertion(+)"
msgid_plural ", %d insertions(+)"
-msgstr[0] ", %d aggiunta(+)"
-msgstr[1] ", %d aggiunte(+)<"
+msgstr[0] ", %d inserzione(+)"
+msgstr[1] ", %d inserzioni(+)"
#: diff.c:1432
#, c-format
msgid ", %d deletion(-)"
msgid_plural ", %d deletions(-)"
-msgstr[0] ". %d eliminato(-)"
-msgstr[1] ", %d eliminati(-)"
+msgstr[0] ". %d rimozione(-)"
+msgstr[1] ", %d rimozioni(-)"
#: diff.c:3478
-#, c-format, fuzzy
+#, c-format
msgid ""
"Failed to parse --dirstat/-X option parameter:\n"
"%s"
msgstr ""
-"Errore nel parametro dell'opzione --dirstat/-X:\n"
+"Analisi del parametro dell'opzione --dirstat/-X non riuscita:\n"
"%s"
#: gpg-interface.c:59
msgid "could not run gpg."
-msgstr "impossibile eseguire gpg."
+msgstr "non è stato possibile eseguire gpg."
#: gpg-interface.c:71
msgid "gpg did not accept the data"
msgid "gpg failed to sign the data"
msgstr "gpg non è riuscito a firmare i dati"
-#: grep.c:1280
+#: grep.c:1320
#, c-format
msgid "'%s': unable to read %s"
msgstr "'%s': impossibile leggere %s"
-#: grep.c:1297
+#: grep.c:1337
#, c-format
msgid "'%s': %s"
msgstr "'%s': %s"
-#: grep.c:1308
+#: grep.c:1348
#, c-format
msgid "'%s': short read %s"
msgstr ""
#: help.c:214
msgid "git commands available from elsewhere on your $PATH"
-msgstr "i comandi git sono disponibili in un altro percorso nel tuo $PATH"
+msgstr "comandi git disponibili altrove nel tuo $PATH"
#: help.c:270
#, c-format
"able to execute it. Maybe git-%s is broken?"
msgstr ""
"'%s' sembra essere un comando git, ma non è stato\n"
-"possibile eseguirlo. Fore git-%s è corrotto?"
+"possibile eseguirlo. Forse git-%s è corrotto?"
#: help.c:327
msgid "Uh oh. Your system reports no Git commands at all."
-msgstr "Oh oh. Il sistema non riporta alcun comando Git."
+msgstr "Oh oh. Il tuo sistema non riporta alcun comando Git."
#: help.c:349
#, c-format
#: help.c:361
#, c-format
msgid "git: '%s' is not a git command. See 'git --help'."
-msgstr "git: '%s' non è un comando git. Consultare 'git --help'."
+msgstr "git: '%s' non è un comando git. Vedi 'git --help'."
#: help.c:365
msgid ""
msgid_plural ""
"\n"
"Did you mean one of these?"
-msgstr[0] "\nSi intendeva questo?"
-msgstr[1] "\nSi intendeva uno di questi?"
+msgstr[0] ""
+"\n"
+"Intendevi questo?"
+msgstr[1] ""
+"\n"
+"Intendevi uno di questi?"
#: parse-options.c:493
msgid "..."
msgid " %s"
msgstr " %s"
-#: remote.c:1607
+#: remote.c:1629
#, c-format
msgid "Your branch is ahead of '%s' by %d commit.\n"
msgid_plural "Your branch is ahead of '%s' by %d commits.\n"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Il tuo branch è avanti rispetto a '%s' di %d commit.\n"
+msgstr[1] "Il tuo branch è avanti rispetto a '%s' di %d commit.\n"
-#: remote.c:1613
+#: remote.c:1635
#, c-format
msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: remote.c:1621
+#: remote.c:1643
#, c-format
msgid ""
"Your branch and '%s' have diverged,\n"
#: builtin/merge.c:1088 builtin/merge.c:1098
#, c-format
msgid "Could not open '%s' for writing"
-msgstr "Impossibile aprire '%s' per la scrittura"
+msgstr "Non è stato possibile aprire '%s' per la scrittura"
#: sequencer.c:123 builtin/merge.c:333 builtin/merge.c:868
#: builtin/merge.c:1090 builtin/merge.c:1103
"after resolving the conflicts, mark the corrected paths\n"
"with 'git add <paths>' or 'git rm <paths>'"
msgstr ""
-"dopo aver risolto i conflitti, segnare i percorsi corretti\n"
-"con 'git add <percorso>' o 'git rm <percorso>'"
+"dopo aver risolto i conflitti, segna i path corretti\n"
+"con 'git add <path>' o 'git rm <path>'"
#: sequencer.c:147
msgid ""
"with 'git add <paths>' or 'git rm <paths>'\n"
"and commit the result with 'git commit'"
msgstr ""
-"dopo aver risolto i conflitti, segnare i percorsi corretti\n"
-"con 'git add <percorso>' o 'git rm <percorso>' ed effettuare\n"
+"dopo aver risolto i conflitti, segna i path corretti\n"
+"con 'git add <path>' o 'git rm <path>' ed eseguire\n"
"il commit del risultato con 'git commit'"
-#: sequencer.c:160 sequencer.c:741 sequencer.c:824
+#: sequencer.c:160 sequencer.c:758 sequencer.c:841
#, c-format
msgid "Could not write to %s"
msgstr "Non è stato possibile scrivere su %s"
#: sequencer.c:178
msgid "Your local changes would be overwritten by cherry-pick."
-msgstr "Le modifiche locali verranno sovrascritte da cherry-pick"
+msgstr "Le tue modifiche locali verranno sovrascritte da cherry-pick"
#: sequencer.c:180
msgid "Your local changes would be overwritten by revert."
-msgstr "Le modifiche locali verranno sovrascritte da revert."
+msgstr "Le tue modifiche locali verranno sovrascritte da revert."
#: sequencer.c:183
msgid "Commit your changes or stash them to proceed."
-msgstr "Effettuare il commit delle modifiche o annullarle per procedere."
+msgstr ""
#. TRANSLATORS: %s will be "revert" or "cherry-pick"
#: sequencer.c:233
#, c-format
msgid "%s: Unable to write new index file"
-msgstr "%s: non è stato possibile scrivere il nuovo file indice"
+msgstr "%s: impossibile scrivere il nuovo index file"
#: sequencer.c:261
msgid "Could not resolve HEAD commit\n"
#: sequencer.c:282
msgid "Unable to update cache tree\n"
-msgstr "Impossibile aggiornare la cache dell'albero\n"
+msgstr ""
-#: sequencer.c:323
+#: sequencer.c:324
#, c-format
msgid "Could not parse commit %s\n"
-msgstr ""
+msgstr "Non è stato possibile analizzare il commit %s\n"
-#: sequencer.c:328
+#: sequencer.c:329
#, c-format
msgid "Could not parse parent commit %s\n"
msgstr ""
-#: sequencer.c:358
+#: sequencer.c:395
msgid "Your index file is unmerged."
msgstr ""
-#: sequencer.c:361
+#: sequencer.c:398
msgid "You do not have a valid HEAD"
-msgstr ""
+msgstr "Non hai un HEAD valido"
-#: sequencer.c:376
+#: sequencer.c:413
#, c-format
msgid "Commit %s is a merge but no -m option was given."
-msgstr "Il commit %s è un merge ma non è stata fornita l'opzione -m."
+msgstr "Il commit %s è un merge ma non è stata specificata l'opzione -m."
-#: sequencer.c:384
+#: sequencer.c:421
#, c-format
msgid "Commit %s does not have parent %d"
msgstr ""
-#: sequencer.c:388
+#: sequencer.c:425
#, c-format
msgid "Mainline was specified but commit %s is not a merge."
msgstr ""
#. TRANSLATORS: The first %s will be "revert" or
#. "cherry-pick", the second %s a SHA1
-#: sequencer.c:399
+#: sequencer.c:436
#, c-format
msgid "%s: cannot parse parent commit %s"
msgstr ""
-#: sequencer.c:403
-#, c-format, fuzzy
+#: sequencer.c:440
+#, c-format
msgid "Cannot get commit message for %s"
-msgstr "Non è possibile prelevare il messaggio di commit per %s"
+msgstr "Impossibile ottenere il messaggio di commit per %s"
-#: sequencer.c:491
+#: sequencer.c:524
#, c-format
msgid "could not revert %s... %s"
msgstr "non è stato possibile eseguire il revert di %s... %s"
-#: sequencer.c:492
+#: sequencer.c:525
#, c-format
msgid "could not apply %s... %s"
msgstr "non è stato possibile applicare %s... %s"
-#: sequencer.c:536
+#: sequencer.c:553
msgid "empty commit set passed"
msgstr "è stato passato un set di commit vuoto"
-#: sequencer.c:544
+#: sequencer.c:561
#, c-format
msgid "git %s: failed to read the index"
-msgstr "git %s: lettura dell'indice non riuscita"
+msgstr "git %s: lettura di index non riuscita"
-#: sequencer.c:549
+#: sequencer.c:566
#, c-format
msgid "git %s: failed to refresh the index"
-msgstr "git %s: aggiornamento dell'indice non riuscito"
+msgstr "git %s: aggiornamento di index non riuscito"
-#: sequencer.c:607
+#: sequencer.c:624
#, c-format
msgid "Cannot %s during a %s"
msgstr ""
-#: sequencer.c:629
+#: sequencer.c:646
#, c-format
msgid "Could not parse line %d."
-msgstr ""
+msgstr "Non è stato possibile analizzare la riga %d."
-#: sequencer.c:634
+#: sequencer.c:651
msgid "No commits parsed."
-msgstr ""
+msgstr "Nessun commit analizzato."
-#: sequencer.c:647
+#: sequencer.c:664
#, c-format
msgid "Could not open %s"
msgstr "Non è stato possibile aprire %s"
-#: sequencer.c:651
+#: sequencer.c:668
#, c-format
msgid "Could not read %s."
-msgstr ""
+msgstr "Non è stato possibile leggere %s."
-#: sequencer.c:658
+#: sequencer.c:675
#, c-format
msgid "Unusable instruction sheet: %s"
msgstr ""
-#: sequencer.c:686
+#: sequencer.c:703
#, c-format
msgid "Invalid key: %s"
msgstr "Chiave non valida: %s"
-#: sequencer.c:689
+#: sequencer.c:706
#, c-format
msgid "Invalid value for %s: %s"
msgstr "Valore non valido per %s: %s"
-#: sequencer.c:701
+#: sequencer.c:718
#, c-format
msgid "Malformed options sheet: %s"
msgstr ""
-#: sequencer.c:722
+#: sequencer.c:739
msgid "a cherry-pick or revert is already in progress"
msgstr "è già in corso un'operazione di cherry-pick o di revert"
-#: sequencer.c:723
+#: sequencer.c:740
msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
-msgstr "provare \"git cherry-pick (--continue | --quit | -- abort)\""
+msgstr "prova \"git cherry-pick (--continue | --quit | -- abort)\""
-#: sequencer.c:727
+#: sequencer.c:744
#, c-format
msgid "Could not create sequencer directory %s"
msgstr ""
-#: sequencer.c:743 sequencer.c:828
+#: sequencer.c:760 sequencer.c:845
#, c-format
msgid "Error wrapping up %s."
msgstr ""
-#: sequencer.c:762 sequencer.c:896
+#: sequencer.c:779 sequencer.c:913
msgid "no cherry-pick or revert in progress"
msgstr "nessuna operazione di cherry-pick o revert in corso"
-#: sequencer.c:764
+#: sequencer.c:781
msgid "cannot resolve HEAD"
-msgstr "non è possibile risolvere HEAD"
+msgstr "impossibile risolvere HEAD"
-#: sequencer.c:766
+#: sequencer.c:783
msgid "cannot abort from a branch yet to be born"
msgstr ""
-#: sequencer.c:788 builtin/apply.c:3689
+#: sequencer.c:805 builtin/apply.c:3697
#, c-format
msgid "cannot open %s: %s"
-msgstr "non è possibile aprire %s: %s"
+msgstr "impossibile aprire %s: %s"
-#: sequencer.c:791
+#: sequencer.c:808
#, c-format
msgid "cannot read %s: %s"
-msgstr "non è possibile leggere %s: %s"
+msgstr "impossibile leggere %s: %s"
-#: sequencer.c:792
+#: sequencer.c:809
msgid "unexpected end of file"
msgstr "fine del file inattesa"
-#: sequencer.c:798
+#: sequencer.c:815
#, c-format
msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
msgstr ""
-#: sequencer.c:821
+#: sequencer.c:838
#, c-format
msgid "Could not format %s."
msgstr ""
-#: sequencer.c:983
+#: sequencer.c:1000
msgid "Can't revert as initial commit"
-msgstr ""
+msgstr "Impossibile eseguire il revert come commit iniziale"
-#: sequencer.c:984
+#: sequencer.c:1001
msgid "Can't cherry-pick into empty head"
msgstr ""
#: sha1_name.c:864
msgid "HEAD does not point to a branch"
-msgstr "HEAD non punta ad un ramo"
+msgstr "HEAD non punta ad un branch"
#: sha1_name.c:867
#, c-format
msgid "No such branch: '%s'"
-msgstr "Nessun ramo esistente: '%s'"
+msgstr "Nessun branch esistente: '%s'"
#: sha1_name.c:869
#, c-format
msgid "Upstream branch '%s' not stored as a remote-tracking branch"
msgstr ""
+#: wrapper.c:413
+#, c-format
+msgid "unable to look up current user in the passwd file: %s"
+msgstr "impossibile trovare l'utente corrente nel file passwd: %s"
+
+#: wrapper.c:414
+msgid "no such user"
+msgstr "utente non esistente"
+
#: wt-status.c:135
msgid "Unmerged paths:"
msgstr ""
#: wt-status.c:141 wt-status.c:158
#, c-format
msgid " (use \"git reset %s <file>...\" to unstage)"
-msgstr " (usare \"git reset %s <file>...\" per rimuoverlo dallo stage)"
+msgstr ""
#: wt-status.c:143 wt-status.c:160
msgid " (use \"git rm --cached <file>...\" to unstage)"
-msgstr " (usare \"git rm --cached <file>...\" per rimuoverlo dallo stage)"
+msgstr ""
#: wt-status.c:144
msgid " (use \"git add/rm <file>...\" as appropriate to mark resolution)"
-msgstr ""
+msgstr " (usa \"git add/rm <file>...\" come appropriato per la risoluzione)"
#: wt-status.c:152
msgid "Changes to be committed:"
-msgstr "Modifiche di cui effettuare il commit:"
+msgstr ""
#: wt-status.c:170
msgid "Changes not staged for commit:"
-msgstr "Modifiche non pronte per il commit:"
+msgstr ""
#: wt-status.c:174
msgid " (use \"git add <file>...\" to update what will be committed)"
#: wt-status.c:253
msgid "untracked content, "
-msgstr "contenuto non tracciato, "
+msgstr ""
#: wt-status.c:267
#, c-format
#: wt-status.c:737
msgid "On branch "
-msgstr "Sul ramo "
+msgstr "Sul branch "
#: wt-status.c:744
msgid "Not currently on any branch."
-msgstr "Al momento non si è su alcun ramo."
+msgstr ""
#: wt-status.c:755
msgid "Initial commit"
#: wt-status.c:769
msgid "Untracked"
-msgstr "Non tracciato"
+msgstr ""
#: wt-status.c:771
msgid "Ignored"
#: wt-status.c:775
msgid " (use -u option to show untracked files)"
-msgstr " (usare l'opzione -u per visualizzare i file non tracciati)"
+msgstr ""
#: wt-status.c:781
msgid "No changes"
#: wt-status.c:787
msgid " (use \"git add\" and/or \"git commit -a\")"
-msgstr " (usare \"git add\" e/o \"git commit -a\")"
+msgstr " (usa \"git add\" e/o \"git commit -a\")"
#: wt-status.c:789
#, c-format
#: wt-status.c:791
msgid " (use \"git add\" to track)"
-msgstr " (usare \"git add\" per tracciare)"
+msgstr ""
#: wt-status.c:793 wt-status.c:796 wt-status.c:799
#, c-format
#: wt-status.c:794
msgid " (create/copy files and use \"git add\" to track)"
-msgstr " (crea/copia file e usa \"git add\" per tracciarli)"
+msgstr ""
#: wt-status.c:797
msgid " (use -u to show untracked files)"
-msgstr " (usare -u per mostrare i file non tracciati)"
+msgstr ""
#: wt-status.c:800
msgid " (working directory clean)"
-msgstr " (cartella di lavoro pulita)"
+msgstr ""
#: wt-status.c:908
msgid "HEAD (no branch)"
-msgstr "HEAD (nessun ramo)"
+msgstr "HEAD (nessun branch)"
#: wt-status.c:914
msgid "Initial commit on "
#: wt-status.c:929
msgid "behind "
-msgstr ""
+msgstr "indietro "
#: wt-status.c:932 wt-status.c:935
msgid "ahead "
-msgstr ""
+msgstr "avanti "
#: wt-status.c:937
msgid ", behind "
-msgstr ""
+msgstr ", indietro "
#: builtin/add.c:62
-#, c-format, fuzzy
+#, c-format
msgid "unexpected diff status %c"
msgstr "status diff %c inatteso"
#: builtin/add.c:176
#, c-format
msgid "Path '%s' is in submodule '%.*s'"
-msgstr ""
+msgstr "Il path '%s' è nel sottomodulo '%.*s'"
#: builtin/add.c:192
msgid "Unstaged changes after refreshing the index:"
#: builtin/add.c:276
msgid "Could not read the index"
-msgstr "Impossibile leggere l'indice"
+msgstr "Non è stato possibile leggere index"
#: builtin/add.c:286
#, c-format
msgid "Could not open '%s' for writing."
-msgstr "Impossibile aprire '%s' per la scrittura."
+msgstr "Non è stato possibile aprire '%s' per la scrittura."
#: builtin/add.c:290
msgid "Could not write patch"
#: builtin/add.c:295
#, c-format
msgid "Could not stat '%s'"
-msgstr ""
+msgstr "Non è stato possibile eseguire lo stat di '%s'"
#: builtin/add.c:297
msgid "Empty patch. Aborted."
-msgstr "Patch vuota. Operazione terminata."
+msgstr "Patch vuota. Operazione interrotta."
#: builtin/add.c:303
#, c-format
msgid "Could not apply '%s'"
-msgstr "Impossibile applicare '%s'"
+msgstr "Non è stato possibile applicare '%s'"
#: builtin/add.c:312
msgid "The following paths are ignored by one of your .gitignore files:\n"
-msgstr "I seguenti percorsi sono stati ignorati da uno o più file .gitignore:\n"
+msgstr "I seguenti path sono stati ignorati da uno o più dei tuoi file .gitignore:\n"
#: builtin/add.c:352
#, c-format
msgid "Use -f if you really want to add them.\n"
-msgstr "Usare -f se si desidera davvero aggiungerli.\n"
+msgstr "Usa -f se vuoi davvero aggiungerli.\n"
#: builtin/add.c:353
msgid "no files added"
#: builtin/add.c:393
msgid "Option --ignore-missing can only be used together with --dry-run"
-msgstr "L'opzione --ignore-missing può essere usata solo in combinazione con --dry-run"
+msgstr "L'opzione --ignore-missing può essere usata solo con --dry-run"
#: builtin/add.c:413
#, c-format
msgid "Nothing specified, nothing added.\n"
-msgstr "Non è stato specificato nulla, non è stato aggiunto nulla.\n"
+msgstr ""
#: builtin/add.c:414
#, c-format
msgid "Maybe you wanted to say 'git add .'?\n"
-msgstr "Forse si intendeva dire 'git add .'?\n"
+msgstr "Forse intendevi dire 'git add .'?\n"
#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:286 builtin/mv.c:82
#: builtin/rm.c:162
msgid "index file corrupt"
-msgstr "indice del file corrotto"
+msgstr "index file corrotto"
-#: builtin/add.c:476 builtin/apply.c:4100 builtin/mv.c:229 builtin/rm.c:260
+#: builtin/add.c:476 builtin/apply.c:4108 builtin/mv.c:229 builtin/rm.c:260
msgid "Unable to write new index file"
-msgstr "Impossibile scrivere il nuovo file di indice"
+msgstr "Impossibile scrivere il nuovo index file"
#: builtin/apply.c:53
msgid "git apply [options] [<patch>...]"
#: builtin/apply.c:824
#, c-format
msgid "regexec returned %d for input: %s"
-msgstr ""
+msgstr "regexec ha restituito %d per l'input: %s"
#: builtin/apply.c:905
#, c-format
msgid "unable to find filename in patch at line %d"
-msgstr "non è possibile trovare il nome del file nella patch alla riga %d"
+msgstr "impossibile trovare il nome del file nella patch alla riga %d"
#: builtin/apply.c:937
#, c-format
#: builtin/apply.c:941
#, c-format
msgid "git apply: bad git-diff - inconsistent new filename on line %d"
-msgstr "git apply: git-diff errato - nuovo nome del file incosistente alla riga %d"
+msgstr "git apply: git-diff errato - nuovo nome del file inconsistente alla riga %d"
#: builtin/apply.c:942
#, c-format
#: builtin/apply.c:1656
#, c-format
msgid "corrupt patch at line %d"
-msgstr "patch corrotta alla riga %d"
+msgstr ""
#: builtin/apply.c:1692
#, c-format
#: builtin/apply.c:1958
#, c-format
msgid "patch with only garbage at line %d"
-msgstr "patch con sola spazzatura alla riga %d"
+msgstr ""
#: builtin/apply.c:2048
#, c-format
msgstr "dati della patch binaria mancanti per '%s'"
#: builtin/apply.c:2903
-#, c-format, fuzzy
+#, c-format
msgid "binary patch does not apply to '%s'"
msgstr "la patch binaria non può essere applicata a '%s'"
#: builtin/apply.c:2930
#, c-format
msgid "patch failed: %s:%ld"
-msgstr "patch non riuscito: %s:%ld"
+msgstr "patch non riuscita: %s:%ld"
#: builtin/apply.c:3045
#, c-format
#: builtin/apply.c:3105
#, c-format
msgid "%s: already exists in working directory"
-msgstr "%s: esiste già nella cartella di lavoro"
+msgstr "%s: esiste già nella directory di lavoro"
#: builtin/apply.c:3143
#, c-format
msgid "%s: has been deleted/renamed"
-msgstr "%s: è stato eliminato/rinominato"
+msgstr "%s: è stata eliminata/rinominata"
#: builtin/apply.c:3148 builtin/apply.c:3179
#, c-format
#: builtin/apply.c:3159
#, c-format
msgid "%s: does not exist in index"
-msgstr "%s: non esiste nell'indice"
+msgstr "%s: non esiste in index"
#: builtin/apply.c:3173
#, c-format
msgid "%s: does not match index"
-msgstr "%s: non corrisponde all'indice"
+msgstr "%s: non corrisponde a index"
#: builtin/apply.c:3190
#, c-format
#: builtin/apply.c:3247
#, c-format
msgid "%s: already exists in index"
-msgstr "%s: esiste già nell'indice"
+msgstr "%s: esiste già in index"
-#: builtin/apply.c:3266
+#: builtin/apply.c:3267
#, c-format
-msgid "new mode (%o) of %s does not match old mode (%o)%s%s"
-msgstr "la nuova modalità (%o) di %s non corrisponde alla modalità precedente (%o)%s%s"
+msgid "new mode (%o) of %s does not match old mode (%o)"
+msgstr ""
#: builtin/apply.c:3272
#, c-format
+msgid "new mode (%o) of %s does not match old mode (%o) of %s"
+msgstr ""
+
+#: builtin/apply.c:3280
+#, c-format
msgid "%s: patch does not apply"
msgstr "%s: la patch non può essere applicata"
-#: builtin/apply.c:3285
+#: builtin/apply.c:3293
#, c-format
msgid "Checking patch %s..."
-msgstr "Verifica della patch %s..."
+msgstr "Controllo della patch %s..."
-#: builtin/apply.c:3340 builtin/checkout.c:212 builtin/reset.c:158
+#: builtin/apply.c:3348 builtin/checkout.c:212 builtin/reset.c:158
#, c-format
msgid "make_cache_entry failed for path '%s'"
-msgstr "make_cache_entry non riuscito per il percorso '%s'"
+msgstr "make_cache_entry non riuscito per il path '%s'"
-#: builtin/apply.c:3483
+#: builtin/apply.c:3491
#, c-format
msgid "unable to remove %s from index"
-msgstr "impossibile rimuovere %s dall'indice"
+msgstr "impossibile rimuovere %s da index"
-#: builtin/apply.c:3510
+#: builtin/apply.c:3518
#, c-format
msgid "corrupt patch for subproject %s"
-msgstr ""
+msgstr "patch corrotta per il sottoprogetto %s"
-#: builtin/apply.c:3514
+#: builtin/apply.c:3522
#, c-format
msgid "unable to stat newly created file '%s'"
msgstr "impossibile eseguire lo stat del file appena creato '%s'"
-#: builtin/apply.c:3519
+#: builtin/apply.c:3527
#, c-format
msgid "unable to create backing store for newly created file %s"
msgstr ""
-#: builtin/apply.c:3522
+#: builtin/apply.c:3530
#, c-format
msgid "unable to add cache entry for %s"
msgstr "impossibile aggiungere la voce della cache per %s"
-#: builtin/apply.c:3555
+#: builtin/apply.c:3563
#, c-format
msgid "closing file '%s'"
msgstr "chiusura del file '%s'"
-#: builtin/apply.c:3604
+#: builtin/apply.c:3612
#, c-format
msgid "unable to write file '%s' mode %o"
-msgstr "non è possibile scrivere il file '%s' in modalità %o"
+msgstr "impossibile scrivere il file '%s' in modalità %o"
-#: builtin/apply.c:3660
+#: builtin/apply.c:3668
#, c-format
msgid "Applied patch %s cleanly."
-msgstr ""
+msgstr "Patch %s applicata correttamente."
-#: builtin/apply.c:3668
+#: builtin/apply.c:3676
msgid "internal error"
msgstr "errore interno"
#. Say this even without --verbose
-#: builtin/apply.c:3671
+#: builtin/apply.c:3679
#, c-format
msgid "Applying patch %%s with %d reject..."
msgid_plural "Applying patch %%s with %d rejects..."
msgstr[0] ""
msgstr[1] ""
-#: builtin/apply.c:3681
+#: builtin/apply.c:3689
#, c-format
msgid "truncating .rej filename to %.*s.rej"
msgstr ""
-#: builtin/apply.c:3702
+#: builtin/apply.c:3710
#, c-format
msgid "Hunk #%d applied cleanly."
-msgstr ""
+msgstr "Frammento #%d applicato correttamente."
-#: builtin/apply.c:3705
+#: builtin/apply.c:3713
#, c-format
msgid "Rejected hunk #%d."
-msgstr ""
+msgstr "Frammento #%d respinto."
-#: builtin/apply.c:3836
+#: builtin/apply.c:3844
msgid "unrecognized input"
msgstr "input non riconosciuto"
-#: builtin/apply.c:3847
+#: builtin/apply.c:3855
msgid "unable to read index file"
-msgstr "impossibile leggere il file dell'indice"
+msgstr "impossibile leggere index file"
-#: builtin/apply.c:3962 builtin/apply.c:3965
+#: builtin/apply.c:3970 builtin/apply.c:3973
msgid "path"
-msgstr "percorso"
+msgstr "path"
-#: builtin/apply.c:3963
+#: builtin/apply.c:3971
msgid "don't apply changes matching the given path"
-msgstr ""
+msgstr "non applica le modifiche corrispondenti al path specificato"
-#: builtin/apply.c:3966
+#: builtin/apply.c:3974
msgid "apply changes matching the given path"
-msgstr ""
+msgstr "applica le modifiche corrispondenti al path specificato"
-#: builtin/apply.c:3968
+#: builtin/apply.c:3976
msgid "num"
msgstr "num"
-#: builtin/apply.c:3969
+#: builtin/apply.c:3977
msgid "remove <num> leading slashes from traditional diff paths"
msgstr ""
-#: builtin/apply.c:3972
+#: builtin/apply.c:3980
msgid "ignore additions made by the patch"
-msgstr ""
+msgstr "ignora le aggiunte create dalla patch"
-#: builtin/apply.c:3974
+#: builtin/apply.c:3982
msgid "instead of applying the patch, output diffstat for the input"
msgstr "invece di applicare la patch, mostra l'output di diffstat per l'input"
-#: builtin/apply.c:3978
+#: builtin/apply.c:3986
msgid "shows number of added and deleted lines in decimal notation"
msgstr "mostra il numero di righe aggiunte e eliminate in notazione decimale"
-#: builtin/apply.c:3980
+#: builtin/apply.c:3988
msgid "instead of applying the patch, output a summary for the input"
msgstr "invece di applicare la patch, mostra un riassunto per l'input"
-#: builtin/apply.c:3982
+#: builtin/apply.c:3990
msgid "instead of applying the patch, see if the patch is applicable"
msgstr "invece di applicare la patch, verifica se può essere applicata"
-#: builtin/apply.c:3984
+#: builtin/apply.c:3992
msgid "make sure the patch is applicable to the current index"
-msgstr "assicura che la patch sia applicabile all'indice corrente"
+msgstr "assicura che la patch sia applicabile all'attuale index"
-#: builtin/apply.c:3986
+#: builtin/apply.c:3994
msgid "apply a patch without touching the working tree"
-msgstr "applica una patch senza modificare l'albero di lavoro"
+msgstr ""
-#: builtin/apply.c:3988
+#: builtin/apply.c:3996
msgid "also apply the patch (use with --stat/--summary/--check)"
-msgstr "applica anche la patch (usare con --stat/--summary/--check)"
+msgstr "applica anche la patch (da usare con --stat/--summary/--check)"
-#: builtin/apply.c:3990
+#: builtin/apply.c:3998
msgid "build a temporary index based on embedded index information"
-msgstr "crea un indice temporaneo basato sulle informazioni incorporate dell'indice"
+msgstr ""
-#: builtin/apply.c:3992
+#: builtin/apply.c:4000
msgid "paths are separated with NUL character"
-msgstr "i percorsi sono separati con un carattere NUL"
+msgstr "i path sono separati con un carattere NUL"
-#: builtin/apply.c:3995
+#: builtin/apply.c:4003
msgid "ensure at least <n> lines of context match"
msgstr "assicura almeno <n> righe di contesto corrispondente"
-#: builtin/apply.c:3996
+#: builtin/apply.c:4004
msgid "action"
msgstr "azione"
-#: builtin/apply.c:3997
+#: builtin/apply.c:4005
msgid "detect new or modified lines that have whitespace errors"
msgstr "rileva righe nuove o modificate che hanno errori di spazi bianchi"
-#: builtin/apply.c:4000 builtin/apply.c:4003
+#: builtin/apply.c:4008 builtin/apply.c:4011
msgid "ignore changes in whitespace when finding context"
msgstr ""
-#: builtin/apply.c:4006
+#: builtin/apply.c:4014
msgid "apply the patch in reverse"
msgstr "applica la patch in maniera inversa"
-#: builtin/apply.c:4008
+#: builtin/apply.c:4016
msgid "don't expect at least one line of context"
msgstr ""
-#: builtin/apply.c:4010
+#: builtin/apply.c:4018
msgid "leave the rejected hunks in corresponding *.rej files"
-msgstr ""
+msgstr "lascia i frammenti respinti nei file .rej corrispondenti"
-#: builtin/apply.c:4012
+#: builtin/apply.c:4020
msgid "allow overlapping hunks"
-msgstr ""
+msgstr "consente la sovrapposizione dei frammenti"
-#: builtin/apply.c:4013
+#: builtin/apply.c:4021
msgid "be verbose"
msgstr "dettagliato"
-#: builtin/apply.c:4015
+#: builtin/apply.c:4023
msgid "tolerate incorrectly detected missing new-line at the end of file"
msgstr ""
-#: builtin/apply.c:4018
+#: builtin/apply.c:4026
msgid "do not trust the line counts in the hunk headers"
msgstr ""
-#: builtin/apply.c:4020
+#: builtin/apply.c:4028
msgid "root"
msgstr "radice"
-#: builtin/apply.c:4021
+#: builtin/apply.c:4029
msgid "prepend <root> to all filenames"
msgstr "antepone <root> a tutti i nomi file"
-#: builtin/apply.c:4042
+#: builtin/apply.c:4050
msgid "--index outside a repository"
-msgstr "--index al di fuori di un deposito"
+msgstr "--index al di fuori di un repository"
-#: builtin/apply.c:4045
+#: builtin/apply.c:4053
msgid "--cached outside a repository"
-msgstr "--cached al di fuori di un deposito"
+msgstr "--cached al di fuori di un repository"
-#: builtin/apply.c:4061
+#: builtin/apply.c:4069
#, c-format
msgid "can't open patch '%s'"
msgstr "impossibile aprire la patch '%s'"
-#: builtin/apply.c:4075
+#: builtin/apply.c:4083
#, c-format
msgid "squelched %d whitespace error"
msgid_plural "squelched %d whitespace errors"
msgstr[0] ""
msgstr[1] ""
-#: builtin/apply.c:4081 builtin/apply.c:4091
+#: builtin/apply.c:4089 builtin/apply.c:4099
#, c-format
msgid "%d line adds whitespace errors."
msgid_plural "%d lines add whitespace errors."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d riga aggiunge errori di spazi bianchi."
+msgstr[1] "%d righe aggiungono errori di spazi bianchi."
#: builtin/archive.c:17
#, c-format
msgid "could not create archive file '%s'"
-msgstr "impossibile creare il file dell'archivio '%s'"
+msgstr "non è stato possibile creare il file del repository '%s'"
#: builtin/archive.c:20
msgid "could not redirect output"
-msgstr "impossibile redirigere l'output"
+msgstr "non è stato possibile redirigere l'output"
#: builtin/archive.c:37
msgid "git archive: Remote with no URL"
-msgstr "git archive: Remote non ha una URL"
+msgstr "git archive: Remote non ha un URL"
#: builtin/archive.c:58
msgid "git archive: expected ACK/NAK, got EOF"
#: builtin/archive.c:71
msgid "git archive: expected a flush"
-msgstr ""
+msgstr "git archive: atteso un flush"
#: builtin/branch.c:144
#, c-format
#: builtin/branch.c:202
#, c-format
msgid "remote branch '%s' not found."
-msgstr "il ramo remoto '%s' non è stato trovato."
+msgstr "il branch remoto '%s' non è stato trovato."
#: builtin/branch.c:203
#, c-format
msgid "branch '%s' not found."
-msgstr "ramo '%s' non trovato."
+msgstr "branch '%s' non trovato."
#: builtin/branch.c:210
#, c-format
#: builtin/branch.c:225
#, c-format
msgid "Error deleting remote branch '%s'"
-msgstr "Errore nella rimozione del ramo remoto '%s'"
+msgstr "Errore nella rimozione del branch remoto '%s'"
#: builtin/branch.c:226
#, c-format
msgid "Error deleting branch '%s'"
-msgstr "Errore nella rimozione del ramo '%s'"
+msgstr "Errore nella rimozione del branch '%s'"
#: builtin/branch.c:233
#, c-format
#: builtin/branch.c:337
#, c-format
msgid "branch '%s' does not point at a commit"
-msgstr "il ramo '%s' non punta ad un commit"
+msgstr "il branch '%s' non punta ad un commit"
#: builtin/branch.c:409
#, c-format
#: builtin/branch.c:535
msgid "(no branch)"
-msgstr "(nessun ramo)"
+msgstr "(nessun branch)"
#: builtin/branch.c:600
msgid "some refs could not be read"
#: builtin/branch.c:623
#, c-format
msgid "Invalid branch name: '%s'"
-msgstr "Nome del ramo non valido: '%s'"
+msgstr "Nome del branch non valido: '%s'"
#: builtin/branch.c:638
msgid "Branch rename failed"
#: builtin/branch.c:653
msgid "Branch is renamed, but update of config-file failed"
-msgstr "Il ramo è stato rinominato, ma l'aggiornamento del file di configurazione è fallito"
+msgstr ""
+"Il branch è stato rinominato, ma l'aggiornamento del file di configurazione "
+"è fallito"
#: builtin/branch.c:668
#, c-format
msgid "malformed object name %s"
-msgstr "nome dell'oggetto %s non corretto"
+msgstr "nome dell'oggetto %s errato"
#: builtin/branch.c:692
#, c-format
#: builtin/branch.c:857
msgid "-a and -r options to 'git branch' do not make sense with a branch name"
-msgstr "le opzioni -a e -r per 'git branch' non hanno senso con il nome di un ramo"
+msgstr ""
+"le opzioni -a e -r per 'git branch' non hanno senso con il nome di un branch"
#: builtin/bundle.c:47
#, c-format
#: builtin/checkout.c:113 builtin/checkout.c:146
#, c-format
msgid "path '%s' does not have our version"
-msgstr "il percorso '%s' non ha la nostra versione"
+msgstr "il path '%s' non ha la nostra versione"
#: builtin/checkout.c:115 builtin/checkout.c:148
#, c-format
msgid "path '%s' does not have their version"
-msgstr "il percorso '%s' non ha la loro versione"
+msgstr "il path '%s' non ha la loro versione"
#: builtin/checkout.c:131
#, c-format
#: builtin/checkout.c:175
#, c-format
msgid "path '%s' does not have necessary versions"
-msgstr "il percorso '%s' non ha le versioni necessarie"
+msgstr "il path '%s' non ha le versioni necessarie"
#: builtin/checkout.c:192
#, c-format
#: builtin/checkout.c:234 builtin/checkout.c:392
msgid "corrupt index file"
-msgstr "file indice corrotto"
+msgstr "file index corrotto"
#: builtin/checkout.c:264 builtin/checkout.c:271
#, c-format
#: builtin/checkout.c:302 builtin/checkout.c:498 builtin/clone.c:583
#: builtin/merge.c:812
msgid "unable to write new index file"
-msgstr "impossibile scrivere il nuovo file di indice"
+msgstr "impossibile scrivere il nuovo file index"
#: builtin/checkout.c:319 builtin/diff.c:302 builtin/merge.c:408
msgid "diff_setup_done failed"
#: builtin/checkout.c:414
msgid "you need to resolve your current index first"
-msgstr "è necessario risolvere prima l'indice corrente"
+msgstr "è necessario risolvere prima l'attuale index"
#: builtin/checkout.c:533
#, c-format
#: builtin/checkout.c:573
#, c-format
msgid "Reset branch '%s'\n"
-msgstr "Ripristina il ramo '%s'\n"
+msgstr "Ripristina il branch '%s'\n"
#: builtin/checkout.c:576
#, c-format
#: builtin/checkout.c:584
#, c-format
msgid "Switched to branch '%s'\n"
-msgstr "Si è passati al ramo '%s'\n"
+msgstr "Si è passati al branch '%s'\n"
#: builtin/checkout.c:640
#, c-format
" git branch new_branch_name %s\n"
"\n"
msgstr ""
-"Se si desidera mantenerle creando un nuovo ramo, questo potrebbe essere\n"
+"Se si vuole mantenerle creando un nuovo branch, questo potrebbe essere\n"
"un buon momento per farlo con:\n"
"\n"
-" git branch nuovo_nome_ramo %s\n"
+" git branch nuovo_nome_branch %s\n"
"\n"
#: builtin/checkout.c:694
#: builtin/checkout.c:894
#, c-format
msgid "reference is not a tree: %s"
-msgstr "il riferimento non è un albero: %s"
+msgstr ""
#: builtin/checkout.c:974
msgid "-B cannot be used with -b"
#: builtin/checkout.c:983
msgid "--patch is incompatible with all other options"
-msgstr "--patch è incompatibile con tutte le altre opzioni"
+msgstr "--patch non è compatibile con tutte le altre opzioni"
#: builtin/checkout.c:986
msgid "--detach cannot be used with -b/-B/--orphan"
-msgstr "--detach non può essere usato con -b/-B/--orphan"
+msgstr "--detach non può essere usata con -b/-B/--orphan"
#: builtin/checkout.c:988
msgid "--detach cannot be used with -t"
-msgstr "--detach non può essere usato con -t"
+msgstr "--detach non può essere usata con -t"
#: builtin/checkout.c:994
msgid "--track needs a branch name"
-msgstr "--track necessita del nome di un ramo"
+msgstr "--track necessita del nome di un branch"
#: builtin/checkout.c:1001
msgid "Missing branch name; try -b"
-msgstr "Nome del ramo mancante; provare con -b"
+msgstr "Nome del branch mancante; prova con -b"
#: builtin/checkout.c:1007
msgid "--orphan and -b|-B are mutually exclusive"
#: builtin/checkout.c:1009
msgid "--orphan cannot be used with -t"
-msgstr "--orphan non può essere usato con -t"
+msgstr "--orphan non può essere usata con -t"
#: builtin/checkout.c:1019
msgid "git checkout: -f and -m are incompatible"
#: builtin/checkout.c:1068
msgid "git checkout: --detach does not take a path argument"
-msgstr ""
+msgstr "git checkout: --detach non prende un path come argomento"
#: builtin/checkout.c:1071
msgid ""
#: builtin/checkout.c:1093
msgid "--ours/--theirs is incompatible with switching branches."
-msgstr ""
+msgstr "--ours/--theirs non sono compatibili con il passaggio ai branch."
#: builtin/clean.c:78
msgid "-x and -X cannot be used together"
msgid ""
"clean.requireForce set to true and neither -n nor -f given; refusing to clean"
msgstr ""
+"clean.requireForce è impostato a vero, ma né -n né -f sono state specificate; "
+"clean interrotto"
#: builtin/clean.c:85
msgid ""
"clean.requireForce defaults to true and neither -n nor -f given; refusing to "
"clean"
msgstr ""
+"clean.requireForce è vero per default, ma né -n né -f sono state specificate; "
+"clean interrotto"
#: builtin/clean.c:155 builtin/clean.c:176
#, c-format
#: builtin/clone.c:243
#, c-format
msgid "reference repository '%s' is not a local directory."
-msgstr "l'archivio di riferimento '%s' non è una cartella locale."
+msgstr "il repository di riferimento '%s' non è una directory locale."
#: builtin/clone.c:302
#, c-format
#: builtin/clone.c:306
#, c-format
msgid "failed to create directory '%s'"
-msgstr "creazione della cartella '%s' non riuscita"
+msgstr "creazione della directory '%s' non riuscita"
#: builtin/clone.c:308 builtin/diff.c:75
#, c-format
#: builtin/clone.c:310
#, c-format
msgid "%s exists and is not a directory"
-msgstr "%s esiste e non è una cartella"
+msgstr "%s esiste e non è una directory"
#: builtin/clone.c:324
#, c-format
msgstr "stat di %s non riuscito\n"
#: builtin/clone.c:341
-#, c-format, fuzzy
+#, c-format
msgid "failed to unlink '%s'"
msgstr "rimozione del link '%s' non riuscita"
#: builtin/clone.c:440
#, c-format
msgid "Could not find remote branch %s to clone."
-msgstr "Impossibile trovare il ramo remoto %s da clonare."
+msgstr "Non è stato possibile trovare il branch remoto %s da clonare."
#: builtin/clone.c:549
-#, fuzzy
msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
msgstr ""
-"l'HEAD remoto si riferisce ad un ref inesistente, impossibile eseguire il\n"
+"l'HEAD remoto si riferisce ad un ref inesistente, impossibile eseguire il "
"checkout.\n"
#: builtin/clone.c:639
#: builtin/clone.c:643
msgid "You must specify a repository to clone."
-msgstr "È necessario specificare un archivio da clonare."
+msgstr "Devi specificare un repository da clonare."
#: builtin/clone.c:654
#, c-format
#: builtin/clone.c:668
#, c-format
msgid "repository '%s' does not exist"
-msgstr "l'archivio '%s' non esiste"
+msgstr "il repository '%s' non esiste"
#: builtin/clone.c:673
msgid "--depth is ignored in local clones; use file:// instead."
-msgstr "--depth è ingnorato nei cloni locali; usare file:// invece."
+msgstr ""
#: builtin/clone.c:683
#, c-format
msgid "destination path '%s' already exists and is not an empty directory."
-msgstr "il percorso di destinazione '%s' esiste già e non è una cartella vuota."
+msgstr ""
+"il path di destinazione '%s' esiste già e non è una directory vuota."
#: builtin/clone.c:693
#, c-format
msgid "working tree '%s' already exists."
-msgstr "l'albero di lavoro '%s' esiste già."
+msgstr ""
#: builtin/clone.c:706 builtin/clone.c:720
#, c-format
#: builtin/clone.c:728
#, c-format
msgid "Cloning into bare repository '%s'...\n"
-msgstr ""
+msgstr "Clone nel repository spoglio '%s'...\n"
#: builtin/clone.c:730
#, c-format
#: builtin/clone.c:835
#, c-format
msgid "Remote branch %s not found in upstream %s"
-msgstr "Il ramo remoto %s non è stato trovato in upstream %s"
+msgstr "Il branch remoto %s non è stato trovato in upstream %s"
#: builtin/clone.c:842
msgid "You appear to have cloned an empty repository."
-msgstr "Sembra che sia stato clonato un archivio vuoto."
+msgstr "Sembra che tu abbia clonato un repository vuoto."
#: builtin/column.c:51
msgid "--command must be the first argument"
"\n"
" git commit --amend --reset-author\n"
msgstr ""
-"Il nome e l'indirizzo email sono stati configurati automaticamente usando\n"
-"il nome utente ed il nome host. Per favore, verificare che siano esatti.\n"
+"Il tuo nome e l'indirizzo email sono stati configurati automaticamente usando\n"
+"il tuo nome utente ed il nome host. Per favore, verifica che siano esatti.\n"
"È possibile eliminare questo messaggio impostandoli esplicitamente:\n"
"\n"
" git config --global user.name \"Tuo Nome\"\n"
" git config --global user.email tu@esempio.com\n"
"\n"
-"Dopo questa operazione, per ripristinare l'identità usata in questo commit:\n"
+"Dopo questa operazione, puoi ripristinare l'identità usata in questo commit con:\n"
"\n"
" git commit --amend --reset-author\n"
#: builtin/commit.c:301
msgid "interactive add failed"
-msgstr ""
+msgstr "add interattivo non riuscito"
#: builtin/commit.c:334 builtin/commit.c:355 builtin/commit.c:405
msgid "unable to write new_index file"
-msgstr "non è possibile scrivere il file new_index"
+msgstr "impossibile scrivere il file new_index"
#: builtin/commit.c:386
msgid "cannot do a partial commit during a merge."
-msgstr "non è possibile eseguire un commit parziale durante un merge."
+msgstr "impossibile eseguire un commit parziale durante un merge."
#: builtin/commit.c:388
msgid "cannot do a partial commit during a cherry-pick."
-msgstr "non è possibile eseguire un commit parziale durante un cherry-pick."
+msgstr "impossibile eseguire un commit parziale durante un cherry-pick."
#: builtin/commit.c:398
msgid "cannot read the index"
-msgstr "non è possibile leggere l'indice"
+msgstr "impossibile leggere index"
#: builtin/commit.c:418
msgid "unable to write temporary index file"
-msgstr "scrittura del file di indice temporaneo non riuscita"
+msgstr ""
#: builtin/commit.c:493 builtin/commit.c:499
#, c-format
#: builtin/commit.c:522
msgid "malformed --author parameter"
-msgstr "parametro --author non corretto"
+msgstr "parametro --author malformato"
-#: builtin/commit.c:583
+#: builtin/commit.c:582
#, c-format
msgid "Malformed ident string: '%s'"
msgstr ""
-#: builtin/commit.c:621 builtin/commit.c:654 builtin/commit.c:968
+#: builtin/commit.c:620 builtin/commit.c:653 builtin/commit.c:967
#, c-format
msgid "could not lookup commit %s"
-msgstr ""
+msgstr "non è stato possibile trovare il commit %s"
-#: builtin/commit.c:633 builtin/shortlog.c:296
+#: builtin/commit.c:632 builtin/shortlog.c:296
#, c-format
msgid "(reading log message from standard input)\n"
msgstr "(lettura del messaggio di log dallo standard input)\n"
-#: builtin/commit.c:635
+#: builtin/commit.c:634
msgid "could not read log from standard input"
-msgstr "impossibile leggere il log dallo standard input"
+msgstr "non è stato possibile leggere il log dallo standard input"
-#: builtin/commit.c:639
+#: builtin/commit.c:638
#, c-format
msgid "could not read log file '%s'"
-msgstr "impossibile leggere il file di log '%s'"
+msgstr "non è stato possibile leggere il file di log '%s'"
-#: builtin/commit.c:645
+#: builtin/commit.c:644
msgid "commit has empty message"
msgstr "il commit ha un messaggio vuoto"
-#: builtin/commit.c:661
+#: builtin/commit.c:660
msgid "could not read MERGE_MSG"
-msgstr "impossibile leggere MERGE_MSG"
+msgstr "non è stato possibile leggere MERGE_MSG"
-#: builtin/commit.c:665
+#: builtin/commit.c:664
msgid "could not read SQUASH_MSG"
-msgstr "impossibile leggere SQUASH_MSG"
+msgstr "non è stato possibile leggere SQUASH_MSG"
-#: builtin/commit.c:669
+#: builtin/commit.c:668
#, c-format
msgid "could not read '%s'"
-msgstr "impossibile leggere '%s'"
+msgstr "non è stato possibile leggere '%s'"
-#: builtin/commit.c:721
+#: builtin/commit.c:720
msgid "could not write commit template"
msgstr "non è stato possibile scrivere il modello di commit"
-#: builtin/commit.c:732
+#: builtin/commit.c:731
#, c-format
msgid ""
"\n"
msgstr ""
"\n"
"Sembra che si stia eseguendo il commit di un merge.\n"
-"Se l'operazione non è corretta, per favore eliminare il file\n"
+"Se l'operazione non è corretta, per favore elimina il file\n"
"\t%s\n"
-"e riprovare.\n"
+"e riprova.\n"
-#: builtin/commit.c:737
+#: builtin/commit.c:736
#, c-format
msgid ""
"\n"
"\t%s\n"
"and try again.\n"
msgstr ""
+"\n"
+"Sembra che si stia eseguendo il commit di un cherry-pick.\n"
+"Se l'operazione non è corretta, per favore rimuovi il file\n"
+"\t%s\n"
+"e riprova.\n"
-#: builtin/commit.c:749
-#, fuzzy
+#: builtin/commit.c:748
msgid ""
"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be ignored, and an empty message aborts the commit.\n"
msgstr ""
-"Per favore, inserire il messaggio di commit per le modifiche effettuate.\n"
-"Le righe che iniziano con '#' verranno ignorate, ed un messaggio vuoto\n"
-"annulla il commit.\n"
+"Per favore inserisci il messaggio di commit per le modifiche. Le righe\n"
+"che iniziano con '#' verranno ignorate, e un messaggio vuoto annulla il commit.\n"
-#: builtin/commit.c:754
-#, fuzzy
+#: builtin/commit.c:753
msgid ""
"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be kept; you may remove them yourself if you want to.\n"
"An empty message aborts the commit.\n"
msgstr ""
-"Per favore, inserire il messaggio di commit per le modifiche effettuate.\n"
-"Le righe che iniziano con '#' verranno mantenute; possono essere rimosse\n"
-"manualmente se si vuole. Un messaggio vuoto annulla il commit.\n"
+"Per favore inserisci il messaggio di commit per le modifiche. Le\n"
+"righe che iniziano con '#' verranno mantenute; possono comunque essere\n"
+"rimosse manualmente. Un messaggio vuoto annulla il commit.\n"
-#: builtin/commit.c:767
+#: builtin/commit.c:766
#, c-format
msgid "%sAuthor: %s"
msgstr "%sAutore: %s"
-#: builtin/commit.c:774
+#: builtin/commit.c:773
#, c-format
msgid "%sCommitter: %s"
msgstr "%sCommitter: %s"
-#: builtin/commit.c:794
+#: builtin/commit.c:793
msgid "Cannot read index"
-msgstr "Impossibile leggere l'indice"
+msgstr "Impossibile leggere index"
-#: builtin/commit.c:831
+#: builtin/commit.c:830
msgid "Error building trees"
-msgstr "Errore nella creazione degli alberi"
+msgstr ""
-#: builtin/commit.c:846 builtin/tag.c:361
+#: builtin/commit.c:845 builtin/tag.c:361
#, c-format
msgid "Please supply the message using either -m or -F option.\n"
-msgstr "Per favore, fornire il messaggio usando l'opzione -m o -F.\n"
+msgstr "Per favore, specifica il messaggio usando l'opzione -m o -F.\n"
-#: builtin/commit.c:943
+#: builtin/commit.c:942
#, c-format
msgid "No existing author found with '%s'"
msgstr "Nessun autore esistente trovato con '%s'"
-#: builtin/commit.c:958 builtin/commit.c:1158
+#: builtin/commit.c:957 builtin/commit.c:1157
#, c-format
msgid "Invalid untracked files mode '%s'"
msgstr ""
-#: builtin/commit.c:998
+#: builtin/commit.c:997
msgid "Using both --reset-author and --author does not make sense"
msgstr "L'uso di entrambe le opzioni --reset-author e --author non ha senso"
-#: builtin/commit.c:1009
+#: builtin/commit.c:1008
msgid "You have nothing to amend."
-msgstr "Non c'è nulla da riparare."
+msgstr ""
-#: builtin/commit.c:1012
+#: builtin/commit.c:1011
msgid "You are in the middle of a merge -- cannot amend."
-msgstr "Si è nel mezzo di un merge -- non è possibile riparare."
+msgstr ""
-#: builtin/commit.c:1014
+#: builtin/commit.c:1013
msgid "You are in the middle of a cherry-pick -- cannot amend."
msgstr ""
-#: builtin/commit.c:1017
+#: builtin/commit.c:1016
msgid "Options --squash and --fixup cannot be used together"
msgstr "Le opzioni --squash e --fixup non possono essere usate insieme"
-#: builtin/commit.c:1027
+#: builtin/commit.c:1026
msgid "Only one of -c/-C/-F/--fixup can be used."
msgstr "Solo una delle opzioni -c/-C/-F/--fixup può essere usata."
-#: builtin/commit.c:1029
+#: builtin/commit.c:1028
msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
msgstr "L'opzione -m non può essere combinata con -c/-C/-F/--fixup."
-#: builtin/commit.c:1037
+#: builtin/commit.c:1036
msgid "--reset-author can be used only with -C, -c or --amend."
msgstr "L'opzione --reset-author può essere usata solo con -C, -c o --amend."
-#: builtin/commit.c:1054
+#: builtin/commit.c:1053
msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
-msgstr "Può essere usata solo una delle opzioni --include/--only/--all/--interactive/--patch ."
+msgstr ""
+"Può essere usata solo una delle opzioni --include/--only/--all/--"
+"interactive/--patch ."
-#: builtin/commit.c:1056
+#: builtin/commit.c:1055
msgid "No paths with --include/--only does not make sense."
-msgstr ""
+msgstr "Devi specificare un path se usi --include/--only."
-#: builtin/commit.c:1058
-#, fuzzy
+#: builtin/commit.c:1057
msgid "Clever... amending the last one with dirty index."
-msgstr "Furbo... riparare l'ultimo con un indice errato."
+msgstr ""
-#: builtin/commit.c:1060
+#: builtin/commit.c:1059
msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
msgstr ""
-#: builtin/commit.c:1070 builtin/tag.c:577
+#: builtin/commit.c:1069 builtin/tag.c:577
#, c-format
msgid "Invalid cleanup mode %s"
msgstr ""
-#: builtin/commit.c:1075
+#: builtin/commit.c:1074
msgid "Paths with -a does not make sense."
-msgstr ""
+msgstr "I path con -a non hanno senso."
-#: builtin/commit.c:1258
+#: builtin/commit.c:1257
msgid "couldn't look up newly created commit"
-msgstr ""
+msgstr "non è stato possibile trovare il commit appena creato"
-#: builtin/commit.c:1260
+#: builtin/commit.c:1259
msgid "could not parse newly created commit"
-msgstr ""
+msgstr "non è stato possibile analizzare il commit appena creato"
-#: builtin/commit.c:1301
+#: builtin/commit.c:1300
msgid "detached HEAD"
msgstr ""
-#: builtin/commit.c:1303
+#: builtin/commit.c:1302
msgid " (root-commit)"
-msgstr ""
+msgstr " (root-commit)"
-#: builtin/commit.c:1447
+#: builtin/commit.c:1446
msgid "could not parse HEAD commit"
-msgstr ""
+msgstr "non è stato possibile analizzare il commit HEAD"
-#: builtin/commit.c:1485 builtin/merge.c:509
+#: builtin/commit.c:1484 builtin/merge.c:509
#, c-format
msgid "could not open '%s' for reading"
msgstr "non è stato possibile aprire '%s' per la lettura"
-#: builtin/commit.c:1492
+#: builtin/commit.c:1491
#, c-format
msgid "Corrupt MERGE_HEAD file (%s)"
msgstr "File MERGE_HEAD corrotto (%s)"
-#: builtin/commit.c:1499
+#: builtin/commit.c:1498
msgid "could not read MERGE_MODE"
msgstr "non è stato possibile leggere MERGE_MODE"
-#: builtin/commit.c:1518
+#: builtin/commit.c:1517
#, c-format
msgid "could not read commit message: %s"
msgstr "non è stato possibile leggere il messaggio di commit: %s"
-#: builtin/commit.c:1532
+#: builtin/commit.c:1531
#, c-format
msgid "Aborting commit; you did not edit the message.\n"
-msgstr "Commit annullato; il messaggio non è stato modificato.\n"
+msgstr "Commit interrotto; il messaggio non è stato modificato.\n"
-#: builtin/commit.c:1537
+#: builtin/commit.c:1536
#, c-format
msgid "Aborting commit due to empty commit message.\n"
-msgstr "Annullamento del commit a causa di un messaggio di commit vuoto.\n"
+msgstr "Interruzione del commit a causa di un messaggio di commit vuoto.\n"
-#: builtin/commit.c:1552 builtin/merge.c:936 builtin/merge.c:961
+#: builtin/commit.c:1551 builtin/merge.c:936 builtin/merge.c:961
msgid "failed to write commit object"
msgstr "scrittura dell'oggetto di commit non riuscita"
-#: builtin/commit.c:1573
+#: builtin/commit.c:1572
msgid "cannot lock HEAD ref"
msgstr ""
-#: builtin/commit.c:1577
+#: builtin/commit.c:1576
msgid "cannot update HEAD ref"
msgstr ""
-#: builtin/commit.c:1588
+#: builtin/commit.c:1587
msgid ""
"Repository has been updated, but unable to write\n"
"new_index file. Check that disk is not full or quota is\n"
"not exceeded, and then \"git reset HEAD\" to recover."
msgstr ""
-"L'archivio è stato aggiornato, ma non è stato possibile scrivere il file\n"
-"new_index. Verificare che l'unità disco non sia piena o che la quota non sia\n"
-"stata superata, ed eseguire \"git reset HEAD\"ccc per il ripristino."
+"Il repository è stato aggiornato, ma non è stato possibile scrivere il file\n"
+"new_index. Verifica che l'unità disco non sia piena o che la quota non sia\n"
+"stata superata, ed esegui \"git reset HEAD\" per il ripristino."
#: builtin/describe.c:234
#, c-format
#: builtin/describe.c:240
#, c-format
msgid "tag '%s' is really '%s' here"
-msgstr ""
+msgstr "il tag '%s' è davvero '%s' qui"
#: builtin/describe.c:267
-#, c-format, fuzzy
+#, c-format
msgid "Not a valid object name %s"
msgstr "Non è il nome di un oggetto valido %s"
msgstr "%s non è un oggetto '%s' valido"
#: builtin/describe.c:287
-#, c-format, fuzzy
+#, c-format
msgid "no tag exactly matches '%s'"
msgstr "nessun tag corrisponde esattamente a '%s'"
"Try --always, or create some tags."
msgstr ""
"Nessun tag può descrivere '%s'.\n"
-"Provare con --always, o creare dei tag."
+"Prova con --always, o crea dei tag."
#: builtin/describe.c:378
#, c-format
#: builtin/diff.c:297
msgid "Not a git repository"
-msgstr "Non è un archivio git"
+msgstr "Non è un repository git"
#: builtin/diff.c:347
#, c-format
msgid "invalid object '%s' given."
-msgstr ""
+msgstr "oggetto non valido '%s' specificato."
#: builtin/diff.c:352
#, c-format
#: builtin/diff.c:362
#, c-format
msgid "more than two blobs given: '%s'"
-msgstr ""
+msgstr "più di due blob specificati: '%s'"
#: builtin/diff.c:370
#, c-format
msgid "unhandled object '%s' given."
-msgstr ""
+msgstr "oggetto non gestito '%s' specificato."
#: builtin/fetch.c:200
msgid "Couldn't find remote ref HEAD"
#: builtin/fetch.c:285
msgid "[tag update]"
-msgstr ""
+msgstr "[tag aggiornata]"
#: builtin/fetch.c:287 builtin/fetch.c:322 builtin/fetch.c:340
msgid " (unable to update local ref)"
-msgstr ""
+msgstr " (impossibile aggiornare il ref locale)"
#: builtin/fetch.c:305
-#, fuzzy
msgid "[new tag]"
msgstr "[nuova tag]"
#: builtin/fetch.c:308
msgid "[new branch]"
-msgstr "[nuovo ramo]"
+msgstr "[nuovo branch]"
#: builtin/fetch.c:311
msgid "[new ref]"
-msgstr ""
+msgstr "[nuovo ref]"
#: builtin/fetch.c:356
msgid "unable to update local ref"
-msgstr ""
+msgstr "impossibile aggiornare il ref locale"
#: builtin/fetch.c:356
msgid "forced update"
-msgstr ""
+msgstr "aggiornamento forzato"
#: builtin/fetch.c:362
msgid "(non-fast-forward)"
"some local refs could not be updated; try running\n"
" 'git remote prune %s' to remove any old, conflicting branches"
msgstr ""
+"non è stato possibile aggiornare alcuni ref locali; prova con\n"
+" 'git remote prune %s' per rimuovere ogni branch che vada in conflitto"
#: builtin/fetch.c:549
#, c-format
#: builtin/fetch.c:789
#, c-format
msgid "Option \"%s\" is ignored for %s\n"
-msgstr ""
+msgstr "L'opzione \"%s\" è ignorata per %s\n"
#: builtin/fetch.c:888
#, c-format
"No remote repository specified. Please, specify either a URL or a\n"
"remote name from which new revisions should be fetched."
msgstr ""
+"Nessun repository remoto specificato. Per favore, specifica un URL o\n"
+"il nome di un remote da cui prelevare nuove revisioni."
#: builtin/fetch.c:927
-#, fuzzy
msgid "You need to specify a tag name."
-msgstr "È necessario specificare il nome di un tag."
+msgstr "Devi specificare il nome di un tag."
#: builtin/fetch.c:979
msgid "fetch --all does not take a repository argument"
-msgstr "fetch --all non richiede l'archivio come argomento"
+msgstr "fetch --all non richiede il repository come argomento"
#: builtin/fetch.c:981
msgid "fetch --all does not make sense with refspecs"
#: builtin/gc.c:63
#, c-format
msgid "Invalid %s: '%s'"
-msgstr ""
+msgstr "%s non valido: '%s'"
#: builtin/gc.c:90
#, c-format
#: builtin/grep.c:216
#, c-format
msgid "grep: failed to create thread: %s"
-msgstr ""
+msgstr "grep: creazione del thread non riuscita: %s"
#: builtin/grep.c:402
#, c-format
#: builtin/grep.c:478 builtin/grep.c:512
#, c-format
msgid "unable to read tree (%s)"
-msgstr ""
+msgstr "impossibile leggere il tree (%s)"
#: builtin/grep.c:526
#, c-format
#: builtin/grep.c:584
#, c-format
msgid "switch `%c' expects a numerical value"
-msgstr ""
+msgstr "switch '%c' richiede un valore numerico"
#: builtin/grep.c:601
#, c-format
msgid "cannot open '%s'"
msgstr "impossibile aprire '%s'"
-#: builtin/grep.c:888
+#: builtin/grep.c:885
msgid "no pattern given."
-msgstr ""
+msgstr "nessun modello specificato."
-#: builtin/grep.c:902
+#: builtin/grep.c:899
#, c-format
msgid "bad object %s"
msgstr "oggetto %s errato"
-#: builtin/grep.c:943
+#: builtin/grep.c:940
msgid "--open-files-in-pager only works on the worktree"
-msgstr "--open-files-in-pager funziona solo nell'albero di lavoro"
+msgstr ""
-#: builtin/grep.c:966
+#: builtin/grep.c:963
msgid "--cached or --untracked cannot be used with --no-index."
msgstr "--cached o --untracked non può essere usato con --no-index."
-#: builtin/grep.c:971
+#: builtin/grep.c:968
msgid "--no-index or --untracked cannot be used with revs."
-msgstr ""
+msgstr "--no-index o --untracked non possono essere usate con le revisioni."
-#: builtin/grep.c:974
+#: builtin/grep.c:971
msgid "--[no-]exclude-standard cannot be used for tracked contents."
-msgstr "--[no-]exclude-standard non può essere usato per il contenuto tracciato."
+msgstr ""
-#: builtin/grep.c:982
+#: builtin/grep.c:979
msgid "both --cached and trees are given."
msgstr ""
#: builtin/help.c:108
#, c-format
msgid "emacsclient version '%d' too old (< 22)."
-msgstr "la versione '%d' di emacsclient è vecchia (<22)."
+msgstr "la versione '%d' di emacsclient è troppo vecchia (<22)."
#: builtin/help.c:126 builtin/help.c:154 builtin/help.c:163 builtin/help.c:171
#, c-format
"'%s': path for unsupported man viewer.\n"
"Please consider using 'man.<tool>.cmd' instead."
msgstr ""
-"'%s': percorso ad un visualizzatore man non supportato.\n"
-"Utilizzare invece 'man.<tool>.cmd'."
+"'%s': path ad un visualizzatore man pages non supportato.\n"
+"Usa invece 'man.<tool>.cmd'."
#: builtin/help.c:223
#, c-format
"'%s': cmd for supported man viewer.\n"
"Please consider using 'man.<tool>.path' instead."
msgstr ""
+"'%s': comando per visualizzatore man pages supportato.\n"
+"Per favore usa 'man.<tool>.path' invece."
#: builtin/help.c:287
msgid "The most commonly used git commands are:"
#: builtin/help.c:355
#, c-format
msgid "'%s': unknown man viewer."
-msgstr "'%s': visualizzatore mano sconosciuto."
+msgstr "'%s': visualizzatore man sconosciuto."
#: builtin/help.c:372
msgid "no man viewer handled the request"
#: builtin/help.c:391
#, c-format
msgid "'%s': not a documentation directory."
-msgstr "'%s': non è una cartella della documentazione."
+msgstr "'%s': non è una directory della documentazione."
#: builtin/help.c:432 builtin/help.c:439
#, c-format
#: builtin/index-pack.c:256
msgid "pack too large for current definition of off_t"
-msgstr ""
+msgstr "pack troppo largo per la definizione corrente di off_t"
#: builtin/index-pack.c:272
#, c-format
msgid "unable to create '%s'"
-msgstr "non è possibile creare '%s'"
+msgstr "impossibile creare '%s'"
#: builtin/index-pack.c:277
#, c-format
msgid "cannot open packfile '%s'"
-msgstr ""
+msgstr "impossibile aprire il file pack '%s'"
#: builtin/index-pack.c:291
-#, fuzzy
msgid "pack signature mismatch"
msgstr "la firma del pack non coincide"
#: builtin/index-pack.c:598
#, c-format
msgid "invalid blob object %s"
-msgstr ""
+msgstr "oggetto blob %s non valido"
#: builtin/index-pack.c:610
-#, c-format, fuzzy
+#, c-format
msgid "invalid %s"
msgstr "%s non valido"
msgstr "Indicizzazione degli oggetti"
#: builtin/index-pack.c:872
-#, fuzzy
msgid "pack is corrupted (SHA1 mismatch)"
msgstr "il pack è corrotto (SHA1 non corrisponde)"
#, c-format
msgid "pack has %d unresolved delta"
msgid_plural "pack has %d unresolved deltas"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "pack ha %d delta irrisolto"
+msgstr[1] "pack ha %d delta irrisolti"
#: builtin/index-pack.c:998
#, c-format
#: builtin/index-pack.c:1077
#, c-format
msgid "local object %s is corrupt"
-msgstr ""
+msgstr "l'oggetto locale %s è corrotto"
#: builtin/index-pack.c:1101
-#, fuzzy
msgid "error while closing pack file"
-msgstr "errore durante la chiusura del file pack"
+msgstr "errore nella chiusura del file pack"
#: builtin/index-pack.c:1114
-#, c-format, fuzzy
+#, c-format
msgid "cannot write keep file '%s'"
-msgstr "non è stato possibile scrivere il keep file '%s'"
+msgstr "impossibile scrivere il file keep '%s'"
#: builtin/index-pack.c:1122
#, c-format
#: builtin/index-pack.c:1135
msgid "cannot store pack file"
-msgstr ""
+msgstr "impossibile archiviare il file pack"
#: builtin/index-pack.c:1146
msgid "cannot store index file"
-msgstr ""
+msgstr "impossibile archiviare index file"
#: builtin/index-pack.c:1247
#, c-format
msgid "Cannot open existing pack file '%s'"
-msgstr ""
+msgstr "Impossibile aprire il file pack '%s' esistente"
#: builtin/index-pack.c:1249
#, c-format
msgstr ""
#: builtin/index-pack.c:1296
-#, c-format, fuzzy
+#, c-format
msgid "non delta: %d object"
msgid_plural "non delta: %d objects"
msgstr[0] "non delta: %d oggetto"
msgstr[1] "non delta: %d oggetti"
#: builtin/index-pack.c:1303
-#, c-format, fuzzy
+#, c-format
msgid "chain length = %d: %lu object"
msgid_plural "chain length = %d: %lu objects"
msgstr[0] "lunghezza della catena = %d: %lu oggetto"
msgstr "--fix-thin non può essere usato senza --stdin"
#: builtin/index-pack.c:1411 builtin/index-pack.c:1421
-#, c-format, fuzzy
+#, c-format
msgid "packfile name '%s' does not end with '.pack'"
msgstr "il nome del file pack '%s' non termina con '.pack'"
#: builtin/index-pack.c:1430
-#, fuzzy
msgid "--verify with no packfile name given"
-msgstr "--verify senza un nome del file pack fornito"
+msgstr "--verify senza un nome del file pack specificato"
#: builtin/init-db.c:35
#, c-format
msgid "Could not make %s writable by group"
-msgstr ""
+msgstr "Non è stato possible rendere %s scrivibile dal gruppo"
#: builtin/init-db.c:62
#, c-format
#: builtin/init-db.c:67
#, c-format
msgid "cannot stat '%s'"
-msgstr "non è stato possibile eseguire lo stat di '%s'"
+msgstr "impossibile eseguire lo stat di '%s'"
#: builtin/init-db.c:73
#, c-format
#: builtin/init-db.c:354
#, c-format
msgid "unable to handle file type %d"
-msgstr ""
+msgstr "impossibile gestire il tipo di file %d"
#: builtin/init-db.c:357
#, c-format
msgid "unable to move %s to %s"
-msgstr "non è stato possibile spostare %s in %s"
+msgstr "impossibile spostare %s in %s"
#: builtin/init-db.c:362
#, c-format
msgid "Could not create git link %s"
-msgstr ""
+msgstr "Non è stato possibile creare il link git %s"
#.
#. * TRANSLATORS: The first '%s' is either "Reinitialized
#: builtin/init-db.c:419
#, c-format
msgid "%s%s Git repository in %s%s\n"
-msgstr "%s%s archivio Git in %s%s\n"
+msgstr "%s%s repository Git in %s%s\n"
#: builtin/init-db.c:420
-#, fuzzy
msgid "Reinitialized existing"
msgstr "Reinizializzato un esistente"
#: builtin/init-db.c:420
-#, fuzzy
msgid "Initialized empty"
-msgstr "Inizializzato un vuoto"
+msgstr "Inizializzato un"
#: builtin/init-db.c:421
msgid " shared"
"%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-"
"dir=<directory>)"
msgstr ""
-"%s (o --work-tree=<cartella>) non consentito senza specificare %s (o --git-"
-"dir=<cartella>)"
+"%s (o --work-tree=<directory>) non consentito senza specificare %s (o --git-"
+"dir=<directory>)"
#: builtin/init-db.c:578
msgid "Cannot access current working directory"
-msgstr "Non è stato possibile accedere alla cartella di lavoro corrente"
+msgstr "Impossibile accedere alla directory di lavoro corrente"
#: builtin/init-db.c:585
#, c-format
msgid "Cannot access work tree '%s'"
-msgstr "Non è stato possibile accedere all'albero di lavoro '%s'"
+msgstr ""
#: builtin/log.c:188
#, c-format
msgid "Final output: %d %s\n"
-msgstr ""
+msgstr "Output finale: %d %s\n"
#: builtin/log.c:401 builtin/log.c:489
#, c-format
msgid "format.headers without value"
msgstr "format.headers non ha alcun valore"
-#: builtin/log.c:675
+#: builtin/log.c:676
msgid "name of output directory is too long"
-msgstr "il nome della cartella di output è troppo lungo"
+msgstr "il nome della directory di output è troppo lungo"
-#: builtin/log.c:686
+#: builtin/log.c:687
#, c-format
msgid "Cannot open patch file %s"
-msgstr "Non è possibile aprire il file patch %s"
+msgstr "Impossibile aprire il file patch %s"
-#: builtin/log.c:700
+#: builtin/log.c:701
msgid "Need exactly one range."
msgstr ""
-#: builtin/log.c:708
+#: builtin/log.c:709
msgid "Not a range."
msgstr ""
-#: builtin/log.c:745
-msgid "Could not extract email from committer identity."
-msgstr "Non è stato possibile estrarre l'indirizzo email dall'identità del committer."
-
-#: builtin/log.c:791
+#: builtin/log.c:786
msgid "Cover letter needs email format"
msgstr ""
-#: builtin/log.c:885
+#: builtin/log.c:859
#, c-format
msgid "insane in-reply-to: %s"
msgstr ""
-#: builtin/log.c:958
+#: builtin/log.c:932
msgid "Two output directories?"
-msgstr "Due cartelle di output?"
+msgstr "Due directory di output?"
-#: builtin/log.c:1179
+#: builtin/log.c:1153
#, c-format
msgid "bogus committer info %s"
msgstr ""
-#: builtin/log.c:1224
+#: builtin/log.c:1198
msgid "-n and -k are mutually exclusive."
msgstr ""
-#: builtin/log.c:1226
+#: builtin/log.c:1200
msgid "--subject-prefix and -k are mutually exclusive."
msgstr ""
-#: builtin/log.c:1234
+#: builtin/log.c:1208
msgid "--name-only does not make sense"
msgstr "--name-only non ha senso"
-#: builtin/log.c:1236
+#: builtin/log.c:1210
msgid "--name-status does not make sense"
msgstr "--name-status non ha senso"
-#: builtin/log.c:1238
+#: builtin/log.c:1212
msgid "--check does not make sense"
msgstr "--check non ha senso"
-#: builtin/log.c:1261
+#: builtin/log.c:1235
msgid "standard output, or directory, which one?"
-msgstr "standard output, o cartella, quale dei due?"
+msgstr "standard output, o directory, quale dei due?"
-#: builtin/log.c:1263
+#: builtin/log.c:1237
#, c-format
msgid "Could not create directory '%s'"
-msgstr "Non è stato possibile creare la cartella '%s'"
+msgstr "Non è stato possibile creare la directory '%s'"
-#: builtin/log.c:1416
+#: builtin/log.c:1390
msgid "Failed to create output files"
msgstr "Creazione dei file di output non riuscita"
-#: builtin/log.c:1520
+#: builtin/log.c:1494
#, c-format
msgid ""
"Could not find a tracked remote branch, please specify <upstream> manually.\n"
msgstr ""
-#: builtin/log.c:1536 builtin/log.c:1538 builtin/log.c:1550
+#: builtin/log.c:1510 builtin/log.c:1512 builtin/log.c:1524
#, c-format
msgid "Unknown commit %s"
msgstr "Commit %s sconosciuto"
#: builtin/merge.c:629
msgid "git write-tree failed to write a tree"
-msgstr "git write-tree non è riuscito a scrivere un albero"
+msgstr ""
#: builtin/merge.c:679
msgid "failed to read the cache"
#: builtin/merge.c:697
msgid "Unable to write index."
-msgstr "Non è possibile scrivere l'indice."
+msgstr "Impossibile scrivere index."
#: builtin/merge.c:710
msgid "Not handling anything other than two heads merge."
msgstr "Splendido.\n"
#: builtin/merge.c:993
-#, c-format, fuzzy
+#, c-format
msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
msgstr ""
-"Merge automatico fallito; risolvere i conflitti ed effettuare il commit del\n"
-"risultato.\n"
+"Merge automatico fallito; risolvi i conflitti ed eseguire il commit\n"
+"del risultato.\n"
#: builtin/merge.c:1009
#, c-format
#: builtin/merge.c:1050
msgid "No current branch."
-msgstr "Nessun ramo corrente."
+msgstr "Nessun branch corrente."
#: builtin/merge.c:1052
msgid "No remote for the current branch."
-msgstr ""
+msgstr "Nessun remote per il branch corrente."
#: builtin/merge.c:1054
-#, fuzzy
msgid "No default upstream defined for the current branch."
-msgstr "Nessun upstream di default definito per il ramo corrente."
+msgstr "Nessun upstream di default definito per il branch corrente."
#: builtin/merge.c:1059
#, c-format
msgstr ""
#: builtin/merge.c:1146 builtin/merge.c:1303
-#, c-format, fuzzy
+#, c-format
msgid "%s - not something we can merge"
-msgstr "%s - non è qualcosa per cui effettuare il merge"
+msgstr "%s - non è qualcosa per cui possiamo eseguire il merge"
#: builtin/merge.c:1214
msgid "There is no merge to abort (MERGE_HEAD missing)."
-msgstr ""
+msgstr "Non c'è nessun merge da interrompere (manca MERGE_HEAD)"
#: builtin/merge.c:1230 git-pull.sh:31
msgid ""
"Please, commit your changes before you can merge."
msgstr ""
"Il merge non è stato concluso (esiste MERGE_HEAD).\n"
-"Per favore, effettuare il commit delle modifiche prima del merge."
+"Per favore, esegui il commit delle modifiche prima del merge."
#: builtin/merge.c:1233 git-pull.sh:34
msgid "You have not concluded your merge (MERGE_HEAD exists)."
"Please, commit your changes before you can merge."
msgstr ""
"Il cherry-pick non è stato concluso (esiste CHERRY_PICK_HEAD).\n"
-"Per favore, eseguire il commit delle modifiche prima del merge."
+"Per favore, esegui il commit delle modifiche prima del merge."
#: builtin/merge.c:1240
msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
-msgstr ""
+msgstr "Il tuo cherry-pick non è stato concluso (CHERRY_PICK_HEAD esiste)."
#: builtin/merge.c:1249
msgid "You cannot combine --squash with --no-ff."
-msgstr "Non è possibile combinare --squash con --no-off."
+msgstr "Impossibile combinare --squash con --no-off."
#: builtin/merge.c:1254
msgid "You cannot combine --no-ff with --ff-only."
-msgstr "Non è possibile combinare --no-ff con --ff-only."
+msgstr "Impossibile combinare --no-ff con --ff-only."
#: builtin/merge.c:1261
msgid "No commit specified and merge.defaultToUpstream not set."
#: builtin/merge.c:1490
msgid "Not possible to fast-forward, aborting."
-msgstr ""
+msgstr "Fast-forward non possibile, stop."
#: builtin/merge.c:1513 builtin/merge.c:1592
#, c-format
#: builtin/merge.c:1517
#, c-format
msgid "Trying merge strategy %s...\n"
-msgstr ""
+msgstr "Tentativo con la strategia di merge %s...\n"
#: builtin/merge.c:1583
#, c-format
msgid "No merge strategy handled the merge.\n"
-msgstr ""
+msgstr "Nessuna strategia di merge ha gestito il merge.\n"
#: builtin/merge.c:1585
#, c-format
msgid "Merge with strategy %s failed.\n"
-msgstr ""
+msgstr "Merge con la strategia %s fallito.\n"
#: builtin/merge.c:1594
#, c-format
#, c-format
msgid "Automatic merge went well; stopped before committing as requested\n"
msgstr ""
+"Il merge automatico è andato a buon fine; fermato prima del commit come "
+"richiesto\n"
#: builtin/mv.c:108
#, c-format
#: builtin/mv.c:115
msgid "can not move directory into itself"
-msgstr ""
+msgstr "non è possibile spostare la directory in sé stessa"
#: builtin/mv.c:118
msgid "cannot move directory over file"
-msgstr ""
+msgstr "non è possibile spostare la directory su un file"
#: builtin/mv.c:128
#, c-format
msgid "Huh? %.*s is in index?"
-msgstr "Eh? %.*s si trova nell'indice?"
+msgstr "Eh? %.*s si trova in index?"
#: builtin/mv.c:140
msgid "source directory is empty"
-msgstr "la cartella sorgente è vuota"
+msgstr "la directory sorgente è vuota"
#: builtin/mv.c:171
msgid "not under version control"
-msgstr "non si trova nel sistema di controllo versione"
+msgstr "non è sotto controllo di versione"
#: builtin/mv.c:173
msgid "destination exists"
#: builtin/mv.c:184
msgid "Cannot overwrite"
-msgstr ""
+msgstr "Impossibile sovrascrivere"
#: builtin/mv.c:187
msgid "multiple sources for the same target"
#: builtin/mv.c:215 builtin/remote.c:731
#, c-format
msgid "renaming '%s' failed"
-msgstr ""
+msgstr "rinomina di '%s' non riuscita"
#: builtin/notes.c:139
#, c-format
msgid "unable to start 'show' for object '%s'"
-msgstr ""
+msgstr "impossibile avviare 'show' per l'oggetto '%s'"
#: builtin/notes.c:145
msgid "can't fdopen 'show' output fd"
#: builtin/notes.c:175 builtin/tag.c:347
#, c-format
msgid "could not create file '%s'"
-msgstr ""
+msgstr "non è stato possibile creare il file '%s'"
#: builtin/notes.c:189
msgid "Please supply the note contents using either -m or -F option"
-msgstr ""
+msgstr "Per favore specifica il contenuto delle note usando le opzioni -m o -F"
#: builtin/notes.c:210 builtin/notes.c:973
#, c-format
msgid "Removing note for object %s\n"
-msgstr ""
+msgstr "Rimozione della nota per l'oggetto %s\n"
#: builtin/notes.c:215
msgid "unable to write note object"
-msgstr ""
+msgstr "impossibile scrivere l'oggetto nota"
#: builtin/notes.c:217
#, c-format
msgid "The note contents has been left in %s"
-msgstr ""
+msgstr "Il contenuto della nota è stato lasciato in %s"
#: builtin/notes.c:251 builtin/tag.c:542
#, c-format
msgid "cannot read '%s'"
-msgstr ""
+msgstr "impossibile leggere '%s'"
#: builtin/notes.c:253 builtin/tag.c:545
#, c-format
msgid "could not open or read '%s'"
-msgstr ""
+msgstr "non è stato possibile aprire o leggere '%s'"
#: builtin/notes.c:272 builtin/notes.c:445 builtin/notes.c:447
#: builtin/notes.c:507 builtin/notes.c:561 builtin/notes.c:644
#: builtin/notes.c:275
#, c-format
msgid "Failed to read object '%s'."
-msgstr ""
+msgstr "Lettura dell'oggetto '%s' non riuscita."
#: builtin/notes.c:299
msgid "Cannot commit uninitialized/unreferenced notes tree"
#: builtin/notes.c:350
#, c-format
msgid "Refusing to rewrite notes in %s (outside of refs/notes/)"
-msgstr ""
+msgstr "Impossibile riscrivere le note in %s (al di fuori di refs/notes/)"
#. TRANSLATORS: The first %s is the name of the
#. environment variable, the second %s is its value
#: builtin/notes.c:441
#, c-format
msgid "Malformed input line: '%s'."
-msgstr ""
+msgstr "Riga di input malformata: '%s'."
#: builtin/notes.c:456
#, c-format
msgid "Failed to copy notes from '%s' to '%s'"
-msgstr ""
+msgstr "Copia delle note da '%s' a '%s' non riuscita"
#: builtin/notes.c:500 builtin/notes.c:554 builtin/notes.c:627
#: builtin/notes.c:639 builtin/notes.c:712 builtin/notes.c:759
#: builtin/notes.c:585 builtin/notes.c:662
#, c-format
msgid "Overwriting existing notes for object %s\n"
-msgstr ""
+msgstr "Sovrascrittura delle note esistenti per l'oggetto %s\n"
#: builtin/notes.c:635
msgid "too few parameters"
"Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite "
"existing notes"
msgstr ""
+"Impossibile copiare le note. Trovate note esistenti per l'oggetto %s. Usa "
+"'-f' per sovrascrivere le note esistenti"
#: builtin/notes.c:668
#, c-format
msgid "Missing notes on source object %s. Cannot copy."
-msgstr ""
+msgstr "Note mancanti per l'oggetto sorgente %s. Impossibile copiare."
#: builtin/notes.c:717
#, c-format
"The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n"
"Please use 'git notes add -f -m/-F/-c/-C' instead.\n"
msgstr ""
+"Le opzioni -m/-F/-c/-C per il sottocomando 'edit' sono deprecate.\n"
+"Per favore usa 'git notes add -f -m/-F/-c/-C' invece.\n"
#: builtin/notes.c:971
#, c-format
#: builtin/notes.c:1103 builtin/remote.c:1598
#, c-format
msgid "Unknown subcommand: %s"
-msgstr ""
+msgstr "Sottocomando sconosciuto: %s"
-#: builtin/pack-objects.c:2315
+#: builtin/pack-objects.c:2337
#, c-format
msgid "unsupported index version %s"
-msgstr ""
+msgstr "versione %s di index non supportata"
-#: builtin/pack-objects.c:2319
+#: builtin/pack-objects.c:2341
#, c-format
msgid "bad index version '%s'"
-msgstr "versione dell'indice '%s' errata"
+msgstr "versione '%s' di index errata"
-#: builtin/pack-objects.c:2342
+#: builtin/pack-objects.c:2364
#, c-format
msgid "option %s does not accept negative form"
msgstr "l'opzione %s non accetta forme negative"
-#: builtin/pack-objects.c:2346
+#: builtin/pack-objects.c:2368
#, c-format
msgid "unable to parse value '%s' for option %s"
-msgstr ""
+msgstr "impossibile analizzare il valore '%s' per l'opzione %s"
#: builtin/push.c:45
msgid "tag shorthand without <tag>"
#: builtin/push.c:64
msgid "--delete only accepts plain target ref names"
-msgstr ""
+msgstr "--delete accetta solo nomi dei ref di destinazione in chiaro"
#: builtin/push.c:99
msgid ""
"\n"
" git push --set-upstream %s %s\n"
msgstr ""
+"Il branch corrente %s non ha alcun branch upstream.\n"
+"Per eseguire il push del branch corrente ed impostare remote come upstream, usa\n"
+"\n"
+" git push --set-upstream %s %s\n"
#: builtin/push.c:136
#, c-format
msgid "The current branch %s has multiple upstream branches, refusing to push."
-msgstr ""
+msgstr "Il branch corrente %s ha branch multipli in upstream; push non eseguito."
#: builtin/push.c:139
#, c-format
msgid ""
"You didn't specify any refspecs to push, and push.default is \"nothing\"."
msgstr ""
+"Non è stato specificato alcun refspec per il push, e push.default è \"nothing\"."
#: builtin/push.c:181
msgid ""
#: builtin/push.c:269
#, c-format
msgid "bad repository '%s'"
-msgstr "archivio '%s' errato"
+msgstr "repository '%s' errato"
#: builtin/push.c:270
msgid ""
"\n"
" git push <name>\n"
msgstr ""
+"Nessuna destinazione per il push configurata.\n"
+"Specifica un URL dalla riga di comando oppure configurare un repository "
+"remoto usando\n"
+"\n"
+" git remote add <nome> <url>\n"
+"\n"
+"e poi eseguire il push usando il nome del remote\n"
+"\n"
+" git push <nome>\n"
#: builtin/push.c:285
msgid "--all and --tags are incompatible"
-msgstr "--all e tags non sono compatibili"
+msgstr "--all e --tags non sono compatibili"
#: builtin/push.c:286
msgid "--all can't be combined with refspecs"
#: builtin/push.c:291
msgid "--mirror and --tags are incompatible"
-msgstr ""
+msgstr "--mirror e --tags non sono compatibili"
#: builtin/push.c:292
msgid "--mirror can't be combined with refspecs"
#: builtin/push.c:387
msgid "--delete doesn't make sense without any refs"
-msgstr ""
+msgstr "--delete non ha senso senza alcun ref"
#: builtin/remote.c:98
#, c-format
"\t use --mirror=fetch or --mirror=push instead"
msgstr ""
"--mirror è pericoloso e deprecato; per favore\n"
-"\t usare invece --mirror-fetch o --mirror-push"
+"\t usa invece --mirror-fetch o --mirror-push"
#: builtin/remote.c:147
#, c-format
msgid "unknown mirror argument: %s"
-msgstr ""
+msgstr "argomento di mirror sconosciuto: %s"
#: builtin/remote.c:185
msgid "specifying a master branch makes no sense with --mirror"
-msgstr ""
+msgstr "specificare un branch master con --mirror non ha senso"
#: builtin/remote.c:187
msgid "specifying branches to track makes sense only with fetch mirrors"
#: builtin/remote.c:195 builtin/remote.c:646
#, c-format
msgid "remote %s already exists."
-msgstr ""
+msgstr "il remoto %s esiste già."
#: builtin/remote.c:199 builtin/remote.c:650
#, c-format
msgid "'%s' is not a valid remote name"
-msgstr ""
+msgstr "'%s' non è un nome di remoto valido"
#: builtin/remote.c:243
#, c-format
msgid "Could not setup master '%s'"
-msgstr ""
+msgstr "Non è stato possibile configurare il master '%s'"
#: builtin/remote.c:299
#, c-format
msgid "more than one %s"
-msgstr ""
+msgstr "più di un %s"
#: builtin/remote.c:339
#, c-format
#: builtin/remote.c:440 builtin/remote.c:448
msgid "(matching)"
-msgstr ""
+msgstr "(corrispondente)"
#: builtin/remote.c:452
msgid "(delete)"
-msgstr ""
+msgstr "(elimina)"
#: builtin/remote.c:595 builtin/remote.c:601 builtin/remote.c:607
#, c-format
msgid "Could not append '%s' to '%s'"
-msgstr ""
+msgstr "Non è stato possibile aggiungere '%s' a '%s'"
#: builtin/remote.c:639 builtin/remote.c:792 builtin/remote.c:890
#, c-format
msgid "No such remote: %s"
-msgstr ""
+msgstr "Remote non esistente: %s"
#: builtin/remote.c:656
-#, c-format, fuzzy
+#, c-format
msgid "Could not rename config section '%s' to '%s'"
-msgstr "Non è stato possibile rinominare la sezione di configurazione '%s' in '%s'"
+msgstr "Non è stato possibile rinominare la sezione di configurazione da '%s' in '%s'"
#: builtin/remote.c:662 builtin/remote.c:799
#, c-format
#: builtin/remote.c:677
#, c-format
msgid ""
-"Not updating non-default fetch respec\n"
+"Not updating non-default fetch refspec\n"
"\t%s\n"
"\tPlease update the configuration manually if necessary."
msgstr ""
#: builtin/remote.c:694
#, c-format
msgid "Could not set '%s'"
-msgstr ""
+msgstr "Non è stato possibile impostare '%s'"
#: builtin/remote.c:716
#, c-format
msgid "deleting '%s' failed"
-msgstr "eliminazione di '%s' fallita"
+msgstr "eliminazione di '%s' non riuscita"
#: builtin/remote.c:750
#, c-format
#: builtin/remote.c:764
#, c-format
msgid "Could not remove branch %s"
-msgstr "Non è stato possibile rimuovere il ramo %s"
+msgstr "Non è stato possibile rimuovere il branch %s"
#: builtin/remote.c:834
msgid ""
"Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n"
"to delete them, use:"
msgstr[0] ""
+"Nota: un branch al di fuori della gerarchia refs/remotes/ non è stato "
+"eliminato;\n"
+"per eliminarlo, usare:"
msgstr[1] ""
+"Nota: alcuni branch al di fuori della gerarchia refs/remotes/ non sono stati "
+"eliminati;\n"
+"per eliminarli, usare:"
#: builtin/remote.c:943
#, c-format
#: builtin/remote.c:948
msgid " stale (use 'git remote prune' to remove)"
-msgstr ""
+msgstr " vecchio (usare 'git remote prune' per rimuoverlo)"
#: builtin/remote.c:950
msgid " ???"
-msgstr ""
+msgstr "???"
#: builtin/remote.c:991
#, c-format
msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
msgstr ""
+"branch.%s.merge non valido; impossibile eseguire il rebase su > 1 branch"
#: builtin/remote.c:998
#, c-format
#: builtin/remote.c:1001
#, c-format
msgid " merges with remote %s"
-msgstr ""
+msgstr " merge con il remote %s"
#: builtin/remote.c:1002
msgid " and with remote"
-msgstr ""
+msgstr " e con il remote"
#: builtin/remote.c:1004
#, c-format
msgid "merges with remote %s"
-msgstr ""
+msgstr "merge con il remote %s"
#: builtin/remote.c:1005
msgid " and with remote"
#: builtin/remote.c:1051
msgid "create"
-msgstr ""
+msgstr "crea"
#: builtin/remote.c:1054
msgid "delete"
-msgstr ""
+msgstr "elimina"
#: builtin/remote.c:1058
msgid "up to date"
-msgstr ""
+msgstr "aggiornato"
#: builtin/remote.c:1061
msgid "fast-forwardable"
#: builtin/remote.c:1064
msgid "local out of date"
-msgstr ""
+msgstr "locale non aggiornato"
#: builtin/remote.c:1071
#, c-format
#: builtin/remote.c:1081
#, c-format
msgid " %-*s pushes to %s"
-msgstr ""
+msgstr " %-*s esegue il push su %s"
#: builtin/remote.c:1118
#, c-format
msgid "* remote %s"
-msgstr ""
+msgstr "* remote %s"
#: builtin/remote.c:1119
#, c-format
#: builtin/remote.c:1133 builtin/remote.c:1135 builtin/remote.c:1137
#, c-format
msgid " HEAD branch: %s"
-msgstr " ramo HEAD: %s"
+msgstr " branch HEAD: %s"
#: builtin/remote.c:1139
#, c-format
msgid ""
" HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
msgstr ""
+" branch HEAD (l'HEAD remoto è ambiguo, potrebbe essere uno dei seguenti):\n"
#: builtin/remote.c:1151
#, c-format
msgid " Remote branch:%s"
msgid_plural " Remote branches:%s"
-msgstr[0] " Ramo remoto:%s"
-msgstr[1] " Rami remoti:%s"
+msgstr[0] " Branch remoto:%s"
+msgstr[1] " Branch remoti:%s"
#: builtin/remote.c:1154 builtin/remote.c:1181
msgid " (status not queried)"
#: builtin/remote.c:1163
msgid " Local branch configured for 'git pull':"
msgid_plural " Local branches configured for 'git pull':"
-msgstr[0] " Ramo locale configurato per 'git pull':"
-msgstr[1] " Rami locali configurati per 'git pull':"
+msgstr[0] " Branch locale configurato per 'git pull':"
+msgstr[1] " Branch locali configurati per 'git pull':"
#: builtin/remote.c:1171
msgid " Local refs will be mirrored by 'git push'"
#, c-format
msgid " Local ref configured for 'git push'%s:"
msgid_plural " Local refs configured for 'git push'%s:"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] " Ref locale configurato per 'git push'%s:"
+msgstr[1] " Ref locali configurati per 'git push'%s:"
#: builtin/remote.c:1216
msgid "Cannot determine remote HEAD"
-msgstr ""
+msgstr "Impossibile determinare l'HEAD remoto"
#: builtin/remote.c:1218
msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
#: builtin/remote.c:1228
#, c-format
msgid "Could not delete %s"
-msgstr ""
+msgstr "Non è stato possibile eliminare %s"
#: builtin/remote.c:1236
#, c-format
msgid "Not a valid ref: %s"
-msgstr ""
+msgstr "Non è un ref valido: %s"
#: builtin/remote.c:1238
#, c-format
msgid "Could not setup %s"
-msgstr ""
+msgstr "Non è stato possibile configurare %s"
#: builtin/remote.c:1274
#, c-format
#: builtin/remote.c:1282
#, c-format
msgid "URL: %s"
-msgstr ""
+msgstr "URL: %s"
#: builtin/remote.c:1295
#, c-format
#: builtin/remote.c:1387 builtin/remote.c:1461
#, c-format
msgid "No such remote '%s'"
-msgstr ""
+msgstr "Remote '%s' non esistente"
#: builtin/remote.c:1414
msgid "no remote specified"
-msgstr ""
+msgstr "nessun remote specificato"
#: builtin/remote.c:1447
msgid "--add --delete doesn't make sense"
#: builtin/reset.c:85
#, c-format
msgid "Failed to find tree of %s."
-msgstr "Ricerca dell'albero di %s non riuscita."
+msgstr ""
#: builtin/reset.c:96
msgid "Could not write new index file."
-msgstr "Non è stato possibile scrivere il nuovo file indice."
+msgstr "Non è stato possibile scrivere il nuovo index file."
#: builtin/reset.c:106
-#, c-format, fuzzy
+#, c-format
msgid "HEAD is now at %s"
msgstr "HEAD ora si trova a %s"
#: builtin/reset.c:130
msgid "Could not read index"
-msgstr "Non è possibile leggere l'indice"
+msgstr "Non è stato possibile leggere index"
#: builtin/reset.c:133
msgid "Unstaged changes after reset:"
#: builtin/reset.c:223
#, c-format
msgid "Cannot do a %s reset in the middle of a merge."
-msgstr ""
+msgstr "Impossibile eseguire un %s reset nel corso di un merge."
#: builtin/reset.c:297
#, c-format
msgid "Could not parse object '%s'."
-msgstr ""
+msgstr "Non è stato possibile analizzare l'oggetto '%s'."
#: builtin/reset.c:302
msgid "--patch is incompatible with --{hard,mixed,soft}"
#: builtin/reset.c:311
msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
-msgstr "--mixed con i percorsi è deprecata; usare invece 'git reset -- <percorso>'."
+msgstr "--mixed con i path è deprecata; usa invece 'git reset -- <path>'."
#: builtin/reset.c:313
#, c-format
msgstr ""
#: builtin/reset.c:325
-#, c-format, fuzzy
+#, c-format
msgid "%s reset is not allowed in a bare repository"
-msgstr "%s reset non è consentito in un archivio scoperto #FIXME: bare"
+msgstr "%s reset non è consentito in un repository spoglio"
#: builtin/reset.c:341
-#, c-format, fuzzy
+#, c-format
msgid "Could not reset index file to revision '%s'."
-msgstr "Non è possibile ripristinare il file indice alla revisione '%s'."
+msgstr ""
+"Non è stato possibile ripristinare index file "
+"alla revisione '%s'."
#: builtin/revert.c:70 builtin/revert.c:92
#, c-format
msgid "%s: %s cannot be used with %s"
-msgstr "%s: %s non può essere usato con %s"
+msgstr "%s: %s non può essere usata con %s"
#: builtin/revert.c:131
msgid "program error"
msgstr "errore del programma"
#: builtin/revert.c:221
-#, fuzzy
msgid "revert failed"
msgstr "revert non riuscito"
#: builtin/revert.c:236
-#, fuzzy
msgid "cherry-pick failed"
msgstr "cherry-pick non riuscito"
"(use --cached to keep the file, or -f to force removal)"
msgstr ""
"'%s' contiene delle modifiche locali\n"
-"(usare --cached per mantenere il file, o -f per forzare la rimozione)"
+"(usa --cached per mantenere il file, o -f per forzare la rimozione)"
#: builtin/rm.c:194
#, c-format
msgstr ""
#: builtin/tag.c:207
-#, c-format, fuzzy
+#, c-format
msgid "tag name too long: %.*s..."
msgstr "nome tag troppo lungo: %.*s..."
#: builtin/tag.c:239
#, c-format
msgid "could not verify the tag '%s'"
-msgstr "non è possibile verificare il tag '%s'"
+msgstr "non è stato possibile verificare il tag '%s'"
#: builtin/tag.c:249
msgid ""
"# Lines starting with '#' will be ignored.\n"
"#\n"
msgstr ""
+"\n"
+"#\n"
+"# Scrivere un messaggio associato al tag\n"
+"# Le righe che iniziano con '#' verranno ignorate.\n"
+"#\n"
#: builtin/tag.c:256
msgid ""
"want to.\n"
"#\n"
msgstr ""
+"\n"
+"#\n"
+"# Scrivere un messaggio associato al tag\n"
+"# Le righe che iniziano con '#' verranno mantenute; possono essere comunque "
+"rimosse manualmente.\n"
+"#\n"
#: builtin/tag.c:298
msgid "unable to sign the tag"
-msgstr "non è possibile firmare il tag"
+msgstr "impossibile firmare il tag"
#: builtin/tag.c:300
msgid "unable to write tag file"
-msgstr ""
+msgstr "impossibile scrivere il file di tag"
#: builtin/tag.c:325
-#, fuzzy
msgid "bad object type."
msgstr "tipo di oggetto errato."
#: builtin/tag.c:338
-#, fuzzy
msgid "tag header too big."
-msgstr "intestazione del tag troppo grande"
+msgstr "intestazione del tag troppo grande."
#: builtin/tag.c:370
-#, fuzzy
msgid "no tag message?"
msgstr "nessun messaggio per il tag?"
#: builtin/tag.c:376
-#, c-format, fuzzy
+#, c-format
msgid "The tag message has been left in %s\n"
-msgstr "Il messaggio tag è stato lasciato in %s\n"
+msgstr "Il messaggio del tag è stato lasciato in %s\n"
#: builtin/tag.c:425
-#, fuzzy
msgid "switch 'points-at' requires an object"
msgstr "lo switch 'points-at' richiede un oggetto"
#: builtin/tag.c:427
#, c-format
msgid "malformed object name '%s'"
-msgstr ""
+msgstr "nome oggetto '%s' malformato"
#: builtin/tag.c:506
msgid "--column and -n are incompatible"
msgstr "troppi parametri"
#: builtin/tag.c:561
-#, c-format, fuzzy
+#, c-format
msgid "'%s' is not a valid tag name."
msgstr "'%s' non è un nome tag valido."
#: builtin/tag.c:584
#, c-format
msgid "%s: cannot lock the ref"
-msgstr ""
+msgstr "%s: impossibile riservare il ref"
#: builtin/tag.c:586
#, c-format
msgid "%s: cannot update the ref"
-msgstr ""
+msgstr "%s: impossibile aggiornare il ref"
#: builtin/tag.c:588
#, c-format
#: git.c:16
msgid "See 'git help <command>' for more information on a specific command."
-msgstr "Consultare 'git help <comando> per maggiori informazioni su un comando specifico."
+msgstr ""
+"Vedi 'git help <comando> per maggiori informazioni su un comando "
+"specifico."
#: parse-options.h:133 parse-options.h:235
msgid "n"
msgstr "n"
#: parse-options.h:141
-#, fuzzy
msgid "time"
msgstr "tempo"
msgstr "meno dettagliato"
#: parse-options.h:236
-#, fuzzy
msgid "use <n> digits to display SHA-1s"
-msgstr "usa <n> cifre per mostrare SHA-1"
+msgstr "usare <n> cifre per mostrare gli hash SHA-1"
#: common-cmds.h:8
-#, fuzzy
msgid "Add file contents to the index"
-msgstr "Aggiunge il contenuto del file all'indice"
+msgstr "Aggiunge il contenuto del file a index"
#: common-cmds.h:9
msgid "Find by binary search the change that introduced a bug"
-msgstr ""
+msgstr "Cerca mediante ricerca binaria la modifica che ha introdotto un bug"
#: common-cmds.h:10
msgid "List, create, or delete branches"
-msgstr "Elenca, crea o elimina rami"
+msgstr "Elenca, crea o elimina branch"
#: common-cmds.h:11
msgid "Checkout a branch or paths to the working tree"
#: common-cmds.h:12
msgid "Clone a repository into a new directory"
-msgstr "Clona un archivio in una nuova cartella"
+msgstr "Clona un repository in una nuova directory"
#: common-cmds.h:13
-#, fuzzy
msgid "Record changes to the repository"
-msgstr "Registra modifiche nell'archivio"
+msgstr "Registra modifiche nel repository"
#: common-cmds.h:14
msgid "Show changes between commits, commit and working tree, etc"
-msgstr "Mostra le modifiche tra i commit, commit e albero di lavoro, ecc"
+msgstr ""
#: common-cmds.h:15
msgid "Download objects and refs from another repository"
-msgstr ""
+msgstr "Scarica oggetti e ref da un altro repository"
#: common-cmds.h:16
msgid "Print lines matching a pattern"
#: common-cmds.h:17
msgid "Create an empty git repository or reinitialize an existing one"
-msgstr "Crea un archivio git vuoto o reinizializza uno esistente"
+msgstr "Crea un repository git vuoto o reinizializza uno esistente"
#: common-cmds.h:18
msgid "Show commit logs"
msgstr "Mostra log del commit"
#: common-cmds.h:19
-#, fuzzy
msgid "Join two or more development histories together"
-msgstr "Unisce due o più cronologie di sviluppo insieme"
+msgstr "Unisce due o più cronologie di sviluppo"
#: common-cmds.h:20
msgid "Move or rename a file, a directory, or a symlink"
-msgstr "Sposta o rinomina un file, una cartella o un link simbolico"
+msgstr "Sposta o rinomina un file, una directory o un link simbolico"
#: common-cmds.h:21
-#, fuzzy
msgid "Fetch from and merge with another repository or a local branch"
-msgstr "Preleva e applica da un altro archivio o un ramo locale"
+msgstr "Combina fetche + merge da un altro repository o un branch locale"
#: common-cmds.h:22
msgid "Update remote refs along with associated objects"
-msgstr ""
+msgstr "Aggiorna i ref remoti insieme agli oggetti associati"
#: common-cmds.h:23
msgid "Forward-port local commits to the updated upstream head"
msgstr ""
#: common-cmds.h:24
-#, fuzzy
msgid "Reset current HEAD to the specified state"
msgstr "Ripristina l'HEAD corrente allo stato specificato"
#: common-cmds.h:25
msgid "Remove files from the working tree and from the index"
-msgstr "Rimuove file dall'albero di lavoro e dall'indice"
+msgstr ""
#: common-cmds.h:26
msgid "Show various types of objects"
#: common-cmds.h:27
msgid "Show the working tree status"
-msgstr "Mostra lo stato dell'albero di lavoro"
+msgstr ""
#: common-cmds.h:28
-#, fuzzy
msgid "Create, list, delete or verify a tag object signed with GPG"
-msgstr "Crea, elenca. elimina o verifica un oggetto tag firmato con GPG"
+msgstr "Crea, elenca, elimina o verifica un oggetto tag firmato con GPG"
#: git-am.sh:50
-#, fuzzy
msgid "You need to set your committer info first"
msgstr "È necessario impostare le informazioni sul committer"
+#: git-am.sh:95
+msgid ""
+"You seem to have moved HEAD since the last 'am' failure.\n"
+"Not rewinding to ORIG_HEAD"
+msgstr ""
+
+#: git-am.sh:105
+#, sh-format
+msgid ""
+"When you have resolved this problem run \"$cmdline --resolved\".\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+"Quando hai risolto il problema esegui \"$cmdline --resolved\".\n"
+"Se vuoi saltare questa patch, esegui invece \"$cmdline --skip\".\n"
+"Per ripristinare il branch originale e interrompere l'applicazione delle "
+"patch esegui \"$cmdline --abort\"."
+
+#: git-am.sh:121
+msgid "Cannot fall back to three-way merge."
+msgstr ""
+
#: git-am.sh:137
msgid "Repository lacks necessary blobs to fall back on 3-way merge."
msgstr ""
"Did you hand edit your patch?\n"
"It does not apply to blobs recorded in its index."
msgstr ""
+"La tua patch è stata modificata manualmente?\n"
+"Non può essere applicata ai blob registrati nel proprio index."
#: git-am.sh:163
msgid "Falling back to patching base and 3-way merge..."
msgstr ""
#: git-am.sh:275
-#, fuzzy
msgid "Only one StGIT patch series can be applied at once"
msgstr "Può essere applicata solo una serie di patch StGIT per volta"
#: git-am.sh:364
msgid "Patch format detection failed."
-msgstr ""
+msgstr "Rilevamento del formato della patch non riuscito."
#: git-am.sh:418
msgid "-d option is no longer supported. Do not use."
msgstr ""
#: git-am.sh:486
-#, fuzzy
msgid "Please make up your mind. --skip or --abort?"
-msgstr "Per favore, decidetevi. --skip o --abort?"
+msgstr "Per favore, deciditi. --skip o --abort?"
#: git-am.sh:513
msgid "Resolve operation not in progress, we are not resuming."
msgid "Dirty index: cannot apply patches (dirty: $files)"
msgstr ""
+#: git-am.sh:671
+#, sh-format
+msgid ""
+"Patch is empty. Was it split wrong?\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+
+#: git-am.sh:708
+msgid "Patch does not have a valid e-mail address."
+msgstr "La patch non contiene un indirizzo email valido."
+
#: git-am.sh:755
-#, fuzzy
msgid "cannot be interactive without stdin connected to a terminal."
msgstr ""
-"non è possibile passare in modalità interattiva senza uno standard input connesso ad\n"
-"un terminale"
+
+#: git-am.sh:759
+msgid "Commit Body is:"
+msgstr ""
#. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
#. in your translation. The program will only accept English
#. input at this point.
#: git-am.sh:766
-#, fuzzy
msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
-msgstr "Applicare? [s]ì/[n]o/[m]odifica/[v]isualizza/mostra [p]atch/[a]ccetta tutto "
+msgstr "Applicare? sì[y]/no[n]/modifica[e]/visualizza patch[v]/accetta tutto[a] "
#: git-am.sh:802
#, sh-format
msgid "Applying: $FIRSTLINE"
msgstr ""
+#: git-am.sh:823
+msgid ""
+"No changes - did you forget to use 'git add'?\n"
+"If there is nothing left to stage, chances are that something else\n"
+"already introduced the same changes; you might want to skip this patch."
+msgstr ""
+
+#: git-am.sh:831
+msgid ""
+"You still have unmerged paths in your index\n"
+"did you forget to use 'git add'?"
+msgstr ""
+
#: git-am.sh:847
msgid "No changes -- Patch already applied."
msgstr "Nessuna modifica -- patch già applicata."
+#: git-am.sh:857
+#, sh-format
+msgid "Patch failed at $msgnum $FIRSTLINE"
+msgstr "Patch non riuscita a $msgnum $FIRSTLINE"
+
#: git-am.sh:873
msgid "applying to an empty history"
msgstr ""
+#: git-bisect.sh:48
+msgid "You need to start by \"git bisect start\""
+msgstr "Devi iniziare con \"git bisect start\""
+
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
#. at this point.
#: git-bisect.sh:54
-#, fuzzy
msgid "Do you want me to do it for you [Y/n]? "
-msgstr "Volete che me ne occupi io [S/n]? "
+msgstr "Vuoi che me ne occupi io [Y/n]? "
#: git-bisect.sh:95
#, sh-format
msgid "unrecognised option: '$arg'"
-msgstr "opzione non riconoscitua: '$arg'"
+msgstr "opzione non riconosciuta: '$arg'"
#: git-bisect.sh:99
#, sh-format
msgid "'$arg' does not appear to be a valid revision"
-msgstr ""
+msgstr "'$arg' non sembra essere una revisione valida"
#: git-bisect.sh:117
-#, fuzzy
msgid "Bad HEAD - I need a HEAD"
-msgstr "HEAD errata - ho bisogno di una HEAD"
+msgstr ""
#: git-bisect.sh:130
#, sh-format
msgid ""
"Checking out '$start_head' failed. Try 'git bisect reset <validbranch>'."
msgstr ""
+"Checkout di '$start_head' non riuscito. Prova 'git bisect reset "
+"<branch-valido>'."
#: git-bisect.sh:140
msgid "won't bisect on seeked tree"
#: git-bisect.sh:144
msgid "Bad HEAD - strange symbolic ref"
-msgstr ""
+msgstr "HEAD errato - strano ref simbolico"
#: git-bisect.sh:189
#, sh-format
msgid "Bad bisect_write argument: $state"
-msgstr ""
+msgstr "Argomento bisect_write errato: $state"
#: git-bisect.sh:218
#, sh-format
#: git-bisect.sh:232
msgid "Please call 'bisect_state' with at least one argument."
-msgstr "Per favore, chiamare 'bisect_state' con almeno un argomento."
+msgstr "Per favore, chiama 'bisect_state' con almeno un argomento."
#: git-bisect.sh:244
#, sh-format
msgid "'git bisect bad' can take only one argument."
msgstr "'git bisect bad' può prendere un solo argomento."
+#. have bad but not good. we could bisect although
+#. this is less optimum.
+#: git-bisect.sh:273
+msgid "Warning: bisecting only with a bad commit."
+msgstr ""
+
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
#. at this point.
#: git-bisect.sh:279
msgid "Are you sure [Y/n]? "
-msgstr "Si è sicuri? [S/n] "
+msgstr "Sei sicuro? [Y/n] "
+
+#: git-bisect.sh:289
+msgid ""
+"You need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+"Devi specificare almeno una revisione corretta ed una errata.\n"
+"(Puoi usare \"git bisect bad\" e \"git bisect good\" per questo scopo.)"
+
+#: git-bisect.sh:292
+msgid ""
+"You need to start by \"git bisect start\".\n"
+"You then need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+
+#: git-bisect.sh:347 git-bisect.sh:474
+msgid "We are not bisecting."
+msgstr "Non stiamo eseguendo un bisect."
#: git-bisect.sh:354
#, sh-format
#: git-bisect.sh:408
msgid "?? what are you talking about?"
+msgstr "?? di cosa si sta parlando?"
+
+#: git-bisect.sh:420
+#, sh-format
+msgid "running $command"
+msgstr "sto eseguendo $command"
+
+#: git-bisect.sh:427
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"exit code $res from '$command' is < 0 or >= 128"
msgstr ""
+"bisect run non riuscito:\n"
+"il codice di uscita $res da '$command' è < 0 oppure >= 128"
-#: git-bisect.sh:474
-#, fuzzy
-msgid "We are not bisecting."
-msgstr "Non stiamo eseguendo il bisect."
+#: git-bisect.sh:453
+msgid "bisect run cannot continue any more"
+msgstr "bisect run non può più proseguire"
+
+#: git-bisect.sh:459
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"'bisect_state $state' exited with error code $res"
+msgstr ""
+"bisect run non riuscito:\n"
+"bisect_state $state è uscito con il codice di errore $res"
+
+#: git-bisect.sh:466
+msgid "bisect run success"
+msgstr "bisect run eseguito con successo"
#: git-pull.sh:21
msgid ""
#: git-pull.sh:25
msgid "Pull is not possible because you have unmerged files."
msgstr ""
+"Il pull non è possibile perché ci sono file di cui non è stato eseguito il "
+"merge."
#: git-pull.sh:197
msgid "updating an unborn branch with changes added to the index"
msgstr ""
+#. The fetch involved updating the current branch.
+#. The working tree and the index file is still based on the
+#. $orig_head commit, but we are merging into $curr_head.
+#. First update the working tree to match $curr_head.
+#: git-pull.sh:228
+#, sh-format
+msgid ""
+"Warning: fetch updated the current branch head.\n"
+"Warning: fast-forwarding your working tree from\n"
+"Warning: commit $orig_head."
+msgstr ""
+
#: git-pull.sh:253
msgid "Cannot merge multiple branches into empty head"
-msgstr ""
+msgstr "Impossibile eseguire il merge di branch multipli in un head vuoto"
#: git-pull.sh:257
msgid "Cannot rebase onto multiple branches"
-msgstr "Non è possibile eseguire il rebase su rami multipli"
+msgstr "Impossibile eseguire il rebase su branch multipli"
#: git-stash.sh:51
-#, fuzzy
msgid "git stash clear with parameters is unimplemented"
msgstr "git stash clear con parametri non è implementato"
#: git-stash.sh:74
msgid "You do not have the initial commit yet"
-msgstr "Non esiste ancora un commit iniziale"
+msgstr "Non hai ancora un commit iniziale"
#: git-stash.sh:89
-#, fuzzy
msgid "Cannot save the current index state"
-msgstr "Non è possibile salvare lo stato corrente dell'indice"
+msgstr "Impossibile salvare lo stato corrente di index"
#: git-stash.sh:123 git-stash.sh:136
-#, fuzzy
msgid "Cannot save the current worktree state"
-msgstr "Non è possibile salvare lo stato dell'albero di lavoro corrente"
+msgstr ""
#: git-stash.sh:140
msgid "No changes selected"
msgstr ""
#: git-stash.sh:156
-#, fuzzy
msgid "Cannot record working tree state"
-msgstr "Non è possbile registrare lo stato dell'albero di lavoro"
+msgstr ""
+
+#. TRANSLATORS: $option is an invalid option, like
+#. `--blah-blah'. The 7 spaces at the beginning of the
+#. second line correspond to "error: ". So you should line
+#. up the second line with however many characters the
+#. translation of "error: " takes in your language. E.g. in
+#. English this is:
+#.
+#. $ git stash save --blah-blah 2>&1 | head -n 2
+#. error: unknown option for 'stash save': --blah-blah
+#. To provide a message, use git stash save -- '--blah-blah'
+#: git-stash.sh:202
+#, sh-format
+msgid ""
+"error: unknown option for 'stash save': $option\n"
+" To provide a message, use git stash save -- '$option'"
+msgstr ""
+"errore: opzione sconosciuta per 'stash save': $option\n"
+" Per aggiungere un messaggio, usare git stash save -- '$option'"
#: git-stash.sh:223
msgid "No local changes to save"
#: git-stash.sh:227
msgid "Cannot initialize stash"
-msgstr "Non è possibile inizializzare stash"
+msgstr "Impossibile inizializzare stash"
#: git-stash.sh:235
-#, fuzzy
msgid "Cannot save the current status"
-msgstr "Non è possibile salvare lo stato attuale"
+msgstr "Impossibile salvare lo stato attuale"
#: git-stash.sh:253
-#, fuzzy
msgid "Cannot remove worktree changes"
-msgstr "Non è possibile rimuovere le modifiche all'albero di lavoro"
+msgstr ""
#: git-stash.sh:352
msgid "No stash found."
msgstr "Nessuno stash trovato."
#: git-stash.sh:359
-#, sh-format, fuzzy
+#, sh-format
msgid "Too many revisions specified: $REV"
msgstr "Troppe revisioni specificate: $REV"
msgstr "'$args' non è un commit di tipo stash"
#: git-stash.sh:404
-#, sh-format, fuzzy
+#, sh-format
msgid "'$args' is not a stash reference"
-msgstr "'$args' non è un riferimento a stash"
+msgstr "'$args' non è un referimento a uno stash"
#: git-stash.sh:412
msgid "unable to refresh index"
-msgstr "non è stato possibile aggiornare l'indice"
+msgstr "impossibile aggiornare index"
#: git-stash.sh:416
msgid "Cannot apply a stash in the middle of a merge"
-msgstr "Non è possibile applicare uno stash nel mezzo di un merge"
+msgstr "Impossibile applicare uno stash nel mezzo di un merge"
#: git-stash.sh:424
-#, fuzzy
msgid "Conflicts in index. Try without --index."
-msgstr "Ci sono conflitti nell'indice. Provare senza --index."
+msgstr "Ci sono conflitti in index. Prova senza --index."
#: git-stash.sh:426
msgid "Could not save index tree"
-msgstr "Non è stato possibile salvare l'indice dell'albero"
+msgstr ""
#: git-stash.sh:460
msgid "Cannot unstage modified files"
msgstr ""
+#: git-stash.sh:474
+msgid "Index was not unstashed."
+msgstr ""
+
#: git-stash.sh:491
#, sh-format
msgid "Dropped ${REV} ($s)"
-msgstr ""
+msgstr "${REV} eliminata ($s)"
#: git-stash.sh:492
#, sh-format
msgid "${REV}: Could not drop stash entry"
-msgstr ""
+msgstr "${REV}: non è stato possibile rimuovere la voce di stash"
#: git-stash.sh:499
-#, fuzzy
msgid "No branch name specified"
-msgstr "Nessun nome del ramo specificato"
+msgstr "Nome del branch non specificato"
#: git-stash.sh:570
msgid "(To restore them type \"git stash apply\")"
-msgstr "(Per ripristinarli digitare \"git stash apply\")"
+msgstr "(Per ripristinarli digita \"git stash apply\")"
#: git-submodule.sh:56
#, sh-format
#: git-submodule.sh:249
#, sh-format
msgid "repo URL: '$repo' must be absolute or begin with ./|../"
-msgstr ""
+msgstr "repo URL: '$repo' deve essere assoluto o iniziare con ./|../"
#: git-submodule.sh:266
#, sh-format
msgid "'$sm_path' already exists in the index"
+msgstr "'$sm_path' esiste già in index"
+
+#: git-submodule.sh:270
+#, sh-format
+msgid ""
+"The following path is ignored by one of your .gitignore files:\n"
+"$sm_path\n"
+"Use -f if you really want to add it."
+msgstr ""
+"Il seguente path è ignorato da uno dei tuoi file .gitignore:\n"
+"$sm_path\n"
+"Usa -f se vuoi davvero aggiungerlo."
+
+#: git-submodule.sh:281
+#, sh-format
+msgid "Adding existing repo at '$sm_path' to the index"
msgstr ""
#: git-submodule.sh:283
#, sh-format
msgid "'$sm_path' already exists and is not a valid git repo"
-msgstr ""
+msgstr "'$sm_path' esiste già e non è un repository git valido"
#: git-submodule.sh:297
#, sh-format
#, sh-format
msgid "Stopping at '$sm_path'; script returned non-zero status."
msgstr ""
+"Interruzione a '$sm_path'; lo script ha restituito uno stato diverso da zero."
-#: git-submodule.sh:405
+#: git-submodule.sh:406
#, sh-format
msgid "No url found for submodule path '$sm_path' in .gitmodules"
msgstr ""
-#: git-submodule.sh:414
+#: git-submodule.sh:415
#, sh-format
msgid "Failed to register url for submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:422
+#: git-submodule.sh:417
#, sh-format
-msgid "Failed to register update mode for submodule path '$sm_path'"
+msgid "Submodule '$name' ($url) registered for path '$sm_path'"
msgstr ""
-#: git-submodule.sh:424
+#: git-submodule.sh:425
#, sh-format
-msgid "Submodule '$name' ($url) registered for path '$sm_path'"
+msgid "Failed to register update mode for submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:523
+#: git-submodule.sh:524
#, sh-format
msgid ""
"Submodule path '$sm_path' not initialized\n"
"Maybe you want to use 'update --init'?"
msgstr ""
-#: git-submodule.sh:536
+#: git-submodule.sh:537
#, sh-format
msgid "Unable to find current revision in submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:555
+#: git-submodule.sh:556
#, sh-format
msgid "Unable to fetch in submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:569
+#: git-submodule.sh:570
#, sh-format
msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:570
+#: git-submodule.sh:571
#, sh-format
msgid "Submodule path '$sm_path': rebased into '$sha1'"
msgstr ""
-#: git-submodule.sh:575
+#: git-submodule.sh:576
#, sh-format
msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:576
+#: git-submodule.sh:577
#, sh-format
msgid "Submodule path '$sm_path': merged in '$sha1'"
msgstr ""
-#: git-submodule.sh:581
+#: git-submodule.sh:582
#, sh-format
msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:582
+#: git-submodule.sh:583
#, sh-format
msgid "Submodule path '$sm_path': checked out '$sha1'"
msgstr ""
-#: git-submodule.sh:604 git-submodule.sh:927
+#: git-submodule.sh:605 git-submodule.sh:928
#, sh-format
msgid "Failed to recurse into submodule path '$sm_path'"
msgstr ""
-#: git-submodule.sh:712
-msgid "--"
-msgstr "--"
+#: git-submodule.sh:713
+msgid "--cached cannot be used with --files"
+msgstr "--cached non può essere usata con --files"
+
+#. unexpected type
+#: git-submodule.sh:753
+#, sh-format
+msgid "unexpected mode $mod_dst"
+msgstr "modalità $mod_dst inattesa"
-#: git-submodule.sh:770
+#: git-submodule.sh:771
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_src"
msgstr " Attenzione: $name non contiene commit $sha1_src"
-#: git-submodule.sh:773
+#: git-submodule.sh:774
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_dst"
msgstr " Attenzione: $name non contiene commit $sha1_dst"
-#: git-submodule.sh:776
+#: git-submodule.sh:777
#, sh-format
msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
msgstr " Attenzione: $name non contiene commit $sha1_src e $sha1_dst"
-#: git-submodule.sh:801
+#: git-submodule.sh:802
msgid "blob"
-msgstr ""
+msgstr "blob"
-#: git-submodule.sh:802
+#: git-submodule.sh:803
msgid "submodule"
+msgstr "sottomodulo"
+
+#: git-submodule.sh:840
+msgid "# Submodules changed but not updated:"
+msgstr ""
+
+#: git-submodule.sh:842
+msgid "# Submodule changes to be committed:"
msgstr ""
-#: git-submodule.sh:973
+#: git-submodule.sh:974
#, sh-format
msgid "Synchronizing submodule url for '$name'"
msgstr ""
+
+#~ msgid "--"
+#~ msgstr "--"
+
+#~ msgid "Could not extract email from committer identity."
+#~ msgstr ""
+#~ "Non è stato possibile estrarre l'indirizzo email dall'identità del "
+#~ "committer."
msgstr ""
"Project-Id-Version: git 1.7.10\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-05-15 06:31+0800\n"
-"PO-Revision-Date: 2012-05-28 22:35+0100\n"
+"POT-Creation-Date: 2012-07-03 10:23+0800\n"
+"PO-Revision-Date: 2012-07-04 19:33+0100\n"
"Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
"lämpligt för att ange lösning och checka in,\n"
"eller använd \"git commit -a\"."
-#: commit.c:47
+#: bundle.c:36
+#, c-format
+msgid "'%s' does not look like a v2 bundle file"
+msgstr "'%s' ser inte ut som en v2-bundle-fil"
+
+#: bundle.c:63
+#, c-format
+msgid "unrecognized header: %s%s (%d)"
+msgstr "okänt huvud: %s%s (%d)"
+
+#: bundle.c:89 builtin/commit.c:696
+#, c-format
+msgid "could not open '%s'"
+msgstr "kunde inte öppna \"%s\""
+
+#: bundle.c:140
+msgid "Repository lacks these prerequisite commits:"
+msgstr "Arkivet saknar dessa nödvändiga incheckningar:"
+
+#: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
+#: builtin/log.c:721 builtin/log.c:1310 builtin/log.c:1529 builtin/merge.c:347
+#: builtin/shortlog.c:181
+msgid "revision walk setup failed"
+msgstr "misslyckades skapa revisionstraversering"
+
+#: bundle.c:186
+#, c-format
+msgid "The bundle contains %d ref"
+msgid_plural "The bundle contains %d refs"
+msgstr[0] "Paketet (bundlen) innehåller %d referens"
+msgstr[1] "Paketet (bundlen) innehåller %d referenser"
+
+#: bundle.c:192
+msgid "The bundle records a complete history."
+msgstr "Paketet (bundlen) beskriver en komplett historik."
+
+#: bundle.c:195
+#, c-format
+msgid "The bundle requires this ref"
+msgid_plural "The bundle requires these %d refs"
+msgstr[0] "Paketet (bundlen) kräver denna referens"
+msgstr[1] "Paketet (bundlen) kräver dessa %d referenser"
+
+#: bundle.c:294
+msgid "rev-list died"
+msgstr "rev-list dog"
+
+#: bundle.c:300 builtin/log.c:1206 builtin/shortlog.c:284
+#, c-format
+msgid "unrecognized argument: %s"
+msgstr "okänt argument: %s"
+
+#: bundle.c:335
+#, c-format
+msgid "ref '%s' is excluded by the rev-list options"
+msgstr "referensen \"%s\" exkluderas av argumenten till rev-list"
+
+#: bundle.c:380
+msgid "Refusing to create empty bundle."
+msgstr "Vägrar skapa ett tomt paket (bundle)."
+
+#: bundle.c:398
+msgid "Could not spawn pack-objects"
+msgstr "Kunde inte starta pack-objects"
+
+#: bundle.c:416
+msgid "pack-objects died"
+msgstr "pack-objects misslyckades"
+
+#: bundle.c:419
+#, c-format
+msgid "cannot create '%s'"
+msgstr "kan inte skapa \"%s\""
+
+#: bundle.c:441
+msgid "index-pack died"
+msgstr "index-pack dog"
+
+#: commit.c:48
#, c-format
msgid "could not parse %s"
msgstr "kunde inte tolka %s"
-#: commit.c:49
+#: commit.c:50
#, c-format
msgid "%s %s is not a commit!"
msgstr "%s %s är inte en incheckning!"
msgid "failed to close rev-list's stdin: %s"
msgstr "kunde inte stänga rev-list:s standard in: %s"
+#: date.c:95
+msgid "in the future"
+msgstr "i framtiden"
+
+#: date.c:101
+#, c-format
+msgid "%lu second ago"
+msgid_plural "%lu seconds ago"
+msgstr[0] "%lu sekund sedan"
+msgstr[1] "%lu sekunder sedan"
+
+#: date.c:108
+#, c-format
+msgid "%lu minute ago"
+msgid_plural "%lu minutes ago"
+msgstr[0] "%lu minut sedan"
+msgstr[1] "%lu minuter sedan"
+
+#: date.c:115
+#, c-format
+msgid "%lu hour ago"
+msgid_plural "%lu hours ago"
+msgstr[0] "%lu timme sedan"
+msgstr[1] "%lu timmar sedan"
+
+#: date.c:122
+#, c-format
+msgid "%lu day ago"
+msgid_plural "%lu days ago"
+msgstr[0] "%lu dag sedan"
+msgstr[1] "%lu dagar sedan"
+
+#: date.c:128
+#, c-format
+msgid "%lu week ago"
+msgid_plural "%lu weeks ago"
+msgstr[0] "%lu vecka sedan"
+msgstr[1] "%lu veckor sedan"
+
+#: date.c:135
+#, c-format
+msgid "%lu month ago"
+msgid_plural "%lu months ago"
+msgstr[0] "%lu månad sedan"
+msgstr[1] "%lu månader sedan"
+
+#: date.c:146
+#, c-format
+msgid "%lu year"
+msgid_plural "%lu years"
+msgstr[0] "%lu år"
+msgstr[1] "%lu år"
+
+#: date.c:149
+#, c-format
+msgid "%s, %lu month ago"
+msgid_plural "%s, %lu months ago"
+msgstr[0] "%s, %lu månad sedan"
+msgstr[1] "%s, %lu månader sedan"
+
+#: date.c:154 date.c:159
+#, c-format
+msgid "%lu year ago"
+msgid_plural "%lu years ago"
+msgstr[0] "%lu år sedan"
+msgstr[1] "%lu år sedan"
+
#: diff.c:105
#, c-format
msgid " Failed to parse dirstat cut-off percentage '%.*s'\n"
msgstr[0] ", %d borttagning(-)"
msgstr[1] ", %d borttagningar(-)"
-#: diff.c:3439
+#: diff.c:3478
#, c-format
msgid ""
"Failed to parse --dirstat/-X option parameter:\n"
msgid "gpg failed to sign the data"
msgstr "gpg misslyckades signera data"
-#: grep.c:1280
+#: grep.c:1320
#, c-format
msgid "'%s': unable to read %s"
msgstr "\"%s\" kunde inte läsa %s"
-#: grep.c:1297
+#: grep.c:1337
#, c-format
msgid "'%s': %s"
msgstr "\"%s\": %s"
-#: grep.c:1308
+#: grep.c:1348
#, c-format
msgid "'%s': short read %s"
msgstr "\"%s\": kort läsning %s"
-#: help.c:287
+#: help.c:208
+#, c-format
+msgid "available git commands in '%s'"
+msgstr "git-kommandon tillgängliga i \"%s\""
+
+#: help.c:215
+msgid "git commands available from elsewhere on your $PATH"
+msgstr "git-kommandon från andra platser i din $PATH"
+
+#: help.c:271
#, c-format
msgid ""
"'%s' appears to be a git command, but we were not\n"
"\"%s\" verkar vara ett git-kommando, men vi kan inte\n"
"köra det. Kanske git-%s är trasigt?"
-#: remote.c:1607
+#: help.c:328
+msgid "Uh oh. Your system reports no Git commands at all."
+msgstr "Oj då. Ditt system rapporterar inga Git-kommandon alls."
+
+#: help.c:350
+#, c-format
+msgid ""
+"WARNING: You called a Git command named '%s', which does not exist.\n"
+"Continuing under the assumption that you meant '%s'"
+msgstr ""
+"VARNING: Du anropade ett Git-kommando vid namn \"%s\", som inte finns.\n"
+"Fortsätter under förutsättningen att du menade \"%s\""
+
+#: help.c:355
+#, c-format
+msgid "in %0.1f seconds automatically..."
+msgstr "automatiskt om %0.1f sekunder..."
+
+#: help.c:362
+#, c-format
+msgid "git: '%s' is not a git command. See 'git --help'."
+msgstr "git: \"%s\" är inte ett git-kommando. Se \"git --help\"."
+
+#: help.c:366
+msgid ""
+"\n"
+"Did you mean this?"
+msgid_plural ""
+"\n"
+"Did you mean one of these?"
+msgstr[0] ""
+"\n"
+"Menade du detta?"
+msgstr[1] ""
+"\n"
+"Menade du ett av dessa?"
+
+#: parse-options.c:493
+msgid "..."
+msgstr "..."
+
+#: parse-options.c:511
+#, c-format
+msgid "usage: %s"
+msgstr "användning: %s"
+
+#. TRANSLATORS: the colon here should align with the
+#. one in "usage: %s" translation
+#: parse-options.c:515
+#, c-format
+msgid " or: %s"
+msgstr " eller: %s"
+
+#: parse-options.c:518
+#, c-format
+msgid " %s"
+msgstr " %s"
+
+#: remote.c:1629
#, c-format
msgid "Your branch is ahead of '%s' by %d commit.\n"
msgid_plural "Your branch is ahead of '%s' by %d commits.\n"
msgstr[0] "Din gren ligger före \"%s\" med %d incheckning.\n"
msgstr[1] "Din gren ligger före \"%s\" med %d incheckningar.\n"
-#: remote.c:1613
+#: remote.c:1635
#, c-format
msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
msgid_plural ""
msgstr[1] ""
"Din gren ligger efter \"%s\" med %d incheckningar, och kan snabbspolas.\n"
-#: remote.c:1621
+#: remote.c:1643
#, c-format
msgid ""
"Your branch and '%s' have diverged,\n"
"Din gren och \"%s\" har divergerat,\n"
"och har %d respektive %d olika incheckningar.\n"
-#: sequencer.c:120 builtin/merge.c:865 builtin/merge.c:978
+#: sequencer.c:121 builtin/merge.c:865 builtin/merge.c:978
#: builtin/merge.c:1088 builtin/merge.c:1098
#, c-format
msgid "Could not open '%s' for writing"
msgstr "Kunde inte öppna \"%s\" för skrivning"
-#: sequencer.c:122 builtin/merge.c:333 builtin/merge.c:868
+#: sequencer.c:123 builtin/merge.c:333 builtin/merge.c:868
#: builtin/merge.c:1090 builtin/merge.c:1103
#, c-format
msgid "Could not write to '%s'"
msgstr "Kunde inte skriva till \"%s\""
-#: sequencer.c:143
+#: sequencer.c:144
msgid ""
"after resolving the conflicts, mark the corrected paths\n"
"with 'git add <paths>' or 'git rm <paths>'"
"efter att ha löst konflikterna, markera de rättade sökvägarna\n"
"med \"git add <sökvägar>\" eller \"git rm <sökvägar>\""
-#: sequencer.c:146
+#: sequencer.c:147
msgid ""
"after resolving the conflicts, mark the corrected paths\n"
"with 'git add <paths>' or 'git rm <paths>'\n"
"med \"git add <sökvägar>\" eller \"git rm <sökvägar>\"\n"
"och checka in resultatet med \"git commit\""
-#: sequencer.c:159 sequencer.c:685 sequencer.c:768
+#: sequencer.c:160 sequencer.c:758 sequencer.c:841
#, c-format
msgid "Could not write to %s"
msgstr "Kunde inte skriva till %s"
-#: sequencer.c:162
+#: sequencer.c:163
#, c-format
msgid "Error wrapping up %s"
msgstr "Fel vid ombrytning av %s"
-#: sequencer.c:177
+#: sequencer.c:178
msgid "Your local changes would be overwritten by cherry-pick."
msgstr "Dina lokala ändringar skulle skrivas över av \"cherry-pick\"."
-#: sequencer.c:179
+#: sequencer.c:180
msgid "Your local changes would be overwritten by revert."
msgstr "Dina lokala ändringar skulle skrivas över av \"revert\"."
-#: sequencer.c:182
+#: sequencer.c:183
msgid "Commit your changes or stash them to proceed."
msgstr "Checka in dina ändringar eller använd \"stash\" för att fortsätta."
#. TRANSLATORS: %s will be "revert" or "cherry-pick"
-#: sequencer.c:232
+#: sequencer.c:233
#, c-format
msgid "%s: Unable to write new index file"
msgstr "%s: Kunde inte skriva ny indexfil"
-#: sequencer.c:298
+#: sequencer.c:261
+msgid "Could not resolve HEAD commit\n"
+msgstr "Kunde inte bestämma HEAD:s incheckning\n"
+
+#: sequencer.c:282
+msgid "Unable to update cache tree\n"
+msgstr "Kan inte uppdatera cacheträd\n"
+
+#: sequencer.c:324
+#, c-format
+msgid "Could not parse commit %s\n"
+msgstr "Kunde inte tolka incheckningen %s\n"
+
+#: sequencer.c:329
+#, c-format
+msgid "Could not parse parent commit %s\n"
+msgstr "Kunde inte tolka föräldraincheckningen %s\n"
+
+#: sequencer.c:395
msgid "Your index file is unmerged."
msgstr "Din indexfil har inte slagits ihop."
-#: sequencer.c:301
+#: sequencer.c:398
msgid "You do not have a valid HEAD"
msgstr "Du har ingen giltig HEAD"
-#: sequencer.c:316
+#: sequencer.c:413
#, c-format
msgid "Commit %s is a merge but no -m option was given."
msgstr "Incheckning %s är en sammanslagning, men flaggan -m angavs inte."
-#: sequencer.c:324
+#: sequencer.c:421
#, c-format
msgid "Commit %s does not have parent %d"
msgstr "Incheckning %s har inte förälder %d"
-#: sequencer.c:328
+#: sequencer.c:425
#, c-format
msgid "Mainline was specified but commit %s is not a merge."
msgstr "Huvudlinje angavs, men incheckningen %s är inte en sammanslagning"
#. TRANSLATORS: The first %s will be "revert" or
#. "cherry-pick", the second %s a SHA1
-#: sequencer.c:339
+#: sequencer.c:436
#, c-format
msgid "%s: cannot parse parent commit %s"
msgstr "%s: kan inte tolka föräldraincheckningen %s"
-#: sequencer.c:343
+#: sequencer.c:440
#, c-format
msgid "Cannot get commit message for %s"
msgstr "Kan inte hämta incheckningsmeddelande för %s"
-#: sequencer.c:427
+#: sequencer.c:524
#, c-format
msgid "could not revert %s... %s"
msgstr "kunde inte ångra %s... %s"
-#: sequencer.c:428
+#: sequencer.c:525
#, c-format
msgid "could not apply %s... %s"
-msgstr "kunde inte applicera %s... %s"
-
-#: sequencer.c:450 sequencer.c:909 builtin/log.c:288 builtin/log.c:713
-#: builtin/log.c:1329 builtin/log.c:1548 builtin/merge.c:347
-#: builtin/shortlog.c:181
-msgid "revision walk setup failed"
-msgstr "misslyckades skapa revisionstraversering"
+msgstr "kunde inte tillämpa %s... %s"
-#: sequencer.c:453
+#: sequencer.c:553
msgid "empty commit set passed"
msgstr "den angivna uppsättningen incheckningar är tom"
-#: sequencer.c:461
+#: sequencer.c:561
#, c-format
msgid "git %s: failed to read the index"
msgstr "git %s: misslyckades läsa indexet"
-#: sequencer.c:466
+#: sequencer.c:566
#, c-format
msgid "git %s: failed to refresh the index"
msgstr "git %s: misslyckades uppdatera indexet"
-#: sequencer.c:551
+#: sequencer.c:624
#, c-format
msgid "Cannot %s during a %s"
msgstr "kan inte %s under en %s"
-#: sequencer.c:573
+#: sequencer.c:646
#, c-format
msgid "Could not parse line %d."
msgstr "Kan inte tolka rad %d."
-#: sequencer.c:578
+#: sequencer.c:651
msgid "No commits parsed."
msgstr "Inga incheckningar lästes."
-#: sequencer.c:591
+#: sequencer.c:664
#, c-format
msgid "Could not open %s"
msgstr "Kunde inte öppna %s"
-#: sequencer.c:595
+#: sequencer.c:668
#, c-format
msgid "Could not read %s."
msgstr "kunde inte läsa %s."
-#: sequencer.c:602
+#: sequencer.c:675
#, c-format
msgid "Unusable instruction sheet: %s"
msgstr "Oanvändbart manus: %s"
-#: sequencer.c:630
+#: sequencer.c:703
#, c-format
msgid "Invalid key: %s"
msgstr "Felaktig nyckel: %s"
-#: sequencer.c:633
+#: sequencer.c:706
#, c-format
msgid "Invalid value for %s: %s"
msgstr "Felaktigt värde för %s: %s"
-#: sequencer.c:645
+#: sequencer.c:718
#, c-format
msgid "Malformed options sheet: %s"
msgstr "Trasigt manus: %s"
-#: sequencer.c:666
+#: sequencer.c:739
msgid "a cherry-pick or revert is already in progress"
msgstr "en \"cherry-pick\" eller \"revert\" pågår redan"
-#: sequencer.c:667
+#: sequencer.c:740
msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
msgstr "testa \"git cherry-pick (--continue | --quit | --abort)\""
-#: sequencer.c:671
+#: sequencer.c:744
#, c-format
msgid "Could not create sequencer directory %s"
msgstr "Kunde inte skapa \"sequencer\"-katalogen \"%s\""
-#: sequencer.c:687 sequencer.c:772
+#: sequencer.c:760 sequencer.c:845
#, c-format
msgid "Error wrapping up %s."
msgstr "Fel vid ombrytning av %s."
-#: sequencer.c:706 sequencer.c:840
+#: sequencer.c:779 sequencer.c:913
msgid "no cherry-pick or revert in progress"
msgstr "ingen \"cherry-pick\" eller \"revert\" pågår"
-#: sequencer.c:708
+#: sequencer.c:781
msgid "cannot resolve HEAD"
msgstr "kan inte bestämma HEAD"
-#: sequencer.c:710
+#: sequencer.c:783
msgid "cannot abort from a branch yet to be born"
msgstr "kan inte avbryta från en gren som ännu inte är född"
-#: sequencer.c:732
+#: sequencer.c:805 builtin/apply.c:3697
#, c-format
msgid "cannot open %s: %s"
msgstr "kan inte öppna %s: %s"
-#: sequencer.c:735
+#: sequencer.c:808
#, c-format
msgid "cannot read %s: %s"
msgstr "kan inte läsa %s: %s"
-#: sequencer.c:736
+#: sequencer.c:809
msgid "unexpected end of file"
msgstr "oväntat filslut"
-#: sequencer.c:742
+#: sequencer.c:815
#, c-format
msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
msgstr "sparad HEAD-fil från före \"cherry-pick\", \"%s\", är trasig"
-#: sequencer.c:765
+#: sequencer.c:838
#, c-format
msgid "Could not format %s."
msgstr "Kunde inte formatera %s."
-#: sequencer.c:927
+#: sequencer.c:1000
msgid "Can't revert as initial commit"
msgstr "Kan inte ångra som första incheckning"
-#: sequencer.c:928
+#: sequencer.c:1001
msgid "Can't cherry-pick into empty head"
msgstr "Kan inte göra \"cherry-pick\" i ett tomt huvud"
-#: wt-status.c:134
+#: sha1_name.c:864
+msgid "HEAD does not point to a branch"
+msgstr "HEAD pekar inte på en gren"
+
+#: sha1_name.c:867
+#, c-format
+msgid "No such branch: '%s'"
+msgstr "Okänd gren: \"%s\""
+
+#: sha1_name.c:869
+#, c-format
+msgid "No upstream configured for branch '%s'"
+msgstr "Ingen standarduppström angiven för grenen \"%s\""
+
+#: sha1_name.c:872
+#, c-format
+msgid "Upstream branch '%s' not stored as a remote-tracking branch"
+msgstr "Uppströmsgrenen \"%s\" är inte lagrad som en fjärrspårande gren"
+
+#: wrapper.c:413
+#, c-format
+msgid "unable to look up current user in the passwd file: %s"
+msgstr "kan inte slå upp aktuell användare i passwd-filen: %s"
+
+#: wrapper.c:414
+msgid "no such user"
+msgstr "okänd användare"
+
+#: wt-status.c:141
msgid "Unmerged paths:"
msgstr "Ej sammanslagna sökvägar:"
-#: wt-status.c:140 wt-status.c:157
+#: wt-status.c:168 wt-status.c:195
#, c-format
msgid " (use \"git reset %s <file>...\" to unstage)"
msgstr " (använd \"git reset %s <fil>...\" för att ta bort från kö)"
-#: wt-status.c:142 wt-status.c:159
+#: wt-status.c:170 wt-status.c:197
msgid " (use \"git rm --cached <file>...\" to unstage)"
msgstr " (använd \"git rm --cached <fil>...\" för att ta bort från kö)"
-#: wt-status.c:143
+#: wt-status.c:174
+msgid " (use \"git add <file>...\" to mark resolution)"
+msgstr " (använd \"git add <fil>...\" för att ange lösning)"
+
+#: wt-status.c:176 wt-status.c:180
msgid " (use \"git add/rm <file>...\" as appropriate to mark resolution)"
msgstr " (använd \"git add/rm <fil>...\" som lämpligt för att ange lösning)"
-#: wt-status.c:151
+#: wt-status.c:178
+msgid " (use \"git rm <file>...\" to mark resolution)"
+msgstr " (använd \"git rm <fil>...\" för att ange lösning)"
+
+#: wt-status.c:189
msgid "Changes to be committed:"
msgstr "Ändringar att checka in:"
-#: wt-status.c:169
+#: wt-status.c:207
msgid "Changes not staged for commit:"
msgstr "Ändringar ej i incheckningskön:"
-#: wt-status.c:173
+#: wt-status.c:211
msgid " (use \"git add <file>...\" to update what will be committed)"
msgstr ""
" (använd \"git add <fil>...\" för att uppdatera vad som skall checkas in)"
-#: wt-status.c:175
+#: wt-status.c:213
msgid " (use \"git add/rm <file>...\" to update what will be committed)"
msgstr ""
" (använd \"git add/rm <fil>...\" för att uppdatera vad som skall checkas in)"
-#: wt-status.c:176
+#: wt-status.c:214
msgid ""
" (use \"git checkout -- <file>...\" to discard changes in working directory)"
msgstr ""
" (använd \"git checkout -- <fil>...\" för att förkasta ändringar i "
"arbetskatalogen)"
-#: wt-status.c:178
+#: wt-status.c:216
msgid " (commit or discard the untracked or modified content in submodules)"
msgstr ""
" (checka in eller förkasta ospårat eller ändrat innehåll i undermoduler)"
# %s är ett verb ("Untracked"/"Ignored"); lägg till ett -e.
-#: wt-status.c:187
+#: wt-status.c:225
#, c-format
msgid "%s files:"
msgstr "%se filer:"
-#: wt-status.c:190
+#: wt-status.c:228
#, c-format
msgid " (use \"git %s <file>...\" to include in what will be committed)"
msgstr ""
" (använd \"git %s <fil>...\" för att ta med i vad som skall checkas in)"
-#: wt-status.c:207
+#: wt-status.c:245
msgid "bug"
msgstr "programfel"
-#: wt-status.c:212
+#: wt-status.c:250
msgid "both deleted:"
msgstr "borttaget av bägge:"
-#: wt-status.c:213
+#: wt-status.c:251
msgid "added by us:"
msgstr "tillagt av oss:"
-#: wt-status.c:214
+#: wt-status.c:252
msgid "deleted by them:"
msgstr "borttaget av dem:"
-#: wt-status.c:215
+#: wt-status.c:253
msgid "added by them:"
msgstr "tillagt av dem:"
-#: wt-status.c:216
+#: wt-status.c:254
msgid "deleted by us:"
msgstr "borttaget av oss:"
-#: wt-status.c:217
+#: wt-status.c:255
msgid "both added:"
msgstr "tillagt av bägge:"
-#: wt-status.c:218
+#: wt-status.c:256
msgid "both modified:"
msgstr "ändrat av bägge:"
-#: wt-status.c:248
+#: wt-status.c:286
msgid "new commits, "
msgstr "nya incheckningar, "
-#: wt-status.c:250
+#: wt-status.c:288
msgid "modified content, "
msgstr "ändrat innehåll, "
-#: wt-status.c:252
+#: wt-status.c:290
msgid "untracked content, "
msgstr "ospårat innehåll, "
-#: wt-status.c:266
+#: wt-status.c:304
#, c-format
msgid "new file: %s"
msgstr "ny fil: %s"
-#: wt-status.c:269
+#: wt-status.c:307
#, c-format
msgid "copied: %s -> %s"
msgstr "kopierad: %s -> %s"
-#: wt-status.c:272
+#: wt-status.c:310
#, c-format
msgid "deleted: %s"
msgstr "borttagen: %s"
-#: wt-status.c:275
+#: wt-status.c:313
#, c-format
msgid "modified: %s"
msgstr "ändrad: %s"
-#: wt-status.c:278
+#: wt-status.c:316
#, c-format
msgid "renamed: %s -> %s"
msgstr "namnbyte: %s -> %s"
-#: wt-status.c:281
+#: wt-status.c:319
#, c-format
msgid "typechange: %s"
msgstr "typbyte: %s"
-#: wt-status.c:284
+#: wt-status.c:322
#, c-format
msgid "unknown: %s"
msgstr "okänd: %s"
-#: wt-status.c:287
+#: wt-status.c:325
#, c-format
msgid "unmerged: %s"
msgstr "osammansl.: %s"
-#: wt-status.c:290
+#: wt-status.c:328
#, c-format
msgid "bug: unhandled diff status %c"
msgstr "programfel: diff-status %c ej hanterad"
-#: wt-status.c:713
+#: wt-status.c:786
+msgid "You have unmerged paths."
+msgstr "Du har ej sammanslagna sökvägar."
+
+#: wt-status.c:789 wt-status.c:913
+msgid " (fix conflicts and run \"git commit\")"
+msgstr " (rätta konflikter och kör \"git commit\")"
+
+#: wt-status.c:792
+msgid "All conflicts fixed but you are still merging."
+msgstr "Alla konflikter har rättats men du är fortfarande i en sammanslagning."
+
+#: wt-status.c:795
+msgid " (use \"git commit\" to conclude merge)"
+msgstr " (använd \"git commit\" för att slutföra sammanslagningen)"
+
+#: wt-status.c:805
+msgid "You are in the middle of an am session."
+msgstr "Du är i mitten av en körning av \"git am\"."
+
+#: wt-status.c:808
+msgid "The current patch is empty."
+msgstr "Aktuell patch är tom."
+
+#: wt-status.c:812
+msgid " (fix conflicts and then run \"git am --resolved\")"
+msgstr " (rätta konflikter och kör sedan \"git am --resolved\")"
+
+#: wt-status.c:814
+msgid " (use \"git am --skip\" to skip this patch)"
+msgstr " (använd \"git am --skip\" för att hoppa över patchen)"
+
+#: wt-status.c:816
+msgid " (use \"git am --abort\" to restore the original branch)"
+msgstr " (använd \"git am --abort\" för att återställa ursprungsgrenen)"
+
+#: wt-status.c:874 wt-status.c:884
+msgid "You are currently rebasing."
+msgstr "Du håller på med en ombasering."
+
+#: wt-status.c:877
+msgid " (fix conflicts and then run \"git rebase --continue\")"
+msgstr " (rätta konflikter och kör sedan \"git rebase --continue\")"
+
+#: wt-status.c:879
+msgid " (use \"git rebase --skip\" to skip this patch)"
+msgstr " (använd \"git rebase --skip\" för att hoppa över patchen)"
+
+#: wt-status.c:881
+msgid " (use \"git rebase --abort\" to check out the original branch)"
+msgstr " (använd \"git rebase --abort\" för att checka ut ursprungsgrenen)"
+
+#: wt-status.c:887
+msgid " (all conflicts fixed: run \"git rebase --continue\")"
+msgstr " (alla konflikter rättade: kör \"git rebase --continue\")"
+
+#: wt-status.c:889
+msgid "You are currently splitting a commit during a rebase."
+msgstr "Du håller på att dela upp en incheckning i en ombasering."
+
+#: wt-status.c:892
+msgid " (Once your working directory is clean, run \"git rebase --continue\")"
+msgstr " (Så fort din arbetskatalog är ren, kör \"git rebase --continue\")"
+
+#: wt-status.c:894
+msgid "You are currently editing a commit during a rebase."
+msgstr "Du håller på att redigera en incheckning under en ombasering."
+
+#: wt-status.c:897
+msgid " (use \"git commit --amend\" to amend the current commit)"
+msgstr ""
+" (använd \"git commit --amend\" för att lägga till på aktuell incheckning)"
+
+#: wt-status.c:899
+msgid ""
+" (use \"git rebase --continue\" once you are satisfied with your changes)"
+msgstr " (använd \"git rebase --continue\" när du är nöjd med dina ändringar)"
+
+#: wt-status.c:909
+msgid "You are currently cherry-picking."
+msgstr "Du håller på med en \"cherry-pick\"."
+
+#: wt-status.c:916
+msgid " (all conflicts fixed: run \"git commit\")"
+msgstr " (alla konflikter har rättats: kör \"git commit\")"
+
+#: wt-status.c:925
+msgid "You are currently bisecting."
+msgstr "Du håller på med en \"bisect\"."
+
+#: wt-status.c:928
+msgid " (use \"git bisect reset\" to get back to the original branch)"
+msgstr ""
+" (använd \"git bisect reset\" för att komma tillbaka till ursprungsgrenen)"
+
+#: wt-status.c:979
msgid "On branch "
msgstr "På grenen "
-#: wt-status.c:720
+#: wt-status.c:986
msgid "Not currently on any branch."
msgstr "Inte på någon gren för närvarande."
-#: wt-status.c:731
+#: wt-status.c:998
msgid "Initial commit"
msgstr "Första incheckning"
-#: wt-status.c:745
+#: wt-status.c:1012
msgid "Untracked"
msgstr "Ospårad"
-#: wt-status.c:747
+#: wt-status.c:1014
msgid "Ignored"
msgstr "Ignorerad"
# %s är nästa sträng eller tom.
-#: wt-status.c:749
+#: wt-status.c:1016
#, c-format
msgid "Untracked files not listed%s"
msgstr "Ospårade filer visas ej%s"
-#: wt-status.c:751
+#: wt-status.c:1018
msgid " (use -u option to show untracked files)"
msgstr " (använd flaggan -u för att visa ospårade filer)"
-#: wt-status.c:757
+#: wt-status.c:1024
msgid "No changes"
msgstr "Inga ändringar"
-#: wt-status.c:761
+#: wt-status.c:1028
#, c-format
msgid "no changes added to commit%s\n"
msgstr "inga ändringar att checka in%s\n"
-#: wt-status.c:763
+#: wt-status.c:1030
msgid " (use \"git add\" and/or \"git commit -a\")"
msgstr " (använd \"git add\" och/eller \"git commit -a\")"
-#: wt-status.c:765
+#: wt-status.c:1032
#, c-format
msgid "nothing added to commit but untracked files present%s\n"
msgstr "inget köat för incheckning, men ospårade filer finns%s\n"
-#: wt-status.c:767
+#: wt-status.c:1034
msgid " (use \"git add\" to track)"
msgstr " (använd \"git add\" för att spåra)"
-#: wt-status.c:769 wt-status.c:772 wt-status.c:775
+#: wt-status.c:1036 wt-status.c:1039 wt-status.c:1042
#, c-format
msgid "nothing to commit%s\n"
msgstr "inget att checka in%s\n"
-#: wt-status.c:770
+#: wt-status.c:1037
msgid " (create/copy files and use \"git add\" to track)"
msgstr " (skapa/kopiera filer och använd \"git add\" för att spåra)"
-#: wt-status.c:773
+#: wt-status.c:1040
msgid " (use -u to show untracked files)"
msgstr " (använd -u för att visa ospårade filer)"
-#: wt-status.c:776
+#: wt-status.c:1043
msgid " (working directory clean)"
msgstr " (arbetskatalogen ren)"
-#: wt-status.c:884
+#: wt-status.c:1151
msgid "HEAD (no branch)"
msgstr "HEAD (ingen gren)"
-#: wt-status.c:890
+#: wt-status.c:1157
msgid "Initial commit on "
msgstr "Första incheckning på "
-#: wt-status.c:905
+#: wt-status.c:1172
msgid "behind "
msgstr "efter "
-#: wt-status.c:908 wt-status.c:911
+#: wt-status.c:1175 wt-status.c:1178
msgid "ahead "
msgstr "före "
-#: wt-status.c:913
+#: wt-status.c:1180
msgid ", behind "
msgstr ", efter "
msgid "unexpected diff status %c"
msgstr "diff-status %c förväntades inte"
-#: builtin/add.c:67 builtin/commit.c:298
+#: builtin/add.c:67 builtin/commit.c:226
msgid "updating files failed"
msgstr "misslyckades uppdatera filer"
msgid "Unstaged changes after refreshing the index:"
msgstr "Ospårade ändringar efter att ha uppdaterat indexet:"
-#: builtin/add.c:195 builtin/add.c:456 builtin/rm.c:186
+#: builtin/add.c:195 builtin/add.c:459 builtin/rm.c:186
#, c-format
msgid "pathspec '%s' did not match any files"
msgstr "sökvägsangivelsen \"%s\" motsvarade inte några filer"
#: builtin/add.c:303
#, c-format
msgid "Could not apply '%s'"
-msgstr "Kunde inte applicera \"%s\""
+msgstr "Kunde inte tillämpa \"%s\""
#: builtin/add.c:312
msgid "The following paths are ignored by one of your .gitignore files:\n"
msgid "Maybe you wanted to say 'git add .'?\n"
msgstr "Kanske menade du att skriva \"git add .\"?\n"
-#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:358 builtin/mv.c:82
+#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:286 builtin/mv.c:82
#: builtin/rm.c:162
msgid "index file corrupt"
msgstr "indexfilen trasig"
-#: builtin/add.c:476 builtin/mv.c:229 builtin/rm.c:260
+#: builtin/add.c:480 builtin/apply.c:4108 builtin/mv.c:229 builtin/rm.c:260
msgid "Unable to write new index file"
msgstr "Kunde inte skriva ny indexfil"
+#: builtin/apply.c:53
+msgid "git apply [options] [<patch>...]"
+msgstr "git apply [flaggor] [<patch>...]"
+
+#: builtin/apply.c:106
+#, c-format
+msgid "unrecognized whitespace option '%s'"
+msgstr "okänt alternativ för whitespace: \"%s\""
+
+#: builtin/apply.c:121
+#, c-format
+msgid "unrecognized whitespace ignore option '%s'"
+msgstr "okänt alternativ för ignore-whitespace: \"%s\""
+
+#: builtin/apply.c:815
+#, c-format
+msgid "Cannot prepare timestamp regexp %s"
+msgstr "Kan inte förbereda reguljärt uttryck för tidsstämpeln %s"
+
+#: builtin/apply.c:824
+#, c-format
+msgid "regexec returned %d for input: %s"
+msgstr "regexec returnerade %d för indata: %s"
+
+#: builtin/apply.c:905
+#, c-format
+msgid "unable to find filename in patch at line %d"
+msgstr "kan inte hitta filnamn i patchen på rad %d"
+
+#: builtin/apply.c:937
+#, c-format
+msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
+msgstr "git apply: dålig git-diff - förväntade /dev/null, fick %s på rad %d"
+
+#: builtin/apply.c:941
+#, c-format
+msgid "git apply: bad git-diff - inconsistent new filename on line %d"
+msgstr "git apply: dålig git-diff - motsägande nytt filnamn på rad %d"
+
+#: builtin/apply.c:942
+#, c-format
+msgid "git apply: bad git-diff - inconsistent old filename on line %d"
+msgstr "git apply: dålig git-diff - motsägande gammalt filnamn på rad %d"
+
+#: builtin/apply.c:949
+#, c-format
+msgid "git apply: bad git-diff - expected /dev/null on line %d"
+msgstr "git apply: dålig git-diff - förväntade /dev/null på rad %d"
+
+#: builtin/apply.c:1394
+#, c-format
+msgid "recount: unexpected line: %.*s"
+msgstr "recount: förväntade rad: %.*s"
+
+#: builtin/apply.c:1451
+#, c-format
+msgid "patch fragment without header at line %d: %.*s"
+msgstr "patch-fragment utan huvud på rad %d: %.*s"
+
+#: builtin/apply.c:1468
+#, c-format
+msgid ""
+"git diff header lacks filename information when removing %d leading pathname "
+"component (line %d)"
+msgid_plural ""
+"git diff header lacks filename information when removing %d leading pathname "
+"components (line %d)"
+msgstr[0] ""
+"git-diff-huvudet saknar filnamnsinformation när %d ledande sökvägskomponent\n"
+"tas bort (rad %d)"
+msgstr[1] ""
+"git-diff-huvudet saknar filnamnsinformation när %d ledande "
+"sökvägskomponenter\n"
+"tas bort (rad %d)"
+
+#: builtin/apply.c:1628
+msgid "new file depends on old contents"
+msgstr "ny fil beror på gammalt innehåll"
+
+#: builtin/apply.c:1630
+msgid "deleted file still has contents"
+msgstr "borttagen fil har fortfarande innehåll"
+
+#: builtin/apply.c:1656
+#, c-format
+msgid "corrupt patch at line %d"
+msgstr "trasig patch på rad %d"
+
+#: builtin/apply.c:1692
+#, c-format
+msgid "new file %s depends on old contents"
+msgstr "nya filen %s beror på gammalt innehåll"
+
+#: builtin/apply.c:1694
+#, c-format
+msgid "deleted file %s still has contents"
+msgstr "borttagna filen %s har fortfarande innehåll"
+
+#: builtin/apply.c:1697
+#, c-format
+msgid "** warning: file %s becomes empty but is not deleted"
+msgstr "** varning: filen %s blir tom men har inte tagits bort"
+
+#: builtin/apply.c:1843
+#, c-format
+msgid "corrupt binary patch at line %d: %.*s"
+msgstr "trasig binärpatch på rad %d: %.*s"
+
+#. there has to be one hunk (forward hunk)
+#: builtin/apply.c:1872
+#, c-format
+msgid "unrecognized binary patch at line %d"
+msgstr "binärpatchen på rad %d känns inte igen"
+
+#: builtin/apply.c:1958
+#, c-format
+msgid "patch with only garbage at line %d"
+msgstr "patch med bara skräp på rad %d"
+
+#: builtin/apply.c:2048
+#, c-format
+msgid "unable to read symlink %s"
+msgstr "kunde inte läsa symboliska länken %s"
+
+#: builtin/apply.c:2052
+#, c-format
+msgid "unable to open or read %s"
+msgstr "kunde inte öppna eller läsa %s"
+
+#: builtin/apply.c:2123
+msgid "oops"
+msgstr "hoppsan"
+
+#: builtin/apply.c:2645
+#, c-format
+msgid "invalid start of line: '%c'"
+msgstr "felaktig inledning på rad: \"%c\""
+
+#: builtin/apply.c:2763
+#, c-format
+msgid "Hunk #%d succeeded at %d (offset %d line)."
+msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
+msgstr[0] "Stycke %d lyckades på %d (offset %d rad)."
+msgstr[1] "Stycke %d lyckades på %d (offset %d rader)."
+
+#: builtin/apply.c:2775
+#, c-format
+msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
+msgstr "Sammanhang reducerat till (%ld/%ld) för att tillämpa fragment vid %d"
+
+#: builtin/apply.c:2781
+#, c-format
+msgid ""
+"while searching for:\n"
+"%.*s"
+msgstr ""
+"vid sökning efter:\n"
+"%.*s"
+
+#: builtin/apply.c:2800
+#, c-format
+msgid "missing binary patch data for '%s'"
+msgstr "saknar binära patchdata för \"%s\""
+
+#: builtin/apply.c:2903
+#, c-format
+msgid "binary patch does not apply to '%s'"
+msgstr "binärpatchen kan inte tillämpas på \"%s\""
+
+#: builtin/apply.c:2909
+#, c-format
+msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
+msgstr "binärpatchen på \"%s\" ger felaktigt resultat (förväntade %s, fick %s)"
+
+#: builtin/apply.c:2930
+#, c-format
+msgid "patch failed: %s:%ld"
+msgstr "patch misslyckades: %s:%ld"
+
+#: builtin/apply.c:3045
+#, c-format
+msgid "patch %s has been renamed/deleted"
+msgstr "patchen %s har ändrat namn/tagits bort"
+
+#: builtin/apply.c:3052 builtin/apply.c:3069
+#, c-format
+msgid "read of %s failed"
+msgstr "misslyckades läsa %s"
+
+#: builtin/apply.c:3084
+msgid "removal patch leaves file contents"
+msgstr "patch för borttagning lämnar kvar filinnehåll"
+
+#: builtin/apply.c:3105
+#, c-format
+msgid "%s: already exists in working directory"
+msgstr "%s: finns redan i arbetskatalogen"
+
+#: builtin/apply.c:3143
+#, c-format
+msgid "%s: has been deleted/renamed"
+msgstr "%s: har tagits bort/ändrat namn"
+
+#: builtin/apply.c:3148 builtin/apply.c:3179
+#, c-format
+msgid "%s: %s"
+msgstr "%s: %s"
+
+#: builtin/apply.c:3159
+#, c-format
+msgid "%s: does not exist in index"
+msgstr "%s: finns inte i indexet"
+
+#: builtin/apply.c:3173
+#, c-format
+msgid "%s: does not match index"
+msgstr "%s: motsvarar inte indexet"
+
+#: builtin/apply.c:3190
+#, c-format
+msgid "%s: wrong type"
+msgstr "%s: fel typ"
+
+#: builtin/apply.c:3192
+#, c-format
+msgid "%s has type %o, expected %o"
+msgstr "%s har typen %o, förväntade %o"
+
+#: builtin/apply.c:3247
+#, c-format
+msgid "%s: already exists in index"
+msgstr "%s: finns redan i indexet"
+
+#: builtin/apply.c:3267
+#, c-format
+msgid "new mode (%o) of %s does not match old mode (%o)"
+msgstr "nytt läge (%o) för %s motsvarar inte gammalt läge (%o)"
+
+#: builtin/apply.c:3272
+#, c-format
+msgid "new mode (%o) of %s does not match old mode (%o) of %s"
+msgstr "nytt läge (%o) för %s motsvarar inte gammalt läge (%o) för %s"
+
+#: builtin/apply.c:3280
+#, c-format
+msgid "%s: patch does not apply"
+msgstr "%s: patchen kan inte tillämpas"
+
+#: builtin/apply.c:3293
+#, c-format
+msgid "Checking patch %s..."
+msgstr "Kontrollerar patchen %s..."
+
+#: builtin/apply.c:3348 builtin/checkout.c:212 builtin/reset.c:158
+#, c-format
+msgid "make_cache_entry failed for path '%s'"
+msgstr "make_cache_entry misslyckades för sökvägen \"%s\""
+
+#: builtin/apply.c:3491
+#, c-format
+msgid "unable to remove %s from index"
+msgstr "kan inte ta bort %s från indexet"
+
+#: builtin/apply.c:3518
+#, c-format
+msgid "corrupt patch for subproject %s"
+msgstr "trasig patch för underprojektet %s"
+
+#: builtin/apply.c:3522
+#, c-format
+msgid "unable to stat newly created file '%s'"
+msgstr "kan inte ta status på nyligen skapade filen \"%s\""
+
+#: builtin/apply.c:3527
+#, c-format
+msgid "unable to create backing store for newly created file %s"
+msgstr "kan inte skapa säkerhetsminne för nyligen skapade filen %s"
+
+#: builtin/apply.c:3530
+#, c-format
+msgid "unable to add cache entry for %s"
+msgstr "kan inte lägga till cachepost för %s"
+
+#: builtin/apply.c:3563
+#, c-format
+msgid "closing file '%s'"
+msgstr "stänger filen \"%s\""
+
+#: builtin/apply.c:3612
+#, c-format
+msgid "unable to write file '%s' mode %o"
+msgstr "kan inte skriva filen \"%s\" läge %o"
+
+#: builtin/apply.c:3668
+#, c-format
+msgid "Applied patch %s cleanly."
+msgstr "Tillämpade patchen %s rent."
+
+#: builtin/apply.c:3676
+msgid "internal error"
+msgstr "internt fel"
+
+#. Say this even without --verbose
+#: builtin/apply.c:3679
+#, c-format
+msgid "Applying patch %%s with %d reject..."
+msgid_plural "Applying patch %%s with %d rejects..."
+msgstr[0] "Tillämpade patchen %%s med %d refuserad..."
+msgstr[1] "Tillämpade patchen %%s med %d refuserade..."
+
+#: builtin/apply.c:3689
+#, c-format
+msgid "truncating .rej filename to %.*s.rej"
+msgstr "trunkerar .rej-filnamnet till %.*s.rej"
+
+#: builtin/apply.c:3710
+#, c-format
+msgid "Hunk #%d applied cleanly."
+msgstr "Stycke %d tillämpades rent."
+
+#: builtin/apply.c:3713
+#, c-format
+msgid "Rejected hunk #%d."
+msgstr "Refuserar stycke %d."
+
+#: builtin/apply.c:3844
+msgid "unrecognized input"
+msgstr "indata känns inte igen"
+
+#: builtin/apply.c:3855
+msgid "unable to read index file"
+msgstr "kan inte läsa indexfilen"
+
+#: builtin/apply.c:3970 builtin/apply.c:3973
+msgid "path"
+msgstr "sökväg"
+
+#: builtin/apply.c:3971
+msgid "don't apply changes matching the given path"
+msgstr "tillämpa inte ändringar som motsvarar given sökväg"
+
+#: builtin/apply.c:3974
+msgid "apply changes matching the given path"
+msgstr "tillämpa ändringar som motsvarar given sökväg"
+
+#: builtin/apply.c:3976
+msgid "num"
+msgstr "antal"
+
+#: builtin/apply.c:3977
+msgid "remove <num> leading slashes from traditional diff paths"
+msgstr "ta bort <antal> inledande snedstreck från traditionella diff-sökvägar"
+
+#: builtin/apply.c:3980
+msgid "ignore additions made by the patch"
+msgstr "ignorera tillägg gjorda av patchen"
+
+#: builtin/apply.c:3982
+msgid "instead of applying the patch, output diffstat for the input"
+msgstr "istället för att tillämpa patchen, skriv ut diffstat för indata"
+
+#: builtin/apply.c:3986
+msgid "shows number of added and deleted lines in decimal notation"
+msgstr "visar antal tillagda och borttagna rader decimalt"
+
+#: builtin/apply.c:3988
+msgid "instead of applying the patch, output a summary for the input"
+msgstr "istället för att tillämpa patchen, skriv ut en summering av indata"
+
+#: builtin/apply.c:3990
+msgid "instead of applying the patch, see if the patch is applicable"
+msgstr "istället för att tillämpa patchen, se om patchen kan tillämpas"
+
+#: builtin/apply.c:3992
+msgid "make sure the patch is applicable to the current index"
+msgstr "se till att patchen kan tillämpas på aktuellt index"
+
+#: builtin/apply.c:3994
+msgid "apply a patch without touching the working tree"
+msgstr "tillämpa en patch utan att röra arbetskatalogen"
+
+#: builtin/apply.c:3996
+msgid "also apply the patch (use with --stat/--summary/--check)"
+msgstr "tillämpa också patchen (använd med --stat/--summary/--check)"
+
+#: builtin/apply.c:3998
+msgid "build a temporary index based on embedded index information"
+msgstr "bygg ett temporärt index baserat på inbyggd indexinformation"
+
+#: builtin/apply.c:4000
+msgid "paths are separated with NUL character"
+msgstr "sökvägar avdelas med NUL-tecken"
+
+#: builtin/apply.c:4003
+msgid "ensure at least <n> lines of context match"
+msgstr "se till att åtminstone <n> rader sammanhang är lika"
+
+#: builtin/apply.c:4004
+msgid "action"
+msgstr "åtgärd"
+
+#: builtin/apply.c:4005
+msgid "detect new or modified lines that have whitespace errors"
+msgstr "detektera nya eller ändrade rader som har fel i blanktecken"
+
+#: builtin/apply.c:4008 builtin/apply.c:4011
+msgid "ignore changes in whitespace when finding context"
+msgstr "ignorera ändringar i blanktecken för sammanhang"
+
+#: builtin/apply.c:4014
+msgid "apply the patch in reverse"
+msgstr "tillämpa patchen baklänges"
+
+#: builtin/apply.c:4016
+msgid "don't expect at least one line of context"
+msgstr "förvänta inte minst en rad sammanhang"
+
+#: builtin/apply.c:4018
+msgid "leave the rejected hunks in corresponding *.rej files"
+msgstr "lämna refuserade stycken i motsvarande *.rej-filer"
+
+#: builtin/apply.c:4020
+msgid "allow overlapping hunks"
+msgstr "tillåt överlappande stycken"
+
+#: builtin/apply.c:4021
+msgid "be verbose"
+msgstr "var pratsam"
+
+#: builtin/apply.c:4023
+msgid "tolerate incorrectly detected missing new-line at the end of file"
+msgstr "tolerera felaktigt detekterade saknade nyradstecken vid filslut"
+
+#: builtin/apply.c:4026
+msgid "do not trust the line counts in the hunk headers"
+msgstr "lite inte på antalet linjer i styckehuvuden"
+
+#: builtin/apply.c:4028
+msgid "root"
+msgstr "rot"
+
+#: builtin/apply.c:4029
+msgid "prepend <root> to all filenames"
+msgstr "lägg till <rot> i alla filnamn"
+
+#: builtin/apply.c:4050
+msgid "--index outside a repository"
+msgstr "--index utanför arkiv"
+
+#: builtin/apply.c:4053
+msgid "--cached outside a repository"
+msgstr "--cached utanför arkiv"
+
+#: builtin/apply.c:4069
+#, c-format
+msgid "can't open patch '%s'"
+msgstr "kan inte öppna patchen \"%s\""
+
+#: builtin/apply.c:4083
+#, c-format
+msgid "squelched %d whitespace error"
+msgid_plural "squelched %d whitespace errors"
+msgstr[0] "undertryckte %d fel i blanksteg"
+msgstr[1] "undertryckte %d fel i blanksteg"
+
+#: builtin/apply.c:4089 builtin/apply.c:4099
+#, c-format
+msgid "%d line adds whitespace errors."
+msgid_plural "%d lines add whitespace errors."
+msgstr[0] "%d rad lägger till fel i blanksteg."
+msgstr[1] "%d rader lägger till fel i blanksteg."
+
#: builtin/archive.c:17
#, c-format
msgid "could not create archive file '%s'"
msgid "git archive: expected a flush"
msgstr "git archive: förväntade en tömning (flush)"
-#: builtin/branch.c:137
+#: builtin/branch.c:144
#, c-format
msgid ""
"deleting branch '%s' that has been merged to\n"
"tar bort grenen \"%s\" som har slagits ihop med\n"
" \"%s\", men ännu inte slagits ihop med HEAD."
-#: builtin/branch.c:141
+#: builtin/branch.c:148
#, c-format
msgid ""
"not deleting branch '%s' that is not yet merged to\n"
"tar inte bort grenen \"%s\" som inte har slagits ihop med\n"
" \"%s\", trots att den har slagits ihop med HEAD."
-#. TRANSLATORS: This is "remote " in "remote branch '%s' not found"
-#: builtin/branch.c:163
-msgid "remote "
-msgstr "fjärr"
-
-#: builtin/branch.c:171
+#: builtin/branch.c:180
msgid "cannot use -a with -d"
msgstr "kan inte ange -a med -d"
-#: builtin/branch.c:177
+#: builtin/branch.c:186
msgid "Couldn't look up commit object for HEAD"
msgstr "Kunde inte slå upp incheckningsobjekt för HEAD"
-#: builtin/branch.c:182
+#: builtin/branch.c:191
#, c-format
msgid "Cannot delete the branch '%s' which you are currently on."
msgstr "Kan inte ta bort grenen \"%s\" som du befinner dig på för närvarande."
-#: builtin/branch.c:192
+#: builtin/branch.c:202
#, c-format
-msgid "%sbranch '%s' not found."
-msgstr "%sgrenen \"%s\" hittades inte."
+msgid "remote branch '%s' not found."
+msgstr "fjärrgrenen \"%s\" hittades inte."
-#: builtin/branch.c:200
+#: builtin/branch.c:203
+#, c-format
+msgid "branch '%s' not found."
+msgstr "grenen \"%s\" hittades inte."
+
+#: builtin/branch.c:210
#, c-format
msgid "Couldn't look up commit object for '%s'"
msgstr "Kunde inte slå upp incheckningsobjekt för \"%s\""
-#: builtin/branch.c:206
+#: builtin/branch.c:216
#, c-format
msgid ""
"The branch '%s' is not fully merged.\n"
"Grenen \"%s\" har inte slagits samman i sin helhet.\n"
"Om du är säker på att du vill ta bort den, kör \"git branch -D %s\"."
-#: builtin/branch.c:214
+#: builtin/branch.c:225
+#, c-format
+msgid "Error deleting remote branch '%s'"
+msgstr "Fel vid borttagning av fjärrgrenen \"%s\""
+
+#: builtin/branch.c:226
#, c-format
-msgid "Error deleting %sbranch '%s'"
-msgstr "Fel vid borttagning av %sgrenen \"%s\""
+msgid "Error deleting branch '%s'"
+msgstr "Fel vid borttagning av grenen \"%s\""
-#: builtin/branch.c:219
+#: builtin/branch.c:233
#, c-format
-msgid "Deleted %sbranch %s (was %s).\n"
-msgstr "Tog bort %sgrenen %s (var %s).\n"
+msgid "Deleted remote branch %s (was %s).\n"
+msgstr "Tog bort fjärrgrenen %s (var %s).\n"
-#: builtin/branch.c:224
+#: builtin/branch.c:234
+#, c-format
+msgid "Deleted branch %s (was %s).\n"
+msgstr "Tog bort grenen %s (var %s).\n"
+
+#: builtin/branch.c:239
msgid "Update of config-file failed"
msgstr "Misslyckades uppdatera konfigurationsfil"
-#: builtin/branch.c:322
+#: builtin/branch.c:337
#, c-format
msgid "branch '%s' does not point at a commit"
msgstr "grenen \"%s\" pekar inte på en incheckning"
-#: builtin/branch.c:394
+#: builtin/branch.c:409
+#, c-format
+msgid "[%s: behind %d]"
+msgstr "[%s: bakom %d] "
+
+#: builtin/branch.c:411
+#, c-format
+msgid "[behind %d]"
+msgstr "[bakom %d] "
+
+#: builtin/branch.c:415
+#, c-format
+msgid "[%s: ahead %d]"
+msgstr "[%s: före %d] "
+
+#: builtin/branch.c:417
#, c-format
-msgid "behind %d] "
-msgstr "bakom %d] "
+msgid "[ahead %d]"
+msgstr "[före %d] "
-#: builtin/branch.c:396
+#: builtin/branch.c:420
#, c-format
-msgid "ahead %d] "
-msgstr "före %d] "
+msgid "[%s: ahead %d, behind %d]"
+msgstr "[%s: före %d, bakom %d] "
-#: builtin/branch.c:398
+#: builtin/branch.c:423
#, c-format
-msgid "ahead %d, behind %d] "
-msgstr "före %d, bakom %d] "
+msgid "[ahead %d, behind %d]"
+msgstr "[före %d, bakom %d] "
-#: builtin/branch.c:501
+#: builtin/branch.c:535
msgid "(no branch)"
msgstr "(ingen gren)"
-#: builtin/branch.c:566
+#: builtin/branch.c:600
msgid "some refs could not be read"
msgstr "vissa referenser kunde inte läsas"
-#: builtin/branch.c:579
+#: builtin/branch.c:613
msgid "cannot rename the current branch while not on any."
msgstr ""
"kunde inte byta namn på aktuell gren när du inte befinner dig på någon."
-#: builtin/branch.c:589
+#: builtin/branch.c:623
#, c-format
msgid "Invalid branch name: '%s'"
msgstr "Felaktigt namn på gren: \"%s\""
-#: builtin/branch.c:604
+#: builtin/branch.c:638
msgid "Branch rename failed"
msgstr "Misslyckades byta namn på gren"
-#: builtin/branch.c:608
+#: builtin/branch.c:642
#, c-format
msgid "Renamed a misnamed branch '%s' away"
msgstr "Bytte bort namn på en felaktigt namngiven gren \"%s\""
-#: builtin/branch.c:612
+#: builtin/branch.c:646
#, c-format
msgid "Branch renamed to %s, but HEAD is not updated!"
msgstr "Grenen namnbytt till %s, men HEAD har inte uppdaterats!"
-#: builtin/branch.c:619
+#: builtin/branch.c:653
msgid "Branch is renamed, but update of config-file failed"
msgstr "Grenen namnbytt, men misslyckades uppdatera konfigurationsfilen"
-#: builtin/branch.c:634
+#: builtin/branch.c:668
#, c-format
msgid "malformed object name %s"
msgstr "felformat objektnamn %s"
-#: builtin/branch.c:658
+#: builtin/branch.c:692
#, c-format
-msgid "could not write branch description template: %s\n"
-msgstr "kunde inte skriva grenbeskrivningsmall: %s\n"
+msgid "could not write branch description template: %s"
+msgstr "kunde inte skriva grenbeskrivningsmall: %s"
-#: builtin/branch.c:746
+#: builtin/branch.c:783
msgid "Failed to resolve HEAD as a valid ref."
msgstr "Misslyckades slå upp HEAD som giltig referens"
-#: builtin/branch.c:751 builtin/clone.c:558
+#: builtin/branch.c:788 builtin/clone.c:558
msgid "HEAD not found below refs/heads!"
msgstr "HEAD hittades inte under refs/heads!"
-#: builtin/branch.c:809
+#: builtin/branch.c:808
+msgid "--column and --verbose are incompatible"
+msgstr "--column och --verbose är inkompatibla"
+
+#: builtin/branch.c:857
msgid "-a and -r options to 'git branch' do not make sense with a branch name"
msgstr ""
"flaggorna -a och -r på \"git branch\" kan inte anges tillsammans med ett "
msgid "Unable to add merge result for '%s'"
msgstr "Kunde inte lägga till sammanslagningsresultat för \"%s\""
-#: builtin/checkout.c:212 builtin/reset.c:158
-#, c-format
-msgid "make_cache_entry failed for path '%s'"
-msgstr "make_cache_entry misslyckades för sökvägen \"%s\""
-
#: builtin/checkout.c:234 builtin/checkout.c:392
msgid "corrupt index file"
msgstr "indexfilen är trasig"
msgid "Can not do reflog for '%s'\n"
msgstr "Kan inte skapa referenslog för \"%s\"\n"
-#: builtin/checkout.c:565
+#: builtin/checkout.c:566
msgid "HEAD is now at"
msgstr "HEAD är nu på"
-#: builtin/checkout.c:572
+#: builtin/checkout.c:573
#, c-format
msgid "Reset branch '%s'\n"
msgstr "Återställ gren \"%s\"\n"
-#: builtin/checkout.c:575
+#: builtin/checkout.c:576
#, c-format
msgid "Already on '%s'\n"
msgstr "Redan på \"%s\"\n"
-#: builtin/checkout.c:579
+#: builtin/checkout.c:580
#, c-format
msgid "Switched to and reset branch '%s'\n"
msgstr "Växlade till och nollställde grenen \"%s\"\n"
-#: builtin/checkout.c:581
+#: builtin/checkout.c:582
#, c-format
msgid "Switched to a new branch '%s'\n"
msgstr "Växlade till en ny gren \"%s\"\n"
-#: builtin/checkout.c:583
+#: builtin/checkout.c:584
#, c-format
msgid "Switched to branch '%s'\n"
msgstr "Växlade till grenen \"%s\"\n"
-#: builtin/checkout.c:639
+#: builtin/checkout.c:640
#, c-format
msgid " ... and %d more.\n"
msgstr " ... och %d till.\n"
#. The singular version
-#: builtin/checkout.c:645
+#: builtin/checkout.c:646
#, c-format
msgid ""
"Warning: you are leaving %d commit behind, not connected to\n"
"\n"
"%s\n"
-#: builtin/checkout.c:663
+#: builtin/checkout.c:664
#, c-format
msgid ""
"If you want to keep them by creating a new branch, this may be a good time\n"
" git branch nytt_grennamn %s\n"
"\n"
-#: builtin/checkout.c:693
+#: builtin/checkout.c:694
msgid "internal error in revision walk"
msgstr "internt fel vid genomgång av revisioner (revision walk)"
-#: builtin/checkout.c:697
+#: builtin/checkout.c:698
msgid "Previous HEAD position was"
msgstr "Tidigare position för HEAD var"
-#: builtin/checkout.c:723
+#: builtin/checkout.c:724
msgid "You are on a branch yet to be born"
msgstr "Du är på en gren som ännu inte är född"
#. case (1)
-#: builtin/checkout.c:854
+#: builtin/checkout.c:855
#, c-format
msgid "invalid reference: %s"
msgstr "felaktig referens: %s"
#. case (1): want a tree
-#: builtin/checkout.c:893
+#: builtin/checkout.c:894
#, c-format
msgid "reference is not a tree: %s"
msgstr "referensen är inte ett träd: %s"
-#: builtin/checkout.c:973
+#: builtin/checkout.c:974
msgid "-B cannot be used with -b"
msgstr "-B kan inte användas med -b"
-#: builtin/checkout.c:982
+#: builtin/checkout.c:983
msgid "--patch is incompatible with all other options"
msgstr "--patch är inkompatibel med alla andra flaggor"
-#: builtin/checkout.c:985
+#: builtin/checkout.c:986
msgid "--detach cannot be used with -b/-B/--orphan"
msgstr "--detcah kan inte användas med -b/-B/--orphan"
-#: builtin/checkout.c:987
+#: builtin/checkout.c:988
msgid "--detach cannot be used with -t"
msgstr "--detach kan inte användas med -t"
-#: builtin/checkout.c:993
+#: builtin/checkout.c:994
msgid "--track needs a branch name"
msgstr "--track behöver ett namn på en gren"
-#: builtin/checkout.c:1000
+#: builtin/checkout.c:1001
msgid "Missing branch name; try -b"
msgstr "Grennamn saknas; försök med -b"
-#: builtin/checkout.c:1006
+#: builtin/checkout.c:1007
msgid "--orphan and -b|-B are mutually exclusive"
msgstr "--orphan och -b|-B kan inte användas samtidigt"
-#: builtin/checkout.c:1008
+#: builtin/checkout.c:1009
msgid "--orphan cannot be used with -t"
msgstr "--orphan kan inte användas med -t"
-#: builtin/checkout.c:1018
+#: builtin/checkout.c:1019
msgid "git checkout: -f and -m are incompatible"
msgstr "git checkout: -f och -m är inkompatibla"
-#: builtin/checkout.c:1052
+#: builtin/checkout.c:1053
msgid "invalid path specification"
msgstr "felaktig sökvägsangivelse"
-#: builtin/checkout.c:1060
+#: builtin/checkout.c:1061
#, c-format
msgid ""
"git checkout: updating paths is incompatible with switching branches.\n"
"git checkout: uppdatera sökvägar är inkompatibelt med att växla gren.\n"
"Ville du checka ut \"%s\" som inte kan lösas som en sammanslaning?"
-#: builtin/checkout.c:1062
+#: builtin/checkout.c:1063
msgid "git checkout: updating paths is incompatible with switching branches."
msgstr "git checkout: uppdatera sökvägar är inkompatibelt med att växla gren."
-#: builtin/checkout.c:1067
+#: builtin/checkout.c:1068
msgid "git checkout: --detach does not take a path argument"
msgstr "git checkout: --detach tar inte en sökväg som argument"
-#: builtin/checkout.c:1070
+#: builtin/checkout.c:1071
msgid ""
"git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
"checking out of the index."
"git checkout: --ours/--theirs, --force och --merge är inkompatibla när\n"
"du checkar ut från indexet."
-#: builtin/checkout.c:1089
+#: builtin/checkout.c:1090
msgid "Cannot switch branch to a non-commit."
msgstr "Kan inte växla gren på en icke-incheckning."
-#: builtin/checkout.c:1092
+#: builtin/checkout.c:1093
msgid "--ours/--theirs is incompatible with switching branches."
msgstr "--ours/--theirs är inkompatibla med att byta gren."
msgid "You appear to have cloned an empty repository."
msgstr "Du verkar ha klonat ett tomt arkiv."
-#: builtin/commit.c:42
+#: builtin/column.c:51
+msgid "--command must be the first argument"
+msgstr "--command måste vara första argument"
+
+#: builtin/commit.c:43
msgid ""
"Your name and email address were configured automatically based\n"
"on your username and hostname. Please check that they are accurate.\n"
"\n"
" git commit --amend --reset-author\n"
-#: builtin/commit.c:54
+#: builtin/commit.c:55
msgid ""
"You asked to amend the most recent commit, but doing so would make\n"
"it empty. You can repeat your command with --allow-empty, or you can\n"
"blir den tom. Du kan köra kommandot på nytt med --allow-empty, eller\n"
"så kan du ta bort incheckningen helt med \"git reset HEAD^\".\n"
-#: builtin/commit.c:59
+#: builtin/commit.c:60
msgid ""
"The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
"If you wish to commit it anyway, use:\n"
"\n"
"Annars använder du \"git reset\"\n"
-#: builtin/commit.c:205 builtin/reset.c:33
-msgid "merge"
-msgstr "sammanslagning"
-
-#: builtin/commit.c:208
-msgid "cherry-pick"
-msgstr "cherry-pick"
-
-#: builtin/commit.c:325
+#: builtin/commit.c:253
msgid "failed to unpack HEAD tree object"
msgstr "misslyckades packa upp HEAD:s trädobjekt"
-#: builtin/commit.c:367
+#: builtin/commit.c:295
msgid "unable to create temporary index"
msgstr "kunde inte skapa temporär indexfil"
-#: builtin/commit.c:373
+#: builtin/commit.c:301
msgid "interactive add failed"
msgstr "interaktiv tilläggning misslyckades"
-#: builtin/commit.c:406 builtin/commit.c:427 builtin/commit.c:473
+#: builtin/commit.c:334 builtin/commit.c:355 builtin/commit.c:405
msgid "unable to write new_index file"
msgstr "kunde inte skriva filen new_index"
-# %s är antingen "merge" eller "cherry-pick".
-#: builtin/commit.c:457
-#, c-format
-msgid "cannot do a partial commit during a %s."
-msgstr "kan inte utföra en delvis incheckning under en %s"
+#: builtin/commit.c:386
+msgid "cannot do a partial commit during a merge."
+msgstr "kan inte utföra en delvis incheckning under en sammanslagning."
-#: builtin/commit.c:466
+#: builtin/commit.c:388
+msgid "cannot do a partial commit during a cherry-pick."
+msgstr "kan inte utföra en delvis incheckning under en cherry-pick."
+
+#: builtin/commit.c:398
msgid "cannot read the index"
msgstr "kan inte läsa indexet"
-#: builtin/commit.c:486
+#: builtin/commit.c:418
msgid "unable to write temporary index file"
msgstr "kunde inte skriva temporär indexfil"
-#: builtin/commit.c:561 builtin/commit.c:567
+#: builtin/commit.c:493 builtin/commit.c:499
#, c-format
msgid "invalid commit: %s"
msgstr "felaktig incheckning: %s"
-#: builtin/commit.c:590
+#: builtin/commit.c:522
msgid "malformed --author parameter"
msgstr "felformad \"--author\"-flagga"
-#: builtin/commit.c:651
+#: builtin/commit.c:582
#, c-format
msgid "Malformed ident string: '%s'"
msgstr "Felaktig indragningssträng: \"%s\""
-#: builtin/commit.c:689 builtin/commit.c:722 builtin/commit.c:1033
+#: builtin/commit.c:620 builtin/commit.c:653 builtin/commit.c:967
#, c-format
msgid "could not lookup commit %s"
msgstr "kunde inte slå upp incheckningen %s"
-#: builtin/commit.c:701 builtin/shortlog.c:296
+#: builtin/commit.c:632 builtin/shortlog.c:296
#, c-format
msgid "(reading log message from standard input)\n"
msgstr "(läser loggmeddelande från standard in)\n"
-#: builtin/commit.c:703
+#: builtin/commit.c:634
msgid "could not read log from standard input"
msgstr "kunde inte läsa logg från standard in"
-#: builtin/commit.c:707
+#: builtin/commit.c:638
#, c-format
msgid "could not read log file '%s'"
msgstr "kunde inte läsa loggfilen \"%s\""
-#: builtin/commit.c:713
+#: builtin/commit.c:644
msgid "commit has empty message"
msgstr "incheckningen har ett tomt meddelande"
-#: builtin/commit.c:729
+#: builtin/commit.c:660
msgid "could not read MERGE_MSG"
msgstr "kunde inte läsa MERGE_MSG"
-#: builtin/commit.c:733
+#: builtin/commit.c:664
msgid "could not read SQUASH_MSG"
msgstr "kunde inte läsa SQUASH_MSG"
-#: builtin/commit.c:737
+#: builtin/commit.c:668
#, c-format
msgid "could not read '%s'"
msgstr "kunde inte läsa \"%s\""
-#: builtin/commit.c:765
-#, c-format
-msgid "could not open '%s'"
-msgstr "kunde inte öppna \"%s\""
-
-#: builtin/commit.c:789
+#: builtin/commit.c:720
msgid "could not write commit template"
msgstr "kunde inte skriva incheckningsmall"
-# %s är "merge" eller "cherry-pick"
-#: builtin/commit.c:799
+#: builtin/commit.c:731
#, c-format
msgid ""
"\n"
-"It looks like you may be committing a %s.\n"
+"It looks like you may be committing a merge.\n"
"If this is not correct, please remove the file\n"
"\t%s\n"
"and try again.\n"
msgstr ""
"\n"
-"Det verkar som du checkar in en %s.\n"
+"Det verkar som du checkar in en sammanslagning.\n"
"Om det inte stämmer tar du bort filen\n"
"\t%s\n"
"och försöker igen.\n"
-#: builtin/commit.c:812
-msgid "Please enter the commit message for your changes."
-msgstr "Ange ett incheckningsmeddelande för dina ändringar."
+#: builtin/commit.c:736
+#, c-format
+msgid ""
+"\n"
+"It looks like you may be committing a cherry-pick.\n"
+"If this is not correct, please remove the file\n"
+"\t%s\n"
+"and try again.\n"
+msgstr ""
+"\n"
+"Det verkar som du checkar in en cherry-pick.\n"
+"Om det inte stämmer tar du bort filen\n"
+"\t%s\n"
+"och försöker igen.\n"
-#: builtin/commit.c:815
+#: builtin/commit.c:748
msgid ""
-" Lines starting\n"
+"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be ignored, and an empty message aborts the commit.\n"
msgstr ""
-" Rader som inleds\n"
+"Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n"
"med \"#\" kommer ignoreras, och ett tomt meddelande avbryter incheckningen.\n"
-#: builtin/commit.c:820
+#: builtin/commit.c:753
msgid ""
-" Lines starting\n"
+"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be kept; you may remove them yourself if you want to.\n"
"An empty message aborts the commit.\n"
msgstr ""
-" Rader som inleds\n"
+"Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n"
"med \"#\" kommer behållas; du kan själv ta bort dem om du vill.\n"
"Ett tomt meddelande avbryter incheckningen.\n"
-#: builtin/commit.c:832
+#: builtin/commit.c:766
#, c-format
msgid "%sAuthor: %s"
msgstr "%sFörfattare: %s"
-#: builtin/commit.c:839
+#: builtin/commit.c:773
#, c-format
msgid "%sCommitter: %s"
msgstr "%sIncheckare: %s"
-#: builtin/commit.c:859
+#: builtin/commit.c:793
msgid "Cannot read index"
msgstr "Kan inte läsa indexet"
-#: builtin/commit.c:896
+#: builtin/commit.c:830
msgid "Error building trees"
msgstr "Fel vid byggande av träd"
-#: builtin/commit.c:911 builtin/tag.c:357
+#: builtin/commit.c:845 builtin/tag.c:361
#, c-format
msgid "Please supply the message using either -m or -F option.\n"
msgstr "Ange meddelandet en av flaggorna -m eller -F.\n"
-#: builtin/commit.c:1008
+#: builtin/commit.c:942
#, c-format
msgid "No existing author found with '%s'"
msgstr "Hittade ingen befintlig författare med \"%s\""
-#: builtin/commit.c:1023 builtin/commit.c:1217
+#: builtin/commit.c:957 builtin/commit.c:1157
#, c-format
msgid "Invalid untracked files mode '%s'"
msgstr "Ogiltigt läge för ospårade filer: \"%s\""
-#: builtin/commit.c:1063
+#: builtin/commit.c:997
msgid "Using both --reset-author and --author does not make sense"
msgstr "Kan inte använda både --reset-author och --author"
-#: builtin/commit.c:1074
+#: builtin/commit.c:1008
msgid "You have nothing to amend."
msgstr "Du har inget att utöka."
-#: builtin/commit.c:1076
-#, c-format
-msgid "You are in the middle of a %s -- cannot amend."
-msgstr "Du är i mitten av en %s -- kan inte utöka."
+#: builtin/commit.c:1011
+msgid "You are in the middle of a merge -- cannot amend."
+msgstr "Du är i mitten av en sammanslagning -- kan inte utöka."
-#: builtin/commit.c:1078
+#: builtin/commit.c:1013
+msgid "You are in the middle of a cherry-pick -- cannot amend."
+msgstr "Du är i mitten av en cherry-pick -- kan inte utöka."
+
+#: builtin/commit.c:1016
msgid "Options --squash and --fixup cannot be used together"
msgstr "Flaggorna --squash och --fixup kan inte användas samtidigt"
-#: builtin/commit.c:1088
+#: builtin/commit.c:1026
msgid "Only one of -c/-C/-F/--fixup can be used."
msgstr "Endast en av -c/-C/-F/--fixup kan användas."
-#: builtin/commit.c:1090
+#: builtin/commit.c:1028
msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
msgstr "Flaggan -m kan inte kombineras med -c/-C/-F/--fixup."
-#: builtin/commit.c:1098
+#: builtin/commit.c:1036
msgid "--reset-author can be used only with -C, -c or --amend."
msgstr "--reset-author kan endast användas med -C, -c eller --amend."
-#: builtin/commit.c:1115
+#: builtin/commit.c:1053
msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
msgstr ""
"Endast en av --include/--only/--all/--interactive/--patch kan användas."
-#: builtin/commit.c:1117
+#: builtin/commit.c:1055
msgid "No paths with --include/--only does not make sense."
msgstr "Du måste ange sökvägar tillsammans med --include/--only."
-#: builtin/commit.c:1119
+#: builtin/commit.c:1057
msgid "Clever... amending the last one with dirty index."
msgstr "Smart... utöka den senaste med smutsigt index."
-#: builtin/commit.c:1121
+#: builtin/commit.c:1059
msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
msgstr "Explicita sökvägar angavs utan -i eller -o; antar --only sökvägar..."
-#: builtin/commit.c:1131 builtin/tag.c:556
+#: builtin/commit.c:1069 builtin/tag.c:577
#, c-format
msgid "Invalid cleanup mode %s"
msgstr "Felaktigt städningsläge %s"
-#: builtin/commit.c:1136
+#: builtin/commit.c:1074
msgid "Paths with -a does not make sense."
msgstr "Kan inte ange sökvägar med -a."
-#: builtin/commit.c:1315
+#: builtin/commit.c:1257
msgid "couldn't look up newly created commit"
msgstr "kunde inte slå upp en precis skapad incheckning"
-#: builtin/commit.c:1317
+#: builtin/commit.c:1259
msgid "could not parse newly created commit"
msgstr "kunde inte tolka en precis skapad incheckning"
-#: builtin/commit.c:1358
+#: builtin/commit.c:1300
msgid "detached HEAD"
msgstr "frånkopplad HEAD"
-#: builtin/commit.c:1360
+#: builtin/commit.c:1302
msgid " (root-commit)"
msgstr " (rotincheckning)"
-#: builtin/commit.c:1450
+#: builtin/commit.c:1446
msgid "could not parse HEAD commit"
msgstr "kunde inte tolka HEAD:s incheckning"
-#: builtin/commit.c:1487 builtin/merge.c:509
+#: builtin/commit.c:1484 builtin/merge.c:509
#, c-format
msgid "could not open '%s' for reading"
msgstr "kunde inte öppna \"%s\" för läsning"
-#: builtin/commit.c:1494
+#: builtin/commit.c:1491
#, c-format
msgid "Corrupt MERGE_HEAD file (%s)"
msgstr "Trasig MERGE_HEAD-fil (%s)"
-#: builtin/commit.c:1501
+#: builtin/commit.c:1498
msgid "could not read MERGE_MODE"
msgstr "kunde inte läsa MERGE_MODE"
-#: builtin/commit.c:1520
+#: builtin/commit.c:1517
#, c-format
msgid "could not read commit message: %s"
msgstr "kunde inte läsa incheckningsmeddelande: %s"
-#: builtin/commit.c:1534
+#: builtin/commit.c:1531
#, c-format
msgid "Aborting commit; you did not edit the message.\n"
msgstr "Avbryter incheckning; meddelandet inte redigerat.\n"
-#: builtin/commit.c:1539
+#: builtin/commit.c:1536
#, c-format
msgid "Aborting commit due to empty commit message.\n"
msgstr "Avbryter på grund av tomt incheckningsmeddelande.\n"
-#: builtin/commit.c:1554 builtin/merge.c:936 builtin/merge.c:961
+#: builtin/commit.c:1551 builtin/merge.c:936 builtin/merge.c:961
msgid "failed to write commit object"
msgstr "kunde inte skriva incheckningsobjekt"
-#: builtin/commit.c:1575
+#: builtin/commit.c:1572
msgid "cannot lock HEAD ref"
msgstr "kunde inte låsa HEAD-referens"
-#: builtin/commit.c:1579
+#: builtin/commit.c:1576
msgid "cannot update HEAD ref"
msgstr "kunde inte uppdatera HEAD-referens"
-#: builtin/commit.c:1590
+#: builtin/commit.c:1587
msgid ""
"Repository has been updated, but unable to write\n"
"new_index file. Check that disk is not full or quota is\n"
msgid "Not a git repository"
msgstr "Inte ett git-arkiv"
-#: builtin/diff.c:347
+#: builtin/diff.c:341
#, c-format
msgid "invalid object '%s' given."
msgstr "objektet \"%s\" som angavs är felaktigt."
-#: builtin/diff.c:352
+#: builtin/diff.c:346
#, c-format
msgid "more than %d trees given: '%s'"
msgstr "mer än %d träd angavs: \"%s\""
-#: builtin/diff.c:362
+#: builtin/diff.c:356
#, c-format
msgid "more than two blobs given: '%s'"
msgstr "mer än två blobbar angavs: \"%s\""
-#: builtin/diff.c:370
+#: builtin/diff.c:364
#, c-format
msgid "unhandled object '%s' given."
msgstr "ej hanterat objekt \"%s\" angavs."
#: builtin/fetch.c:549
#, c-format
-msgid " (%s will become dangling)\n"
-msgstr " (%s kommer bli dinglande)\n"
+msgid " (%s will become dangling)"
+msgstr " (%s kommer bli dinglande)"
#: builtin/fetch.c:550
#, c-format
-msgid " (%s has become dangling)\n"
-msgstr " (%s har blivit dinglande)\n"
+msgid " (%s has become dangling)"
+msgstr " (%s har blivit dinglande)"
#: builtin/fetch.c:557
msgid "[deleted]"
msgstr "[borttagen]"
-#: builtin/fetch.c:558
+#: builtin/fetch.c:558 builtin/remote.c:1055
msgid "(none)"
msgstr "(ingen)"
msgid "Fetching %s\n"
msgstr "Hämtar %s\n"
-#: builtin/fetch.c:890
+#: builtin/fetch.c:890 builtin/remote.c:100
#, c-format
msgid "Could not fetch %s"
msgstr "Kunde inte hämta %s"
msgid "unable to read tree (%s)"
msgstr "kunde inte läsa träd (%s)"
-#: builtin/grep.c:526
+#: builtin/grep.c:526
+#, c-format
+msgid "unable to grep from object of type %s"
+msgstr "Kunde inte \"grep\" från objekt av typen %s"
+
+#: builtin/grep.c:584
+#, c-format
+msgid "switch `%c' expects a numerical value"
+msgstr "flaggan \"%c\" antar ett numeriskt värde"
+
+#: builtin/grep.c:601
+#, c-format
+msgid "cannot open '%s'"
+msgstr "kan inte öppna \"%s\""
+
+#: builtin/grep.c:885
+msgid "no pattern given."
+msgstr "inget mönster angavs."
+
+#: builtin/grep.c:899
+#, c-format
+msgid "bad object %s"
+msgstr "felaktigt objekt %s"
+
+#: builtin/grep.c:940
+msgid "--open-files-in-pager only works on the worktree"
+msgstr "--open-files-in-pager fungerar endast i arbetskatalogen"
+
+#: builtin/grep.c:963
+msgid "--cached or --untracked cannot be used with --no-index."
+msgstr "--cached och --untracked kan inte användas med --no-index."
+
+#: builtin/grep.c:968
+msgid "--no-index or --untracked cannot be used with revs."
+msgstr "--no-index och --untracked kan inte användas med revisioner."
+
+#: builtin/grep.c:971
+msgid "--[no-]exclude-standard cannot be used for tracked contents."
+msgstr "--[no-]exclude-standard kan inte användas för spårat innehåll."
+
+#: builtin/grep.c:979
+msgid "both --cached and trees are given."
+msgstr "både --cached och träd angavs."
+
+#: builtin/help.c:63
+#, c-format
+msgid "unrecognized help format '%s'"
+msgstr "okänt hjälpformat: %s"
+
+#: builtin/help.c:91
+msgid "Failed to start emacsclient."
+msgstr "Misslyckades starta emacsclient."
+
+#: builtin/help.c:104
+msgid "Failed to parse emacsclient version."
+msgstr "Kunde inte tolka emacsclient-version."
+
+#: builtin/help.c:112
+#, c-format
+msgid "emacsclient version '%d' too old (< 22)."
+msgstr "emacsclient version \"%d\" för gammal (< 22)."
+
+#: builtin/help.c:130 builtin/help.c:158 builtin/help.c:167 builtin/help.c:175
+#, c-format
+msgid "failed to exec '%s': %s"
+msgstr "exec misslyckades för \"%s\": %s"
+
+#: builtin/help.c:215
+#, c-format
+msgid ""
+"'%s': path for unsupported man viewer.\n"
+"Please consider using 'man.<tool>.cmd' instead."
+msgstr ""
+"\"%s\": sökväg för man-visare som ej stöds.\n"
+"Använd \"man.<verktyg>.cmd\" istället."
+
+#: builtin/help.c:227
+#, c-format
+msgid ""
+"'%s': cmd for supported man viewer.\n"
+"Please consider using 'man.<tool>.path' instead."
+msgstr ""
+"\"%s\": kommando för man-visare som stöds.\n"
+"Använd \"man.<verktyg>.path\" istället."
+
+#: builtin/help.c:291
+msgid "The most commonly used git commands are:"
+msgstr "De mest använda git-kommandona är:"
+
+#: builtin/help.c:359
+#, c-format
+msgid "'%s': unknown man viewer."
+msgstr "\"%s\": okänd man-visare."
+
+#: builtin/help.c:376
+msgid "no man viewer handled the request"
+msgstr "ingen man-visare hanterade förfrågan"
+
+#: builtin/help.c:384
+msgid "no info viewer handled the request"
+msgstr "ingen info-visare hanterade förfrågan"
+
+#: builtin/help.c:395
+#, c-format
+msgid "'%s': not a documentation directory."
+msgstr "\"%s\": inte en dokumentationskatalog."
+
+#: builtin/help.c:436 builtin/help.c:443
+#, c-format
+msgid "usage: %s%s"
+msgstr "användning: %s%s"
+
+#: builtin/help.c:459
+#, c-format
+msgid "`git %s' is aliased to `%s'"
+msgstr "\"git %s\" är ett alias för \"%s\""
+
+#: builtin/index-pack.c:170
+#, c-format
+msgid "object type mismatch at %s"
+msgstr "objekttyp stämmer inte överens vid %s"
+
+#: builtin/index-pack.c:190
+msgid "object of unexpected type"
+msgstr "objekt av oväntad typ"
+
+#: builtin/index-pack.c:227
+#, c-format
+msgid "cannot fill %d byte"
+msgid_plural "cannot fill %d bytes"
+msgstr[0] "kan inte fylla %d byte"
+msgstr[1] "kan inte fylla %d byte"
+
+#: builtin/index-pack.c:237
+msgid "early EOF"
+msgstr "tidigt filslut"
+
+#: builtin/index-pack.c:238
+msgid "read error on input"
+msgstr "indataläsfel"
+
+#: builtin/index-pack.c:250
+msgid "used more bytes than were available"
+msgstr "använde fler byte än tillgängligt"
+
+#: builtin/index-pack.c:257
+msgid "pack too large for current definition of off_t"
+msgstr "paket för stort för nuvarande definition av off_t"
+
+#: builtin/index-pack.c:273
+#, c-format
+msgid "unable to create '%s'"
+msgstr "kunde inte skapa \"%s\""
+
+#: builtin/index-pack.c:278
+#, c-format
+msgid "cannot open packfile '%s'"
+msgstr "kan inte öppna paketfilen \"%s\""
+
+#: builtin/index-pack.c:292
+msgid "pack signature mismatch"
+msgstr "paketsignatur stämmer inte överens"
+
+#: builtin/index-pack.c:312
+#, c-format
+msgid "pack has bad object at offset %lu: %s"
+msgstr "paketet har felaktigt objekt vid index %lu: %s"
+
+#: builtin/index-pack.c:434
+#, c-format
+msgid "inflate returned %d"
+msgstr "inflate returnerade %d"
+
+#: builtin/index-pack.c:483
+msgid "offset value overflow for delta base object"
+msgstr "indexvärdespill för deltabasobjekt"
+
+#: builtin/index-pack.c:491
+msgid "delta base offset is out of bound"
+msgstr "deltabasindex utanför gränsen"
+
+#: builtin/index-pack.c:499
+#, c-format
+msgid "unknown object type %d"
+msgstr "okänd objekttyp %d"
+
+#: builtin/index-pack.c:531
+msgid "cannot pread pack file"
+msgstr "kan inte utföra \"pread\" på paketfil"
+
+#: builtin/index-pack.c:533
+#, c-format
+msgid "premature end of pack file, %lu byte missing"
+msgid_plural "premature end of pack file, %lu bytes missing"
+msgstr[0] "för tidigt slut på paketfilen, %lu byte saknas"
+msgstr[1] "för tidigt slut på paketfilen, %lu byte saknas"
+
+#: builtin/index-pack.c:555
+msgid "serious inflate inconsistency"
+msgstr "allvarlig inflate-inkonsekvens"
+
+#: builtin/index-pack.c:646 builtin/index-pack.c:652 builtin/index-pack.c:675
+#: builtin/index-pack.c:709 builtin/index-pack.c:718
+#, c-format
+msgid "SHA1 COLLISION FOUND WITH %s !"
+msgstr "SHA1-KOLLISION UPPTÄCKT VID %s !"
+
+#: builtin/index-pack.c:649 builtin/pack-objects.c:170
+#: builtin/pack-objects.c:262
+#, c-format
+msgid "unable to read %s"
+msgstr "kunde inte läsa %s"
+
+#: builtin/index-pack.c:715
+#, c-format
+msgid "cannot read existing object %s"
+msgstr "kan inte läsa befintligt objekt %s"
+
+#: builtin/index-pack.c:729
+#, c-format
+msgid "invalid blob object %s"
+msgstr "ogiltigt blob-objekt %s"
+
+#: builtin/index-pack.c:744
+#, c-format
+msgid "invalid %s"
+msgstr "ogiltigt %s"
+
+#: builtin/index-pack.c:746
+msgid "Error in object"
+msgstr "Fel i objekt"
+
+#: builtin/index-pack.c:748
+#, c-format
+msgid "Not all child objects of %s are reachable"
+msgstr "Inte alla barnobjekt för %s kan nås"
+
+#: builtin/index-pack.c:818 builtin/index-pack.c:844
+msgid "failed to apply delta"
+msgstr "misslyckades tillämpa delta"
+
+#: builtin/index-pack.c:983
+msgid "Receiving objects"
+msgstr "Tar bort objeckt"
+
+#: builtin/index-pack.c:983
+msgid "Indexing objects"
+msgstr "Skapar index för objekt"
+
+#: builtin/index-pack.c:1009
+msgid "pack is corrupted (SHA1 mismatch)"
+msgstr "paketet är trasigt (SHA1 stämmer inte)"
+
+#: builtin/index-pack.c:1014
+msgid "cannot fstat packfile"
+msgstr "kan inte utföra \"fstat\" på paketfil"
+
+#: builtin/index-pack.c:1017
+msgid "pack has junk at the end"
+msgstr "paket har skräp i slutet"
+
+#: builtin/index-pack.c:1028
+msgid "confusion beyond insanity in parse_pack_objects()"
+msgstr "förvirrad bortom vanvett i parse_pack_objects()"
+
+#: builtin/index-pack.c:1051
+msgid "Resolving deltas"
+msgstr "Analyserar delta"
+
+#: builtin/index-pack.c:1102
+msgid "confusion beyond insanity"
+msgstr "förvirrad bortom vanvett"
+
+#: builtin/index-pack.c:1121
+#, c-format
+msgid "pack has %d unresolved delta"
+msgid_plural "pack has %d unresolved deltas"
+msgstr[0] "paketet har %d oanalyserat delta"
+msgstr[1] "paketet har %d oanalyserade delta"
+
+#: builtin/index-pack.c:1146
+#, c-format
+msgid "unable to deflate appended object (%d)"
+msgstr "kunde inte utföra \"deflate\" på tillagt objekt (%d)"
+
+#: builtin/index-pack.c:1225
+#, c-format
+msgid "local object %s is corrupt"
+msgstr "lokalt objekt %s är trasigt"
+
+#: builtin/index-pack.c:1249
+msgid "error while closing pack file"
+msgstr "fel vid stängning av paketfil"
+
+#: builtin/index-pack.c:1262
+#, c-format
+msgid "cannot write keep file '%s'"
+msgstr "kan inte ta skriva \"keep\"-fil \"%s\""
+
+#: builtin/index-pack.c:1270
#, c-format
-msgid "unable to grep from object of type %s"
-msgstr "Kunde inte \"grep\" från objekt av typen %s"
+msgid "cannot close written keep file '%s'"
+msgstr "akn inte stänga skriven \"keep\"-fil \"%s\""
-#: builtin/grep.c:584
+#: builtin/index-pack.c:1283
+msgid "cannot store pack file"
+msgstr "kan inte spara paketfil"
+
+#: builtin/index-pack.c:1294
+msgid "cannot store index file"
+msgstr "kan inte spara indexfil"
+
+#: builtin/index-pack.c:1395
#, c-format
-msgid "switch `%c' expects a numerical value"
-msgstr "flaggan \"%c\" antar ett numeriskt värde"
+msgid "Cannot open existing pack file '%s'"
+msgstr "Kan inte öppna befintlig paketfil \"%s\""
-#: builtin/grep.c:601
+#: builtin/index-pack.c:1397
#, c-format
-msgid "cannot open '%s'"
-msgstr "kan inte öppna \"%s\""
+msgid "Cannot open existing pack idx file for '%s'"
+msgstr "Kan inte öppna befintligt paket-idx-fil för \"%s\""
-#: builtin/grep.c:888
-msgid "no pattern given."
-msgstr "inget mönster angavs."
+#: builtin/index-pack.c:1444
+#, c-format
+msgid "non delta: %d object"
+msgid_plural "non delta: %d objects"
+msgstr[0] "icke-delta: %d objekt"
+msgstr[1] "icke-delta: %d objekt"
-#: builtin/grep.c:902
+#: builtin/index-pack.c:1451
#, c-format
-msgid "bad object %s"
-msgstr "felaktigt objekt %s"
+msgid "chain length = %d: %lu object"
+msgid_plural "chain length = %d: %lu objects"
+msgstr[0] "kedjelängd = %d: %lu objekt"
+msgstr[1] "kedjelängd = %d: %lu objekt"
-#: builtin/grep.c:943
-msgid "--open-files-in-pager only works on the worktree"
-msgstr "--open-files-in-pager fungerar endast i arbetskatalogen"
+#: builtin/index-pack.c:1478
+msgid "Cannot come back to cwd"
+msgstr "Kan inte gå tillbaka till arbetskatalogen (cwd)"
-#: builtin/grep.c:966
-msgid "--cached or --untracked cannot be used with --no-index."
-msgstr "--cached och --untracked kan inte användas med --no-index."
+#: builtin/index-pack.c:1522 builtin/index-pack.c:1525
+#: builtin/index-pack.c:1537 builtin/index-pack.c:1541
+#, c-format
+msgid "bad %s"
+msgstr "felaktig %s"
-#: builtin/grep.c:971
-msgid "--no-index or --untracked cannot be used with revs."
-msgstr "--no-index och --untracked kan inte användas med revisioner."
+#: builtin/index-pack.c:1555
+msgid "--fix-thin cannot be used without --stdin"
+msgstr "--fix-thin kan inte användas med --stdin"
-#: builtin/grep.c:974
-msgid "--[no-]exclude-standard cannot be used for tracked contents."
-msgstr "--[no-]exclude-standard kan inte användas för spårat innehåll."
+#: builtin/index-pack.c:1559 builtin/index-pack.c:1569
+#, c-format
+msgid "packfile name '%s' does not end with '.pack'"
+msgstr "paketfilnamnet \"%s\" slutar inte med \".pack\""
-#: builtin/grep.c:982
-msgid "both --cached and trees are given."
-msgstr "både --cached och träd angavs."
+#: builtin/index-pack.c:1578
+msgid "--verify with no packfile name given"
+msgstr "--verify angavs utan paketfilnamn"
#: builtin/init-db.c:35
#, c-format
msgid "Cannot access work tree '%s'"
msgstr "Kan inte komma åt arbetskatalogen \"%s\""
-#: builtin/log.c:187
+#: builtin/log.c:189
#, c-format
msgid "Final output: %d %s\n"
msgstr "Slututdata: %d %s\n"
-#: builtin/log.c:395 builtin/log.c:483
+#: builtin/log.c:402 builtin/log.c:490
#, c-format
msgid "Could not read object %s"
msgstr "Kunde inte läsa objektet %s"
-#: builtin/log.c:507
+#: builtin/log.c:514
#, c-format
msgid "Unknown type: %d"
msgstr "Okänd typ: %d"
-#: builtin/log.c:596
+#: builtin/log.c:603
msgid "format.headers without value"
msgstr "format.headers utan värde"
-#: builtin/log.c:669
+#: builtin/log.c:677
msgid "name of output directory is too long"
msgstr "namnet på utdatakatalogen är för långt"
-#: builtin/log.c:680
+#: builtin/log.c:688
#, c-format
msgid "Cannot open patch file %s"
msgstr "Kan inte öppna patchfilen %s"
-#: builtin/log.c:694
+#: builtin/log.c:702
msgid "Need exactly one range."
msgstr "Behöver precis ett intervall."
-#: builtin/log.c:702
+#: builtin/log.c:710
msgid "Not a range."
msgstr "Inte ett intervall."
-#: builtin/log.c:739
-msgid "Could not extract email from committer identity."
-msgstr "Kunde inte extrahera e-postadress från incheckarens identitet."
-
-#: builtin/log.c:785
+#: builtin/log.c:787
msgid "Cover letter needs email format"
msgstr "Omslagsbrevet behöver e-postformat"
-#: builtin/log.c:879
+#: builtin/log.c:860
#, c-format
msgid "insane in-reply-to: %s"
msgstr "tokigt in-reply-to: %s"
-#: builtin/log.c:952
+#: builtin/log.c:933
msgid "Two output directories?"
msgstr "Två utdatakataloger?"
-#: builtin/log.c:1173
+#: builtin/log.c:1154
#, c-format
msgid "bogus committer info %s"
msgstr "felaktig incheckarinformation %s"
-#: builtin/log.c:1218
+#: builtin/log.c:1199
msgid "-n and -k are mutually exclusive."
msgstr "-n och -k kan inte användas samtidigt."
-#: builtin/log.c:1220
+#: builtin/log.c:1201
msgid "--subject-prefix and -k are mutually exclusive."
msgstr "--subject-prefix och -k kan inte användas samtidigt."
-#: builtin/log.c:1225 builtin/shortlog.c:284
-#, c-format
-msgid "unrecognized argument: %s"
-msgstr "okänt argument: %s"
-
-#: builtin/log.c:1228
+#: builtin/log.c:1209
msgid "--name-only does not make sense"
msgstr "kan inte använda --name-only"
-#: builtin/log.c:1230
+#: builtin/log.c:1211
msgid "--name-status does not make sense"
msgstr "kan inte använda --name-status"
-#: builtin/log.c:1232
+#: builtin/log.c:1213
msgid "--check does not make sense"
msgstr "kan inte använda --check"
-#: builtin/log.c:1255
+#: builtin/log.c:1236
msgid "standard output, or directory, which one?"
msgstr "standard ut, eller katalog, vilken skall det vara?"
-#: builtin/log.c:1257
+#: builtin/log.c:1238
#, c-format
msgid "Could not create directory '%s'"
msgstr "Kunde inte skapa katalogen \"%s\""
-#: builtin/log.c:1410
+#: builtin/log.c:1391
msgid "Failed to create output files"
msgstr "Misslyckades skapa utdatafiler"
-#: builtin/log.c:1514
+#: builtin/log.c:1495
#, c-format
msgid ""
"Could not find a tracked remote branch, please specify <upstream> manually.\n"
msgstr "Kunde inte hitta en spårad fjärrgren, ange <uppström> manuellt.\n"
-#: builtin/log.c:1530 builtin/log.c:1532 builtin/log.c:1544
+#: builtin/log.c:1511 builtin/log.c:1513 builtin/log.c:1525
#, c-format
msgid "Unknown commit %s"
msgstr "Okänd incheckning %s"
msgid "Renaming %s to %s\n"
msgstr "Byter namn på %s till %s\n"
-#: builtin/mv.c:215
+#: builtin/mv.c:215 builtin/remote.c:731
#, c-format
msgid "renaming '%s' failed"
msgstr "misslyckades byta namn på \"%s\""
msgid "failed to finish 'show' for object '%s'"
msgstr "kunde inte avsluta \"show\" för objektet \"%s\""
-#: builtin/notes.c:175 builtin/tag.c:343
+#: builtin/notes.c:175 builtin/tag.c:347
#, c-format
msgid "could not create file '%s'"
msgstr "kunde inte skapa filen \"%s\""
msgid "The note contents has been left in %s"
msgstr "Anteckningens innehåll har lämnats kvar i %s"
-#: builtin/notes.c:251 builtin/tag.c:521
+#: builtin/notes.c:251 builtin/tag.c:542
#, c-format
msgid "cannot read '%s'"
msgstr "kunde inte läsa \"%s\""
-#: builtin/notes.c:253 builtin/tag.c:524
+#: builtin/notes.c:253 builtin/tag.c:545
#, c-format
msgid "could not open or read '%s'"
msgstr "kunde inte öppna eller läsa \"%s\""
#: builtin/notes.c:272 builtin/notes.c:445 builtin/notes.c:447
#: builtin/notes.c:507 builtin/notes.c:561 builtin/notes.c:644
#: builtin/notes.c:649 builtin/notes.c:724 builtin/notes.c:766
-#: builtin/notes.c:968 builtin/reset.c:293 builtin/tag.c:537
+#: builtin/notes.c:968 builtin/reset.c:293 builtin/tag.c:558
#, c-format
msgid "Failed to resolve '%s' as a valid ref."
msgstr "Kunde inte slå upp \"%s\" som en giltig referens."
msgid "Object %s has no note\n"
msgstr "Objektet %s har ingen anteckning\n"
-#: builtin/notes.c:1103
+#: builtin/notes.c:1103 builtin/remote.c:1598
#, c-format
msgid "Unknown subcommand: %s"
msgstr "Okänt underkommando: %s"
-#: builtin/pack-objects.c:2315
+#: builtin/pack-objects.c:183 builtin/pack-objects.c:186
+#, c-format
+msgid "deflate error (%d)"
+msgstr "fel i deflate (%d)"
+
+#: builtin/pack-objects.c:2398
#, c-format
msgid "unsupported index version %s"
msgstr "indexversionen %s stöds ej"
-#: builtin/pack-objects.c:2319
+#: builtin/pack-objects.c:2402
#, c-format
msgid "bad index version '%s'"
msgstr "felaktig indexversion \"%s\""
-#: builtin/pack-objects.c:2342
+#: builtin/pack-objects.c:2425
#, c-format
msgid "option %s does not accept negative form"
msgstr "flaggan %s godtar inte negativ form"
-#: builtin/pack-objects.c:2346
+#: builtin/pack-objects.c:2429
#, c-format
msgid "unable to parse value '%s' for option %s"
msgstr "kunde inte tolka värdet \"%s\" för flaggan %s"
msgid "--delete only accepts plain target ref names"
msgstr "--delete godtar endast enkla målreferensnamn"
-#: builtin/push.c:84
+#: builtin/push.c:99
+msgid ""
+"\n"
+"To choose either option permanently, see push.default in 'git help config'."
+msgstr ""
+"\n"
+"För att välja ett av alternativen permanent, se push.default i \"git help "
+"config\"."
+
+#: builtin/push.c:102
+#, c-format
+msgid ""
+"The upstream branch of your current branch does not match\n"
+"the name of your current branch. To push to the upstream branch\n"
+"on the remote, use\n"
+"\n"
+" git push %s HEAD:%s\n"
+"\n"
+"To push to the branch of the same name on the remote, use\n"
+"\n"
+" git push %s %s\n"
+"%s"
+msgstr ""
+"Uppströmsgrenen för din nuvarande gren stämmer inte överens\n"
+"med namnet på din aktuella gren. För att sända till uppströmsgrenen\n"
+"i fjärrarkivet använder du\n"
+"\n"
+" git push %s HEAD:%s\n"
+"\n"
+"För att sända till grenen med samma namn i fjärrarkivet använder du\n"
+"\n"
+" git push %s %s\n"
+"%s"
+
+#: builtin/push.c:121
#, c-format
msgid ""
"You are not currently on a branch.\n"
"\n"
" git push %s HEAD:<namn-på-fjärrgren>\n"
-#: builtin/push.c:91
+#: builtin/push.c:128
+#, c-format
+msgid ""
+"The current branch %s has no upstream branch.\n"
+"To push the current branch and set the remote as upstream, use\n"
+"\n"
+" git push --set-upstream %s %s\n"
+msgstr ""
+"Den aktuella grenen %s har ingen uppströmsgren.\n"
+"För att sända aktuell gren och ange fjärrarkiv som uppström använder du\n"
+"\n"
+" git push --set-upstream %s %s\n"
+
+#: builtin/push.c:136
+#, c-format
+msgid "The current branch %s has multiple upstream branches, refusing to push."
+msgstr "Den aktuella grenen %s har flera uppströmsgrenar, vägrar sända."
+
+#: builtin/push.c:139
+#, c-format
+msgid ""
+"You are pushing to remote '%s', which is not the upstream of\n"
+"your current branch '%s', without telling me what to push\n"
+"to update which remote branch."
+msgstr ""
+"Du sänder till fjärren \"%s\", som inte är uppströms för den\n"
+"aktuella grenen \"%s\", utan att tala om för mig vad som\n"
+"skall sändas för att uppdatera fjärrgrenen."
+
+#: builtin/push.c:174
+msgid ""
+"You didn't specify any refspecs to push, and push.default is \"nothing\"."
+msgstr ""
+"Du angav inga referensspecifikationer att sända, och push.default är "
+"\"nothing\"."
+
+#: builtin/push.c:181
+msgid ""
+"Updates were rejected because the tip of your current branch is behind\n"
+"its remote counterpart. Merge the remote changes (e.g. 'git pull')\n"
+"before pushing again.\n"
+"See the 'Note about fast-forwards' in 'git push --help' for details."
+msgstr ""
+"Uppdateringar avvisades då änden på din befintliga gren är bakom\n"
+"dess fjärrmotsvarighet. Slå ihop fjärrändringarna (t.ex. \"git pull\")\n"
+"innan du sänder igen.\n"
+"Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer."
+
+#: builtin/push.c:187
+msgid ""
+"Updates were rejected because a pushed branch tip is behind its remote\n"
+"counterpart. If you did not intend to push that branch, you may want to\n"
+"specify branches to push or set the 'push.default' configuration\n"
+"variable to 'current' or 'upstream' to push only the current branch."
+msgstr ""
+"Uppdateringar avvisades då änden på en insänd gren är bakom dess\n"
+"fjärrmotsvarighet. Om det inte var meningen att sända in grenen, bör\n"
+"du specificera grenar att sända, eller ändra inställningsvariabeln\n"
+"\"push-default\" till \"current\" eller \"upstream\" för att endast sända\n"
+"aktuell gren."
+
+#: builtin/push.c:193
+msgid ""
+"Updates were rejected because a pushed branch tip is behind its remote\n"
+"counterpart. Check out this branch and merge the remote changes\n"
+"(e.g. 'git pull') before pushing again.\n"
+"See the 'Note about fast-forwards' in 'git push --help' for details."
+msgstr ""
+"Uppdateringar avvisades då änden på en gren som sänds in är bakom dess\n"
+"fjärrmotsvarighet. Checka ut grenen och slå ihop fjärrändringarna (t.ex.\n"
+"\"git pull\") innan du sänder igen.\n"
+"Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer."
+
+#: builtin/push.c:233
+#, c-format
+msgid "Pushing to %s\n"
+msgstr "Sänder till %s\n"
+
+#: builtin/push.c:237
+#, c-format
+msgid "failed to push some refs to '%s'"
+msgstr "misslyckades sända vissa referenser till \"%s\""
+
+#: builtin/push.c:269
+#, c-format
+msgid "bad repository '%s'"
+msgstr "felaktigt arkiv \"%s\""
+
+#: builtin/push.c:270
+msgid ""
+"No configured push destination.\n"
+"Either specify the URL from the command-line or configure a remote "
+"repository using\n"
+"\n"
+" git remote add <name> <url>\n"
+"\n"
+"and then push using the remote name\n"
+"\n"
+" git push <name>\n"
+msgstr ""
+"Ingen destination har angivits.\n"
+"Ange antingen URL:en på kommandoraden eller ställ in ett uppströmsarkiv med\n"
+"\n"
+" git remote add <namn> <url>\n"
+"\n"
+"och sänd sedan med hjälp av fjärrnamnet\n"
+"\n"
+" git push <namn>\n"
+
+#: builtin/push.c:285
+msgid "--all and --tags are incompatible"
+msgstr "--all och --tags är inkompatibla"
+
+#: builtin/push.c:286
+msgid "--all can't be combined with refspecs"
+msgstr "--all kan inte kombineras med referensspecifikationer"
+
+#: builtin/push.c:291
+msgid "--mirror and --tags are incompatible"
+msgstr "--mirror och --tags är inkompatibla"
+
+#: builtin/push.c:292
+msgid "--mirror can't be combined with refspecs"
+msgstr "--mirror kan inte kombineras med referensspecifikationer"
+
+#: builtin/push.c:297
+msgid "--all and --mirror are incompatible"
+msgstr "--all och --mirror är inkompatibla"
+
+#: builtin/push.c:385
+msgid "--delete is incompatible with --all, --mirror and --tags"
+msgstr "--delete är imkompatibel med --all, --mirror och --tags"
+
+#: builtin/push.c:387
+msgid "--delete doesn't make sense without any refs"
+msgstr "--delete kan inte användas utan referenser"
+
+#: builtin/remote.c:98
+#, c-format
+msgid "Updating %s"
+msgstr "Uppdaterar %s"
+
+#: builtin/remote.c:130
+msgid ""
+"--mirror is dangerous and deprecated; please\n"
+"\t use --mirror=fetch or --mirror=push instead"
+msgstr ""
+"--mirror är farlig och föråldrad; använd\n"
+"\t --mirror=fetch eller --mirror=push istället"
+
+#: builtin/remote.c:147
+#, c-format
+msgid "unknown mirror argument: %s"
+msgstr "okänt argument till mirror: %s"
+
+#: builtin/remote.c:185
+msgid "specifying a master branch makes no sense with --mirror"
+msgstr "att ange en master-gren ger ingen mening med --mirror"
+
+#: builtin/remote.c:187
+msgid "specifying branches to track makes sense only with fetch mirrors"
+msgstr "att ange grenar att spåra ger mening bara med hämtningsspeglar"
+
+#: builtin/remote.c:195 builtin/remote.c:646
+#, c-format
+msgid "remote %s already exists."
+msgstr "fjärrarkivet %s finns redan."
+
+#: builtin/remote.c:199 builtin/remote.c:650
+#, c-format
+msgid "'%s' is not a valid remote name"
+msgstr "\"%s\" är inte ett giltigt namn på fjärrarkiv"
+
+#: builtin/remote.c:243
+#, c-format
+msgid "Could not setup master '%s'"
+msgstr "Kunde inte skapa master \"%s\""
+
+#: builtin/remote.c:299
+#, c-format
+msgid "more than one %s"
+msgstr "mer än en %s"
+
+#: builtin/remote.c:339
+#, c-format
+msgid "Could not get fetch map for refspec %s"
+msgstr "Kunde inte hämta mappning för referensspecifikation %s"
+
+#: builtin/remote.c:440 builtin/remote.c:448
+msgid "(matching)"
+msgstr "(matchande)"
+
+#: builtin/remote.c:452
+msgid "(delete)"
+msgstr "(ta bort)"
+
+#: builtin/remote.c:595 builtin/remote.c:601 builtin/remote.c:607
+#, c-format
+msgid "Could not append '%s' to '%s'"
+msgstr "Kunde inte tillämpa \"%s\" på \"%s\""
+
+#: builtin/remote.c:639 builtin/remote.c:792 builtin/remote.c:890
+#, c-format
+msgid "No such remote: %s"
+msgstr "Inget sådant fjärrarkiv: %s"
+
+#: builtin/remote.c:656
+#, c-format
+msgid "Could not rename config section '%s' to '%s'"
+msgstr "Kunde inte byta namn på konfigurationssektionen \"%s\" till \"%s\""
+
+#: builtin/remote.c:662 builtin/remote.c:799
+#, c-format
+msgid "Could not remove config section '%s'"
+msgstr "Kunde inte ta bort konfigurationssektionen \"%s\""
+
+#: builtin/remote.c:677
+#, c-format
+msgid ""
+"Not updating non-default fetch refspec\n"
+"\t%s\n"
+"\tPlease update the configuration manually if necessary."
+msgstr ""
+"Uppdaterar inte icke-standard hämtningsreferensspecifikation\n"
+"\t%s\n"
+"\tUppdatera konfigurationen manuellt om nödvändigt."
+
+#: builtin/remote.c:683
+#, c-format
+msgid "Could not append '%s'"
+msgstr "Kunde inte lägga till på \"%s\""
+
+#: builtin/remote.c:694
+#, c-format
+msgid "Could not set '%s'"
+msgstr "Kunde inte sätta \"%s\""
+
+#: builtin/remote.c:716
+#, c-format
+msgid "deleting '%s' failed"
+msgstr "misslyckades ta bort \"%s\""
+
+#: builtin/remote.c:750
+#, c-format
+msgid "creating '%s' failed"
+msgstr "misslyckades skapa \"%s\""
+
+#: builtin/remote.c:764
+#, c-format
+msgid "Could not remove branch %s"
+msgstr "Kunde inte ta bort grenen %s"
+
+#: builtin/remote.c:834
+msgid ""
+"Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
+"to delete it, use:"
+msgid_plural ""
+"Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n"
+"to delete them, use:"
+msgstr[0] ""
+"Observera: En gren utanför hierarkin refs/remotes/ togs inte bort;\n"
+"för att ta bort den, använd:"
+msgstr[1] ""
+"Observera: Några grenar utanför hierarkin refs/remotes/ togs inte bort;\n"
+"för att ta bort dem, använd:"
+
+#: builtin/remote.c:943
+#, c-format
+msgid " new (next fetch will store in remotes/%s)"
+msgstr " ny (nästa hämtning sparar i remotes/%s)"
+
+#: builtin/remote.c:946
+msgid " tracked"
+msgstr " spårad"
+
+#: builtin/remote.c:948
+msgid " stale (use 'git remote prune' to remove)"
+msgstr " förlegad (använd \"git remote prune\" för att ta bort)"
+
+#: builtin/remote.c:950
+msgid " ???"
+msgstr " ???"
+
+#: builtin/remote.c:991
+#, c-format
+msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
+msgstr "ogiltig branch.%s.merge; kan inte ombasera över > 1 gren"
+
+#: builtin/remote.c:998
+#, c-format
+msgid "rebases onto remote %s"
+msgstr "ombaseras på fjärren %s"
+
+#: builtin/remote.c:1001
+#, c-format
+msgid " merges with remote %s"
+msgstr " sammanslås med fjärren %s"
+
+#: builtin/remote.c:1002
+msgid " and with remote"
+msgstr " och med fjärren"
+
+#: builtin/remote.c:1004
+#, c-format
+msgid "merges with remote %s"
+msgstr "sammanslås med fjärren %s"
+
+#: builtin/remote.c:1005
+msgid " and with remote"
+msgstr " och med fjärren"
+
+#: builtin/remote.c:1051
+msgid "create"
+msgstr "skapa"
+
+#: builtin/remote.c:1054
+msgid "delete"
+msgstr "ta bort"
+
+#: builtin/remote.c:1058
+msgid "up to date"
+msgstr "àjour"
+
+#: builtin/remote.c:1061
+msgid "fast-forwardable"
+msgstr "kan snabbspolas"
+
+#: builtin/remote.c:1064
+msgid "local out of date"
+msgstr "lokal föråldrad"
+
+#: builtin/remote.c:1071
+#, c-format
+msgid " %-*s forces to %-*s (%s)"
+msgstr " %-*s tvingar till %-*s (%s)"
+
+#: builtin/remote.c:1074
+#, c-format
+msgid " %-*s pushes to %-*s (%s)"
+msgstr " %-*s sänder till %-*s (%s)"
+
+#: builtin/remote.c:1078
+#, c-format
+msgid " %-*s forces to %s"
+msgstr " %-*s tvingar till %s"
+
+#: builtin/remote.c:1081
+#, c-format
+msgid " %-*s pushes to %s"
+msgstr " %-*s sänder till %s"
+
+#: builtin/remote.c:1118
+#, c-format
+msgid "* remote %s"
+msgstr "* fjärr %s"
+
+#: builtin/remote.c:1119
#, c-format
-msgid ""
-"The current branch %s has no upstream branch.\n"
-"To push the current branch and set the remote as upstream, use\n"
-"\n"
-" git push --set-upstream %s %s\n"
-msgstr ""
-"Den aktuella grenen %s har ingen uppströmsgren.\n"
-"För att sända aktuell gren och ange fjärrarkiv som uppström använder du\n"
-"\n"
-" git push --set-upstream %s %s\n"
+msgid " Fetch URL: %s"
+msgstr " Hämt-URL: %s"
-#: builtin/push.c:99
+#: builtin/remote.c:1120 builtin/remote.c:1285
+msgid "(no URL)"
+msgstr "(ingen URL)"
+
+#: builtin/remote.c:1129 builtin/remote.c:1131
#, c-format
-msgid "The current branch %s has multiple upstream branches, refusing to push."
-msgstr "Den aktuella grenen %s har flera uppströmsgrenar, vägrar sända."
+msgid " Push URL: %s"
+msgstr " Sänd-URL: %s"
-#: builtin/push.c:102
+#: builtin/remote.c:1133 builtin/remote.c:1135 builtin/remote.c:1137
#, c-format
-msgid ""
-"You are pushing to remote '%s', which is not the upstream of\n"
-"your current branch '%s', without telling me what to push\n"
-"to update which remote branch."
-msgstr ""
-"Du sänder till fjärren \"%s\", som inte är uppströms för den\n"
-"aktuella grenen \"%s\", utan att tala om för mig vad som\n"
-"skall sändas för att uppdatera fjärrgrenen."
+msgid " HEAD branch: %s"
+msgstr " HEAD-gren: %s"
-#: builtin/push.c:131
+#: builtin/remote.c:1139
+#, c-format
msgid ""
-"You didn't specify any refspecs to push, and push.default is \"nothing\"."
-msgstr ""
-"Du angav inga referensspecifikationer att sända, och push.default är "
-"\"nothing\"."
+" HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
+msgstr " HEAD-gren (HEAD på fjärr är tvetydig, kan vara en av följande):\n"
-#: builtin/push.c:138
-msgid ""
-"Updates were rejected because the tip of your current branch is behind\n"
-"its remote counterpart. Merge the remote changes (e.g. 'git pull')\n"
-"before pushing again.\n"
-"See the 'Note about fast-forwards' in 'git push --help' for details."
-msgstr ""
-"Uppdateringar avvisades då änden på din befintliga gren är bakom\n"
-"dess fjärrmotsvarighet. Slå ihop fjärrändringarna (t.ex. \"git pull\")\n"
-"innan du sänder igen.\n"
-"Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer."
+#: builtin/remote.c:1151
+#, c-format
+msgid " Remote branch:%s"
+msgid_plural " Remote branches:%s"
+msgstr[0] " Fjärrgren:%s"
+msgstr[1] " Fjärrgrenar:%s"
-#: builtin/push.c:144
-msgid ""
-"Updates were rejected because a pushed branch tip is behind its remote\n"
-"counterpart. If you did not intend to push that branch, you may want to\n"
-"specify branches to push or set the 'push.default' configuration\n"
-"variable to 'current' or 'upstream' to push only the current branch."
-msgstr ""
-"Uppdateringar avvisades då änden på en insänd gren är bakom dess\n"
-"fjärrmotsvarighet. Om det inte var meningen att sända in grenen, bör\n"
-"du specificera grenar att sända, eller ändra inställningsvariabeln\n"
-"\"push-default\" till \"current\" eller \"upstream\" för att endast sända\n"
-"aktuell gren."
+#: builtin/remote.c:1154 builtin/remote.c:1181
+msgid " (status not queried)"
+msgstr " (status inte förfrågad)"
-#: builtin/push.c:150
-msgid ""
-"Updates were rejected because a pushed branch tip is behind its remote\n"
-"counterpart. Check out this branch and merge the remote changes\n"
-"(e.g. 'git pull') before pushing again.\n"
-"See the 'Note about fast-forwards' in 'git push --help' for details."
-msgstr ""
-"Uppdateringar avvisades då änden på en gren som sänds in är bakom dess\n"
-"fjärrmotsvarighet. Checka ut grenen och slå ihop fjärrändringarna (t.ex.\n"
-"\"git pull\") innan du sänder igen.\n"
-"Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer."
+#: builtin/remote.c:1163
+msgid " Local branch configured for 'git pull':"
+msgid_plural " Local branches configured for 'git pull':"
+msgstr[0] " Lokal gren konfigurerad för \"git pull\":"
+msgstr[1] " Lokala grenar konfigurerade för \"git pull\":"
-#: builtin/push.c:190
+#: builtin/remote.c:1171
+msgid " Local refs will be mirrored by 'git push'"
+msgstr " Lokala referenser speglas av \"git push\""
+
+#: builtin/remote.c:1178
#, c-format
-msgid "Pushing to %s\n"
-msgstr "Sänder till %s\n"
+msgid " Local ref configured for 'git push'%s:"
+msgid_plural " Local refs configured for 'git push'%s:"
+msgstr[0] " Lokal referens konfigurerad för \"git push\"%s:"
+msgstr[1] " Lokala referenser konfigurerade för \"git push\"%s:"
+
+#: builtin/remote.c:1216
+msgid "Cannot determine remote HEAD"
+msgstr "Kan inte bestämma HEAD på fjärren"
-#: builtin/push.c:194
+#: builtin/remote.c:1218
+msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
+msgstr "Flera HEAD-grenar på fjärren. Välj en explicit med:"
+
+#: builtin/remote.c:1228
#, c-format
-msgid "failed to push some refs to '%s'"
-msgstr "misslyckades sända vissa referenser till \"%s\""
+msgid "Could not delete %s"
+msgstr "Kunde inte ta bort %s"
-#: builtin/push.c:226
+#: builtin/remote.c:1236
#, c-format
-msgid "bad repository '%s'"
-msgstr "felaktigt arkiv \"%s\""
+msgid "Not a valid ref: %s"
+msgstr "Inte en giltig referens: %s"
-#: builtin/push.c:227
-msgid ""
-"No configured push destination.\n"
-"Either specify the URL from the command-line or configure a remote "
-"repository using\n"
-"\n"
-" git remote add <name> <url>\n"
-"\n"
-"and then push using the remote name\n"
-"\n"
-" git push <name>\n"
-msgstr ""
-"Ingen destination har angivits.\n"
-"Ange antingen URL:en på kommandoraden eller ställ in ett uppströmsarkiv med\n"
-"\n"
-" git remote add <namn> <url>\n"
-"\n"
-"och sänd sedan med hjälp av fjärrnamnet\n"
-"\n"
-" git push <namn>\n"
+#: builtin/remote.c:1238
+#, c-format
+msgid "Could not setup %s"
+msgstr "Kunde inte ställa in %s"
-#: builtin/push.c:242
-msgid "--all and --tags are incompatible"
-msgstr "--all och --tags är inkompatibla"
+#: builtin/remote.c:1274
+#, c-format
+msgid " %s will become dangling!"
+msgstr " %s kommer bli dinglande!"
-#: builtin/push.c:243
-msgid "--all can't be combined with refspecs"
-msgstr "--all kan inte kombineras med referensspecifikationer"
+#: builtin/remote.c:1275
+#, c-format
+msgid " %s has become dangling!"
+msgstr " %s har blivit dinglande!"
-#: builtin/push.c:248
-msgid "--mirror and --tags are incompatible"
-msgstr "--mirror och --tags är inkompatibla"
+#: builtin/remote.c:1281
+#, c-format
+msgid "Pruning %s"
+msgstr "Rensar %s"
-#: builtin/push.c:249
-msgid "--mirror can't be combined with refspecs"
-msgstr "--mirror kan inte kombineras med referensspecifikationer"
+#: builtin/remote.c:1282
+#, c-format
+msgid "URL: %s"
+msgstr "URL: %s"
-#: builtin/push.c:254
-msgid "--all and --mirror are incompatible"
-msgstr "--all och --mirror är inkompatibla"
+#: builtin/remote.c:1295
+#, c-format
+msgid " * [would prune] %s"
+msgstr " * [skulle rensa] %s"
-#: builtin/push.c:334
-msgid "--delete is incompatible with --all, --mirror and --tags"
-msgstr "--delete är imkompatibel med --all, --mirror och --tags"
+#: builtin/remote.c:1298
+#, c-format
+msgid " * [pruned] %s"
+msgstr " * [rensad] %s"
-#: builtin/push.c:336
-msgid "--delete doesn't make sense without any refs"
-msgstr "--delete kan inte användas utan referenser"
+#: builtin/remote.c:1387 builtin/remote.c:1461
+#, c-format
+msgid "No such remote '%s'"
+msgstr "Ingen sådan fjärr \"%s\""
+
+#: builtin/remote.c:1414
+msgid "no remote specified"
+msgstr "ingen fjärr angavs"
+
+#: builtin/remote.c:1447
+msgid "--add --delete doesn't make sense"
+msgstr "--add --delete ger ingen mening"
+
+#: builtin/remote.c:1487
+#, c-format
+msgid "Invalid old URL pattern: %s"
+msgstr "Felaktig gammalt URL-mönster: %s"
+
+#: builtin/remote.c:1495
+#, c-format
+msgid "No such URL found: %s"
+msgstr "Ingen sådan URL hittades: %s"
+
+#: builtin/remote.c:1497
+msgid "Will not delete all non-push URLs"
+msgstr "Kommer inte ta bort alla icke-sänd-URL:er"
#: builtin/reset.c:33
msgid "mixed"
msgid "hard"
msgstr "hård"
+#: builtin/reset.c:33
+msgid "merge"
+msgstr "sammanslagning"
+
#: builtin/reset.c:33
msgid "keep"
msgstr "behåll"
msgid "%s: %s cannot be used with %s"
msgstr "%s: %s kan inte användas med %s"
-#: builtin/revert.c:127
+#: builtin/revert.c:131
msgid "program error"
msgstr "programfel"
-#: builtin/revert.c:213
+#: builtin/revert.c:221
msgid "revert failed"
msgstr "\"revert\" misslyckades"
-#: builtin/revert.c:228
+#: builtin/revert.c:236
msgid "cherry-pick failed"
msgstr "\"cherry-pick\" misslyckades"
msgid "Missing author: %s"
msgstr "Författare saknas: %s"
-#: builtin/tag.c:58
+#: builtin/tag.c:60
#, c-format
msgid "malformed object at '%s'"
msgstr "felformat objekt vid \"%s\""
-#: builtin/tag.c:205
+#: builtin/tag.c:207
#, c-format
msgid "tag name too long: %.*s..."
msgstr "taggnamnet för långt: %.*s..."
-#: builtin/tag.c:210
+#: builtin/tag.c:212
#, c-format
msgid "tag '%s' not found."
msgstr "taggen \"%s\" hittades inte."
-#: builtin/tag.c:225
+#: builtin/tag.c:227
#, c-format
msgid "Deleted tag '%s' (was %s)\n"
msgstr "Tog bort tagg \"%s\" (var %s)\n"
-#: builtin/tag.c:237
+#: builtin/tag.c:239
#, c-format
msgid "could not verify the tag '%s'"
msgstr "kunde inte bekräfta taggen \"%s\""
-#: builtin/tag.c:247
+#: builtin/tag.c:249
msgid ""
"\n"
"#\n"
"# Rader som inleds med \"#\" ignoreras.\n"
"#\n"
-#: builtin/tag.c:254
+#: builtin/tag.c:256
msgid ""
"\n"
"#\n"
"# du vill.\n"
"#\n"
-#: builtin/tag.c:294
+#: builtin/tag.c:298
msgid "unable to sign the tag"
msgstr "kunde inte signera taggen"
-#: builtin/tag.c:296
+#: builtin/tag.c:300
msgid "unable to write tag file"
msgstr "kunde inte skriva tagg-filen"
-#: builtin/tag.c:321
+#: builtin/tag.c:325
msgid "bad object type."
msgstr "felaktig objekttyp"
-#: builtin/tag.c:334
+#: builtin/tag.c:338
msgid "tag header too big."
msgstr "tagghuvud för stort."
-#: builtin/tag.c:366
+#: builtin/tag.c:370
msgid "no tag message?"
msgstr "inget taggmeddelande?"
-#: builtin/tag.c:372
+#: builtin/tag.c:376
#, c-format
msgid "The tag message has been left in %s\n"
msgstr "Taggmeddelandet har lämnats i %s\n"
-#: builtin/tag.c:421
+#: builtin/tag.c:425
msgid "switch 'points-at' requires an object"
msgstr "flaggan \"points-at\" behöver ett object"
-#: builtin/tag.c:423
+#: builtin/tag.c:427
#, c-format
msgid "malformed object name '%s'"
msgstr "felformat objektnamn \"%s\""
-#: builtin/tag.c:502
+#: builtin/tag.c:506
+msgid "--column and -n are incompatible"
+msgstr "--column och -n är inkompatibla"
+
+#: builtin/tag.c:523
msgid "-n option is only allowed with -l."
msgstr "Flaggan -n är endast tillåten tillsammans med -l."
-#: builtin/tag.c:504
+#: builtin/tag.c:525
msgid "--contains option is only allowed with -l."
msgstr "Flaggan --contains är endast tillåten tillsammans med -l"
-#: builtin/tag.c:506
+#: builtin/tag.c:527
msgid "--points-at option is only allowed with -l."
msgstr "Flaggan --points-at är endast tillåten tillsammans med -l."
-#: builtin/tag.c:514
+#: builtin/tag.c:535
msgid "only one -F or -m option is allowed."
msgstr "endast en av flaggorna -F eller -m tillåts."
-#: builtin/tag.c:534
+#: builtin/tag.c:555
msgid "too many params"
msgstr "för många parametrar"
-#: builtin/tag.c:540
+#: builtin/tag.c:561
#, c-format
msgid "'%s' is not a valid tag name."
msgstr "\"%s\" är inte ett giltigt taggnamn."
-#: builtin/tag.c:545
+#: builtin/tag.c:566
#, c-format
msgid "tag '%s' already exists"
msgstr "taggen \"%s\" finns redan"
-#: builtin/tag.c:563
+#: builtin/tag.c:584
#, c-format
msgid "%s: cannot lock the ref"
msgstr "%s: kan inte låsa referensen"
-#: builtin/tag.c:565
+#: builtin/tag.c:586
#, c-format
msgid "%s: cannot update the ref"
msgstr "%s: kan inte uppdatera referensen"
-#: builtin/tag.c:567
+#: builtin/tag.c:588
#, c-format
msgid "Updated tag '%s' (was %s)\n"
msgstr "Uppdaterad tagg \"%s\" (var %s)\n"
-#: git-am.sh:49
+#: git.c:16
+msgid "See 'git help <command>' for more information on a specific command."
+msgstr ""
+"Se \"git help <kommando>\" för mer information om ett specifikt kommando."
+
+#: parse-options.h:133 parse-options.h:235
+msgid "n"
+msgstr "n"
+
+#: parse-options.h:141
+msgid "time"
+msgstr "tid"
+
+# %s är ett verb ("Untracked"/"Ignored"); lägg till ett -e.
+#: parse-options.h:149
+msgid "file"
+msgstr "fil"
+
+#: parse-options.h:151
+msgid "when"
+msgstr "när"
+
+#: parse-options.h:156
+msgid "no-op (backward compatibility)"
+msgstr "ingen funktion (bakåtkompatibilitet)"
+
+#: parse-options.h:228
+msgid "be more verbose"
+msgstr "var mer pratsam"
+
+#: parse-options.h:230
+msgid "be more quiet"
+msgstr "var mer tyst"
+
+#: parse-options.h:236
+msgid "use <n> digits to display SHA-1s"
+msgstr "använd <n> siffror för att visa SHA-1:or"
+
+#: common-cmds.h:8
+msgid "Add file contents to the index"
+msgstr "Lägg filinnehåll till indexet"
+
+#: common-cmds.h:9
+msgid "Find by binary search the change that introduced a bug"
+msgstr "Binärsök för att hitta ändringen som introducerade ett fel"
+
+#: common-cmds.h:10
+msgid "List, create, or delete branches"
+msgstr "Visa, skapa eller ta bort grenar"
+
+#: common-cmds.h:11
+msgid "Checkout a branch or paths to the working tree"
+msgstr "Checka ut en gren eller filer i arbetskatalogen"
+
+#: common-cmds.h:12
+msgid "Clone a repository into a new directory"
+msgstr "Klona ett arkiv till en ny katalog"
+
+#: common-cmds.h:13
+msgid "Record changes to the repository"
+msgstr "Protokollför ändringar i arkivet"
+
+#: common-cmds.h:14
+msgid "Show changes between commits, commit and working tree, etc"
+msgstr "Visa ändringar mellan incheckningar, med arbetskatalogen, osv"
+
+#: common-cmds.h:15
+msgid "Download objects and refs from another repository"
+msgstr "Hämta objekt och referenser från annat arkiv"
+
+#: common-cmds.h:16
+msgid "Print lines matching a pattern"
+msgstr "Visa rader som motsvarar mönster"
+
+#: common-cmds.h:17
+msgid "Create an empty git repository or reinitialize an existing one"
+msgstr "Skapa tomt git-arkiv eller ominitiera ett befintligt"
+
+#: common-cmds.h:18
+msgid "Show commit logs"
+msgstr "Visa incheckningsloggar"
+
+#: common-cmds.h:19
+msgid "Join two or more development histories together"
+msgstr "Slå ihop två eller flera utvecklingshistorier"
+
+#: common-cmds.h:20
+msgid "Move or rename a file, a directory, or a symlink"
+msgstr "Flytta eller byt namn på en fil, katalog eller symbolisk länk"
+
+#: common-cmds.h:21
+msgid "Fetch from and merge with another repository or a local branch"
+msgstr "Hämta från och slå ihop med annat arkiv eller en lokal gren"
+
+#: common-cmds.h:22
+msgid "Update remote refs along with associated objects"
+msgstr "Uppdatera fjärr-referenser och tillhörande objekt"
+
+#: common-cmds.h:23
+msgid "Forward-port local commits to the updated upstream head"
+msgstr "Framåtanpassa lokala kommandon på uppdaterat uppströmshuvud"
+
+#: common-cmds.h:24
+msgid "Reset current HEAD to the specified state"
+msgstr "Återställ aktuell HEAD till angivet tillstånd"
+
+#: common-cmds.h:25
+msgid "Remove files from the working tree and from the index"
+msgstr "Ta bort filer från arbetskatalogen och från indexet"
+
+#: common-cmds.h:26
+msgid "Show various types of objects"
+msgstr "Visa olika sorters objekt"
+
+#: common-cmds.h:27
+msgid "Show the working tree status"
+msgstr "Visa status för arbetskatalogen"
+
+#: common-cmds.h:28
+msgid "Create, list, delete or verify a tag object signed with GPG"
+msgstr "Skapa, visa, ta bort eller verifiera ett taggobjekt signerat med GPG"
+
+#: git-am.sh:50
msgid "You need to set your committer info first"
msgstr "Du måste ställa in din incheckarinformation först"
-#: git-am.sh:136
+#: git-am.sh:95
+msgid ""
+"You seem to have moved HEAD since the last 'am' failure.\n"
+"Not rewinding to ORIG_HEAD"
+msgstr ""
+"Du verkar ha flyttat HEAD sedan \"am\" sist misslyckades.\n"
+"Återställer inte till ORIG_HEAD"
+
+#: git-am.sh:105
+#, sh-format
+msgid ""
+"When you have resolved this problem run \"$cmdline --resolved\".\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+"När du har löst problemet kör du \"$cmdline --resolved\".\n"
+"Om du vill hoppa över patchen kör du istället \"$cmdline --skip\".\n"
+"För att återställa originalgrenen och avbryta kör du \"$cmdline --abort\"."
+
+#: git-am.sh:121
+msgid "Cannot fall back to three-way merge."
+msgstr "Kan inte falla tillbaka på trevägssammanslagning."
+
+#: git-am.sh:137
msgid "Repository lacks necessary blobs to fall back on 3-way merge."
msgstr ""
"Arkivet saknar objekt som behövs för att falla tillbaka på 3-"
"vägssammanslagning."
-#: git-am.sh:147
+#: git-am.sh:154
msgid ""
"Did you hand edit your patch?\n"
"It does not apply to blobs recorded in its index."
msgstr ""
"Har du handredigerat din patch?\n"
-"Den kan inte appliceras på blobbar som antecknats i dess index."
+"Den kan inte tillämpas på blobbar som antecknats i dess index."
-#: git-am.sh:156
+#: git-am.sh:163
msgid "Falling back to patching base and 3-way merge..."
msgstr ""
"Faller tillbaka på att pacha grundversionen och trevägssammanslagning..."
-#: git-am.sh:268
+#: git-am.sh:275
msgid "Only one StGIT patch series can be applied at once"
-msgstr "Endast en StGIT-patchserie kan appliceras åt gången"
+msgstr "Endast en StGIT-patchserie kan tillämpas åt gången"
-#: git-am.sh:355
+#: git-am.sh:362
#, sh-format
msgid "Patch format $patch_format is not supported."
msgstr "Patchformatet $patch_format stöds inte."
-#: git-am.sh:357
+#: git-am.sh:364
msgid "Patch format detection failed."
msgstr "Misslyckades detektera patchformat."
-#: git-am.sh:411
+#: git-am.sh:418
msgid "-d option is no longer supported. Do not use."
msgstr "Flaggan -d stöds inte lägre. Använd inte."
-#: git-am.sh:474
+#: git-am.sh:481
#, sh-format
msgid "previous rebase directory $dotest still exists but mbox given."
msgstr "tidigare rebase-katalog $dotest finns fortfarande, men mbox angavs."
-#: git-am.sh:479
+#: git-am.sh:486
msgid "Please make up your mind. --skip or --abort?"
msgstr "Bestäm dig. --skip eller --abort?"
-#: git-am.sh:506
+#: git-am.sh:513
msgid "Resolve operation not in progress, we are not resuming."
msgstr "Lösningsoperation pågår inte, vi återupptar inte."
-#: git-am.sh:572
+#: git-am.sh:579
#, sh-format
msgid "Dirty index: cannot apply patches (dirty: $files)"
-msgstr "Smutsigt index: kan inte applicera patchar (smutsiga: $files)"
+msgstr "Smutsigt index: kan inte tillämpa patchar (smutsiga: $files)"
+
+#: git-am.sh:671
+#, sh-format
+msgid ""
+"Patch is empty. Was it split wrong?\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+"Patchen är tom. Delades den upp felaktigt?\n"
+"Om du vill hoppa över patchen kör du istället \"$cmdline --skip\".\n"
+"För att återställa originalgrenen och avbryta kör du \"$cmdline --abort\"."
-#: git-am.sh:748
+#: git-am.sh:708
+msgid "Patch does not have a valid e-mail address."
+msgstr "Patchen har inte någon giltig e-postadress."
+
+#: git-am.sh:755
msgid "cannot be interactive without stdin connected to a terminal."
msgstr ""
"kan inte vara interaktiv om standard in inte är ansluten till en terminal."
+#: git-am.sh:759
+msgid "Commit Body is:"
+msgstr "Incheckningskroppen är:"
+
#. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
#. in your translation. The program will only accept English
#. input at this point.
-#: git-am.sh:759
+#: git-am.sh:766
msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
-msgstr "Applicera? Y=ja/N=nej/E=redigera/V=visa patch/A=godta alla "
+msgstr "Tillämpa? Y=ja/N=nej/E=redigera/V=visa patch/A=godta alla "
-#: git-am.sh:795
+#: git-am.sh:802
#, sh-format
msgid "Applying: $FIRSTLINE"
-msgstr "Applicerar: $FIRSTLINE"
+msgstr "Tillämpar: $FIRSTLINE"
+
+#: git-am.sh:823
+msgid ""
+"No changes - did you forget to use 'git add'?\n"
+"If there is nothing left to stage, chances are that something else\n"
+"already introduced the same changes; you might want to skip this patch."
+msgstr ""
+"Inga ändringar - glömde du använda \"git add\"?\n"
+"Om det inte är något kvar att köa kan det hända att något annat redan\n"
+"introducerat samma ändringar; kanske du bör hoppa över patchen."
+
+#: git-am.sh:831
+msgid ""
+"You still have unmerged paths in your index\n"
+"did you forget to use 'git add'?"
+msgstr ""
+"Du har fortfarande sökvägar som inte slagits samman i ditt index\n"
+"glömde du använda \"git add\"?"
-#: git-am.sh:840
+#: git-am.sh:847
msgid "No changes -- Patch already applied."
-msgstr "Inga ändringar -- Patchen har redan applicerats."
+msgstr "Inga ändringar -- Patchen har redan tillämpats."
+
+#: git-am.sh:857
+#, sh-format
+msgid "Patch failed at $msgnum $FIRSTLINE"
+msgstr "Patchen misslyckades vid $msgnum $FIRSTLINE"
-#: git-am.sh:866
+#: git-am.sh:873
msgid "applying to an empty history"
-msgstr "applicerar på en tom historik"
+msgstr "tillämpar på en tom historik"
+
+#: git-bisect.sh:48
+msgid "You need to start by \"git bisect start\""
+msgstr "Du måste starta med \"git bisect start\""
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
msgid "'git bisect bad' can take only one argument."
msgstr "\"git bisect bad\" kan bara ta ett argument."
+#. have bad but not good. we could bisect although
+#. this is less optimum.
+#: git-bisect.sh:273
+msgid "Warning: bisecting only with a bad commit."
+msgstr "Varning: utför \"bisect\" med endast en dålig incheckning"
+
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
#. at this point.
msgid "Are you sure [Y/n]? "
msgstr "Är du säker [Y=ja/N=nej]? "
+#: git-bisect.sh:289
+msgid ""
+"You need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+"Du måste ange åtminstone en bra och en dålig version.\n"
+"(Du kan använda \"git bisect bad\" och \"git bisect good\" för detta.)"
+
+#: git-bisect.sh:292
+msgid ""
+"You need to start by \"git bisect start\".\n"
+"You then need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+"Du måste starta med \"git bisect start\".\n"
+"Du måste sedan ange åtminstone en bra och en dålig version.\n"
+"(Du kan använda \"git bisect bad\" och \"git bisect good\" för detta.)"
+
+#: git-bisect.sh:347 git-bisect.sh:474
+msgid "We are not bisecting."
+msgstr "Vi utför ingen bisect för tillfället."
+
#: git-bisect.sh:354
#, sh-format
msgid "'$invalid' is not a valid commit"
msgid "?? what are you talking about?"
msgstr "?? vad menar du?"
-#: git-bisect.sh:474
-msgid "We are not bisecting."
-msgstr "Vi utför ingen bisect för tillfället."
+#: git-bisect.sh:420
+#, sh-format
+msgid "running $command"
+msgstr "kör $command"
+
+#: git-bisect.sh:427
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"exit code $res from '$command' is < 0 or >= 128"
+msgstr ""
+"\"bisect\"-körningen misslyckades:\n"
+"felkod $res från \"$command\" är < 0 eller >= 128"
+
+#: git-bisect.sh:453
+msgid "bisect run cannot continue any more"
+msgstr "\"bisect\"-körningen kan inte fortsätta längre"
+
+#: git-bisect.sh:459
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"'bisect_state $state' exited with error code $res"
+msgstr ""
+"\"bisect\"-körningen misslyckades:\n"
+"\"bisect_state $state\" avslutades med felkoden $res"
+
+#: git-bisect.sh:466
+msgid "bisect run success"
+msgstr "\"bisect\"-körningen lyckades"
#: git-pull.sh:21
msgid ""
msgid "updating an unborn branch with changes added to the index"
msgstr "uppdaterar en ofödd gren med ändringar som lagts till i indexet"
+#. The fetch involved updating the current branch.
+#. The working tree and the index file is still based on the
+#. $orig_head commit, but we are merging into $curr_head.
+#. First update the working tree to match $curr_head.
+#: git-pull.sh:228
+#, sh-format
+msgid ""
+"Warning: fetch updated the current branch head.\n"
+"Warning: fast-forwarding your working tree from\n"
+"Warning: commit $orig_head."
+msgstr ""
+"Varning: fetch uppdaterade huvudet för aktuell gren.\n"
+"Varning: snabbspolar din arbetskatalog från\n"
+"Varning: incheckningen $orig_head."
+
#: git-pull.sh:253
msgid "Cannot merge multiple branches into empty head"
msgstr "Kan inte slå ihop flera grenar i ett tomt huvud."
msgid "Cannot record working tree state"
msgstr "Kan inte registrera tillstånd för arbetskatalog"
+#. TRANSLATORS: $option is an invalid option, like
+#. `--blah-blah'. The 7 spaces at the beginning of the
+#. second line correspond to "error: ". So you should line
+#. up the second line with however many characters the
+#. translation of "error: " takes in your language. E.g. in
+#. English this is:
+#.
+#. $ git stash save --blah-blah 2>&1 | head -n 2
+#. error: unknown option for 'stash save': --blah-blah
+#. To provide a message, use git stash save -- '--blah-blah'
+#: git-stash.sh:202
+#, sh-format
+msgid ""
+"error: unknown option for 'stash save': $option\n"
+" To provide a message, use git stash save -- '$option'"
+msgstr ""
+"fel: felaktig flagga för \"stash save\": $option\n"
+" För att ange ett meddelande, använd git stash save -- \"$option\""
+
#: git-stash.sh:223
msgid "No local changes to save"
msgstr "Inga lokala ändringar att spara"
#: git-stash.sh:416
msgid "Cannot apply a stash in the middle of a merge"
-msgstr "Kan inte applicera en \"stash\" mitt i en sammanslagning"
+msgstr "Kan inte tillämpa en \"stash\" mitt i en sammanslagning"
#: git-stash.sh:424
msgid "Conflicts in index. Try without --index."
msgid "Cannot unstage modified files"
msgstr "Kan inte ta bort ändrade filer ur kön"
+#: git-stash.sh:474
+msgid "Index was not unstashed."
+msgstr "Indexet har inte tagits ur kön."
+
#: git-stash.sh:491
#, sh-format
msgid "Dropped ${REV} ($s)"
msgid "(To restore them type \"git stash apply\")"
msgstr "(För att återställa dem, skriv \"git stash apply\")"
-#: git-submodule.sh:56
+#: git-submodule.sh:88
#, sh-format
msgid "cannot strip one component off url '$remoteurl'"
msgstr "kan inte ta bort en komponent från url:en \"$remoteurl\""
-#: git-submodule.sh:108
+#: git-submodule.sh:145
#, sh-format
-msgid "No submodule mapping found in .gitmodules for path '$path'"
-msgstr "Hittade ingen undermodulmappning i .gitmodules för sökvägen \"$path\""
+msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
+msgstr ""
+"Hittade ingen undermodulmappning i .gitmodules för sökvägen \"$sm_path\""
-#: git-submodule.sh:149
+#: git-submodule.sh:186
#, sh-format
-msgid "Clone of '$url' into submodule path '$path' failed"
-msgstr "Misslyckades klona \"$url\" till undermodulsökvägen \"$path\""
+msgid "Clone of '$url' into submodule path '$sm_path' failed"
+msgstr "Misslyckades klona \"$url\" till undermodulsökvägen \"$sm_path\""
-#: git-submodule.sh:159
+#: git-submodule.sh:196
#, sh-format
msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
msgstr "Gitkatalog \"$a\" ingår i underkatalogsökvägen \"$b\" eller omvänt"
-#: git-submodule.sh:248
+#: git-submodule.sh:285
#, sh-format
msgid "repo URL: '$repo' must be absolute or begin with ./|../"
msgstr "arkiv-URL: \"$repo\" måste vara absolut eller börja med ./|../"
-#: git-submodule.sh:265
+#: git-submodule.sh:302
+#, sh-format
+msgid "'$sm_path' already exists in the index"
+msgstr "\"$sm_path\" finns redan i indexet"
+
+#: git-submodule.sh:306
#, sh-format
-msgid "'$path' already exists in the index"
-msgstr "\"$path\" finns redan i indexet"
+msgid ""
+"The following path is ignored by one of your .gitignore files:\n"
+"$sm_path\n"
+"Use -f if you really want to add it."
+msgstr ""
+"Följande sökvägar ignoreras av en av dina .gitignore-filer:\n"
+"$sm_path\n"
+"Använd -f om du verkligen vill lägga till den"
-#: git-submodule.sh:282
+#: git-submodule.sh:317
#, sh-format
-msgid "'$path' already exists and is not a valid git repo"
-msgstr "\"$path\" finns redan och är inte ett giltigt git-arkiv"
+msgid "Adding existing repo at '$sm_path' to the index"
+msgstr "Lägger till befintligt arkiv i \"$sm_path\" i indexet"
-#: git-submodule.sh:296
+#: git-submodule.sh:319
#, sh-format
-msgid "Unable to checkout submodule '$path'"
-msgstr "Kan inte checka ut undermodul \"$path\""
+msgid "'$sm_path' already exists and is not a valid git repo"
+msgstr "\"$sm_path\" finns redan och är inte ett giltigt git-arkiv"
-#: git-submodule.sh:301
+#: git-submodule.sh:333
#, sh-format
-msgid "Failed to add submodule '$path'"
-msgstr "Misslyckades lägga till underkatalog \"$path\""
+msgid "Unable to checkout submodule '$sm_path'"
+msgstr "Kan inte checka ut undermodulen \"$sm_path\""
-#: git-submodule.sh:306
+#: git-submodule.sh:338
#, sh-format
-msgid "Failed to register submodule '$path'"
-msgstr "Misslyckades registrera undermodul \"$path\""
+msgid "Failed to add submodule '$sm_path'"
+msgstr "Misslyckades lägga till undermodulen \"$sm_path\""
-#: git-submodule.sh:348
+#: git-submodule.sh:343
#, sh-format
-msgid "Entering '$prefix$path'"
-msgstr "Går in i \"$prefix$path\""
+msgid "Failed to register submodule '$sm_path'"
+msgstr "Misslyckades registrera undermodulen \"$sm_path\""
-#: git-submodule.sh:360
+#: git-submodule.sh:385
#, sh-format
-msgid "Stopping at '$path'; script returned non-zero status."
-msgstr "Stoppar på \"$path\"; skriptet returnerade en status skild från noll."
+msgid "Entering '$prefix$sm_path'"
+msgstr "Går in i \"$prefix$sm_path\""
-#: git-submodule.sh:402
+#: git-submodule.sh:399
#, sh-format
-msgid "No url found for submodule path '$path' in .gitmodules"
-msgstr "Hittade ingen url för undermodulsökvägen \"$path\" i .gitmodules"
+msgid "Stopping at '$sm_path'; script returned non-zero status."
+msgstr ""
+"Stoppar på \"$sm_path\"; skriptet returnerade en status skild från noll."
-#: git-submodule.sh:411
+#: git-submodule.sh:442
#, sh-format
-msgid "Failed to register url for submodule path '$path'"
-msgstr "Misslyckades registrera url för underkatalogsökväg \"$path\""
+msgid "No url found for submodule path '$sm_path' in .gitmodules"
+msgstr "Hittade ingen url för undermodulsökvägen \"$sm_path\" i .gitmodules"
-#: git-submodule.sh:419
+#: git-submodule.sh:451
#, sh-format
-msgid "Failed to register update mode for submodule path '$path'"
-msgstr ""
-"Misslyckades registrera uppdateringsläge för undermodulsökväg \"$path\""
+msgid "Failed to register url for submodule path '$sm_path'"
+msgstr "Misslyckades registrera url för underkatalogsökväg \"$sm_path\""
+
+#: git-submodule.sh:453
+#, sh-format
+msgid "Submodule '$name' ($url) registered for path '$sm_path'"
+msgstr "Undermodulen \"$name\" ($url) registrerad för sökvägen \"$sm_path\""
-#: git-submodule.sh:421
+#: git-submodule.sh:461
#, sh-format
-msgid "Submodule '$name' ($url) registered for path '$path'"
-msgstr "Undermodulen \"$name\" ($url) registrerad för sökvägen \"$path\""
+msgid "Failed to register update mode for submodule path '$sm_path'"
+msgstr ""
+"Misslyckades registrera uppdateringsläge för undermodulsökväg \"$sm_path\""
-#: git-submodule.sh:520
+#: git-submodule.sh:560
#, sh-format
msgid ""
-"Submodule path '$path' not initialized\n"
+"Submodule path '$sm_path' not initialized\n"
"Maybe you want to use 'update --init'?"
msgstr ""
-"Undermodulen \"$path\" har inte initierats\n"
+"Undermodulen \"$sm_path\" har inte initierats\n"
"Kanske du vill köra \"update --init\"?"
-#: git-submodule.sh:533
+#: git-submodule.sh:573
#, sh-format
-msgid "Unable to find current revision in submodule path '$path'"
-msgstr "Kan inte hitta aktuell revision i undermodulsökväg \"$path\""
+msgid "Unable to find current revision in submodule path '$sm_path'"
+msgstr "Kan inte hitta aktuell revision i undermodulsökväg \"$sm_path\""
-#: git-submodule.sh:552
+#: git-submodule.sh:592
#, sh-format
-msgid "Unable to fetch in submodule path '$path'"
-msgstr "Kan inte hämta i undermodulsökväg \"$path\""
+msgid "Unable to fetch in submodule path '$sm_path'"
+msgstr "Kan inte hämta i undermodulsökväg \"$sm_path\""
-#: git-submodule.sh:566
+#: git-submodule.sh:606
#, sh-format
-msgid "Unable to rebase '$sha1' in submodule path '$path'"
-msgstr "Kan inte göra \"rebase\" av \"$sha1\" i undermodulsökväg \"$path\""
+msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
+msgstr "Kan inte ombasera \"$sha1\" i undermodulsökväg \"$sm_path\""
-#: git-submodule.sh:567
+#: git-submodule.sh:607
#, sh-format
-msgid "Submodule path '$path': rebased into '$sha1'"
-msgstr "Undermodulsökvägen \"$path\": \"rebase\":ad in i \"$sha1\""
+msgid "Submodule path '$sm_path': rebased into '$sha1'"
+msgstr "Undermodulsökvägen \"$sm_path\": ombaserade in i \"$sha1\""
-#: git-submodule.sh:572
+#: git-submodule.sh:612
#, sh-format
-msgid "Unable to merge '$sha1' in submodule path '$path'"
-msgstr "Kan inte slå ihop \"$sha1\" i undermodulsökvägen \"$path\""
+msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
+msgstr "Kan inte slå ihop \"$sha1\" i undermodulsökvägen \"$sm_path\""
-#: git-submodule.sh:573
+#: git-submodule.sh:613
#, sh-format
-msgid "Submodule path '$path': merged in '$sha1'"
-msgstr "Undermodulsökvägen \"$path\": sammanslagen i \"$sha1\""
+msgid "Submodule path '$sm_path': merged in '$sha1'"
+msgstr "Undermodulsökvägen \"$sm_path\": sammanslagen i \"$sha1\""
-#: git-submodule.sh:578
+#: git-submodule.sh:618
#, sh-format
-msgid "Unable to checkout '$sha1' in submodule path '$path'"
-msgstr "Kan inte checka ut \"$sha1\" i undermodulsökvägen \"$path\""
+msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
+msgstr "Kan inte checka ut \"$sha1\" i undermodulsökvägen \"$sm_path\""
-#: git-submodule.sh:579
+#: git-submodule.sh:619
#, sh-format
-msgid "Submodule path '$path': checked out '$sha1'"
-msgstr "Undermodulsökvägen \"$path\": checkade ut \"$sha1\""
+msgid "Submodule path '$sm_path': checked out '$sha1'"
+msgstr "Undermodulsökvägen \"$sm_path\": checkade ut \"$sha1\""
-#: git-submodule.sh:601 git-submodule.sh:924
+#: git-submodule.sh:641 git-submodule.sh:964
#, sh-format
-msgid "Failed to recurse into submodule path '$path'"
-msgstr "Misslyckades rekursera in i undermodulsökvägen \"$path\""
+msgid "Failed to recurse into submodule path '$sm_path'"
+msgstr "Misslyckades rekursera in i undermodulsökvägen \"$sm_path\""
-#: git-submodule.sh:709
-msgid "--"
-msgstr "--"
+#: git-submodule.sh:749
+msgid "--cached cannot be used with --files"
+msgstr "--cached kan inte användas med --files"
-#: git-submodule.sh:767
+#. unexpected type
+#: git-submodule.sh:789
+#, sh-format
+msgid "unexpected mode $mod_dst"
+msgstr "oväntat läge $mod_dst"
+
+#: git-submodule.sh:807
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_src"
msgstr " Varning: $name innehåller inte incheckning $sha1_src"
-#: git-submodule.sh:770
+#: git-submodule.sh:810
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_dst"
msgstr " Varning: $name innehåller inte incheckning $sha1_dst"
-#: git-submodule.sh:773
+#: git-submodule.sh:813
#, sh-format
msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
msgstr " Varning: $name innehåller inte incheckningar $sha1_src och $sha1_dst"
-#: git-submodule.sh:798
+#: git-submodule.sh:838
msgid "blob"
msgstr "blob"
-#: git-submodule.sh:799
+#: git-submodule.sh:839
msgid "submodule"
msgstr "undermodul"
-#: git-submodule.sh:970
+#: git-submodule.sh:876
+msgid "# Submodules changed but not updated:"
+msgstr "# Undermoduler ändrade men inte uppdaterade:"
+
+#: git-submodule.sh:878
+msgid "# Submodule changes to be committed:"
+msgstr "# Undermodulers ändringar att checka in:"
+
+#: git-submodule.sh:1022
#, sh-format
msgid "Synchronizing submodule url for '$name'"
msgstr "Synkroniserar undermodul-url för \"$name\""
+#~ msgid "cherry-pick"
+#~ msgstr "cherry-pick"
+
+#~ msgid "Please enter the commit message for your changes."
+#~ msgstr "Ange ett incheckningsmeddelande för dina ändringar."
+
+#~ msgid "Could not extract email from committer identity."
+#~ msgstr "Kunde inte extrahera e-postadress från incheckarens identitet."
+
+#~ msgid "--"
+#~ msgstr "--"
+
#~ msgid "Too many options specified"
#~ msgstr "För många flaggor angavs"
#~ msgid "signing key value too long (%.10s...)"
#~ msgstr "signeringsnyckelvärdet för långt (%.10s...)"
-
-#~ msgid ""
-#~ "When you have resolved this problem run \"$cmdline --resolved\".\n"
-#~ "If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
-#~ "To restore the original branch and stop patching run \"$cmdline --abort\"."
-#~ msgstr ""
-#~ "När du har löst problemet kör du \"$cmdline --resolved\".\n"
-#~ "Om du vill hoppa över patchen kör du istället \"$cmdline --skip\".\n"
-#~ "För att återställa originalgrenen och avbryta kör du \"$cmdline --abort\"."
-
-#~ msgid ""
-#~ "Patch is empty. Was it split wrong?\n"
-#~ "If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
-#~ "To restore the original branch and stop patching run \"$cmdline --abort\"."
-#~ msgstr ""
-#~ "Patchen är tom. Delades den upp felaktigt?\n"
-#~ "Om du vill hoppa över patchen kör du istället \"$cmdline --skip\".\n"
-#~ "För att återställa originalgrenen och avbryta kör du \"$cmdline --abort\"."
-
-#~ msgid "Patch does not have a valid e-mail address."
-#~ msgstr "Patchen har inte någon giltig e-postadress."
-
-#~ msgid "Commit Body is:"
-#~ msgstr "Incheckningskroppen är:"
-
-#~ msgid ""
-#~ "No changes - did you forget to use 'git add'?\n"
-#~ "If there is nothing left to stage, chances are that something else\n"
-#~ "already introduced the same changes; you might want to skip this patch."
-#~ msgstr ""
-#~ "Inga ändringar - glömde du använda \"git add\"?\n"
-#~ "Om det inte är något kvar att köa kan det hända att något annat redan\n"
-#~ "introducerat samma ändringar; kanske du bör hoppa över patchen."
-
-#~ msgid ""
-#~ "You still have unmerged paths in your index\n"
-#~ "did you forget to use 'git add'?"
-#~ msgstr ""
-#~ "Du har fortfarande sökvägar som inte slagits samman i ditt index\n"
-#~ "glömde du använda \"git add\"?"
-
-#~ msgid "Patch failed at $msgnum $FIRSTLINE"
-#~ msgstr "Patchen misslyckades vid $msgnum $FIRSTLINE"
-
-#, fuzzy
-#~ msgid "You need to start by \"git bisect start\""
-#~ msgstr "Du måste ställa in din incheckarinformation först"
-
-#, fuzzy
-#~ msgid "Index was not unstashed."
-#~ msgstr "kunde köra stash."
-
-#, fuzzy
-#~ msgid "# Submodules changed but not updated:"
-#~ msgstr "# Ändrade men inte uppdaterade:"
-
-#, fuzzy
-#~ msgid "# Submodule changes to be committed:"
-#~ msgstr "# Ändringar att checka in:"
#
msgid ""
msgstr ""
-"Project-Id-Version: git-1.7.10.1\n"
+"Project-Id-Version: git-1.7.11.1-107-g72601\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-05-21 08:57+0800\n"
-"PO-Revision-Date: 2012-05-31 09:13+0700\n"
+"POT-Creation-Date: 2012-07-03 10:23+0800\n"
+"PO-Revision-Date: 2012-07-03 14:21+0700\n"
"Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
"Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
"MIME-Version: 1.0\n"
#: bundle.c:63
#, c-format
msgid "unrecognized header: %s%s (%d)"
-msgstr "Không nhận ra phần đầu: %s%s (%d)"
+msgstr "phần đầu (header) không được thừa nhận: %s%s (%d)"
#: bundle.c:89
-#: builtin/commit.c:697
+#: builtin/commit.c:696
#, c-format
msgid "could not open '%s'"
msgstr "không thể mở '%s'"
msgstr "Khó chứa thiếu những lần chuyển giao (commit) cần trước hết này:"
#: bundle.c:164
-#: sequencer.c:533
-#: sequencer.c:965
-#: builtin/log.c:289
-#: builtin/log.c:719
-#: builtin/log.c:1335
-#: builtin/log.c:1554
+#: sequencer.c:550
+#: sequencer.c:982
+#: builtin/log.c:290
+#: builtin/log.c:721
+#: builtin/log.c:1310
+#: builtin/log.c:1529
#: builtin/merge.c:347
#: builtin/shortlog.c:181
msgid "revision walk setup failed"
#, c-format
msgid "The bundle contains %d ref"
msgid_plural "The bundle contains %d refs"
-msgstr[0] "Bundle chứa %d chiếu"
-msgstr[1] "Bundle chứa %d chiếu"
+msgstr[0] "Bundle chứa %d tham chiếu (refs)"
+msgstr[1] "Bundle chứa %d tham chiếu (refs)"
#: bundle.c:192
+msgid "The bundle records a complete history."
+msgstr "Lệnh bundle ghi lại toàn bộ lịch sử."
+
+#: bundle.c:195
#, c-format
msgid "The bundle requires this ref"
msgid_plural "The bundle requires these %d refs"
-msgstr[0] "Lệnh bundle yêu cầu tham chiếu này"
-msgstr[1] "Lệnh bundle yêu cầu %d tham chiếu"
+msgstr[0] "Lệnh bundle yêu cầu tham chiếu (refs) này"
+msgstr[1] "Lệnh bundle yêu cầu %d tham chiếu (refs) này"
-#: bundle.c:290
+#: bundle.c:294
msgid "rev-list died"
msgstr "rev-list bị chết"
-#: bundle.c:296
-#: builtin/log.c:1231
+#: bundle.c:300
+#: builtin/log.c:1206
#: builtin/shortlog.c:284
#, c-format
msgid "unrecognized argument: %s"
-msgstr "không nhận ra đối số: %s"
+msgstr "đối số không được thừa nhận: %s"
-#: bundle.c:331
+#: bundle.c:335
#, c-format
msgid "ref '%s' is excluded by the rev-list options"
msgstr "tham chiếu '%s' bị loại trừ bởi các tùy chọn rev-list"
-#: bundle.c:376
+#: bundle.c:380
msgid "Refusing to create empty bundle."
msgstr "Từ chối tạo một bundle trống rỗng."
-#: bundle.c:394
+#: bundle.c:398
msgid "Could not spawn pack-objects"
msgstr "Không thể sản sinh pack-objects"
-#: bundle.c:412
+#: bundle.c:416
msgid "pack-objects died"
msgstr "pack-objects đã chết"
-#: bundle.c:415
+#: bundle.c:419
#, c-format
msgid "cannot create '%s'"
msgstr "không thể tạo '%s'"
-#: bundle.c:437
+#: bundle.c:441
msgid "index-pack died"
msgstr "index-pack đã chết"
#: diff.c:1400
msgid " 0 files changed\n"
-msgstr " 0 tập tin bị thay đổi\n"
+msgstr " 0 tập tin nào bị thay đổi\n"
#: diff.c:1404
#, c-format
msgid "gpg failed to sign the data"
msgstr "gpg gặp lỗi khi ký dữ liệu"
-#: grep.c:1280
+#: grep.c:1320
#, c-format
msgid "'%s': unable to read %s"
msgstr "'%s': không thể đọc %s"
-#: grep.c:1297
+#: grep.c:1337
#, c-format
msgid "'%s': %s"
msgstr "'%s': %s"
-#: grep.c:1308
+#: grep.c:1348
#, c-format
msgid "'%s': short read %s"
msgstr "'%s': đọc ngắn %s"
-#: help.c:207
+#: help.c:208
#, c-format
msgid "available git commands in '%s'"
msgstr "các lệnh git sẵn sàng để dùng trong '%s'"
-#: help.c:214
+#: help.c:215
msgid "git commands available from elsewhere on your $PATH"
msgstr "các lệnh git sẵn sàng để dùng từ một nơi khác trong $PATH của bạn"
-#: help.c:270
+#: help.c:271
#, c-format
msgid ""
"'%s' appears to be a git command, but we were not\n"
"'%s' trông như là một lệnh git, nhưng chúng tôi không\n"
"thể thực thi nó. Có lẽ là lệnh git-%s đã bị hỏng?"
-#: help.c:327
+#: help.c:328
msgid "Uh oh. Your system reports no Git commands at all."
msgstr "Ối chà. Hệ thống của bạn báo rằng chẳng có lệnh Git nào cả."
-#: help.c:349
+#: help.c:350
#, c-format
msgid ""
"WARNING: You called a Git command named '%s', which does not exist.\n"
"CẢNH BÁO: Bạn đã gọi lệnh Git có tên '%s', mà nó lại không sẵn có.\n"
"Giả định rằng ý bạn là '%s'"
-#: help.c:354
+#: help.c:355
#, c-format
msgid "in %0.1f seconds automatically..."
msgstr "trong %0.1f giây một cách tự động..."
-#: help.c:361
+#: help.c:362
#, c-format
msgid "git: '%s' is not a git command. See 'git --help'."
msgstr "git: '%s' không phải là một lệnh của git. Xem thêm 'git --help'."
-#: help.c:365
+#: help.c:366
msgid ""
"\n"
"Did you mean this?"
msgid " %s"
msgstr " %s"
-#: remote.c:1607
+#: remote.c:1629
#, c-format
msgid "Your branch is ahead of '%s' by %d commit.\n"
msgid_plural "Your branch is ahead of '%s' by %d commits.\n"
msgstr[0] "Nhánh của bạn là đầu của '%s' bởi %d lần chuyển giao (commit).\n"
msgstr[1] "Nhánh của bạn là đầu của '%s' bởi %d lần chuyển giao (commit).\n"
-#: remote.c:1613
+#: remote.c:1635
#, c-format
msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
msgid_plural "Your branch is behind '%s' by %d commits, and can be fast-forwarded.\n"
msgstr[0] "Nhánh của bạn thì ở đằng sau '%s' bởi %d lần chuyển giao (commit), và có thể được fast-forward.\n"
msgstr[1] "Nhánh của bạn thì ở đằng sau '%s' bởi %d lần chuyển giao (commit), và có thể được fast-forward.\n"
-#: remote.c:1621
+#: remote.c:1643
#, c-format
msgid ""
"Your branch and '%s' have diverged,\n"
"và chuyển giao (commit) kết quả bằng lệnh 'git commit'"
#: sequencer.c:160
-#: sequencer.c:741
-#: sequencer.c:824
+#: sequencer.c:758
+#: sequencer.c:841
#, c-format
msgid "Could not write to %s"
msgstr "Không thể ghi vào %s"
msgid "Unable to update cache tree\n"
msgstr "Không thể cập nhật cây bộ nhớ đệm\n"
-#: sequencer.c:323
+#: sequencer.c:324
#, c-format
msgid "Could not parse commit %s\n"
msgstr "Không thể phân tích commit (lần chuyển giao) %s\n"
-#: sequencer.c:328
+#: sequencer.c:329
#, c-format
msgid "Could not parse parent commit %s\n"
msgstr "Không thể phân tích commit (lần chuyển giao) cha mẹ %s\n"
-#: sequencer.c:358
+#: sequencer.c:395
msgid "Your index file is unmerged."
msgstr "Tập tin lưu mục lục của bạn không được hòa trộn."
-#: sequencer.c:361
+#: sequencer.c:398
msgid "You do not have a valid HEAD"
msgstr "Bạn không có HEAD nào hợp lệ"
-#: sequencer.c:376
+#: sequencer.c:413
#, c-format
msgid "Commit %s is a merge but no -m option was given."
msgstr "Lần chuyển giao (commit) %s là một lần hòa trộn nhưng không đưa ra tùy chọn -m."
-#: sequencer.c:384
+#: sequencer.c:421
#, c-format
msgid "Commit %s does not have parent %d"
msgstr "Lần chuyển giao (commit) %s không có cha mẹ %d"
-#: sequencer.c:388
+#: sequencer.c:425
#, c-format
msgid "Mainline was specified but commit %s is not a merge."
msgstr "Luồng chính được chỉ định nhưng lần chuyển giao (commit) %s không phải là một lần hòa trộn."
#. TRANSLATORS: The first %s will be "revert" or
#. "cherry-pick", the second %s a SHA1
-#: sequencer.c:399
+#: sequencer.c:436
#, c-format
msgid "%s: cannot parse parent commit %s"
msgstr "%s: không thể phân tích lần chuyển giao mẹ của %s"
-#: sequencer.c:403
+#: sequencer.c:440
#, c-format
msgid "Cannot get commit message for %s"
msgstr "Không thể lấy thông điệp lần chuyển giao (commit) cho %s"
-#: sequencer.c:491
+#: sequencer.c:524
#, c-format
msgid "could not revert %s... %s"
msgstr "không thể revert %s... %s"
-#: sequencer.c:492
+#: sequencer.c:525
#, c-format
msgid "could not apply %s... %s"
msgstr "không thể apply (áp dụng miếng vá) %s... %s"
-#: sequencer.c:536
+#: sequencer.c:553
msgid "empty commit set passed"
msgstr "lần chuyển giao (commit) trống rỗng đặt là hợp quy cách"
-#: sequencer.c:544
+#: sequencer.c:561
#, c-format
msgid "git %s: failed to read the index"
msgstr "git %s: gặp lỗi đọc bảng mục lục"
-#: sequencer.c:549
+#: sequencer.c:566
#, c-format
msgid "git %s: failed to refresh the index"
msgstr "git %s: gặp lỗi khi làm tươi mới bảng mục lục"
-#: sequencer.c:607
+#: sequencer.c:624
#, c-format
msgid "Cannot %s during a %s"
msgstr "Không thể %s trong khi %s"
-#: sequencer.c:629
+#: sequencer.c:646
#, c-format
msgid "Could not parse line %d."
msgstr "Không phân tích được dòng %d."
-#: sequencer.c:634
+#: sequencer.c:651
msgid "No commits parsed."
-msgstr "Không có lần chuyển giao (commit) nào được phân tích"
+msgstr "Không có lần chuyển giao (commit) nào được phân tích."
-#: sequencer.c:647
+#: sequencer.c:664
#, c-format
msgid "Could not open %s"
msgstr "Không thể mở %s"
-#: sequencer.c:651
+#: sequencer.c:668
#, c-format
msgid "Could not read %s."
msgstr "Không thể đọc %s."
-#: sequencer.c:658
+#: sequencer.c:675
#, c-format
msgid "Unusable instruction sheet: %s"
msgstr "Bảng chỉ thị không thể dùng được: %s"
-#: sequencer.c:686
+#: sequencer.c:703
#, c-format
msgid "Invalid key: %s"
msgstr "Khóa không đúng: %s"
-#: sequencer.c:689
+#: sequencer.c:706
#, c-format
msgid "Invalid value for %s: %s"
msgstr "Giá trị không hợp lệ %s: %s"
-#: sequencer.c:701
+#: sequencer.c:718
#, c-format
msgid "Malformed options sheet: %s"
msgstr "Bảng tùy chọn dị hình: %s"
-#: sequencer.c:722
+#: sequencer.c:739
msgid "a cherry-pick or revert is already in progress"
msgstr "một thao tác cherry-pick hoặc revert đang được thực hiện"
-#: sequencer.c:723
+#: sequencer.c:740
msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
msgstr "hãy thử \"git cherry-pick (--continue | --quit | --abort)\""
-#: sequencer.c:727
+#: sequencer.c:744
#, c-format
msgid "Could not create sequencer directory %s"
msgstr "Không thể tạo thư mục xếp dãy %s"
-#: sequencer.c:743
-#: sequencer.c:828
+#: sequencer.c:760
+#: sequencer.c:845
#, c-format
msgid "Error wrapping up %s."
msgstr "Lỗi bao bọc %s."
-#: sequencer.c:762
-#: sequencer.c:896
+#: sequencer.c:779
+#: sequencer.c:913
msgid "no cherry-pick or revert in progress"
msgstr "không cherry-pick hay revert trong tiến trình"
-#: sequencer.c:764
+#: sequencer.c:781
msgid "cannot resolve HEAD"
msgstr "không thể phân giải HEAD"
-#: sequencer.c:766
+#: sequencer.c:783
msgid "cannot abort from a branch yet to be born"
-msgstr "không thể hủy bỏ một nhánh mà nó còn chưa được tạo ra"
+msgstr "không thể hủy bỏ từ một nhánh mà nó còn chưa được tạo ra"
-#: sequencer.c:788
-#: builtin/apply.c:3689
+#: sequencer.c:805
+#: builtin/apply.c:3697
#, c-format
msgid "cannot open %s: %s"
msgstr "không thể mở %s: %s"
-#: sequencer.c:791
+#: sequencer.c:808
#, c-format
msgid "cannot read %s: %s"
msgstr "không thể đọc %s: %s"
-#: sequencer.c:792
+#: sequencer.c:809
msgid "unexpected end of file"
msgstr "kết thúc tập tin đột xuất"
-#: sequencer.c:798
+#: sequencer.c:815
#, c-format
msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
-msgstr "tập tin HEAD 'pre-cherry-pick' '%s' bị hỏng"
+msgstr "tập tin HEAD 'pre-cherry-pick' đã lưu '%s' bị hỏng"
-#: sequencer.c:821
+#: sequencer.c:838
#, c-format
msgid "Could not format %s."
-msgstr "Không thể định %s."
+msgstr "Không thể định dạng %s."
-#: sequencer.c:983
+#: sequencer.c:1000
msgid "Can't revert as initial commit"
msgstr "Không thể revert một lần chuyển giao (commit) khởi tạo"
-#: sequencer.c:984
+#: sequencer.c:1001
msgid "Can't cherry-pick into empty head"
msgstr "Không thể cherry-pick vào một đầu (head) trống rỗng"
#: sha1_name.c:869
#, c-format
msgid "No upstream configured for branch '%s'"
-msgstr "Không có dòng ngược được cấu hình cho nhánh '%s'"
+msgstr "Không có dòng ngược (upstream) được cấu hình cho nhánh '%s'"
#: sha1_name.c:872
#, c-format
msgid "Upstream branch '%s' not stored as a remote-tracking branch"
-msgstr "Nhánh ngược dòng (upstream) '%s' không được lưu lại như là một nhánh 'remote-tracking'"
+msgstr "Nhánh dòng ngược (upstream) '%s' không được lưu lại như là một nhánh 'remote-tracking'"
+
+#: wrapper.c:413
+#, c-format
+msgid "unable to look up current user in the passwd file: %s"
+msgstr "không tìm thấy người dùng hiện tại trong tập tin passwd: %s"
+
+#: wrapper.c:414
+msgid "no such user"
+msgstr "không có người dùng như vậy"
-#: wt-status.c:135
+#: wt-status.c:141
msgid "Unmerged paths:"
msgstr "Những đường dẫn chưa được hòa trộn:"
-#: wt-status.c:141
-#: wt-status.c:158
+#: wt-status.c:168
+#: wt-status.c:195
#, c-format
msgid " (use \"git reset %s <file>...\" to unstage)"
msgstr " (sử dụng \"git reset %s <tập-tin>...\" để bỏ một stage (trạng thái))"
-#: wt-status.c:143
-#: wt-status.c:160
+#: wt-status.c:170
+#: wt-status.c:197
msgid " (use \"git rm --cached <file>...\" to unstage)"
msgstr " (sử dụng \"git rm --cached <tập-tin>...\" để bỏ trạng thái (stage))"
-#: wt-status.c:144
+#: wt-status.c:174
+msgid " (use \"git add <file>...\" to mark resolution)"
+msgstr " (sử dụng \"git add <tập-tin>...\" để đánh dấu là cần giải quyết)"
+
+#: wt-status.c:176
+#: wt-status.c:180
msgid " (use \"git add/rm <file>...\" as appropriate to mark resolution)"
msgstr " (sử dụng \"git add/rm <tập-tin>...\" như là một cách thích hợp để đánh dấu là cần được giải quyết)"
-#: wt-status.c:152
+#: wt-status.c:178
+msgid " (use \"git rm <file>...\" to mark resolution)"
+msgstr " (sử dụng \"git rm <tập-tin>...\" để đánh dấu là cần giải quyết)"
+
+#: wt-status.c:189
msgid "Changes to be committed:"
msgstr "Những thay đổi sẽ được chuyển giao:"
-#: wt-status.c:170
+#: wt-status.c:207
msgid "Changes not staged for commit:"
msgstr "Các thay đổi không được đặt trạng thái (stage) cho lần chuyển giao (commit):"
-#: wt-status.c:174
+#: wt-status.c:211
msgid " (use \"git add <file>...\" to update what will be committed)"
msgstr " (sử dụng \"git add <tập-tin>...\" để cập nhật những gì cần chuyển giao (commit))"
-#: wt-status.c:176
+#: wt-status.c:213
msgid " (use \"git add/rm <file>...\" to update what will be committed)"
msgstr " (sử dụng \"git add/rm <tập_tin>...\" để cập nhật những gì sẽ được chuyển giao)"
-#: wt-status.c:177
+#: wt-status.c:214
msgid " (use \"git checkout -- <file>...\" to discard changes in working directory)"
msgstr " (sử dụng \"git checkout -- <tập_tin>...\" để loại bỏ những thay đổi trong thư mục làm việc)"
-#: wt-status.c:179
+#: wt-status.c:216
msgid " (commit or discard the untracked or modified content in submodules)"
msgstr " (chuyển giao (commit) hoặc là loại bỏ các nội dung không-bị-theo-vết hay đã bị chỉnh sửa trong mô-đun-con)"
-#: wt-status.c:188
+#: wt-status.c:225
#, c-format
msgid "%s files:"
msgstr "%s tệp tin:"
-#: wt-status.c:191
+#: wt-status.c:228
#, c-format
msgid " (use \"git %s <file>...\" to include in what will be committed)"
msgstr " (sử dụng \"git %s <tập-tin>...\" để bao gồm thêm vào những gì cần chuyển giao (commit))"
-#: wt-status.c:208
+#: wt-status.c:245
msgid "bug"
msgstr "lỗi"
-#: wt-status.c:213
+#: wt-status.c:250
msgid "both deleted:"
msgstr "bị xóa bởi cả hai:"
-#: wt-status.c:214
+#: wt-status.c:251
msgid "added by us:"
msgstr "được thêm vào bởi chúng tôi:"
-#: wt-status.c:215
+#: wt-status.c:252
msgid "deleted by them:"
-msgstr "bị xóa bởi họ:"
+msgstr "bị xóa đi bởi họ:"
-#: wt-status.c:216
+#: wt-status.c:253
msgid "added by them:"
msgstr "được thêm vào bởi họ:"
-#: wt-status.c:217
+#: wt-status.c:254
msgid "deleted by us:"
msgstr "bị xóa bởi chúng tôi:"
-#: wt-status.c:218
+#: wt-status.c:255
msgid "both added:"
msgstr "được thêm vào bởi cả hai:"
-#: wt-status.c:219
+#: wt-status.c:256
msgid "both modified:"
msgstr "bị sửa bởi cả hai:"
-#: wt-status.c:249
+#: wt-status.c:286
msgid "new commits, "
msgstr " lần chuyển giao (commit) mới, "
-#: wt-status.c:251
+#: wt-status.c:288
msgid "modified content, "
msgstr "nội dung được sửa đổi,"
-#: wt-status.c:253
+#: wt-status.c:290
msgid "untracked content, "
msgstr "nội dung chưa được theo dõi"
-#: wt-status.c:267
+#: wt-status.c:304
#, c-format
msgid "new file: %s"
msgstr "tập tin mới: %s"
-#: wt-status.c:270
+#: wt-status.c:307
#, c-format
msgid "copied: %s -> %s"
msgstr "đã sao chép: %s -> %s"
-#: wt-status.c:273
+#: wt-status.c:310
#, c-format
msgid "deleted: %s"
-msgstr "đã xóa: %s"
+msgstr "bị xóa: %s"
-#: wt-status.c:276
+#: wt-status.c:313
#, c-format
msgid "modified: %s"
-msgstr "đã chỉnh sửa: %s"
+msgstr "bị sửa đổi: %s"
-#: wt-status.c:279
+#: wt-status.c:316
#, c-format
msgid "renamed: %s -> %s"
msgstr "đã đổi tên: %s -> %s"
-#: wt-status.c:282
+#: wt-status.c:319
#, c-format
msgid "typechange: %s"
msgstr "đổi-kiểu: %s"
-#: wt-status.c:285
+#: wt-status.c:322
#, c-format
msgid "unknown: %s"
msgstr "không rõ: %s"
-#: wt-status.c:288
+#: wt-status.c:325
#, c-format
msgid "unmerged: %s"
msgstr "chưa hòa trộn: %s"
-#: wt-status.c:291
+#: wt-status.c:328
#, c-format
msgid "bug: unhandled diff status %c"
msgstr "lỗi: không lấy được trạng thái lệnh diff %c"
-#: wt-status.c:737
+#: wt-status.c:786
+msgid "You have unmerged paths."
+msgstr "Bạn có những đường dẫn chưa được hòa trộn."
+
+#: wt-status.c:789
+#: wt-status.c:913
+msgid " (fix conflicts and run \"git commit\")"
+msgstr " (sửa các xung đột sau đó chạy \"git commit\")"
+
+#: wt-status.c:792
+msgid "All conflicts fixed but you are still merging."
+msgstr "Tất cả các xung đột đã được giải quyết nhưng bạn vẫn đang hòa trộn."
+
+#: wt-status.c:795
+msgid " (use \"git commit\" to conclude merge)"
+msgstr " (sử dụng \"git commit\" để hoàn tất việc hòa trộn)"
+
+#: wt-status.c:805
+msgid "You are in the middle of an am session."
+msgstr "Bạn đang ở giữa của một phiên 'am'."
+
+#: wt-status.c:808
+msgid "The current patch is empty."
+msgstr "Miếng vá hiện tại bị trống rỗng."
+
+#: wt-status.c:812
+msgid " (fix conflicts and then run \"git am --resolved\")"
+msgstr " (sửa các xung đột và sau đó chạy lệnh \"git am --resolved\")"
+
+#: wt-status.c:814
+msgid " (use \"git am --skip\" to skip this patch)"
+msgstr " (sử dụng \"git am --skip\" để bỏ qua lần vá này)"
+
+#: wt-status.c:816
+msgid " (use \"git am --abort\" to restore the original branch)"
+msgstr " (sử dụng \"git am --abort\" để phục hồi lại nhánh nguyên thủy)"
+
+#: wt-status.c:874
+#: wt-status.c:884
+msgid "You are currently rebasing."
+msgstr "Bạn hiện nay đang thực hiện việc rebase (tái cấu trúc)."
+
+#: wt-status.c:877
+msgid " (fix conflicts and then run \"git rebase --continue\")"
+msgstr " (sửa các xung đột và sau đó chạy lệnh \"git rebase --continue\")"
+
+#: wt-status.c:879
+msgid " (use \"git rebase --skip\" to skip this patch)"
+msgstr " (sử dụng \"git rebase --skip\" để bỏ qua lần vá này)"
+
+#: wt-status.c:881
+msgid " (use \"git rebase --abort\" to check out the original branch)"
+msgstr " (sử dụng \"git rebase --abort\" để check-out nhánh nguyên thủy)"
+
+#: wt-status.c:887
+msgid " (all conflicts fixed: run \"git rebase --continue\")"
+msgstr " (khi tất cả các xung đột đã sửa xong: chạy lệnh \"git rebase --continue\")"
+
+#: wt-status.c:889
+msgid "You are currently splitting a commit during a rebase."
+msgstr "Bạn hiện tại đang cắt đôi một lần chuyển giao trong khi đang thực hiện việc rebase."
+
+#: wt-status.c:892
+msgid " (Once your working directory is clean, run \"git rebase --continue\")"
+msgstr " (Một khi thư mục làm việc của bạn đã gọn gàng, chạy \"git rebase --continue\")"
+
+#: wt-status.c:894
+msgid "You are currently editing a commit during a rebase."
+msgstr "Bạn hiện đang sửa một lần chuyển giao trong khi bạn thực hiện rebase."
+
+#: wt-status.c:897
+msgid " (use \"git commit --amend\" to amend the current commit)"
+msgstr " (sử dụng \"git commit --amend\" để tu bổ lần chuyển giao (commit) hiện tại)"
+
+#: wt-status.c:899
+msgid " (use \"git rebase --continue\" once you are satisfied with your changes)"
+msgstr " (sử dụng \"git rebase --continue\" một khi bạn cảm thấy hài lòng về những thay đổi của mình)"
+
+#: wt-status.c:909
+msgid "You are currently cherry-picking."
+msgstr "Bạn hiện nay đang thực hiện việc cherry-pick."
+
+#: wt-status.c:916
+msgid " (all conflicts fixed: run \"git commit\")"
+msgstr " (khi tất cả các xung đột đã sửa xong: chạy lệnh \"git commit\")"
+
+#: wt-status.c:925
+msgid "You are currently bisecting."
+msgstr "Bạn hiện tại đang thực hiện việc bisect (chia đôi)."
+
+#: wt-status.c:928
+msgid " (use \"git bisect reset\" to get back to the original branch)"
+msgstr " (sử dụng \"git bisect reset\" để quay trở lại nhánh nguyên thủy)"
+
+#: wt-status.c:979
msgid "On branch "
msgstr "Trên nhánh"
-#: wt-status.c:744
+#: wt-status.c:986
msgid "Not currently on any branch."
msgstr "Hiện tại chẳng ở nhánh nào cả."
-#: wt-status.c:755
+#: wt-status.c:998
msgid "Initial commit"
msgstr "Lần chuyển giao (commit) khởi đầu"
-#: wt-status.c:769
+#: wt-status.c:1012
msgid "Untracked"
msgstr "Không được theo vết"
-#: wt-status.c:771
+#: wt-status.c:1014
msgid "Ignored"
msgstr "Bị bỏ qua"
-#: wt-status.c:773
+#: wt-status.c:1016
#, c-format
msgid "Untracked files not listed%s"
msgstr "Những tập tin không bị theo vết không được liệt kê ra %s"
-#: wt-status.c:775
+#: wt-status.c:1018
msgid " (use -u option to show untracked files)"
msgstr " (sử dụng tùy chọn -u để hiển thị các tập tin chưa được theo dõi)"
-#: wt-status.c:781
+#: wt-status.c:1024
msgid "No changes"
msgstr "Không có thay đổi nào"
-#: wt-status.c:785
+#: wt-status.c:1028
#, c-format
msgid "no changes added to commit%s\n"
msgstr "không có thay đổi nào được thêm vào lần chuyển giao (commit)%s\n"
-#: wt-status.c:787
+#: wt-status.c:1030
msgid " (use \"git add\" and/or \"git commit -a\")"
msgstr " (sử dụng \"git add\" và/hoặc \"git commit -a\")"
-#: wt-status.c:789
+#: wt-status.c:1032
#, c-format
msgid "nothing added to commit but untracked files present%s\n"
msgstr "không có gì được thêm vào lần chuyển giao (commit) nhưng có những tập tin không được theo dấu vết hiện diện%s\n"
-#: wt-status.c:791
+#: wt-status.c:1034
msgid " (use \"git add\" to track)"
msgstr " (sử dụng \"git add\" để theo dõi dấu vết)"
-#: wt-status.c:793
-#: wt-status.c:796
-#: wt-status.c:799
+#: wt-status.c:1036
+#: wt-status.c:1039
+#: wt-status.c:1042
#, c-format
msgid "nothing to commit%s\n"
msgstr "không có gì để chuyển giao (commit) %s\n"
-#: wt-status.c:794
+#: wt-status.c:1037
msgid " (create/copy files and use \"git add\" to track)"
msgstr " (tạo/sao-chép các tập tin và sử dụng \"git add\" để theo dõi dấu vết)"
-#: wt-status.c:797
+#: wt-status.c:1040
msgid " (use -u to show untracked files)"
msgstr " (sử dụng tùy chọn -u để hiển thị các tập tin chưa được theo dõi)"
-#: wt-status.c:800
+#: wt-status.c:1043
msgid " (working directory clean)"
-msgstr " (thư mục làm việc không có dữ liệu)"
+msgstr " (thư mục làm việc sạch sẽ)"
-#: wt-status.c:908
+#: wt-status.c:1151
msgid "HEAD (no branch)"
msgstr "HEAD (chưa có nhánh nào)"
-#: wt-status.c:914
+#: wt-status.c:1157
msgid "Initial commit on "
msgstr "Lần chuyển giao (commit) khởi tạo trên"
-#: wt-status.c:929
+#: wt-status.c:1172
msgid "behind "
msgstr "đằng sau"
-#: wt-status.c:932
-#: wt-status.c:935
+#: wt-status.c:1175
+#: wt-status.c:1178
msgid "ahead "
msgstr "phía trước"
-#: wt-status.c:937
+#: wt-status.c:1180
msgid ", behind "
msgstr ", đằng sau"
msgstr "Các thay đổi không được lưu trạng thái sau khi làm tươi mới lại bảng mục lục:"
#: builtin/add.c:195
-#: builtin/add.c:456
+#: builtin/add.c:459
#: builtin/rm.c:186
#, c-format
msgid "pathspec '%s' did not match any files"
msgid "index file corrupt"
msgstr "tập tin ghi bảng mục lục bị hỏng"
-#: builtin/add.c:476
-#: builtin/apply.c:4100
+#: builtin/add.c:480
+#: builtin/apply.c:4108
#: builtin/mv.c:229
#: builtin/rm.c:260
msgid "Unable to write new index file"
msgid "%s: already exists in index"
msgstr "%s: đã có từ trước trong bảng mục lục"
-#: builtin/apply.c:3266
+#: builtin/apply.c:3267
#, c-format
-msgid "new mode (%o) of %s does not match old mode (%o)%s%s"
-msgstr "chế độ mới (%o) của %s không khớp với chế độ cũ (%o)%s%s"
+msgid "new mode (%o) of %s does not match old mode (%o)"
+msgstr "chế độ mới (%o) của %s không khớp với chế độ cũ (%o)"
#: builtin/apply.c:3272
#, c-format
+msgid "new mode (%o) of %s does not match old mode (%o) of %s"
+msgstr "chế độ mới (%o) của %s không khớp với chế độ cũ (%o) của %s"
+
+#: builtin/apply.c:3280
+#, c-format
msgid "%s: patch does not apply"
msgstr "%s: miếng vá không được áp dụng"
-#: builtin/apply.c:3285
+#: builtin/apply.c:3293
#, c-format
msgid "Checking patch %s..."
msgstr "Đang kiểm tra miếng vá %s..."
-#: builtin/apply.c:3340
+#: builtin/apply.c:3348
#: builtin/checkout.c:212
#: builtin/reset.c:158
#, c-format
msgid "make_cache_entry failed for path '%s'"
msgstr "make_cache_entry gặp lỗi đối với đường dẫn '%s'"
-#: builtin/apply.c:3483
+#: builtin/apply.c:3491
#, c-format
msgid "unable to remove %s from index"
msgstr "không thể gỡ bỏ %s từ mục lục"
-#: builtin/apply.c:3510
+#: builtin/apply.c:3518
#, c-format
msgid "corrupt patch for subproject %s"
msgstr "miếng vá sai hỏng cho dự án con (subproject) %s"
-#: builtin/apply.c:3514
+#: builtin/apply.c:3522
#, c-format
msgid "unable to stat newly created file '%s'"
msgstr "không thể lấy trạng thái về tập tin %s mới hơn đã được tạo"
-#: builtin/apply.c:3519
+#: builtin/apply.c:3527
#, c-format
msgid "unable to create backing store for newly created file %s"
msgstr "không thể tạo 'backing store' cho tập tin được tạo mới hơn %s"
-#: builtin/apply.c:3522
+#: builtin/apply.c:3530
#, c-format
msgid "unable to add cache entry for %s"
msgstr "không thể thêm mục nhớ tạm cho %s"
-#: builtin/apply.c:3555
+#: builtin/apply.c:3563
#, c-format
msgid "closing file '%s'"
msgstr "đang đóng tập tin '%s'"
-#: builtin/apply.c:3604
+#: builtin/apply.c:3612
#, c-format
msgid "unable to write file '%s' mode %o"
msgstr "không thể ghi vào tập tin '%s' chế độ (mode) %o"
-#: builtin/apply.c:3660
+#: builtin/apply.c:3668
#, c-format
msgid "Applied patch %s cleanly."
msgstr "Đã áp dụng miếng và %s một cách sạch sẽ."
-#: builtin/apply.c:3668
+#: builtin/apply.c:3676
msgid "internal error"
msgstr "lỗi nội bộ"
#. Say this even without --verbose
-#: builtin/apply.c:3671
+#: builtin/apply.c:3679
#, c-format
msgid "Applying patch %%s with %d reject..."
msgid_plural "Applying patch %%s with %d rejects..."
msgstr[0] "Đang áp dụng miếng vá %%s với %d lần từ chối..."
msgstr[1] "Đang áp dụng miếng vá %%s với %d lần từ chối..."
-#: builtin/apply.c:3681
+#: builtin/apply.c:3689
#, c-format
msgid "truncating .rej filename to %.*s.rej"
msgstr "đang cắt cụt tên tập tin .rej thành %.*s.rej"
-#: builtin/apply.c:3702
+#: builtin/apply.c:3710
#, c-format
msgid "Hunk #%d applied cleanly."
msgstr "Khối nhớ #%d được áp dụng gọn gàng."
-#: builtin/apply.c:3705
+#: builtin/apply.c:3713
#, c-format
msgid "Rejected hunk #%d."
msgstr "hunk #%d bị từ chối."
-#: builtin/apply.c:3836
+#: builtin/apply.c:3844
msgid "unrecognized input"
msgstr "không thừa nhận đầu vào"
-#: builtin/apply.c:3847
+#: builtin/apply.c:3855
msgid "unable to read index file"
msgstr "không thể đọc tập tin lưu bảng mục lục"
-#: builtin/apply.c:3962
-#: builtin/apply.c:3965
+#: builtin/apply.c:3970
+#: builtin/apply.c:3973
msgid "path"
msgstr "đường-dẫn"
-#: builtin/apply.c:3963
+#: builtin/apply.c:3971
msgid "don't apply changes matching the given path"
msgstr "không áp dụng các thay đổi khớp với đường dẫn đã cho"
-#: builtin/apply.c:3966
+#: builtin/apply.c:3974
msgid "apply changes matching the given path"
msgstr "áp dụng các thay đổi khớp với đường dẫn đã cho"
-#: builtin/apply.c:3968
+#: builtin/apply.c:3976
msgid "num"
msgstr "số"
-#: builtin/apply.c:3969
+#: builtin/apply.c:3977
msgid "remove <num> leading slashes from traditional diff paths"
msgstr "gỡ bỏ <số> phần dẫn đầu (slashe) từ đường dẫn diff cổ điển"
-#: builtin/apply.c:3972
+#: builtin/apply.c:3980
msgid "ignore additions made by the patch"
msgstr "lờ đi phần phụ thêm tạo ra bởi miếng vá"
-#: builtin/apply.c:3974
+#: builtin/apply.c:3982
msgid "instead of applying the patch, output diffstat for the input"
msgstr "thay vì áp dụng một miếng vá, kết xuất kết quả từ lệnh diffstat cho đầu ra"
-#: builtin/apply.c:3978
+#: builtin/apply.c:3986
msgid "shows number of added and deleted lines in decimal notation"
msgstr "hiển thị số lượng các dòng được thêm vào và xóa đi theo ký hiệu thập phân"
-#: builtin/apply.c:3980
+#: builtin/apply.c:3988
msgid "instead of applying the patch, output a summary for the input"
msgstr "thay vì áp dụng một miếng vá, kết xuất kết quả cho đầu vào"
-#: builtin/apply.c:3982
+#: builtin/apply.c:3990
msgid "instead of applying the patch, see if the patch is applicable"
msgstr "thay vì áp dụng miếng vá, hãy xem xem miếng vá có thích hợp không"
-#: builtin/apply.c:3984
+#: builtin/apply.c:3992
msgid "make sure the patch is applicable to the current index"
msgstr "hãy chắc chắn là miếng vá thích hợp với bảng mục lục hiện hành"
-#: builtin/apply.c:3986
+#: builtin/apply.c:3994
msgid "apply a patch without touching the working tree"
msgstr "áp dụng một miếng vá mà không động chạm đến cây làm việc"
-#: builtin/apply.c:3988
+#: builtin/apply.c:3996
msgid "also apply the patch (use with --stat/--summary/--check)"
msgstr "đồng thời áp dụng miếng vá (sử dụng với tùy chọn --stat/--summary/--check)"
-#: builtin/apply.c:3990
+#: builtin/apply.c:3998
msgid "build a temporary index based on embedded index information"
msgstr "xây dựng bảng mục lục tạm thời trên cơ sở thông tin bảng mục lục được nhúng"
-#: builtin/apply.c:3992
+#: builtin/apply.c:4000
msgid "paths are separated with NUL character"
msgstr "các đường dẫn bị ngăn cách bởi ký tự NULL"
-#: builtin/apply.c:3995
+#: builtin/apply.c:4003
msgid "ensure at least <n> lines of context match"
msgstr "đảm bảo rằng có ít nhất <n> dòng nội dung khớp"
-#: builtin/apply.c:3996
+#: builtin/apply.c:4004
msgid "action"
msgstr "hành động"
-#: builtin/apply.c:3997
+#: builtin/apply.c:4005
msgid "detect new or modified lines that have whitespace errors"
msgstr "tìm thấy một dòng mới hoặc bị sửa đổi mà nó có lỗi do khoảng trắng"
-#: builtin/apply.c:4000
-#: builtin/apply.c:4003
+#: builtin/apply.c:4008
+#: builtin/apply.c:4011
msgid "ignore changes in whitespace when finding context"
msgstr "lờ đi sự thay đổi do khoảng trắng khi quét nội dung"
-#: builtin/apply.c:4006
+#: builtin/apply.c:4014
msgid "apply the patch in reverse"
msgstr "áp dụng miếng vá theo chiều ngược"
-#: builtin/apply.c:4008
+#: builtin/apply.c:4016
msgid "don't expect at least one line of context"
msgstr "đừng hy vọng có ít nhất một dòng nội dung"
-#: builtin/apply.c:4010
+#: builtin/apply.c:4018
msgid "leave the rejected hunks in corresponding *.rej files"
msgstr "để lại khối dữ liệu bị từ chối trong các tập tin *.rej tương ứng"
-#: builtin/apply.c:4012
+#: builtin/apply.c:4020
msgid "allow overlapping hunks"
msgstr "cho phép chồng khối nhớ"
-#: builtin/apply.c:4013
+#: builtin/apply.c:4021
msgid "be verbose"
msgstr "chi tiết"
-#: builtin/apply.c:4015
+#: builtin/apply.c:4023
msgid "tolerate incorrectly detected missing new-line at the end of file"
msgstr "dung sai không chính xác đã tìm thấy thiếu dòng mới tại cuối tập tin"
-#: builtin/apply.c:4018
+#: builtin/apply.c:4026
msgid "do not trust the line counts in the hunk headers"
msgstr "không tin số lượng dòng trong phần đầu khối dữ liệu"
-#: builtin/apply.c:4020
+#: builtin/apply.c:4028
msgid "root"
msgstr "root"
-#: builtin/apply.c:4021
+#: builtin/apply.c:4029
msgid "prepend <root> to all filenames"
msgstr "treo thêm <root> vào tất cả các tên tập tin"
-#: builtin/apply.c:4042
+#: builtin/apply.c:4050
msgid "--index outside a repository"
msgstr "--index ở ngoài một kho chứa"
-#: builtin/apply.c:4045
+#: builtin/apply.c:4053
msgid "--cached outside a repository"
msgstr "--cached ở ngoài một kho chứa"
-#: builtin/apply.c:4061
+#: builtin/apply.c:4069
#, c-format
msgid "can't open patch '%s'"
msgstr "không thể mở miếng vá '%s'"
-#: builtin/apply.c:4075
+#: builtin/apply.c:4083
#, c-format
msgid "squelched %d whitespace error"
msgid_plural "squelched %d whitespace errors"
msgstr[0] "đã chấm dứt %d lỗi khoảng trắng"
msgstr[1] "đã chấm dứt %d lỗi khoảng trắng"
-#: builtin/apply.c:4081
-#: builtin/apply.c:4091
+#: builtin/apply.c:4089
+#: builtin/apply.c:4099
#, c-format
msgid "%d line adds whitespace errors."
msgid_plural "%d lines add whitespace errors."
msgid "malformed --author parameter"
msgstr "đối số --author bị dị hình"
-#: builtin/commit.c:583
+#: builtin/commit.c:582
#, c-format
msgid "Malformed ident string: '%s'"
msgstr "Chuỗi thụt lề đầu dòng dị hình: '%s'"
-#: builtin/commit.c:621
-#: builtin/commit.c:654
-#: builtin/commit.c:968
+#: builtin/commit.c:620
+#: builtin/commit.c:653
+#: builtin/commit.c:967
#, c-format
msgid "could not lookup commit %s"
msgstr "không thể tìm kiếm commit (lần chuyển giao) %s"
-#: builtin/commit.c:633
+#: builtin/commit.c:632
#: builtin/shortlog.c:296
#, c-format
msgid "(reading log message from standard input)\n"
msgstr "(đang đọc thông điệp nhật ký từ đầu vào tiêu chuẩn)\n"
-#: builtin/commit.c:635
+#: builtin/commit.c:634
msgid "could not read log from standard input"
msgstr "không thể đọc nhật ký từ đầu vào tiêu chuẩn"
-#: builtin/commit.c:639
+#: builtin/commit.c:638
#, c-format
msgid "could not read log file '%s'"
msgstr "không đọc được tệp nhật ký '%s'"
-#: builtin/commit.c:645
+#: builtin/commit.c:644
msgid "commit has empty message"
msgstr "lần chuyển giao (commit) có ghi chú trống rỗng"
-#: builtin/commit.c:661
+#: builtin/commit.c:660
msgid "could not read MERGE_MSG"
msgstr "không thể đọc MERGE_MSG"
-#: builtin/commit.c:665
+#: builtin/commit.c:664
msgid "could not read SQUASH_MSG"
msgstr "không thể đọc SQUASH_MSG"
-#: builtin/commit.c:669
+#: builtin/commit.c:668
#, c-format
msgid "could not read '%s'"
msgstr "Không thể đọc '%s'."
-#: builtin/commit.c:721
+#: builtin/commit.c:720
msgid "could not write commit template"
msgstr "không thể ghi mẫu commit"
-#: builtin/commit.c:732
+#: builtin/commit.c:731
#, c-format
msgid ""
"\n"
"\t%s\n"
"và thử lại.\n"
-#: builtin/commit.c:737
+#: builtin/commit.c:736
#, c-format
msgid ""
"\n"
"\t%s\n"
"và thử lại.\n"
-#: builtin/commit.c:749
+#: builtin/commit.c:748
msgid ""
"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be ignored, and an empty message aborts the commit.\n"
"Hãy nhập vào các thông tin để giải thích các thay đổi của bạn. Những dòng được\n"
"bắt đầu bằng '#' sẽ được bỏ qua, phần chú thích này nếu rỗng sẽ làm hủy bỏ lần chuyển giao (commit).\n"
-#: builtin/commit.c:754
+#: builtin/commit.c:753
msgid ""
"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be kept; you may remove them yourself if you want to.\n"
"bắt đầu bằng '#' sẽ được bỏ qua; bạn có thể xóa chúng đi nếu muốn.\n"
"Phần chú thích này nếu rỗng sẽ làm hủy bỏ lần chuyển giao (commit).\n"
-#: builtin/commit.c:767
+#: builtin/commit.c:766
#, c-format
msgid "%sAuthor: %s"
msgstr "%sTác giả: %s"
-#: builtin/commit.c:774
+#: builtin/commit.c:773
#, c-format
msgid "%sCommitter: %s"
msgstr "%sNgười chuyển giao (commit): %s"
-#: builtin/commit.c:794
+#: builtin/commit.c:793
msgid "Cannot read index"
msgstr "không đọc được bảng mục lục"
-#: builtin/commit.c:831
+#: builtin/commit.c:830
msgid "Error building trees"
msgstr "Gặp lỗi khi xây dựng cây"
-#: builtin/commit.c:846
+#: builtin/commit.c:845
#: builtin/tag.c:361
#, c-format
msgid "Please supply the message using either -m or -F option.\n"
msgstr "Xin hãy áp dụng thông điệp sử dụng hoặc là tùy chọn -m hoặc là -F.\n"
-#: builtin/commit.c:943
+#: builtin/commit.c:942
#, c-format
msgid "No existing author found with '%s'"
msgstr "Không tìm thấy tác giả đã sẵn có với '%s'"
-#: builtin/commit.c:958
-#: builtin/commit.c:1158
+#: builtin/commit.c:957
+#: builtin/commit.c:1157
#, c-format
msgid "Invalid untracked files mode '%s'"
msgstr "Chế độ cho các tập tin không bị theo vết không hợp lệ '%s'"
-#: builtin/commit.c:998
+#: builtin/commit.c:997
msgid "Using both --reset-author and --author does not make sense"
msgstr "Sử dụng cả hai tùy chọn --reset-author và --author không hợp lý"
-#: builtin/commit.c:1009
+#: builtin/commit.c:1008
msgid "You have nothing to amend."
msgstr "Không có gì để amend (tu bổ) cả."
-#: builtin/commit.c:1012
+#: builtin/commit.c:1011
msgid "You are in the middle of a merge -- cannot amend."
msgstr "Bạn đang ở giữa của quá trình hòa trộn -- không thể thực hiện amend (tu bổ)."
-#: builtin/commit.c:1014
+#: builtin/commit.c:1013
msgid "You are in the middle of a cherry-pick -- cannot amend."
msgstr "Bạn đang ở giữa của quá trình cherry-pick -- không thể thực hiện amend (tu bổ)."
-#: builtin/commit.c:1017
+#: builtin/commit.c:1016
msgid "Options --squash and --fixup cannot be used together"
msgstr "Các tùy chọn --squash và --fixup không thể sử dụng cùng với nhau"
-#: builtin/commit.c:1027
+#: builtin/commit.c:1026
msgid "Only one of -c/-C/-F/--fixup can be used."
msgstr "Chỉ một tùy chọn trong số -c/-C/-F/--fixup được sử dụng"
-#: builtin/commit.c:1029
+#: builtin/commit.c:1028
msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
msgstr "Tùy chọn -m không thể được tổ hợp cùng với -c/-C/-F/--fixup."
-#: builtin/commit.c:1037
+#: builtin/commit.c:1036
msgid "--reset-author can be used only with -C, -c or --amend."
msgstr "--reset-author chỉ có thể được sử dụng với tùy chọn -C, -c hay --amend."
-#: builtin/commit.c:1054
+#: builtin/commit.c:1053
msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
msgstr "Chỉ một trong các tùy chọn --include/--only/--all/--interactive/--patch được sử dụng."
-#: builtin/commit.c:1056
+#: builtin/commit.c:1055
msgid "No paths with --include/--only does not make sense."
msgstr "Không đường dẫn với các tùy chọn --include/--only không hợp lý."
-#: builtin/commit.c:1058
+#: builtin/commit.c:1057
msgid "Clever... amending the last one with dirty index."
msgstr "Giỏi... đang tu bổ cái cuối với bảng mục lục phi nghĩa."
-#: builtin/commit.c:1060
+#: builtin/commit.c:1059
msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
msgstr "Những đường dẫn rõ ràng được chỉ ra không có tùy chọn -i cũng không -o; đang giả định --only những-đường-dẫn..."
-#: builtin/commit.c:1070
+#: builtin/commit.c:1069
#: builtin/tag.c:577
#, c-format
msgid "Invalid cleanup mode %s"
msgstr "Chế độ dọn dẹp không hợp lệ %s"
-#: builtin/commit.c:1075
+#: builtin/commit.c:1074
msgid "Paths with -a does not make sense."
msgstr "Các đường dẫn với tùy chọn -a không hợp lý."
-#: builtin/commit.c:1258
+#: builtin/commit.c:1257
msgid "couldn't look up newly created commit"
msgstr "không thể tìm thấy lần chuyển giao (commit) mới hơn đã được tạo"
-#: builtin/commit.c:1260
+#: builtin/commit.c:1259
msgid "could not parse newly created commit"
msgstr "không thể phân tích cú pháp của đối tượng chuyển giao mới hơn đã được tạo"
-#: builtin/commit.c:1301
+#: builtin/commit.c:1300
msgid "detached HEAD"
msgstr "đã rời khỏi HEAD"
-#: builtin/commit.c:1303
+#: builtin/commit.c:1302
msgid " (root-commit)"
msgstr " (root-commit)"
-#: builtin/commit.c:1447
+#: builtin/commit.c:1446
msgid "could not parse HEAD commit"
msgstr "không thể phân tích commit (lần chuyển giao) HEAD"
-#: builtin/commit.c:1485
+#: builtin/commit.c:1484
#: builtin/merge.c:509
#, c-format
msgid "could not open '%s' for reading"
msgstr "không thể mở %s' để đọc"
-#: builtin/commit.c:1492
+#: builtin/commit.c:1491
#, c-format
msgid "Corrupt MERGE_HEAD file (%s)"
msgstr "Tập tin MERGE_HEAD sai hỏng (%s)"
-#: builtin/commit.c:1499
+#: builtin/commit.c:1498
msgid "could not read MERGE_MODE"
msgstr "không thể đọc MERGE_MODE"
-#: builtin/commit.c:1518
+#: builtin/commit.c:1517
#, c-format
msgid "could not read commit message: %s"
msgstr "không thể đọc thông điệp (message) commit (lần chuyển giao): %s"
-#: builtin/commit.c:1532
+#: builtin/commit.c:1531
#, c-format
msgid "Aborting commit; you did not edit the message.\n"
msgstr "Đang bỏ qua việc chuyển giao (commit); bạn đã không biên soạn thông điệp (message).\n"
-#: builtin/commit.c:1537
+#: builtin/commit.c:1536
#, c-format
msgid "Aborting commit due to empty commit message.\n"
msgstr "Đang bỏ qua lần chuyển giao (commit) bởi vì thông điệp của nó trống rỗng.\n"
-#: builtin/commit.c:1552
+#: builtin/commit.c:1551
#: builtin/merge.c:936
#: builtin/merge.c:961
msgid "failed to write commit object"
msgstr "gặp lỗi khi ghi đối tượng chuyển giao (commit)"
-#: builtin/commit.c:1573
+#: builtin/commit.c:1572
msgid "cannot lock HEAD ref"
msgstr "không thể khóa HEAD ref (tham chiếu)"
-#: builtin/commit.c:1577
+#: builtin/commit.c:1576
msgid "cannot update HEAD ref"
msgstr "không thể cập nhật HEAD ref (tham chiếu)"
-#: builtin/commit.c:1588
+#: builtin/commit.c:1587
msgid ""
"Repository has been updated, but unable to write\n"
"new_index file. Check that disk is not full or quota is\n"
msgid "Not a git repository"
msgstr "Không phải là kho git"
-#: builtin/diff.c:347
+#: builtin/diff.c:341
#, c-format
msgid "invalid object '%s' given."
msgstr "đối tượng đã cho '%s' không hợp lệ."
-#: builtin/diff.c:352
+#: builtin/diff.c:346
#, c-format
msgid "more than %d trees given: '%s'"
msgstr "đã chỉ ra nhiều hơn %d cây (tree): '%s'"
-#: builtin/diff.c:362
+#: builtin/diff.c:356
#, c-format
msgid "more than two blobs given: '%s'"
msgstr "đã cho nhiều hơn hai đối tượng blob: '%s'"
-#: builtin/diff.c:370
+#: builtin/diff.c:364
#, c-format
msgid "unhandled object '%s' given."
msgstr "đã cho đối tượng không thể nắm giữ '%s'."
msgid "cannot open '%s'"
msgstr "không mở được '%s'"
-#: builtin/grep.c:888
+#: builtin/grep.c:885
msgid "no pattern given."
msgstr "chưa chỉ ra mẫu."
-#: builtin/grep.c:902
+#: builtin/grep.c:899
#, c-format
msgid "bad object %s"
msgstr "đối tượng sai %s"
-#: builtin/grep.c:943
+#: builtin/grep.c:940
msgid "--open-files-in-pager only works on the worktree"
msgstr "--open-files-in-pager chỉ làm việc trên cây-làm-việc"
-#: builtin/grep.c:966
+#: builtin/grep.c:963
msgid "--cached or --untracked cannot be used with --no-index."
msgstr "--cached hay --untracked không được sử dụng với --no-index."
-#: builtin/grep.c:971
+#: builtin/grep.c:968
msgid "--no-index or --untracked cannot be used with revs."
msgstr "--no-index hay --untracked không được sử dụng cùng với các tùy chọn liên quan đến revs."
-#: builtin/grep.c:974
+#: builtin/grep.c:971
msgid "--[no-]exclude-standard cannot be used for tracked contents."
msgstr "--[no-]exclude-standard không thể sử dụng cho nội dung lưu dấu vết."
-#: builtin/grep.c:982
+#: builtin/grep.c:979
msgid "both --cached and trees are given."
msgstr "cả hai --cached và các cây phải được chỉ ra."
-#: builtin/help.c:59
+#: builtin/help.c:63
#, c-format
msgid "unrecognized help format '%s'"
msgstr "không nhận ra định dạng trợ giúp '%s'"
-#: builtin/help.c:87
+#: builtin/help.c:91
msgid "Failed to start emacsclient."
msgstr "Lỗi khởi chạy emacsclient."
-#: builtin/help.c:100
+#: builtin/help.c:104
msgid "Failed to parse emacsclient version."
msgstr "Gặp lỗi khi phân tích phiên bản emacsclient."
-#: builtin/help.c:108
+#: builtin/help.c:112
#, c-format
msgid "emacsclient version '%d' too old (< 22)."
msgstr "phiên bản của emacsclient '%d' quá cũ (< 22)."
-#: builtin/help.c:126
-#: builtin/help.c:154
-#: builtin/help.c:163
-#: builtin/help.c:171
+#: builtin/help.c:130
+#: builtin/help.c:158
+#: builtin/help.c:167
+#: builtin/help.c:175
#, c-format
msgid "failed to exec '%s': %s"
msgstr "gặp lỗi khi thực thi '%s': %s"
-#: builtin/help.c:211
+#: builtin/help.c:215
#, c-format
msgid ""
"'%s': path for unsupported man viewer.\n"
"'%s': đường dẫn không hỗ trợ bộ trình chiếu man.\n"
"Hãy cân nhắc đến việc sử dụng 'man.<tool>.cmd' để thay thế."
-#: builtin/help.c:223
+#: builtin/help.c:227
#, c-format
msgid ""
"'%s': cmd for supported man viewer.\n"
"'%s': cmd (lệnh) hỗ trợ bộ trình chiếu man.\n"
"Hãy cân nhắc đến việc sử dụng 'man.<tool>.path' để thay thế."
-#: builtin/help.c:287
+#: builtin/help.c:291
msgid "The most commonly used git commands are:"
msgstr "Những lệnh git hay được sử dụng nhất là:"
-#: builtin/help.c:355
+#: builtin/help.c:359
#, c-format
msgid "'%s': unknown man viewer."
msgstr "'%s': không rõ chương trình xem man."
-#: builtin/help.c:372
+#: builtin/help.c:376
msgid "no man viewer handled the request"
msgstr "không có trình xem trợ giúp dạng manpage tiếp hợp với yêu cầu"
-#: builtin/help.c:380
+#: builtin/help.c:384
msgid "no info viewer handled the request"
msgstr "không có trình xem trợ giúp dạng info tiếp hợp với yêu cầu"
-#: builtin/help.c:391
+#: builtin/help.c:395
#, c-format
msgid "'%s': not a documentation directory."
msgstr "'%s': không phải là một thư mục tài liệu."
-#: builtin/help.c:432
-#: builtin/help.c:439
+#: builtin/help.c:436
+#: builtin/help.c:443
#, c-format
msgid "usage: %s%s"
msgstr "cách sử dụng: %s%s"
-#: builtin/help.c:453
+#: builtin/help.c:459
#, c-format
msgid "`git %s' is aliased to `%s'"
msgstr "`git %s' được đặt bí danh thành `%s'"
-#: builtin/index-pack.c:169
+#: builtin/index-pack.c:170
#, c-format
msgid "object type mismatch at %s"
msgstr "kiểu đối tượng không khớp tại %s"
-#: builtin/index-pack.c:189
+#: builtin/index-pack.c:190
msgid "object of unexpected type"
msgstr "đối tượng của kiểu không mong đợi"
-#: builtin/index-pack.c:226
+#: builtin/index-pack.c:227
#, c-format
msgid "cannot fill %d byte"
msgid_plural "cannot fill %d bytes"
msgstr[0] "không thể điền vào %d byte"
msgstr[1] "không thể điền vào %d byte"
-#: builtin/index-pack.c:236
+#: builtin/index-pack.c:237
msgid "early EOF"
msgstr "vừa đúng lúc EOF"
-#: builtin/index-pack.c:237
+#: builtin/index-pack.c:238
msgid "read error on input"
msgstr "lỗi đọc ở đầu vào"
-#: builtin/index-pack.c:249
+#: builtin/index-pack.c:250
msgid "used more bytes than were available"
msgstr "sử dụng nhiều hơn số lượng byte mà nó sẵn có"
-#: builtin/index-pack.c:256
+#: builtin/index-pack.c:257
msgid "pack too large for current definition of off_t"
msgstr "pack quá lớn so với định nghĩa hiện tại của kiểu off_t"
-#: builtin/index-pack.c:272
+#: builtin/index-pack.c:273
#, c-format
msgid "unable to create '%s'"
msgstr "không thể tạo '%s'"
-#: builtin/index-pack.c:277
+#: builtin/index-pack.c:278
#, c-format
msgid "cannot open packfile '%s'"
msgstr "không thể mở packfile '%s'"
-#: builtin/index-pack.c:291
+#: builtin/index-pack.c:292
msgid "pack signature mismatch"
msgstr "chữ ký cho pack không khớp"
-#: builtin/index-pack.c:311
+#: builtin/index-pack.c:312
#, c-format
msgid "pack has bad object at offset %lu: %s"
msgstr "pack có đối tượng sai khoảng bù (offset) %lu: %s"
-#: builtin/index-pack.c:405
+#: builtin/index-pack.c:434
#, c-format
msgid "inflate returned %d"
msgstr "xả nén trả về %d"
-#: builtin/index-pack.c:450
+#: builtin/index-pack.c:483
msgid "offset value overflow for delta base object"
msgstr "tràn giá trị khoảng bù cho đối tượng delta cơ sở"
-#: builtin/index-pack.c:458
+#: builtin/index-pack.c:491
msgid "delta base offset is out of bound"
msgstr "khoảng bù cơ sở cho delta nằm ngoài phạm vi"
-#: builtin/index-pack.c:466
+#: builtin/index-pack.c:499
#, c-format
msgid "unknown object type %d"
msgstr "không hiểu kiểu đối tượng %d"
-#: builtin/index-pack.c:495
+#: builtin/index-pack.c:531
msgid "cannot pread pack file"
msgstr "không thể chạy hàm pread cho tập tin pack"
-#: builtin/index-pack.c:497
+#: builtin/index-pack.c:533
#, c-format
msgid "premature end of pack file, %lu byte missing"
msgid_plural "premature end of pack file, %lu bytes missing"
msgstr[0] "tập tin pack bị kết thúc sớm, %lu byte bị thiếu"
msgstr[1] "tập tin pack bị kết thúc sớm, %lu byte bị thiếu"
-#: builtin/index-pack.c:510
+#: builtin/index-pack.c:555
msgid "serious inflate inconsistency"
msgstr "sự mâu thuẫn xả nén nghiêm trọng"
-#: builtin/index-pack.c:583
-#, c-format
-msgid "cannot read existing object %s"
-msgstr "không thể đọc đối tượng đã tồn tại %s"
-
-#: builtin/index-pack.c:586
+#: builtin/index-pack.c:646
+#: builtin/index-pack.c:652
+#: builtin/index-pack.c:675
+#: builtin/index-pack.c:709
+#: builtin/index-pack.c:718
#, c-format
msgid "SHA1 COLLISION FOUND WITH %s !"
msgstr "SỰ VA CHẠM SHA1 ĐÃ XẢY RA VỚI %s!"
-#: builtin/index-pack.c:598
+#: builtin/index-pack.c:649
+#: builtin/pack-objects.c:170
+#: builtin/pack-objects.c:262
+#, c-format
+msgid "unable to read %s"
+msgstr "không thể đọc %s"
+
+#: builtin/index-pack.c:715
+#, c-format
+msgid "cannot read existing object %s"
+msgstr "không thể đọc đối tượng đã tồn tại %s"
+
+#: builtin/index-pack.c:729
#, c-format
msgid "invalid blob object %s"
msgstr "đối tượng blob không hợp lệ %s"
-#: builtin/index-pack.c:610
+#: builtin/index-pack.c:744
#, c-format
msgid "invalid %s"
msgstr "%s không hợp lệ"
-#: builtin/index-pack.c:612
+#: builtin/index-pack.c:746
msgid "Error in object"
msgstr "Lỗi trong đối tượng"
-#: builtin/index-pack.c:614
+#: builtin/index-pack.c:748
#, c-format
msgid "Not all child objects of %s are reachable"
msgstr "Không phải tất cả các đối tượng con của %s là có thể với tới được"
-#: builtin/index-pack.c:687
-#: builtin/index-pack.c:713
+#: builtin/index-pack.c:818
+#: builtin/index-pack.c:844
msgid "failed to apply delta"
msgstr "gặp lỗi khi áp dụng delta"
-#: builtin/index-pack.c:850
+#: builtin/index-pack.c:983
msgid "Receiving objects"
msgstr "Đang nhận về các đối tượng"
-#: builtin/index-pack.c:850
+#: builtin/index-pack.c:983
msgid "Indexing objects"
msgstr "Các đối tượng bảng mục lục"
-#: builtin/index-pack.c:872
+#: builtin/index-pack.c:1009
msgid "pack is corrupted (SHA1 mismatch)"
msgstr "pack bị sai hỏng (SHA1 không khớp)"
-#: builtin/index-pack.c:877
+#: builtin/index-pack.c:1014
msgid "cannot fstat packfile"
msgstr "không thể fstat packfile"
-#: builtin/index-pack.c:880
+#: builtin/index-pack.c:1017
msgid "pack has junk at the end"
msgstr "pack có phần thừa ở cuối"
-#: builtin/index-pack.c:903
+#: builtin/index-pack.c:1028
+msgid "confusion beyond insanity in parse_pack_objects()"
+msgstr "lộn xộn hơn cả điên rồ khi chạy hàm parse_pack_objects()"
+
+#: builtin/index-pack.c:1051
msgid "Resolving deltas"
msgstr "Đang phân giải các delta"
-#: builtin/index-pack.c:954
+#: builtin/index-pack.c:1102
msgid "confusion beyond insanity"
msgstr "lộn xộn hơn cả điên rồ"
-#: builtin/index-pack.c:973
+#: builtin/index-pack.c:1121
#, c-format
msgid "pack has %d unresolved delta"
msgid_plural "pack has %d unresolved deltas"
msgstr[0] "pack có %d delta chưa được giải quyết"
msgstr[1] "pack có %d delta chưa được giải quyết"
-#: builtin/index-pack.c:998
+#: builtin/index-pack.c:1146
#, c-format
msgid "unable to deflate appended object (%d)"
msgstr "không thể xả đối tượng nối thêm (%d)"
-#: builtin/index-pack.c:1077
+#: builtin/index-pack.c:1225
#, c-format
msgid "local object %s is corrupt"
msgstr "đối tượng nội bộ %s bị hỏng"
-#: builtin/index-pack.c:1101
+#: builtin/index-pack.c:1249
msgid "error while closing pack file"
msgstr "gặp lỗi trong khi đóng tập tin pack"
-#: builtin/index-pack.c:1114
+#: builtin/index-pack.c:1262
#, c-format
msgid "cannot write keep file '%s'"
msgstr "không thể ghi tập tin giữ lại '%s'"
-#: builtin/index-pack.c:1122
+#: builtin/index-pack.c:1270
#, c-format
msgid "cannot close written keep file '%s'"
msgstr "không thể đóng tập tin giữ lại đã được ghi '%s'"
-#: builtin/index-pack.c:1135
+#: builtin/index-pack.c:1283
msgid "cannot store pack file"
msgstr "không thể lưu tập tin pack"
-#: builtin/index-pack.c:1146
+#: builtin/index-pack.c:1294
msgid "cannot store index file"
msgstr "không thể lưu trữ tập tin ghi mục lục"
-#: builtin/index-pack.c:1247
+#: builtin/index-pack.c:1395
#, c-format
msgid "Cannot open existing pack file '%s'"
msgstr "Không thể mở tập tin pack đã sẵn có '%s' "
-#: builtin/index-pack.c:1249
+#: builtin/index-pack.c:1397
#, c-format
msgid "Cannot open existing pack idx file for '%s'"
msgstr "Không thể mở tập tin 'pack idx' cho '%s'"
-#: builtin/index-pack.c:1296
+#: builtin/index-pack.c:1444
#, c-format
msgid "non delta: %d object"
msgid_plural "non delta: %d objects"
msgstr[0] "không delta: %d đối tượng"
msgstr[1] "không delta: %d đối tượng"
-#: builtin/index-pack.c:1303
+#: builtin/index-pack.c:1451
#, c-format
msgid "chain length = %d: %lu object"
msgid_plural "chain length = %d: %lu objects"
msgstr[0] "chiều dài xích = %d: %lu đối tượng"
msgstr[1] "chiều dài xích = %d: %lu đối tượng"
-#: builtin/index-pack.c:1330
+#: builtin/index-pack.c:1478
msgid "Cannot come back to cwd"
msgstr "Không thể quay lại cwd"
-#: builtin/index-pack.c:1374
-#: builtin/index-pack.c:1377
-#: builtin/index-pack.c:1389
-#: builtin/index-pack.c:1393
+#: builtin/index-pack.c:1522
+#: builtin/index-pack.c:1525
+#: builtin/index-pack.c:1537
+#: builtin/index-pack.c:1541
#, c-format
msgid "bad %s"
msgstr "%s sai"
-#: builtin/index-pack.c:1407
+#: builtin/index-pack.c:1555
msgid "--fix-thin cannot be used without --stdin"
msgstr "--fix-thin không thể được dùng mà không có --stdin"
-#: builtin/index-pack.c:1411
-#: builtin/index-pack.c:1421
+#: builtin/index-pack.c:1559
+#: builtin/index-pack.c:1569
#, c-format
msgid "packfile name '%s' does not end with '.pack'"
msgstr "tên tập tin packfile '%s' không được kết thúc bằng đuôi '.pack'"
-#: builtin/index-pack.c:1430
+#: builtin/index-pack.c:1578
msgid "--verify with no packfile name given"
msgstr "dùng tùy chọn --verify mà không đưa ra tên packfile"
msgid "Cannot access work tree '%s'"
msgstr "không thể truy cập cây (tree) làm việc '%s'"
-#: builtin/log.c:188
+#: builtin/log.c:189
#, c-format
msgid "Final output: %d %s\n"
msgstr "Kết xuất cuối cùng: %d %s\n"
-#: builtin/log.c:401
-#: builtin/log.c:489
+#: builtin/log.c:402
+#: builtin/log.c:490
#, c-format
msgid "Could not read object %s"
msgstr "Không thể đọc đối tượng %s"
-#: builtin/log.c:513
+#: builtin/log.c:514
#, c-format
msgid "Unknown type: %d"
msgstr "Không nhận ra kiểu: %d"
-#: builtin/log.c:602
+#: builtin/log.c:603
msgid "format.headers without value"
msgstr "format.headers không có giá trị cụ thể"
-#: builtin/log.c:675
+#: builtin/log.c:677
msgid "name of output directory is too long"
msgstr "tên của thư mục kết xuất quá dài"
-#: builtin/log.c:686
+#: builtin/log.c:688
#, c-format
msgid "Cannot open patch file %s"
msgstr "Không thể mở tập tin miếng vá: %s"
-#: builtin/log.c:700
+#: builtin/log.c:702
msgid "Need exactly one range."
msgstr "Cần chính xác một vùng."
-#: builtin/log.c:708
+#: builtin/log.c:710
msgid "Not a range."
msgstr "Không phải là một vùng."
-#: builtin/log.c:745
-msgid "Could not extract email from committer identity."
-msgstr "Không thể rút trích địa chỉ thư điện tử từ định danh người chuyển giao"
-
-#: builtin/log.c:791
+#: builtin/log.c:787
msgid "Cover letter needs email format"
msgstr "'Cover letter' cần cho định dạng thư"
-#: builtin/log.c:885
+#: builtin/log.c:860
#, c-format
msgid "insane in-reply-to: %s"
msgstr "in-reply-to điên rồ: %s"
-#: builtin/log.c:958
+#: builtin/log.c:933
msgid "Two output directories?"
msgstr "Hai thư mục kết xuất?"
-#: builtin/log.c:1179
+#: builtin/log.c:1154
#, c-format
msgid "bogus committer info %s"
msgstr "thông tin người chuyển giao không có thực %s"
-#: builtin/log.c:1224
+#: builtin/log.c:1199
msgid "-n and -k are mutually exclusive."
msgstr "-n và -k loại từ lẫn nhau."
-#: builtin/log.c:1226
+#: builtin/log.c:1201
msgid "--subject-prefix and -k are mutually exclusive."
msgstr "--subject-prefix và -k xung khắc nhau."
-#: builtin/log.c:1234
+#: builtin/log.c:1209
msgid "--name-only does not make sense"
msgstr "--name-only không hợp lý"
-#: builtin/log.c:1236
+#: builtin/log.c:1211
msgid "--name-status does not make sense"
msgstr "--name-status không hợp lý"
-#: builtin/log.c:1238
+#: builtin/log.c:1213
msgid "--check does not make sense"
msgstr "--check không hợp lý"
-#: builtin/log.c:1261
+#: builtin/log.c:1236
msgid "standard output, or directory, which one?"
msgstr "đầu ra chuẩn, hay thư mục, chọn cái nào?"
-#: builtin/log.c:1263
+#: builtin/log.c:1238
#, c-format
msgid "Could not create directory '%s'"
msgstr "Không thể tạo thư mục '%s'"
-#: builtin/log.c:1416
+#: builtin/log.c:1391
msgid "Failed to create output files"
msgstr "Gặp lỗi khi tạo các tập tin kết xuất"
-#: builtin/log.c:1520
+#: builtin/log.c:1495
#, c-format
msgid "Could not find a tracked remote branch, please specify <upstream> manually.\n"
msgstr "Không tìm thấy nhánh mạng bị theo vết, hãy chỉ định <dòng-ngược> một cách thủ công.\n"
-#: builtin/log.c:1536
-#: builtin/log.c:1538
-#: builtin/log.c:1550
+#: builtin/log.c:1511
+#: builtin/log.c:1513
+#: builtin/log.c:1525
#, c-format
msgid "Unknown commit %s"
msgstr "Không hiểu lần chuyển giao (commit) %s"
msgid "Unknown subcommand: %s"
msgstr "Không hiểu câu lệnh con: %s"
-#: builtin/pack-objects.c:2315
+#: builtin/pack-objects.c:183
+#: builtin/pack-objects.c:186
+#, c-format
+msgid "deflate error (%d)"
+msgstr "lỗi giải nén (%d)"
+
+#: builtin/pack-objects.c:2398
#, c-format
msgid "unsupported index version %s"
msgstr "phiên bản mục lục không được hỗ trợ %s"
-#: builtin/pack-objects.c:2319
+#: builtin/pack-objects.c:2402
#, c-format
msgid "bad index version '%s'"
msgstr "phiên bản mục lục sai '%s'"
-#: builtin/pack-objects.c:2342
+#: builtin/pack-objects.c:2425
#, c-format
msgid "option %s does not accept negative form"
msgstr "tùy chọn %s không chấp nhận dạng thức âm"
-#: builtin/pack-objects.c:2346
+#: builtin/pack-objects.c:2429
#, c-format
msgid "unable to parse value '%s' for option %s"
msgstr "không thể phân tích giá trị '%s' cho tùy chọn %s"
"\n"
" git push --set-upstream %s %s\n"
msgstr ""
-"Nhánh hiện tại %s không có nhánh ngược dòng (upstream) nào.\n"
-"Để push (đẩy lên) nhánh hiện tại và đặt máy chủ như là ngược dòng (upstream), sử dụng\n"
+"Nhánh hiện tại %s không có nhánh dòng ngược (upstream) nào.\n"
+"Để push (đẩy lên) nhánh hiện tại và đặt máy chủ như là dòng ngược (upstream), sử dụng\n"
"\n"
" git push --set-upstream %s %s\n"
#: builtin/push.c:136
#, c-format
msgid "The current branch %s has multiple upstream branches, refusing to push."
-msgstr "Nhánh hiện tại %s có đa nhánh ngược dòng (upstream), từ chối push."
+msgstr "Nhánh hiện tại %s có đa nhánh dòng ngược (upstream), từ chối push."
#: builtin/push.c:139
#, c-format
#: builtin/remote.c:677
#, c-format
msgid ""
-"Not updating non-default fetch respec\n"
+"Not updating non-default fetch refspec\n"
"\t%s\n"
"\tPlease update the configuration manually if necessary."
msgstr ""
msgid "You need to set your committer info first"
msgstr "Bạn cần đặt thông tin về người chuyển giao mã nguồn trước đã"
+#: git-am.sh:95
+msgid ""
+"You seem to have moved HEAD since the last 'am' failure.\n"
+"Not rewinding to ORIG_HEAD"
+msgstr ""
+"Bạn có lẽ đã có HEAD đã bị di chuyển đi kể từ lần 'am' thất bại cuối cùng.\n"
+"Không thể chuyển tới ORIG_HEAD"
+
+#: git-am.sh:105
+#, sh-format
+msgid ""
+"When you have resolved this problem run \"$cmdline --resolved\".\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+"Khi bạn cần giải quyết vấn đề này hãy chạy lệnh \"$cmdline --resolved\".\n"
+"Nếu bạn có ý định bỏ qua miếng vá, thay vào đó bạn chạy \"$cmdline --skip\".\n"
+"Để phục hồi lại thành nhánh nguyên thủy và dừng việc vá lại thì chạy \"$cmdline --abort\"."
+
+#: git-am.sh:121
+msgid "Cannot fall back to three-way merge."
+msgstr "Đang trở lại để hòa trộn kiểu 'three-way'."
+
#: git-am.sh:137
msgid "Repository lacks necessary blobs to fall back on 3-way merge."
msgstr "Kho thiếu đối tượng blob cần thiết để trở về trên '3-way merge'."
msgid "Dirty index: cannot apply patches (dirty: $files)"
msgstr "Bảng mục lục sai: không thể áp dụng các miếng vá (sai: $files)"
+#: git-am.sh:671
+#, sh-format
+msgid ""
+"Patch is empty. Was it split wrong?\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+"Miếng vá trống rỗng. Nó đã bị chia cắt sai phải không?\n"
+"Nếu bạn thích bỏ qua miếng vá này, hãy chạy lệnh sau để thay thế \"$cmdline --skip\".\n"
+"Để phục hồi lại nhánh nguyên thủy và dừng vá lại hãy chạy lệnh \"$cmdline --abort\"."
+
+#: git-am.sh:708
+msgid "Patch does not have a valid e-mail address."
+msgstr "Miếng vá không có địa chỉ e-mail hợp lệ."
+
#: git-am.sh:755
msgid "cannot be interactive without stdin connected to a terminal."
msgstr "không thể được tương tác mà không có stdin kết nối với một thiết bị cuối"
+#: git-am.sh:759
+msgid "Commit Body is:"
+msgstr "Thân của lần chuyển giao (commit) là:"
+
#. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
#. in your translation. The program will only accept English
#. input at this point.
msgid "Applying: $FIRSTLINE"
msgstr "Đang áp dụng (miếng vá): $FIRSTLINE"
+#: git-am.sh:823
+msgid ""
+"No changes - did you forget to use 'git add'?\n"
+"If there is nothing left to stage, chances are that something else\n"
+"already introduced the same changes; you might want to skip this patch."
+msgstr ""
+"Không có thay đổi nào - bạn đã quên sử dụng lệnh 'git add' à?\n"
+"Nếu ở đây không có gì còn lại stage, tình cờ là có một số thứ khác\n"
+"đã sẵn được đưa vào với cùng nội dung thay đổi; bạn có lẽ muốn bỏ qua miếng vá này."
+
+#: git-am.sh:831
+msgid ""
+"You still have unmerged paths in your index\n"
+"did you forget to use 'git add'?"
+msgstr ""
+"Bạn vẫn có những đường dẫn chưa được hòa trộn trong bảng mục lục của mình\n"
+"bạn đã quên sử dụng lệnh 'git add' à?"
+
#: git-am.sh:847
msgid "No changes -- Patch already applied."
msgstr "Không thay đổi gì cả -- Miếng vá đã được áp dụng rồi."
+#: git-am.sh:857
+#, sh-format
+msgid "Patch failed at $msgnum $FIRSTLINE"
+msgstr "Vá gặp lỗi tại $msgnum $FIRSTLINE"
+
#: git-am.sh:873
msgid "applying to an empty history"
msgstr "áp dụng vào một lịch sử trống rỗng"
+#: git-bisect.sh:48
+msgid "You need to start by \"git bisect start\""
+msgstr "Bạn cần khởi đầu bằng \"git bisect start\""
+
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
#. at this point.
msgid "'git bisect bad' can take only one argument."
msgstr "'git bisect bad' có thể lấy chỉ một đối số."
+#. have bad but not good. we could bisect although
+#. this is less optimum.
+#: git-bisect.sh:273
+msgid "Warning: bisecting only with a bad commit."
+msgstr "Cảnh báo: chỉ thực hiện việc bisect với một lần chuyển giao (commit) sai."
+
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
#. at this point.
msgid "Are you sure [Y/n]? "
msgstr "Bạn có chắc chắn chưa [Y/n]?"
+#: git-bisect.sh:289
+msgid ""
+"You need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+"Bạn phải chỉ cho tôi ít nhất một điểm xét duyệt tốt và một điểm sai.\n"
+"(Bạn có thể sử dụng \"git bisect bad\" và \"git bisect good\" cho cái đó.)"
+
+#: git-bisect.sh:292
+msgid ""
+"You need to start by \"git bisect start\".\n"
+"You then need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+"Bạn cần bắt đầu bằng lệnh \"git bisect start\".\n"
+"Bạn sau đó cần phải chỉ cho tôi ít nhất một điểm xét duyệt đúng và một điểm sai.\n"
+"(Bạn có thể sử dụng \"git bisect bad\" và \"git bisect good\" cho chúng.)"
+
+#: git-bisect.sh:347
+#: git-bisect.sh:474
+msgid "We are not bisecting."
+msgstr "Chúng tôi không bisect."
+
#: git-bisect.sh:354
#, sh-format
msgid "'$invalid' is not a valid commit"
"Could not check out original HEAD '$branch'.\n"
"Try 'git bisect reset <commit>'."
msgstr ""
-"Không thể check out original HEAD '$branch'.\n"
-"Hãy thử 'git bisect reset <commit>'."
+"Không thể check-out HEAD nguyên thủy của '$branch'.\n"
+"Hãy thử 'git bisect reset <lần-chuyển-giao>'."
#: git-bisect.sh:390
msgid "No logfile given"
msgid "?? what are you talking about?"
msgstr "?? bạn đang nói gì thế?"
-#: git-bisect.sh:474
-msgid "We are not bisecting."
-msgstr "Chúng tôi không bisect."
+#: git-bisect.sh:420
+#, sh-format
+msgid "running $command"
+msgstr "đang chạy lệnh $command"
+
+#: git-bisect.sh:427
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"exit code $res from '$command' is < 0 or >= 128"
+msgstr ""
+"chạy bisect gặp lỗi:\n"
+"mã trả về $res từ lệnh '$command' là < 0 hoặc >= 128"
+
+#: git-bisect.sh:453
+msgid "bisect run cannot continue any more"
+msgstr "bisect không thể tiếp tục thêm được nữa"
+
+#: git-bisect.sh:459
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"'bisect_state $state' exited with error code $res"
+msgstr ""
+"chạy bisect gặp lỗi:\n"
+"'bisect_state $state' đã thoát ra với mã lỗi $res"
+
+#: git-bisect.sh:466
+msgid "bisect run success"
+msgstr "bisect chạy thành công"
#: git-pull.sh:21
msgid ""
msgid "updating an unborn branch with changes added to the index"
msgstr "đang cập nhật một nhánh chưa được sinh ra với các thay đổi được thêm vào bảng mục lục"
+#. The fetch involved updating the current branch.
+#. The working tree and the index file is still based on the
+#. $orig_head commit, but we are merging into $curr_head.
+#. First update the working tree to match $curr_head.
+#: git-pull.sh:228
+#, sh-format
+msgid ""
+"Warning: fetch updated the current branch head.\n"
+"Warning: fast-forwarding your working tree from\n"
+"Warning: commit $orig_head."
+msgstr ""
+"Cảnh báo: fetch đã cập nhật head nhánh hiện tại.\n"
+"Cảnh báo: đang fast-forward cây làm việc của bạn từ\n"
+"Cảnh báo: commit $orig_head."
+
#: git-pull.sh:253
msgid "Cannot merge multiple branches into empty head"
msgstr "Không thể hòa trộn nhiều nhánh và trong một head trống rỗng"
msgid "Cannot record working tree state"
msgstr "Không thể ghi lại trạng thái cây làm việc hiện hành"
+#. TRANSLATORS: $option is an invalid option, like
+#. `--blah-blah'. The 7 spaces at the beginning of the
+#. second line correspond to "error: ". So you should line
+#. up the second line with however many characters the
+#. translation of "error: " takes in your language. E.g. in
+#. English this is:
+#.
+#. $ git stash save --blah-blah 2>&1 | head -n 2
+#. error: unknown option for 'stash save': --blah-blah
+#. To provide a message, use git stash save -- '--blah-blah'
+#: git-stash.sh:202
+#, sh-format
+msgid ""
+"error: unknown option for 'stash save': $option\n"
+" To provide a message, use git stash save -- '$option'"
+msgstr ""
+"lỗi: không hiểu tùy chọn cho 'stash save': $option\n"
+" Để cung cấp một thông điệp, sử dụng git stash save -- '$option'"
+
#: git-stash.sh:223
msgid "No local changes to save"
msgstr "Không có thay đổi nội bộ nào được ghi lại"
msgid "Cannot unstage modified files"
msgstr "Không thể bỏ trạng thía của các tập tin đã được sửa chữa"
+#: git-stash.sh:474
+msgid "Index was not unstashed."
+msgstr "Bảng mục lục đã không được bỏ stash."
+
#: git-stash.sh:491
#, sh-format
msgid "Dropped ${REV} ($s)"
msgid "(To restore them type \"git stash apply\")"
msgstr "(Để phục hồi lại chúng hãy gõ \"git stash apply\")"
-#: git-submodule.sh:56
+#: git-submodule.sh:88
#, sh-format
msgid "cannot strip one component off url '$remoteurl'"
msgstr "không thể tháo bỏ một thành phần ra khỏi url '$remoteurl'"
-#: git-submodule.sh:109
+#: git-submodule.sh:145
#, sh-format
msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
msgstr "Không tìm thấy ánh xạ (mapping) mô-đun-con trong .gitmodules cho đường dẫn '$sm_path'"
-#: git-submodule.sh:150
+#: git-submodule.sh:186
#, sh-format
msgid "Clone of '$url' into submodule path '$sm_path' failed"
msgstr "Nhân bản '$url' vào đường dẫn mô-đun-con '$sm_path' gặp lỗi"
-#: git-submodule.sh:160
+#: git-submodule.sh:196
#, sh-format
msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
msgstr "Gitdir '$a' là bộ phận của đường dẫn mô-đun-con '$b' hoặc \"vice versa\""
-#: git-submodule.sh:249
+#: git-submodule.sh:285
#, sh-format
msgid "repo URL: '$repo' must be absolute or begin with ./|../"
msgstr "repo URL: '$repo' phải là đường dẫn tuyệt đối hoặc là bắt đầu bằng ./|../"
-#: git-submodule.sh:266
+#: git-submodule.sh:302
#, sh-format
msgid "'$sm_path' already exists in the index"
msgstr "'$sm_path' thực sự đã tồn tại ở bảng mục lục rồi"
-#: git-submodule.sh:283
+#: git-submodule.sh:306
+#, sh-format
+msgid ""
+"The following path is ignored by one of your .gitignore files:\n"
+"$sm_path\n"
+"Use -f if you really want to add it."
+msgstr ""
+"Các đường dẫn theo sau đây sẽ bị lờ đi bởi một trong các tập tin .gitignore của bạn:\n"
+"$sm_path\n"
+"Sử dụng -f nếu bạn thực sự muốn thêm nó vào."
+
+#: git-submodule.sh:317
+#, sh-format
+msgid "Adding existing repo at '$sm_path' to the index"
+msgstr "Đang thêm repo có sẵn tại '$sm_path' vào bảng mục lục"
+
+#: git-submodule.sh:319
#, sh-format
msgid "'$sm_path' already exists and is not a valid git repo"
msgstr "'$sm_path' đã tồn tại từ trước và không phải là một kho git hợp lệ"
-#: git-submodule.sh:297
+#: git-submodule.sh:333
#, sh-format
msgid "Unable to checkout submodule '$sm_path'"
msgstr "Không thể checkout mô-đun con '$sm_path'"
-#: git-submodule.sh:302
+#: git-submodule.sh:338
#, sh-format
msgid "Failed to add submodule '$sm_path'"
msgstr "Gặp lỗi khi thêm mô-đun con '$sm_path'"
-#: git-submodule.sh:307
+#: git-submodule.sh:343
#, sh-format
msgid "Failed to register submodule '$sm_path'"
msgstr "Gặp lỗi khi đăng ký với hệ thống mô-đun con '$sm_path'"
-#: git-submodule.sh:349
+#: git-submodule.sh:385
#, sh-format
msgid "Entering '$prefix$sm_path'"
msgstr "Đang nhập '$prefix$sm_path'"
-#: git-submodule.sh:363
+#: git-submodule.sh:399
#, sh-format
msgid "Stopping at '$sm_path'; script returned non-zero status."
msgstr "Dừng lại tại '$sm_path'; script trả về trạng thái khác không."
-#: git-submodule.sh:405
+#: git-submodule.sh:442
#, sh-format
msgid "No url found for submodule path '$sm_path' in .gitmodules"
msgstr "Không tìm thấy url cho đường dẫn mô-đun-con '$sm_path' trong .gitmodules"
-#: git-submodule.sh:414
+#: git-submodule.sh:451
#, sh-format
msgid "Failed to register url for submodule path '$sm_path'"
msgstr "Gặp lỗi khi đăng ký url cho đường dẫn mô-đun-con '$sm_path'"
-#: git-submodule.sh:422
-#, sh-format
-msgid "Failed to register update mode for submodule path '$sm_path'"
-msgstr "Gặp lỗi khi đăng ký chế độ cập nhật cho đường dẫn mô-đun-con '$sm_path'"
-
-#: git-submodule.sh:424
+#: git-submodule.sh:453
#, sh-format
msgid "Submodule '$name' ($url) registered for path '$sm_path'"
msgstr "Mô-đun-con '$name' ($url) được đăng ký cho đường dẫn '$sm_path'"
-#: git-submodule.sh:523
+#: git-submodule.sh:461
+#, sh-format
+msgid "Failed to register update mode for submodule path '$sm_path'"
+msgstr "Gặp lỗi khi đăng ký chế độ cập nhật cho đường dẫn mô-đun-con '$sm_path'"
+
+#: git-submodule.sh:560
#, sh-format
msgid ""
"Submodule path '$sm_path' not initialized\n"
"Đường dẫn mô-đun-con '$sm_path' chưa được khởi tạo\n"
"Có lẽ bạn muốn sử dụng lệnh 'update --init'?"
-#: git-submodule.sh:536
+#: git-submodule.sh:573
#, sh-format
msgid "Unable to find current revision in submodule path '$sm_path'"
msgstr "Không tìm thấy điểm xét lại hiện hành trong đường dẫn mô-đun-con '$sm_path'"
-#: git-submodule.sh:555
+#: git-submodule.sh:592
#, sh-format
msgid "Unable to fetch in submodule path '$sm_path'"
msgstr "Không thể lấy về (fetch) trong đường dẫn mô-đun-con '$sm_path'"
-#: git-submodule.sh:569
+#: git-submodule.sh:606
#, sh-format
msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
msgstr "Không thể rebase '$sha1' trong đường dẫn mô-đun-con '$sm_path'"
-#: git-submodule.sh:570
+#: git-submodule.sh:607
#, sh-format
msgid "Submodule path '$sm_path': rebased into '$sha1'"
msgstr "Đường dẫn mô-đun-con '$sm_path': được rebase vào trong '$sha1'"
-#: git-submodule.sh:575
+#: git-submodule.sh:612
#, sh-format
msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
msgstr "Không thể hòa trộn (merge) '$sha1' trong đường dẫn mô-đun-con '$sm_path'"
-#: git-submodule.sh:576
+#: git-submodule.sh:613
#, sh-format
msgid "Submodule path '$sm_path': merged in '$sha1'"
msgstr "Đường dẫn mô-đun-con '$sm_path': được hòa trộn vào '$sha1'"
-#: git-submodule.sh:581
+#: git-submodule.sh:618
#, sh-format
msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
msgstr "Không thể checkout '$sha1' trong đường dẫn mô-đun-con '$sm_path'"
-#: git-submodule.sh:582
+#: git-submodule.sh:619
#, sh-format
msgid "Submodule path '$sm_path': checked out '$sha1'"
msgstr "Đường dẫn mô-đun-con '$sm_path': được checkout '$sha1'"
-#: git-submodule.sh:604
-#: git-submodule.sh:927
+#: git-submodule.sh:641
+#: git-submodule.sh:964
#, sh-format
msgid "Failed to recurse into submodule path '$sm_path'"
msgstr "Gặp lỗi khi đệ quy vào trong đường dẫn mô-đun-con '$sm_path'"
-#: git-submodule.sh:712
-msgid "--"
-msgstr "--"
+#: git-submodule.sh:749
+msgid "--cached cannot be used with --files"
+msgstr "--cached không thể được sử dụng cùng với --files"
-#: git-submodule.sh:770
+#. unexpected type
+#: git-submodule.sh:789
+#, sh-format
+msgid "unexpected mode $mod_dst"
+msgstr "chế độ không như mong chờ $mod_dst"
+
+#: git-submodule.sh:807
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_src"
msgstr " Cảnh báo: $name không chứa lần chuyển giao (commit) $sha1_src"
-#: git-submodule.sh:773
+#: git-submodule.sh:810
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_dst"
msgstr " Cảnh báo: $name không chứa lần chuyển giao (commit) $sha1_dst"
-#: git-submodule.sh:776
+#: git-submodule.sh:813
#, sh-format
msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
msgstr " Cảnh báo: $name không chứa những lần chuyển giao (commit) $sha1_src và $sha1_dst"
-#: git-submodule.sh:801
+#: git-submodule.sh:838
msgid "blob"
msgstr "blob"
-#: git-submodule.sh:802
+#: git-submodule.sh:839
msgid "submodule"
msgstr "mô-đun con"
-#: git-submodule.sh:973
+#: git-submodule.sh:876
+msgid "# Submodules changed but not updated:"
+msgstr "# Những mô-đun-con đã bị thay đổi nhưng chưa được cập nhật:"
+
+#: git-submodule.sh:878
+msgid "# Submodule changes to be committed:"
+msgstr "# Những thay đổi mô-đun-con được chuyển giao (commit):"
+
+#: git-submodule.sh:1022
#, sh-format
msgid "Synchronizing submodule url for '$name'"
msgstr "Đang đồng bộ hóa url mô-đun-con cho '$name'"
+#~ msgid "--"
+#~ msgstr "--"
+
+#~ msgid "Could not extract email from committer identity."
+#~ msgstr ""
+#~ "Không thể rút trích địa chỉ thư điện tử từ định danh người chuyển giao"
+
#, fuzzy
#~ msgid "could not parse commit %s\n"
#~ msgstr "Không thể phân tích commit (lần chuyển giao) %s\n"
msgstr ""
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-05-21 08:57+0800\n"
-"PO-Revision-Date: 2012-06-01 17:43+0800\n"
+"POT-Creation-Date: 2012-07-03 10:23+0800\n"
+"PO-Revision-Date: 2012-07-04 22:38+0800\n"
"Last-Translator: Jiang Xin <worldhello.net@gmail.com>\n"
"Language-Team: GitHub <https://github.com/gotgit/git/>\n"
"Language: zh_CN\n"
msgid "unrecognized header: %s%s (%d)"
msgstr "未能识别的包头:%s%s (%d)"
-#: bundle.c:89 builtin/commit.c:697
+#: bundle.c:89 builtin/commit.c:696
#, c-format
msgid "could not open '%s'"
msgstr "不能打开 '%s'"
msgid "Repository lacks these prerequisite commits:"
msgstr "版本库缺少这些必备的提交:"
-#: bundle.c:164 sequencer.c:533 sequencer.c:965 builtin/log.c:289
-#: builtin/log.c:719 builtin/log.c:1335 builtin/log.c:1554 builtin/merge.c:347
+#: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
+#: builtin/log.c:721 builtin/log.c:1310 builtin/log.c:1529 builtin/merge.c:347
#: builtin/shortlog.c:181
msgid "revision walk setup failed"
msgstr "版本遍历设置失败"
msgstr[1] "这个包中含有 %d 个引用"
#: bundle.c:192
+msgid "The bundle records a complete history."
+msgstr "这个包记录一个完整历史。"
+
+#: bundle.c:195
#, c-format
msgid "The bundle requires this ref"
msgid_plural "The bundle requires these %d refs"
msgstr[0] "这个包需要这个引用"
msgstr[1] "这个包需要 %d 个这些引用"
-#: bundle.c:290
+#: bundle.c:294
msgid "rev-list died"
msgstr "rev-list 终止"
-#: bundle.c:296 builtin/log.c:1231 builtin/shortlog.c:284
+#: bundle.c:300 builtin/log.c:1206 builtin/shortlog.c:284
#, c-format
msgid "unrecognized argument: %s"
msgstr "未能识别的参数:%s"
-#: bundle.c:331
+#: bundle.c:335
#, c-format
msgid "ref '%s' is excluded by the rev-list options"
msgstr "引用 '%s' 被 rev-list 选项排除"
-#: bundle.c:376
+#: bundle.c:380
msgid "Refusing to create empty bundle."
msgstr "不能创建空包。"
-#: bundle.c:394
+#: bundle.c:398
msgid "Could not spawn pack-objects"
msgstr "不能生成 pack-objects 进程"
-#: bundle.c:412
+#: bundle.c:416
msgid "pack-objects died"
msgstr "pack-objects 终止"
-#: bundle.c:415
+#: bundle.c:419
#, c-format
msgid "cannot create '%s'"
msgstr "不能创建 '%s'"
-#: bundle.c:437
+#: bundle.c:441
msgid "index-pack died"
msgstr "index-pack 终止"
msgid "gpg failed to sign the data"
msgstr "gpg 无法为数据签名"
-#: grep.c:1280
+#: grep.c:1320
#, c-format
msgid "'%s': unable to read %s"
msgstr "'%s':无法读取 %s"
-#: grep.c:1297
+#: grep.c:1337
#, c-format
msgid "'%s': %s"
msgstr "'%s':%s"
-#: grep.c:1308
+#: grep.c:1348
#, c-format
msgid "'%s': short read %s"
msgstr "'%s':读取不完整 %s"
-#: help.c:207
+#: help.c:208
#, c-format
msgid "available git commands in '%s'"
msgstr "在 '%s' 下可用的 git 命令"
-#: help.c:214
+#: help.c:215
msgid "git commands available from elsewhere on your $PATH"
msgstr "在 $PATH 路径中的其他地方可用的 git 命令"
-#: help.c:270
+#: help.c:271
#, c-format
msgid ""
"'%s' appears to be a git command, but we were not\n"
"'%s' 像是一个 git 命令,但却无法运行。\n"
"可能是 git-%s 受损?"
-#: help.c:327
+#: help.c:328
msgid "Uh oh. Your system reports no Git commands at all."
msgstr "唉呀,您的系统中未发现 Git 命令。"
-#: help.c:349
+#: help.c:350
#, c-format
msgid ""
"WARNING: You called a Git command named '%s', which does not exist.\n"
"警告:您运行一个不存在的 Git 命令 '%s'。继续执行假定您要要运行的\n"
"是 '%s'"
-#: help.c:354
+#: help.c:355
#, c-format
msgid "in %0.1f seconds automatically..."
msgstr "在 %0.1f 秒钟后自动运行..."
-#: help.c:361
+#: help.c:362
#, c-format
msgid "git: '%s' is not a git command. See 'git --help'."
msgstr "git:'%s' 不是一个 git 命令。参见 'git --help'。"
-#: help.c:365
+#: help.c:366
msgid ""
"\n"
"Did you mean this?"
msgid " %s"
msgstr " %s"
-#: remote.c:1607
+#: remote.c:1629
#, c-format
msgid "Your branch is ahead of '%s' by %d commit.\n"
msgid_plural "Your branch is ahead of '%s' by %d commits.\n"
msgstr[0] "您的分支领先 '%s' 共 %d 个提交。\n"
msgstr[1] "您的分支领先 '%s' 共 %d 个提交。\n"
-#: remote.c:1613
+#: remote.c:1635
#, c-format
msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
msgid_plural ""
msgstr[0] "您的分支落后 '%s' 共 %d 个提交,并且可以快进。\n"
msgstr[1] "您的分支落后 '%s' 共 %d 个提交,并且可以快进。\n"
-#: remote.c:1621
+#: remote.c:1643
#, c-format
msgid ""
"Your branch and '%s' have diverged,\n"
"冲突解决完毕后,用 'git add <paths>' 或 'git rm <paths>'\n"
"对修正后的文件做标记,然后用 'git commit' 提交"
-#: sequencer.c:160 sequencer.c:741 sequencer.c:824
+#: sequencer.c:160 sequencer.c:758 sequencer.c:841
#, c-format
msgid "Could not write to %s"
msgstr "不能写入 %s"
msgid "Unable to update cache tree\n"
msgstr "不能更新缓存\n"
-#: sequencer.c:323
+#: sequencer.c:324
#, c-format
msgid "Could not parse commit %s\n"
msgstr "不能解析提交 %s\n"
-#: sequencer.c:328
+#: sequencer.c:329
#, c-format
msgid "Could not parse parent commit %s\n"
msgstr "不能解析父提交 %s\n"
-#: sequencer.c:358
+#: sequencer.c:395
msgid "Your index file is unmerged."
msgstr "您的索引文件未完成合并。"
-#: sequencer.c:361
+#: sequencer.c:398
msgid "You do not have a valid HEAD"
msgstr "您没有一个有效的 HEAD"
-#: sequencer.c:376
+#: sequencer.c:413
#, c-format
msgid "Commit %s is a merge but no -m option was given."
msgstr "提交 %s 是一个合并提交但未提供 -m 选项。"
-#: sequencer.c:384
+#: sequencer.c:421
#, c-format
msgid "Commit %s does not have parent %d"
msgstr "提交 %s 没有父提交 %d"
-#: sequencer.c:388
+#: sequencer.c:425
#, c-format
msgid "Mainline was specified but commit %s is not a merge."
msgstr "指定了主线但提交 %s 不是一个合并。"
#. TRANSLATORS: The first %s will be "revert" or
#. "cherry-pick", the second %s a SHA1
-#: sequencer.c:399
+#: sequencer.c:436
#, c-format
msgid "%s: cannot parse parent commit %s"
msgstr "%s:不能解析父提交 %s"
-#: sequencer.c:403
+#: sequencer.c:440
#, c-format
msgid "Cannot get commit message for %s"
msgstr "不能得到 %s 的提交说明"
-#: sequencer.c:491
+#: sequencer.c:524
#, c-format
msgid "could not revert %s... %s"
msgstr "不能还原 %s... %s"
-#: sequencer.c:492
+#: sequencer.c:525
#, c-format
msgid "could not apply %s... %s"
msgstr "不能应用 %s... %s"
-#: sequencer.c:536
+#: sequencer.c:553
msgid "empty commit set passed"
msgstr "提供了空的提交集"
-#: sequencer.c:544
+#: sequencer.c:561
#, c-format
msgid "git %s: failed to read the index"
msgstr "git %s:无法读取索引"
-#: sequencer.c:549
+#: sequencer.c:566
#, c-format
msgid "git %s: failed to refresh the index"
msgstr "git %s:无法刷新索引"
-#: sequencer.c:607
+#: sequencer.c:624
#, c-format
msgid "Cannot %s during a %s"
msgstr "无法 %s 在一个 %s 过程中"
-#: sequencer.c:629
+#: sequencer.c:646
#, c-format
msgid "Could not parse line %d."
msgstr "不能解析第 %d 行。"
-#: sequencer.c:634
+#: sequencer.c:651
msgid "No commits parsed."
msgstr "没有提交被解析。"
-#: sequencer.c:647
+#: sequencer.c:664
#, c-format
msgid "Could not open %s"
msgstr "不能打开 %s"
-#: sequencer.c:651
+#: sequencer.c:668
#, c-format
msgid "Could not read %s."
msgstr "不能读取 %s。"
-#: sequencer.c:658
+#: sequencer.c:675
#, c-format
msgid "Unusable instruction sheet: %s"
msgstr "无用的指令表单:%s"
-#: sequencer.c:686
+#: sequencer.c:703
#, c-format
msgid "Invalid key: %s"
msgstr "无效键名:%s"
-#: sequencer.c:689
+#: sequencer.c:706
#, c-format
msgid "Invalid value for %s: %s"
msgstr "%s 的值无效:%s"
-#: sequencer.c:701
+#: sequencer.c:718
#, c-format
msgid "Malformed options sheet: %s"
msgstr "非法的选项表单:%s"
-#: sequencer.c:722
+#: sequencer.c:739
msgid "a cherry-pick or revert is already in progress"
msgstr "一个拣选或还原操作已在进行"
-#: sequencer.c:723
+#: sequencer.c:740
msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
msgstr "尝试 \"git cherry-pick (--continue | --quit | --abort)\""
-#: sequencer.c:727
+#: sequencer.c:744
#, c-format
msgid "Could not create sequencer directory %s"
msgstr "不能创建序列目录 %s"
-#: sequencer.c:743 sequencer.c:828
+#: sequencer.c:760 sequencer.c:845
#, c-format
msgid "Error wrapping up %s."
msgstr "错误收尾 %s。"
-#: sequencer.c:762 sequencer.c:896
+#: sequencer.c:779 sequencer.c:913
msgid "no cherry-pick or revert in progress"
msgstr "没有拣选或还原操作在进行"
-#: sequencer.c:764
+#: sequencer.c:781
msgid "cannot resolve HEAD"
msgstr "不能解析 HEAD"
-#: sequencer.c:766
+#: sequencer.c:783
msgid "cannot abort from a branch yet to be born"
msgstr "不能从尚未建立的分支终止"
-#: sequencer.c:788 builtin/apply.c:3689
+#: sequencer.c:805 builtin/apply.c:3697
#, c-format
msgid "cannot open %s: %s"
msgstr "不能打开 %s:%s"
-#: sequencer.c:791
+#: sequencer.c:808
#, c-format
msgid "cannot read %s: %s"
msgstr "不能读取 %s:%s"
-#: sequencer.c:792
+#: sequencer.c:809
msgid "unexpected end of file"
msgstr "未预期的文件结束"
-#: sequencer.c:798
+#: sequencer.c:815
#, c-format
msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
msgstr "保存拣选提交前的 HEAD 文件 '%s' 损坏"
-#: sequencer.c:821
+#: sequencer.c:838
#, c-format
msgid "Could not format %s."
msgstr "不能格式化 %s。"
-#: sequencer.c:983
+#: sequencer.c:1000
msgid "Can't revert as initial commit"
msgstr "不能作为初始提交还原"
-#: sequencer.c:984
+#: sequencer.c:1001
msgid "Can't cherry-pick into empty head"
msgstr "不能拣选到空分支"
msgid "Upstream branch '%s' not stored as a remote-tracking branch"
msgstr "上游分支 '%s' 没有存储为一个远程跟踪分支"
-#: wt-status.c:135
+#: wrapper.c:413
+#, c-format
+msgid "unable to look up current user in the passwd file: %s"
+msgstr "无法在 passwd 文件中查询到当前用户:%s"
+
+#: wrapper.c:414
+msgid "no such user"
+msgstr "无此用户"
+
+#: wt-status.c:141
msgid "Unmerged paths:"
msgstr "未合并的路径:"
# 译者:注意保持前导空格
-#: wt-status.c:141 wt-status.c:158
+#: wt-status.c:168 wt-status.c:195
#, c-format
msgid " (use \"git reset %s <file>...\" to unstage)"
msgstr " (使用 \"git reset %s <file>...\" 撤出暂存区)"
# 译者:注意保持前导空格
-#: wt-status.c:143 wt-status.c:160
+#: wt-status.c:170 wt-status.c:197
msgid " (use \"git rm --cached <file>...\" to unstage)"
msgstr " (使用 \"git rm --cached <file>...\" 撤出暂存区)"
# 译者:注意保持前导空格
-#: wt-status.c:144
+#: wt-status.c:174
+msgid " (use \"git add <file>...\" to mark resolution)"
+msgstr " (使用 \"git add <file>...\" 标记解决方案)"
+
+# 译者:注意保持前导空格
+#: wt-status.c:176 wt-status.c:180
msgid " (use \"git add/rm <file>...\" as appropriate to mark resolution)"
msgstr " (酌情使用 \"git add/rm <file>...\" 标记解决方案)"
-#: wt-status.c:152
+# 译者:注意保持前导空格
+#: wt-status.c:178
+msgid " (use \"git rm <file>...\" to mark resolution)"
+msgstr " (使用 \"git rm <file>...\" 标记解决方案)"
+
+#: wt-status.c:189
msgid "Changes to be committed:"
msgstr "要提交的变更:"
-#: wt-status.c:170
+#: wt-status.c:207
msgid "Changes not staged for commit:"
msgstr "尚未暂存以备提交的变更:"
# 译者:注意保持前导空格
-#: wt-status.c:174
+#: wt-status.c:211
msgid " (use \"git add <file>...\" to update what will be committed)"
msgstr " (使用 \"git add <file>...\" 更新要提交的内容)"
# 译者:注意保持前导空格
-#: wt-status.c:176
+#: wt-status.c:213
msgid " (use \"git add/rm <file>...\" to update what will be committed)"
msgstr " (使用 \"git add/rm <file>...\" 更新要提交的内容)"
# 译者:注意保持前导空格
-#: wt-status.c:177
+#: wt-status.c:214
msgid ""
" (use \"git checkout -- <file>...\" to discard changes in working directory)"
msgstr " (使用 \"git checkout -- <file>...\" 丢弃工作区的改动)"
# 译者:注意保持前导空格
-#: wt-status.c:179
+#: wt-status.c:216
msgid " (commit or discard the untracked or modified content in submodules)"
msgstr " (提交或丢弃子模组中未跟踪或修改的内容)"
-#: wt-status.c:188
+#: wt-status.c:225
#, c-format
msgid "%s files:"
msgstr "%s文件:"
# 译者:注意保持前导空格
-#: wt-status.c:191
+#: wt-status.c:228
#, c-format
msgid " (use \"git %s <file>...\" to include in what will be committed)"
msgstr " (使用 \"git %s <file>...\" 以包含要提交的内容)"
-#: wt-status.c:208
+#: wt-status.c:245
msgid "bug"
msgstr "bug"
-#: wt-status.c:213
+#: wt-status.c:250
msgid "both deleted:"
msgstr "双方删除:"
-#: wt-status.c:214
+#: wt-status.c:251
msgid "added by us:"
msgstr "由我们添加:"
-#: wt-status.c:215
+#: wt-status.c:252
msgid "deleted by them:"
msgstr "由他们删除:"
-#: wt-status.c:216
+#: wt-status.c:253
msgid "added by them:"
msgstr "由他们添加:"
-#: wt-status.c:217
+#: wt-status.c:254
msgid "deleted by us:"
msgstr "由我们删除:"
-#: wt-status.c:218
+#: wt-status.c:255
msgid "both added:"
msgstr "双方添加:"
-#: wt-status.c:219
+#: wt-status.c:256
msgid "both modified:"
msgstr "双方修改:"
# 译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:249
+#: wt-status.c:286
msgid "new commits, "
msgstr "新提交, "
# 译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:251
+#: wt-status.c:288
msgid "modified content, "
msgstr "修改的内容, "
# 译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:253
+#: wt-status.c:290
msgid "untracked content, "
msgstr "未跟踪的内容, "
# 译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:267
+#: wt-status.c:304
#, c-format
msgid "new file: %s"
msgstr "新文件: %s"
# 译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:270
+#: wt-status.c:307
#, c-format
msgid "copied: %s -> %s"
msgstr "拷贝: %s -> %s"
# 译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:273
+#: wt-status.c:310
#, c-format
msgid "deleted: %s"
msgstr "删除: %s"
# 译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:276
+#: wt-status.c:313
#, c-format
msgid "modified: %s"
msgstr "修改: %s"
# 译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:279
+#: wt-status.c:316
#, c-format
msgid "renamed: %s -> %s"
msgstr "重命名: %s -> %s"
# 译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:282
+#: wt-status.c:319
#, c-format
msgid "typechange: %s"
msgstr "类型变更: %s"
# 译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:285
+#: wt-status.c:322
#, c-format
msgid "unknown: %s"
msgstr "未知: %s"
# 译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:288
+#: wt-status.c:325
#, c-format
msgid "unmerged: %s"
msgstr "未合并: %s"
-#: wt-status.c:291
+#: wt-status.c:328
#, c-format
msgid "bug: unhandled diff status %c"
msgstr "bug:未处理的差异状态 %c"
-#: wt-status.c:737
+#: wt-status.c:786
+msgid "You have unmerged paths."
+msgstr "您有路径尚未合并。"
+
+# 译者:注意保持前导空格
+#: wt-status.c:789 wt-status.c:913
+msgid " (fix conflicts and run \"git commit\")"
+msgstr " (解决冲突并运行 \"git commit\")"
+
+#: wt-status.c:792
+msgid "All conflicts fixed but you are still merging."
+msgstr "所有冲突已解决但您仍处于合并中。"
+
+# 译者:注意保持前导空格
+#: wt-status.c:795
+msgid " (use \"git commit\" to conclude merge)"
+msgstr " (使用 \"git commit\" 结束合并)"
+
+#: wt-status.c:805
+msgid "You are in the middle of an am session."
+msgstr "您正处于一个 am 过程中。"
+
+#: wt-status.c:808
+msgid "The current patch is empty."
+msgstr "当前的补丁为空。"
+
+# 译者:注意保持前导空格
+#: wt-status.c:812
+msgid " (fix conflicts and then run \"git am --resolved\")"
+msgstr " (解决冲突,然后运行 \"git am --resolved\")"
+
+# 译者:注意保持前导空格
+#: wt-status.c:814
+msgid " (use \"git am --skip\" to skip this patch)"
+msgstr " (使用 \"git am --skip\" 跳过此补丁)"
+
+# 译者:注意保持前导空格
+#: wt-status.c:816
+msgid " (use \"git am --abort\" to restore the original branch)"
+msgstr " (使用 \"git am --abort\" 恢复原有分支)"
+
+#: wt-status.c:874 wt-status.c:884
+msgid "You are currently rebasing."
+msgstr "您正在变基。"
+
+# 译者:注意保持前导空格
+#: wt-status.c:877
+msgid " (fix conflicts and then run \"git rebase --continue\")"
+msgstr " (解决冲突,然后运行 \"git rebase --continue\")"
+
+# 译者:注意保持前导空格
+#: wt-status.c:879
+msgid " (use \"git rebase --skip\" to skip this patch)"
+msgstr " (使用 \"git rebase --skip\" 跳过此补丁)"
+
+# 译者:注意保持前导空格
+#: wt-status.c:881
+msgid " (use \"git rebase --abort\" to check out the original branch)"
+msgstr " (使用 \"git rebase --abort\" 以检出原有分支)"
+
+# 译者:注意保持前导空格
+#: wt-status.c:887
+msgid " (all conflicts fixed: run \"git rebase --continue\")"
+msgstr " (所有冲突已解决:运行 \"git rebase --continue\")"
+
+#: wt-status.c:889
+msgid "You are currently splitting a commit during a rebase."
+msgstr "您正在变基过程中拆分一个提交。"
+
+# 译者:注意保持前导空格
+#: wt-status.c:892
+msgid " (Once your working directory is clean, run \"git rebase --continue\")"
+msgstr " (一旦您工作目录提交干净后,运行 \"git rebase --continue\")"
+
+#: wt-status.c:894
+msgid "You are currently editing a commit during a rebase."
+msgstr "您正在变基过程中编辑一个提交。"
+
+# 译者:注意保持前导空格
+#: wt-status.c:897
+msgid " (use \"git commit --amend\" to amend the current commit)"
+msgstr " (使用 \"git commit --amend\" 修补当前提交)"
+
+# 译者:注意保持前导空格
+#: wt-status.c:899
+msgid ""
+" (use \"git rebase --continue\" once you are satisfied with your changes)"
+msgstr ""
+" (执行 \"git rebase --continue\" 一旦您满意您的修改)"
+
+#: wt-status.c:909
+msgid "You are currently cherry-picking."
+msgstr "您正在做拣选操作。"
+
+# 译者:注意保持前导空格
+#: wt-status.c:916
+msgid " (all conflicts fixed: run \"git commit\")"
+msgstr " (解决所有冲突后,执行 \"git commit\")"
+
+#: wt-status.c:925
+msgid "You are currently bisecting."
+msgstr "您正在做二分查找。"
+
+# 译者:注意保持前导空格
+#: wt-status.c:928
+msgid " (use \"git bisect reset\" to get back to the original branch)"
+msgstr " (使用 \"git bisect reset\" 以回到原有分支)"
+
+#: wt-status.c:979
msgid "On branch "
msgstr "位于分支 "
-#: wt-status.c:744
+#: wt-status.c:986
msgid "Not currently on any branch."
msgstr "当前不在任何分支上。"
-#: wt-status.c:755
+#: wt-status.c:998
msgid "Initial commit"
msgstr "初始提交"
-#: wt-status.c:769
+#: wt-status.c:1012
msgid "Untracked"
msgstr "未跟踪的"
-#: wt-status.c:771
+#: wt-status.c:1014
msgid "Ignored"
msgstr "忽略的"
-#: wt-status.c:773
+#: wt-status.c:1016
#, c-format
msgid "Untracked files not listed%s"
msgstr "未跟踪的文件没有列出%s"
# 译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:775
+#: wt-status.c:1018
msgid " (use -u option to show untracked files)"
msgstr "(使用 -u 参数显示未跟踪的文件)"
-#: wt-status.c:781
+#: wt-status.c:1024
msgid "No changes"
msgstr "没有修改"
-#: wt-status.c:785
+#: wt-status.c:1028
#, c-format
msgid "no changes added to commit%s\n"
msgstr "修改尚未加入提交%s\n"
# 译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:787
+#: wt-status.c:1030
msgid " (use \"git add\" and/or \"git commit -a\")"
msgstr "(使用 \"git add\" 和/或 \"git commit -a\")"
-#: wt-status.c:789
+#: wt-status.c:1032
#, c-format
msgid "nothing added to commit but untracked files present%s\n"
msgstr "空提交但存在未跟踪文件%s\n"
# 译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:791
+#: wt-status.c:1034
msgid " (use \"git add\" to track)"
msgstr "(使用 \"git add\" 建立跟踪)"
-#: wt-status.c:793 wt-status.c:796 wt-status.c:799
+#: wt-status.c:1036 wt-status.c:1039 wt-status.c:1042
#, c-format
msgid "nothing to commit%s\n"
msgstr "无须提交%s\n"
# 译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:794
+#: wt-status.c:1037
msgid " (create/copy files and use \"git add\" to track)"
msgstr "(新建/拷贝的文件使用 \"git add\" 建立跟踪)"
# 译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:797
+#: wt-status.c:1040
msgid " (use -u to show untracked files)"
msgstr "(使用 -u 显示未跟踪文件)"
# 译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:800
+#: wt-status.c:1043
msgid " (working directory clean)"
msgstr "(干净的工作区)"
-#: wt-status.c:908
+#: wt-status.c:1151
msgid "HEAD (no branch)"
msgstr "HEAD(非分支)"
# 译者:注意保持句尾空格
-#: wt-status.c:914
+#: wt-status.c:1157
msgid "Initial commit on "
msgstr "初始提交于 "
# 译者:注意保持句尾空格
-#: wt-status.c:929
+#: wt-status.c:1172
msgid "behind "
msgstr "落后 "
# 译者:注意保持句尾空格
-#: wt-status.c:932 wt-status.c:935
+#: wt-status.c:1175 wt-status.c:1178
msgid "ahead "
msgstr "领先 "
# 译者:注意保持句尾空格
-#: wt-status.c:937
+#: wt-status.c:1180
msgid ", behind "
msgstr ",落后 "
msgid "Unstaged changes after refreshing the index:"
msgstr "刷新索引之后尚未被暂存的变更:"
-#: builtin/add.c:195 builtin/add.c:456 builtin/rm.c:186
+#: builtin/add.c:195 builtin/add.c:459 builtin/rm.c:186
#, c-format
msgid "pathspec '%s' did not match any files"
msgstr "路径 '%s' 未匹配任何文件"
msgid "index file corrupt"
msgstr "索引文件损坏"
-#: builtin/add.c:476 builtin/apply.c:4100 builtin/mv.c:229 builtin/rm.c:260
+#: builtin/add.c:480 builtin/apply.c:4108 builtin/mv.c:229 builtin/rm.c:260
msgid "Unable to write new index file"
msgstr "无法写入新索引文件"
msgid "%s: already exists in index"
msgstr "%s:已经存在于索引中"
-#: builtin/apply.c:3266
-#, fuzzy, c-format
-msgid "new mode (%o) of %s does not match old mode (%o)%s%s"
-msgstr "%2$s 的新模式(%1$o)和旧模式(%3$o)%4$s%5$s 不匹配"
+#: builtin/apply.c:3267
+#, c-format
+msgid "new mode (%o) of %s does not match old mode (%o)"
+msgstr "%2$s 的新模式(%1$o)和旧模式(%3$o)不匹配"
#: builtin/apply.c:3272
#, c-format
+msgid "new mode (%o) of %s does not match old mode (%o) of %s"
+msgstr "%2$s 的新模式(%1$o)和 %4$s 的旧模式(%3$o)不匹配"
+
+#: builtin/apply.c:3280
+#, c-format
msgid "%s: patch does not apply"
msgstr "%s:补丁未应用"
-#: builtin/apply.c:3285
+#: builtin/apply.c:3293
#, c-format
msgid "Checking patch %s..."
msgstr "检查补丁 %s..."
-#: builtin/apply.c:3340 builtin/checkout.c:212 builtin/reset.c:158
+#: builtin/apply.c:3348 builtin/checkout.c:212 builtin/reset.c:158
#, c-format
msgid "make_cache_entry failed for path '%s'"
msgstr "对路径 '%s' 的 make_cache_entry 操作失败"
-#: builtin/apply.c:3483
+#: builtin/apply.c:3491
#, c-format
msgid "unable to remove %s from index"
msgstr "不能从索引中移除 %s"
-#: builtin/apply.c:3510
+#: builtin/apply.c:3518
#, c-format
msgid "corrupt patch for subproject %s"
msgstr "子项目 %s 损坏的补丁"
-#: builtin/apply.c:3514
+#: builtin/apply.c:3522
#, c-format
msgid "unable to stat newly created file '%s'"
msgstr "不能枚举新建文件 '%s' 的状态"
-#: builtin/apply.c:3519
+#: builtin/apply.c:3527
#, c-format
msgid "unable to create backing store for newly created file %s"
msgstr "不能为新建文件 %s 创建后端存储"
-#: builtin/apply.c:3522
+#: builtin/apply.c:3530
#, c-format
msgid "unable to add cache entry for %s"
msgstr "无法为 %s 添加缓存条目"
-#: builtin/apply.c:3555
+#: builtin/apply.c:3563
#, c-format
msgid "closing file '%s'"
msgstr "关闭文件 '%s'"
-#: builtin/apply.c:3604
+#: builtin/apply.c:3612
#, c-format
msgid "unable to write file '%s' mode %o"
msgstr "不能写文件 '%s' 权限 %o"
-#: builtin/apply.c:3660
+#: builtin/apply.c:3668
#, c-format
msgid "Applied patch %s cleanly."
msgstr "成功应用补丁 %s。"
-#: builtin/apply.c:3668
+#: builtin/apply.c:3676
msgid "internal error"
msgstr "内部错误"
#. Say this even without --verbose
-#: builtin/apply.c:3671
+#: builtin/apply.c:3679
#, c-format
msgid "Applying patch %%s with %d reject..."
msgid_plural "Applying patch %%s with %d rejects..."
msgstr[0] "应用补丁 %%s 时 %d 个被拒绝..."
msgstr[1] "应用补丁 %%s 时 %d 个被拒绝..."
-#: builtin/apply.c:3681
+#: builtin/apply.c:3689
#, c-format
msgid "truncating .rej filename to %.*s.rej"
msgstr "截短 .rej 文件名为 %.*s.rej"
-#: builtin/apply.c:3702
+#: builtin/apply.c:3710
#, c-format
msgid "Hunk #%d applied cleanly."
msgstr "第 #%d 个片段成功应用。"
-#: builtin/apply.c:3705
+#: builtin/apply.c:3713
#, c-format
msgid "Rejected hunk #%d."
msgstr "拒绝第 #%d 个片段。"
-#: builtin/apply.c:3836
+#: builtin/apply.c:3844
msgid "unrecognized input"
msgstr "未能识别的输入"
-#: builtin/apply.c:3847
+#: builtin/apply.c:3855
msgid "unable to read index file"
msgstr "无法读取索引文件"
-#: builtin/apply.c:3962 builtin/apply.c:3965
+#: builtin/apply.c:3970 builtin/apply.c:3973
msgid "path"
msgstr "路径"
-#: builtin/apply.c:3963
+#: builtin/apply.c:3971
msgid "don't apply changes matching the given path"
msgstr "不要应用与给出路径向匹配的变更"
-#: builtin/apply.c:3966
+#: builtin/apply.c:3974
msgid "apply changes matching the given path"
msgstr "应用与给出路径向匹配的变更"
-#: builtin/apply.c:3968
+#: builtin/apply.c:3976
msgid "num"
msgstr "数字"
-#: builtin/apply.c:3969
+#: builtin/apply.c:3977
msgid "remove <num> leading slashes from traditional diff paths"
msgstr "从传统的 diff 路径中移除 <数字> 个前导路径"
-#: builtin/apply.c:3972
+#: builtin/apply.c:3980
msgid "ignore additions made by the patch"
msgstr "忽略补丁中的添加的文件"
-#: builtin/apply.c:3974
+#: builtin/apply.c:3982
msgid "instead of applying the patch, output diffstat for the input"
msgstr "不应用补丁,而是显示输入的差异统计(diffstat)"
-#: builtin/apply.c:3978
+#: builtin/apply.c:3986
msgid "shows number of added and deleted lines in decimal notation"
msgstr "以数字方式显示添加或删除行的数量"
-#: builtin/apply.c:3980
+#: builtin/apply.c:3988
msgid "instead of applying the patch, output a summary for the input"
msgstr "不应用补丁,而是显示输入的概要"
-#: builtin/apply.c:3982
+#: builtin/apply.c:3990
msgid "instead of applying the patch, see if the patch is applicable"
msgstr "不应用补丁,而是查看补丁是否可应用"
-#: builtin/apply.c:3984
+#: builtin/apply.c:3992
msgid "make sure the patch is applicable to the current index"
msgstr "确认补丁可以应用到当前索引"
-#: builtin/apply.c:3986
+#: builtin/apply.c:3994
msgid "apply a patch without touching the working tree"
msgstr "应用补丁而不修改工作区"
-#: builtin/apply.c:3988
+#: builtin/apply.c:3996
msgid "also apply the patch (use with --stat/--summary/--check)"
msgstr "同时应用此补丁(和 --stat/--summary/--check 共用)"
-#: builtin/apply.c:3990
+#: builtin/apply.c:3998
msgid "build a temporary index based on embedded index information"
msgstr "创建一个临时索引基于嵌入的索引信息"
-#: builtin/apply.c:3992
+#: builtin/apply.c:4000
msgid "paths are separated with NUL character"
msgstr "路径以 NUL 字符分隔"
-#: builtin/apply.c:3995
+#: builtin/apply.c:4003
msgid "ensure at least <n> lines of context match"
msgstr "确保至少匹配 <n> 行上下文"
-#: builtin/apply.c:3996
+#: builtin/apply.c:4004
msgid "action"
msgstr "动作"
-#: builtin/apply.c:3997
+#: builtin/apply.c:4005
msgid "detect new or modified lines that have whitespace errors"
msgstr "检查新增和修改的行中间的空白字符滥用"
-#: builtin/apply.c:4000 builtin/apply.c:4003
+#: builtin/apply.c:4008 builtin/apply.c:4011
msgid "ignore changes in whitespace when finding context"
msgstr "查找上下文时忽略空白字符的变更"
-#: builtin/apply.c:4006
+#: builtin/apply.c:4014
msgid "apply the patch in reverse"
msgstr "反向应用补丁"
-#: builtin/apply.c:4008
+#: builtin/apply.c:4016
msgid "don't expect at least one line of context"
msgstr "无需至少一行上下文"
-#: builtin/apply.c:4010
+#: builtin/apply.c:4018
msgid "leave the rejected hunks in corresponding *.rej files"
msgstr "将拒绝的补丁片段保存在对应的 *.rej 文件中"
-#: builtin/apply.c:4012
+#: builtin/apply.c:4020
msgid "allow overlapping hunks"
msgstr "允许重叠的补丁片段"
-#: builtin/apply.c:4013
+#: builtin/apply.c:4021
msgid "be verbose"
msgstr "冗长输出"
-#: builtin/apply.c:4015
+#: builtin/apply.c:4023
msgid "tolerate incorrectly detected missing new-line at the end of file"
msgstr "宽容不正确的文件末尾换行符"
-#: builtin/apply.c:4018
+#: builtin/apply.c:4026
msgid "do not trust the line counts in the hunk headers"
msgstr "不信任补丁片段的头信息中的行号"
-#: builtin/apply.c:4020
+#: builtin/apply.c:4028
msgid "root"
msgstr "根目录"
-#: builtin/apply.c:4021
+#: builtin/apply.c:4029
msgid "prepend <root> to all filenames"
msgstr "为所有文件名前添加 <根目录>"
-#: builtin/apply.c:4042
+#: builtin/apply.c:4050
msgid "--index outside a repository"
msgstr "--index 在一个版本库之外"
-#: builtin/apply.c:4045
+#: builtin/apply.c:4053
msgid "--cached outside a repository"
msgstr "--cached 在一个版本库之外"
-#: builtin/apply.c:4061
+#: builtin/apply.c:4069
#, c-format
msgid "can't open patch '%s'"
msgstr "不能打开补丁 '%s'"
-#: builtin/apply.c:4075
+#: builtin/apply.c:4083
#, c-format
msgid "squelched %d whitespace error"
msgid_plural "squelched %d whitespace errors"
msgstr[0] "抑制下仍有 %d 个空白字符误用"
msgstr[1] "抑制下仍有 %d 个空白字符误用"
-#: builtin/apply.c:4081 builtin/apply.c:4091
+#: builtin/apply.c:4089 builtin/apply.c:4099
#, c-format
msgid "%d line adds whitespace errors."
msgid_plural "%d lines add whitespace errors."
msgid "malformed --author parameter"
msgstr "非法的 --author 参数"
-#: builtin/commit.c:583
+#: builtin/commit.c:582
#, c-format
msgid "Malformed ident string: '%s'"
msgstr "非法的身份字符串:'%s'"
-#: builtin/commit.c:621 builtin/commit.c:654 builtin/commit.c:968
+#: builtin/commit.c:620 builtin/commit.c:653 builtin/commit.c:967
#, c-format
msgid "could not lookup commit %s"
msgstr "不能查询提交 %s"
-#: builtin/commit.c:633 builtin/shortlog.c:296
+#: builtin/commit.c:632 builtin/shortlog.c:296
#, c-format
msgid "(reading log message from standard input)\n"
msgstr "(正从标准输入中读取日志信息)\n"
-#: builtin/commit.c:635
+#: builtin/commit.c:634
msgid "could not read log from standard input"
msgstr "不能从标准输入中读取日志信息"
-#: builtin/commit.c:639
+#: builtin/commit.c:638
#, c-format
msgid "could not read log file '%s'"
msgstr "不能读取日志文件 '%s'"
-#: builtin/commit.c:645
+#: builtin/commit.c:644
msgid "commit has empty message"
msgstr "提交说明为空"
-#: builtin/commit.c:661
+#: builtin/commit.c:660
msgid "could not read MERGE_MSG"
msgstr "不能读取 MERGE_MSG"
-#: builtin/commit.c:665
+#: builtin/commit.c:664
msgid "could not read SQUASH_MSG"
msgstr "不能读取 SQUASH_MSG"
-#: builtin/commit.c:669
+#: builtin/commit.c:668
#, c-format
msgid "could not read '%s'"
msgstr "不能读取 '%s'"
-#: builtin/commit.c:721
+#: builtin/commit.c:720
msgid "could not write commit template"
msgstr "不能写提交模版"
-#: builtin/commit.c:732
+#: builtin/commit.c:731
#, c-format
msgid ""
"\n"
"\t%s\n"
"然后重试。\n"
-#: builtin/commit.c:737
+#: builtin/commit.c:736
#, c-format
msgid ""
"\n"
"\t%s\n"
"然后重试。\n"
-#: builtin/commit.c:749
+#: builtin/commit.c:748
msgid ""
"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be ignored, and an empty message aborts the commit.\n"
"请为您的变更输入提交说明。以 '#' 开始的行将被忽略,而一个空的提交\n"
"说明将会终止提交。\n"
-#: builtin/commit.c:754
+#: builtin/commit.c:753
msgid ""
"Please enter the commit message for your changes. Lines starting\n"
"with '#' will be kept; you may remove them yourself if you want to.\n"
"如果您想这样做的话。而一个空的提交说明将会终止提交。\n"
# 译者:为保证在输出中对齐,注意调整句中空格!
-#: builtin/commit.c:767
+#: builtin/commit.c:766
#, c-format
msgid "%sAuthor: %s"
msgstr "%s作者: %s"
# 译者:为保证在输出中对齐,注意调整句中空格!
-#: builtin/commit.c:774
+#: builtin/commit.c:773
#, c-format
msgid "%sCommitter: %s"
msgstr "%s提交者: %s"
-#: builtin/commit.c:794
+#: builtin/commit.c:793
msgid "Cannot read index"
msgstr "无法读取索引"
-#: builtin/commit.c:831
+#: builtin/commit.c:830
msgid "Error building trees"
msgstr "无法创建树对象"
-#: builtin/commit.c:846 builtin/tag.c:361
+#: builtin/commit.c:845 builtin/tag.c:361
#, c-format
msgid "Please supply the message using either -m or -F option.\n"
msgstr "请使用 -m 或者 -F 选项提供提交说明。\n"
-#: builtin/commit.c:943
+#: builtin/commit.c:942
#, c-format
msgid "No existing author found with '%s'"
msgstr "没有找到匹配 '%s' 的作者"
-#: builtin/commit.c:958 builtin/commit.c:1158
+#: builtin/commit.c:957 builtin/commit.c:1157
#, c-format
msgid "Invalid untracked files mode '%s'"
msgstr "无效的未追踪文件参数 '%s'"
-#: builtin/commit.c:998
+#: builtin/commit.c:997
msgid "Using both --reset-author and --author does not make sense"
msgstr "同时使用 --reset-author 和 --author 没有意义"
-#: builtin/commit.c:1009
+#: builtin/commit.c:1008
msgid "You have nothing to amend."
msgstr "您没有可修补的提交。"
-#: builtin/commit.c:1012
+#: builtin/commit.c:1011
msgid "You are in the middle of a merge -- cannot amend."
msgstr "您正处于一个合并过程中 -- 无法修补提交。"
-#: builtin/commit.c:1014
+#: builtin/commit.c:1013
msgid "You are in the middle of a cherry-pick -- cannot amend."
msgstr "您正处于一个拣选过程中 -- 无法修补提交。"
-#: builtin/commit.c:1017
+#: builtin/commit.c:1016
msgid "Options --squash and --fixup cannot be used together"
msgstr "选项 --squash 和 --fixup 不能共用"
-#: builtin/commit.c:1027
+#: builtin/commit.c:1026
msgid "Only one of -c/-C/-F/--fixup can be used."
msgstr "只能用一个 -c/-C/-F/--fixup 选项。"
-#: builtin/commit.c:1029
+#: builtin/commit.c:1028
msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
msgstr "选项 -m 不能和 -c/-C/-F/--fixup 共用。"
-#: builtin/commit.c:1037
+#: builtin/commit.c:1036
msgid "--reset-author can be used only with -C, -c or --amend."
msgstr "--reset-author 只能和 -C、-c 或 --amend 共用。"
-#: builtin/commit.c:1054
+#: builtin/commit.c:1053
msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
msgstr "只能用一个 --include/--only/--all/--interactive/--patch 选项。"
-#: builtin/commit.c:1056
+#: builtin/commit.c:1055
msgid "No paths with --include/--only does not make sense."
msgstr "参数 --include/--only 不跟路径没有意义。"
-#: builtin/commit.c:1058
+#: builtin/commit.c:1057
msgid "Clever... amending the last one with dirty index."
msgstr "聪明... 在索引不干净下修补最后的提交。"
-#: builtin/commit.c:1060
+#: builtin/commit.c:1059
msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
msgstr "指定了明确的路径而没有使用 -i 或 -o 选项;认为是 --only paths..."
-#: builtin/commit.c:1070 builtin/tag.c:577
+#: builtin/commit.c:1069 builtin/tag.c:577
#, c-format
msgid "Invalid cleanup mode %s"
msgstr "无效的清理模式 %s"
-#: builtin/commit.c:1075
+#: builtin/commit.c:1074
msgid "Paths with -a does not make sense."
msgstr "路径和 -a 选项共用没有意义。"
-#: builtin/commit.c:1258
+#: builtin/commit.c:1257
msgid "couldn't look up newly created commit"
msgstr "无法找到新创建的提交"
-#: builtin/commit.c:1260
+#: builtin/commit.c:1259
msgid "could not parse newly created commit"
msgstr "不能解析新创建的提交"
-#: builtin/commit.c:1301
+#: builtin/commit.c:1300
msgid "detached HEAD"
msgstr "分离头指针"
# 译者:中文字符串拼接,可删除前导空格
-#: builtin/commit.c:1303
+#: builtin/commit.c:1302
msgid " (root-commit)"
msgstr "(根提交)"
-#: builtin/commit.c:1447
+#: builtin/commit.c:1446
msgid "could not parse HEAD commit"
msgstr "不能解析 HEAD 提交"
-#: builtin/commit.c:1485 builtin/merge.c:509
+#: builtin/commit.c:1484 builtin/merge.c:509
#, c-format
msgid "could not open '%s' for reading"
msgstr "不能为读入打开 '%s'"
-#: builtin/commit.c:1492
+#: builtin/commit.c:1491
#, c-format
msgid "Corrupt MERGE_HEAD file (%s)"
msgstr "损坏的 MERGE_HEAD 文件(%s)"
-#: builtin/commit.c:1499
+#: builtin/commit.c:1498
msgid "could not read MERGE_MODE"
msgstr "不能读取 MERGE_MODE"
-#: builtin/commit.c:1518
+#: builtin/commit.c:1517
#, c-format
msgid "could not read commit message: %s"
msgstr "不能读取提交说明:%s"
-#: builtin/commit.c:1532
+#: builtin/commit.c:1531
#, c-format
msgid "Aborting commit; you did not edit the message.\n"
msgstr "终止提交;您未更改来自模版的提交说明。\n"
-#: builtin/commit.c:1537
+#: builtin/commit.c:1536
#, c-format
msgid "Aborting commit due to empty commit message.\n"
msgstr "终止提交因为提交说明为空。\n"
-#: builtin/commit.c:1552 builtin/merge.c:936 builtin/merge.c:961
+#: builtin/commit.c:1551 builtin/merge.c:936 builtin/merge.c:961
msgid "failed to write commit object"
msgstr "无法写提交对象"
-#: builtin/commit.c:1573
+#: builtin/commit.c:1572
msgid "cannot lock HEAD ref"
msgstr "无法锁定 HEAD 引用"
-#: builtin/commit.c:1577
+#: builtin/commit.c:1576
msgid "cannot update HEAD ref"
msgstr "无法更新 HEAD 引用"
-#: builtin/commit.c:1588
+#: builtin/commit.c:1587
msgid ""
"Repository has been updated, but unable to write\n"
"new_index file. Check that disk is not full or quota is\n"
msgid "Not a git repository"
msgstr "不是一个 git 版本库"
-#: builtin/diff.c:347
+#: builtin/diff.c:341
#, c-format
msgid "invalid object '%s' given."
msgstr "提供了无效对象 '%s'。"
-#: builtin/diff.c:352
+#: builtin/diff.c:346
#, c-format
msgid "more than %d trees given: '%s'"
msgstr "提供了超过 %d 个树对象:'%s'"
-#: builtin/diff.c:362
+#: builtin/diff.c:356
#, c-format
msgid "more than two blobs given: '%s'"
msgstr "提供了超过两个 blob 对象:'%s'"
-#: builtin/diff.c:370
+#: builtin/diff.c:364
#, c-format
msgid "unhandled object '%s' given."
msgstr "提供了无法处理的对象 '%s'。"
msgid "cannot open '%s'"
msgstr "不能打开 '%s'"
-#: builtin/grep.c:888
+#: builtin/grep.c:885
msgid "no pattern given."
msgstr "未提供模式匹配。"
-#: builtin/grep.c:902
+#: builtin/grep.c:899
#, c-format
msgid "bad object %s"
msgstr "坏对象 %s"
-#: builtin/grep.c:943
+#: builtin/grep.c:940
msgid "--open-files-in-pager only works on the worktree"
msgstr "--open-files-in-pager 仅用于工作区"
-#: builtin/grep.c:966
+#: builtin/grep.c:963
msgid "--cached or --untracked cannot be used with --no-index."
msgstr "--cached 或 --untracked 不能与 --no-index 共用。"
-#: builtin/grep.c:971
+#: builtin/grep.c:968
msgid "--no-index or --untracked cannot be used with revs."
msgstr "--no-index 或 --untracked 不能和版本共用。"
-#: builtin/grep.c:974
+#: builtin/grep.c:971
msgid "--[no-]exclude-standard cannot be used for tracked contents."
msgstr "--[no-]exclude-standard 不能用于已跟踪内容。"
-#: builtin/grep.c:982
+#: builtin/grep.c:979
msgid "both --cached and trees are given."
msgstr "同时给出了 --cached 和树对象。"
-#: builtin/help.c:59
+#: builtin/help.c:63
#, c-format
msgid "unrecognized help format '%s'"
msgstr "未能识别的帮助格式 '%s'"
-#: builtin/help.c:87
+#: builtin/help.c:91
msgid "Failed to start emacsclient."
msgstr "无法启动 emacsclient。"
-#: builtin/help.c:100
+#: builtin/help.c:104
msgid "Failed to parse emacsclient version."
msgstr "无法解析 emacsclient 版本。"
-#: builtin/help.c:108
+#: builtin/help.c:112
#, c-format
msgid "emacsclient version '%d' too old (< 22)."
msgstr "emacsclient 版本 '%d' 太老 (< 22)。"
-#: builtin/help.c:126 builtin/help.c:154 builtin/help.c:163 builtin/help.c:171
+#: builtin/help.c:130 builtin/help.c:158 builtin/help.c:167 builtin/help.c:175
#, c-format
msgid "failed to exec '%s': %s"
msgstr "无法执行 '%s':%s"
-#: builtin/help.c:211
+#: builtin/help.c:215
#, c-format
msgid ""
"'%s': path for unsupported man viewer.\n"
"'%s':不支持的 man 手册查看器的路径。\n"
"请使用 'man.<tool>.cmd'。"
-#: builtin/help.c:223
+#: builtin/help.c:227
#, c-format
msgid ""
"'%s': cmd for supported man viewer.\n"
"'%s': 支持的 man 手册查看器命令。\n"
"请使用 'man.<tool>.path'。"
-#: builtin/help.c:287
+#: builtin/help.c:291
msgid "The most commonly used git commands are:"
msgstr "最常用的 git 命令有:"
-#: builtin/help.c:355
+#: builtin/help.c:359
#, c-format
msgid "'%s': unknown man viewer."
msgstr "'%s':未知的 man 查看器。"
-#: builtin/help.c:372
+#: builtin/help.c:376
msgid "no man viewer handled the request"
msgstr "没有 man 查看器处理此请求"
-#: builtin/help.c:380
+#: builtin/help.c:384
msgid "no info viewer handled the request"
msgstr "没有 info 查看器处理此请求"
-#: builtin/help.c:391
+#: builtin/help.c:395
#, c-format
msgid "'%s': not a documentation directory."
msgstr "'%s':不是一个文档目录。"
-#: builtin/help.c:432 builtin/help.c:439
+#: builtin/help.c:436 builtin/help.c:443
#, c-format
msgid "usage: %s%s"
msgstr "用法:%s%s"
-#: builtin/help.c:453
+#: builtin/help.c:459
#, c-format
msgid "`git %s' is aliased to `%s'"
msgstr "`git %s' 是 `%s' 的别名"
-#: builtin/index-pack.c:169
+#: builtin/index-pack.c:170
#, c-format
msgid "object type mismatch at %s"
msgstr "%s 的对象类型不匹配"
-#: builtin/index-pack.c:189
+#: builtin/index-pack.c:190
msgid "object of unexpected type"
msgstr "意外的类型的对象"
-#: builtin/index-pack.c:226
+#: builtin/index-pack.c:227
#, c-format
msgid "cannot fill %d byte"
msgid_plural "cannot fill %d bytes"
msgstr[0] "无法填充 %d 字节"
msgstr[1] "无法填充 %d 字节"
-#: builtin/index-pack.c:236
+#: builtin/index-pack.c:237
msgid "early EOF"
msgstr "过早的文件结束符(EOF)"
-#: builtin/index-pack.c:237
+#: builtin/index-pack.c:238
msgid "read error on input"
msgstr "输入上的读错误"
-#: builtin/index-pack.c:249
+#: builtin/index-pack.c:250
msgid "used more bytes than were available"
msgstr "用掉了超过可用的字节"
-#: builtin/index-pack.c:256
+#: builtin/index-pack.c:257
msgid "pack too large for current definition of off_t"
msgstr "包太大超过了当前 off_t 的定义"
-#: builtin/index-pack.c:272
+#: builtin/index-pack.c:273
#, c-format
msgid "unable to create '%s'"
msgstr "不能创建 '%s'"
-#: builtin/index-pack.c:277
+#: builtin/index-pack.c:278
#, c-format
msgid "cannot open packfile '%s'"
msgstr "无法打开包文件 '%s'"
-#: builtin/index-pack.c:291
+#: builtin/index-pack.c:292
msgid "pack signature mismatch"
msgstr "包签名不匹配"
-#: builtin/index-pack.c:311
+#: builtin/index-pack.c:312
#, c-format
msgid "pack has bad object at offset %lu: %s"
msgstr "包中有错误的对象位于 %lu:%s"
-#: builtin/index-pack.c:405
+#: builtin/index-pack.c:434
#, c-format
msgid "inflate returned %d"
msgstr "解压缩返回 %d"
-#: builtin/index-pack.c:450
+#: builtin/index-pack.c:483
msgid "offset value overflow for delta base object"
msgstr "偏移值覆盖了 delta 基准对象"
-#: builtin/index-pack.c:458
+#: builtin/index-pack.c:491
msgid "delta base offset is out of bound"
msgstr "delta 基准偏移越界"
-#: builtin/index-pack.c:466
+#: builtin/index-pack.c:499
#, c-format
msgid "unknown object type %d"
msgstr "未知对象类型 %d"
-#: builtin/index-pack.c:495
+#: builtin/index-pack.c:531
msgid "cannot pread pack file"
msgstr "无法读取包文件"
-#: builtin/index-pack.c:497
+#: builtin/index-pack.c:533
#, c-format
msgid "premature end of pack file, %lu byte missing"
msgid_plural "premature end of pack file, %lu bytes missing"
msgstr[0] "包文件过早结束,缺少 %lu 字节"
msgstr[1] "包文件过早结束,缺少 %lu 字节"
-#: builtin/index-pack.c:510
+#: builtin/index-pack.c:555
msgid "serious inflate inconsistency"
msgstr "解压缩严重的不一致"
-#: builtin/index-pack.c:583
-#, c-format
-msgid "cannot read existing object %s"
-msgstr "不能读取现存对象 %s"
-
-#: builtin/index-pack.c:586
+#: builtin/index-pack.c:646 builtin/index-pack.c:652 builtin/index-pack.c:675
+#: builtin/index-pack.c:709 builtin/index-pack.c:718
#, c-format
msgid "SHA1 COLLISION FOUND WITH %s !"
msgstr "发现 %s 出现 SHA1 冲突!"
-#: builtin/index-pack.c:598
+#: builtin/index-pack.c:649 builtin/pack-objects.c:170
+#: builtin/pack-objects.c:262
+#, c-format
+msgid "unable to read %s"
+msgstr "不能读 %s"
+
+#: builtin/index-pack.c:715
+#, c-format
+msgid "cannot read existing object %s"
+msgstr "不能读取现存对象 %s"
+
+#: builtin/index-pack.c:729
#, c-format
msgid "invalid blob object %s"
msgstr "无效的 blob 对象 %s"
-#: builtin/index-pack.c:610
+#: builtin/index-pack.c:744
#, c-format
msgid "invalid %s"
msgstr "无效的 %s"
-#: builtin/index-pack.c:612
+#: builtin/index-pack.c:746
msgid "Error in object"
msgstr "对象中出错"
-#: builtin/index-pack.c:614
+#: builtin/index-pack.c:748
#, c-format
msgid "Not all child objects of %s are reachable"
msgstr "%s 的所有子对象并非都可达"
-#: builtin/index-pack.c:687 builtin/index-pack.c:713
+#: builtin/index-pack.c:818 builtin/index-pack.c:844
msgid "failed to apply delta"
msgstr "无法应用 delta"
-#: builtin/index-pack.c:850
+#: builtin/index-pack.c:983
msgid "Receiving objects"
msgstr "接收对象中"
-#: builtin/index-pack.c:850
+#: builtin/index-pack.c:983
msgid "Indexing objects"
msgstr "索引对象中"
-#: builtin/index-pack.c:872
+#: builtin/index-pack.c:1009
msgid "pack is corrupted (SHA1 mismatch)"
msgstr "包冲突(SHA1 不匹配)"
-#: builtin/index-pack.c:877
+#: builtin/index-pack.c:1014
msgid "cannot fstat packfile"
msgstr "不能枚举包文件状态"
-#: builtin/index-pack.c:880
+#: builtin/index-pack.c:1017
msgid "pack has junk at the end"
msgstr "包的结尾有垃圾数据"
-#: builtin/index-pack.c:903
+#: builtin/index-pack.c:1028
+msgid "confusion beyond insanity in parse_pack_objects()"
+msgstr "parse_pack_objects() 中遇到不可理喻的问题"
+
+#: builtin/index-pack.c:1051
msgid "Resolving deltas"
msgstr "处理 delta 中"
-#: builtin/index-pack.c:954
+#: builtin/index-pack.c:1102
msgid "confusion beyond insanity"
msgstr "不可理喻"
-#: builtin/index-pack.c:973
+#: builtin/index-pack.c:1121
#, c-format
msgid "pack has %d unresolved delta"
msgid_plural "pack has %d unresolved deltas"
msgstr[0] "包有 %d 个未解决的 delta"
msgstr[1] "包有 %d 个未解决的 delta"
-#: builtin/index-pack.c:998
+#: builtin/index-pack.c:1146
#, c-format
msgid "unable to deflate appended object (%d)"
msgstr "不能缩小附加对象(%d)"
-#: builtin/index-pack.c:1077
+#: builtin/index-pack.c:1225
#, c-format
msgid "local object %s is corrupt"
msgstr "本地对象 %s 已损坏"
-#: builtin/index-pack.c:1101
+#: builtin/index-pack.c:1249
msgid "error while closing pack file"
msgstr "关闭包文件时出错"
-#: builtin/index-pack.c:1114
+#: builtin/index-pack.c:1262
#, c-format
msgid "cannot write keep file '%s'"
msgstr "无法写保留文件 '%s'"
-#: builtin/index-pack.c:1122
+#: builtin/index-pack.c:1270
#, c-format
msgid "cannot close written keep file '%s'"
msgstr "无法关闭保留文件 '%s'"
-#: builtin/index-pack.c:1135
+#: builtin/index-pack.c:1283
msgid "cannot store pack file"
msgstr "无法存储包文件"
-#: builtin/index-pack.c:1146
+#: builtin/index-pack.c:1294
msgid "cannot store index file"
msgstr "无法存储索引文件"
-#: builtin/index-pack.c:1247
+#: builtin/index-pack.c:1395
#, c-format
msgid "Cannot open existing pack file '%s'"
msgstr "无法打开现存包文件 '%s'"
-#: builtin/index-pack.c:1249
+#: builtin/index-pack.c:1397
#, c-format
msgid "Cannot open existing pack idx file for '%s'"
msgstr "无法为 %s 打开包索引文件"
-#: builtin/index-pack.c:1296
+#: builtin/index-pack.c:1444
#, c-format
msgid "non delta: %d object"
msgid_plural "non delta: %d objects"
msgstr[0] "非 delta:%d 个对象"
msgstr[1] "非 delta:%d 个对象"
-#: builtin/index-pack.c:1303
+#: builtin/index-pack.c:1451
#, c-format
msgid "chain length = %d: %lu object"
msgid_plural "chain length = %d: %lu objects"
msgstr[0] "链长 = %d: %lu 对象"
msgstr[1] "链长 = %d: %lu 对象"
-#: builtin/index-pack.c:1330
+#: builtin/index-pack.c:1478
msgid "Cannot come back to cwd"
msgstr "无法返回当前工作目录"
-#: builtin/index-pack.c:1374 builtin/index-pack.c:1377
-#: builtin/index-pack.c:1389 builtin/index-pack.c:1393
+#: builtin/index-pack.c:1522 builtin/index-pack.c:1525
+#: builtin/index-pack.c:1537 builtin/index-pack.c:1541
#, c-format
msgid "bad %s"
msgstr "错误选项 %s"
-#: builtin/index-pack.c:1407
+#: builtin/index-pack.c:1555
msgid "--fix-thin cannot be used without --stdin"
msgstr "--fix-thin 不能和 --stdin 共用"
-#: builtin/index-pack.c:1411 builtin/index-pack.c:1421
+#: builtin/index-pack.c:1559 builtin/index-pack.c:1569
#, c-format
msgid "packfile name '%s' does not end with '.pack'"
msgstr "包名 '%s' 没有以 '.pack' 结尾"
-#: builtin/index-pack.c:1430
+#: builtin/index-pack.c:1578
msgid "--verify with no packfile name given"
msgstr "--verify 没有提供包名参数"
msgid "Cannot access work tree '%s'"
msgstr "不能访问工作区 '%s'"
-#: builtin/log.c:188
+#: builtin/log.c:189
#, c-format
msgid "Final output: %d %s\n"
msgstr "最终输出:%d %s\n"
-#: builtin/log.c:401 builtin/log.c:489
+#: builtin/log.c:402 builtin/log.c:490
#, c-format
msgid "Could not read object %s"
msgstr "不能读取对象 %s"
-#: builtin/log.c:513
+#: builtin/log.c:514
#, c-format
msgid "Unknown type: %d"
msgstr "未知类型:%d"
-#: builtin/log.c:602
+#: builtin/log.c:603
msgid "format.headers without value"
msgstr "format.headers 没有值"
-#: builtin/log.c:675
+#: builtin/log.c:677
msgid "name of output directory is too long"
msgstr "输出目录名太长"
-#: builtin/log.c:686
+#: builtin/log.c:688
#, c-format
msgid "Cannot open patch file %s"
msgstr "无法打开补丁文件 %s"
-#: builtin/log.c:700
+#: builtin/log.c:702
msgid "Need exactly one range."
msgstr "只需要一个范围。"
-#: builtin/log.c:708
+#: builtin/log.c:710
msgid "Not a range."
msgstr "不是一个范围。"
-#: builtin/log.c:745
-msgid "Could not extract email from committer identity."
-msgstr "不能从提交者身份中提取邮件地址。"
-
-#: builtin/log.c:791
+#: builtin/log.c:787
msgid "Cover letter needs email format"
msgstr "信封需要邮件地址格式"
-#: builtin/log.c:885
+#: builtin/log.c:860
#, c-format
msgid "insane in-reply-to: %s"
msgstr "不正常的 in-reply-to:%s"
-#: builtin/log.c:958
+#: builtin/log.c:933
msgid "Two output directories?"
msgstr "两个输出目录?"
-#: builtin/log.c:1179
+#: builtin/log.c:1154
#, c-format
msgid "bogus committer info %s"
msgstr "虚假的提交者信息 %s"
-#: builtin/log.c:1224
+#: builtin/log.c:1199
msgid "-n and -k are mutually exclusive."
msgstr "-n 和 -k 互斥。"
-#: builtin/log.c:1226
+#: builtin/log.c:1201
msgid "--subject-prefix and -k are mutually exclusive."
msgstr "--subject-prefix 和 -k 互斥。"
-#: builtin/log.c:1234
+#: builtin/log.c:1209
msgid "--name-only does not make sense"
msgstr "--name-only 无意义"
-#: builtin/log.c:1236
+#: builtin/log.c:1211
msgid "--name-status does not make sense"
msgstr "--name-status 无意义"
-#: builtin/log.c:1238
+#: builtin/log.c:1213
msgid "--check does not make sense"
msgstr "--check 无意义"
-#: builtin/log.c:1261
+#: builtin/log.c:1236
msgid "standard output, or directory, which one?"
msgstr "标准输出或目录,哪一个?"
-#: builtin/log.c:1263
+#: builtin/log.c:1238
#, c-format
msgid "Could not create directory '%s'"
msgstr "不能创建目录 '%s'"
-#: builtin/log.c:1416
+#: builtin/log.c:1391
msgid "Failed to create output files"
msgstr "无法创建输出文件"
-#: builtin/log.c:1520
+#: builtin/log.c:1495
#, c-format
msgid ""
"Could not find a tracked remote branch, please specify <upstream> manually.\n"
msgstr "不能找到跟踪的远程分支,请手工指定 <upstream>。\n"
-#: builtin/log.c:1536 builtin/log.c:1538 builtin/log.c:1550
+#: builtin/log.c:1511 builtin/log.c:1513 builtin/log.c:1525
#, c-format
msgid "Unknown commit %s"
msgstr "未知提交 %s"
msgid "Unknown subcommand: %s"
msgstr "未知子命令:%s"
-#: builtin/pack-objects.c:2315
+#: builtin/pack-objects.c:183 builtin/pack-objects.c:186
+#, c-format
+msgid "deflate error (%d)"
+msgstr "压缩错误 (%d)"
+
+#: builtin/pack-objects.c:2398
#, c-format
msgid "unsupported index version %s"
msgstr "不支持的索引版本 %s"
-#: builtin/pack-objects.c:2319
+#: builtin/pack-objects.c:2402
#, c-format
msgid "bad index version '%s'"
msgstr "坏的索引版本 '%s'"
-#: builtin/pack-objects.c:2342
+#: builtin/pack-objects.c:2425
#, c-format
msgid "option %s does not accept negative form"
msgstr "选项 %s 不接受否定格式"
-#: builtin/pack-objects.c:2346
+#: builtin/pack-objects.c:2429
#, c-format
msgid "unable to parse value '%s' for option %s"
msgstr "不能解析选项 %1$s 的值 '%2$s'"
#: builtin/remote.c:677
#, c-format
msgid ""
-"Not updating non-default fetch respec\n"
+"Not updating non-default fetch refspec\n"
"\t%s\n"
"\tPlease update the configuration manually if necessary."
msgstr ""
msgid "You need to set your committer info first"
msgstr "您需要先设置你的提交者信息"
+#: git-am.sh:95
+msgid ""
+"You seem to have moved HEAD since the last 'am' failure.\n"
+"Not rewinding to ORIG_HEAD"
+msgstr "您好像在上一次 'am' 失败后移动了 HEAD。未回退至 ORIG_HEAD"
+
+#: git-am.sh:105
+#, sh-format
+msgid ""
+"When you have resolved this problem run \"$cmdline --resolved\".\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+"当您解决了此问题后,执行 \"$cmdline --resolved\"。\n"
+"如果您想跳过此补丁,则执行 \"$cmdline --skip\"。\n"
+"要恢复原分支并停止打补丁,执行 \"$cmdline --abort\"。"
+
+#: git-am.sh:121
+msgid "Cannot fall back to three-way merge."
+msgstr "无法求助于三路合并。"
+
#: git-am.sh:137
msgid "Repository lacks necessary blobs to fall back on 3-way merge."
msgstr "版本库缺乏必要的 blob 数据以进行三路合并。"
#: git-am.sh:163
msgid "Falling back to patching base and 3-way merge..."
-msgstr "回退到补丁基础版本并使用三路合并..."
+msgstr "转而在基础版本上打补丁及进行三路合并..."
#: git-am.sh:275
msgid "Only one StGIT patch series can be applied at once"
msgid "Dirty index: cannot apply patches (dirty: $files)"
msgstr "脏的索引:不能应用补丁(脏文件:$files)"
+#: git-am.sh:671
+#, sh-format
+msgid ""
+"Patch is empty. Was it split wrong?\n"
+"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
+"To restore the original branch and stop patching run \"$cmdline --abort\"."
+msgstr ""
+"补丁为空。是不是切分错误?\n"
+"如果您想要跳过这个补丁,执行 \"$cmdline --skip\"。\n"
+"要恢复原分支并停止打补丁,执行 \"$cmdline --abort\"。"
+
+#: git-am.sh:708
+msgid "Patch does not have a valid e-mail address."
+msgstr "补丁中没有一个有效的邮件地址。"
+
#: git-am.sh:755
msgid "cannot be interactive without stdin connected to a terminal."
msgstr "标准输入没有和终端关联,不能进行交互式操作。"
+#: git-am.sh:759
+msgid "Commit Body is:"
+msgstr "提交内容为:"
+
# 译者:注意保持句尾空格
#. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
#. in your translation. The program will only accept English
msgid "Applying: $FIRSTLINE"
msgstr "正应用:$FIRSTLINE"
+#: git-am.sh:823
+msgid ""
+"No changes - did you forget to use 'git add'?\n"
+"If there is nothing left to stage, chances are that something else\n"
+"already introduced the same changes; you might want to skip this patch."
+msgstr ""
+"没有变更 —— 您是不是忘了执行 'git add'?\n"
+"如果没有什么要添加到暂存区的,则很可能是其它提交已经引入了相同的变更。\n"
+"您也许想要跳过这个补丁。"
+
+#: git-am.sh:831
+msgid ""
+"You still have unmerged paths in your index\n"
+"did you forget to use 'git add'?"
+msgstr "您的索引中仍有未合并的路径。您是否忘了执行 'git add'?"
+
#: git-am.sh:847
msgid "No changes -- Patch already applied."
msgstr "没有变更 -- 补丁已经应用过。"
+#: git-am.sh:857
+#, sh-format
+msgid "Patch failed at $msgnum $FIRSTLINE"
+msgstr "补丁失败于 $msgnum $FIRSTLINE"
+
#: git-am.sh:873
msgid "applying to an empty history"
msgstr "正应用到一个空历史上"
+#: git-bisect.sh:48
+msgid "You need to start by \"git bisect start\""
+msgstr "您需要执行 \"git bisect start\" 来开始"
+
# 译者:注意保持句尾空格
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
msgid "'git bisect bad' can take only one argument."
msgstr "'git bisect bad' 只能带一个参数。"
+#. have bad but not good. we could bisect although
+#. this is less optimum.
+#: git-bisect.sh:273
+msgid "Warning: bisecting only with a bad commit."
+msgstr "警告:在仅有一个坏提交下进行二分查找。"
+
# 译者:注意保持句尾空格
#. TRANSLATORS: Make sure to include [Y] and [n] in your
#. translation. The program will only accept English input
msgid "Are you sure [Y/n]? "
msgstr "您确认么[Y/n]? "
+#: git-bisect.sh:289
+msgid ""
+"You need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+"您需要给我至少一个好版本和一个坏版本。\n"
+"(您可以用 \"git bisect bad\" 和 \"git bisect good\" 命令来标识。)"
+
+#: git-bisect.sh:292
+msgid ""
+"You need to start by \"git bisect start\".\n"
+"You then need to give me at least one good and one bad revisions.\n"
+"(You can use \"git bisect bad\" and \"git bisect good\" for that.)"
+msgstr ""
+"您需要执行 \"git bisect start\" 来开始。\n"
+"然后需要提供我至少一个好版本和一个坏版本。\n"
+"(您可以用 \"git bisect bad\" 和 \"git bisect good\" 命令来标识。)"
+
+#: git-bisect.sh:347 git-bisect.sh:474
+msgid "We are not bisecting."
+msgstr "我们没有在二分查找。"
+
#: git-bisect.sh:354
#, sh-format
msgid "'$invalid' is not a valid commit"
msgid "?? what are you talking about?"
msgstr "?? 您在说什么?"
-#: git-bisect.sh:474
-msgid "We are not bisecting."
-msgstr "我们没有在二分查找。"
+#: git-bisect.sh:420
+#, sh-format
+msgid "running $command"
+msgstr "运行 $command"
+
+#: git-bisect.sh:427
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"exit code $res from '$command' is < 0 or >= 128"
+msgstr ""
+"二分查找运行失败:\n"
+"命令 '$command' 的退出码 $res 或者小于 0 或者大于等于 128"
+
+#: git-bisect.sh:453
+msgid "bisect run cannot continue any more"
+msgstr "二分查找不能继续运行"
+
+#: git-bisect.sh:459
+#, sh-format
+msgid ""
+"bisect run failed:\n"
+"'bisect_state $state' exited with error code $res"
+msgstr ""
+"二分查找运行失败:\n"
+"'bisect_state $state' 退出码为 $res"
+
+#: git-bisect.sh:466
+msgid "bisect run success"
+msgstr "二分查找运行成功"
#: git-pull.sh:21
msgid ""
msgid "updating an unborn branch with changes added to the index"
msgstr "更新尚未诞生的分支,变更添加至索引"
+#. The fetch involved updating the current branch.
+#. The working tree and the index file is still based on the
+#. $orig_head commit, but we are merging into $curr_head.
+#. First update the working tree to match $curr_head.
+#: git-pull.sh:228
+#, sh-format
+msgid ""
+"Warning: fetch updated the current branch head.\n"
+"Warning: fast-forwarding your working tree from\n"
+"Warning: commit $orig_head."
+msgstr ""
+"警告:fetch 更新了当前的分支。您的工作区\n"
+"警告:从原提交 $orig_head 快进。"
+
#: git-pull.sh:253
msgid "Cannot merge multiple branches into empty head"
msgstr "无法将多个分支合并到空分支"
msgid "Cannot record working tree state"
msgstr "不能记录工作区状态"
+#. TRANSLATORS: $option is an invalid option, like
+#. `--blah-blah'. The 7 spaces at the beginning of the
+#. second line correspond to "error: ". So you should line
+#. up the second line with however many characters the
+#. translation of "error: " takes in your language. E.g. in
+#. English this is:
+#.
+#. $ git stash save --blah-blah 2>&1 | head -n 2
+#. error: unknown option for 'stash save': --blah-blah
+#. To provide a message, use git stash save -- '--blah-blah'
+#: git-stash.sh:202
+#, sh-format
+msgid ""
+"error: unknown option for 'stash save': $option\n"
+" To provide a message, use git stash save -- '$option'"
+msgstr ""
+"错误:'stash save' 的未知选项:$option\n"
+" 要提供一个描述信息,使用 git stash save -- '$option'"
+
#: git-stash.sh:223
msgid "No local changes to save"
msgstr "没有要保存的本地修改"
msgid "Cannot unstage modified files"
msgstr "无法还原修改的文件"
+#: git-stash.sh:474
+msgid "Index was not unstashed."
+msgstr "索引的进度没有被恢复。"
+
#: git-stash.sh:491
#, sh-format
msgid "Dropped ${REV} ($s)"
msgid "(To restore them type \"git stash apply\")"
msgstr "(为恢复数据输入 \"git stash apply\")"
-#: git-submodule.sh:56
+#: git-submodule.sh:88
#, sh-format
msgid "cannot strip one component off url '$remoteurl'"
msgstr "无法从 url '$remoteurl' 剥离一个组件"
-#: git-submodule.sh:109
+#: git-submodule.sh:145
#, sh-format
msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
msgstr "未在 .gitmodules 中发现路径 '$sm_path' 的子模组映射"
-#: git-submodule.sh:150
+#: git-submodule.sh:186
#, sh-format
msgid "Clone of '$url' into submodule path '$sm_path' failed"
msgstr "无法克隆 '$url' 到子模组路径 '$sm_path'"
-#: git-submodule.sh:160
+#: git-submodule.sh:196
#, sh-format
msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
msgstr "Gitdir '$a' 在子模组路径 '$b' 之下或者相反"
-#: git-submodule.sh:249
+#: git-submodule.sh:285
#, sh-format
msgid "repo URL: '$repo' must be absolute or begin with ./|../"
msgstr "版本库URL:'$repo' 必须是绝对路径或以 ./|../ 起始"
-#: git-submodule.sh:266
+#: git-submodule.sh:302
#, sh-format
msgid "'$sm_path' already exists in the index"
msgstr "'$sm_path' 已经存在于索引中"
-#: git-submodule.sh:283
+#: git-submodule.sh:306
+#, sh-format
+msgid ""
+"The following path is ignored by one of your .gitignore files:\n"
+"$sm_path\n"
+"Use -f if you really want to add it."
+msgstr ""
+"以下路径被您的一个 .gitignore 文件所忽略:\n"
+"$sm_path\n"
+"如果您确实想添加它,使用 -f 参数。"
+
+#: git-submodule.sh:317
+#, sh-format
+msgid "Adding existing repo at '$sm_path' to the index"
+msgstr "添加位于 '$sm_path' 的现存版本库到索引"
+
+#: git-submodule.sh:319
#, sh-format
msgid "'$sm_path' already exists and is not a valid git repo"
msgstr "'$sm_path' 已存在且不是一个有效的 git 版本库"
-#: git-submodule.sh:297
+#: git-submodule.sh:333
#, sh-format
msgid "Unable to checkout submodule '$sm_path'"
msgstr "不能检出子模组 '$sm_path'"
-#: git-submodule.sh:302
+#: git-submodule.sh:338
#, sh-format
msgid "Failed to add submodule '$sm_path'"
msgstr "无法添加子模组 '$sm_path'"
-#: git-submodule.sh:307
+#: git-submodule.sh:343
#, sh-format
msgid "Failed to register submodule '$sm_path'"
msgstr "无法注册子模组 '$sm_path'"
-#: git-submodule.sh:349
+#: git-submodule.sh:385
#, sh-format
msgid "Entering '$prefix$sm_path'"
msgstr "正在进入 '$prefix$sm_path'"
-#: git-submodule.sh:363
+#: git-submodule.sh:399
#, sh-format
msgid "Stopping at '$sm_path'; script returned non-zero status."
msgstr "停止于 '$sm_path',脚本返回非零值。"
-#: git-submodule.sh:405
+#: git-submodule.sh:442
#, sh-format
msgid "No url found for submodule path '$sm_path' in .gitmodules"
msgstr "在 .gitmodules 中未找到子模组路径 '$sm_path' 的 url"
-#: git-submodule.sh:414
+#: git-submodule.sh:451
#, sh-format
msgid "Failed to register url for submodule path '$sm_path'"
msgstr "无法为子模组路径 '$sm_path' 注册 url"
-#: git-submodule.sh:422
-#, sh-format
-msgid "Failed to register update mode for submodule path '$sm_path'"
-msgstr "无法为子模组路径 '$sm_path' 注册更新模式"
-
-#: git-submodule.sh:424
+#: git-submodule.sh:453
#, sh-format
msgid "Submodule '$name' ($url) registered for path '$sm_path'"
msgstr "子模组 '$name' ($url) 已为路径 '$sm_path' 注册"
-#: git-submodule.sh:523
+#: git-submodule.sh:461
+#, sh-format
+msgid "Failed to register update mode for submodule path '$sm_path'"
+msgstr "无法为子模组路径 '$sm_path' 注册更新模式"
+
+#: git-submodule.sh:560
#, sh-format
msgid ""
"Submodule path '$sm_path' not initialized\n"
"子模组路径 '$sm_path' 没有初始化\n"
"也许您想用 'update --init'?"
-#: git-submodule.sh:536
+#: git-submodule.sh:573
#, sh-format
msgid "Unable to find current revision in submodule path '$sm_path'"
msgstr "无法在子模组路径 '$sm_path' 中找到当前版本"
-#: git-submodule.sh:555
+#: git-submodule.sh:592
#, sh-format
msgid "Unable to fetch in submodule path '$sm_path'"
msgstr "无法在子模组路径 '$sm_path' 中获取"
-#: git-submodule.sh:569
+#: git-submodule.sh:606
#, sh-format
msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
msgstr "无法在子模组路径 '$sm_path' 中变基 '$sha1'"
-#: git-submodule.sh:570
+#: git-submodule.sh:607
#, sh-format
msgid "Submodule path '$sm_path': rebased into '$sha1'"
msgstr "子模组路径 '$sm_path':变基至 '$sha1'"
-#: git-submodule.sh:575
+#: git-submodule.sh:612
#, sh-format
msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
msgstr "无法合并 '$sha1' 到子模组路径 '$sm_path' 中"
-#: git-submodule.sh:576
+#: git-submodule.sh:613
#, sh-format
msgid "Submodule path '$sm_path': merged in '$sha1'"
msgstr "子模组路径 '$sm_path':已合并入 '$sha1'"
-#: git-submodule.sh:581
+#: git-submodule.sh:618
#, sh-format
msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
msgstr "无法在子模组路径 '$sm_path' 中检出 '$sha1'"
-#: git-submodule.sh:582
+#: git-submodule.sh:619
#, sh-format
msgid "Submodule path '$sm_path': checked out '$sha1'"
msgstr "子模组路径 '$sm_path':检出 '$sha1'"
-#: git-submodule.sh:604 git-submodule.sh:927
+#: git-submodule.sh:641 git-submodule.sh:964
#, sh-format
msgid "Failed to recurse into submodule path '$sm_path'"
msgstr "无法递归进子模组路径 '$sm_path'"
-#: git-submodule.sh:712
-msgid "--"
-msgstr "--"
+#: git-submodule.sh:749
+msgid "--cached cannot be used with --files"
+msgstr "--cached 不能和 --files 共用"
+
+#. unexpected type
+#: git-submodule.sh:789
+#, sh-format
+msgid "unexpected mode $mod_dst"
+msgstr "意外的模式 $mod_dst"
# 译者:注意保持前导空格
-#: git-submodule.sh:770
+#: git-submodule.sh:807
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_src"
msgstr " 警告:$name 未包含提交 $sha1_src"
# 译者:注意保持前导空格
-#: git-submodule.sh:773
+#: git-submodule.sh:810
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_dst"
msgstr " 警告:$name 未包含提交 $sha1_dst"
# 译者:注意保持前导空格
-#: git-submodule.sh:776
+#: git-submodule.sh:813
#, sh-format
msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
msgstr " 警告:$name 未包含提交 $sha1_src 和 $sha1_dst"
-#: git-submodule.sh:801
+#: git-submodule.sh:838
msgid "blob"
msgstr "blob"
-#: git-submodule.sh:802
+#: git-submodule.sh:839
msgid "submodule"
msgstr "子模组"
-#: git-submodule.sh:973
+#: git-submodule.sh:876
+msgid "# Submodules changed but not updated:"
+msgstr "# 子模组已修改但尚未更新:"
+
+#: git-submodule.sh:878
+msgid "# Submodule changes to be committed:"
+msgstr "要提交的子模组变更:"
+
+#: git-submodule.sh:1022
#, sh-format
msgid "Synchronizing submodule url for '$name'"
msgstr "为 '$name' 同步子模组 url"
-
-#~ msgid "cherry-pick"
-#~ msgstr "拣选"
-
-#~ msgid "Please enter the commit message for your changes."
-#~ msgstr "请为您的修改输入提交说明。"
-
-#~ msgid "Too many options specified"
-#~ msgstr "指定了太多的选项"
int cache_name_compare(const char *name1, int flags1, const char *name2, int flags2)
{
- int len1 = flags1 & CE_NAMEMASK;
- int len2 = flags2 & CE_NAMEMASK;
- int len = len1 < len2 ? len1 : len2;
- int cmp;
+ int len1, len2, len, cmp;
+
+ len1 = flags1 & CE_NAMEMASK;
+ if (CE_NAMEMASK <= len1)
+ len1 = strlen(name1 + CE_NAMEMASK) + CE_NAMEMASK;
+ len2 = flags2 & CE_NAMEMASK;
+ if (CE_NAMEMASK <= len2)
+ len2 = strlen(name2 + CE_NAMEMASK) + CE_NAMEMASK;
+ len = len1 < len2 ? len1 : len2;
cmp = memcmp(name1, name2, len);
if (cmp)
continue;
if (pathspec &&
- !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen))
+ !match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))
filtered = 1;
if (ce_stage(ce)) {
if (!ce_stage(ce))
continue;
unmerged = 1;
- len = strlen(ce->name);
+ len = ce_namelen(ce);
size = cache_entry_size(len);
new_ce = xcalloc(1, size);
memcpy(new_ce->name, ce->name, len);
case 0:
if (!memcmp(dst_value, "refs/", 5))
matched_dst = make_linked_ref(dst_value, dst_tail);
+ else if (is_null_sha1(matched_src->new_sha1))
+ error("unable to delete '%s': remote ref does not exist",
+ dst_value);
else if ((dst_guess = guess_ref(dst_value, matched_src)))
matched_dst = make_linked_ref(dst_guess, dst_tail);
else
continue;
hex = xstrdup(sha1_to_hex(sha1));
string_list_insert(rr, path)->util = hex;
- if (mkdir(git_path("rr-cache/%s", hex), 0755))
+ if (mkdir_in_gitdir(git_path("rr-cache/%s", hex)))
continue;
handle_file(path, NULL, rerere_path(hex, "preimage"));
fprintf(stderr, "Recorded preimage for '%s'\n", path);
if (has_rerere_resolution(name)) {
if (!merge(name, path)) {
- if (rerere_autoupdate)
+ const char *msg;
+ if (rerere_autoupdate) {
string_list_insert(&update, path);
- fprintf(stderr,
- "%s '%s' using previous resolution.\n",
- rerere_autoupdate
- ? "Staged" : "Resolved",
- path);
+ msg = "Staged '%s' using previous resolution.\n";
+ } else
+ msg = "Resolved '%s' using previous resolution.\n";
+ fprintf(stderr, msg, path);
goto mark_resolved;
}
}
flags ^= UNINTERESTING;
arg++;
}
- if (get_sha1(arg, sha1))
+ if (get_sha1_committish(arg, sha1))
return 0;
while (1) {
it = get_reference(revs, arg, sha1, 0);
revs->limited = 1;
}
-int handle_revision_arg(const char *arg_, struct rev_info *revs,
- int flags,
- int cant_be_filename)
+int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsigned revarg_opt)
{
- unsigned mode;
+ struct object_context oc;
char *dotdot;
struct object *object;
unsigned char sha1[20];
int local_flags;
const char *arg = arg_;
+ int cant_be_filename = revarg_opt & REVARG_CANNOT_BE_FILENAME;
+ unsigned get_sha1_flags = 0;
dotdot = strstr(arg, "..");
if (dotdot) {
next = "HEAD";
if (dotdot == arg)
this = "HEAD";
- if (!get_sha1(this, from_sha1) &&
- !get_sha1(next, sha1)) {
+ if (!get_sha1_committish(this, from_sha1) &&
+ !get_sha1_committish(next, sha1)) {
struct commit *a, *b;
struct commit_list *exclude;
local_flags = UNINTERESTING;
arg++;
}
- if (get_sha1_with_mode(arg, sha1, &mode))
+
+ if (revarg_opt & REVARG_COMMITTISH)
+ get_sha1_flags = GET_SHA1_COMMITTISH;
+
+ if (get_sha1_with_context(arg, get_sha1_flags, sha1, &oc))
return revs->ignore_missing ? 0 : -1;
if (!cant_be_filename)
verify_non_filename(revs->prefix, arg);
object = get_reference(revs, arg, sha1, flags ^ local_flags);
add_rev_cmdline(revs, object, arg_, REV_CMD_REV, flags ^ local_flags);
- add_pending_object_with_mode(revs, object, arg, mode);
+ add_pending_object_with_mode(revs, object, arg, oc.mode);
return 0;
}
}
die("options not supported in --stdin mode");
}
- if (handle_revision_arg(sb.buf, revs, 0, 1))
+ if (handle_revision_arg(sb.buf, revs, 0, REVARG_CANNOT_BE_FILENAME))
die("bad revision '%s'", sb.buf);
}
if (seen_dashdash)
revs->topo_order = 1;
} else if (!strcmp(arg, "--simplify-merges")) {
revs->simplify_merges = 1;
+ revs->topo_order = 1;
revs->rewrite_parents = 1;
revs->simplify_history = 0;
revs->limited = 1;
} else if (!strcmp(arg, "--simplify-by-decoration")) {
revs->simplify_merges = 1;
+ revs->topo_order = 1;
revs->rewrite_parents = 1;
revs->simplify_history = 0;
revs->simplify_by_decoration = 1;
*/
int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *opt)
{
- int i, flags, left, seen_dashdash, read_from_stdin, got_rev_arg = 0;
+ int i, flags, left, seen_dashdash, read_from_stdin, got_rev_arg = 0, revarg_opt;
struct cmdline_pathspec prune_data;
const char *submodule = NULL;
/* Second, deal with arguments and options */
flags = 0;
+ revarg_opt = opt ? opt->revarg_opt : 0;
+ if (seen_dashdash)
+ revarg_opt |= REVARG_CANNOT_BE_FILENAME;
read_from_stdin = 0;
for (left = i = 1; i < argc; i++) {
const char *arg = argv[i];
continue;
}
- if (handle_revision_arg(arg, revs, flags, seen_dashdash)) {
+
+ if (handle_revision_arg(arg, revs, flags, revarg_opt)) {
int j;
if (seen_dashdash || *arg == '^')
die("bad revision '%s'", arg);
* but the latter we have checked in the main loop.
*/
for (j = i; j < argc; j++)
- verify_filename(revs->prefix, argv[j]);
+ verify_filename(revs->prefix, argv[j], j == i);
append_prune_data(&prune_data, argv + i);
break;
if (revs->def && !revs->pending.nr && !got_rev_arg) {
unsigned char sha1[20];
struct object *object;
- unsigned mode;
- if (get_sha1_with_mode(revs->def, sha1, &mode))
+ struct object_context oc;
+ if (get_sha1_with_context(revs->def, 0, sha1, &oc))
die("bad default revision '%s'", revs->def);
object = get_reference(revs, revs->def, sha1, 0);
- add_pending_object_with_mode(revs, object, revs->def, mode);
+ add_pending_object_with_mode(revs, object, revs->def, oc.mode);
}
/* Did the user ask for any diff output? Run the diff! */
}
/*
- * Do we know what commit all of our parents should be rewritten to?
- * Otherwise we are not ready to rewrite this one yet.
+ * Do we know what commit all of our parents that matter
+ * should be rewritten to? Otherwise we are not ready to
+ * rewrite this one yet.
*/
for (cnt = 0, p = commit->parents; p; p = p->next) {
pst = locate_simplify_state(revs, p->item);
tail = &commit_list_insert(p->item, tail)->next;
cnt++;
}
+ if (revs->first_parent_only)
+ break;
}
if (cnt) {
tail = &commit_list_insert(commit, tail)->next;
for (p = commit->parents; p; p = p->next) {
pst = locate_simplify_state(revs, p->item);
p->item = pst->simplified;
+ if (revs->first_parent_only)
+ break;
}
- cnt = remove_duplicate_parents(commit);
+ if (!revs->first_parent_only)
+ cnt = remove_duplicate_parents(commit);
+ else
+ cnt = 1;
/*
* It is possible that we are a merge and one side branch
static void simplify_merges(struct rev_info *revs)
{
- struct commit_list *list;
+ struct commit_list *list, *next;
struct commit_list *yet_to_do, **tail;
+ struct commit *commit;
- if (!revs->topo_order)
- sort_in_topological_order(&revs->commits, revs->lifo);
if (!revs->prune)
return;
/* feed the list reversed */
yet_to_do = NULL;
- for (list = revs->commits; list; list = list->next)
- commit_list_insert(list->item, &yet_to_do);
+ for (list = revs->commits; list; list = next) {
+ commit = list->item;
+ next = list->next;
+ /*
+ * Do not free(list) here yet; the original list
+ * is used later in this function.
+ */
+ commit_list_insert(commit, &yet_to_do);
+ }
while (yet_to_do) {
list = yet_to_do;
yet_to_do = NULL;
tail = &yet_to_do;
while (list) {
- struct commit *commit = list->item;
- struct commit_list *next = list->next;
+ commit = list->item;
+ next = list->next;
free(list);
list = next;
tail = simplify_one(revs, commit, tail);
revs->commits = NULL;
tail = &revs->commits;
while (list) {
- struct commit *commit = list->item;
- struct commit_list *next = list->next;
struct merge_simplify_state *st;
+
+ commit = list->item;
+ next = list->next;
free(list);
list = next;
st = locate_simplify_state(revs, commit);
void (*tweak)(struct rev_info *, struct setup_revision_opt *);
const char *submodule;
int assume_dashdash;
+ unsigned revarg_opt;
};
extern void init_revisions(struct rev_info *revs, const char *prefix);
extern void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,
const struct option *options,
const char * const usagestr[]);
-extern int handle_revision_arg(const char *arg, struct rev_info *revs,int flags,int cant_be_filename);
+#define REVARG_CANNOT_BE_FILENAME 01
+#define REVARG_COMMITTISH 02
+extern int handle_revision_arg(const char *arg, struct rev_info *revs, int flags, unsigned revarg_opt);
extern void reset_revision_walk(void);
extern int prepare_revision_walk(struct rev_info *revs);
static int inside_git_dir = -1;
static int inside_work_tree = -1;
-char *prefix_path(const char *prefix, int len, const char *path)
+static char *prefix_path_gently(const char *prefix, int len, const char *path)
{
const char *orig = path;
char *sanitized;
if (strncmp(sanitized, work_tree, len) ||
(len > root_len && sanitized[len] != '\0' && sanitized[len] != '/')) {
error_out:
- die("'%s' is outside repository", orig);
+ free(sanitized);
+ return NULL;
}
if (sanitized[len] == '/')
len++;
return sanitized;
}
+char *prefix_path(const char *prefix, int len, const char *path)
+{
+ char *r = prefix_path_gently(prefix, len, path);
+ if (!r)
+ die("'%s' is outside repository", path);
+ return r;
+}
+
+int path_inside_repo(const char *prefix, const char *path)
+{
+ int len = prefix ? strlen(prefix) : 0;
+ char *r = prefix_path_gently(prefix, len, path);
+ if (r) {
+ free(r);
+ return 1;
+ }
+ return 0;
+}
+
int check_filename(const char *prefix, const char *arg)
{
const char *name;
die_errno("failed to stat '%s'", arg);
}
-static void NORETURN die_verify_filename(const char *prefix, const char *arg)
+static void NORETURN die_verify_filename(const char *prefix,
+ const char *arg,
+ int diagnose_misspelt_rev)
{
- unsigned char sha1[20];
- unsigned mode;
-
+ if (!diagnose_misspelt_rev)
+ die("%s: no such path in the working tree.\n"
+ "Use '-- <path>...' to specify paths that do not exist locally.",
+ arg);
/*
* Saying "'(icase)foo' does not exist in the index" when the
* user gave us ":(icase)foo" is just stupid. A magic pathspec
* begins with a colon and is followed by a non-alnum; do not
- * let get_sha1_with_mode_1(only_to_die=1) to even trigger.
+ * let maybe_die_on_misspelt_object_name() even trigger.
*/
if (!(arg[0] == ':' && !isalnum(arg[1])))
- /* try a detailed diagnostic ... */
- get_sha1_with_mode_1(arg, sha1, &mode, 1, prefix);
+ maybe_die_on_misspelt_object_name(arg, prefix);
/* ... or fall back the most general message. */
die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
* as true, because even if such a filename were to exist, we want
* it to be preceded by the "--" marker (or we want the user to
* use a format like "./-filename")
+ *
+ * The "diagnose_misspelt_rev" is used to provide a user-friendly
+ * diagnosis when dying upon finding that "name" is not a pathname.
+ * If set to 1, the diagnosis will try to diagnose "name" as an
+ * invalid object name (e.g. HEAD:foo). If set to 0, the diagnosis
+ * will only complain about an inexisting file.
+ *
+ * This function is typically called to check that a "file or rev"
+ * argument is unambiguous. In this case, the caller will want
+ * diagnose_misspelt_rev == 1 when verifying the first non-rev
+ * argument (which could have been a revision), and
+ * diagnose_misspelt_rev == 0 for the next ones (because we already
+ * saw a filename, there's not ambiguity anymore).
*/
-void verify_filename(const char *prefix, const char *arg)
+void verify_filename(const char *prefix,
+ const char *arg,
+ int diagnose_misspelt_rev)
{
if (*arg == '-')
die("bad flag '%s' used after filename", arg);
if (check_filename(prefix, arg))
return;
- die_verify_filename(prefix, arg);
+ die_verify_filename(prefix, arg, diagnose_misspelt_rev);
}
/*
static int get_sha1_oneline(const char *, unsigned char *, struct commit_list *);
-static int find_short_object_filename(int len, const char *name, unsigned char *sha1)
+typedef int (*disambiguate_hint_fn)(const unsigned char *, void *);
+
+struct disambiguate_state {
+ disambiguate_hint_fn fn;
+ void *cb_data;
+ unsigned char candidate[20];
+ unsigned candidate_exists:1;
+ unsigned candidate_checked:1;
+ unsigned candidate_ok:1;
+ unsigned disambiguate_fn_used:1;
+ unsigned ambiguous:1;
+ unsigned always_call_fn:1;
+};
+
+static void update_candidates(struct disambiguate_state *ds, const unsigned char *current)
+{
+ if (ds->always_call_fn) {
+ ds->ambiguous = ds->fn(current, ds->cb_data) ? 1 : 0;
+ return;
+ }
+ if (!ds->candidate_exists) {
+ /* this is the first candidate */
+ hashcpy(ds->candidate, current);
+ ds->candidate_exists = 1;
+ return;
+ } else if (!hashcmp(ds->candidate, current)) {
+ /* the same as what we already have seen */
+ return;
+ }
+
+ if (!ds->fn) {
+ /* cannot disambiguate between ds->candidate and current */
+ ds->ambiguous = 1;
+ return;
+ }
+
+ if (!ds->candidate_checked) {
+ ds->candidate_ok = ds->fn(ds->candidate, ds->cb_data);
+ ds->disambiguate_fn_used = 1;
+ ds->candidate_checked = 1;
+ }
+
+ if (!ds->candidate_ok) {
+ /* discard the candidate; we know it does not satisify fn */
+ hashcpy(ds->candidate, current);
+ ds->candidate_checked = 0;
+ return;
+ }
+
+ /* if we reach this point, we know ds->candidate satisfies fn */
+ if (ds->fn(current, ds->cb_data)) {
+ /*
+ * if both current and candidate satisfy fn, we cannot
+ * disambiguate.
+ */
+ ds->candidate_ok = 0;
+ ds->ambiguous = 1;
+ }
+
+ /* otherwise, current can be discarded and candidate is still good */
+}
+
+static void find_short_object_filename(int len, const char *hex_pfx, struct disambiguate_state *ds)
{
struct alternate_object_database *alt;
char hex[40];
- int found = 0;
static struct alternate_object_database *fakeent;
if (!fakeent) {
+ /*
+ * Create a "fake" alternate object database that
+ * points to our own object database, to make it
+ * easier to get a temporary working space in
+ * alt->name/alt->base while iterating over the
+ * object databases including our own.
+ */
const char *objdir = get_object_directory();
int objdir_len = strlen(objdir);
int entlen = objdir_len + 43;
}
fakeent->next = alt_odb_list;
- sprintf(hex, "%.2s", name);
- for (alt = fakeent; alt && found < 2; alt = alt->next) {
+ sprintf(hex, "%.2s", hex_pfx);
+ for (alt = fakeent; alt && !ds->ambiguous; alt = alt->next) {
struct dirent *de;
DIR *dir;
- sprintf(alt->name, "%.2s/", name);
+ sprintf(alt->name, "%.2s/", hex_pfx);
dir = opendir(alt->base);
if (!dir)
continue;
- while ((de = readdir(dir)) != NULL) {
+
+ while (!ds->ambiguous && (de = readdir(dir)) != NULL) {
+ unsigned char sha1[20];
+
if (strlen(de->d_name) != 38)
continue;
- if (memcmp(de->d_name, name + 2, len - 2))
+ if (memcmp(de->d_name, hex_pfx + 2, len - 2))
continue;
- if (!found) {
- memcpy(hex + 2, de->d_name, 38);
- found++;
- }
- else if (memcmp(hex + 2, de->d_name, 38)) {
- found = 2;
- break;
- }
+ memcpy(hex + 2, de->d_name, 38);
+ if (!get_sha1_hex(hex, sha1))
+ update_candidates(ds, sha1);
}
closedir(dir);
}
- if (found == 1)
- return get_sha1_hex(hex, sha1) == 0;
- return found;
}
static int match_sha(unsigned len, const unsigned char *a, const unsigned char *b)
return 1;
}
-static int find_short_packed_object(int len, const unsigned char *match, unsigned char *sha1)
+static void unique_in_pack(int len,
+ const unsigned char *bin_pfx,
+ struct packed_git *p,
+ struct disambiguate_state *ds)
{
- struct packed_git *p;
- const unsigned char *found_sha1 = NULL;
- int found = 0;
-
- prepare_packed_git();
- for (p = packed_git; p && found < 2; p = p->next) {
- uint32_t num, last;
- uint32_t first = 0;
- open_pack_index(p);
- num = p->num_objects;
- last = num;
- while (first < last) {
- uint32_t mid = (first + last) / 2;
- const unsigned char *now;
- int cmp;
-
- now = nth_packed_object_sha1(p, mid);
- cmp = hashcmp(match, now);
- if (!cmp) {
- first = mid;
- break;
- }
- if (cmp > 0) {
- first = mid+1;
- continue;
- }
- last = mid;
+ uint32_t num, last, i, first = 0;
+ const unsigned char *current = NULL;
+
+ open_pack_index(p);
+ num = p->num_objects;
+ last = num;
+ while (first < last) {
+ uint32_t mid = (first + last) / 2;
+ const unsigned char *current;
+ int cmp;
+
+ current = nth_packed_object_sha1(p, mid);
+ cmp = hashcmp(bin_pfx, current);
+ if (!cmp) {
+ first = mid;
+ break;
}
- if (first < num) {
- const unsigned char *now, *next;
- now = nth_packed_object_sha1(p, first);
- if (match_sha(len, match, now)) {
- next = nth_packed_object_sha1(p, first+1);
- if (!next|| !match_sha(len, match, next)) {
- /* unique within this pack */
- if (!found) {
- found_sha1 = now;
- found++;
- }
- else if (hashcmp(found_sha1, now)) {
- found = 2;
- break;
- }
- }
- else {
- /* not even unique within this pack */
- found = 2;
- break;
- }
- }
+ if (cmp > 0) {
+ first = mid+1;
+ continue;
}
+ last = mid;
+ }
+
+ /*
+ * At this point, "first" is the location of the lowest object
+ * with an object name that could match "bin_pfx". See if we have
+ * 0, 1 or more objects that actually match(es).
+ */
+ for (i = first; i < num && !ds->ambiguous; i++) {
+ current = nth_packed_object_sha1(p, i);
+ if (!match_sha(len, bin_pfx, current))
+ break;
+ update_candidates(ds, current);
}
- if (found == 1)
- hashcpy(sha1, found_sha1);
- return found;
+}
+
+static void find_short_packed_object(int len, const unsigned char *bin_pfx,
+ struct disambiguate_state *ds)
+{
+ struct packed_git *p;
+
+ prepare_packed_git();
+ for (p = packed_git; p && !ds->ambiguous; p = p->next)
+ unique_in_pack(len, bin_pfx, p, ds);
}
#define SHORT_NAME_NOT_FOUND (-1)
#define SHORT_NAME_AMBIGUOUS (-2)
-static int find_unique_short_object(int len, char *canonical,
- unsigned char *res, unsigned char *sha1)
+static int finish_object_disambiguation(struct disambiguate_state *ds,
+ unsigned char *sha1)
{
- int has_unpacked, has_packed;
- unsigned char unpacked_sha1[20], packed_sha1[20];
+ if (ds->ambiguous)
+ return SHORT_NAME_AMBIGUOUS;
- prepare_alt_odb();
- has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);
- has_packed = find_short_packed_object(len, res, packed_sha1);
- if (!has_unpacked && !has_packed)
+ if (!ds->candidate_exists)
return SHORT_NAME_NOT_FOUND;
- if (1 < has_unpacked || 1 < has_packed)
+
+ if (!ds->candidate_checked)
+ /*
+ * If this is the only candidate, there is no point
+ * calling the disambiguation hint callback.
+ *
+ * On the other hand, if the current candidate
+ * replaced an earlier candidate that did _not_ pass
+ * the disambiguation hint callback, then we do have
+ * more than one objects that match the short name
+ * given, so we should make sure this one matches;
+ * otherwise, if we discovered this one and the one
+ * that we previously discarded in the reverse order,
+ * we would end up showing different results in the
+ * same repository!
+ */
+ ds->candidate_ok = (!ds->disambiguate_fn_used ||
+ ds->fn(ds->candidate, ds->cb_data));
+
+ if (!ds->candidate_ok)
return SHORT_NAME_AMBIGUOUS;
- if (has_unpacked != has_packed) {
- hashcpy(sha1, (has_packed ? packed_sha1 : unpacked_sha1));
+
+ hashcpy(sha1, ds->candidate);
+ return 0;
+}
+
+static int disambiguate_commit_only(const unsigned char *sha1, void *cb_data_unused)
+{
+ int kind = sha1_object_info(sha1, NULL);
+ return kind == OBJ_COMMIT;
+}
+
+static int disambiguate_committish_only(const unsigned char *sha1, void *cb_data_unused)
+{
+ struct object *obj;
+ int kind;
+
+ kind = sha1_object_info(sha1, NULL);
+ if (kind == OBJ_COMMIT)
+ return 1;
+ if (kind != OBJ_TAG)
return 0;
- }
- /* Both have unique ones -- do they match? */
- if (hashcmp(packed_sha1, unpacked_sha1))
- return SHORT_NAME_AMBIGUOUS;
- hashcpy(sha1, packed_sha1);
+
+ /* We need to do this the hard way... */
+ obj = deref_tag(lookup_object(sha1), NULL, 0);
+ if (obj && obj->type == OBJ_COMMIT)
+ return 1;
return 0;
}
-static int get_short_sha1(const char *name, int len, unsigned char *sha1,
- int quietly)
+static int disambiguate_tree_only(const unsigned char *sha1, void *cb_data_unused)
{
- int i, status;
- char canonical[40];
- unsigned char res[20];
+ int kind = sha1_object_info(sha1, NULL);
+ return kind == OBJ_TREE;
+}
- if (len < MINIMUM_ABBREV || len > 40)
- return -1;
- hashclr(res);
- memset(canonical, 'x', 40);
+static int disambiguate_treeish_only(const unsigned char *sha1, void *cb_data_unused)
+{
+ struct object *obj;
+ int kind;
+
+ kind = sha1_object_info(sha1, NULL);
+ if (kind == OBJ_TREE || kind == OBJ_COMMIT)
+ return 1;
+ if (kind != OBJ_TAG)
+ return 0;
+
+ /* We need to do this the hard way... */
+ obj = deref_tag(lookup_object(sha1), NULL, 0);
+ if (obj && (obj->type == OBJ_TREE || obj->type == OBJ_COMMIT))
+ return 1;
+ return 0;
+}
+
+static int disambiguate_blob_only(const unsigned char *sha1, void *cb_data_unused)
+{
+ int kind = sha1_object_info(sha1, NULL);
+ return kind == OBJ_BLOB;
+}
+
+static int prepare_prefixes(const char *name, int len,
+ unsigned char *bin_pfx,
+ char *hex_pfx)
+{
+ int i;
+
+ hashclr(bin_pfx);
+ memset(hex_pfx, 'x', 40);
for (i = 0; i < len ;i++) {
unsigned char c = name[i];
unsigned char val;
}
else
return -1;
- canonical[i] = c;
+ hex_pfx[i] = c;
if (!(i & 1))
val <<= 4;
- res[i >> 1] |= val;
+ bin_pfx[i >> 1] |= val;
}
+ return 0;
+}
+
+static int get_short_sha1(const char *name, int len, unsigned char *sha1,
+ unsigned flags)
+{
+ int status;
+ char hex_pfx[40];
+ unsigned char bin_pfx[20];
+ struct disambiguate_state ds;
+ int quietly = !!(flags & GET_SHA1_QUIETLY);
+
+ if (len < MINIMUM_ABBREV || len > 40)
+ return -1;
+ if (prepare_prefixes(name, len, bin_pfx, hex_pfx) < 0)
+ return -1;
+
+ prepare_alt_odb();
+
+ memset(&ds, 0, sizeof(ds));
+ if (flags & GET_SHA1_COMMIT)
+ ds.fn = disambiguate_commit_only;
+ else if (flags & GET_SHA1_COMMITTISH)
+ ds.fn = disambiguate_committish_only;
+ else if (flags & GET_SHA1_TREE)
+ ds.fn = disambiguate_tree_only;
+ else if (flags & GET_SHA1_TREEISH)
+ ds.fn = disambiguate_treeish_only;
+ else if (flags & GET_SHA1_BLOB)
+ ds.fn = disambiguate_blob_only;
+
+ find_short_object_filename(len, hex_pfx, &ds);
+ find_short_packed_object(len, bin_pfx, &ds);
+ status = finish_object_disambiguation(&ds, sha1);
- status = find_unique_short_object(i, canonical, res, sha1);
if (!quietly && (status == SHORT_NAME_AMBIGUOUS))
- return error("short SHA1 %.*s is ambiguous.", len, canonical);
+ return error("short SHA1 %.*s is ambiguous.", len, hex_pfx);
return status;
}
+
+int for_each_abbrev(const char *prefix, each_abbrev_fn fn, void *cb_data)
+{
+ char hex_pfx[40];
+ unsigned char bin_pfx[20];
+ struct disambiguate_state ds;
+ int len = strlen(prefix);
+
+ if (len < MINIMUM_ABBREV || len > 40)
+ return -1;
+ if (prepare_prefixes(prefix, len, bin_pfx, hex_pfx) < 0)
+ return -1;
+
+ prepare_alt_odb();
+
+ memset(&ds, 0, sizeof(ds));
+ ds.always_call_fn = 1;
+ ds.cb_data = cb_data;
+ ds.fn = fn;
+
+ find_short_object_filename(len, hex_pfx, &ds);
+ find_short_packed_object(len, bin_pfx, &ds);
+ return ds.ambiguous;
+}
+
const char *find_unique_abbrev(const unsigned char *sha1, int len)
{
int status, exists;
return hex;
while (len < 40) {
unsigned char sha1_ret[20];
- status = get_short_sha1(hex, len, sha1_ret, 1);
+ status = get_short_sha1(hex, len, sha1_ret, GET_SHA1_QUIETLY);
if (exists
? !status
: status == SHORT_NAME_NOT_FOUND) {
return 0;
}
-static int get_sha1_1(const char *name, int len, unsigned char *sha1);
+static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned lookup_flags);
static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
{
ret = interpret_branch_name(str+at, &buf);
if (ret > 0) {
/* substitute this branch name and restart */
- return get_sha1_1(buf.buf, buf.len, sha1);
+ return get_sha1_1(buf.buf, buf.len, sha1, 0);
} else if (ret == 0) {
return -1;
}
unsigned char *result, int idx)
{
unsigned char sha1[20];
- int ret = get_sha1_1(name, len, sha1);
+ int ret = get_sha1_1(name, len, sha1, GET_SHA1_COMMITTISH);
struct commit *commit;
struct commit_list *p;
struct commit *commit;
int ret;
- ret = get_sha1_1(name, len, sha1);
+ ret = get_sha1_1(name, len, sha1, GET_SHA1_COMMITTISH);
if (ret)
return ret;
commit = lookup_commit_reference(sha1);
unsigned char outer[20];
const char *sp;
unsigned int expected_type = 0;
+ unsigned lookup_flags = 0;
struct object *o;
/*
else
return -1;
- if (get_sha1_1(name, sp - name - 2, outer))
+ if (expected_type == OBJ_COMMIT)
+ lookup_flags = GET_SHA1_COMMITTISH;
+
+ if (get_sha1_1(name, sp - name - 2, outer, lookup_flags))
return -1;
o = parse_object(outer);
static int get_describe_name(const char *name, int len, unsigned char *sha1)
{
const char *cp;
+ unsigned flags = GET_SHA1_QUIETLY | GET_SHA1_COMMIT;
for (cp = name + len - 1; name + 2 <= cp; cp--) {
char ch = *cp;
if (ch == 'g' && cp[-1] == '-') {
cp++;
len -= cp - name;
- return get_short_sha1(cp, len, sha1, 1);
+ return get_short_sha1(cp, len, sha1, flags);
}
}
}
return -1;
}
-static int get_sha1_1(const char *name, int len, unsigned char *sha1)
+static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned lookup_flags)
{
int ret, has_suffix;
const char *cp;
if (!ret)
return 0;
- return get_short_sha1(name, len, sha1, 0);
+ return get_short_sha1(name, len, sha1, lookup_flags);
}
/*
struct strbuf sb;
strbuf_init(&sb, dots - name);
strbuf_add(&sb, name, dots - name);
- st = get_sha1(sb.buf, sha1_tmp);
+ st = get_sha1_committish(sb.buf, sha1_tmp);
strbuf_release(&sb);
}
if (st)
if (!one)
return -1;
- if (get_sha1(dots[3] ? (dots + 3) : "HEAD", sha1_tmp))
+ if (get_sha1_committish(dots[3] ? (dots + 3) : "HEAD", sha1_tmp))
return -1;
two = lookup_commit_reference_gently(sha1_tmp, 0);
if (!two)
int get_sha1(const char *name, unsigned char *sha1)
{
struct object_context unused;
- return get_sha1_with_context(name, sha1, &unused);
+ return get_sha1_with_context(name, 0, sha1, &unused);
+}
+
+/*
+ * Many callers know that the user meant to name a committish by
+ * syntactical positions where the object name appears. Calling this
+ * function allows the machinery to disambiguate shorter-than-unique
+ * abbreviated object names between committish and others.
+ *
+ * Note that this does NOT error out when the named object is not a
+ * committish. It is merely to give a hint to the disambiguation
+ * machinery.
+ */
+int get_sha1_committish(const char *name, unsigned char *sha1)
+{
+ struct object_context unused;
+ return get_sha1_with_context(name, GET_SHA1_COMMITTISH,
+ sha1, &unused);
+}
+
+int get_sha1_treeish(const char *name, unsigned char *sha1)
+{
+ struct object_context unused;
+ return get_sha1_with_context(name, GET_SHA1_TREEISH,
+ sha1, &unused);
+}
+
+int get_sha1_commit(const char *name, unsigned char *sha1)
+{
+ struct object_context unused;
+ return get_sha1_with_context(name, GET_SHA1_COMMIT,
+ sha1, &unused);
+}
+
+int get_sha1_tree(const char *name, unsigned char *sha1)
+{
+ struct object_context unused;
+ return get_sha1_with_context(name, GET_SHA1_TREE,
+ sha1, &unused);
+}
+
+int get_sha1_blob(const char *name, unsigned char *sha1)
+{
+ struct object_context unused;
+ return get_sha1_with_context(name, GET_SHA1_BLOB,
+ sha1, &unused);
}
/* Must be called only when object_name:filename doesn't exist. */
}
-int get_sha1_with_mode_1(const char *name, unsigned char *sha1, unsigned *mode,
- int only_to_die, const char *prefix)
-{
- struct object_context oc;
- int ret;
- ret = get_sha1_with_context_1(name, sha1, &oc, only_to_die, prefix);
- *mode = oc.mode;
- return ret;
-}
-
static char *resolve_relative_path(const char *rel)
{
if (prefixcmp(rel, "./") && prefixcmp(rel, "../"))
rel);
}
-int get_sha1_with_context_1(const char *name, unsigned char *sha1,
- struct object_context *oc,
- int only_to_die, const char *prefix)
+static int get_sha1_with_context_1(const char *name,
+ unsigned flags,
+ const char *prefix,
+ unsigned char *sha1,
+ struct object_context *oc)
{
int ret, bracket_depth;
int namelen = strlen(name);
const char *cp;
+ int only_to_die = flags & GET_SHA1_ONLY_TO_DIE;
memset(oc, 0, sizeof(*oc));
oc->mode = S_IFINVALID;
- ret = get_sha1_1(name, namelen, sha1);
+ ret = get_sha1_1(name, namelen, sha1, flags);
if (!ret)
return ret;
- /* sha1:path --> object name of path in ent sha1
+ /*
+ * sha1:path --> object name of path in ent sha1
* :path -> object name of absolute path in index
* :./path -> object name of path relative to cwd in index
* :[0-3]:path -> object name of path in index at stage
strncpy(object_name, name, cp-name);
object_name[cp-name] = '\0';
}
- if (!get_sha1_1(name, cp-name, tree_sha1)) {
+ if (!get_sha1_1(name, cp-name, tree_sha1, GET_SHA1_TREEISH)) {
const char *filename = cp+1;
char *new_filename = NULL;
if (new_filename)
filename = new_filename;
ret = get_tree_entry(tree_sha1, filename, sha1, &oc->mode);
- if (only_to_die) {
+ if (ret && only_to_die) {
diagnose_invalid_sha1_path(prefix, filename,
tree_sha1, object_name);
free(object_name);
}
return ret;
}
+
+/*
+ * Call this function when you know "name" given by the end user must
+ * name an object but it doesn't; the function _may_ die with a better
+ * diagnostic message than "no such object 'name'", e.g. "Path 'doc' does not
+ * exist in 'HEAD'" when given "HEAD:doc", or it may return in which case
+ * you have a chance to diagnose the error further.
+ */
+void maybe_die_on_misspelt_object_name(const char *name, const char *prefix)
+{
+ struct object_context oc;
+ unsigned char sha1[20];
+ get_sha1_with_context_1(name, GET_SHA1_ONLY_TO_DIE, prefix, sha1, &oc);
+}
+
+int get_sha1_with_context(const char *str, unsigned flags, unsigned char *sha1, struct object_context *orc)
+{
+ return get_sha1_with_context_1(str, flags, NULL, sha1, orc);
+}
Use test_done instead if you need to stop the tests early (see
"Skipping tests" below).
+ - use '! git cmd' when you want to make sure the git command exits
+ with failure in a controlled way by calling "die()". Instead,
+ use 'test_must_fail git cmd'. This will signal a failure if git
+ dies in an unexpected way (e.g. segfault).
+
+ - use perl without spelling it as "$PERL_PATH". This is to help our
+ friends on Windows where the platform Perl often adds CR before
+ the end of line, and they bundle Git with a version of Perl that
+ does not do so, whose path is specified with $PERL_PATH.
+
+ - use sh without spelling it as "$SHELL_PATH", when the script can
+ be misinterpreted by broken platform shell (e.g. Solaris).
+
+ - chdir around in tests. It is not sufficient to chdir to
+ somewhere and then chdir back to the original location later in
+ the test, as any intermediate step can fail and abort the test,
+ causing the next test to start in an unexpected directory. Do so
+ inside a subshell if necessary.
+
- Break the TAP output
The raw output from your test may be interpreted by a TAP harness. TAP
of the test_* functions (see the "Test harness library" section
below), e.g.:
- test_expect_success PERL 'I need Perl' "
- '$PERL_PATH' -e 'hlagh() if unf_unf()'
- "
+ test_expect_success PERL 'I need Perl' '
+ "$PERL_PATH" -e "hlagh() if unf_unf()"
+ '
The advantage of skipping tests like this is that platforms that don't
have the PERL and other optional dependencies get an indication of how
--- /dev/null
+#!/bin/sh
+#
+# Ensures that tests are run under Bash; primarily intended for running tests
+# of the completion script.
+
+if test -n "$BASH" && test -z "$POSIXLY_CORRECT"; then
+ # we are in full-on bash mode
+ true
+elif type bash >/dev/null 2>&1; then
+ # execute in full-on bash mode
+ unset POSIXLY_CORRECT
+ exec bash "$0" "$@"
+else
+ echo '1..0 #SKIP skipping bash completion tests; bash not available'
+ exit 0
+fi
+
+. ./test-lib.sh
# stdout and stderr should be provided on stdin,
# separated by "--".
check() {
+ credential_opts=
+ credential_cmd=$1
+ shift
+ for arg in "$@"; do
+ credential_opts="$credential_opts -c credential.helper='$arg'"
+ done
read_chunk >stdin &&
read_chunk >expect-stdout &&
read_chunk >expect-stderr &&
- test-credential "$@" <stdin >stdout 2>stderr &&
+ if ! eval "git $credential_opts credential $credential_cmd <stdin >stdout 2>stderr"; then
+ echo "git credential failed with code $?" &&
+ cat stderr &&
+ false
+ fi &&
test_cmp expect-stdout stdout &&
test_cmp expect-stderr stderr
}
echo protocol=$2
echo host=$3
echo username=$4
- ) | test-credential reject $1
+ ) | git -c credential.helper=$1 credential reject
}
helper_test() {
protocol=https
host=example.com
--
+ protocol=https
+ host=example.com
username=askpass-username
password=askpass-password
--
protocol=https
host=example.com
--
+ protocol=https
+ host=example.com
username=store-user
password=store-pass
--
protocol=http
host=example.com
--
+ protocol=http
+ host=example.com
username=askpass-username
password=askpass-password
--
protocol=https
host=other.tld
--
+ protocol=https
+ host=other.tld
username=askpass-username
password=askpass-password
--
host=example.com
username=other
--
+ protocol=https
+ host=example.com
username=other
password=askpass-password
--
host=path.tld
path=bar.git
--
+ protocol=http
+ host=path.tld
+ path=bar.git
username=askpass-username
password=askpass-password
--
protocol=https
host=example.com
--
+ protocol=https
+ host=example.com
username=askpass-username
password=askpass-password
--
host=example.com
username=user1
--
+ protocol=https
+ host=example.com
username=user1
password=pass1
EOF
host=example.com
username=user2
--
+ protocol=https
+ host=example.com
username=user2
password=pass2
EOF
host=example.com
username=user1
--
+ protocol=https
+ host=example.com
username=user1
password=askpass-password
--
host=example.com
username=user2
--
+ protocol=https
+ host=example.com
username=user2
password=pass2
EOF
protocol=https
host=timeout.tld
--
+ protocol=https
+ host=timeout.tld
username=askpass-username
password=askpass-password
--
# Library code for git p4 tests
#
+# p4 tests never use the top-level repo; always build/clone into
+# a subdirectory called "$git"
+TEST_NO_CREATE_REPO=NoThanks
+
. ./test-lib.sh
if ! test_have_prereq PYTHON; then
export P4EDITOR=:
db="$TRASH_DIRECTORY/db"
-cli="$TRASH_DIRECTORY/cli"
+cli=$(test-path-utils real_path "$TRASH_DIRECTORY/cli")
git="$TRASH_DIRECTORY/git"
pidfile="$TRASH_DIRECTORY/p4d.pid"
start_p4d() {
mkdir -p "$db" "$cli" "$git" &&
+ rm -f "$pidfile" &&
(
p4d -q -r "$db" -p $P4DPORT &
echo $! >"$pidfile"
) &&
- for i in 1 2 3 4 5 ; do
- p4 info >/dev/null 2>&1 && break || true &&
- echo waiting for p4d to start &&
+
+ # This gives p4d a long time to start up, as it can be
+ # quite slow depending on the machine. Set this environment
+ # variable to something smaller to fail faster in, say,
+ # an automated test setup. If the p4d process dies, that
+ # will be caught with the "kill -0" check below.
+ i=${P4D_START_PATIENCE:-300}
+ pid=$(cat "$pidfile")
+ ready=
+ while test $i -gt 0
+ do
+ # succeed when p4 client commands start to work
+ if p4 info >/dev/null 2>&1
+ then
+ ready=true
+ break
+ fi
+ # fail if p4d died
+ kill -0 $pid 2>/dev/null || break
+ echo waiting for p4d to start
sleep 1
- done &&
- # complain if it never started
- p4 info >/dev/null &&
+ i=$(( $i - 1 ))
+ done
+
+ if test -z "$ready"
+ then
+ # p4d failed to start
+ return 1
+ fi
+
+ # build a client
(
cd "$cli" &&
p4 client -i <<-EOF
View: //depot/... //client/...
EOF
)
+ return 0
}
kill_p4d() {
}
cleanup_git() {
- rm -rf "$git"
+ rm -rf "$git" &&
+ mkdir "$git"
+}
+
+marshal_dump() {
+ what=$1 &&
+ line=${2:-1} &&
+ cat >"$TRASH_DIRECTORY/marshal-dump.py" <<-EOF &&
+ import marshal
+ import sys
+ for i in range($line):
+ d = marshal.load(sys.stdin)
+ print d['$what']
+ EOF
+ "$PYTHON_PATH" "$TRASH_DIRECTORY/marshal-dump.py"
}
host=example.com
path=foo.git
--
+ protocol=ftp
+ host=example.com
+ path=foo.git
username=one
password=two
--
host=example.com
path=repo.git
--
+ protocol=https
+ host=example.com
username=foo
password=bar
--
protocol=https
host=bar
--
+ protocol=https
+ host=bar
username=askpass-username
password=askpass-password
--
protocol=https
host=example.com
--
+ protocol=https
+ host=example.com
username=foo
password=askpass-password
--
host=example.com
path=foo.git
--
+ protocol=https
+ host=example.com
username=foo
password=bar
--
host=example.com
path=foo.git
--
+ protocol=https
+ host=example.com
+ path=foo.git
username=foo
password=bar
--
'
test_expect_success 'ls-tree output in wrong order given to mktree (1)' '
- perl -e "print reverse <>" <top |
+ "$PERL_PATH" -e "print reverse <>" <top |
git mktree >actual &&
test_cmp tree actual
'
test_expect_success 'ls-tree output in wrong order given to mktree (2)' '
- perl -e "print reverse <>" <top.withsub |
+ "$PERL_PATH" -e "print reverse <>" <top.withsub |
git mktree >actual &&
test_cmp tree.withsub actual
'
'
+test_expect_success 'index-pack' '
+ git clone file://"`pwd`"/.git foo &&
+ GIT_DIR=non-existent git index-pack --strict --verify foo/.git/objects/pack/*.pack
+'
+
test_expect_success 'repack' '
git repack -ad
'
+test_expect_success 'pack-objects with large loose object' '
+ SHA1=`git hash-object huge` &&
+ test_create_repo loose &&
+ echo $SHA1 | git pack-objects --stdout |
+ GIT_ALLOC_LIMIT=0 GIT_DIR=loose/.git git unpack-objects &&
+ echo $SHA1 | GIT_DIR=loose/.git git pack-objects pack &&
+ test_create_repo packed &&
+ mv pack-* packed/.git/objects/pack &&
+ GIT_DIR=packed/.git git cat-file blob $SHA1 >actual &&
+ cmp huge actual
+'
+
test_expect_success 'tar achiving' '
git archive --format=tar HEAD >/dev/null
'
# We need an arbitrary other user give permission to using ACLs. root
# is a good candidate: exists on all unices, and it has permission
# anyway, so we don't create a security hole running the testsuite.
-
-setfacl_out="$(setfacl -m u:root:rwx . 2>&1)"
-setfacl_ret=$?
-
-if test $setfacl_ret != 0
-then
- say "Unable to use setfacl (output: '$setfacl_out'; return code: '$setfacl_ret')"
-else
- test_set_prereq SETFACL
-fi
+test_expect_success 'checking for a working acl setup' '
+ if setfacl -m d:m:rwx -m u:root:rwx . &&
+ getfacl . | grep user:root:rwx &&
+ touch should-have-readable-acl &&
+ getfacl should-have-readable-acl | egrep "mask::?rw-"
+ then
+ test_set_prereq SETFACL
+ fi
+'
if test -z "$LOGNAME"
then
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas,
+# Thomas Nguy, Khoi Nguyen
+# Grenoble INP Ensimag
+#
+
+test_description='Compatibility with $XDG_CONFIG_HOME/git/ files'
+
+. ./test-lib.sh
+
+test_expect_success 'read config: xdg file exists and ~/.gitconfig doesn'\''t' '
+ mkdir -p .config/git &&
+ echo "[alias]" >.config/git/config &&
+ echo " myalias = !echo in_config" >>.config/git/config &&
+ echo in_config >expected &&
+ git myalias >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'read config: xdg file exists and ~/.gitconfig exists' '
+ >.gitconfig &&
+ echo "[alias]" >.gitconfig &&
+ echo " myalias = !echo in_gitconfig" >>.gitconfig &&
+ echo in_gitconfig >expected &&
+ git myalias >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'read with --get: xdg file exists and ~/.gitconfig doesn'\''t' '
+ rm .gitconfig &&
+ echo "[user]" >.config/git/config &&
+ echo " name = read_config" >>.config/git/config &&
+ echo read_config >expected &&
+ git config --get user.name >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'read with --get: xdg file exists and ~/.gitconfig exists' '
+ >.gitconfig &&
+ echo "[user]" >.gitconfig &&
+ echo " name = read_gitconfig" >>.gitconfig &&
+ echo read_gitconfig >expected &&
+ git config --get user.name >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'read with --list: xdg file exists and ~/.gitconfig doesn'\''t' '
+ rm .gitconfig &&
+ echo user.name=read_config >expected &&
+ git config --global --list >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'read with --list: xdg file exists and ~/.gitconfig exists' '
+ >.gitconfig &&
+ echo "[user]" >.gitconfig &&
+ echo " name = read_gitconfig" >>.gitconfig &&
+ echo user.name=read_gitconfig >expected &&
+ git config --global --list >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'Setup' '
+ git init git &&
+ cd git &&
+ echo foo >to_be_excluded
+'
+
+
+test_expect_success 'Exclusion of a file in the XDG ignore file' '
+ mkdir -p "$HOME"/.config/git/ &&
+ echo to_be_excluded >"$HOME"/.config/git/ignore &&
+ test_must_fail git add to_be_excluded
+'
+
+
+test_expect_success 'Exclusion in both XDG and local ignore files' '
+ echo to_be_excluded >.gitignore &&
+ test_must_fail git add to_be_excluded
+'
+
+
+test_expect_success 'Exclusion in a non-XDG global ignore file' '
+ rm .gitignore &&
+ echo >"$HOME"/.config/git/ignore &&
+ echo to_be_excluded >"$HOME"/my_gitignore &&
+ git config core.excludesfile "$HOME"/my_gitignore &&
+ test_must_fail git add to_be_excluded
+'
+
+
+test_expect_success 'Checking attributes in the XDG attributes file' '
+ echo foo >f &&
+ git check-attr -a f >actual &&
+ test_line_count -eq 0 actual &&
+ echo "f attr_f" >"$HOME"/.config/git/attributes &&
+ echo "f: attr_f: set" >expected &&
+ git check-attr -a f >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'Checking attributes in both XDG and local attributes files' '
+ echo "f -attr_f" >.gitattributes &&
+ echo "f: attr_f: unset" >expected &&
+ git check-attr -a f >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'Checking attributes in a non-XDG global attributes file' '
+ test_might_fail rm .gitattributes &&
+ echo "f attr_f=test" >"$HOME"/my_gitattributes &&
+ git config core.attributesfile "$HOME"/my_gitattributes &&
+ echo "f: attr_f: test" >expected &&
+ git check-attr -a f >actual &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'write: xdg file exists and ~/.gitconfig doesn'\''t' '
+ mkdir -p "$HOME"/.config/git &&
+ >"$HOME"/.config/git/config &&
+ test_might_fail rm "$HOME"/.gitconfig &&
+ git config --global user.name "write_config" &&
+ echo "[user]" >expected &&
+ echo " name = write_config" >>expected &&
+ test_cmp expected "$HOME"/.config/git/config
+'
+
+
+test_expect_success 'write: xdg file exists and ~/.gitconfig exists' '
+ >"$HOME"/.gitconfig &&
+ git config --global user.name "write_gitconfig" &&
+ echo "[user]" >expected &&
+ echo " name = write_gitconfig" >>expected &&
+ test_cmp expected "$HOME"/.gitconfig
+'
+
+
+test_expect_success 'write: ~/.config/git/ exists and config file doesn'\''t' '
+ test_might_fail rm "$HOME"/.gitconfig &&
+ test_might_fail rm "$HOME"/.config/git/config &&
+ git config --global user.name "write_gitconfig" &&
+ echo "[user]" >expected &&
+ echo " name = write_gitconfig" >>expected &&
+ test_cmp expected "$HOME"/.gitconfig
+'
+
+
+test_done
grep "BUG: startup_info struct is not initialized." error
'
+test_expect_success '<commit>:file correctly diagnosed after a pathname' '
+ test_must_fail git rev-parse file.txt HEAD:file.txt 1>actual 2>error &&
+ test_i18ngrep ! "exists on disk" error &&
+ test_i18ngrep "no such path in the working tree" error &&
+ cat >expect <<-\EOF &&
+ file.txt
+ HEAD:file.txt
+ EOF
+ test_cmp expect actual
+'
+
test_done
--- /dev/null
+#!/bin/sh
+
+test_description='object name disambiguation
+
+Create blobs, trees, commits and a tag that all share the same
+prefix, and make sure "git rev-parse" can take advantage of
+type information to disambiguate short object names that are
+not necessarily unique.
+
+The final history used in the test has five commits, with the bottom
+one tagged as v1.0.0. They all have one regular file each.
+
+ +-------------------------------------------+
+ | |
+ | .-------b3wettvi---- ad2uee |
+ | / / |
+ | a2onsxbvj---czy8f73t--ioiley5o |
+ | |
+ +-------------------------------------------+
+
+'
+
+. ./test-lib.sh
+
+test_expect_success 'blob and tree' '
+ test_tick &&
+ (
+ for i in 0 1 2 3 4 5 6 7 8 9
+ do
+ echo $i
+ done
+ echo
+ echo b1rwzyc3
+ ) >a0blgqsjc &&
+
+ # create one blob 0000000000b36
+ git add a0blgqsjc &&
+
+ # create one tree 0000000000cdc
+ git write-tree
+'
+
+test_expect_success 'warn ambiguity when no candidate matches type hint' '
+ test_must_fail git rev-parse --verify 000000000^{commit} 2>actual &&
+ grep "short SHA1 000000000 is ambiguous" actual
+'
+
+test_expect_success 'disambiguate tree-ish' '
+ # feed tree-ish in an unambiguous way
+ git rev-parse --verify 0000000000cdc:a0blgqsjc &&
+
+ # ambiguous at the object name level, but there is only one
+ # such tree-ish (the other is a blob)
+ git rev-parse --verify 000000000:a0blgqsjc
+'
+
+test_expect_success 'disambiguate blob' '
+ sed -e "s/|$//" >patch <<-EOF &&
+ diff --git a/frotz b/frotz
+ index 000000000..ffffff 100644
+ --- a/frotz
+ +++ b/frotz
+ @@ -10,3 +10,4 @@
+ 9
+ |
+ b1rwzyc3
+ +irwry
+ EOF
+ (
+ GIT_INDEX_FILE=frotz &&
+ export GIT_INDEX_FILE &&
+ git apply --build-fake-ancestor frotz patch &&
+ git cat-file blob :frotz >actual
+ ) &&
+ test_cmp a0blgqsjc actual
+'
+
+test_expect_success 'disambiguate tree' '
+ commit=$(echo "d7xm" | git commit-tree 000000000) &&
+ test $(git rev-parse $commit^{tree}) = $(git rev-parse 0000000000cdc)
+'
+
+test_expect_success 'first commit' '
+ # create one commit 0000000000e4f
+ git commit -m a2onsxbvj
+'
+
+test_expect_success 'disambiguate commit-ish' '
+ # feed commit-ish in an unambiguous way
+ git rev-parse --verify 0000000000e4f^{commit} &&
+
+ # ambiguous at the object name level, but there is only one
+ # such commit (the others are tree and blob)
+ git rev-parse --verify 000000000^{commit} &&
+
+ # likewise
+ git rev-parse --verify 000000000^0
+'
+
+test_expect_success 'disambiguate commit' '
+ commit=$(echo "hoaxj" | git commit-tree 0000000000cdc -p 000000000) &&
+ test $(git rev-parse $commit^) = $(git rev-parse 0000000000e4f)
+'
+
+test_expect_success 'log name1..name2 takes only commit-ishes on both ends' '
+ git log 000000000..000000000 &&
+ git log ..000000000 &&
+ git log 000000000.. &&
+ git log 000000000...000000000 &&
+ git log ...000000000 &&
+ git log 000000000...
+'
+
+test_expect_success 'rev-parse name1..name2 takes only commit-ishes on both ends' '
+ git rev-parse 000000000..000000000 &&
+ git rev-parse ..000000000 &&
+ git rev-parse 000000000..
+'
+
+test_expect_success 'git log takes only commit-ish' '
+ git log 000000000
+'
+
+test_expect_success 'git reset takes only commit-ish' '
+ git reset 000000000
+'
+
+test_expect_success 'first tag' '
+ # create one tag 0000000000f8f
+ git tag -a -m j7cp83um v1.0.0
+'
+
+test_expect_failure 'two semi-ambiguous commit-ish' '
+ # Once the parser becomes ultra-smart, it could notice that
+ # 110282 before ^{commit} name many different objects, but
+ # that only two (HEAD and v1.0.0 tag) can be peeled to commit,
+ # and that peeling them down to commit yield the same commit
+ # without ambiguity.
+ git rev-parse --verify 110282^{commit} &&
+
+ # likewise
+ git log 000000000..000000000 &&
+ git log ..000000000 &&
+ git log 000000000.. &&
+ git log 000000000...000000000 &&
+ git log ...000000000 &&
+ git log 000000000...
+'
+
+test_expect_failure 'three semi-ambiguous tree-ish' '
+ # Likewise for tree-ish. HEAD, v1.0.0 and HEAD^{tree} share
+ # the prefix but peeling them to tree yields the same thing
+ git rev-parse --verify 000000000^{tree}
+'
+
+test_expect_success 'parse describe name' '
+ # feed an unambiguous describe name
+ git rev-parse --verify v1.0.0-0-g0000000000e4f &&
+
+ # ambiguous at the object name level, but there is only one
+ # such commit (others are blob, tree and tag)
+ git rev-parse --verify v1.0.0-0-g000000000
+'
+
+test_expect_success 'more history' '
+ # commit 0000000000043
+ git mv a0blgqsjc d12cr3h8t &&
+ echo h62xsjeu >>d12cr3h8t &&
+ git add d12cr3h8t &&
+
+ test_tick &&
+ git commit -m czy8f73t &&
+
+ # commit 00000000008ec
+ git mv d12cr3h8t j000jmpzn &&
+ echo j08bekfvt >>j000jmpzn &&
+ git add j000jmpzn &&
+
+ test_tick &&
+ git commit -m ioiley5o &&
+
+ # commit 0000000005b0
+ git checkout v1.0.0^0 &&
+ git mv a0blgqsjc f5518nwu &&
+
+ for i in h62xsjeu j08bekfvt kg7xflhm
+ do
+ echo $i
+ done >>f5518nwu &&
+ git add f5518nwu &&
+
+ test_tick &&
+ git commit -m b3wettvi &&
+ side=$(git rev-parse HEAD) &&
+
+ # commit 000000000066
+ git checkout master &&
+
+ # If you use recursive, merge will fail and you will need to
+ # clean up a0blgqsjc as well. If you use resolve, merge will
+ # succeed.
+ test_might_fail git merge --no-commit -s recursive $side &&
+ git rm -f f5518nwu j000jmpzn &&
+
+ test_might_fail git rm -f a0blgqsjc &&
+ (
+ git cat-file blob $side:f5518nwu
+ echo j3l0i9s6
+ ) >ab2gs879 &&
+ git add ab2gs879 &&
+
+ test_tick &&
+ git commit -m ad2uee
+
+'
+
+test_expect_failure 'parse describe name taking advantage of generation' '
+ # ambiguous at the object name level, but there is only one
+ # such commit at generation 0
+ git rev-parse --verify v1.0.0-0-g000000000 &&
+
+ # likewise for generation 2 and 4
+ git rev-parse --verify v1.0.0-2-g000000000 &&
+ git rev-parse --verify v1.0.0-4-g000000000
+'
+
+# Note: because rev-parse does not even try to disambiguate based on
+# the generation number, this test currently succeeds for a wrong
+# reason. When it learns to use the generation number, the previous
+# test should succeed, and also this test should fail because the
+# describe name used in the test with generation number can name two
+# commits. Make sure that such a future enhancement does not randomly
+# pick one.
+test_expect_success 'parse describe name not ignoring ambiguity' '
+ # ambiguous at the object name level, and there are two such
+ # commits at generation 1
+ test_must_fail git rev-parse --verify v1.0.0-1-g000000000
+'
+
+test_expect_success 'ambiguous commit-ish' '
+ # Now there are many commits that begin with the
+ # common prefix, none of these should pick one at
+ # random. They all should result in ambiguity errors.
+ test_must_fail git rev-parse --verify 110282^{commit} &&
+
+ # likewise
+ test_must_fail git log 000000000..000000000 &&
+ test_must_fail git log ..000000000 &&
+ test_must_fail git log 000000000.. &&
+ test_must_fail git log 000000000...000000000 &&
+ test_must_fail git log ...000000000 &&
+ test_must_fail git log 000000000...
+'
+
+test_expect_success 'rev-parse --disambiguate' '
+ # The test creates 16 objects that share the prefix and two
+ # commits created by commit-tree in earlier tests share a
+ # different prefix.
+ git rev-parse --disambiguate=000000000 >actual &&
+ test $(wc -l <actual) = 16 &&
+ test "$(sed -e "s/^\(.........\).*/\1/" actual | sort -u)" = 000000000
+'
+
+test_done
git reset --hard
'
+test_expect_success 'cannot --detach on an unborn branch' '
+ git checkout master &&
+ git checkout --orphan new &&
+ test_must_fail git checkout --detach
+'
+
test_done
--- /dev/null
+#!/bin/sh
+
+test_description='overly long paths'
+. ./test-lib.sh
+
+test_expect_success setup '
+ p=filefilefilefilefilefilefilefile &&
+ p=$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p &&
+ p=$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p &&
+
+ path_a=${p}_a &&
+ path_z=${p}_z &&
+
+ blob_a=$(echo frotz | git hash-object -w --stdin) &&
+ blob_z=$(echo nitfol | git hash-object -w --stdin) &&
+
+ pat="100644 %s 0\t%s\n"
+'
+
+test_expect_success 'overly-long path by itself is not a problem' '
+ printf "$pat" "$blob_a" "$path_a" |
+ git update-index --add --index-info &&
+ echo "$path_a" >expect &&
+ git ls-files >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'overly-long path does not replace another by mistake' '
+ printf "$pat" "$blob_a" "$path_a" "$blob_z" "$path_z" |
+ git update-index --add --index-info &&
+ (
+ echo "$path_a"
+ echo "$path_z"
+ ) >expect &&
+ git ls-files >actual &&
+ test_cmp expect actual
+'
+
+test_done
tabs ," (dq) and spaces
EOF
git ls-files -z >ls-files.z &&
- perl -pe "y/\000/\012/" <ls-files.z >current &&
+ "$PERL_PATH" -pe "y/\000/\012/" <ls-files.z >current &&
test_cmp expected current
'
tabs ," (dq) and spaces
EOF
git diff-index -z --name-status $t0 >diff-index.z &&
- perl -pe "y/\000/\012/" <diff-index.z >current &&
+ "$PERL_PATH" -pe "y/\000/\012/" <diff-index.z >current &&
test_cmp expected current
'
tabs ," (dq) and spaces
EOF
git diff-tree -z --name-status $t0 $t1 >diff-tree.z &&
- perl -pe y/\\000/\\012/ <diff-tree.z >current &&
+ "$PERL_PATH" -pe y/\\000/\\012/ <diff-tree.z >current &&
test_cmp expected current
'
test_path_is_missing .git/rebase-merge
'
+test_expect_success 'rebase ignores empty commit' '
+ git reset --hard A &&
+ git commit --allow-empty -m empty &&
+ test_commit D &&
+ git rebase C &&
+ test $(git log --format=%s C..) = "D"
+'
+
test_done
test_cmp expect actual
'
+
+test_expect_success 'prepare for rebase -i --exec' '
+ git checkout master &&
+ git checkout -b execute &&
+ test_commit one_exec main.txt one_exec &&
+ test_commit two_exec main.txt two_exec &&
+ test_commit three_exec main.txt three_exec
+'
+
+
+test_expect_success 'running "git rebase -i --exec git show HEAD"' '
+ git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
+ (
+ FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~2 >expect
+ ) &&
+ sed -e "1,9d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase --exec git show HEAD -i"' '
+ git reset --hard execute &&
+ git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
+ (
+ FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~2 >expect
+ ) &&
+ sed -e "1,9d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'running "git rebase -ix git show HEAD"' '
+ git reset --hard execute &&
+ git rebase -ix "git show HEAD" HEAD~2 >actual &&
+ (
+ FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~2 >expect
+ ) &&
+ sed -e "1,9d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several <CMD>' '
+ git reset --hard execute &&
+ git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
+ (
+ FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~2 >expect
+ ) &&
+ sed -e "1,9d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with several instances of --exec' '
+ git reset --hard execute &&
+ git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
+ (
+ FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2
+ exec_git_show_HEAD exec_pwd" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~2 >expect
+ ) &&
+ sed -e "1,11d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'rebase -ix with --autosquash' '
+ git reset --hard execute &&
+ git checkout -b autosquash &&
+ echo second >second.txt &&
+ git add second.txt &&
+ git commit -m "fixup! two_exec" &&
+ echo bis >bis.txt &&
+ git add bis.txt &&
+ git commit -m "fixup! two_exec" &&
+ (
+ git checkout -b autosquash_actual &&
+ git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual
+ ) &&
+ git checkout autosquash &&
+ (
+ git checkout -b autosquash_expected &&
+ FAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
+ export FAKE_LINES &&
+ git rebase -i HEAD~4 >expect
+ ) &&
+ sed -e "1,13d" expect >expected &&
+ test_cmp expected actual
+'
+
+
+test_expect_success 'rebase --exec without -i shows error message' '
+ git reset --hard execute &&
+ test_must_fail git rebase --exec "git show HEAD" HEAD~2 2>actual &&
+ echo "--exec option must be used with --interactive option" >expected &&
+ test_i18ncmp expected actual
+'
+
+
+test_expect_success 'rebase -i --exec without <CMD>' '
+ git reset --hard execute &&
+ test_must_fail git rebase -i --exec 2>tmp &&
+ sed -e "1d" tmp >actual &&
+ test_must_fail git rebase -h >expected &&
+ test_cmp expected actual &&
+ git checkout master
+'
+
+test_expect_success 'rebase -i --root re-order and drop commits' '
+ git checkout E &&
+ FAKE_LINES="3 1 2 5" git rebase -i --root &&
+ test E = $(git cat-file commit HEAD | sed -ne \$p) &&
+ test B = $(git cat-file commit HEAD^ | sed -ne \$p) &&
+ test A = $(git cat-file commit HEAD^^ | sed -ne \$p) &&
+ test C = $(git cat-file commit HEAD^^^ | sed -ne \$p) &&
+ test 0 = $(git cat-file commit HEAD^^^ | grep -c ^parent\ )
+'
+
+test_expect_success 'rebase -i --root retain root commit author and message' '
+ git checkout A &&
+ echo B >file7 &&
+ git add file7 &&
+ GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&
+ FAKE_LINES="2" git rebase -i --root &&
+ git cat-file commit HEAD | grep -q "^author Twerp Snog" &&
+ git cat-file commit HEAD | grep -q "^different author$"
+'
+
+test_expect_success 'rebase -i --root temporary sentinel commit' '
+ git checkout B &&
+ (
+ FAKE_LINES="2" &&
+ export FAKE_LINES &&
+ test_must_fail git rebase -i --root
+ ) &&
+ git cat-file commit HEAD | grep "^tree 4b825dc642cb" &&
+ git rebase --abort
+'
+
test_done
#!/bin/sh
-test_description='rebase should not insist on git message convention'
+test_description='rebase should handle arbitrary git message'
. ./test-lib.sh
to oneline summary format.
EOF
+cat >G <<\EOF
+commit log message containing a diff
+EOF
+
+
test_expect_success setup '
>file1 &&
git add file1 file2 &&
test_tick &&
git commit -m "Initial commit" &&
+ git branch diff-in-message
- git checkout -b side &&
+ git checkout -b multi-line-subject &&
cat F >file2 &&
git add file2 &&
test_tick &&
git cat-file commit HEAD | sed -e "1,/^\$/d" >F0 &&
+ git checkout diff-in-message &&
+ echo "commit log message containing a diff" >G &&
+ echo "" >>G
+ cat G >file2 &&
+ git add file2 &&
+ git diff --cached >>G &&
+ test_tick &&
+ git commit -F G &&
+
+ git cat-file commit HEAD | sed -e "1,/^\$/d" >G0 &&
+
git checkout master &&
echo One >file1 &&
git commit -m "Second commit"
'
-test_expect_success rebase '
+test_expect_success 'rebase commit with multi-line subject' '
- git rebase master side &&
+ git rebase master multi-line-subject &&
git cat-file commit HEAD | sed -e "1,/^\$/d" >F1 &&
test_cmp F0 F1 &&
test_cmp F F0
'
+test_expect_success 'rebase commit with diff in message' '
+ git rebase master diff-in-message &&
+ git cat-file commit HEAD | sed -e "1,/^$/d" >G1 &&
+ test_cmp G0 G1 &&
+ test_cmp G G0
+'
+
test_done
test_commit 4 B
'
-test_expect_success 'rebase --root expects --onto' '
- test_must_fail git rebase --root
+test_expect_success 'rebase --root fails with too many args' '
+ git checkout -B fail other &&
+ test_must_fail git rebase --onto master --root fail fail
'
test_expect_success 'setup pre-rebase hook' '
EOF
test_expect_success 'rebase --root --onto <newbase>' '
- git checkout -b work &&
+ git checkout -b work other &&
git rebase --root --onto master &&
git log --pretty=tformat:"%s" > rebased &&
test_cmp expect rebased
}
test_expect_success setup '
- git config advice.detachedhead false
+ git config advice.detachedhead false &&
echo unrelated >unrelated &&
git add unrelated &&
test_commit initial foo a &&
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2012 Torsten Bögershausen
+#
+
+test_description='utf-8 decomposed (nfd) converted to precomposed (nfc)'
+
+. ./test-lib.sh
+
+Adiarnfc=`printf '\303\204'`
+Adiarnfd=`printf 'A\314\210'`
+
+# check if the feature is compiled in
+mkdir junk &&
+>junk/"$Adiarnfc" &&
+case "$(cd junk && echo *)" in
+ "$Adiarnfd")
+ test_nfd=1
+ ;;
+ *) ;;
+esac
+rm -rf junk
+
+
+if test "$test_nfd"
+then
+ # create more utf-8 variables
+ Odiarnfc=`printf '\303\226'`
+ Odiarnfd=`printf 'O\314\210'`
+ AEligatu=`printf '\303\206'`
+ Invalidu=`printf '\303\377'`
+
+
+ #Create a string with 255 bytes (decomposed)
+ Alongd=$Adiarnfd$Adiarnfd$Adiarnfd$Adiarnfd$Adiarnfd$Adiarnfd$Adiarnfd #21 Byte
+ Alongd=$Alongd$Alongd$Alongd #63 Byte
+ Alongd=$Alongd$Alongd$Alongd$Alongd$Adiarnfd #255 Byte
+
+ #Create a string with 254 bytes (precomposed)
+ Alongc=$AEligatu$AEligatu$AEligatu$AEligatu$AEligatu #10 Byte
+ Alongc=$Alongc$Alongc$Alongc$Alongc$Alongc #50 Byte
+ Alongc=$Alongc$Alongc$Alongc$Alongc$Alongc #250 Byte
+ Alongc=$Alongc$AEligatu$AEligatu #254 Byte
+
+ test_expect_success "detect if nfd needed" '
+ precomposeunicode=`git config core.precomposeunicode` &&
+ test "$precomposeunicode" = false &&
+ git config core.precomposeunicode true
+ '
+ test_expect_success "setup" '
+ >x &&
+ git add x &&
+ git commit -m "1st commit" &&
+ git rm x &&
+ git commit -m "rm x"
+ '
+ test_expect_success "setup case mac" '
+ git checkout -b mac_os
+ '
+ # This will test nfd2nfc in readdir()
+ test_expect_success "add file Adiarnfc" '
+ echo f.Adiarnfc >f.$Adiarnfc &&
+ git add f.$Adiarnfc &&
+ git commit -m "add f.$Adiarnfc"
+ '
+ # This will test nfd2nfc in git stage()
+ test_expect_success "stage file d.Adiarnfd/f.Adiarnfd" '
+ mkdir d.$Adiarnfd &&
+ echo d.$Adiarnfd/f.$Adiarnfd >d.$Adiarnfd/f.$Adiarnfd &&
+ git stage d.$Adiarnfd/f.$Adiarnfd &&
+ git commit -m "add d.$Adiarnfd/f.$Adiarnfd"
+ '
+ test_expect_success "add link Adiarnfc" '
+ ln -s d.$Adiarnfd/f.$Adiarnfd l.$Adiarnfc &&
+ git add l.$Adiarnfc &&
+ git commit -m "add l.Adiarnfc"
+ '
+ # This will test git log
+ test_expect_success "git log f.Adiar" '
+ git log f.$Adiarnfc > f.Adiarnfc.log &&
+ git log f.$Adiarnfd > f.Adiarnfd.log &&
+ test -s f.Adiarnfc.log &&
+ test -s f.Adiarnfd.log &&
+ test_cmp f.Adiarnfc.log f.Adiarnfd.log &&
+ rm f.Adiarnfc.log f.Adiarnfd.log
+ '
+ # This will test git ls-files
+ test_expect_success "git lsfiles f.Adiar" '
+ git ls-files f.$Adiarnfc > f.Adiarnfc.log &&
+ git ls-files f.$Adiarnfd > f.Adiarnfd.log &&
+ test -s f.Adiarnfc.log &&
+ test -s f.Adiarnfd.log &&
+ test_cmp f.Adiarnfc.log f.Adiarnfd.log &&
+ rm f.Adiarnfc.log f.Adiarnfd.log
+ '
+ # This will test git mv
+ test_expect_success "git mv" '
+ git mv f.$Adiarnfd f.$Odiarnfc &&
+ git mv d.$Adiarnfd d.$Odiarnfc &&
+ git mv l.$Adiarnfd l.$Odiarnfc &&
+ git commit -m "mv Adiarnfd Odiarnfc"
+ '
+ # Files can be checked out as nfc
+ # And the link has been corrected from nfd to nfc
+ test_expect_success "git checkout nfc" '
+ rm f.$Odiarnfc &&
+ git checkout f.$Odiarnfc
+ '
+ # Make it possible to checkout files with their NFD names
+ test_expect_success "git checkout file nfd" '
+ rm -f f.* &&
+ git checkout f.$Odiarnfd
+ '
+ # Make it possible to checkout links with their NFD names
+ test_expect_success "git checkout link nfd" '
+ rm l.* &&
+ git checkout l.$Odiarnfd
+ '
+ test_expect_success "setup case mac2" '
+ git checkout master &&
+ git reset --hard &&
+ git checkout -b mac_os_2
+ '
+ # This will test nfd2nfc in git commit
+ test_expect_success "commit file d2.Adiarnfd/f.Adiarnfd" '
+ mkdir d2.$Adiarnfd &&
+ echo d2.$Adiarnfd/f.$Adiarnfd >d2.$Adiarnfd/f.$Adiarnfd &&
+ git add d2.$Adiarnfd/f.$Adiarnfd &&
+ git commit -m "add d2.$Adiarnfd/f.$Adiarnfd" -- d2.$Adiarnfd/f.$Adiarnfd
+ '
+ test_expect_success "setup for long decomposed filename" '
+ git checkout master &&
+ git reset --hard &&
+ git checkout -b mac_os_long_nfd_fn
+ '
+ test_expect_success "Add long decomposed filename" '
+ echo longd >$Alongd &&
+ git add * &&
+ git commit -m "Long filename"
+ '
+ test_expect_success "setup for long precomposed filename" '
+ git checkout master &&
+ git reset --hard &&
+ git checkout -b mac_os_long_nfc_fn
+ '
+ test_expect_success "Add long precomposed filename" '
+ echo longc >$Alongc &&
+ git add * &&
+ git commit -m "Long filename"
+ '
+ # Test if the global core.precomposeunicode stops autosensing
+ # Must be the last test case
+ test_expect_success "respect git config --global core.precomposeunicode" '
+ git config --global core.precomposeunicode true &&
+ rm -rf .git &&
+ git init &&
+ precomposeunicode=`git config core.precomposeunicode` &&
+ test "$precomposeunicode" = "true"
+ '
+else
+ say "Skipping nfc/nfd tests"
+fi
+
+test_done
test_i18ncmp expected current
'
+test_expect_success 'diff --shortstat output for binary file change' '
+ echo " 4 files changed, 2 insertions(+), 2 deletions(-)" >expected &&
+ git diff --shortstat >current &&
+ test_i18ncmp expected current
+'
+
+test_expect_success 'diff --shortstat output for binary file change only' '
+ echo " 1 file changed, 0 insertions(+), 0 deletions(-)" >expected &&
+ git diff --shortstat -- b >current &&
+ test_i18ncmp expected current
+'
+
test_expect_success 'apply --numstat notices binary file change' '
git diff >diff &&
git apply --numstat <diff >current &&
(git format-patch --stdout "$@"; echo $? > status.out) |
# Prints everything between the Message-ID and In-Reply-To,
# and replaces all Message-ID-lookalikes by a sequence number
- perl -ne '
+ "$PERL_PATH" -ne '
if (/^(message-id|references|in-reply-to)/i) {
$printing = 1;
} elsif (/^\S/) {
git diff | grep Binary
'
-echo NULZbetweenZwords | perl -pe 'y/Z/\000/' > file
+echo NULZbetweenZwords | "$PERL_PATH" -pe 'y/Z/\000/' > file
test_expect_success 'force diff with "diff"' '
echo >.gitattributes "file diff" &&
git config --bool diff.suppressBlankEmpty true &&
git diff f > actual &&
test_cmp exp actual &&
- perl -i.bak -p -e "s/^\$/ /" exp &&
+ "$PERL_PATH" -i.bak -p -e "s/^\$/ /" exp &&
git config --bool diff.suppressBlankEmpty false &&
git diff f > actual &&
test_cmp exp actual &&
cat >hexdump <<'EOF'
#!/bin/sh
-perl -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1"
+"$PERL_PATH" -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1"
EOF
chmod +x hexdump
{
echo "#!$SHELL_PATH"
cat <<'EOF'
-perl -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1"
+"$PERL_PATH" -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1"
EOF
} >dump
chmod +x dump
git commit -m first &&
echo 2 >b &&
git add . &&
- git commit -a -m second
+ git commit -a -m second &&
+ mkdir -p test-outside/repo && (
+ cd test-outside/repo &&
+ git init &&
+ echo "1 1" >a &&
+ git add . &&
+ git commit -m 1
+ ) &&
+ mkdir -p test-outside/non/git && (
+ cd test-outside/non/git &&
+ echo "1 1" >a &&
+ echo "1 1" >matching-file &&
+ echo "1 1 " >trailing-space &&
+ echo "1 1" >extra-space &&
+ echo "2" >never-match
+ )
'
test_expect_success 'git diff-tree HEAD^ HEAD' '
}
'
+test_expect_success 'git diff, one file outside repo' '
+ (
+ cd test-outside/repo &&
+ test_expect_code 0 git diff --quiet a ../non/git/matching-file &&
+ test_expect_code 1 git diff --quiet a ../non/git/extra-space
+ )
+'
+
+test_expect_success 'git diff, both files outside repo' '
+ (
+ GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/test-outside" &&
+ export GIT_CEILING_DIRECTORIES &&
+ cd test-outside/non/git &&
+ test_expect_code 0 git diff --quiet a matching-file &&
+ test_expect_code 1 git diff --quiet a extra-space
+ )
+'
+
+test_expect_success 'git diff --ignore-space-at-eol, one file outside repo' '
+ (
+ cd test-outside/repo &&
+ test_expect_code 0 git diff --quiet --ignore-space-at-eol a ../non/git/trailing-space &&
+ test_expect_code 1 git diff --quiet --ignore-space-at-eol a ../non/git/extra-space
+ )
+'
+
+test_expect_success 'git diff --ignore-space-at-eol, both files outside repo' '
+ (
+ GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/test-outside" &&
+ export GIT_CEILING_DIRECTORIES &&
+ cd test-outside/non/git &&
+ test_expect_code 0 git diff --quiet --ignore-space-at-eol a trailing-space &&
+ test_expect_code 1 git diff --quiet --ignore-space-at-eol a extra-space
+ )
+'
+
+test_expect_success 'git diff --ignore-all-space, one file outside repo' '
+ (
+ cd test-outside/repo &&
+ test_expect_code 0 git diff --quiet --ignore-all-space a ../non/git/trailing-space &&
+ test_expect_code 0 git diff --quiet --ignore-all-space a ../non/git/extra-space &&
+ test_expect_code 1 git diff --quiet --ignore-all-space a ../non/git/never-match
+ )
+'
+
+test_expect_success 'git diff --ignore-all-space, both files outside repo' '
+ (
+ GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/test-outside" &&
+ export GIT_CEILING_DIRECTORIES &&
+ cd test-outside/non/git &&
+ test_expect_code 0 git diff --quiet --ignore-all-space a trailing-space &&
+ test_expect_code 0 git diff --quiet --ignore-all-space a extra-space &&
+ test_expect_code 1 git diff --quiet --ignore-all-space a never-match
+ )
+'
+
test_done
mkdir a &&
mkdir b &&
echo 1 >a/1 &&
- echo 2 >a/2
+ echo 2 >a/2 &&
+ git init repo &&
+ echo 1 >repo/a &&
+ mkdir -p non/git &&
+ echo 1 >non/git/a &&
+ echo 1 >non/git/b
'
test_expect_success 'git diff --no-index directories' '
test $? = 1 && test_line_count = 14 cnt
'
+test_expect_success 'git diff --no-index relative path outside repo' '
+ (
+ cd repo &&
+ test_expect_code 0 git diff --no-index a ../non/git/a &&
+ test_expect_code 0 git diff --no-index ../non/git/a ../non/git/b
+ )
+'
+
test_done
git commit -m 'Initial Version' 2>/dev/null &&
git checkout -b binary &&
- perl -pe 'y/x/\000/' <file1 >file3 &&
+ "$PERL_PATH" -pe 'y/x/\000/' <file1 >file3 &&
cat file3 >file4 &&
git add file2 &&
- perl -pe 'y/\000/v/' <file3 >file1 &&
+ "$PERL_PATH" -pe 'y/\000/v/' <file3 >file1 &&
rm -f file2 &&
git update-index --add --remove file1 file2 file3 file4 &&
git commit -m 'Second Version' &&
--- /dev/null
+#!/bin/sh
+
+test_description='git apply --3way'
+
+. ./test-lib.sh
+
+create_file () {
+ for i
+ do
+ echo "$i"
+ done
+}
+
+sanitize_conflicted_diff () {
+ sed -e '
+ /^index /d
+ s/^\(+[<>][<>][<>][<>]*\) .*/\1/
+ '
+}
+
+test_expect_success setup '
+ test_tick &&
+ create_file >one 1 2 3 4 5 6 7 &&
+ cat one >two &&
+ git add one two &&
+ git commit -m initial &&
+
+ git branch side &&
+
+ test_tick &&
+ create_file >one 1 two 3 4 5 six 7 &&
+ create_file >two 1 two 3 4 5 6 7 &&
+ git commit -a -m master &&
+
+ git checkout side &&
+ create_file >one 1 2 3 4 five 6 7 &&
+ create_file >two 1 2 3 4 five 6 7 &&
+ git commit -a -m side &&
+
+ git checkout master
+'
+
+test_expect_success 'apply without --3way' '
+ git diff side^ side >P.diff &&
+
+ # should fail to apply
+ git reset --hard &&
+ git checkout master^0 &&
+ test_must_fail git apply --index P.diff &&
+ # should leave things intact
+ git diff-files --exit-code &&
+ git diff-index --exit-code --cached HEAD
+'
+
+test_expect_success 'apply with --3way' '
+ # Merging side should be similar to applying this patch
+ git diff ...side >P.diff &&
+
+ # The corresponding conflicted merge
+ git reset --hard &&
+ git checkout master^0 &&
+ test_must_fail git merge --no-commit side &&
+ git ls-files -s >expect.ls &&
+ git diff HEAD | sanitize_conflicted_diff >expect.diff &&
+
+ # should fail to apply
+ git reset --hard &&
+ git checkout master^0 &&
+ test_must_fail git apply --index --3way P.diff &&
+ git ls-files -s >actual.ls &&
+ git diff HEAD | sanitize_conflicted_diff >actual.diff &&
+
+ # The result should resemble the corresponding merge
+ test_cmp expect.ls actual.ls &&
+ test_cmp expect.diff actual.diff
+'
+
+test_expect_success 'apply with --3way with rerere enabled' '
+ git config rerere.enabled true &&
+
+ # Merging side should be similar to applying this patch
+ git diff ...side >P.diff &&
+
+ # The corresponding conflicted merge
+ git reset --hard &&
+ git checkout master^0 &&
+ test_must_fail git merge --no-commit side &&
+
+ # Manually resolve and record the resolution
+ create_file 1 two 3 4 five six 7 >one &&
+ git rerere &&
+ cat one >expect &&
+
+ # should fail to apply
+ git reset --hard &&
+ git checkout master^0 &&
+ test_must_fail git apply --index --3way P.diff &&
+
+ # but rerere should have replayed the recorded resolution
+ test_cmp expect one
+'
+
+test_expect_success 'apply -3 with add/add conflict setup' '
+ git reset --hard &&
+
+ git checkout -b adder &&
+ create_file 1 2 3 4 5 6 7 >three &&
+ create_file 1 2 3 4 5 6 7 >four &&
+ git add three four &&
+ git commit -m "add three and four" &&
+
+ git checkout -b another adder^ &&
+ create_file 1 2 3 4 5 6 7 >three &&
+ create_file 1 2 3 four 5 6 7 >four &&
+ git add three four &&
+ git commit -m "add three and four" &&
+
+ # Merging another should be similar to applying this patch
+ git diff adder...another >P.diff &&
+
+ git checkout adder^0 &&
+ test_must_fail git merge --no-commit another &&
+ git ls-files -s >expect.ls &&
+ git diff HEAD | sanitize_conflicted_diff >expect.diff
+'
+
+test_expect_success 'apply -3 with add/add conflict' '
+ # should fail to apply ...
+ git reset --hard &&
+ git checkout adder^0 &&
+ test_must_fail git apply --index --3way P.diff &&
+ # ... and leave conflicts in the index and in the working tree
+ git ls-files -s >actual.ls &&
+ git diff HEAD | sanitize_conflicted_diff >actual.diff &&
+
+ # The result should resemble the corresponding merge
+ test_cmp expect.ls actual.ls &&
+ test_cmp expect.diff actual.diff
+'
+
+test_expect_success 'apply -3 with add/add conflict (dirty working tree)' '
+ # should fail to apply ...
+ git reset --hard &&
+ git checkout adder^0 &&
+ echo >>four &&
+ cat four >four.save &&
+ cat three >three.save &&
+ git ls-files -s >expect.ls &&
+ test_must_fail git apply --index --3way P.diff &&
+ # ... and should not touch anything
+ git ls-files -s >actual.ls &&
+ test_cmp expect.ls actual.ls &&
+ test_cmp four.save four &&
+ test_cmp three.save three
+'
+
+test_done
test_expect_success setup '
for i in a b c d e f g h i j k l m n; do echo $i; done >file1 &&
- perl -pe "y/ijk/\\000\\001\\002/" <file1 >file2 &&
+ "$PERL_PATH" -pe "y/ijk/\\000\\001\\002/" <file1 >file2 &&
git add file1 file2 &&
git commit -m initial &&
git tag initial &&
for i in a b c g h i J K L m o n p q; do echo $i; done >file1 &&
- perl -pe "y/mon/\\000\\001\\002/" <file1 >file2 &&
+ "$PERL_PATH" -pe "y/mon/\\000\\001\\002/" <file1 >file2 &&
git commit -a -m second &&
git tag second &&
cat file1 >saved.file1
'
+test_expect_success 'apply --reject is incompatible with --3way' '
+ test_when_finished "cat saved.file1 >file1" &&
+ git diff >patch.0 &&
+ git checkout file1 &&
+ test_must_fail git apply --reject --3way patch.0 &&
+ git diff --exit-code
+'
+
test_expect_success 'apply without --reject should fail' '
if git apply patch.1
test_might_fail git config --unset rerere.enabled &&
test_must_fail git merge first &&
- sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) &&
+ sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) &&
rr=.git/rr-cache/$sha1 &&
grep "^=======\$" $rr/preimage &&
! test -f $rr/postimage &&
git reset --hard &&
test_must_fail git merge first &&
- sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) &&
+ sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) &&
rr=.git/rr-cache/$sha1 &&
grep ^=======$ $rr/preimage
'
git config rerere.enabled true &&
git reset --hard &&
test_must_fail git merge first &&
- sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) &&
+ sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) &&
rr=.git/rr-cache/$sha1
'
test_expect_success 'rerere clear' '
rm $rr/postimage &&
- echo "$sha1 a1" | perl -pe "y/\012/\000/" >.git/MERGE_RR &&
+ echo "$sha1 a1" | "$PERL_PATH" -pe "y/\012/\000/" >.git/MERGE_RR &&
git rerere clear &&
! test -d $rr
'
git diff --exit-code master
'
-test_expect_success 'am with dos files config am.keepcr overriden by --no-keep-cr' '
+test_expect_success 'am with dos files config am.keepcr overridden by --no-keep-cr' '
git config am.keepcr 1 &&
git checkout -b dosfiles-conf-keepcr-override initial &&
git format-patch -k initial..master &&
git diff --exit-code master
'
-test_expect_success 'am with unix files config am.keepcr overriden by --no-keep-cr' '
+test_expect_success 'am with unix files config am.keepcr overridden by --no-keep-cr' '
git config am.keepcr 1 &&
git checkout -b unixfiles-conf-keepcr-override initial &&
cp -f file1 file &&
test_expect_success \
'setup' \
'rm -f .git/index* &&
- perl -e "print \"a\" x 4096;" > a &&
- perl -e "print \"b\" x 4096;" > b &&
- perl -e "print \"c\" x 4096;" > c &&
+ "$PERL_PATH" -e "print \"a\" x 4096;" > a &&
+ "$PERL_PATH" -e "print \"b\" x 4096;" > b &&
+ "$PERL_PATH" -e "print \"c\" x 4096;" > c &&
test-genrandom "seed a" 2097152 > a_big &&
test-genrandom "seed b" 2097152 > b_big &&
git update-index --add a a_big b b_big c &&
cd "$TRASH"
test_expect_success 'compare delta flavors' '
- perl -e '\''
+ "$PERL_PATH" -e '\''
defined($_ = -s $_) or die for @ARGV;
exit 1 if $ARGV[0] <= $ARGV[1];
'\'' test-2-$packname_2.pack test-3-$packname_3.pack
'test_must_fail git index-pack -o bad.idx test-3.pack 2>msg &&
grep "SHA1 COLLISION FOUND" msg'
+test_expect_success \
+ 'make sure index-pack detects the SHA1 collision (large blobs)' \
+ 'test_must_fail git -c core.bigfilethreshold=1 index-pack -o bad.idx test-3.pack 2>msg &&
+ grep "SHA1 COLLISION FOUND" msg'
+
test_done
'create_new_pack &&
git prune-packed &&
chmod +w ${pack}.pack &&
- perl -i.bak -pe "s/ base /abcdef/" ${pack}.pack &&
+ "$PERL_PATH" -i.bak -pe "s/ base /abcdef/" ${pack}.pack &&
test_must_fail git cat-file blob $blob_1 > /dev/null &&
test_must_fail git cat-file blob $blob_2 > /dev/null &&
test_must_fail git cat-file blob $blob_3 > /dev/null'
'create_new_pack &&
git prune-packed &&
chmod +w ${pack}.pack &&
- perl -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack &&
+ "$PERL_PATH" -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack &&
git cat-file blob $blob_1 > /dev/null &&
test_must_fail git cat-file blob $blob_2 > /dev/null &&
test_must_fail git cat-file blob $blob_3 > /dev/null'
test_cmp expected count.singlebranch
'
+test_expect_success 'single given branch clone' '
+ git clone --single-branch --branch A "file://$(pwd)/." branch-a &&
+ test_must_fail git --git-dir=branch-a/.git rev-parse origin/B
+'
+
test_expect_success 'clone shallow' '
git clone --no-single-branch --depth 2 "file://$(pwd)/." shallow
'
'
test_expect_success 'clone shallow object count' '
- echo "in-pack: 12" > count3.expected &&
+ echo "in-pack: 6" > count3.expected &&
GIT_DIR=shallow3/.git git count-objects -v |
grep "^in-pack" > count3.actual &&
test_cmp count3.expected count3.actual
test_expect_success 'confuses pattern as remote when no remote specified' '
cat >exp <<-\EOF &&
fatal: '\''refs*master'\'' does not appear to be a git repository
- fatal: The remote end hung up unexpectedly
+ fatal: Could not read from remote repository.
+
+ Please make sure you have the correct access rights
+ and the repository exists.
EOF
#
- # Do not expect "git ls-remote <pattern>" to work; ls-remote, correctly,
- # confuses <pattern> for <remote>. Although ugly, this behaviour is akin
- # to the confusion of refspecs for remotes by git-fetch and git-push,
- # eg:
- #
- # $ git fetch branch
- #
-
+ # Do not expect "git ls-remote <pattern>" to work; ls-remote needs
+ # <remote> if you want to feed <pattern>, just like you cannot say
+ # fetch <branch>.
# We could just as easily have used "master"; the "*" emphasizes its
# role as a pattern.
test_must_fail git ls-remote refs*master >actual 2>&1 &&
cat >proxy <<'EOF'
#!/bin/sh
echo >&2 "proxying for $*"
-cmd=`perl -e '
+cmd=`"$PERL_PATH" -e '
read(STDIN, $buf, 4);
my $n = hex($buf) - 4;
read(STDIN, $buf, $n);
done | git fast-import --export-marks=marks &&
# now assign tags to all the dangling commits we created above
- tag=$(perl -e "print \"bla\" x 30") &&
+ tag=$("$PERL_PATH" -e "print \"bla\" x 30") &&
sed -e "s/^:\(.\+\) \(.\+\)$/\2 refs\/tags\/$tag-\1/" <marks >>packed-refs
)
'
test_must_fail git clone not-a-git-repo not-a-git-repo-clone
'
+test_expect_success 'cloning file:// does not hardlink' '
+ git clone --bare file://"$(pwd)"/a non-local &&
+ ! repo_is_hardlinked non-local
+'
+
+test_expect_success 'cloning a local path with --no-local does not hardlink' '
+ git clone --bare --no-local a force-nonlocal &&
+ ! repo_is_hardlinked force-nonlocal
+'
+
test_done
test_expect_success 'corrupt second commit object' \
'
- perl -i.bak -pe "s/second commit/socond commit/" .git/objects/pack/*.pack &&
+ "$PERL_PATH" -i.bak -pe "s/second commit/socond commit/" .git/objects/pack/*.pack &&
test_must_fail git fsck --full
'
test_expect_success '--reverse --parents --full-history combines correctly' '
git rev-list --parents --full-history master -- foo |
- perl -e "print reverse <>" > expected &&
+ "$PERL_PATH" -e "print reverse <>" > expected &&
git rev-list --reverse --parents --full-history master -- foo \
> actual &&
test_cmp actual expected
test_expect_success '--boundary does too' '
git rev-list --boundary --parents --full-history master ^root -- foo |
- perl -e "print reverse <>" > expected &&
+ "$PERL_PATH" -e "print reverse <>" > expected &&
git rev-list --boundary --reverse --parents --full-history \
master ^root -- foo > actual &&
test_cmp actual expected
cat >expected <<-EOF &&
Merge branch ${apos}left${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left:
Left #5
Left #4
cat >expected <<-EOF &&
Merge branch ${apos}left${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left: (5 commits)
Left #5
Left #4
cat >expected <<-EOF &&
Merge branch ${apos}left${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left:
Left #5
Left #4
cat >expected <<-EOF &&
Merge branch ${apos}left${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left: (5 commits)
Left #5
Left #4
cat >expected <<-EOF &&
Merge branch ${apos}left${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left:
Left #5
Left #4
cat >expected.log <<-EOF &&
Sync with left
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* ${apos}left${apos} of $(pwd):
Left #5
Left #4
cat >expected <<-EOF
Merge branches ${apos}left${apos} and ${apos}right${apos}
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left:
Left #5
Left #4
Common #2
Common #1
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* tag ${apos}tag-l5${apos}:
Left #5
Left #4
Common #2
Common #1
- By Another Author (3) and A U Thor (2)
- via Another Committer
+ # By Another Author (3) and A U Thor (2)
+ # Via Another Committer
* left:
Left #5
Left #4
test_expect_success 'setup' '
test_commit A &&
- test_commit B &&
+ GIT_COMMITTER_DATE="@0 +0000" GIT_AUTHOR_DATE="@0 +0000" &&
+ test_commit --notick B &&
git checkout -b branch B &&
test_commit D &&
mkdir dir &&
test_must_fail git --no-pager show foo-tag
'
+test_expect_success 'set up a bit of history' '
+ test_commit main1 &&
+ test_commit main2 &&
+ test_commit main3 &&
+ git tag -m "annotated tag" annotated &&
+ git checkout -b side HEAD^^ &&
+ test_commit side2 &&
+ test_commit side3
+'
+
+test_expect_success 'showing two commits' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main2)
+ commit $(git rev-parse main3)
+ EOF
+ git show main2 main3 >actual &&
+ grep ^commit actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing a range walks (linear)' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main3)
+ commit $(git rev-parse main2)
+ EOF
+ git show main1..main3 >actual &&
+ grep ^commit actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing a range walks (Y shape, ^ first)' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main3)
+ commit $(git rev-parse main2)
+ EOF
+ git show ^side3 main3 >actual &&
+ grep ^commit actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing a range walks (Y shape, ^ last)' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main3)
+ commit $(git rev-parse main2)
+ EOF
+ git show main3 ^side3 >actual &&
+ grep ^commit actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing with -N walks' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main3)
+ commit $(git rev-parse main2)
+ EOF
+ git show -2 main3 >actual &&
+ grep ^commit actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing annotated tag' '
+ cat >expect <<-EOF &&
+ tag annotated
+ commit $(git rev-parse annotated^{commit})
+ EOF
+ git show annotated >actual &&
+ grep -E "^(commit|tag)" actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing annotated tag plus commit' '
+ cat >expect <<-EOF &&
+ tag annotated
+ commit $(git rev-parse annotated^{commit})
+ commit $(git rev-parse side3)
+ EOF
+ git show annotated side3 >actual &&
+ grep -E "^(commit|tag)" actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
+test_expect_success 'showing range' '
+ cat >expect <<-EOF &&
+ commit $(git rev-parse main3)
+ commit $(git rev-parse main2)
+ EOF
+ git show ^side3 annotated >actual &&
+ grep -E "^(commit|tag)" actual >actual.filtered &&
+ test_cmp expect actual.filtered
+'
+
test_done
git add sub &&
git config -f .gitmodules submodule.sub.path sub &&
git config -f .gitmodules submodule.sub.url ../subrepo &&
- cp .git/config pristine-.git-config
+ cp .git/config pristine-.git-config &&
+ cp .gitmodules pristine-.gitmodules
)
'
-test_expect_success 'relative path works with URL' '
+test_expect_success '../subrepo works with URL - ssh://hostname/repo' '
(
cd reltest &&
cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
git config remote.origin.url ssh://hostname/repo &&
git submodule init &&
test "$(git config submodule.sub.url)" = ssh://hostname/subrepo
)
'
-test_expect_success 'relative path works with user@host:path' '
+test_expect_success '../subrepo works with port-qualified URL - ssh://hostname:22/repo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url ssh://hostname:22/repo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = ssh://hostname:22/subrepo
+ )
+'
+
+# About the choice of the path in the next test:
+# - double-slash side-steps path mangling issues on Windows
+# - it is still an absolute local path
+# - there cannot be a server with a blank in its name just in case the
+# path is used erroneously to access a //server/share style path
+test_expect_success '../subrepo path works with local path - //somewhere else/repo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url "//somewhere else/repo" &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = "//somewhere else/subrepo"
+ )
+'
+
+test_expect_success '../subrepo works with file URL - file:///tmp/repo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url file:///tmp/repo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = file:///tmp/subrepo
+ )
+'
+
+test_expect_success '../subrepo works with helper URL- helper:://hostname/repo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url helper:://hostname/repo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = helper:://hostname/subrepo
+ )
+'
+
+test_expect_success '../subrepo works with scp-style URL - user@host:repo' '
(
cd reltest &&
cp pristine-.git-config .git/config &&
)
'
+test_expect_success '../subrepo works with scp-style URL - user@host:path/to/repo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url user@host:path/to/repo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = user@host:path/to/subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - foo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url foo &&
+ # actual: fails with an error
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - foo/bar' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url foo/bar &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = foo/subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - ./foo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url ./foo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - ./foo/bar' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url ./foo/bar &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = foo/subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - ../foo' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url ../foo &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = ../subrepo
+ )
+'
+
+test_expect_success '../subrepo works with relative local path - ../foo/bar' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ git config remote.origin.url ../foo/bar &&
+ git submodule init &&
+ test "$(git config submodule.sub.url)" = ../foo/subrepo
+ )
+'
+
+test_expect_success '../bar/a/b/c works with relative local path - ../foo/bar.git' '
+ (
+ cd reltest &&
+ cp pristine-.git-config .git/config &&
+ cp pristine-.gitmodules .gitmodules &&
+ mkdir -p a/b/c &&
+ (cd a/b/c; git init) &&
+ git config remote.origin.url ../foo/bar.git &&
+ git submodule add ../bar/a/b/c ./a/b/c &&
+ git submodule init &&
+ test "$(git config submodule.a/b/c.url)" = ../foo/bar/a/b/c
+ )
+'
+
test_expect_success 'moving the superproject does not break submodules' '
(
cd addtest &&
(cd super-clone && git submodule update --init) &&
git clone super empty-clone &&
(cd empty-clone && git submodule init) &&
- git clone super top-only-clone
+ git clone super top-only-clone &&
+ git clone super relative-clone &&
+ (cd relative-clone && git submodule update --init)
'
test_expect_success 'change submodule' '
)
'
+test_expect_success '"git submodule sync" handles origin URL of the form foo' '
+ (cd relative-clone &&
+ git remote set-url origin foo &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual fails with: "cannot strip off url foo
+ test "$(git config remote.origin.url)" = "../submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form foo/bar' '
+ (cd relative-clone &&
+ git remote set-url origin foo/bar &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual foo/submodule
+ test "$(git config remote.origin.url)" = "../foo/submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form ./foo' '
+ (cd relative-clone &&
+ git remote set-url origin ./foo &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual ./submodule
+ test "$(git config remote.origin.url)" = "../submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form ./foo/bar' '
+ (cd relative-clone &&
+ git remote set-url origin ./foo/bar &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual ./foo/submodule
+ test "$(git config remote.origin.url)" = "../foo/submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form ../foo' '
+ (cd relative-clone &&
+ git remote set-url origin ../foo &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual ../submodule
+ test "$(git config remote.origin.url)" = "../../submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form ../foo/bar' '
+ (cd relative-clone &&
+ git remote set-url origin ../foo/bar &&
+ git submodule sync &&
+ (cd submodule &&
+ #actual ../foo/submodule
+ test "$(git config remote.origin.url)" = "../../foo/submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync" handles origin URL of the form ../foo/bar with deeply nested submodule' '
+ (cd relative-clone &&
+ git remote set-url origin ../foo/bar &&
+ mkdir -p a/b/c &&
+ ( cd a/b/c &&
+ git init &&
+ :> .gitignore &&
+ git add .gitignore &&
+ test_tick &&
+ git commit -m "initial commit" ) &&
+ git submodule add ../bar/a/b/c ./a/b/c &&
+ git submodule sync &&
+ (cd a/b/c &&
+ #actual ../foo/bar/a/b/c
+ test "$(git config remote.origin.url)" = "../../../../foo/bar/a/b/c"
+ )
+ )
+'
+
+
test_done
EDITOR=./editor git commit --amend
'
+test_expect_success 'amend --only ignores staged contents' '
+ cp file file.expect &&
+ echo changed >file &&
+ git add file &&
+ git commit --no-edit --amend --only &&
+ git cat-file blob HEAD:file >file.actual &&
+ test_cmp file.expect file.actual &&
+ git diff --exit-code
+'
+
test_expect_success 'set up editor' '
cat >editor <<-\EOF &&
#!/bin/sh
test_cmp expect msg
'
+test_expect_success '--amend --edit of empty message' '
+ cat >replace <<-\EOF &&
+ #!/bin/sh
+ echo "amended" >"$1"
+ EOF
+ chmod 755 replace &&
+ git commit --allow-empty --allow-empty-message -m "" &&
+ echo more bongo >file &&
+ git add file &&
+ EDITOR=./replace git commit --edit --amend &&
+ git diff-tree -s --format=%s HEAD >msg &&
+ ./replace expect &&
+ test_cmp expect msg
+'
+
test_expect_success '-m --edit' '
echo amended >expect &&
git commit --allow-empty -m buffer &&
'
+test_expect_success 'commit a file whose name is a dash' '
+ git reset --hard &&
+ for i in 1 2 3 4 5
+ do
+ echo $i
+ done >./- &&
+ git add ./- &&
+ test_tick &&
+ git commit -m "add dash" >output </dev/null &&
+ test_i18ngrep " changed, 5 insertions" output
+'
+
test_done
test_expect_success 'status -z implies porcelain' '
git status --porcelain |
- perl -pe "s/\012/\000/g" >expect &&
+ "$PERL_PATH" -pe "s/\012/\000/g" >expect &&
git status -z >output &&
test_cmp expect output
'
cat >helper <<'EOF'
#!/bin/sh
grep -q '^bin: ' "$1" || { echo "E: $1 is not \"binary\" file" 1>&2; exit 1; }
-perl -p -e 's/^bin: /converted: /' "$1"
+"$PERL_PATH" -p -e 's/^bin: /converted: /' "$1"
EOF
chmod +x helper
compare_svn_head_with () {
# extract just the log message and strip out committer info.
# don't use --limit here since svn 1.1.x doesn't have it,
- LC_ALL="$a_utf8_locale" svn log `git svn info --url` | perl -w -e '
+ LC_ALL="$a_utf8_locale" svn log `git svn info --url` | "$PERL_PATH" -w -e '
use bytes;
$/ = ("-"x72) . "\n";
my @x = <STDIN>;
test x"`sed -n -e 61p < file`" = x61 &&
svn_cmd co "$svnrepo" tmp &&
(cd tmp &&
- perl -i.bak -p -e "s/^58$/5588/" file &&
- perl -i.bak -p -e "s/^61$/6611/" file &&
+ "$PERL_PATH" -i.bak -p -e "s/^58$/5588/" file &&
+ "$PERL_PATH" -i.bak -p -e "s/^61$/6611/" file &&
poke file &&
test x"`sed -n -e 58p < file`" = x5588 &&
test x"`sed -n -e 61p < file`" = x6611 &&
test_expect_success 'change file but in unrelated area' "
test x\"\`sed -n -e 4p < file\`\" = x4 &&
test x\"\`sed -n -e 7p < file\`\" = x7 &&
- perl -i.bak -p -e 's/^4\$/4444/' file &&
- perl -i.bak -p -e 's/^7\$/7777/' file &&
+ "$PERL_PATH" -i.bak -p -e 's/^4\$/4444/' file &&
+ "$PERL_PATH" -i.bak -p -e 's/^7\$/7777/' file &&
test x\"\`sed -n -e 4p < file\`\" = x4444 &&
test x\"\`sed -n -e 7p < file\`\" = x7777 &&
git commit -m '4 => 4444, 7 => 7777' file &&
# This could be written as "head -c $1", but IRIX "head" does not
# support the -c option.
head_c () {
- perl -e '
+ "$PERL_PATH" -e '
my $len = $ARGV[1];
while ($len > 0) {
my $s;
grep :1 git.marks'
test_expect_success \
- 'R: export-marks options can be overriden by commandline options' \
+ 'R: export-marks options can be overridden by commandline options' \
'cat input | git fast-import --export-marks=other.marks &&
grep :1 other.marks'
--cacheinfo 100644 $blob "path with \\backslash" \
--cacheinfo 100644 $blob "path with space" &&
git commit -m addition &&
- git ls-files -z -s | perl -0pe "s{\\t}{$&subdir/}" >index &&
+ git ls-files -z -s | "$PERL_PATH" -0pe "s{\\t}{$&subdir/}" >index &&
git read-tree --empty &&
git update-index -z --index-info <index &&
git commit -m rename &&
git read-tree --empty &&
git commit -m deletion &&
- git fast-export HEAD >export.out &&
+ git fast-export -M HEAD >export.out &&
git rev-list HEAD >expect &&
git init result &&
cd result &&
. ./gitweb-lib.sh
+#
+# Gitweb only provides the functionality tested by the 'modification times'
+# tests if it can access a date parser from one of these modules:
+#
+perl -MHTTP::Date -e 0 >/dev/null 2>&1 && test_set_prereq DATE_PARSER
+perl -MTime::ParseDate -e 0 >/dev/null 2>&1 && test_set_prereq DATE_PARSER
+
# ----------------------------------------------------------------------
# snapshot settings
# ----------------------------------------------------------------------
# modification times (Last-Modified and If-Modified-Since)
-test_expect_success 'modification: feed last-modified' '
+test_expect_success DATE_PARSER 'modification: feed last-modified' '
gitweb_run "p=.git;a=atom;h=master" &&
grep "Status: 200 OK" gitweb.headers &&
grep "Last-modified: Thu, 7 Apr 2005 22:14:13 +0000" gitweb.headers
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: feed if-modified-since (modified)' '
+test_expect_success DATE_PARSER 'modification: feed if-modified-since (modified)' '
export HTTP_IF_MODIFIED_SINCE="Wed, 6 Apr 2005 22:14:13 +0000" &&
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
gitweb_run "p=.git;a=atom;h=master" &&
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: feed if-modified-since (unmodified)' '
+test_expect_success DATE_PARSER 'modification: feed if-modified-since (unmodified)' '
export HTTP_IF_MODIFIED_SINCE="Thu, 7 Apr 2005 22:14:13 +0000" &&
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
gitweb_run "p=.git;a=atom;h=master" &&
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: snapshot last-modified' '
+test_expect_success DATE_PARSER 'modification: snapshot last-modified' '
gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" &&
grep "Status: 200 OK" gitweb.headers &&
grep "Last-modified: Thu, 7 Apr 2005 22:14:13 +0000" gitweb.headers
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: snapshot if-modified-since (modified)' '
+test_expect_success DATE_PARSER 'modification: snapshot if-modified-since (modified)' '
export HTTP_IF_MODIFIED_SINCE="Wed, 6 Apr 2005 22:14:13 +0000" &&
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" &&
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: snapshot if-modified-since (unmodified)' '
+test_expect_success DATE_PARSER 'modification: snapshot if-modified-since (unmodified)' '
export HTTP_IF_MODIFIED_SINCE="Thu, 7 Apr 2005 22:14:13 +0000" &&
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" &&
'
test_debug 'cat gitweb.headers'
-test_expect_success 'modification: tree snapshot' '
+test_expect_success DATE_PARSER 'modification: tree snapshot' '
ID=`git rev-parse --verify HEAD^{tree}` &&
export HTTP_IF_MODIFIED_SINCE="Wed, 6 Apr 2005 22:14:13 +0000" &&
test_when_finished "unset HTTP_IF_MODIFIED_SINCE" &&
test_when_finished cleanup_git &&
(
cd "$git" &&
- test_must_fail git p4 sync
+ test_must_fail git p4 sync 2>errs &&
+ test_i18ngrep "Perhaps you never did" errs
)
'
'
test_expect_success 'exit when p4 fails to produce marshaled output' '
- badp4dir="$TRASH_DIRECTORY/badp4dir" &&
- mkdir "$badp4dir" &&
- test_when_finished "rm \"$badp4dir/p4\" && rmdir \"$badp4dir\"" &&
- cat >"$badp4dir"/p4 <<-EOF &&
+ mkdir badp4dir &&
+ test_when_finished "rm badp4dir/p4 && rmdir badp4dir" &&
+ cat >badp4dir/p4 <<-EOF &&
#!$SHELL_PATH
exit 1
EOF
- chmod 755 "$badp4dir"/p4 &&
- PATH="$badp4dir:$PATH" git p4 clone --dest="$git" //depot >errs 2>&1 ; retval=$? &&
- test $retval -eq 1 &&
- test_must_fail grep -q Traceback errs
-'
-
-test_expect_success 'add p4 files with wildcards in the names' '
- (
- cd "$cli" &&
- echo file-wild-hash >file-wild#hash &&
- echo file-wild-star >file-wild\*star &&
- echo file-wild-at >file-wild@at &&
- echo file-wild-percent >file-wild%percent &&
- p4 add -f file-wild* &&
- p4 submit -d "file wildcards"
- )
-'
-
-test_expect_success 'wildcard files git p4 clone' '
- git p4 clone --dest="$git" //depot &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- test -f file-wild#hash &&
- test -f file-wild\*star &&
- test -f file-wild@at &&
- test -f file-wild%percent
- )
-'
-
-test_expect_success 'wildcard files submit back to p4, add' '
- test_when_finished cleanup_git &&
- git p4 clone --dest="$git" //depot &&
- (
- cd "$git" &&
- echo git-wild-hash >git-wild#hash &&
- echo git-wild-star >git-wild\*star &&
- echo git-wild-at >git-wild@at &&
- echo git-wild-percent >git-wild%percent &&
- git add git-wild* &&
- git commit -m "add some wildcard filenames" &&
- git config git-p4.skipSubmitEdit true &&
- git p4 submit
- ) &&
- (
- cd "$cli" &&
- test_path_is_file git-wild#hash &&
- test_path_is_file git-wild\*star &&
- test_path_is_file git-wild@at &&
- test_path_is_file git-wild%percent
- )
-'
-
-test_expect_success 'wildcard files submit back to p4, modify' '
- test_when_finished cleanup_git &&
- git p4 clone --dest="$git" //depot &&
- (
- cd "$git" &&
- echo new-line >>git-wild#hash &&
- echo new-line >>git-wild\*star &&
- echo new-line >>git-wild@at &&
- echo new-line >>git-wild%percent &&
- git add git-wild* &&
- git commit -m "modify the wildcard files" &&
- git config git-p4.skipSubmitEdit true &&
- git p4 submit
- ) &&
- (
- cd "$cli" &&
- test_line_count = 2 git-wild#hash &&
- test_line_count = 2 git-wild\*star &&
- test_line_count = 2 git-wild@at &&
- test_line_count = 2 git-wild%percent
- )
-'
-
-test_expect_success 'wildcard files submit back to p4, copy' '
- test_when_finished cleanup_git &&
- git p4 clone --dest="$git" //depot &&
+ chmod 755 badp4dir/p4 &&
(
- cd "$git" &&
- cp file2 git-wild-cp#hash &&
- git add git-wild-cp#hash &&
- cp git-wild\*star file-wild-3 &&
- git add file-wild-3 &&
- git commit -m "wildcard copies" &&
- git config git-p4.detectCopies true &&
- git config git-p4.detectCopiesHarder true &&
- git config git-p4.skipSubmitEdit true &&
- git p4 submit
+ PATH="$TRASH_DIRECTORY/badp4dir:$PATH" &&
+ export PATH &&
+ test_expect_code 1 git p4 clone --dest="$git" //depot >errs 2>&1
) &&
- (
- cd "$cli" &&
- test_path_is_file git-wild-cp#hash &&
- test_path_is_file file-wild-3
- )
-'
-
-test_expect_success 'wildcard files submit back to p4, rename' '
- test_when_finished cleanup_git &&
- git p4 clone --dest="$git" //depot &&
- (
- cd "$git" &&
- git mv git-wild@at file-wild-4 &&
- git mv file-wild-3 git-wild-cp%percent &&
- git commit -m "wildcard renames" &&
- git config git-p4.detectRenames true &&
- git config git-p4.skipSubmitEdit true &&
- git p4 submit
- ) &&
- (
- cd "$cli" &&
- test_path_is_missing git-wild@at &&
- test_path_is_file git-wild-cp%percent
- )
-'
-
-test_expect_success 'wildcard files submit back to p4, delete' '
- test_when_finished cleanup_git &&
- git p4 clone --dest="$git" //depot &&
- (
- cd "$git" &&
- git rm git-wild* &&
- git commit -m "delete the wildcard files" &&
- git config git-p4.skipSubmitEdit true &&
- git p4 submit
- ) &&
- (
- cd "$cli" &&
- test_path_is_missing git-wild#hash &&
- test_path_is_missing git-wild\*star &&
- test_path_is_missing git-wild@at &&
- test_path_is_missing git-wild%percent
- )
+ cat errs &&
+ ! test_i18ngrep Traceback errs
'
test_expect_success 'clone bare' '
+ rm -rf "$git" &&
git p4 clone --dest="$git" --bare //depot &&
test_when_finished cleanup_git &&
(
)
'
-p4_add_user() {
- name=$1 fullname=$2 &&
- p4 user -f -i <<-EOF &&
- User: $name
- Email: $name@localhost
- FullName: $fullname
- EOF
- p4 passwd -P secret $name
-}
-
-p4_grant_admin() {
- name=$1 &&
- {
- p4 protect -o &&
- echo " admin user $name * //depot/..."
- } | p4 protect -i
-}
-
-p4_check_commit_author() {
- file=$1 user=$2 &&
- p4 changes -m 1 //depot/$file | grep -q $user
-}
-
-make_change_by_user() {
- file=$1 name=$2 email=$3 &&
- echo "username: a change by $name" >>"$file" &&
- git add "$file" &&
- git commit --author "$name <$email>" -m "a change by $name"
-}
-
-# Test username support, submitting as user 'alice'
-test_expect_success 'preserve users' '
- p4_add_user alice Alice &&
- p4_add_user bob Bob &&
- p4_grant_admin alice &&
- git p4 clone --dest="$git" //depot &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- echo "username: a change by alice" >>file1 &&
- echo "username: a change by bob" >>file2 &&
- git commit --author "Alice <alice@localhost>" -m "a change by alice" file1 &&
- git commit --author "Bob <bob@localhost>" -m "a change by bob" file2 &&
- git config git-p4.skipSubmitEditCheck true &&
- P4EDITOR=touch P4USER=alice P4PASSWD=secret git p4 commit --preserve-user &&
- p4_check_commit_author file1 alice &&
- p4_check_commit_author file2 bob
- )
-'
-
-# Test username support, submitting as bob, who lacks admin rights. Should
-# not submit change to p4 (git diff should show deltas).
-test_expect_success 'refuse to preserve users without perms' '
- git p4 clone --dest="$git" //depot &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- git config git-p4.skipSubmitEditCheck true &&
- echo "username-noperms: a change by alice" >>file1 &&
- git commit --author "Alice <alice@localhost>" -m "perms: a change by alice" file1 &&
- P4EDITOR=touch P4USER=bob P4PASSWD=secret &&
- export P4EDITOR P4USER P4PASSWD &&
- test_must_fail git p4 commit --preserve-user &&
- ! git diff --exit-code HEAD..p4/master
- )
-'
-
-# What happens with unknown author? Without allowMissingP4Users it should fail.
-test_expect_success 'preserve user where author is unknown to p4' '
- git p4 clone --dest="$git" //depot &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- git config git-p4.skipSubmitEditCheck true &&
- echo "username-bob: a change by bob" >>file1 &&
- git commit --author "Bob <bob@localhost>" -m "preserve: a change by bob" file1 &&
- echo "username-unknown: a change by charlie" >>file1 &&
- git commit --author "Charlie <charlie@localhost>" -m "preserve: a change by charlie" file1 &&
- P4EDITOR=touch P4USER=alice P4PASSWD=secret &&
- export P4EDITOR P4USER P4PASSWD &&
- test_must_fail git p4 commit --preserve-user &&
- ! git diff --exit-code HEAD..p4/master &&
-
- echo "$0: repeat with allowMissingP4Users enabled" &&
- git config git-p4.allowMissingP4Users true &&
- git config git-p4.preserveUser true &&
- git p4 commit &&
- git diff --exit-code HEAD..p4/master &&
- p4_check_commit_author file1 alice
- )
-'
-
-# If we're *not* using --preserve-user, git p4 should warn if we're submitting
-# changes that are not all ours.
-# Test: user in p4 and user unknown to p4.
-# Test: warning disabled and user is the same.
-test_expect_success 'not preserving user with mixed authorship' '
- git p4 clone --dest="$git" //depot &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- git config git-p4.skipSubmitEditCheck true &&
- p4_add_user derek Derek &&
-
- make_change_by_user usernamefile3 Derek derek@localhost &&
- P4EDITOR=cat P4USER=alice P4PASSWD=secret &&
- export P4EDITOR P4USER P4PASSWD &&
- git p4 commit |\
- grep "git author derek@localhost does not match" &&
-
- make_change_by_user usernamefile3 Charlie charlie@localhost &&
- git p4 commit |\
- grep "git author charlie@localhost does not match" &&
-
- make_change_by_user usernamefile3 alice alice@localhost &&
- git p4 commit |\
- test_must_fail grep "git author.*does not match" &&
-
- git config git-p4.skipUserNameCheck true &&
- make_change_by_user usernamefile3 Charlie charlie@localhost &&
- git p4 commit |\
- test_must_fail grep "git author.*does not match" &&
-
- p4_check_commit_author usernamefile3 alice
- )
-'
-
-marshal_dump() {
- what=$1
- "$PYTHON_PATH" -c 'import marshal, sys; d = marshal.load(sys.stdin); print d["'$what'"]'
-}
-
# Sleep a bit so that the top-most p4 change did not happen "now". Then
# import the repo and make sure that the initial import has the same time
# as the top-most change.
)
'
-# Rename a file and confirm that rename is not detected in P4.
-# Rename the new file again with detectRenames option enabled and confirm that
-# this is detected in P4.
-# Rename the new file again adding an extra line, configure a big threshold in
-# detectRenames and confirm that rename is not detected in P4.
-# Repeat, this time with a smaller threshold and confirm that the rename is
-# detected in P4.
-test_expect_success 'detect renames' '
- git p4 clone --dest="$git" //depot@all &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- git config git-p4.skipSubmitEdit true &&
-
- git mv file1 file4 &&
- git commit -a -m "Rename file1 to file4" &&
- git diff-tree -r -M HEAD &&
- git p4 submit &&
- p4 filelog //depot/file4 &&
- p4 filelog //depot/file4 | test_must_fail grep -q "branch from" &&
-
- git mv file4 file5 &&
- git commit -a -m "Rename file4 to file5" &&
- git diff-tree -r -M HEAD &&
- git config git-p4.detectRenames true &&
- git p4 submit &&
- p4 filelog //depot/file5 &&
- p4 filelog //depot/file5 | grep -q "branch from //depot/file4" &&
-
- git mv file5 file6 &&
- echo update >>file6 &&
- git add file6 &&
- git commit -a -m "Rename file5 to file6 with changes" &&
- git diff-tree -r -M HEAD &&
- level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
- test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
- git config git-p4.detectRenames $(($level + 2)) &&
- git p4 submit &&
- p4 filelog //depot/file6 &&
- p4 filelog //depot/file6 | test_must_fail grep -q "branch from" &&
-
- git mv file6 file7 &&
- echo update >>file7 &&
- git add file7 &&
- git commit -a -m "Rename file6 to file7 with changes" &&
- git diff-tree -r -M HEAD &&
- level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
- test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
- git config git-p4.detectRenames $(($level - 2)) &&
- git p4 submit &&
- p4 filelog //depot/file7 &&
- p4 filelog //depot/file7 | grep -q "branch from //depot/file6"
- )
-'
-
-# Copy a file and confirm that copy is not detected in P4.
-# Copy a file with detectCopies option enabled and confirm that copy is not
-# detected in P4.
-# Modify and copy a file with detectCopies option enabled and confirm that copy
-# is detected in P4.
-# Copy a file with detectCopies and detectCopiesHarder options enabled and
-# confirm that copy is detected in P4.
-# Modify and copy a file, configure a bigger threshold in detectCopies and
-# confirm that copy is not detected in P4.
-# Modify and copy a file, configure a smaller threshold in detectCopies and
-# confirm that copy is detected in P4.
-test_expect_success 'detect copies' '
- git p4 clone --dest="$git" //depot@all &&
- test_when_finished cleanup_git &&
- (
- cd "$git" &&
- git config git-p4.skipSubmitEdit true &&
-
- cp file2 file8 &&
- git add file8 &&
- git commit -a -m "Copy file2 to file8" &&
- git diff-tree -r -C HEAD &&
- git p4 submit &&
- p4 filelog //depot/file8 &&
- p4 filelog //depot/file8 | test_must_fail grep -q "branch from" &&
-
- cp file2 file9 &&
- git add file9 &&
- git commit -a -m "Copy file2 to file9" &&
- git diff-tree -r -C HEAD &&
- git config git-p4.detectCopies true &&
- git p4 submit &&
- p4 filelog //depot/file9 &&
- p4 filelog //depot/file9 | test_must_fail grep -q "branch from" &&
-
- echo "file2" >>file2 &&
- cp file2 file10 &&
- git add file2 file10 &&
- git commit -a -m "Modify and copy file2 to file10" &&
- git diff-tree -r -C HEAD &&
- git p4 submit &&
- p4 filelog //depot/file10 &&
- p4 filelog //depot/file10 | grep -q "branch from //depot/file" &&
-
- cp file2 file11 &&
- git add file11 &&
- git commit -a -m "Copy file2 to file11" &&
- git diff-tree -r -C --find-copies-harder HEAD &&
- src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
- test "$src" = file10 &&
- git config git-p4.detectCopiesHarder true &&
- git p4 submit &&
- p4 filelog //depot/file11 &&
- p4 filelog //depot/file11 | grep -q "branch from //depot/file" &&
-
- cp file2 file12 &&
- echo "some text" >>file12 &&
- git add file12 &&
- git commit -a -m "Copy file2 to file12 with changes" &&
- git diff-tree -r -C --find-copies-harder HEAD &&
- level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
- test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
- src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
- test "$src" = file10 &&
- git config git-p4.detectCopies $(($level + 2)) &&
- git p4 submit &&
- p4 filelog //depot/file12 &&
- p4 filelog //depot/file12 | test_must_fail grep -q "branch from" &&
-
- cp file2 file13 &&
- echo "different text" >>file13 &&
- git add file13 &&
- git commit -a -m "Copy file2 to file13 with changes" &&
- git diff-tree -r -C --find-copies-harder HEAD &&
- level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
- test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
- src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
- test "$src" = file10 &&
- git config git-p4.detectCopies $(($level - 2)) &&
- git p4 submit &&
- p4 filelog //depot/file13 &&
- p4 filelog //depot/file13 | grep -q "branch from //depot/file"
- )
-'
-
test_expect_success 'kill p4d' '
kill_p4d
'
test_expect_success 'no config, edited' '
git p4 clone --dest="$git" //depot &&
test_when_finished cleanup_git &&
- ed="$TRASH_DIRECTORY/ed.sh" &&
- test_when_finished "rm \"$ed\"" &&
- cat >"$ed" <<-EOF &&
+ test_when_finished "rm ed.sh" &&
+ cat >ed.sh <<-EOF &&
#!$SHELL_PATH
sleep 1
touch "\$1"
exit 0
EOF
- chmod 755 "$ed" &&
+ chmod 755 ed.sh &&
(
cd "$git" &&
echo line >>file1 &&
git commit -a -m "change 5" &&
- P4EDITOR="" EDITOR="\"$ed\"" git p4 submit &&
+ P4EDITOR="" EDITOR="\"$TRASH_DIRECTORY/ed.sh\"" git p4 submit &&
p4 changes //depot/... >wc &&
test_line_count = 5 wc
)
'
test_expect_success 'clone --changesfile' '
- cf="$TRASH_DIRECTORY/cf" &&
- test_when_finished "rm \"$cf\"" &&
- printf "1\n3\n" >"$cf" &&
- git p4 clone --changesfile="$cf" --dest="$git" //depot &&
+ test_when_finished "rm cf" &&
+ printf "1\n3\n" >cf &&
+ git p4 clone --changesfile="$TRASH_DIRECTORY/cf" --dest="$git" //depot &&
test_when_finished cleanup_git &&
(
cd "$git" &&
'
test_expect_success 'clone --changesfile, @all' '
- cf="$TRASH_DIRECTORY/cf" &&
- test_when_finished "rm \"$cf\"" &&
- printf "1\n3\n" >"$cf" &&
- test_must_fail git p4 clone --changesfile="$cf" --dest="$git" //depot@all
+ test_when_finished "rm cf" &&
+ printf "1\n3\n" >cf &&
+ test_must_fail git p4 clone --changesfile="$TRASH_DIRECTORY/cf" --dest="$git" //depot@all
'
# imports both master and p4/master in refs/heads
exec >/dev/null &&
test_must_fail git p4 clone --dest="$git" --use-client-spec
) &&
- cli2="$TRASH_DIRECTORY/cli2" &&
+ cli2=$(test-path-utils real_path "$TRASH_DIRECTORY/cli2") &&
mkdir -p "$cli2" &&
test_when_finished "rmdir \"$cli2\"" &&
(
cleanup_git &&
# same thing again, this time with variable instead of option
- mkdir "$git" &&
(
cd "$git" &&
git init &&
)
'
+#
+# Converting git commit message to p4 change description, including
+# parsing out the optional Jobs: line.
+#
+test_expect_success 'simple one-line description' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo desc2 >desc2 &&
+ git add desc2 &&
+ cat >msg <<-EOF &&
+ One-line description line for desc2.
+ EOF
+ git commit -F - <msg &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit &&
+ change=$(p4 -G changes -m 1 //depot/... | \
+ marshal_dump change) &&
+ # marshal_dump always adds a newline
+ p4 -G describe $change | marshal_dump desc | sed \$d >pmsg &&
+ test_cmp msg pmsg
+ )
+'
+
+test_expect_success 'description with odd formatting' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo desc3 >desc3 &&
+ git add desc3 &&
+ (
+ printf "subject line\n\n\tExtra tab\nline.\n\n" &&
+ printf "Description:\n\tBogus description marker\n\n" &&
+ # git commit eats trailing newlines; only use one
+ printf "Files:\n\tBogus descs marker\n"
+ ) >msg &&
+ git commit -F - <msg &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit &&
+ change=$(p4 -G changes -m 1 //depot/... | \
+ marshal_dump change) &&
+ # marshal_dump always adds a newline
+ p4 -G describe $change | marshal_dump desc | sed \$d >pmsg &&
+ test_cmp msg pmsg
+ )
+'
+
+make_job() {
+ name="$1" &&
+ tab="$(printf \\t)" &&
+ p4 job -o | \
+ sed -e "/^Job:/s/.*/Job: $name/" \
+ -e "/^Description/{ n; s/.*/$tab job text/; }" | \
+ p4 job -i
+}
+
+test_expect_success 'description with Jobs section at end' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo desc4 >desc4 &&
+ git add desc4 &&
+ echo 6060842 >jobname &&
+ (
+ printf "subject line\n\n\tExtra tab\nline.\n\n" &&
+ printf "Files:\n\tBogus files marker\n" &&
+ printf "Junk: 3164175\n" &&
+ printf "Jobs: $(cat jobname)\n"
+ ) >msg &&
+ git commit -F - <msg &&
+ git config git-p4.skipSubmitEdit true &&
+ # build a job
+ make_job $(cat jobname) &&
+ git p4 submit &&
+ change=$(p4 -G changes -m 1 //depot/... | \
+ marshal_dump change) &&
+ # marshal_dump always adds a newline
+ p4 -G describe $change | marshal_dump desc | sed \$d >pmsg &&
+ # make sure Jobs line and all following is gone
+ sed "/^Jobs:/,\$d" msg >jmsg &&
+ test_cmp jmsg pmsg &&
+ # make sure p4 knows about job
+ p4 -G describe $change | marshal_dump job0 >job0 &&
+ test_cmp jobname job0
+ )
+'
+
+test_expect_success 'description with Jobs and values on separate lines' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo desc5 >desc5 &&
+ git add desc5 &&
+ echo PROJ-6060842 >jobname1 &&
+ echo PROJ-6060847 >jobname2 &&
+ (
+ printf "subject line\n\n\tExtra tab\nline.\n\n" &&
+ printf "Files:\n\tBogus files marker\n" &&
+ printf "Junk: 3164175\n" &&
+ printf "Jobs:\n" &&
+ printf "\t$(cat jobname1)\n" &&
+ printf "\t$(cat jobname2)\n"
+ ) >msg &&
+ git commit -F - <msg &&
+ git config git-p4.skipSubmitEdit true &&
+ # build two jobs
+ make_job $(cat jobname1) &&
+ make_job $(cat jobname2) &&
+ git p4 submit &&
+ change=$(p4 -G changes -m 1 //depot/... | \
+ marshal_dump change) &&
+ # marshal_dump always adds a newline
+ p4 -G describe $change | marshal_dump desc | sed \$d >pmsg &&
+ # make sure Jobs line and all following is gone
+ sed "/^Jobs:/,\$d" msg >jmsg &&
+ test_cmp jmsg pmsg &&
+ # make sure p4 knows about the two jobs
+ p4 -G describe $change >change &&
+ (
+ marshal_dump job0 <change &&
+ marshal_dump job1 <change
+ ) | sort >jobs &&
+ cat jobname1 jobname2 | sort >expected &&
+ test_cmp expected jobs
+ )
+'
+
+test_expect_success 'description with Jobs section and bogus following text' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo desc6 >desc6 &&
+ git add desc6 &&
+ echo 6060843 >jobname &&
+ (
+ printf "subject line\n\n\tExtra tab\nline.\n\n" &&
+ printf "Files:\n\tBogus files marker\n" &&
+ printf "Junk: 3164175\n" &&
+ printf "Jobs: $(cat jobname)\n" &&
+ printf "MoreJunk: 3711\n"
+ ) >msg &&
+ git commit -F - <msg &&
+ git config git-p4.skipSubmitEdit true &&
+ # build a job
+ make_job $(cat jobname) &&
+ test_must_fail git p4 submit 2>err &&
+ test_i18ngrep "Unknown field name" err
+ )
+'
+
test_expect_success 'kill p4d' '
kill_p4d
'
# environment variable is set
test_expect_success 'P4CONFIG and absolute dir clone' '
printf "P4PORT=$P4PORT\nP4CLIENT=$P4CLIENT\n" >p4config &&
- test_when_finished "rm \"$TRASH_DIRECTORY/p4config\"" &&
+ test_when_finished "rm p4config" &&
test_when_finished cleanup_git &&
(
P4CONFIG=p4config && export P4CONFIG &&
# same thing, but with relative directory name, note missing $ on --dest
test_expect_success 'P4CONFIG and relative dir clone' '
printf "P4PORT=$P4PORT\nP4CLIENT=$P4CLIENT\n" >p4config &&
- test_when_finished "rm \"$TRASH_DIRECTORY/p4config\"" &&
+ test_when_finished "rm p4config" &&
test_when_finished cleanup_git &&
(
P4CONFIG=p4config && export P4CONFIG &&
#!/bin/sh
-test_description='git-p4 rcs keywords'
+test_description='git p4 rcs keywords'
. ./lib-git-p4.sh
)
'
-# hack; git-p4 submit should do it on its own
+# hack; git p4 submit should do it on its own
test_expect_success 'cleanup after failure' '
(
cd "$cli" &&
)
'
-# hack; git-p4 submit should do it on its own
+# hack; git p4 submit should do it on its own
test_expect_success 'cleanup after failure 2' '
(
cd "$cli" &&
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
git config git-p4.attemptRCSCleanup true &&
- (cd ../cli && p4_append_to_file kwfile1.c) &&
+ (cd "$cli" && p4_append_to_file kwfile1.c) &&
old_lines=$(wc -l <kwfile1.c) &&
- perl -n -i -e "print unless m/Revision:/" kwfile1.c &&
+ "$PERL_PATH" -n -i -e "print unless m/Revision:/" kwfile1.c &&
new_lines=$(wc -l <kwfile1.c) &&
test $new_lines = $(($old_lines - 1)) &&
--- /dev/null
+#!/bin/sh
+
+test_description='git p4 wildcards'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+test_expect_success 'add p4 files with wildcards in the names' '
+ (
+ cd "$cli" &&
+ printf "file2\nhas\nsome\nrandom\ntext\n" >file2 &&
+ p4 add file2 &&
+ echo file-wild-hash >file-wild#hash &&
+ echo file-wild-star >file-wild\*star &&
+ echo file-wild-at >file-wild@at &&
+ echo file-wild-percent >file-wild%percent &&
+ p4 add -f file-wild* &&
+ p4 submit -d "file wildcards"
+ )
+'
+
+test_expect_success 'wildcard files git p4 clone' '
+ git p4 clone --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ test -f file-wild#hash &&
+ test -f file-wild\*star &&
+ test -f file-wild@at &&
+ test -f file-wild%percent
+ )
+'
+
+test_expect_success 'wildcard files submit back to p4, add' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo git-wild-hash >git-wild#hash &&
+ echo git-wild-star >git-wild\*star &&
+ echo git-wild-at >git-wild@at &&
+ echo git-wild-percent >git-wild%percent &&
+ git add git-wild* &&
+ git commit -m "add some wildcard filenames" &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file git-wild#hash &&
+ test_path_is_file git-wild\*star &&
+ test_path_is_file git-wild@at &&
+ test_path_is_file git-wild%percent
+ )
+'
+
+test_expect_success 'wildcard files submit back to p4, modify' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo new-line >>git-wild#hash &&
+ echo new-line >>git-wild\*star &&
+ echo new-line >>git-wild@at &&
+ echo new-line >>git-wild%percent &&
+ git add git-wild* &&
+ git commit -m "modify the wildcard files" &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_line_count = 2 git-wild#hash &&
+ test_line_count = 2 git-wild\*star &&
+ test_line_count = 2 git-wild@at &&
+ test_line_count = 2 git-wild%percent
+ )
+'
+
+test_expect_success 'wildcard files submit back to p4, copy' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ cp file2 git-wild-cp#hash &&
+ git add git-wild-cp#hash &&
+ cp git-wild\*star file-wild-3 &&
+ git add file-wild-3 &&
+ git commit -m "wildcard copies" &&
+ git config git-p4.detectCopies true &&
+ git config git-p4.detectCopiesHarder true &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_file git-wild-cp#hash &&
+ test_path_is_file file-wild-3
+ )
+'
+
+test_expect_success 'wildcard files submit back to p4, rename' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git mv git-wild@at file-wild-4 &&
+ git mv file-wild-3 git-wild-cp%percent &&
+ git commit -m "wildcard renames" &&
+ git config git-p4.detectRenames true &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing git-wild@at &&
+ test_path_is_file git-wild-cp%percent
+ )
+'
+
+test_expect_success 'wildcard files submit back to p4, delete' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git rm git-wild* &&
+ git commit -m "delete the wildcard files" &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit
+ ) &&
+ (
+ cd "$cli" &&
+ test_path_is_missing git-wild#hash &&
+ test_path_is_missing git-wild\*star &&
+ test_path_is_missing git-wild@at &&
+ test_path_is_missing git-wild%percent
+ )
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='git p4 preserve users'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+test_expect_success 'create files' '
+ (
+ cd "$cli" &&
+ p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
+ echo file1 >file1 &&
+ echo file2 >file2 &&
+ p4 add file1 file2 &&
+ p4 submit -d "add files"
+ )
+'
+
+p4_add_user() {
+ name=$1 fullname=$2 &&
+ p4 user -f -i <<-EOF &&
+ User: $name
+ Email: $name@localhost
+ FullName: $fullname
+ EOF
+ p4 passwd -P secret $name
+}
+
+p4_grant_admin() {
+ name=$1 &&
+ {
+ p4 protect -o &&
+ echo " admin user $name * //depot/..."
+ } | p4 protect -i
+}
+
+p4_check_commit_author() {
+ file=$1 user=$2 &&
+ p4 changes -m 1 //depot/$file | grep -q $user
+}
+
+make_change_by_user() {
+ file=$1 name=$2 email=$3 &&
+ echo "username: a change by $name" >>"$file" &&
+ git add "$file" &&
+ git commit --author "$name <$email>" -m "a change by $name"
+}
+
+# Test username support, submitting as user 'alice'
+test_expect_success 'preserve users' '
+ p4_add_user alice Alice &&
+ p4_add_user bob Bob &&
+ p4_grant_admin alice &&
+ git p4 clone --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ echo "username: a change by alice" >>file1 &&
+ echo "username: a change by bob" >>file2 &&
+ git commit --author "Alice <alice@localhost>" -m "a change by alice" file1 &&
+ git commit --author "Bob <bob@localhost>" -m "a change by bob" file2 &&
+ git config git-p4.skipSubmitEditCheck true &&
+ P4EDITOR=touch P4USER=alice P4PASSWD=secret git p4 commit --preserve-user &&
+ p4_check_commit_author file1 alice &&
+ p4_check_commit_author file2 bob
+ )
+'
+
+# Test username support, submitting as bob, who lacks admin rights. Should
+# not submit change to p4 (git diff should show deltas).
+test_expect_success 'refuse to preserve users without perms' '
+ git p4 clone --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEditCheck true &&
+ echo "username-noperms: a change by alice" >>file1 &&
+ git commit --author "Alice <alice@localhost>" -m "perms: a change by alice" file1 &&
+ P4EDITOR=touch P4USER=bob P4PASSWD=secret &&
+ export P4EDITOR P4USER P4PASSWD &&
+ test_must_fail git p4 commit --preserve-user &&
+ ! git diff --exit-code HEAD..p4/master
+ )
+'
+
+# What happens with unknown author? Without allowMissingP4Users it should fail.
+test_expect_success 'preserve user where author is unknown to p4' '
+ git p4 clone --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEditCheck true &&
+ echo "username-bob: a change by bob" >>file1 &&
+ git commit --author "Bob <bob@localhost>" -m "preserve: a change by bob" file1 &&
+ echo "username-unknown: a change by charlie" >>file1 &&
+ git commit --author "Charlie <charlie@localhost>" -m "preserve: a change by charlie" file1 &&
+ P4EDITOR=touch P4USER=alice P4PASSWD=secret &&
+ export P4EDITOR P4USER P4PASSWD &&
+ test_must_fail git p4 commit --preserve-user &&
+ ! git diff --exit-code HEAD..p4/master &&
+
+ echo "$0: repeat with allowMissingP4Users enabled" &&
+ git config git-p4.allowMissingP4Users true &&
+ git config git-p4.preserveUser true &&
+ git p4 commit &&
+ git diff --exit-code HEAD..p4/master &&
+ p4_check_commit_author file1 alice
+ )
+'
+
+# If we're *not* using --preserve-user, git-p4 should warn if we're submitting
+# changes that are not all ours.
+# Test: user in p4 and user unknown to p4.
+# Test: warning disabled and user is the same.
+test_expect_success 'not preserving user with mixed authorship' '
+ git p4 clone --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEditCheck true &&
+ p4_add_user derek Derek &&
+
+ make_change_by_user usernamefile3 Derek derek@localhost &&
+ P4EDITOR=cat P4USER=alice P4PASSWD=secret &&
+ export P4EDITOR P4USER P4PASSWD &&
+ git p4 commit |\
+ grep "git author derek@localhost does not match" &&
+
+ make_change_by_user usernamefile3 Charlie charlie@localhost &&
+ git p4 commit |\
+ grep "git author charlie@localhost does not match" &&
+
+ make_change_by_user usernamefile3 alice alice@localhost &&
+ git p4 commit |\
+ test_must_fail grep "git author.*does not match" &&
+
+ git config git-p4.skipUserNameCheck true &&
+ make_change_by_user usernamefile3 Charlie charlie@localhost &&
+ git p4 commit |\
+ test_must_fail grep "git author.*does not match" &&
+
+ p4_check_commit_author usernamefile3 alice
+ )
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='git p4 rename'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+# We rely on this behavior to detect for p4 move availability.
+test_expect_success 'p4 help unknown returns 1' '
+ (
+ cd "$cli" &&
+ (
+ p4 help client >errs 2>&1
+ echo $? >retval
+ )
+ echo 0 >expected &&
+ test_cmp expected retval &&
+ rm retval &&
+ (
+ p4 help nosuchcommand >errs 2>&1
+ echo $? >retval
+ )
+ echo 1 >expected &&
+ test_cmp expected retval &&
+ rm retval
+ )
+'
+
+test_expect_success 'create files' '
+ (
+ cd "$cli" &&
+ p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
+ cat >file1 <<-EOF &&
+ A large block of text
+ in file1 that will generate
+ enough context so that rename
+ and copy detection will find
+ something interesting to do.
+ EOF
+ cat >file2 <<-EOF &&
+ /*
+ * This blob looks a bit
+ * different.
+ */
+ int main(int argc, char **argv)
+ {
+ char text[200];
+
+ strcpy(text, "copy/rename this");
+ printf("text is %s\n", text);
+ return 0;
+ }
+ EOF
+ p4 add file1 file2 &&
+ p4 submit -d "add files"
+ )
+'
+
+# Rename a file and confirm that rename is not detected in P4.
+# Rename the new file again with detectRenames option enabled and confirm that
+# this is detected in P4.
+# Rename the new file again adding an extra line, configure a big threshold in
+# detectRenames and confirm that rename is not detected in P4.
+# Repeat, this time with a smaller threshold and confirm that the rename is
+# detected in P4.
+test_expect_success 'detect renames' '
+ git p4 clone --dest="$git" //depot@all &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+
+ git mv file1 file4 &&
+ git commit -a -m "Rename file1 to file4" &&
+ git diff-tree -r -M HEAD &&
+ git p4 submit &&
+ p4 filelog //depot/file4 >filelog &&
+ ! grep " from //depot" filelog &&
+
+ git mv file4 file5 &&
+ git commit -a -m "Rename file4 to file5" &&
+ git diff-tree -r -M HEAD &&
+ git config git-p4.detectRenames true &&
+ git p4 submit &&
+ p4 filelog //depot/file5 >filelog &&
+ grep " from //depot/file4" filelog &&
+
+ git mv file5 file6 &&
+ echo update >>file6 &&
+ git add file6 &&
+ git commit -a -m "Rename file5 to file6 with changes" &&
+ git diff-tree -r -M HEAD &&
+ level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
+ test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
+ git config git-p4.detectRenames $(($level + 2)) &&
+ git p4 submit &&
+ p4 filelog //depot/file6 >filelog &&
+ ! grep " from //depot" filelog &&
+
+ git mv file6 file7 &&
+ echo update >>file7 &&
+ git add file7 &&
+ git commit -a -m "Rename file6 to file7 with changes" &&
+ git diff-tree -r -M HEAD &&
+ level=$(git diff-tree -r -M HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/R0*//") &&
+ test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
+ git config git-p4.detectRenames $(($level - 2)) &&
+ git p4 submit &&
+ p4 filelog //depot/file7 >filelog &&
+ grep " from //depot/file6" filelog
+ )
+'
+
+# Copy a file and confirm that copy is not detected in P4.
+# Copy a file with detectCopies option enabled and confirm that copy is not
+# detected in P4.
+# Modify and copy a file with detectCopies option enabled and confirm that copy
+# is detected in P4.
+# Copy a file with detectCopies and detectCopiesHarder options enabled and
+# confirm that copy is detected in P4.
+# Modify and copy a file, configure a bigger threshold in detectCopies and
+# confirm that copy is not detected in P4.
+# Modify and copy a file, configure a smaller threshold in detectCopies and
+# confirm that copy is detected in P4.
+test_expect_success 'detect copies' '
+ git p4 clone --dest="$git" //depot@all &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+
+ cp file2 file8 &&
+ git add file8 &&
+ git commit -a -m "Copy file2 to file8" &&
+ git diff-tree -r -C HEAD &&
+ git p4 submit &&
+ p4 filelog //depot/file8 &&
+ p4 filelog //depot/file8 | test_must_fail grep -q "branch from" &&
+
+ cp file2 file9 &&
+ git add file9 &&
+ git commit -a -m "Copy file2 to file9" &&
+ git diff-tree -r -C HEAD &&
+ git config git-p4.detectCopies true &&
+ git p4 submit &&
+ p4 filelog //depot/file9 &&
+ p4 filelog //depot/file9 | test_must_fail grep -q "branch from" &&
+
+ echo "file2" >>file2 &&
+ cp file2 file10 &&
+ git add file2 file10 &&
+ git commit -a -m "Modify and copy file2 to file10" &&
+ git diff-tree -r -C HEAD &&
+ git p4 submit &&
+ p4 filelog //depot/file10 &&
+ p4 filelog //depot/file10 | grep -q "branch from //depot/file" &&
+
+ cp file2 file11 &&
+ git add file11 &&
+ git commit -a -m "Copy file2 to file11" &&
+ git diff-tree -r -C --find-copies-harder HEAD &&
+ src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
+ test "$src" = file10 &&
+ git config git-p4.detectCopiesHarder true &&
+ git p4 submit &&
+ p4 filelog //depot/file11 &&
+ p4 filelog //depot/file11 | grep -q "branch from //depot/file" &&
+
+ cp file2 file12 &&
+ echo "some text" >>file12 &&
+ git add file12 &&
+ git commit -a -m "Copy file2 to file12 with changes" &&
+ git diff-tree -r -C --find-copies-harder HEAD &&
+ level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
+ test -n "$level" && test "$level" -gt 0 && test "$level" -lt 98 &&
+ src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
+ test "$src" = file10 -o "$src" = file11 &&
+ git config git-p4.detectCopies $(($level + 2)) &&
+ git p4 submit &&
+ p4 filelog //depot/file12 &&
+ p4 filelog //depot/file12 | test_must_fail grep -q "branch from" &&
+
+ cp file2 file13 &&
+ echo "different text" >>file13 &&
+ git add file13 &&
+ git commit -a -m "Copy file2 to file13 with changes" &&
+ git diff-tree -r -C --find-copies-harder HEAD &&
+ level=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f1 | cut -d" " -f5 | sed "s/C0*//") &&
+ test -n "$level" && test "$level" -gt 2 && test "$level" -lt 100 &&
+ src=$(git diff-tree -r -C --find-copies-harder HEAD | sed 1d | cut -f2) &&
+ test "$src" = file10 -o "$src" = file11 -o "$src" = file12 &&
+ git config git-p4.detectCopies $(($level - 2)) &&
+ git p4 submit &&
+ p4 filelog //depot/file13 &&
+ p4 filelog //depot/file13 | grep -q "branch from //depot/file"
+ )
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
# Copyright (c) 2012 Felipe Contreras
#
-if test -n "$BASH" && test -z "$POSIXLY_CORRECT"; then
- # we are in full-on bash mode
- true
-elif type bash >/dev/null 2>&1; then
- # execute in full-on bash mode
- unset POSIXLY_CORRECT
- exec bash "$0" "$@"
-else
- echo '1..0 #SKIP skipping bash completion tests; bash not available'
- exit 0
-fi
-
test_description='test bash completion'
-. ./test-lib.sh
+. ./lib-bash.sh
complete ()
{
local _cword
_words=( $1 )
(( _cword = ${#_words[@]} - 1 ))
- __git_wrap_main_git && print_comp
+ __git_wrap__git_main && print_comp
}
test_completion ()
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2012 SZEDER Gábor
+#
+
+test_description='test git-specific bash prompt functions'
+
+. ./lib-bash.sh
+
+. "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh"
+
+actual="$TRASH_DIRECTORY/actual"
+
+test_expect_success 'setup for prompt tests' '
+ mkdir -p subdir/subsubdir &&
+ git init otherrepo &&
+ echo 1 > file &&
+ git add file &&
+ test_tick &&
+ git commit -m initial &&
+ git tag -a -m msg1 t1 &&
+ git checkout -b b1 &&
+ echo 2 > file &&
+ git commit -m "second b1" file &&
+ echo 3 > file &&
+ git commit -m "third b1" file &&
+ git tag -a -m msg2 t2 &&
+ git checkout -b b2 master &&
+ echo 0 > file &&
+ git commit -m "second b2" file &&
+ git checkout master
+'
+
+test_expect_success 'gitdir - from command line (through $__git_dir)' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ (
+ __git_dir="$TRASH_DIRECTORY/otherrepo/.git" &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - repo as argument' '
+ echo "otherrepo/.git" > expected &&
+ __gitdir "otherrepo" > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - remote as argument' '
+ echo "remote" > expected &&
+ __gitdir "remote" > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - .git directory in cwd' '
+ echo ".git" > expected &&
+ __gitdir > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - .git directory in parent' '
+ echo "$TRASH_DIRECTORY/.git" > expected &&
+ (
+ cd subdir/subsubdir &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - cwd is a .git directory' '
+ echo "." > expected &&
+ (
+ cd .git &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - parent is a .git directory' '
+ echo "$TRASH_DIRECTORY/.git" > expected &&
+ (
+ cd .git/refs/heads &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - $GIT_DIR set while .git directory in cwd' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ (
+ GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" &&
+ export GIT_DIR &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - $GIT_DIR set while .git directory in parent' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ (
+ GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" &&
+ export GIT_DIR &&
+ cd subdir &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - non-existing $GIT_DIR' '
+ (
+ GIT_DIR="$TRASH_DIRECTORY/non-existing" &&
+ export GIT_DIR &&
+ test_must_fail __gitdir
+ )
+'
+
+test_expect_success 'gitdir - gitfile in cwd' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git &&
+ test_when_finished "rm -f subdir/.git" &&
+ (
+ cd subdir &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - gitfile in parent' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git &&
+ test_when_finished "rm -f subdir/.git" &&
+ (
+ cd subdir/subsubdir &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success SYMLINKS 'gitdir - resulting path avoids symlinks' '
+ echo "$TRASH_DIRECTORY/otherrepo/.git" > expected &&
+ mkdir otherrepo/dir &&
+ test_when_finished "rm -rf otherrepo/dir" &&
+ ln -s otherrepo/dir link &&
+ test_when_finished "rm -f link" &&
+ (
+ cd link &&
+ __gitdir > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'gitdir - not a git repository' '
+ (
+ cd subdir/subsubdir &&
+ GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY" &&
+ export GIT_CEILING_DIRECTORIES &&
+ test_must_fail __gitdir
+ )
+'
+
+test_expect_success 'prompt - branch name' '
+ printf " (master)" > expected &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - detached head' '
+ printf " ((%s...))" $(git log -1 --format="%h" b1^) > expected &&
+ git checkout b1^ &&
+ test_when_finished "git checkout master" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - describe detached head - contains' '
+ printf " ((t2~1))" > expected &&
+ git checkout b1^ &&
+ test_when_finished "git checkout master" &&
+ (
+ GIT_PS1_DESCRIBE_STYLE=contains &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - describe detached head - branch' '
+ printf " ((b1~1))" > expected &&
+ git checkout b1^ &&
+ test_when_finished "git checkout master" &&
+ (
+ GIT_PS1_DESCRIBE_STYLE=branch &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - describe detached head - describe' '
+ printf " ((t1-1-g%s))" $(git log -1 --format="%h" b1^) > expected &&
+ git checkout b1^ &&
+ test_when_finished "git checkout master" &&
+ (
+ GIT_PS1_DESCRIBE_STYLE=describe &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - describe detached head - default' '
+ printf " ((t2))" > expected &&
+ git checkout --detach b1 &&
+ test_when_finished "git checkout master" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - inside .git directory' '
+ printf " (GIT_DIR!)" > expected &&
+ (
+ cd .git &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - deep inside .git directory' '
+ printf " (GIT_DIR!)" > expected &&
+ (
+ cd .git/refs/heads &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - inside bare repository' '
+ printf " (BARE:master)" > expected &&
+ git init --bare bare.git &&
+ test_when_finished "rm -rf bare.git" &&
+ (
+ cd bare.git &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - interactive rebase' '
+ printf " (b1|REBASE-i)" > expected
+ echo "#!$SHELL_PATH" >fake_editor.sh &&
+ cat >>fake_editor.sh <<\EOF &&
+echo "edit $(git log -1 --format="%h")" > "$1"
+EOF
+ test_when_finished "rm -f fake_editor.sh" &&
+ chmod a+x fake_editor.sh &&
+ test_set_editor "$TRASH_DIRECTORY/fake_editor.sh" &&
+ git checkout b1 &&
+ test_when_finished "git checkout master" &&
+ git rebase -i HEAD^ &&
+ test_when_finished "git rebase --abort"
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - rebase merge' '
+ printf " (b2|REBASE-m)" > expected &&
+ git checkout b2 &&
+ test_when_finished "git checkout master" &&
+ test_must_fail git rebase --merge b1 b2 &&
+ test_when_finished "git rebase --abort" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - rebase' '
+ printf " ((t2)|REBASE)" > expected &&
+ git checkout b2 &&
+ test_when_finished "git checkout master" &&
+ test_must_fail git rebase b1 b2 &&
+ test_when_finished "git rebase --abort" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - merge' '
+ printf " (b1|MERGING)" > expected &&
+ git checkout b1 &&
+ test_when_finished "git checkout master" &&
+ test_must_fail git merge b2 &&
+ test_when_finished "git reset --hard" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - cherry-pick' '
+ printf " (master|CHERRY-PICKING)" > expected &&
+ test_must_fail git cherry-pick b1 &&
+ test_when_finished "git reset --hard" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - bisect' '
+ printf " (master|BISECTING)" > expected &&
+ git bisect start &&
+ test_when_finished "git bisect reset" &&
+ __git_ps1 > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - clean' '
+ printf " (master)" > expected &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - dirty worktree' '
+ printf " (master *)" > expected &&
+ echo "dirty" > file &&
+ test_when_finished "git reset --hard" &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - dirty index' '
+ printf " (master +)" > expected &&
+ echo "dirty" > file &&
+ test_when_finished "git reset --hard" &&
+ git add -u &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - dirty index and worktree' '
+ printf " (master *+)" > expected &&
+ echo "dirty index" > file &&
+ test_when_finished "git reset --hard" &&
+ git add -u &&
+ echo "dirty worktree" > file &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - before root commit' '
+ printf " (master #)" > expected &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ cd otherrepo &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - disabled by config' '
+ printf " (master)" > expected &&
+ echo "dirty" > file &&
+ test_when_finished "git reset --hard" &&
+ test_config bash.showDirtyState false &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - not shown inside .git directory' '
+ printf " (GIT_DIR!)" > expected &&
+ echo "dirty" > file &&
+ test_when_finished "git reset --hard" &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ cd .git &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - stash status indicator - no stash' '
+ printf " (master)" > expected &&
+ (
+ GIT_PS1_SHOWSTASHSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - stash status indicator - stash' '
+ printf " (master $)" > expected &&
+ echo 2 >file &&
+ git stash &&
+ test_when_finished "git stash drop" &&
+ (
+ GIT_PS1_SHOWSTASHSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - stash status indicator - not shown inside .git directory' '
+ printf " (GIT_DIR!)" > expected &&
+ echo 2 >file &&
+ git stash &&
+ test_when_finished "git stash drop" &&
+ (
+ GIT_PS1_SHOWSTASHSTATE=y &&
+ cd .git &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - untracked files status indicator - no untracked files' '
+ printf " (master)" > expected &&
+ (
+ GIT_PS1_SHOWUNTRACKEDFILES=y &&
+ cd otherrepo &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - untracked files status indicator - untracked files' '
+ printf " (master %%)" > expected &&
+ (
+ GIT_PS1_SHOWUNTRACKEDFILES=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - untracked files status indicator - not shown inside .git directory' '
+ printf " (GIT_DIR!)" > expected &&
+ (
+ GIT_PS1_SHOWUNTRACKEDFILES=y &&
+ cd .git &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - format string starting with dash' '
+ printf -- "-master" > expected &&
+ __git_ps1 "-%s" > "$actual" &&
+ test_cmp expected "$actual"
+'
+
+test_done
}
nul_to_q () {
- perl -pe 'y/\000/Q/'
+ "$PERL_PATH" -pe 'y/\000/Q/'
}
q_to_nul () {
- perl -pe 'y/Q/\000/'
+ "$PERL_PATH" -pe 'y/Q/\000/'
}
q_to_cr () {
# Both <file> and <contents> default to <message>.
test_commit () {
- file=${2:-"$1.t"}
+ notick= &&
+ if test "z$1" = "z--notick"
+ then
+ notick=yes
+ shift
+ fi &&
+ file=${2:-"$1.t"} &&
echo "${3-$1}" > "$file" &&
git add "$file" &&
- test_tick &&
+ if test -z "$notick"
+ then
+ test_tick
+ fi &&
git commit -m "$1" &&
git tag "$1"
}
. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
+export PERL_PATH
+
if test -z "$GIT_TEST_CMP"
then
if test -n "$GIT_TEST_CMP_USE_COPIED_CONTEXT"
+++ /dev/null
-#include "cache.h"
-#include "credential.h"
-#include "string-list.h"
-
-static const char usage_msg[] =
-"test-credential <fill|approve|reject> [helper...]";
-
-int main(int argc, const char **argv)
-{
- const char *op;
- struct credential c = CREDENTIAL_INIT;
- int i;
-
- op = argv[1];
- if (!op)
- usage(usage_msg);
- for (i = 2; i < argc; i++)
- string_list_append(&c.helpers, argv[i]);
-
- if (credential_read(&c, stdin) < 0)
- die("unable to read credential from stdin");
-
- if (!strcmp(op, "fill")) {
- credential_fill(&c);
- if (c.username)
- printf("username=%s\n", c.username);
- if (c.password)
- printf("password=%s\n", c.password);
- }
- else if (!strcmp(op, "approve"))
- credential_approve(&c);
- else if (!strcmp(op, "reject"))
- credential_reject(&c);
- else
- usage(usage_msg);
-
- return 0;
-}
die("input error");
if (ferror(stdout))
die("output error");
- buffer_reset(&stdin_buf);
return 0;
}
die_errno("cannot close preimage");
if (buffer_deinit(&delta))
die_errno("cannot close delta");
- buffer_reset(&preimage);
strbuf_release(&preimage_view.buf);
- buffer_reset(&delta);
return 0;
}
o->el = ⪙
}
+ if (o->dir) {
+ o->path_exclude_check = xmalloc(sizeof(struct path_exclude_check));
+ path_exclude_check_init(o->path_exclude_check, o->dir);
+ }
memset(&o->result, 0, sizeof(o->result));
o->result.initialized = 1;
o->result.timestamp.sec = o->src_index->timestamp.sec;
done:
free_excludes(&el);
+ if (o->path_exclude_check) {
+ path_exclude_check_clear(o->path_exclude_check);
+ free(o->path_exclude_check);
+ }
return ret;
return_failed:
* First let's make sure we do not have a local modification
* in that directory.
*/
- namelen = strlen(ce->name);
+ namelen = ce_namelen(ce);
for (i = locate_in_src_index(ce, o);
i < o->src_index->cache_nr;
i++) {
if (ignore_case && icase_exists(o, name, len, st))
return 0;
- if (o->dir && excluded(o->dir, name, &dtype))
+ if (o->dir &&
+ path_excluded(o->path_exclude_check, name, -1, &dtype))
/*
* ce->name is explicitly excluded, so it is Ok to
* overwrite it.
const char *prefix;
int cache_bottom;
struct dir_struct *dir;
+ struct path_exclude_check *path_exclude_check;
struct pathspec *pathspec;
merge_fn_t fn;
const char *msgs[NB_UNPACK_TREES_ERROR_TYPES];
#else
typedef char * iconv_ibp;
#endif
-char *reencode_string(const char *in, const char *out_encoding, const char *in_encoding)
+char *reencode_string_iconv(const char *in, size_t insz, iconv_t conv)
{
- iconv_t conv;
- size_t insz, outsz, outalloc;
+ size_t outsz, outalloc;
char *out, *outpos;
iconv_ibp cp;
- if (!in_encoding)
- return NULL;
- conv = iconv_open(out_encoding, in_encoding);
- if (conv == (iconv_t) -1)
- return NULL;
- insz = strlen(in);
outsz = insz;
outalloc = outsz + 1; /* for terminating NUL */
out = xmalloc(outalloc);
size_t sofar;
if (errno != E2BIG) {
free(out);
- iconv_close(conv);
return NULL;
}
/* insz has remaining number of bytes.
break;
}
}
+ return out;
+}
+
+char *reencode_string(const char *in, const char *out_encoding, const char *in_encoding)
+{
+ iconv_t conv;
+ char *out;
+
+ if (!in_encoding)
+ return NULL;
+ conv = iconv_open(out_encoding, in_encoding);
+ if (conv == (iconv_t) -1)
+ return NULL;
+ out = reencode_string_iconv(in, strlen(in), conv);
iconv_close(conv);
return out;
}
int indent, int indent2, int width);
#ifndef NO_ICONV
+char *reencode_string_iconv(const char *in, size_t insz, iconv_t conv);
char *reencode_string(const char *in, const char *out_encoding, const char *in_encoding);
#else
#define reencode_string(a,b,c) NULL
die_errno("error closing fast-import feedback stream");
}
-void fast_export_reset(void)
-{
- buffer_reset(&report_buffer);
-}
-
void fast_export_delete(const char *path)
{
putchar('D');
if (ends_with(header, headerlen, " missing"))
return error("cat-blob reports missing blob: %s", header);
- type = memmem(header, headerlen, " blob ", strlen(" blob "));
+ type = strstr(header, " blob ");
if (!type)
return error("cat-blob header has wrong object type: %s", header);
n = strtoumax(type + strlen(" blob "), (char **) &end, 10);
}
/* Mode. */
- if (response_end - response < strlen("100644") ||
+ if (response_end - response < (signed) strlen("100644") ||
response[strlen("100644")] != ' ')
die("invalid ls response: missing mode: %s", response);
*mode = 0;
}
/* ' blob ' or ' tree ' */
- if (response_end - response < strlen(" blob ") ||
+ if (response_end - response < (signed) strlen(" blob ") ||
(response[1] != 'b' && response[1] != 't'))
die("unexpected ls response: not a tree or blob: %s", response);
response += strlen(" blob ");
void fast_export_init(int fd);
void fast_export_deinit(void);
-void fast_export_reset(void);
void fast_export_delete(const char *path);
void fast_export_modify(const char *path, uint32_t mode, const char *dataref);
}
return done;
}
-
-void buffer_reset(struct line_buffer *buf)
-{
-}
int buffer_init(struct line_buffer *buf, const char *filename);
int buffer_fdinit(struct line_buffer *buf, int fd);
int buffer_deinit(struct line_buffer *buf);
-void buffer_reset(struct line_buffer *buf);
int buffer_tmpfile_init(struct line_buffer *buf);
FILE *buffer_tmpfile_rewind(struct line_buffer *buf); /* prepare to write. */
return -1;
if (off < view->off || off + width < view->off + view->width)
return error("invalid delta: window slides left");
- if (view->max_off >= 0 && view->max_off < off + width)
+ if (view->max_off >= 0 && view->max_off < off + (off_t) width)
return error("delta preimage ends early");
file_offset = view->off + view->buf.len;
static int read_chunk(struct line_buffer *delta, off_t *delta_len,
struct strbuf *buf, size_t len)
{
+ assert(*delta_len >= 0);
strbuf_reset(buf);
- if (len > *delta_len ||
+ if (len > (uintmax_t) *delta_len ||
buffer_read_binary(delta, buf, len) != len)
return error_short_read(delta);
*delta_len -= buf->len;
static int apply_one_window(struct line_buffer *delta, off_t *delta_len,
struct sliding_view *preimage, FILE *out)
{
+ int rv = -1;
struct window ctx = WINDOW_INIT(preimage);
size_t out_len;
size_t instructions_len;
if (apply_window_in_core(&ctx))
goto error_out;
if (ctx.out.len != out_len) {
- error("invalid delta: incorrect postimage length");
+ rv = error("invalid delta: incorrect postimage length");
goto error_out;
}
if (write_strbuf(&ctx.out, out))
goto error_out;
- window_release(&ctx);
- return 0;
+ rv = 0;
error_out:
window_release(&ctx);
- return -1;
+ return rv;
}
int svndiff0_apply(struct line_buffer *delta, off_t delta_len,
struct sliding_view *preimage, FILE *postimage)
{
- assert(delta && preimage && postimage);
+ assert(delta && preimage && postimage && delta_len >= 0);
if (read_magic(delta, &delta_len))
return -1;
while (delta_len) { /* For each window: */
- off_t pre_off = pre_off; /* stupid GCC... */
+ off_t pre_off = -1;
size_t pre_len;
if (read_offset(delta, &pre_off, &delta_len) ||
#define NODE_CTX 2 /* node metadata */
#define INTERNODE_CTX 3 /* between nodes */
-#define LENGTH_UNKNOWN (~0)
#define DATE_RFC2822_LEN 31
static struct line_buffer input = LINE_BUFFER_INIT;
static struct {
- uint32_t action, propLength, srcRev, type;
- off_t text_length;
+ uint32_t action, srcRev, type;
+ off_t prop_length, text_length;
struct strbuf src, dst;
uint32_t text_delta, prop_delta;
} node_ctx;
{
node_ctx.type = 0;
node_ctx.action = NODEACT_UNKNOWN;
- node_ctx.propLength = LENGTH_UNKNOWN;
+ node_ctx.prop_length = -1;
node_ctx.text_length = -1;
strbuf_reset(&node_ctx.src);
node_ctx.srcRev = 0;
static void handle_node(void)
{
const uint32_t type = node_ctx.type;
- const int have_props = node_ctx.propLength != LENGTH_UNKNOWN;
+ const int have_props = node_ctx.prop_length != -1;
const int have_text = node_ctx.text_length != -1;
/*
* Old text for this node:
if (have_props) {
if (!node_ctx.prop_delta)
node_ctx.type = type;
- if (node_ctx.propLength)
+ if (node_ctx.prop_length)
read_props();
}
reset_rev_ctx(atoi(val));
break;
case sizeof("Node-path"):
- if (prefixcmp(t, "Node-"))
+ if (constcmp(t, "Node-"))
continue;
if (!constcmp(t + strlen("Node-"), "path")) {
if (active_ctx == NODE_CTX)
node_ctx.srcRev = atoi(val);
break;
case sizeof("Text-content-length"):
- if (!constcmp(t, "Text-content-length")) {
+ if (constcmp(t, "Text") && constcmp(t, "Prop"))
+ continue;
+ if (constcmp(t + 4, "-content-length"))
+ continue;
+ {
char *end;
- uintmax_t textlen;
+ uintmax_t len;
- textlen = strtoumax(val, &end, 10);
+ len = strtoumax(val, &end, 10);
if (!isdigit(*val) || *end)
die("invalid dump: non-numeric length %s", val);
- if (textlen > maximum_signed_value_of_type(off_t))
+ if (len > maximum_signed_value_of_type(off_t))
die("unrepresentable length in dump: %s", val);
- node_ctx.text_length = (off_t) textlen;
+
+ if (*t == 'T')
+ node_ctx.text_length = (off_t) len;
+ else
+ node_ctx.prop_length = (off_t) len;
break;
}
- if (constcmp(t, "Prop-content-length"))
- continue;
- node_ctx.propLength = atoi(val);
- break;
case sizeof("Text-delta"):
if (!constcmp(t, "Text-delta")) {
node_ctx.text_delta = !strcmp(val, "true");
void svndump_reset(void)
{
- fast_export_reset();
- buffer_reset(&input);
strbuf_release(&dump_ctx.uuid);
strbuf_release(&dump_ctx.url);
strbuf_release(&rev_ctx.log);
--- /dev/null
+#include "git-compat-util.h"
+#include "version.h"
+
+const char git_version_string[] = GIT_VERSION;
+
+const char *git_user_agent(void)
+{
+ static const char *agent = NULL;
+
+ if (!agent) {
+ agent = getenv("GIT_USER_AGENT");
+ if (!agent)
+ agent = GIT_USER_AGENT;
+ }
+
+ return agent;
+}
--- /dev/null
+#ifndef VERSION_H
+#define VERSION_H
+
+extern const char git_version_string[];
+
+const char *git_user_agent(void);
+
+#endif /* VERSION_H */