Message cleanup.
* ah/misc-message-fixes:
unpack-trees: do not capitalize "working"
git-merge-octopus: do not capitalize "octopus"
git-rebase--interactive: fix English grammar
cat-file: put spaces around pipes in usage string
am: put spaces around pipe in usage string
--- /dev/null
+Git 2.11 Release Notes
+======================
+
+Updates since v2.10
+-------------------
+
+UI, Workflows & Features
+
+ * "git format-patch --cover-letter HEAD^" to format a single patch
+ with a separate cover letter now numbers the output as [PATCH 0/1]
+ and [PATCH 1/1] by default.
+
+ * An incoming "git push" that attempts to push too many bytes can now
+ be rejected by setting a new configuration variable at the receiving
+ end.
+
+ * "git nosuchcommand --help" said "No manual entry for gitnosuchcommand",
+ which was not intuitive, given that "git nosuchcommand" said "git:
+ 'nosuchcommand' is not a git command".
+
+ * "git clone --resurse-submodules --reference $path $URL" is a way to
+ reduce network transfer cost by borrowing objects in an existing
+ $path repository when cloning the superproject from $URL; it
+ learned to also peek into $path for presense of corresponding
+ repositories of submodules and borrow objects from there when able.
+
+ * The "git diff --submodule={short,log}" mechanism has been enhanced
+ to allow "--submodule=diff" to show the patch between the submodule
+ commits bound to the superproject.
+
+
+Performance, Internal Implementation, Development Support etc.
+
+ * The delta-base-cache mechanism has been a key to the performance in
+ a repository with a tightly packed packfile, but it did not scale
+ well even with a larger value of core.deltaBaseCacheLimit.
+
+ * Enhance "git status --porcelain" output by collecting more data on
+ the state of the index and the working tree files, which may
+ further be used to teach git-prompt (in contrib/) to make fewer
+ calls to git.
+
+ * Extract a small helper out of the function that reads the authors
+ script file "git am" internally uses.
+ (merge a77598e jc/am-read-author-file later to maint).
+
+
+Also contains various documentation updates and code clean-ups.
+
+
+Fixes since v2.10
+-----------------
+
+Unless otherwise noted, all the fixes since v2.9 in the maintenance
+track are contained in this release (see the maintenance releases'
+notes for details).
+
+ * Clarify various ways to specify the "revision ranges" in the
+ documentation.
+ (merge a117be4 po/range-doc later to maint).
+
+ * "diff-highlight" script (in contrib/) learned to work better with
+ "git log -p --graph" output.
+ (merge 3dbfe2b bh/diff-highlight-graph later to maint).
+
+ * The test framework left the number of tests and success/failure
+ count in the t/test-results directory, keyed by the name of the
+ test script plus the process ID. The latter however turned out not
+ to serve any useful purpose. The process ID part of the filename
+ has been removed.
+ (merge 5c885c1 jk/test-lib-drop-pid-from-results later to maint).
+
+ * Having a submodule whose ".git" repository is somehow corrupt
+ caused a few commands that recurse into submodules loop forever.
+ (merge 10f5c52 jc/submodule-anchor-git-dir later to maint).
+
+ * "git symbolic-ref -d HEAD" happily removes the symbolic ref, but
+ the resulting repository becomes an invalid one. Teach the command
+ to forbid removal of HEAD.
+ (merge 12cfa79 jc/forbid-symbolic-ref-d-HEAD later to maint).
+
+ * A test spawned a short-lived background process, which sometimes
+ prevented the test directory from getting removed at the end of the
+ script on some platforms.
+ (merge 5babb5b js/t6026-clean-up later to maint).
+
+ * Update a few tests that used to use GIT_CURL_VERBOSE to use the
+ newer GIT_TRACE_CURL.
+ (merge 14e2411 ep/use-git-trace-curl-in-tests later to maint).
+
+ * Other minor doc, test and build updates and code cleanups.
+ (merge 3e1952e jk/squelch-false-warning-from-gcc-o3 later to maint).
+ (merge ca2baa3 rs/compat-strdup later to maint).
+ (merge d233097 rs/hex2chr later to maint).
+ (merge c00bfc9 js/t9903-chaining later to maint).
+ (merge 5e4e5bb sb/xdiff-remove-unused-static-decl later to maint).
+ (merge 5cb5fe4 sb/transport-report-missing-submodule-on-stderr later to maint).
--- /dev/null
+Git v2.9.4 Release Notes
+========================
+
+Fixes since v2.9.3
+------------------
+
+ * There are certain house-keeping tasks that need to be performed at
+ the very beginning of any Git program, and programs that are not
+ built-in commands had to do them exactly the same way as "git"
+ potty does. It was easy to make mistakes in one-off standalone
+ programs (like test helpers). A common "main()" function that
+ calls cmd_main() of individual program has been introduced to
+ make it harder to make mistakes.
+
+ * "git merge" with renormalization did not work well with
+ merge-recursive, due to "safer crlf" conversion kicking in when it
+ shouldn't.
+
+ * The reflog output format is documented better, and a new format
+ --date=unix to report the seconds-since-epoch (without timezone)
+ has been added.
+
+ * "git push --force-with-lease" already had enough logic to allow
+ ensuring that such a push results in creation of a ref (i.e. the
+ receiving end did not have another push from sideways that would be
+ discarded by our force-pushing), but didn't expose this possibility
+ to the users. It does so now.
+
+ * "import-tars" fast-import script (in contrib/) used to ignore a
+ hardlink target and replaced it with an empty file, which has been
+ corrected to record the same blob as the other file the hardlink is
+ shared with.
+
+ * "git mv dir non-existing-dir/" did not work in some environments
+ the same way as existing mainstream platforms. The code now moves
+ "dir" to "non-existing-dir", without relying on rename("A", "B/")
+ that strips the trailing slash of '/'.
+
+ * The "t/" hierarchy is prone to get an unusual pathname; "make test"
+ has been taught to make sure they do not contain paths that cannot
+ be checked out on Windows (and the mechanism can be reusable to
+ catch pathnames that are not portable to other platforms as need
+ arises).
+
+ * When "git merge-recursive" works on history with many criss-cross
+ merges in "verbose" mode, the names the command assigns to the
+ virtual merge bases could have overwritten each other by unintended
+ reuse of the same piece of memory.
+
+ * "git checkout --detach <branch>" used to give the same advice
+ message as that is issued when "git checkout <tag>" (or anything
+ that is not a branch name) is given, but asking with "--detach" is
+ an explicit enough sign that the user knows what is going on. The
+ advice message has been squelched in this case.
+
+ * "git difftool" by default ignores the error exit from the backend
+ commands it spawns, because often they signal that they found
+ differences by exiting with a non-zero status code just like "diff"
+ does; the exit status codes 126 and above however are special in
+ that they are used to signal that the command is not executable,
+ does not exist, or killed by a signal. "git difftool" has been
+ taught to notice these exit status codes.
+
+ * On Windows, help.browser configuration variable used to be ignored,
+ which has been corrected.
+
+ * The "git -c var[=val] cmd" facility to append a configuration
+ variable definition at the end of the search order was described in
+ git(1) manual page, but not in git-config(1), which was more likely
+ place for people to look for when they ask "can I make a one-shot
+ override, and if so how?"
+
+ * The tempfile (hence its user lockfile) API lets the caller to open
+ a file descriptor to a temporary file, write into it and then
+ finalize it by first closing the filehandle and then either
+ removing or renaming the temporary file. When the process spawns a
+ subprocess after obtaining the file descriptor, and if the
+ subprocess has not exited when the attempt to remove or rename is
+ made, the last step fails on Windows, because the subprocess has
+ the file descriptor still open. Open tempfile with O_CLOEXEC flag
+ to avoid this (on Windows, this is mapped to O_NOINHERIT).
+
+Also contains minor documentation updates and code clean-ups.
archive, summarize the relevant points of the discussion.
If you want to reference a previous commit in the history of a stable
-branch use the format "abbreviated sha1 (subject, date)". So for example
-like this: "Commit f86a374 (pack-bitmap.c: fix a memleak, 2015-03-30)
-noticed [...]".
+branch, use the format "abbreviated sha1 (subject, date)",
+with the subject enclosed in a pair of double-quotes, like this:
+
+ Commit f86a374 ("pack-bitmap.c: fix a memleak", 2015-03-30)
+ noticed that ...
+
+The "Copy commit summary" command of gitk can be used to obtain this
+format.
(3) Generate your patch using Git tools out of your commits.
especially on slow filesystems. If not set, the value of
`transfer.unpackLimit` is used instead.
+receive.maxInputSize::
+ If the size of the incoming pack stream is larger than this
+ limit, then git-receive-pack will error out, instead of
+ accepting the pack file. If not set or set to 0, then the size
+ is unlimited.
+
receive.denyDeletes::
If set to true, git-receive-pack will deny a ref update that deletes
the ref. Use this to prevent such a ref deletion via a push.
in parallel. A value of 0 will give some reasonable default.
If unset, it defaults to 1.
+submodule.alternateLocation::
+ Specifies how the submodules obtain alternates when submodules are
+ cloned. Possible values are `no`, `superproject`.
+ By default `no` is assumed, which doesn't add references. When the
+ value is set to `superproject` the submodule to be cloned computes
+ its alternates location relative to the superprojects alternate.
+
+submodule.alternateErrorStrategy
+ Specifies how to treat errors with the alternates for a submodule
+ as computed via `submodule.alternateLocation`. Possible values are
+ `ignore`, `info`, `die`. Default is `die`.
+
tag.forceSignAnnotated::
A boolean to specify whether annotated tags created should be GPG signed.
If `--annotate` is specified on the command line, it takes
diff.submodule::
Specify the format in which differences in submodules are
- shown. The "log" format lists the commits in the range like
- linkgit:git-submodule[1] `summary` does. The "short" format
- format just shows the names of the commits at the beginning
- and end of the range. Defaults to short.
+ shown. The "short" format just shows the names of the commits
+ at the beginning and end of the range. The "log" format lists
+ the commits in the range like linkgit:git-submodule[1] `summary`
+ does. The "diff" format shows an inline diff of the changed
+ contents of the submodule. Defaults to "short".
diff.wordRegex::
A POSIX Extended Regular Expression used to determine what is a "word"
of the `--diff-filter` option on what the status letters mean.
--submodule[=<format>]::
- Specify how differences in submodules are shown. When `--submodule`
- or `--submodule=log` is given, the 'log' format is used. This format lists
- the commits in the range like linkgit:git-submodule[1] `summary` does.
- Omitting the `--submodule` option or specifying `--submodule=short`,
- uses the 'short' format. This format just shows the names of the commits
- at the beginning and end of the range. Can be tweaked via the
- `diff.submodule` configuration variable.
+ Specify how differences in submodules are shown. When specifying
+ `--submodule=short` the 'short' format is used. This format just
+ shows the names of the commits at the beginning and end of the range.
+ When `--submodule` or `--submodule=log` is specified, the 'log'
+ format is used. This format lists the commits in the range like
+ linkgit:git-submodule[1] `summary` does. When `--submodule=diff`
+ is specified, the 'diff' format is used. This format shows an
+ inline diff of the changes in the submodule contents between the
+ commit range. Defaults to `diff.submodule` or the 'short' format
+ if the config option is unset.
--color[=<when>]::
Show colored diff.
--no-prefix::
Do not show any source or destination prefix.
+--line-prefix=<prefix>::
+ Prepend an additional prefix to every line of output.
+
For more detailed explanation on these common options, see also
linkgit:gitdiffcore[7].
its source repository, you can simply run `git repack -a` to copy all
objects from the source repository into a pack in the cloned repository.
---reference <repository>::
+--reference[-if-able] <repository>::
If the reference repository is on the local machine,
automatically setup `.git/objects/info/alternates` to
obtain objects from the reference repository. Using
an already existing repository as an alternate will
require fewer objects to be copied from the repository
being cloned, reducing network and local storage costs.
+ When using the `--reference-if-able`, a non existing
+ directory is skipped with a warning instead of aborting
+ the clone.
+
*NOTE*: see the NOTE for the `--shared` option, and also the
`--dissociate` option.
Specifying 0 will cause Git to auto-detect the number of CPU's
and use maximum 3 threads.
+--max-input-size=<size>::
+ Die, if the pack is larger than <size>.
Note
----
option, which tells it if updates to a ref should be denied if they
are not fast-forwards.
+A number of other receive.* config options are available to tweak
+its behavior, see linkgit:git-config[1].
+
OPTIONS
-------
<directory>::
--branch::
Show the branch and tracking info even in short-format.
---porcelain::
+--porcelain[=<version>]::
Give the output in an easy-to-parse format for scripts.
This is similar to the short output, but will remain stable
across Git versions and regardless of user configuration. See
below for details.
++
+The version parameter is used to specify the format version.
+This is optional and defaults to the original version 'v1' format.
--long::
Give the output in the long-format. This is the default.
-z::
Terminate entries with NUL, instead of LF. This implies
- the `--porcelain` output format if no other format is given.
+ the `--porcelain=v1` output format if no other format is given.
--column[=<options>]::
--no-column::
If -b is used the short-format status is preceded by a line
-## branchname tracking info
+ ## branchname tracking info
-Porcelain Format
-~~~~~~~~~~~~~~~~
+Porcelain Format Version 1
+~~~~~~~~~~~~~~~~~~~~~~~~~~
-The porcelain format is similar to the short format, but is guaranteed
+Version 1 porcelain format is similar to the short format, but is guaranteed
not to change in a backwards-incompatible way between Git versions or
based on user configuration. This makes it ideal for parsing by scripts.
The description of the short format above also describes the porcelain
characters are not specially formatted; no quoting or
backslash-escaping is performed.
+Porcelain Format Version 2
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Version 2 format adds more detailed information about the state of
+the worktree and changed items. Version 2 also defines an extensible
+set of easy to parse optional headers.
+
+Header lines start with "#" and are added in response to specific
+command line arguments. Parsers should ignore headers they
+don't recognize.
+
+### Branch Headers
+
+If `--branch` is given, a series of header lines are printed with
+information about the current branch.
+
+ Line Notes
+ ------------------------------------------------------------
+ # branch.oid <commit> | (initial) Current commit.
+ # branch.head <branch> | (detached) Current branch.
+ # branch.upstream <upstream_branch> If upstream is set.
+ # branch.ab +<ahead> -<behind> If upstream is set and
+ the commit is present.
+ ------------------------------------------------------------
+
+### Changed Tracked Entries
+
+Following the headers, a series of lines are printed for tracked
+entries. One of three different line formats may be used to describe
+an entry depending on the type of change. Tracked entries are printed
+in an undefined order; parsers should allow for a mixture of the 3
+line types in any order.
+
+Ordinary changed entries have the following format:
+
+ 1 <XY> <sub> <mH> <mI> <mW> <hH> <hI> <path>
+
+Renamed or copied entries have the following format:
+
+ 2 <XY> <sub> <mH> <mI> <mW> <hH> <hI> <X><score> <path><sep><origPath>
+
+ Field Meaning
+ --------------------------------------------------------
+ <XY> A 2 character field containing the staged and
+ unstaged XY values described in the short format,
+ with unchanged indicated by a "." rather than
+ a space.
+ <sub> A 4 character field describing the submodule state.
+ "N..." when the entry is not a submodule.
+ "S<c><m><u>" when the entry is a submodule.
+ <c> is "C" if the commit changed; otherwise ".".
+ <m> is "M" if it has tracked changes; otherwise ".".
+ <u> is "U" if there are untracked changes; otherwise ".".
+ <mH> The octal file mode in HEAD.
+ <mI> The octal file mode in the index.
+ <mW> The octal file mode in the worktree.
+ <hH> The object name in HEAD.
+ <hI> The object name in the index.
+ <X><score> The rename or copy score (denoting the percentage
+ of similarity between the source and target of the
+ move or copy). For example "R100" or "C75".
+ <path> The pathname. In a renamed/copied entry, this
+ is the path in the index and in the working tree.
+ <sep> When the `-z` option is used, the 2 pathnames are separated
+ with a NUL (ASCII 0x00) byte; otherwise, a tab (ASCII 0x09)
+ byte separates them.
+ <origPath> The pathname in the commit at HEAD. This is only
+ present in a renamed/copied entry, and tells
+ where the renamed/copied contents came from.
+ --------------------------------------------------------
+
+Unmerged entries have the following format; the first character is
+a "u" to distinguish from ordinary changed entries.
+
+ u <xy> <sub> <m1> <m2> <m3> <mW> <h1> <h2> <h3> <path>
+
+ Field Meaning
+ --------------------------------------------------------
+ <XY> A 2 character field describing the conflict type
+ as described in the short format.
+ <sub> A 4 character field describing the submodule state
+ as described above.
+ <m1> The octal file mode in stage 1.
+ <m2> The octal file mode in stage 2.
+ <m3> The octal file mode in stage 3.
+ <mW> The octal file mode in the worktree.
+ <h1> The object name in stage 1.
+ <h2> The object name in stage 2.
+ <h3> The object name in stage 3.
+ <path> The pathname.
+ --------------------------------------------------------
+
+### Other Items
+
+Following the tracked entries (and if requested), a series of
+lines will be printed for untracked and then ignored items
+found in the worktree.
+
+Untracked items have the following format:
+
+ ? <path>
+
+Ignored items have the following format:
+
+ ! <path>
+
+### Pathname Format Notes and -z
+
+When the `-z` option is given, pathnames are printed as is and
+without any quoting and lines are terminated with a NUL (ASCII 0x00)
+byte.
+
+Otherwise, all pathnames will be "C-quoted" if they contain any tab,
+linefeed, double quote, or backslash characters. In C-quoting, these
+characters will be replaced with the corresponding C-style escape
+sequences and the resulting pathname will be double quoted.
+
+
CONFIGURATION
-------------
--strict::
Don't write objects with broken content or links.
+--max-input-size=<size>::
+ Die, if the pack is larger than <size>.
+
GIT
---
Part of the linkgit:git[1] suite
--left-right::
- Mark which side of a symmetric diff a commit is reachable
+ Mark which side of a symmetric difference a commit is reachable
from. Commits from the left side are prefixed with a `<`
symbol and those from the right with a `>` symbol.
Many Git commands take revision parameters as arguments. Depending on
the command, they denote a specific commit or, for commands which
-walk the revision graph (such as linkgit:git-log[1]), all commits which can
-be reached from that commit. In the latter case one can also specify a
-range of revisions explicitly.
+walk the revision graph (such as linkgit:git-log[1]), all commits which are
+reachable from that commit. For commands that walk the revision graph one can
+also specify a range of revisions explicitly.
In addition, some Git commands (such as linkgit:git-show[1]) also take
revision parameters which denote other objects than commits, e.g. blobs
respecting the `auto` settings of the former if we are going to a
terminal). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring
on the next placeholders until the color is switched again.
-- '%m': left, right or boundary mark
+- '%m': left (`<`), right (`>`) or boundary (`-`) mark
- '%n': newline
- '%%': a raw '%'
- '%x00': print a byte from a hex code
--left-only::
--right-only::
- List only commits on the respective side of a symmetric range,
+ List only commits on the respective side of a symmetric difference,
i.e. only those which would be marked `<` resp. `>` by
`--left-right`.
+
endif::git-rev-list[]
--left-right::
- Mark which side of a symmetric diff a commit is reachable from.
+ Mark which side of a symmetric difference a commit is reachable from.
Commits from the left side are prefixed with `<` and those from
the right with `>`. If combined with `--boundary`, those
commits are prefixed with `-`.
-----------------
History traversing commands such as `git log` operate on a set
-of commits, not just a single commit. To these commands,
-specifying a single revision with the notation described in the
-previous section means the set of commits reachable from that
-commit, following the commit ancestry chain.
-
-To exclude commits reachable from a commit, a prefix '{caret}'
-notation is used. E.g. '{caret}r1 r2' means commits reachable
-from 'r2' but exclude the ones reachable from 'r1'.
-
-This set operation appears so often that there is a shorthand
-for it. When you have two commits 'r1' and 'r2' (named according
-to the syntax explained in SPECIFYING REVISIONS above), you can ask
-for commits that are reachable from r2 excluding those that are reachable
-from r1 by '{caret}r1 r2' and it can be written as 'r1..r2'.
-
-A similar notation 'r1\...r2' is called symmetric difference
-of 'r1' and 'r2' and is defined as
-'r1 r2 --not $(git merge-base --all r1 r2)'.
-It is the set of commits that are reachable from either one of
-'r1' or 'r2' but not from both.
-
-In these two shorthands, you can omit one end and let it default to HEAD.
+of commits, not just a single commit.
+
+For these commands,
+specifying a single revision, using the notation described in the
+previous section, means the set of commits `reachable` from the given
+commit.
+
+A commit's reachable set is the commit itself and the commits in
+its ancestry chain.
+
+
+Commit Exclusions
+~~~~~~~~~~~~~~~~~
+
+'{caret}<rev>' (caret) Notation::
+ To exclude commits reachable from a commit, a prefix '{caret}'
+ notation is used. E.g. '{caret}r1 r2' means commits reachable
+ from 'r2' but exclude the ones reachable from 'r1' (i.e. 'r1' and
+ its ancestors).
+
+Dotted Range Notations
+~~~~~~~~~~~~~~~~~~~~~~
+
+The '..' (two-dot) Range Notation::
+ The '{caret}r1 r2' set operation appears so often that there is a shorthand
+ for it. When you have two commits 'r1' and 'r2' (named according
+ to the syntax explained in SPECIFYING REVISIONS above), you can ask
+ for commits that are reachable from r2 excluding those that are reachable
+ from r1 by '{caret}r1 r2' and it can be written as 'r1..r2'.
+
+The '...' (three dot) Symmetric Difference Notation::
+ A similar notation 'r1\...r2' is called symmetric difference
+ of 'r1' and 'r2' and is defined as
+ 'r1 r2 --not $(git merge-base --all r1 r2)'.
+ It is the set of commits that are reachable from either one of
+ 'r1' (left side) or 'r2' (right side) but not from both.
+
+In these two shorthand notations, you can omit one end and let it default to HEAD.
For example, 'origin..' is a shorthand for 'origin..HEAD' and asks "What
did I do since I forked from the origin branch?" Similarly, '..origin'
is a shorthand for 'HEAD..origin' and asks "What did the origin do since
I forked from them?" Note that '..' would mean 'HEAD..HEAD' which is an
empty range that is both reachable and unreachable from HEAD.
-Two other shorthands for naming a set that is formed by a commit
-and its parent commits exist. The 'r1{caret}@' notation means all
-parents of 'r1'. 'r1{caret}!' includes commit 'r1' but excludes
-all of its parents.
+Other <rev>{caret} Parent Shorthand Notations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Two other shorthands exist, particularly useful for merge commits,
+for naming a set that is formed by a commit and its parent commits.
+
+The 'r1{caret}@' notation means all parents of 'r1'.
+
+The 'r1{caret}!' notation includes commit 'r1' but excludes all of its parents.
+By itself, this notation denotes the single commit 'r1'.
+
+While '<rev>{caret}<n>' was about specifying a single commit parent, these
+two notations consider all its parents. For example you can say
+'HEAD{caret}2{caret}@', however you cannot say 'HEAD{caret}@{caret}2'.
-To summarize:
+Revision Range Summary
+----------------------
'<rev>'::
- Include commits that are reachable from (i.e. ancestors of)
- <rev>.
+ Include commits that are reachable from <rev> (i.e. <rev> and its
+ ancestors).
'{caret}<rev>'::
- Exclude commits that are reachable from (i.e. ancestors of)
- <rev>.
+ Exclude commits that are reachable from <rev> (i.e. <rev> and its
+ ancestors).
'<rev1>..<rev2>'::
Include commits that are reachable from <rev2> but exclude
as giving commit '<rev>' and then all its parents prefixed with
'{caret}' to exclude them (and their ancestors).
-Here are a handful of examples:
-
- D G H D
- D F G H I J D F
- ^G D H D
- ^D B E I J F B
- B..C C
- B...C G H D E B C
- ^D B C E I J F B C
- C I J F C
- C^@ I J F
- C^! C
- F^! D G H D F
+Here are a handful of examples using the Loeliger illustration above,
+with each step in the notation's expansion and selection carefully
+spelt out:
+
+ Args Expanded arguments Selected commits
+ D G H D
+ D F G H I J D F
+ ^G D H D
+ ^D B E I J F B
+ ^D B C E I J F B C
+ C I J F C
+ B..C = ^B C C
+ B...C = B ^F C G H D E B C
+ C^@ = C^1
+ = F I J F
+ B^@ = B^1 B^2 B^3
+ = D E F D G H E F I J
+ C^! = C ^C^@
+ = C ^C^1
+ = C ^F C
+ B^! = B ^B^@
+ = B ^B^1 ^B^2 ^B^3
+ = B ^D ^E ^F B
+ F^! D = F ^I ^J D G H D F
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v2.10.0
+DEF_VER=v2.10.0.GIT
LF='
'
# Define USE_NED_ALLOCATOR if you want to replace the platforms default
# memory allocators with the nedmalloc allocator written by Niall Douglas.
#
+# Define OVERRIDE_STRDUP to override the libc version of strdup(3).
+# This is necessary when using a custom allocator in order to avoid
+# crashes due to allocation and free working on different 'heaps'.
+# It's defined automatically if USE_NED_ALLOCATOR is set.
+#
# Define NO_REGEX if you have no or inferior regex support in your C library.
#
# Define HAVE_DEV_TTY if your system can open /dev/tty to interact with the
endif
ifdef USE_NED_ALLOCATOR
- COMPAT_CFLAGS += -Icompat/nedmalloc
- COMPAT_OBJS += compat/nedmalloc/nedmalloc.o
+ COMPAT_CFLAGS += -Icompat/nedmalloc
+ COMPAT_OBJS += compat/nedmalloc/nedmalloc.o
+ OVERRIDE_STRDUP = YesPlease
+endif
+
+ifdef OVERRIDE_STRDUP
+ COMPAT_CFLAGS += -DOVERRIDE_STRDUP
+ COMPAT_OBJS += compat/strdup.o
endif
ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
ifdef USE_NED_ALLOCATOR
compat/nedmalloc/nedmalloc.sp compat/nedmalloc/nedmalloc.o: EXTRA_CPPFLAGS = \
- -DNDEBUG -DOVERRIDE_STRDUP -DREPLACE_SYSTEM_ALLOCATOR
+ -DNDEBUG -DREPLACE_SYSTEM_ALLOCATOR
compat/nedmalloc/nedmalloc.sp: SPARSE_FLAGS += -Wno-non-pointer-null
endif
-Documentation/RelNotes/2.10.0.txt
\ No newline at end of file
+Documentation/RelNotes/2.11.0.txt
\ No newline at end of file
#include "rerere.h"
#include "prompt.h"
#include "mailinfo.h"
+#include "string-list.h"
/**
* Returns 1 if the file is empty or does not exist, 0 otherwise.
}
/**
- * Reads a KEY=VALUE shell variable assignment from `fp`, returning the VALUE
- * as a newly-allocated string. VALUE must be a quoted string, and the KEY must
- * match `key`. Returns NULL on failure.
- *
- * This is used by read_author_script() to read the GIT_AUTHOR_* variables from
- * the author-script.
+ * Take a series of KEY='VALUE' lines where VALUE part is
+ * sq-quoted, and append <KEY, VALUE> at the end of the string list
*/
-static char *read_shell_var(FILE *fp, const char *key)
+static int parse_key_value_squoted(char *buf, struct string_list *list)
{
- struct strbuf sb = STRBUF_INIT;
- const char *str;
-
- if (strbuf_getline_lf(&sb, fp))
- goto fail;
-
- if (!skip_prefix(sb.buf, key, &str))
- goto fail;
-
- if (!skip_prefix(str, "=", &str))
- goto fail;
-
- strbuf_remove(&sb, 0, str - sb.buf);
-
- str = sq_dequote(sb.buf);
- if (!str)
- goto fail;
-
- return strbuf_detach(&sb, NULL);
-
-fail:
- strbuf_release(&sb);
- return NULL;
+ while (*buf) {
+ struct string_list_item *item;
+ char *np;
+ char *cp = strchr(buf, '=');
+ if (!cp)
+ return -1;
+ np = strchrnul(cp, '\n');
+ *cp++ = '\0';
+ item = string_list_append(list, buf);
+
+ buf = np + (*np == '\n');
+ *np = '\0';
+ cp = sq_dequote(cp);
+ if (!cp)
+ return -1;
+ item->util = xstrdup(cp);
+ }
+ return 0;
}
/**
static int read_author_script(struct am_state *state)
{
const char *filename = am_path(state, "author-script");
- FILE *fp;
+ struct strbuf buf = STRBUF_INIT;
+ struct string_list kv = STRING_LIST_INIT_DUP;
+ int retval = -1; /* assume failure */
+ int fd;
assert(!state->author_name);
assert(!state->author_email);
assert(!state->author_date);
- fp = fopen(filename, "r");
- if (!fp) {
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
if (errno == ENOENT)
return 0;
die_errno(_("could not open '%s' for reading"), filename);
}
+ strbuf_read(&buf, fd, 0);
+ close(fd);
+ if (parse_key_value_squoted(buf.buf, &kv))
+ goto finish;
- state->author_name = read_shell_var(fp, "GIT_AUTHOR_NAME");
- if (!state->author_name) {
- fclose(fp);
- return -1;
- }
-
- state->author_email = read_shell_var(fp, "GIT_AUTHOR_EMAIL");
- if (!state->author_email) {
- fclose(fp);
- return -1;
- }
-
- state->author_date = read_shell_var(fp, "GIT_AUTHOR_DATE");
- if (!state->author_date) {
- fclose(fp);
- return -1;
- }
-
- if (fgetc(fp) != EOF) {
- fclose(fp);
- return -1;
- }
-
- fclose(fp);
- return 0;
+ if (kv.nr != 3 ||
+ strcmp(kv.items[0].string, "GIT_AUTHOR_NAME") ||
+ strcmp(kv.items[1].string, "GIT_AUTHOR_EMAIL") ||
+ strcmp(kv.items[2].string, "GIT_AUTHOR_DATE"))
+ goto finish;
+ state->author_name = kv.items[0].util;
+ state->author_email = kv.items[1].util;
+ state->author_date = kv.items[2].util;
+ retval = 0;
+finish:
+ string_list_clear(&kv, !!retval);
+ strbuf_release(&buf);
+ return retval;
}
/**
static int option_progress = -1;
static enum transport_family family;
static struct string_list option_config = STRING_LIST_INIT_NODUP;
-static struct string_list option_reference = STRING_LIST_INIT_NODUP;
+static struct string_list option_required_reference = STRING_LIST_INIT_NODUP;
+static struct string_list option_optional_reference = STRING_LIST_INIT_NODUP;
static int option_dissociate;
static int max_jobs = -1;
N_("number of submodules cloned in parallel")),
OPT_STRING(0, "template", &option_template, N_("template-directory"),
N_("directory from which templates will be used")),
- OPT_STRING_LIST(0, "reference", &option_reference, N_("repo"),
+ OPT_STRING_LIST(0, "reference", &option_required_reference, N_("repo"),
N_("reference repository")),
+ OPT_STRING_LIST(0, "reference-if-able", &option_optional_reference,
+ N_("repo"), N_("reference repository")),
OPT_BOOL(0, "dissociate", &option_dissociate,
N_("use --reference only while cloning")),
OPT_STRING('o', "origin", &option_origin, N_("name"),
static int add_one_reference(struct string_list_item *item, void *cb_data)
{
- char *ref_git;
- const char *repo;
- struct strbuf alternate = STRBUF_INIT;
-
- /* Beware: read_gitfile(), real_path() and mkpath() return static buffer */
- ref_git = xstrdup(real_path(item->string));
-
- repo = read_gitfile(ref_git);
- if (!repo)
- repo = read_gitfile(mkpath("%s/.git", ref_git));
- if (repo) {
- free(ref_git);
- ref_git = xstrdup(repo);
- }
+ struct strbuf err = STRBUF_INIT;
+ int *required = cb_data;
+ char *ref_git = compute_alternate_path(item->string, &err);
- if (!repo && is_directory(mkpath("%s/.git/objects", ref_git))) {
- char *ref_git_git = mkpathdup("%s/.git", ref_git);
- free(ref_git);
- ref_git = ref_git_git;
- } else if (!is_directory(mkpath("%s/objects", ref_git))) {
+ if (!ref_git) {
+ if (*required)
+ die("%s", err.buf);
+ else
+ fprintf(stderr,
+ _("info: Could not add alternate for '%s': %s\n"),
+ item->string, err.buf);
+ } else {
struct strbuf sb = STRBUF_INIT;
- if (get_common_dir(&sb, ref_git))
- die(_("reference repository '%s' as a linked checkout is not supported yet."),
- item->string);
- die(_("reference repository '%s' is not a local repository."),
- item->string);
+ strbuf_addf(&sb, "%s/objects", ref_git);
+ add_to_alternates_file(sb.buf);
+ strbuf_release(&sb);
}
- if (!access(mkpath("%s/shallow", ref_git), F_OK))
- die(_("reference repository '%s' is shallow"), item->string);
-
- if (!access(mkpath("%s/info/grafts", ref_git), F_OK))
- die(_("reference repository '%s' is grafted"), item->string);
-
- strbuf_addf(&alternate, "%s/objects", ref_git);
- add_to_alternates_file(alternate.buf);
- strbuf_release(&alternate);
+ strbuf_release(&err);
free(ref_git);
return 0;
}
static void setup_reference(void)
{
- for_each_string_list(&option_reference, add_one_reference, NULL);
+ int required = 1;
+ for_each_string_list(&option_required_reference,
+ add_one_reference, &required);
+ required = 0;
+ for_each_string_list(&option_optional_reference,
+ add_one_reference, &required);
}
static void copy_alternates(struct strbuf *src, struct strbuf *dst,
else
fprintf(stderr, _("Cloning into '%s'...\n"), dir);
}
+
+ if (option_recursive) {
+ if (option_required_reference.nr &&
+ option_optional_reference.nr)
+ die(_("clone --recursive is not compatible with "
+ "both --reference and --reference-if-able"));
+ else if (option_required_reference.nr) {
+ string_list_append(&option_config,
+ "submodule.alternateLocation=superproject");
+ string_list_append(&option_config,
+ "submodule.alternateErrorStrategy=die");
+ } else if (option_optional_reference.nr) {
+ string_list_append(&option_config,
+ "submodule.alternateLocation=superproject");
+ string_list_append(&option_config,
+ "submodule.alternateErrorStrategy=info");
+ }
+ }
+
init_db(option_template, INIT_DB_QUIET);
write_config(&option_config);
git_config_set(key.buf, repo);
strbuf_reset(&key);
- if (option_reference.nr)
+ if (option_required_reference.nr || option_optional_reference.nr)
setup_reference();
fetch_pattern = value.buf;
static const char *only_include_assumed;
static struct strbuf message = STRBUF_INIT;
-static enum status_format {
- STATUS_FORMAT_NONE = 0,
- STATUS_FORMAT_LONG,
- STATUS_FORMAT_SHORT,
- STATUS_FORMAT_PORCELAIN,
+static enum wt_status_format status_format = STATUS_FORMAT_UNSPECIFIED;
- STATUS_FORMAT_UNSPECIFIED
-} status_format = STATUS_FORMAT_UNSPECIFIED;
+static int opt_parse_porcelain(const struct option *opt, const char *arg, int unset)
+{
+ enum wt_status_format *value = (enum wt_status_format *)opt->value;
+ if (unset)
+ *value = STATUS_FORMAT_NONE;
+ else if (!arg)
+ *value = STATUS_FORMAT_PORCELAIN;
+ else if (!strcmp(arg, "v1") || !strcmp(arg, "1"))
+ *value = STATUS_FORMAT_PORCELAIN;
+ else if (!strcmp(arg, "v2") || !strcmp(arg, "2"))
+ *value = STATUS_FORMAT_PORCELAIN_V2;
+ else
+ die("unsupported porcelain version '%s'", arg);
+
+ return 0;
+}
static int opt_parse_m(const struct option *opt, const char *arg, int unset)
{
s->fp = fp;
s->nowarn = nowarn;
s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0;
+ if (!s->is_initial)
+ hashcpy(s->sha1_commit, sha1);
+ s->status_format = status_format;
+ s->ignore_submodule_arg = ignore_submodule_arg;
wt_status_collect(s);
-
- switch (status_format) {
- case STATUS_FORMAT_SHORT:
- wt_shortstatus_print(s);
- break;
- case STATUS_FORMAT_PORCELAIN:
- wt_porcelain_print(s);
- break;
- case STATUS_FORMAT_UNSPECIFIED:
- die("BUG: finalize_deferred_config() should have been called");
- break;
- case STATUS_FORMAT_NONE:
- case STATUS_FORMAT_LONG:
- wt_status_print(s);
- break;
- }
+ wt_status_print(s);
return s->commitable;
}
* is not in effect here.
*/
static struct status_deferred_config {
- enum status_format status_format;
+ enum wt_status_format status_format;
int show_branch;
} status_deferred_config = {
STATUS_FORMAT_UNSPECIFIED,
static void finalize_deferred_config(struct wt_status *s)
{
int use_deferred_config = (status_format != STATUS_FORMAT_PORCELAIN &&
+ status_format != STATUS_FORMAT_PORCELAIN_V2 &&
!s->null_termination);
if (s->null_termination) {
N_("show status concisely"), STATUS_FORMAT_SHORT),
OPT_BOOL('b', "branch", &s.show_branch,
N_("show branch information")),
- OPT_SET_INT(0, "porcelain", &status_format,
- N_("machine-readable output"),
- STATUS_FORMAT_PORCELAIN),
+ { OPTION_CALLBACK, 0, "porcelain", &status_format,
+ N_("version"), N_("machine-readable output"),
+ PARSE_OPT_OPTARG, opt_parse_porcelain },
OPT_SET_INT(0, "long", &status_format,
N_("show status in long format (default)"),
STATUS_FORMAT_LONG),
fd = hold_locked_index(&index_lock, 0);
s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
+ if (!s.is_initial)
+ hashcpy(s.sha1_commit, sha1);
+
s.ignore_submodule_arg = ignore_submodule_arg;
+ s.status_format = status_format;
+ s.verbose = verbose;
+
wt_status_collect(&s);
if (0 <= fd)
if (s.relative_paths)
s.prefix = prefix;
- switch (status_format) {
- case STATUS_FORMAT_SHORT:
- wt_shortstatus_print(&s);
- break;
- case STATUS_FORMAT_PORCELAIN:
- wt_porcelain_print(&s);
- break;
- case STATUS_FORMAT_UNSPECIFIED:
- die("BUG: finalize_deferred_config() should have been called");
- break;
- case STATUS_FORMAT_NONE:
- case STATUS_FORMAT_LONG:
- s.verbose = verbose;
- s.ignore_submodule_arg = ignore_submodule_arg;
- wt_status_print(&s);
- break;
- }
+ wt_status_print(&s);
return 0;
}
static int show_guides = 0;
static unsigned int colopts;
static enum help_format help_format = HELP_FORMAT_NONE;
+static int exclude_guides;
static struct option builtin_help_options[] = {
OPT_BOOL('a', "all", &show_all, N_("print all available commands")),
+ OPT_HIDDEN_BOOL(0, "exclude-guides", &exclude_guides, N_("exclude guides")),
OPT_BOOL('g', "guides", &show_guides, N_("print list of useful guides")),
OPT_SET_INT('m', "man", &help_format, N_("show man page"), HELP_FORMAT_MAN),
OPT_SET_INT('w', "web", &help_format, N_("show manual in web browser"),
putchar('\n');
}
+static const char *check_git_cmd(const char* cmd)
+{
+ char *alias;
+
+ if (is_git_command(cmd))
+ return cmd;
+
+ alias = alias_lookup(cmd);
+ if (alias) {
+ printf_ln(_("`git %s' is aliased to `%s'"), cmd, alias);
+ free(alias);
+ exit(0);
+ }
+
+ if (exclude_guides)
+ return help_unknown_cmd(cmd);
+
+ return cmd;
+}
+
int cmd_help(int argc, const char **argv, const char *prefix)
{
int nongit;
- char *alias;
enum help_format parsed_help_format;
argc = parse_options(argc, argv, prefix, builtin_help_options,
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])) {
- printf_ln(_("`git %s' is aliased to `%s'"), argv[0], alias);
- free(alias);
- return 0;
- }
+ argv[0] = check_git_cmd(argv[0]);
switch (help_format) {
case HELP_FORMAT_NONE:
static unsigned char input_buffer[4096];
static unsigned int input_offset, input_len;
static off_t consumed_bytes;
+static off_t max_input_size;
static unsigned deepest_delta;
static git_SHA_CTX input_ctx;
static uint32_t input_crc32;
if (signed_add_overflows(consumed_bytes, bytes))
die(_("pack too large for current definition of off_t"));
consumed_bytes += bytes;
+ if (max_input_size && consumed_bytes > max_input_size)
+ die(_("pack exceeds maximum allowed size"));
}
static const char *open_pack_file(const char *pack_name)
opts.off32_limit = strtoul(c+1, &c, 0);
if (*c || opts.off32_limit & 0x80000000)
die(_("bad %s"), arg);
+ } else if (skip_prefix(arg, "--max-input-size=", &arg)) {
+ max_input_size = strtoumax(arg, NULL, 10);
} else
usage(index_pack_usage);
continue;
/* nothing to do */
return 0;
total = nr;
- if (!keep_subject && auto_number && total > 1)
- numbered = 1;
- if (numbered)
- rev.total = total + start_number - 1;
if (cover_letter == -1) {
if (config_cover_letter == COVER_AUTO)
cover_letter = (total > 1);
else
cover_letter = (config_cover_letter == COVER_ON);
}
+ if (!keep_subject && auto_number && (total > 1 || cover_letter))
+ numbered = 1;
+ if (numbered)
+ rev.total = total + start_number - 1;
if (!signature) {
; /* --no-signature inhibits all signatures */
#define ll_find_deltas(l, s, w, d, p) find_deltas(l, &s, w, d, p)
#endif
+static void add_tag_chain(const struct object_id *oid)
+{
+ struct tag *tag;
+
+ /*
+ * We catch duplicates already in add_object_entry(), but we'd
+ * prefer to do this extra check to avoid having to parse the
+ * tag at all if we already know that it's being packed (e.g., if
+ * it was included via bitmaps, we would not have parsed it
+ * previously).
+ */
+ if (packlist_find(&to_pack, oid->hash, NULL))
+ return;
+
+ tag = lookup_tag(oid->hash);
+ while (1) {
+ if (!tag || parse_tag(tag) || !tag->tagged)
+ die("unable to pack objects reachable from tag %s",
+ oid_to_hex(oid));
+
+ add_object_entry(tag->object.oid.hash, OBJ_TAG, NULL, 0);
+
+ if (tag->tagged->type != OBJ_TAG)
+ return;
+
+ tag = (struct tag *)tag->tagged;
+ }
+}
+
static int add_ref_tag(const char *path, const struct object_id *oid, int flag, void *cb_data)
{
struct object_id peeled;
if (starts_with(path, "refs/tags/") && /* is a tag? */
!peel_ref(path, peeled.hash) && /* peelable? */
packlist_find(&to_pack, peeled.hash, NULL)) /* object packed? */
- add_object_entry(oid->hash, OBJ_TAG, NULL, 0);
+ add_tag_chain(oid);
return 0;
}
static int advertise_atomic_push = 1;
static int advertise_push_options;
static int unpack_limit = 100;
+static off_t max_input_size;
static int report_status;
static int use_sideband;
static int use_atomic;
return 0;
}
+ if (strcmp(var, "receive.maxinputsize") == 0) {
+ max_input_size = git_config_int64(var, value);
+ return 0;
+ }
+
return git_default_config(var, value, cb);
}
if (fsck_objects)
argv_array_pushf(&child.args, "--strict%s",
fsck_msg_types.buf);
+ if (max_input_size)
+ argv_array_pushf(&child.args, "--max-input-size=%"PRIuMAX,
+ (uintmax_t)max_input_size);
child.no_stdout = 1;
child.err = err_fd;
child.git_cmd = 1;
fsck_msg_types.buf);
if (!reject_thin)
argv_array_push(&child.args, "--fix-thin");
+ if (max_input_size)
+ argv_array_pushf(&child.args, "--max-input-size=%"PRIuMAX,
+ (uintmax_t)max_input_size);
child.out = -1;
child.err = err_fd;
child.git_cmd = 1;
ctx.fmt = revs->commit_format;
ctx.output_encoding = get_log_output_encoding();
pretty_print_commit(&ctx, commit, &buf);
- if (revs->graph) {
- if (buf.len) {
- if (revs->commit_format != CMIT_FMT_ONELINE)
- graph_show_oneline(revs->graph);
-
- graph_show_commit_msg(revs->graph, &buf);
-
- /*
- * Add a newline after the commit message.
- *
- * Usually, this newline produces a blank
- * padding line between entries, in which case
- * we need to add graph padding on this line.
- *
- * However, the commit message may not end in a
- * newline. In this case the newline simply
- * ends the last line of the commit message,
- * and we don't need any graph output. (This
- * always happens with CMIT_FMT_ONELINE, and it
- * happens with CMIT_FMT_USERFORMAT when the
- * format doesn't explicitly end in a newline.)
- */
- if (buf.len && buf.buf[buf.len - 1] == '\n')
- graph_show_padding(revs->graph);
- putchar('\n');
- } else {
- /*
- * If the message buffer is empty, just show
- * the rest of the graph output for this
- * commit.
- */
- if (graph_show_remainder(revs->graph))
- putchar('\n');
- if (revs->commit_format == CMIT_FMT_ONELINE)
- putchar('\n');
- }
+ if (buf.len) {
+ if (revs->commit_format != CMIT_FMT_ONELINE)
+ graph_show_oneline(revs->graph);
+
+ graph_show_commit_msg(revs->graph, stdout, &buf);
+
+ /*
+ * Add a newline after the commit message.
+ *
+ * Usually, this newline produces a blank
+ * padding line between entries, in which case
+ * we need to add graph padding on this line.
+ *
+ * However, the commit message may not end in a
+ * newline. In this case the newline simply
+ * ends the last line of the commit message,
+ * and we don't need any graph output. (This
+ * always happens with CMIT_FMT_ONELINE, and it
+ * happens with CMIT_FMT_USERFORMAT when the
+ * format doesn't explicitly end in a newline.)
+ */
+ if (buf.len && buf.buf[buf.len - 1] == '\n')
+ graph_show_padding(revs->graph);
+ putchar('\n');
} else {
- if (revs->commit_format != CMIT_FMT_USERFORMAT ||
- buf.len) {
- fwrite(buf.buf, 1, buf.len, stdout);
- putchar(info->hdr_termination);
- }
+ /*
+ * If the message buffer is empty, just show
+ * the rest of the graph output for this
+ * commit.
+ */
+ if (graph_show_remainder(revs->graph))
+ putchar('\n');
+ if (revs->commit_format == CMIT_FMT_ONELINE)
+ putchar('\n');
}
strbuf_release(&buf);
} else {
}
static int clone_submodule(const char *path, const char *gitdir, const char *url,
- const char *depth, const char *reference, int quiet)
+ const char *depth, struct string_list *reference, int quiet)
{
struct child_process cp = CHILD_PROCESS_INIT;
argv_array_push(&cp.args, "--quiet");
if (depth && *depth)
argv_array_pushl(&cp.args, "--depth", depth, NULL);
- if (reference && *reference)
- argv_array_pushl(&cp.args, "--reference", reference, NULL);
+ if (reference->nr) {
+ struct string_list_item *item;
+ for_each_string_list_item(item, reference)
+ argv_array_pushl(&cp.args, "--reference",
+ item->string, NULL);
+ }
if (gitdir && *gitdir)
argv_array_pushl(&cp.args, "--separate-git-dir", gitdir, NULL);
return run_command(&cp);
}
+struct submodule_alternate_setup {
+ const char *submodule_name;
+ enum SUBMODULE_ALTERNATE_ERROR_MODE {
+ SUBMODULE_ALTERNATE_ERROR_DIE,
+ SUBMODULE_ALTERNATE_ERROR_INFO,
+ SUBMODULE_ALTERNATE_ERROR_IGNORE
+ } error_mode;
+ struct string_list *reference;
+};
+#define SUBMODULE_ALTERNATE_SETUP_INIT { NULL, \
+ SUBMODULE_ALTERNATE_ERROR_IGNORE, NULL }
+
+static int add_possible_reference_from_superproject(
+ struct alternate_object_database *alt, void *sas_cb)
+{
+ struct submodule_alternate_setup *sas = sas_cb;
+
+ /* directory name, minus trailing slash */
+ size_t namelen = alt->name - alt->base - 1;
+ struct strbuf name = STRBUF_INIT;
+ strbuf_add(&name, alt->base, namelen);
+
+ /*
+ * If the alternate object store is another repository, try the
+ * standard layout with .git/modules/<name>/objects
+ */
+ if (ends_with(name.buf, ".git/objects")) {
+ char *sm_alternate;
+ struct strbuf sb = STRBUF_INIT;
+ struct strbuf err = STRBUF_INIT;
+ strbuf_add(&sb, name.buf, name.len - strlen("objects"));
+ /*
+ * We need to end the new path with '/' to mark it as a dir,
+ * otherwise a submodule name containing '/' will be broken
+ * as the last part of a missing submodule reference would
+ * be taken as a file name.
+ */
+ strbuf_addf(&sb, "modules/%s/", sas->submodule_name);
+
+ sm_alternate = compute_alternate_path(sb.buf, &err);
+ if (sm_alternate) {
+ string_list_append(sas->reference, xstrdup(sb.buf));
+ free(sm_alternate);
+ } else {
+ switch (sas->error_mode) {
+ case SUBMODULE_ALTERNATE_ERROR_DIE:
+ die(_("submodule '%s' cannot add alternate: %s"),
+ sas->submodule_name, err.buf);
+ case SUBMODULE_ALTERNATE_ERROR_INFO:
+ fprintf(stderr, _("submodule '%s' cannot add alternate: %s"),
+ sas->submodule_name, err.buf);
+ case SUBMODULE_ALTERNATE_ERROR_IGNORE:
+ ; /* nothing */
+ }
+ }
+ strbuf_release(&sb);
+ }
+
+ strbuf_release(&name);
+ return 0;
+}
+
+static void prepare_possible_alternates(const char *sm_name,
+ struct string_list *reference)
+{
+ char *sm_alternate = NULL, *error_strategy = NULL;
+ struct submodule_alternate_setup sas = SUBMODULE_ALTERNATE_SETUP_INIT;
+
+ git_config_get_string("submodule.alternateLocation", &sm_alternate);
+ if (!sm_alternate)
+ return;
+
+ git_config_get_string("submodule.alternateErrorStrategy", &error_strategy);
+
+ if (!error_strategy)
+ error_strategy = xstrdup("die");
+
+ sas.submodule_name = sm_name;
+ sas.reference = reference;
+ if (!strcmp(error_strategy, "die"))
+ sas.error_mode = SUBMODULE_ALTERNATE_ERROR_DIE;
+ else if (!strcmp(error_strategy, "info"))
+ sas.error_mode = SUBMODULE_ALTERNATE_ERROR_INFO;
+ else if (!strcmp(error_strategy, "ignore"))
+ sas.error_mode = SUBMODULE_ALTERNATE_ERROR_IGNORE;
+ else
+ die(_("Value '%s' for submodule.alternateErrorStrategy is not recognized"), error_strategy);
+
+ if (!strcmp(sm_alternate, "superproject"))
+ foreach_alt_odb(add_possible_reference_from_superproject, &sas);
+ else if (!strcmp(sm_alternate, "no"))
+ ; /* do nothing */
+ else
+ die(_("Value '%s' for submodule.alternateLocation is not recognized"), sm_alternate);
+
+ free(sm_alternate);
+ free(error_strategy);
+}
+
static int module_clone(int argc, const char **argv, const char *prefix)
{
- const char *name = NULL, *url = NULL;
- const char *reference = NULL, *depth = NULL;
+ const char *name = NULL, *url = NULL, *depth = NULL;
int quiet = 0;
FILE *submodule_dot_git;
char *p, *path = NULL, *sm_gitdir;
struct strbuf rel_path = STRBUF_INIT;
struct strbuf sb = STRBUF_INIT;
+ struct string_list reference = STRING_LIST_INIT_NODUP;
struct option module_clone_options[] = {
OPT_STRING(0, "prefix", &prefix,
OPT_STRING(0, "url", &url,
N_("string"),
N_("url where to clone the submodule from")),
- OPT_STRING(0, "reference", &reference,
- N_("string"),
+ OPT_STRING_LIST(0, "reference", &reference,
+ N_("repo"),
N_("reference repository")),
OPT_STRING(0, "depth", &depth,
N_("string"),
if (!file_exists(sm_gitdir)) {
if (safe_create_leading_directories_const(sm_gitdir) < 0)
die(_("could not create directory '%s'"), sm_gitdir);
- if (clone_submodule(path, sm_gitdir, url, depth, reference, quiet))
+
+ prepare_possible_alternates(name, &reference);
+
+ if (clone_submodule(path, sm_gitdir, url, depth, &reference, quiet))
die(_("clone of '%s' into submodule path '%s' failed"),
url, path);
} else {
/* configuration parameters which are passed on to the children */
int quiet;
int recommend_shallow;
- const char *reference;
+ struct string_list references;
const char *depth;
const char *recursive_prefix;
const char *prefix;
int failed_clones_nr, failed_clones_alloc;
};
#define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
- SUBMODULE_UPDATE_STRATEGY_INIT, 0, -1, NULL, NULL, NULL, NULL, \
+ SUBMODULE_UPDATE_STRATEGY_INIT, 0, -1, STRING_LIST_INIT_DUP, \
+ NULL, NULL, NULL, \
STRING_LIST_INIT_DUP, 0, NULL, 0, 0}
argv_array_pushl(&child->args, "--path", sub->path, NULL);
argv_array_pushl(&child->args, "--name", sub->name, NULL);
argv_array_pushl(&child->args, "--url", url, NULL);
- if (suc->reference)
- argv_array_push(&child->args, suc->reference);
+ if (suc->references.nr) {
+ struct string_list_item *item;
+ for_each_string_list_item(item, &suc->references)
+ argv_array_pushl(&child->args, "--reference", item->string, NULL);
+ }
if (suc->depth)
argv_array_push(&child->args, suc->depth);
OPT_STRING(0, "update", &update,
N_("string"),
N_("rebase, merge, checkout or none")),
- OPT_STRING(0, "reference", &suc.reference, N_("repo"),
+ OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"),
N_("reference repository")),
OPT_STRING(0, "depth", &suc.depth, "<depth>",
N_("Create a shallow clone truncated to the "
ret = check_symref(argv[0], 1, 0, 0);
if (ret)
die("Cannot delete %s, not a symbolic ref", argv[0]);
+ if (!strcmp(argv[0], "HEAD"))
+ die("deleting '%s' is not allowed", argv[0]);
return delete_ref(argv[0], NULL, REF_NODEREF);
}
static unsigned char buffer[4096];
static unsigned int offset, len;
static off_t consumed_bytes;
+static off_t max_input_size;
static git_SHA_CTX ctx;
static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
if (signed_add_overflows(consumed_bytes, bytes))
die("pack too large for current definition of off_t");
consumed_bytes += bytes;
+ if (max_input_size && consumed_bytes > max_input_size)
+ die(_("pack exceeds maximum allowed size"));
}
static void *get_data(unsigned long size)
len = sizeof(*hdr);
continue;
}
+ if (skip_prefix(arg, "--max-input-size=", &arg)) {
+ max_input_size = strtoumax(arg, NULL, 10);
+ continue;
+ }
usage(unpack_usage);
}
__attribute__((format (printf, 2, 3)));
extern char *git_path_buf(struct strbuf *buf, const char *fmt, ...)
__attribute__((format (printf, 2, 3)));
-extern void strbuf_git_path_submodule(struct strbuf *sb, const char *path,
- const char *fmt, ...)
+extern int strbuf_git_path_submodule(struct strbuf *sb, const char *path,
+ const char *fmt, ...)
__attribute__((format (printf, 3, 4)));
extern char *git_pathdup(const char *fmt, ...)
__attribute__((format (printf, 1, 2)));
#define EMPTY_TREE_SHA1_BIN_LITERAL \
"\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
"\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04"
-#define EMPTY_TREE_SHA1_BIN \
- ((const unsigned char *) EMPTY_TREE_SHA1_BIN_LITERAL)
+extern const struct object_id empty_tree_oid;
+#define EMPTY_TREE_SHA1_BIN (empty_tree_oid.hash)
#define EMPTY_BLOB_SHA1_HEX \
"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
#define EMPTY_BLOB_SHA1_BIN_LITERAL \
"\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \
"\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91"
-#define EMPTY_BLOB_SHA1_BIN \
- ((const unsigned char *) EMPTY_BLOB_SHA1_BIN_LITERAL)
+extern const struct object_id empty_blob_oid;
+#define EMPTY_BLOB_SHA1_BIN (empty_blob_oid.hash)
+
static inline int is_empty_blob_sha1(const unsigned char *sha1)
{
return !hashcmp(sha1, EMPTY_BLOB_SHA1_BIN);
}
+static inline int is_empty_blob_oid(const struct object_id *oid)
+{
+ return !hashcmp(oid->hash, EMPTY_BLOB_SHA1_BIN);
+}
+
+static inline int is_empty_tree_sha1(const unsigned char *sha1)
+{
+ return !hashcmp(sha1, EMPTY_TREE_SHA1_BIN);
+}
+
+static inline int is_empty_tree_oid(const struct object_id *oid)
+{
+ return !hashcmp(oid->hash, EMPTY_TREE_SHA1_BIN);
+}
+
+
int git_mkstemp(char *path, size_t n, const char *template);
/* set default permissions by passing mode arguments to open(2) */
return hexval_table[c];
}
+/*
+ * Convert two consecutive hexadecimal digits into a char. Return a
+ * negative value on error. Don't run over the end of short strings.
+ */
+static inline int hex2chr(const char *s)
+{
+ int val = hexval(s[0]);
+ return (val < 0) ? val : (val << 4) | hexval(s[1]);
+}
+
/* Convert to/from hex/sha1 representation */
#define MINIMUM_ABBREV minimum_abbrev
#define DEFAULT_ABBREV default_abbrev
} *alt_odb_list;
extern void prepare_alt_odb(void);
extern void read_info_alternates(const char * relative_base, int depth);
+extern char *compute_alternate_path(const char *path, struct strbuf *err);
extern void add_to_alternates_file(const char *reference);
typedef int alt_odb_fn(struct alternate_object_database *, void *);
extern int foreach_alt_odb(alt_odb_fn, void*);
/* [fg [bg]] [attr]... */
while (len > 0) {
const char *word = ptr;
- struct color c;
+ struct color c = { COLOR_UNSPECIFIED };
int val, wordlen = 0;
while (len > 0 && !isspace(word[wordlen])) {
return ret;
}
-#ifdef OVERRIDE_STRDUP
-/*
- * This implementation is purely there to override the libc version, to
- * avoid a crash due to allocation and free on different 'heaps'.
- */
-char *strdup(const char *s1)
-{
- size_t len = strlen(s1) + 1;
- char *s2 = malloc(len);
-
- if (s2)
- memcpy(s2, s1, len);
- return s2;
-}
-#endif
-
#if defined(__cplusplus)
}
#endif
--- /dev/null
+#include "../git-compat-util.h"
+
+char *gitstrdup(const char *s1)
+{
+ size_t len = strlen(s1) + 1;
+ char *s2 = malloc(len);
+
+ if (s2)
+ memcpy(s2, s1, len);
+ return s2;
+}
--- /dev/null
+# nothing to build
+all:
+
+test:
+ $(MAKE) -C t
my $COLOR = qr/\x1b\[[0-9;]*m/;
my $BORING = qr/$COLOR|\s/;
+# The patch portion of git log -p --graph should only ever have preceding | and
+# not / or \ as merge history only shows up on the commit line.
+my $GRAPH = qr/$COLOR?\|$COLOR?\s+/;
+
my @removed;
my @added;
my $in_hunk;
while (<>) {
if (!$in_hunk) {
print;
- $in_hunk = /^$COLOR*\@/;
+ $in_hunk = /^$GRAPH*$COLOR*\@\@ /;
}
- elsif (/^$COLOR*-/) {
+ elsif (/^$GRAPH*$COLOR*-/) {
push @removed, $_;
}
- elsif (/^$COLOR*\+/) {
+ elsif (/^$GRAPH*$COLOR*\+/) {
push @added, $_;
}
else {
@added = ();
print;
- $in_hunk = /^$COLOR*[\@ ]/;
+ $in_hunk = /^$GRAPH*$COLOR*[\@ ]/;
}
# Most of the time there is enough output to keep things streaming,
}
}
+# we split either by $COLOR or by character. This has the side effect of
+# leaving in graph cruft. It works because the graph cruft does not contain "-"
+# or "+"
sub split_line {
local $_ = shift;
return utf8::decode($_) ?
my $suffix_a = join('', @$a[($sa+1)..$#$a]);
my $suffix_b = join('', @$b[($sb+1)..$#$b]);
- return $prefix_a !~ /^$COLOR*-$BORING*$/ ||
- $prefix_b !~ /^$COLOR*\+$BORING*$/ ||
+ return $prefix_a !~ /^$GRAPH*$COLOR*-$BORING*$/ ||
+ $prefix_b !~ /^$GRAPH*$COLOR*\+$BORING*$/ ||
$suffix_a !~ /^$BORING*$/ ||
$suffix_b !~ /^$BORING*$/;
}
--- /dev/null
+/trash directory*
+/test-results
--- /dev/null
+-include ../../../config.mak.autogen
+-include ../../../config.mak
+
+# copied from ../../t/Makefile
+SHELL_PATH ?= $(SHELL)
+SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
+
+all: test
+test: $(T)
+
+.PHONY: help clean all test $(T)
+
+help:
+ @echo 'Run "$(MAKE) test" to launch test scripts'
+ @echo 'Run "$(MAKE) clean" to remove trash folders'
+
+$(T):
+ @echo "*** $@ ***"; '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
+
+clean:
+ $(RM) -r 'trash directory'.*
--- /dev/null
+#!/bin/sh
+
+test_description='Test diff-highlight'
+
+CURR_DIR=$(pwd)
+TEST_OUTPUT_DIRECTORY=$(pwd)
+TEST_DIRECTORY="$CURR_DIR"/../../../t
+DIFF_HIGHLIGHT="$CURR_DIR"/../diff-highlight
+
+CW="$(printf "\033[7m")" # white
+CR="$(printf "\033[27m")" # reset
+
+. "$TEST_DIRECTORY"/test-lib.sh
+
+if ! test_have_prereq PERL
+then
+ skip_all='skipping diff-highlight tests; perl not available'
+ test_done
+fi
+
+# dh_test is a test helper function which takes 3 file names as parameters. The
+# first 2 files are used to generate diff and commit output, which is then
+# piped through diff-highlight. The 3rd file should contain the expected output
+# of diff-highlight (minus the diff/commit header, ie. everything after and
+# including the first @@ line).
+dh_test () {
+ a="$1" b="$2" &&
+
+ cat >patch.exp &&
+
+ {
+ cat "$a" >file &&
+ git add file &&
+ git commit -m "Add a file" &&
+
+ cat "$b" >file &&
+ git diff file >diff.raw &&
+ git commit -a -m "Update a file" &&
+ git show >commit.raw
+ } >/dev/null &&
+
+ "$DIFF_HIGHLIGHT" <diff.raw | test_strip_patch_header >diff.act &&
+ "$DIFF_HIGHLIGHT" <commit.raw | test_strip_patch_header >commit.act &&
+ test_cmp patch.exp diff.act &&
+ test_cmp patch.exp commit.act
+}
+
+test_strip_patch_header () {
+ sed -n '/^@@/,$p' $*
+}
+
+# dh_test_setup_history generates a contrived graph such that we have at least
+# 1 nesting (E) and 2 nestings (F).
+#
+# A branch
+# /
+# D---E---F master
+#
+# git log --all --graph
+# * commit
+# | A
+# | * commit
+# | | F
+# | * commit
+# |/
+# | E
+# * commit
+# D
+#
+dh_test_setup_history () {
+ echo "file1" >file1 &&
+ echo "file2" >file2 &&
+ echo "file3" >file3 &&
+
+ cat file1 >file &&
+ git add file &&
+ git commit -m "D" &&
+
+ git checkout -b branch &&
+ cat file2 >file &&
+ git commit -a -m "A" &&
+
+ git checkout master &&
+ cat file2 >file &&
+ git commit -a -m "E" &&
+
+ cat file3 >file &&
+ git commit -a -m "F"
+}
+
+left_trim () {
+ "$PERL_PATH" -pe 's/^\s+//'
+}
+
+trim_graph () {
+ # graphs start with * or |
+ # followed by a space or / or \
+ "$PERL_PATH" -pe 's@^((\*|\|)( |/|\\))+@@'
+}
+
+test_expect_success 'diff-highlight highlights the beginning of a line' '
+ cat >a <<-\EOF &&
+ aaa
+ bbb
+ ccc
+ EOF
+
+ cat >b <<-\EOF &&
+ aaa
+ 0bb
+ ccc
+ EOF
+
+ dh_test a b <<-EOF
+ @@ -1,3 +1,3 @@
+ aaa
+ -${CW}b${CR}bb
+ +${CW}0${CR}bb
+ ccc
+ EOF
+'
+
+test_expect_success 'diff-highlight highlights the end of a line' '
+ cat >a <<-\EOF &&
+ aaa
+ bbb
+ ccc
+ EOF
+
+ cat >b <<-\EOF &&
+ aaa
+ bb0
+ ccc
+ EOF
+
+ dh_test a b <<-EOF
+ @@ -1,3 +1,3 @@
+ aaa
+ -bb${CW}b${CR}
+ +bb${CW}0${CR}
+ ccc
+ EOF
+'
+
+test_expect_success 'diff-highlight highlights the middle of a line' '
+ cat >a <<-\EOF &&
+ aaa
+ bbb
+ ccc
+ EOF
+
+ cat >b <<-\EOF &&
+ aaa
+ b0b
+ ccc
+ EOF
+
+ dh_test a b <<-EOF
+ @@ -1,3 +1,3 @@
+ aaa
+ -b${CW}b${CR}b
+ +b${CW}0${CR}b
+ ccc
+ EOF
+'
+
+test_expect_success 'diff-highlight does not highlight whole line' '
+ cat >a <<-\EOF &&
+ aaa
+ bbb
+ ccc
+ EOF
+
+ cat >b <<-\EOF &&
+ aaa
+ 000
+ ccc
+ EOF
+
+ dh_test a b <<-EOF
+ @@ -1,3 +1,3 @@
+ aaa
+ -bbb
+ +000
+ ccc
+ EOF
+'
+
+test_expect_failure 'diff-highlight highlights mismatched hunk size' '
+ cat >a <<-\EOF &&
+ aaa
+ bbb
+ EOF
+
+ cat >b <<-\EOF &&
+ aaa
+ b0b
+ ccc
+ EOF
+
+ dh_test a b <<-EOF
+ @@ -1,3 +1,3 @@
+ aaa
+ -b${CW}b${CR}b
+ +b${CW}0${CR}b
+ +ccc
+ EOF
+'
+
+# These two code points share the same leading byte in UTF-8 representation;
+# a naive byte-wise diff would highlight only the second byte.
+#
+# - U+00f3 ("o" with acute)
+o_accent=$(printf '\303\263')
+# - U+00f8 ("o" with stroke)
+o_stroke=$(printf '\303\270')
+
+test_expect_success 'diff-highlight treats multibyte utf-8 as a unit' '
+ echo "unic${o_accent}de" >a &&
+ echo "unic${o_stroke}de" >b &&
+ dh_test a b <<-EOF
+ @@ -1 +1 @@
+ -unic${CW}${o_accent}${CR}de
+ +unic${CW}${o_stroke}${CR}de
+ EOF
+'
+
+# Unlike the UTF-8 above, these are combining code points which are meant
+# to modify the character preceding them:
+#
+# - U+0301 (combining acute accent)
+combine_accent=$(printf '\314\201')
+# - U+0302 (combining circumflex)
+combine_circum=$(printf '\314\202')
+
+test_expect_failure 'diff-highlight treats combining code points as a unit' '
+ echo "unico${combine_accent}de" >a &&
+ echo "unico${combine_circum}de" >b &&
+ dh_test a b <<-EOF
+ @@ -1 +1 @@
+ -unic${CW}o${combine_accent}${CR}de
+ +unic${CW}o${combine_circum}${CR}de
+ EOF
+'
+
+test_expect_success 'diff-highlight works with the --graph option' '
+ dh_test_setup_history &&
+
+ # topo-order so that the order of the commits is the same as with --graph
+ # trim graph elements so we can do a diff
+ # trim leading space because our trim_graph is not perfect
+ git log --branches -p --topo-order |
+ "$DIFF_HIGHLIGHT" | left_trim >graph.exp &&
+ git log --branches -p --graph |
+ "$DIFF_HIGHLIGHT" | trim_graph | left_trim >graph.act &&
+ test_cmp graph.exp graph.act
+'
+
+# Most combined diffs won't meet diff-highlight's line-number filter. So we
+# create one here where one side drops a line and the other modifies it. That
+# should result in a diff like:
+#
+# - modified content
+# ++resolved content
+#
+# which naively looks like one side added "+resolved".
+test_expect_success 'diff-highlight ignores combined diffs' '
+ echo "content" >file &&
+ git add file &&
+ git commit -m base &&
+
+ >file &&
+ git commit -am master &&
+
+ git checkout -b other HEAD^ &&
+ echo "modified content" >file &&
+ git commit -am other &&
+
+ test_must_fail git merge master &&
+ echo "resolved content" >file &&
+ git commit -am resolved &&
+
+ cat >expect <<-\EOF &&
+ --- a/file
+ +++ b/file
+ @@@ -1,1 -1,0 +1,1 @@@
+ - modified content
+ ++resolved content
+ EOF
+
+ git show -c | "$DIFF_HIGHLIGHT" >actual.raw &&
+ sed -n "/^---/,\$p" <actual.raw >actual &&
+ test_cmp expect actual
+'
+
+test_done
#include "ll-merge.h"
#include "string-list.h"
#include "argv-array.h"
+#include "graph.h"
#ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0
static int parse_submodule_params(struct diff_options *options, const char *value)
{
if (!strcmp(value, "log"))
- DIFF_OPT_SET(options, SUBMODULE_LOG);
+ options->submodule_format = DIFF_SUBMODULE_LOG;
else if (!strcmp(value, "short"))
- DIFF_OPT_CLR(options, SUBMODULE_LOG);
+ options->submodule_format = DIFF_SUBMODULE_SHORT;
+ else if (!strcmp(value, "diff"))
+ options->submodule_format = DIFF_SUBMODULE_INLINE_DIFF;
else
return -1;
return 0;
*/
if (options->stat_width == -1)
- width = term_columns() - options->output_prefix_length;
+ width = term_columns() - strlen(line_prefix);
else
width = options->stat_width ? options->stat_width : 80;
number_width = decimal_width(max_change) > number_width ?
struct strbuf header = STRBUF_INIT;
const char *line_prefix = diff_line_prefix(o);
- if (DIFF_OPT_TST(o, SUBMODULE_LOG) &&
- (!one->mode || S_ISGITLINK(one->mode)) &&
- (!two->mode || S_ISGITLINK(two->mode))) {
+ diff_set_mnemonic_prefix(o, "a/", "b/");
+ if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
+ a_prefix = o->b_prefix;
+ b_prefix = o->a_prefix;
+ } else {
+ a_prefix = o->a_prefix;
+ b_prefix = o->b_prefix;
+ }
+
+ if (o->submodule_format == DIFF_SUBMODULE_LOG &&
+ (!one->mode || S_ISGITLINK(one->mode)) &&
+ (!two->mode || S_ISGITLINK(two->mode))) {
const char *del = diff_get_color_opt(o, DIFF_FILE_OLD);
const char *add = diff_get_color_opt(o, DIFF_FILE_NEW);
show_submodule_summary(o->file, one->path ? one->path : two->path,
line_prefix,
- one->oid.hash, two->oid.hash,
+ &one->oid, &two->oid,
two->dirty_submodule,
meta, del, add, reset);
return;
+ } else if (o->submodule_format == DIFF_SUBMODULE_INLINE_DIFF &&
+ (!one->mode || S_ISGITLINK(one->mode)) &&
+ (!two->mode || S_ISGITLINK(two->mode))) {
+ const char *del = diff_get_color_opt(o, DIFF_FILE_OLD);
+ const char *add = diff_get_color_opt(o, DIFF_FILE_NEW);
+ show_submodule_inline_diff(o->file, one->path ? one->path : two->path,
+ line_prefix,
+ &one->oid, &two->oid,
+ two->dirty_submodule,
+ meta, del, add, reset, o);
+ return;
}
if (DIFF_OPT_TST(o, ALLOW_TEXTCONV)) {
textconv_two = get_textconv(two);
}
- diff_set_mnemonic_prefix(o, "a/", "b/");
- if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
- a_prefix = o->b_prefix;
- b_prefix = o->a_prefix;
- } else {
- a_prefix = o->a_prefix;
- b_prefix = o->b_prefix;
- }
-
/* Never use a non-valid filename anywhere if at all possible */
name_a = DIFF_FILE_VALID(one) ? name_a : name_b;
name_b = DIFF_FILE_VALID(two) ? name_b : name_a;
DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
handle_ignore_submodules_arg(options, arg);
} else if (!strcmp(arg, "--submodule"))
- DIFF_OPT_SET(options, SUBMODULE_LOG);
+ options->submodule_format = DIFF_SUBMODULE_LOG;
else if (skip_prefix(arg, "--submodule=", &arg))
return parse_submodule_opt(options, arg);
else if (skip_prefix(arg, "--ws-error-highlight=", &arg))
options->a_prefix = optarg;
return argcount;
}
+ else if ((argcount = parse_long_opt("line-prefix", av, &optarg))) {
+ options->line_prefix = optarg;
+ options->line_prefix_length = strlen(options->line_prefix);
+ graph_setup_line_prefix(options);
+ return argcount;
+ }
else if ((argcount = parse_long_opt("dst-prefix", av, &optarg))) {
options->b_prefix = optarg;
return argcount;
#define DIFF_OPT_DIRSTAT_BY_FILE (1 << 20)
#define DIFF_OPT_ALLOW_TEXTCONV (1 << 21)
#define DIFF_OPT_DIFF_FROM_CONTENTS (1 << 22)
-#define DIFF_OPT_SUBMODULE_LOG (1 << 23)
#define DIFF_OPT_DIRTY_SUBMODULES (1 << 24)
#define DIFF_OPT_IGNORE_UNTRACKED_IN_SUBMODULES (1 << 25)
#define DIFF_OPT_IGNORE_DIRTY_SUBMODULES (1 << 26)
DIFF_WORDS_COLOR
};
+enum diff_submodule_format {
+ DIFF_SUBMODULE_SHORT = 0,
+ DIFF_SUBMODULE_LOG,
+ DIFF_SUBMODULE_INLINE_DIFF
+};
+
struct diff_options {
const char *orderfile;
const char *pickaxe;
const char *single_follow;
const char *a_prefix, *b_prefix;
+ const char *line_prefix;
+ size_t line_prefix_length;
unsigned flags;
unsigned touched_flags;
int stat_count;
const char *word_regex;
enum diff_words_type word_diff;
+ enum diff_submodule_format submodule_format;
/* this is set by diffcore for DIFF_FORMAT_PATCH */
int found_changes;
diff_format_fn_t format_callback;
void *format_callback_data;
diff_prefix_fn_t output_prefix;
- int output_prefix_length;
void *output_prefix_data;
int diff_path_counter;
return -1;
}
#define error(...) (error(__VA_ARGS__), const_error())
+#define error_errno(...) (error_errno(__VA_ARGS__), const_error())
#endif
extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params));
const void *needle, size_t needlelen);
#endif
+#ifdef OVERRIDE_STRDUP
+#ifdef strdup
+#undef strdup
+#endif
+#define strdup gitstrdup
+char *gitstrdup(const char *s);
+#endif
+
#ifdef NO_GETPAGESIZE
#define getpagesize() sysconf(_SC_PAGESIZE)
#endif
# Translation of git-gui to Japanese
# Copyright (C) 2007 Shawn Pearce
# This file is distributed under the same license as the git-gui package.
+#
# しらいし ななこ <nanako3@bluebottle.com>, 2007.
+# Satoshi Yasushima <s.yasushima@gmail.com>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: git-gui\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-01-26 15:47-0800\n"
-"PO-Revision-Date: 2010-02-02 19:03+0900\n"
-"Last-Translator: しらいし ななこ <nanako3@lavabit.com>\n"
+"POT-Creation-Date: 2016-05-27 17:52+0900\n"
+"PO-Revision-Date: 2016-06-22 12:50+0900\n"
+"Last-Translator: Satoshi Yasushima <s.yasushima@gmail.com>\n"
"Language-Team: Japanese\n"
+"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: git-gui.sh:41 git-gui.sh:793 git-gui.sh:807 git-gui.sh:820 git-gui.sh:903
-#: git-gui.sh:922
-msgid "git-gui: fatal error"
-msgstr "git-gui: 致命的なエラー"
-
-#: git-gui.sh:743
+#: git-gui.sh:861
#, tcl-format
msgid "Invalid font specified in %s:"
msgstr "%s に無効なフォントが指定されています:"
-#: git-gui.sh:779
+#: git-gui.sh:915
msgid "Main Font"
msgstr "主フォント"
-#: git-gui.sh:780
+#: git-gui.sh:916
msgid "Diff/Console Font"
msgstr "diff/コンソール・フォント"
-#: git-gui.sh:794
+#: git-gui.sh:931 git-gui.sh:945 git-gui.sh:958 git-gui.sh:1048 git-gui.sh:1067
+#: git-gui.sh:3125
+msgid "git-gui: fatal error"
+msgstr "git-gui: 致命的なエラー"
+
+#: git-gui.sh:932
msgid "Cannot find git in PATH."
msgstr "PATH 中に git が見つかりません"
-#: git-gui.sh:821
+#: git-gui.sh:959
msgid "Cannot parse Git version string:"
msgstr "Git バージョン名が理解できません:"
-#: git-gui.sh:839
+#: git-gui.sh:984
#, tcl-format
msgid ""
"Git version cannot be determined.\n"
"\n"
"'%s' はバージョン 1.5.0 と思って良いですか?\n"
-#: git-gui.sh:1128
+#: git-gui.sh:1281
msgid "Git directory not found:"
msgstr "Git ディレクトリが見つかりません:"
-#: git-gui.sh:1146
+#: git-gui.sh:1315
msgid "Cannot move to top of working directory:"
msgstr "作業ディレクトリの最上位に移動できません"
-#: git-gui.sh:1154
+#: git-gui.sh:1323
msgid "Cannot use bare repository:"
msgstr "裸のリポジトリは使えません:"
-#: git-gui.sh:1162
+#: git-gui.sh:1331
msgid "No working directory"
msgstr "作業ディレクトリがありません"
-#: git-gui.sh:1334 lib/checkout_op.tcl:306
+#: git-gui.sh:1503 lib/checkout_op.tcl:306
msgid "Refreshing file status..."
msgstr "ファイル状態を更新しています…"
-#: git-gui.sh:1390
+#: git-gui.sh:1563
msgid "Scanning for modified files ..."
msgstr "変更されたファイルをスキャンしています…"
-#: git-gui.sh:1454
+#: git-gui.sh:1639
msgid "Calling prepare-commit-msg hook..."
msgstr "prepare-commit-msg フックを実行中・・・"
-#: git-gui.sh:1471
+#: git-gui.sh:1656
msgid "Commit declined by prepare-commit-msg hook."
msgstr "prepare-commit-msg フックがコミットを拒否しました"
-#: git-gui.sh:1629 lib/browser.tcl:246
+#: git-gui.sh:1814 lib/browser.tcl:252
msgid "Ready."
msgstr "準備完了"
-#: git-gui.sh:1787
+#: git-gui.sh:1978
#, tcl-format
-msgid "Displaying only %s of %s files."
-msgstr "全体で%s個の内の%sファイルだけ表示しています"
+msgid ""
+"Display limit (gui.maxfilesdisplayed = %s) reached, not showing all %s files."
+msgstr ""
+"表示可能な限界 (gui.maxfilesdisplayed = %s) に達しため、全体で%s個のファイル"
+"を表示できません"
-#: git-gui.sh:1913
+#: git-gui.sh:2101
msgid "Unmodified"
msgstr "変更無し"
-#: git-gui.sh:1915
+#: git-gui.sh:2103
msgid "Modified, not staged"
msgstr "変更あり、コミット未予定"
-#: git-gui.sh:1916 git-gui.sh:1924
+#: git-gui.sh:2104 git-gui.sh:2116
msgid "Staged for commit"
msgstr "コミット予定済"
-#: git-gui.sh:1917 git-gui.sh:1925
+#: git-gui.sh:2105 git-gui.sh:2117
msgid "Portions staged for commit"
msgstr "部分的にコミット予定済"
-#: git-gui.sh:1918 git-gui.sh:1926
+#: git-gui.sh:2106 git-gui.sh:2118
msgid "Staged for commit, missing"
msgstr "コミット予定済、ファイル無し"
-#: git-gui.sh:1920
+#: git-gui.sh:2108
msgid "File type changed, not staged"
msgstr "ファイル型変更、コミット未予定"
-#: git-gui.sh:1921
+#: git-gui.sh:2109 git-gui.sh:2110
+msgid "File type changed, old type staged for commit"
+msgstr "ファイル型変更、旧型コミット予定済"
+
+#: git-gui.sh:2111
msgid "File type changed, staged"
msgstr "ファイル型変更、コミット予定済"
-#: git-gui.sh:1923
+#: git-gui.sh:2112
+msgid "File type change staged, modification not staged"
+msgstr "ファイル型変更コミット予定済、変更コミット未予定"
+
+#: git-gui.sh:2113
+msgid "File type change staged, file missing"
+msgstr "ファイル型変更コミット予定済、ファイル無し"
+
+#: git-gui.sh:2115
msgid "Untracked, not staged"
msgstr "管理外、コミット未予定"
-#: git-gui.sh:1928
+#: git-gui.sh:2120
msgid "Missing"
msgstr "ファイル無し"
-#: git-gui.sh:1929
+#: git-gui.sh:2121
msgid "Staged for removal"
msgstr "削除予定済"
-#: git-gui.sh:1930
+#: git-gui.sh:2122
msgid "Staged for removal, still present"
msgstr "削除予定済、ファイル未削除"
-#: git-gui.sh:1932 git-gui.sh:1933 git-gui.sh:1934 git-gui.sh:1935
-#: git-gui.sh:1936 git-gui.sh:1937
+#: git-gui.sh:2124 git-gui.sh:2125 git-gui.sh:2126 git-gui.sh:2127
+#: git-gui.sh:2128 git-gui.sh:2129
msgid "Requires merge resolution"
msgstr "要マージ解決"
-#: git-gui.sh:1972
+#: git-gui.sh:2164
msgid "Starting gitk... please wait..."
msgstr "gitk を起動中…お待ち下さい…"
-#: git-gui.sh:1984
+#: git-gui.sh:2176
msgid "Couldn't find gitk in PATH"
msgstr "PATH 中に gitk が見つかりません"
-#: git-gui.sh:2043
+#: git-gui.sh:2235
msgid "Couldn't find git gui in PATH"
msgstr "PATH 中に git gui が見つかりません"
-#: git-gui.sh:2455 lib/choose_repository.tcl:36
+#: git-gui.sh:2654 lib/choose_repository.tcl:41
msgid "Repository"
msgstr "リポジトリ"
-#: git-gui.sh:2456
+#: git-gui.sh:2655
msgid "Edit"
msgstr "編集"
-#: git-gui.sh:2458 lib/choose_rev.tcl:561
+#: git-gui.sh:2657 lib/choose_rev.tcl:567
msgid "Branch"
msgstr "ブランチ"
-#: git-gui.sh:2461 lib/choose_rev.tcl:548
+#: git-gui.sh:2660 lib/choose_rev.tcl:554
msgid "Commit@@noun"
msgstr "コミット"
-#: git-gui.sh:2464 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168
+#: git-gui.sh:2663 lib/merge.tcl:123 lib/merge.tcl:152 lib/merge.tcl:170
msgid "Merge"
msgstr "マージ"
-#: git-gui.sh:2465 lib/choose_rev.tcl:557
+#: git-gui.sh:2664 lib/choose_rev.tcl:563
msgid "Remote"
msgstr "リモート"
-#: git-gui.sh:2468
+#: git-gui.sh:2667
msgid "Tools"
msgstr "ツール"
-#: git-gui.sh:2477
+#: git-gui.sh:2676
msgid "Explore Working Copy"
msgstr "ワーキングコピーをブラウズ"
-#: git-gui.sh:2483
+#: git-gui.sh:2682
+msgid "Git Bash"
+msgstr ""
+
+#: git-gui.sh:2692
msgid "Browse Current Branch's Files"
msgstr "現在のブランチのファイルを見る"
-#: git-gui.sh:2487
+#: git-gui.sh:2696
msgid "Browse Branch Files..."
msgstr "ブランチのファイルを見る…"
-#: git-gui.sh:2492
+#: git-gui.sh:2701
msgid "Visualize Current Branch's History"
msgstr "現在のブランチの履歴を見る"
-#: git-gui.sh:2496
+#: git-gui.sh:2705
msgid "Visualize All Branch History"
msgstr "全てのブランチの履歴を見る"
-#: git-gui.sh:2503
+#: git-gui.sh:2712
#, tcl-format
msgid "Browse %s's Files"
msgstr "ブランチ %s のファイルを見る"
-#: git-gui.sh:2505
+#: git-gui.sh:2714
#, tcl-format
msgid "Visualize %s's History"
msgstr "ブランチ %s の履歴を見る"
-#: git-gui.sh:2510 lib/database.tcl:27 lib/database.tcl:67
+#: git-gui.sh:2719 lib/database.tcl:40 lib/database.tcl:66
msgid "Database Statistics"
msgstr "データベース統計"
-#: git-gui.sh:2513 lib/database.tcl:34
+#: git-gui.sh:2722 lib/database.tcl:33
msgid "Compress Database"
msgstr "データベース圧縮"
-#: git-gui.sh:2516
+#: git-gui.sh:2725
msgid "Verify Database"
msgstr "データベース検証"
-#: git-gui.sh:2523 git-gui.sh:2527 git-gui.sh:2531 lib/shortcut.tcl:8
+#: git-gui.sh:2732 git-gui.sh:2736 git-gui.sh:2740 lib/shortcut.tcl:8
#: lib/shortcut.tcl:40 lib/shortcut.tcl:72
msgid "Create Desktop Icon"
msgstr "デスクトップ・アイコンを作る"
-#: git-gui.sh:2539 lib/choose_repository.tcl:183 lib/choose_repository.tcl:191
+#: git-gui.sh:2748 lib/choose_repository.tcl:193 lib/choose_repository.tcl:201
msgid "Quit"
msgstr "終了"
-#: git-gui.sh:2547
+#: git-gui.sh:2756
msgid "Undo"
msgstr "元に戻す"
-#: git-gui.sh:2550
+#: git-gui.sh:2759
msgid "Redo"
msgstr "やり直し"
-#: git-gui.sh:2554 git-gui.sh:3109
+#: git-gui.sh:2763 git-gui.sh:3368
msgid "Cut"
msgstr "切り取り"
-#: git-gui.sh:2557 git-gui.sh:3112 git-gui.sh:3186 git-gui.sh:3259
+#: git-gui.sh:2766 git-gui.sh:3371 git-gui.sh:3445 git-gui.sh:3530
#: lib/console.tcl:69
msgid "Copy"
msgstr "コピー"
-#: git-gui.sh:2560 git-gui.sh:3115
+#: git-gui.sh:2769 git-gui.sh:3374
msgid "Paste"
msgstr "貼り付け"
-#: git-gui.sh:2563 git-gui.sh:3118 lib/branch_delete.tcl:26
-#: lib/remote_branch_delete.tcl:38
+#: git-gui.sh:2772 git-gui.sh:3377 lib/remote_branch_delete.tcl:39
+#: lib/branch_delete.tcl:28
msgid "Delete"
msgstr "削除"
-#: git-gui.sh:2567 git-gui.sh:3122 git-gui.sh:3263 lib/console.tcl:71
+#: git-gui.sh:2776 git-gui.sh:3381 git-gui.sh:3534 lib/console.tcl:71
msgid "Select All"
msgstr "全て選択"
-#: git-gui.sh:2576
+#: git-gui.sh:2785
msgid "Create..."
msgstr "作成…"
-#: git-gui.sh:2582
+#: git-gui.sh:2791
msgid "Checkout..."
msgstr "チェックアウト"
-#: git-gui.sh:2588
+#: git-gui.sh:2797
msgid "Rename..."
msgstr "名前変更…"
-#: git-gui.sh:2593
+#: git-gui.sh:2802
msgid "Delete..."
msgstr "削除…"
-#: git-gui.sh:2598
+#: git-gui.sh:2807
msgid "Reset..."
msgstr "リセット…"
-#: git-gui.sh:2608
+#: git-gui.sh:2817
msgid "Done"
msgstr "完了"
-#: git-gui.sh:2610
+#: git-gui.sh:2819
msgid "Commit@@verb"
msgstr "コミット"
-#: git-gui.sh:2619 git-gui.sh:3050
+#: git-gui.sh:2828 git-gui.sh:3309
msgid "New Commit"
msgstr "新規コミット"
-#: git-gui.sh:2627 git-gui.sh:3057
+#: git-gui.sh:2836 git-gui.sh:3316
msgid "Amend Last Commit"
msgstr "最新コミットを訂正"
-#: git-gui.sh:2637 git-gui.sh:3011 lib/remote_branch_delete.tcl:99
+#: git-gui.sh:2846 git-gui.sh:3270 lib/remote_branch_delete.tcl:101
msgid "Rescan"
msgstr "再スキャン"
-#: git-gui.sh:2643
+#: git-gui.sh:2852
msgid "Stage To Commit"
msgstr "コミット予定する"
-#: git-gui.sh:2649
+#: git-gui.sh:2858
msgid "Stage Changed Files To Commit"
msgstr "変更されたファイルをコミット予定"
-#: git-gui.sh:2655
+#: git-gui.sh:2864
msgid "Unstage From Commit"
msgstr "コミットから降ろす"
-#: git-gui.sh:2661 lib/index.tcl:412
+#: git-gui.sh:2870 lib/index.tcl:442
msgid "Revert Changes"
msgstr "変更を元に戻す"
-#: git-gui.sh:2669 git-gui.sh:3310 git-gui.sh:3341
+#: git-gui.sh:2878 git-gui.sh:3581 git-gui.sh:3612
msgid "Show Less Context"
msgstr "文脈を少なく"
-#: git-gui.sh:2673 git-gui.sh:3314 git-gui.sh:3345
+#: git-gui.sh:2882 git-gui.sh:3585 git-gui.sh:3616
msgid "Show More Context"
msgstr "文脈を多く"
-#: git-gui.sh:2680 git-gui.sh:3024 git-gui.sh:3133
+#: git-gui.sh:2889 git-gui.sh:3283 git-gui.sh:3392
msgid "Sign Off"
msgstr "署名"
-#: git-gui.sh:2696
+#: git-gui.sh:2905
msgid "Local Merge..."
msgstr "ローカル・マージ…"
-#: git-gui.sh:2701
+#: git-gui.sh:2910
msgid "Abort Merge..."
msgstr "マージ中止…"
-#: git-gui.sh:2713 git-gui.sh:2741
+#: git-gui.sh:2922 git-gui.sh:2950
msgid "Add..."
msgstr "追加"
-#: git-gui.sh:2717
+#: git-gui.sh:2926
msgid "Push..."
msgstr "プッシュ…"
-#: git-gui.sh:2721
+#: git-gui.sh:2930
msgid "Delete Branch..."
msgstr "ブランチ削除..."
-#: git-gui.sh:2731 git-gui.sh:3292
+#: git-gui.sh:2940 git-gui.sh:3563
msgid "Options..."
msgstr "オプション…"
-#: git-gui.sh:2742
+#: git-gui.sh:2951
msgid "Remove..."
msgstr "削除..."
-#: git-gui.sh:2751 lib/choose_repository.tcl:50
+#: git-gui.sh:2960 lib/choose_repository.tcl:55
msgid "Help"
msgstr "ヘルプ"
-#: git-gui.sh:2755 git-gui.sh:2759 lib/about.tcl:14
-#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:53
+#: git-gui.sh:2964 git-gui.sh:2968 lib/about.tcl:14
+#: lib/choose_repository.tcl:49 lib/choose_repository.tcl:58
#, tcl-format
msgid "About %s"
msgstr "%s について"
-#: git-gui.sh:2783
+#: git-gui.sh:2992
msgid "Online Documentation"
msgstr "オンライン・ドキュメント"
-#: git-gui.sh:2786 lib/choose_repository.tcl:47 lib/choose_repository.tcl:56
+#: git-gui.sh:2995 lib/choose_repository.tcl:52 lib/choose_repository.tcl:61
msgid "Show SSH Key"
msgstr "SSH キーを表示"
-#: git-gui.sh:2893
+#: git-gui.sh:3014 git-gui.sh:3146
+msgid "Usage"
+msgstr "使い方"
+
+#: git-gui.sh:3095 lib/blame.tcl:573
+msgid "Error"
+msgstr "エラー"
+
+#: git-gui.sh:3126
#, tcl-format
msgid "fatal: cannot stat path %s: No such file or directory"
msgstr ""
"致命的: パス %s が stat できません。そのようなファイルやディレクトリはありま"
"せん"
-#: git-gui.sh:2926
+#: git-gui.sh:3159
msgid "Current Branch:"
msgstr "現在のブランチ"
-#: git-gui.sh:2947
+#: git-gui.sh:3185
msgid "Staged Changes (Will Commit)"
msgstr "ステージングされた(コミット予定済の)変更"
-#: git-gui.sh:2967
+#: git-gui.sh:3205
msgid "Unstaged Changes"
msgstr "コミット予定に入っていない変更"
-#: git-gui.sh:3017
+#: git-gui.sh:3276
msgid "Stage Changed"
msgstr "変更をコミット予定に入れる"
-#: git-gui.sh:3036 lib/transport.tcl:104 lib/transport.tcl:193
+#: git-gui.sh:3295 lib/transport.tcl:137 lib/transport.tcl:229
msgid "Push"
msgstr "プッシュ"
-#: git-gui.sh:3071
+#: git-gui.sh:3330
msgid "Initial Commit Message:"
msgstr "最初のコミットメッセージ:"
-#: git-gui.sh:3072
+#: git-gui.sh:3331
msgid "Amended Commit Message:"
msgstr "訂正したコミットメッセージ:"
-#: git-gui.sh:3073
+#: git-gui.sh:3332
msgid "Amended Initial Commit Message:"
msgstr "訂正した最初のコミットメッセージ:"
-#: git-gui.sh:3074
+#: git-gui.sh:3333
msgid "Amended Merge Commit Message:"
msgstr "訂正したマージコミットメッセージ:"
-#: git-gui.sh:3075
+#: git-gui.sh:3334
msgid "Merge Commit Message:"
msgstr "マージコミットメッセージ:"
-#: git-gui.sh:3076
+#: git-gui.sh:3335
msgid "Commit Message:"
msgstr "コミットメッセージ:"
-#: git-gui.sh:3125 git-gui.sh:3267 lib/console.tcl:73
+#: git-gui.sh:3384 git-gui.sh:3538 lib/console.tcl:73
msgid "Copy All"
msgstr "全てコピー"
-#: git-gui.sh:3149 lib/blame.tcl:104
+#: git-gui.sh:3408 lib/blame.tcl:105
msgid "File:"
msgstr "ファイル:"
-#: git-gui.sh:3255
+#: git-gui.sh:3526
msgid "Refresh"
msgstr "再読み込み"
-#: git-gui.sh:3276
+#: git-gui.sh:3547
msgid "Decrease Font Size"
msgstr "フォントを小さく"
-#: git-gui.sh:3280
+#: git-gui.sh:3551
msgid "Increase Font Size"
msgstr "フォントを大きく"
-#: git-gui.sh:3288 lib/blame.tcl:281
+#: git-gui.sh:3559 lib/blame.tcl:294
msgid "Encoding"
msgstr "エンコーディング"
-#: git-gui.sh:3299
+#: git-gui.sh:3570
msgid "Apply/Reverse Hunk"
msgstr "パッチを適用/取り消す"
-#: git-gui.sh:3304
+#: git-gui.sh:3575
msgid "Apply/Reverse Line"
msgstr "パッチ行を適用/取り消す"
-#: git-gui.sh:3323
+#: git-gui.sh:3594
msgid "Run Merge Tool"
msgstr "マージツールを起動"
-#: git-gui.sh:3328
+#: git-gui.sh:3599
msgid "Use Remote Version"
msgstr "リモートの方を採用"
-#: git-gui.sh:3332
+#: git-gui.sh:3603
msgid "Use Local Version"
msgstr "ローカルの方を採用"
-#: git-gui.sh:3336
+#: git-gui.sh:3607
msgid "Revert To Base"
msgstr "ベース版を採用"
-#: git-gui.sh:3354
+#: git-gui.sh:3625
msgid "Visualize These Changes In The Submodule"
msgstr "サブモジュール内のこれらの変更を見る"
-#: git-gui.sh:3358
+#: git-gui.sh:3629
msgid "Visualize Current Branch History In The Submodule"
msgstr "サブモジュール内で現在のブランチの履歴を見る"
-#: git-gui.sh:3362
+#: git-gui.sh:3633
msgid "Visualize All Branch History In The Submodule"
msgstr "サブモジュール内で全てのブランチの履歴を見る"
-#: git-gui.sh:3367
+#: git-gui.sh:3638
msgid "Start git gui In The Submodule"
msgstr "サブモジュール内でgit guiを起動する"
-#: git-gui.sh:3389
+#: git-gui.sh:3673
msgid "Unstage Hunk From Commit"
msgstr "パッチをコミット予定から外す"
-#: git-gui.sh:3391
+#: git-gui.sh:3675
msgid "Unstage Lines From Commit"
msgstr "コミット予定から行を外す"
-#: git-gui.sh:3393
+#: git-gui.sh:3677
msgid "Unstage Line From Commit"
msgstr "コミット予定から行を外す"
-#: git-gui.sh:3396
+#: git-gui.sh:3680
msgid "Stage Hunk For Commit"
msgstr "パッチをコミット予定に加える"
-#: git-gui.sh:3398
+#: git-gui.sh:3682
msgid "Stage Lines For Commit"
msgstr "パッチ行をコミット予定に加える"
-#: git-gui.sh:3400
+#: git-gui.sh:3684
msgid "Stage Line For Commit"
msgstr "パッチ行をコミット予定に加える"
-#: git-gui.sh:3424
+#: git-gui.sh:3709
msgid "Initializing..."
msgstr "初期化しています…"
-#: git-gui.sh:3541
+#: git-gui.sh:3852
#, tcl-format
msgid ""
"Possible environment issues exist.\n"
"以下の環境変数は %s が起動する Git サブプロセスによって無視されるでしょう:\n"
"\n"
-#: git-gui.sh:3570
+#: git-gui.sh:3881
msgid ""
"\n"
"This is due to a known issue with the\n"
"これは Cygwin で配布されている Tcl バイナリに\n"
"関しての既知の問題によります"
-#: git-gui.sh:3575
+#: git-gui.sh:3886
#, tcl-format
msgid ""
"\n"
"個人的な ~/.gitconfig ファイル内で user.name と user.email の値を設定\n"
"するのが、%s の良い代用となります\n"
-#: lib/about.tcl:26
-msgid "git-gui - a graphical user interface for Git."
-msgstr "Git のグラフィカルUI git-gui"
+#: lib/merge.tcl:13
+msgid ""
+"Cannot merge while amending.\n"
+"\n"
+"You must finish amending this commit before starting any type of merge.\n"
+msgstr ""
+"訂正中にはマージできません。\n"
+"\n"
+"訂正処理を完了するまでは新たにマージを開始できません。\n"
-#: lib/blame.tcl:72
-msgid "File Viewer"
-msgstr "ファイルピューワ"
+#: lib/merge.tcl:27
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before a merge can be performed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"最後にスキャンした状態はリポジトリの状態と合致しません。\n"
+"\n"
+"最後にスキャンして以後、別の Git プログラムがリポジトリを変更しています。マー"
+"ジを開始する前に、再スキャンが必要です。\n"
+"\n"
+"自動的に再スキャンを開始します。\n"
-#: lib/blame.tcl:78
-msgid "Commit:"
-msgstr "コミット:"
+#: lib/merge.tcl:45
+#, tcl-format
+msgid ""
+"You are in the middle of a conflicted merge.\n"
+"\n"
+"File %s has merge conflicts.\n"
+"\n"
+"You must resolve them, stage the file, and commit to complete the current "
+"merge. Only then can you begin another merge.\n"
+msgstr ""
+"衝突のあったマージの途中です。\n"
+"\n"
+"ファイル %s にはマージ中の衝突が残っています。\n"
+"\n"
+"このファイルの衝突を解決し、コミット予定に加えて、コミットすることでマージを"
+"完了します。そうやって始めて、新たなマージを開始できるようになります。\n"
-#: lib/blame.tcl:271
-msgid "Copy Commit"
-msgstr "コミットをコピー"
+#: lib/merge.tcl:55
+#, tcl-format
+msgid ""
+"You are in the middle of a change.\n"
+"\n"
+"File %s is modified.\n"
+"\n"
+"You should complete the current commit before starting a merge. Doing so "
+"will help you abort a failed merge, should the need arise.\n"
+msgstr ""
+"変更の途中です。\n"
+"\n"
+"ファイル %s は変更中です。\n"
+"\n"
+"現在のコミットを完了してからマージを開始して下さい。そうする方がマージに失敗"
+"したときの回復が楽です。\n"
-#: lib/blame.tcl:275
-msgid "Find Text..."
-msgstr "テキストを検索"
+#: lib/merge.tcl:108
+#, tcl-format
+msgid "%s of %s"
+msgstr "%s の %s ブランチ"
-#: lib/blame.tcl:284
-msgid "Do Full Copy Detection"
-msgstr "コピー検知"
+#: lib/merge.tcl:122
+#, tcl-format
+msgid "Merging %s and %s..."
+msgstr "%s と %s をマージ中・・・"
-#: lib/blame.tcl:288
-msgid "Show History Context"
-msgstr "文脈を見せる"
+#: lib/merge.tcl:133
+msgid "Merge completed successfully."
+msgstr "マージが完了しました"
-#: lib/blame.tcl:291
-msgid "Blame Parent Commit"
-msgstr "親コミットを註釈"
+#: lib/merge.tcl:135
+msgid "Merge failed. Conflict resolution is required."
+msgstr "マージが失敗しました。衝突の解決が必要です。"
-#: lib/blame.tcl:450
+#: lib/merge.tcl:160
#, tcl-format
-msgid "Reading %s..."
-msgstr "%s ã\82\92èªã\82\93ã\81§ã\81\84ã\81¾ã\81\99â\80¦"
+msgid "Merge Into %s"
+msgstr "%s ã\81«ã\83\9eã\83¼ã\82¸"
-#: lib/blame.tcl:557
-msgid "Loading copy/move tracking annotations..."
-msgstr "コピー・移動追跡データを読んでいます…"
+#: lib/merge.tcl:166 lib/checkout_op.tcl:567 lib/tools_dlg.tcl:336
+msgid "Visualize"
+msgstr "可視化"
-#: lib/blame.tcl:577
-msgid "lines annotated"
-msgstr "行を注釈しました"
+#: lib/merge.tcl:174 lib/remote_branch_delete.tcl:43 lib/branch_delete.tcl:34
+#: lib/checkout_op.tcl:579 lib/branch_rename.tcl:32 lib/tools_dlg.tcl:41
+#: lib/tools_dlg.tcl:202 lib/tools_dlg.tcl:345 lib/option.tcl:127
+#: lib/transport.tcl:141 lib/choose_font.tcl:45 lib/branch_checkout.tcl:30
+#: lib/browser.tcl:292 lib/remote_add.tcl:34 lib/branch_create.tcl:37
+msgid "Cancel"
+msgstr "中止"
-#: lib/blame.tcl:769
-msgid "Loading original location annotations..."
-msgstr "元位置行の注釈データを読んでいます…"
+#: lib/merge.tcl:179
+msgid "Revision To Merge"
+msgstr "マージするリビジョン"
-#: lib/blame.tcl:772
-msgid "Annotation complete."
-msgstr "注釈完了しました"
+#: lib/merge.tcl:214
+msgid ""
+"Cannot abort while amending.\n"
+"\n"
+"You must finish amending this commit.\n"
+msgstr ""
+"訂正中には中止できません。\n"
+"\n"
+"まず今のコミット訂正を完了させて下さい。\n"
-#: lib/blame.tcl:802
-msgid "Busy"
-msgstr "実行中"
+#: lib/merge.tcl:224
+msgid ""
+"Abort merge?\n"
+"\n"
+"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with aborting the current merge?"
+msgstr ""
+"マージを中断しますか?\n"
+"\n"
+"現在のマージを中断すると、コミットしていない全ての変更が失われます。\n"
+"\n"
+"マージを中断してよろしいですか?"
-#: lib/blame.tcl:803
-msgid "Annotation process is already running."
-msgstr "すでに blame プロセスを実行中です。"
+#: lib/merge.tcl:230
+msgid ""
+"Reset changes?\n"
+"\n"
+"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with resetting the current changes?"
+msgstr ""
+"変更点をリセットしますか?\n"
+"\n"
+"変更点をリセットすると、コミットしていない全ての変更が失われます。\n"
+"\n"
+"リセットしてよろしいですか?"
-#: lib/blame.tcl:842
-msgid "Running thorough copy detection..."
-msgstr "コピー検知を実行中…"
+#: lib/merge.tcl:241
+msgid "Aborting"
+msgstr "中断しています"
-#: lib/blame.tcl:910
-msgid "Loading annotation..."
-msgstr "注釈を読み込んでいます…"
+#: lib/merge.tcl:241
+msgid "files reset"
+msgstr "リセットしたファイル"
-#: lib/blame.tcl:963
-msgid "Author:"
-msgstr "ä½\9cè\80\85:"
+#: lib/merge.tcl:269
+msgid "Abort failed."
+msgstr "ä¸æ\96ã\81«å¤±æ\95\97ã\81\97ã\81¾ã\81\97ã\81\9fã\80\82"
-#: lib/blame.tcl:967
-msgid "Committer:"
-msgstr "コミット者:"
+#: lib/merge.tcl:271
+msgid "Abort completed. Ready."
+msgstr "中断完了。"
-#: lib/blame.tcl:972
-msgid "Original File:"
-msgstr "元ファイル"
+#: lib/error.tcl:20 lib/error.tcl:116
+msgid "error"
+msgstr "エラー"
-#: lib/blame.tcl:1020
-msgid "Cannot find HEAD commit:"
-msgstr "HEAD コミットが見つかりません"
+#: lib/error.tcl:36
+msgid "warning"
+msgstr "警告"
-#: lib/blame.tcl:1075
-msgid "Cannot find parent commit:"
-msgstr "親コミットが見つかりません:"
+#: lib/error.tcl:96
+msgid "You must correct the above errors before committing."
+msgstr "コミットする前に、以上のエラーを修正して下さい"
-#: lib/blame.tcl:1090
-msgid "Unable to display parent"
-msgstr "親を表示できません"
+#: lib/date.tcl:25
+#, tcl-format
+msgid "Invalid date from Git: %s"
+msgstr "Git から出た無効な日付: %s"
-#: lib/blame.tcl:1091 lib/diff.tcl:320
-msgid "Error loading diff:"
-msgstr "diff を読む際のエラーです:"
+#: lib/encoding.tcl:443
+msgid "Default"
+msgstr "デフォールト"
-#: lib/blame.tcl:1231
-msgid "Originally By:"
-msgstr "原作者:"
+#: lib/encoding.tcl:448
+#, tcl-format
+msgid "System (%s)"
+msgstr "システム (%s)"
-#: lib/blame.tcl:1237
-msgid "In File:"
-msgstr "ã\83\95ã\82¡ã\82¤ã\83«:"
+#: lib/encoding.tcl:459 lib/encoding.tcl:465
+msgid "Other"
+msgstr "ã\81\9dã\81®ä»\96"
-#: lib/blame.tcl:1242
-msgid "Copied Or Moved Here By:"
-msgstr "複写・移動者:"
+#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
+msgid "Delete Branch Remotely"
+msgstr "リモートブランチ削除"
-#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
-msgid "Checkout Branch"
-msgstr "ブランチをチェックアウト"
+#: lib/remote_branch_delete.tcl:48
+msgid "From Repository"
+msgstr "元のリポジトリ"
-#: lib/branch_checkout.tcl:23
-msgid "Checkout"
-msgstr "ã\83\81ã\82§ã\83\83ã\82¯ã\82¢ã\82¦ã\83\88"
+#: lib/remote_branch_delete.tcl:51 lib/transport.tcl:165
+msgid "Remote:"
+msgstr "ã\83ªã\83¢ã\83¼ã\83\88:"
-#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
-#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:282
-#: lib/checkout_op.tcl:579 lib/choose_font.tcl:43 lib/merge.tcl:172
-#: lib/option.tcl:125 lib/remote_add.tcl:32 lib/remote_branch_delete.tcl:42
-#: lib/tools_dlg.tcl:40 lib/tools_dlg.tcl:204 lib/tools_dlg.tcl:352
-#: lib/transport.tcl:108
-msgid "Cancel"
-msgstr "中止"
+#: lib/remote_branch_delete.tcl:72 lib/transport.tcl:187
+msgid "Arbitrary Location:"
+msgstr "任意の位置:"
-#: lib/branch_checkout.tcl:32 lib/browser.tcl:287 lib/tools_dlg.tcl:328
-msgid "Revision"
-msgstr "ã\83ªã\83\93ã\82¸ã\83§ã\83³"
+#: lib/remote_branch_delete.tcl:88
+msgid "Branches"
+msgstr "ã\83\96ã\83©ã\83³ã\83\81"
-#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:280
-msgid "Options"
-msgstr "オプション"
+#: lib/remote_branch_delete.tcl:110
+msgid "Delete Only If"
+msgstr "条件付で削除"
-#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
-msgid "Fetch Tracking Branch"
-msgstr "ã\83\88ã\83©ã\83\83ã\82ã\83³ã\82°ã\83»ã\83\96ã\83©ã\83³ã\83\81ã\82\92ã\83\95ã\82§ã\83\83ã\83\81"
+#: lib/remote_branch_delete.tcl:112
+msgid "Merged Into:"
+msgstr "ã\83\9eã\83¼ã\82¸å\85\88:"
-#: lib/branch_checkout.tcl:44
-msgid "Detach From Local Branch"
-msgstr "ローカル・ブランチから削除"
+#: lib/remote_branch_delete.tcl:120 lib/branch_delete.tcl:53
+msgid "Always (Do not perform merge checks)"
+msgstr "無条件(マージ検査をしない)"
-#: lib/branch_create.tcl:22
-msgid "Create Branch"
-msgstr "ブランチを作成"
-
-#: lib/branch_create.tcl:27
-msgid "Create New Branch"
-msgstr "ブランチを新規作成"
-
-#: lib/branch_create.tcl:31 lib/choose_repository.tcl:381
-msgid "Create"
-msgstr "作成"
-
-#: lib/branch_create.tcl:40
-msgid "Branch Name"
-msgstr "ブランチ名"
-
-#: lib/branch_create.tcl:43 lib/remote_add.tcl:39 lib/tools_dlg.tcl:50
-msgid "Name:"
-msgstr "名前:"
-
-#: lib/branch_create.tcl:58
-msgid "Match Tracking Branch Name"
-msgstr "トラッキング・ブランチ名を合わせる"
-
-#: lib/branch_create.tcl:66
-msgid "Starting Revision"
-msgstr "初期リビジョン"
-
-#: lib/branch_create.tcl:72
-msgid "Update Existing Branch:"
-msgstr "既存のブランチを更新:"
-
-#: lib/branch_create.tcl:75
-msgid "No"
-msgstr "いいえ"
+#: lib/remote_branch_delete.tcl:153
+msgid "A branch is required for 'Merged Into'."
+msgstr "'マージ先' にはブランチが必要です。"
-#: lib/branch_create.tcl:80
-msgid "Fast Forward Only"
-msgstr "早送りのみ"
+#: lib/remote_branch_delete.tcl:185
+#, tcl-format
+msgid ""
+"The following branches are not completely merged into %s:\n"
+"\n"
+" - %s"
+msgstr ""
+"以下のブランチは %s に完全にマージされていません:\n"
+"\n"
+" - %s"
-#: lib/branch_create.tcl:85 lib/checkout_op.tcl:571
-msgid "Reset"
-msgstr "リセット"
+#: lib/remote_branch_delete.tcl:190
+#, tcl-format
+msgid ""
+"One or more of the merge tests failed because you have not fetched the "
+"necessary commits. Try fetching from %s first."
+msgstr ""
+"必要なコミットが不足しているために、マージ検査が失敗しました。まず %s から"
+"フェッチして下さい。"
-#: lib/branch_create.tcl:97
-msgid "Checkout After Creation"
-msgstr "作成してすぐチェックアウト"
+#: lib/remote_branch_delete.tcl:208
+msgid "Please select one or more branches to delete."
+msgstr "削除するブランチを選択して下さい。"
-#: lib/branch_create.tcl:131
-msgid "Please select a tracking branch."
-msgstr "トラッキング・ブランチを選択して下さい。"
+#: lib/remote_branch_delete.tcl:218 lib/branch_delete.tcl:115
+msgid ""
+"Recovering deleted branches is difficult.\n"
+"\n"
+"Delete the selected branches?"
+msgstr ""
+"削除したブランチを回復するのは困難です。\n"
+"\n"
+"選択したブランチを削除して良いですか?"
-#: lib/branch_create.tcl:140
+#: lib/remote_branch_delete.tcl:227
#, tcl-format
-msgid "Tracking branch %s is not a branch in the remote repository."
-msgstr "トラッキング・ブランチ %s は遠隔リポジトリのブランチではありません。"
+msgid "Deleting branches from %s"
+msgstr "%s からブランチを削除しています。"
-#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
-msgid "Please supply a branch name."
-msgstr "ã\83\96ã\83©ã\83³ã\83\81å\90\8dã\82\92æ\8c\87å®\9aã\81\97ã\81¦ä¸\8bã\81\95ã\81\84。"
+#: lib/remote_branch_delete.tcl:300
+msgid "No repository selected."
+msgstr "ã\83ªã\83\9dã\82¸ã\83\88ã\83ªã\81\8cé\81¸æ\8a\9eã\81\95ã\82\8cã\81¦ã\81\84ã\81¾ã\81\9bã\82\93。"
-#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
+#: lib/remote_branch_delete.tcl:305
#, tcl-format
-msgid "'%s' is not an acceptable branch name."
-msgstr "'%s' はブランチ名に使えません。"
+msgid "Scanning %s..."
+msgstr "%s をスキャンしています…"
-#: lib/branch_delete.tcl:15
+#: lib/branch_delete.tcl:16
msgid "Delete Branch"
msgstr "ブランチ削除"
-#: lib/branch_delete.tcl:20
+#: lib/branch_delete.tcl:21
msgid "Delete Local Branch"
msgstr "ローカル・ブランチを削除"
-#: lib/branch_delete.tcl:37
+#: lib/branch_delete.tcl:39
msgid "Local Branches"
msgstr "ローカル・ブランチ"
-#: lib/branch_delete.tcl:52
+#: lib/branch_delete.tcl:51
msgid "Delete Only If Merged Into"
msgstr "マージ済みの時のみ削除"
-#: lib/branch_delete.tcl:54 lib/remote_branch_delete.tcl:119
-msgid "Always (Do not perform merge checks)"
-msgstr "無条件(マージ検査をしない)"
-
#: lib/branch_delete.tcl:103
#, tcl-format
msgid "The following branches are not completely merged into %s:"
msgstr "以下のブランチは %s に完全にマージされていません:"
-#: lib/branch_delete.tcl:115 lib/remote_branch_delete.tcl:217
-msgid ""
-"Recovering deleted branches is difficult.\n"
-"\n"
-"Delete the selected branches?"
-msgstr ""
-"削除したブランチを回復するのは困難です。\n"
-"\n"
-"選択したブランチを削除して良いですか?"
-
#: lib/branch_delete.tcl:141
#, tcl-format
msgid ""
"以下のブランチを削除できません:\n"
"%s"
-#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22
-msgid "Rename Branch"
-msgstr "ブランチの名前変更"
+#: lib/choose_rev.tcl:52
+msgid "This Detached Checkout"
+msgstr "分離されたチェックアウト"
-#: lib/branch_rename.tcl:26
-msgid "Rename"
-msgstr "名前変更"
+#: lib/choose_rev.tcl:60
+msgid "Revision Expression:"
+msgstr "リビジョン式:"
-#: lib/branch_rename.tcl:36
-msgid "Branch:"
-msgstr "ã\83\96ã\83©ã\83³ã\83\81:"
+#: lib/choose_rev.tcl:72
+msgid "Local Branch"
+msgstr "ã\83ã\83¼ã\82«ã\83«ã\83»ã\83\96ã\83©ã\83³ã\83\81"
-#: lib/branch_rename.tcl:39
-msgid "New Name:"
-msgstr "新しい名前:"
+#: lib/choose_rev.tcl:77
+msgid "Tracking Branch"
+msgstr "トラッキング・ブランチ"
-#: lib/branch_rename.tcl:75
-msgid "Please select a branch to rename."
-msgstr "名前を変更するブランチを選んで下さい。"
+#: lib/choose_rev.tcl:82 lib/choose_rev.tcl:544
+msgid "Tag"
+msgstr "タグ"
-#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:202
+#: lib/choose_rev.tcl:321
#, tcl-format
-msgid "Branch '%s' already exists."
-msgstr "'%s'というブランチは既に存在します。"
+msgid "Invalid revision: %s"
+msgstr "無効なリビジョン: %s"
-#: lib/branch_rename.tcl:117
-#, tcl-format
-msgid "Failed to rename '%s'."
-msgstr "'%s'の名前変更に失敗しました。"
+#: lib/choose_rev.tcl:342
+msgid "No revision selected."
+msgstr "リビジョンが未選択です。"
-#: lib/browser.tcl:17
-msgid "Starting..."
-msgstr "起動中…"
+#: lib/choose_rev.tcl:350
+msgid "Revision expression is empty."
+msgstr "リビジョン式が空です。"
-#: lib/browser.tcl:26
-msgid "File Browser"
-msgstr "ファイル・ブラウザ"
+#: lib/choose_rev.tcl:537
+msgid "Updated"
+msgstr "更新しました"
-#: lib/browser.tcl:126 lib/browser.tcl:143
-#, tcl-format
-msgid "Loading %s..."
-msgstr "%s をロード中…"
+#: lib/choose_rev.tcl:565
+msgid "URL"
+msgstr "URL"
-#: lib/browser.tcl:187
-msgid "[Up To Parent]"
-msgstr "[上位フォルダへ]"
+#: lib/console.tcl:59
+msgid "Working... please wait..."
+msgstr "実行中…お待ち下さい…"
-#: lib/browser.tcl:267 lib/browser.tcl:273
-msgid "Browse Branch Files"
-msgstr "現在のブランチのファイルを見る"
+#: lib/console.tcl:81 lib/checkout_op.tcl:146 lib/database.tcl:30
+#: lib/sshkey.tcl:55
+msgid "Close"
+msgstr "閉じる"
-#: lib/browser.tcl:278 lib/choose_repository.tcl:398
-#: lib/choose_repository.tcl:486 lib/choose_repository.tcl:497
-#: lib/choose_repository.tcl:1028
-msgid "Browse"
-msgstr "ブラウズ"
+#: lib/console.tcl:186
+msgid "Success"
+msgstr "成功"
+
+#: lib/console.tcl:200
+msgid "Error: Command Failed"
+msgstr "エラー: コマンドが失敗しました"
#: lib/checkout_op.tcl:85
#, tcl-format
msgid "fatal: Cannot resolve %s"
msgstr "致命的エラー: %s を解決できません"
-#: lib/checkout_op.tcl:146 lib/console.tcl:81 lib/database.tcl:31
-#: lib/sshkey.tcl:53
-msgid "Close"
-msgstr "閉じる"
-
#: lib/checkout_op.tcl:175
#, tcl-format
msgid "Branch '%s' does not exist."
msgid "Failed to configure simplified git-pull for '%s'."
msgstr "'%s' に簡易 git-pull を設定できませんでした"
+#: lib/checkout_op.tcl:202 lib/branch_rename.tcl:102
+#, tcl-format
+msgid "Branch '%s' already exists."
+msgstr "'%s'というブランチは既に存在します。"
+
#: lib/checkout_op.tcl:229
#, tcl-format
msgid ""
msgid "Reset '%s'?"
msgstr "'%s' をリセットしますか?"
-#: lib/checkout_op.tcl:567 lib/merge.tcl:164 lib/tools_dlg.tcl:343
-msgid "Visualize"
-msgstr "可視化"
+#: lib/checkout_op.tcl:571 lib/branch_create.tcl:85
+msgid "Reset"
+msgstr "リセット"
#: lib/checkout_op.tcl:635
#, tcl-format
"ましたが、 Git の内部データを更新できませんでした。\n"
"起こるはずのないエラーです。あきらめて %s を終了します。"
-#: lib/choose_font.tcl:39
-msgid "Select"
-msgstr "選択"
+#: lib/blame.tcl:73
+msgid "File Viewer"
+msgstr "ファイルピューワ"
-#: lib/choose_font.tcl:53
-msgid "Font Family"
-msgstr "ã\83\95ã\82©ã\83³ã\83\88ã\83»ã\83\95ã\82¡ã\83\9fã\83ªã\83¼"
+#: lib/blame.tcl:79
+msgid "Commit:"
+msgstr "ã\82³ã\83\9fã\83\83ã\83\88:"
-#: lib/choose_font.tcl:74
-msgid "Font Size"
-msgstr "ã\83\95ã\82©ã\83³ã\83\88ã\81®å¤§ã\81\8dã\81\95"
+#: lib/blame.tcl:280
+msgid "Copy Commit"
+msgstr "ã\82³ã\83\9fã\83\83ã\83\88ã\82\92ã\82³ã\83\94ã\83¼"
-#: lib/choose_font.tcl:91
-msgid "Font Example"
-msgstr "ã\83\95ã\82©ã\83³ã\83\88ã\83»ã\82µã\83³ã\83\97ã\83«"
+#: lib/blame.tcl:284
+msgid "Find Text..."
+msgstr "ã\83\86ã\82ã\82¹ã\83\88ã\82\92æ¤\9cç´¢"
-#: lib/choose_font.tcl:103
-msgid ""
-"This is example text.\n"
-"If you like this text, it can be your font."
-msgstr ""
-"これはサンプル文です。\n"
-"このフォントが気に入ればお使いになれます。"
+#: lib/blame.tcl:288
+msgid "Goto Line..."
+msgstr "指定行に移動…"
-#: lib/choose_repository.tcl:28
-msgid "Git Gui"
-msgstr "Git GUI"
+#: lib/blame.tcl:297
+msgid "Do Full Copy Detection"
+msgstr "コピー検知"
-#: lib/choose_repository.tcl:87 lib/choose_repository.tcl:386
-msgid "Create New Repository"
-msgstr "æ\96°ã\81\97ã\81\84ã\83ªã\83\9dã\82¸ã\83\88ã\83ªã\82\92ä½\9cる"
+#: lib/blame.tcl:301
+msgid "Show History Context"
+msgstr "æ\96\87è\84\88ã\82\92è¦\8bã\81\9bる"
-#: lib/choose_repository.tcl:93
-msgid "New..."
-msgstr "新規…"
+#: lib/blame.tcl:304
+msgid "Blame Parent Commit"
+msgstr "親コミットを注釈"
-#: lib/choose_repository.tcl:100 lib/choose_repository.tcl:471
-msgid "Clone Existing Repository"
-msgstr "既存リポジトリを複製する"
+#: lib/blame.tcl:466
+#, tcl-format
+msgid "Reading %s..."
+msgstr "%s を読んでいます…"
-#: lib/choose_repository.tcl:106
-msgid "Clone..."
-msgstr "複製…"
+#: lib/blame.tcl:594
+msgid "Loading copy/move tracking annotations..."
+msgstr "コピー・移動追跡データを読んでいます…"
-#: lib/choose_repository.tcl:113 lib/choose_repository.tcl:1016
-msgid "Open Existing Repository"
-msgstr "既存リポジトリを開く"
+#: lib/blame.tcl:614
+msgid "lines annotated"
+msgstr "行を注釈しました"
-#: lib/choose_repository.tcl:119
-msgid "Open..."
-msgstr "開く…"
+#: lib/blame.tcl:806
+msgid "Loading original location annotations..."
+msgstr "元位置行の注釈データを読んでいます…"
-#: lib/choose_repository.tcl:132
-msgid "Recent Repositories"
-msgstr "æ\9c\80è¿\91使ã\81£ã\81\9fã\83ªã\83\9dã\82¸ã\83\88ã\83ª"
+#: lib/blame.tcl:809
+msgid "Annotation complete."
+msgstr "注é\87\88å®\8cäº\86ã\81\97ã\81¾ã\81\97ã\81\9f"
-#: lib/choose_repository.tcl:138
-msgid "Open Recent Repository:"
-msgstr "最近使ったリポジトリを開く"
+#: lib/blame.tcl:839
+msgid "Busy"
+msgstr "実行中"
-#: lib/choose_repository.tcl:306 lib/choose_repository.tcl:313
-#: lib/choose_repository.tcl:320
-#, tcl-format
-msgid "Failed to create repository %s:"
-msgstr "リポジトリ %s を作製できません:"
+#: lib/blame.tcl:840
+msgid "Annotation process is already running."
+msgstr "すでに blame プロセスを実行中です。"
-#: lib/choose_repository.tcl:391
-msgid "Directory:"
-msgstr "ã\83\87ã\82£ã\83¬ã\82¯ã\83\88ã\83ª:"
+#: lib/blame.tcl:879
+msgid "Running thorough copy detection..."
+msgstr "ã\82³ã\83\94ã\83¼æ¤\9cç\9f¥ã\82\92å®\9fè¡\8cä¸â\80¦"
-#: lib/choose_repository.tcl:423 lib/choose_repository.tcl:550
-#: lib/choose_repository.tcl:1052
-msgid "Git Repository"
-msgstr "GIT リポジトリ"
+#: lib/blame.tcl:947
+msgid "Loading annotation..."
+msgstr "注釈を読み込んでいます…"
-#: lib/choose_repository.tcl:448
-#, tcl-format
-msgid "Directory %s already exists."
-msgstr "ディレクトリ '%s' は既に存在します。"
+#: lib/blame.tcl:1000
+msgid "Author:"
+msgstr "作者:"
-#: lib/choose_repository.tcl:452
-#, tcl-format
-msgid "File %s already exists."
-msgstr "ファイル '%s' は既に存在します。"
+#: lib/blame.tcl:1004
+msgid "Committer:"
+msgstr "コミット者:"
-#: lib/choose_repository.tcl:466
-msgid "Clone"
-msgstr "複製"
+#: lib/blame.tcl:1009
+msgid "Original File:"
+msgstr "元ファイル"
-#: lib/choose_repository.tcl:479
-msgid "Source Location:"
-msgstr "ソースの位置"
+#: lib/blame.tcl:1057
+msgid "Cannot find HEAD commit:"
+msgstr "HEAD コミットが見つかりません"
-#: lib/choose_repository.tcl:490
-msgid "Target Directory:"
-msgstr "先ディレクトリ:"
+#: lib/blame.tcl:1112
+msgid "Cannot find parent commit:"
+msgstr "親コミットが見つかりません:"
+
+#: lib/blame.tcl:1127
+msgid "Unable to display parent"
+msgstr "親を表示できません"
+
+#: lib/blame.tcl:1128 lib/diff.tcl:356
+msgid "Error loading diff:"
+msgstr "diff を読む際のエラーです:"
+
+#: lib/blame.tcl:1269
+msgid "Originally By:"
+msgstr "原作者:"
+
+#: lib/blame.tcl:1275
+msgid "In File:"
+msgstr "ファイル:"
+
+#: lib/blame.tcl:1280
+msgid "Copied Or Moved Here By:"
+msgstr "複写・移動者:"
+
+#: lib/about.tcl:26
+msgid "git-gui - a graphical user interface for Git."
+msgstr "Git のグラフィカルUI git-gui"
+
+#: lib/choose_repository.tcl:33
+msgid "Git Gui"
+msgstr "Git GUI"
+
+#: lib/choose_repository.tcl:92 lib/choose_repository.tcl:412
+msgid "Create New Repository"
+msgstr "新しいリポジトリを作る"
+
+#: lib/choose_repository.tcl:98
+msgid "New..."
+msgstr "新規…"
+
+#: lib/choose_repository.tcl:105 lib/choose_repository.tcl:496
+msgid "Clone Existing Repository"
+msgstr "既存リポジトリを複製する"
+
+#: lib/choose_repository.tcl:116
+msgid "Clone..."
+msgstr "複製…"
+
+#: lib/choose_repository.tcl:123 lib/choose_repository.tcl:1064
+msgid "Open Existing Repository"
+msgstr "既存リポジトリを開く"
+
+#: lib/choose_repository.tcl:129
+msgid "Open..."
+msgstr "開く…"
+
+#: lib/choose_repository.tcl:142
+msgid "Recent Repositories"
+msgstr "最近使ったリポジトリ"
+
+#: lib/choose_repository.tcl:148
+msgid "Open Recent Repository:"
+msgstr "最近使ったリポジトリを開く"
+
+#: lib/choose_repository.tcl:316 lib/choose_repository.tcl:323
+#: lib/choose_repository.tcl:330
+#, tcl-format
+msgid "Failed to create repository %s:"
+msgstr "リポジトリ %s を作製できません:"
+
+#: lib/choose_repository.tcl:407 lib/branch_create.tcl:33
+msgid "Create"
+msgstr "作成"
+
+#: lib/choose_repository.tcl:417
+msgid "Directory:"
+msgstr "ディレクトリ:"
+
+#: lib/choose_repository.tcl:422 lib/choose_repository.tcl:509
+#: lib/choose_repository.tcl:518 lib/choose_repository.tcl:1074
+#: lib/browser.tcl:288
+msgid "Browse"
+msgstr "ブラウズ"
+
+#: lib/choose_repository.tcl:447 lib/choose_repository.tcl:573
+#: lib/choose_repository.tcl:1098
+msgid "Git Repository"
+msgstr "GIT リポジトリ"
-#: lib/choose_repository.tcl:502
+#: lib/choose_repository.tcl:472
+#, tcl-format
+msgid "Directory %s already exists."
+msgstr "ディレクトリ '%s' は既に存在します。"
+
+#: lib/choose_repository.tcl:476
+#, tcl-format
+msgid "File %s already exists."
+msgstr "ファイル '%s' は既に存在します。"
+
+#: lib/choose_repository.tcl:491
+msgid "Clone"
+msgstr "複製"
+
+#: lib/choose_repository.tcl:504
+msgid "Source Location:"
+msgstr "ソースの位置"
+
+#: lib/choose_repository.tcl:513
+msgid "Target Directory:"
+msgstr "先ディレクトリ:"
+
+#: lib/choose_repository.tcl:523
msgid "Clone Type:"
msgstr "複製方式:"
-#: lib/choose_repository.tcl:508
+#: lib/choose_repository.tcl:528
msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
msgstr "標準(高速・中冗長度・ハードリンク)"
-#: lib/choose_repository.tcl:514
+#: lib/choose_repository.tcl:533
msgid "Full Copy (Slower, Redundant Backup)"
msgstr "全複写(低速・冗長バックアップ)"
-#: lib/choose_repository.tcl:520
+#: lib/choose_repository.tcl:538
msgid "Shared (Fastest, Not Recommended, No Backup)"
msgstr "共有(最高速・非推奨・バックアップ無し)"
-#: lib/choose_repository.tcl:556 lib/choose_repository.tcl:603
-#: lib/choose_repository.tcl:749 lib/choose_repository.tcl:819
-#: lib/choose_repository.tcl:1058 lib/choose_repository.tcl:1066
+#: lib/choose_repository.tcl:545
+msgid "Recursively clone submodules too"
+msgstr "サブモジュールも再帰的に複製する"
+
+#: lib/choose_repository.tcl:579 lib/choose_repository.tcl:626
+#: lib/choose_repository.tcl:772 lib/choose_repository.tcl:842
+#: lib/choose_repository.tcl:1104 lib/choose_repository.tcl:1112
#, tcl-format
msgid "Not a Git repository: %s"
msgstr "Git リポジトリではありません: %s"
-#: lib/choose_repository.tcl:592
+#: lib/choose_repository.tcl:615
msgid "Standard only available for local repository."
msgstr "標準方式は同一計算機上のリポジトリにのみ使えます。"
-#: lib/choose_repository.tcl:596
+#: lib/choose_repository.tcl:619
msgid "Shared only available for local repository."
msgstr "共有方式は同一計算機上のリポジトリにのみ使えます。"
-#: lib/choose_repository.tcl:617
+#: lib/choose_repository.tcl:640
#, tcl-format
msgid "Location %s already exists."
msgstr "'%s' は既に存在します。"
-#: lib/choose_repository.tcl:628
+#: lib/choose_repository.tcl:651
msgid "Failed to configure origin"
msgstr "origin を設定できませんでした"
-#: lib/choose_repository.tcl:640
+#: lib/choose_repository.tcl:663
msgid "Counting objects"
msgstr "オブジェクトを数えています"
-#: lib/choose_repository.tcl:641
+#: lib/choose_repository.tcl:664
msgid "buckets"
msgstr "バケツ"
-#: lib/choose_repository.tcl:665
+#: lib/choose_repository.tcl:688
#, tcl-format
msgid "Unable to copy objects/info/alternates: %s"
msgstr "objects/info/alternates を複写できません: %s"
-#: lib/choose_repository.tcl:701
+#: lib/choose_repository.tcl:724
#, tcl-format
msgid "Nothing to clone from %s."
msgstr "%s から複製する内容はありません"
-#: lib/choose_repository.tcl:703 lib/choose_repository.tcl:917
-#: lib/choose_repository.tcl:929
+#: lib/choose_repository.tcl:726 lib/choose_repository.tcl:940
+#: lib/choose_repository.tcl:952
msgid "The 'master' branch has not been initialized."
msgstr "'master' ブランチが初期化されていません"
-#: lib/choose_repository.tcl:716
+#: lib/choose_repository.tcl:739
msgid "Hardlinks are unavailable. Falling back to copying."
msgstr "ハードリンクが作れないので、コピーします"
-#: lib/choose_repository.tcl:728
+#: lib/choose_repository.tcl:751
#, tcl-format
msgid "Cloning from %s"
msgstr "%s から複製しています"
-#: lib/choose_repository.tcl:759
+#: lib/choose_repository.tcl:782
msgid "Copying objects"
msgstr "オブジェクトを複写しています"
-#: lib/choose_repository.tcl:760
+#: lib/choose_repository.tcl:783
msgid "KiB"
msgstr "KiB"
-#: lib/choose_repository.tcl:784
+#: lib/choose_repository.tcl:807
#, tcl-format
msgid "Unable to copy object: %s"
msgstr "オブジェクトを複写できません: %s"
-#: lib/choose_repository.tcl:794
+#: lib/choose_repository.tcl:817
msgid "Linking objects"
msgstr "オブジェクトを連結しています"
-#: lib/choose_repository.tcl:795
+#: lib/choose_repository.tcl:818
msgid "objects"
msgstr "オブジェクト"
-#: lib/choose_repository.tcl:803
+#: lib/choose_repository.tcl:826
#, tcl-format
msgid "Unable to hardlink object: %s"
msgstr "オブジェクトをハードリンクできません: %s"
-#: lib/choose_repository.tcl:858
+#: lib/choose_repository.tcl:881
msgid "Cannot fetch branches and objects. See console output for details."
msgstr "ブランチやオブジェクトを取得できません。コンソール出力を見て下さい"
-#: lib/choose_repository.tcl:869
+#: lib/choose_repository.tcl:892
msgid "Cannot fetch tags. See console output for details."
msgstr "タグを取得できません。コンソール出力を見て下さい"
-#: lib/choose_repository.tcl:893
+#: lib/choose_repository.tcl:916
msgid "Cannot determine HEAD. See console output for details."
msgstr "HEAD を確定できません。コンソール出力を見て下さい"
-#: lib/choose_repository.tcl:902
+#: lib/choose_repository.tcl:925
#, tcl-format
msgid "Unable to cleanup %s"
msgstr "%s を掃除できません"
-#: lib/choose_repository.tcl:908
+#: lib/choose_repository.tcl:931
msgid "Clone failed."
msgstr "複写に失敗しました。"
-#: lib/choose_repository.tcl:915
+#: lib/choose_repository.tcl:938
msgid "No default branch obtained."
msgstr "デフォールト・ブランチが取得されませんでした"
-#: lib/choose_repository.tcl:926
+#: lib/choose_repository.tcl:949
#, tcl-format
msgid "Cannot resolve %s as a commit."
msgstr "%s をコミットとして解釈できません"
-#: lib/choose_repository.tcl:938
+#: lib/choose_repository.tcl:961
msgid "Creating working directory"
msgstr "作業ディレクトリを作成しています"
-#: lib/choose_repository.tcl:939 lib/index.tcl:67 lib/index.tcl:130
-#: lib/index.tcl:198
+#: lib/choose_repository.tcl:962 lib/index.tcl:70 lib/index.tcl:136
+#: lib/index.tcl:207
msgid "files"
msgstr "ファイル"
-#: lib/choose_repository.tcl:968
+#: lib/choose_repository.tcl:981
+msgid "Cannot clone submodules."
+msgstr "サブモジュールが複製できません。"
+
+#: lib/choose_repository.tcl:990
+msgid "Cloning submodules"
+msgstr "サブモジュールを複製しています"
+
+#: lib/choose_repository.tcl:1015
msgid "Initial file checkout failed."
msgstr "初期チェックアウトに失敗しました"
-#: lib/choose_repository.tcl:1011
+#: lib/choose_repository.tcl:1059
msgid "Open"
msgstr "開く"
-#: lib/choose_repository.tcl:1021
+#: lib/choose_repository.tcl:1069
msgid "Repository:"
msgstr "リポジトリ:"
-#: lib/choose_repository.tcl:1072
+#: lib/choose_repository.tcl:1118
#, tcl-format
msgid "Failed to open repository %s:"
msgstr "リポジトリ %s を開けません:"
-#: lib/choose_rev.tcl:53
-msgid "This Detached Checkout"
-msgstr "分離されたチェックアウト"
+#: lib/branch_rename.tcl:15 lib/branch_rename.tcl:23
+msgid "Rename Branch"
+msgstr "ブランチの名前変更"
-#: lib/choose_rev.tcl:60
-msgid "Revision Expression:"
-msgstr "リビジョン式:"
+#: lib/branch_rename.tcl:28
+msgid "Rename"
+msgstr "名前変更"
-#: lib/choose_rev.tcl:74
-msgid "Local Branch"
-msgstr "ã\83ã\83¼ã\82«ã\83«ã\83»ã\83\96ã\83©ã\83³ã\83\81"
+#: lib/branch_rename.tcl:38
+msgid "Branch:"
+msgstr "ã\83\96ã\83©ã\83³ã\83\81:"
-#: lib/choose_rev.tcl:79
-msgid "Tracking Branch"
-msgstr "トラッキング・ブランチ"
+#: lib/branch_rename.tcl:46
+msgid "New Name:"
+msgstr "新しい名前:"
-#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:538
-msgid "Tag"
-msgstr "タグ"
+#: lib/branch_rename.tcl:81
+msgid "Please select a branch to rename."
+msgstr "名前を変更するブランチを選んで下さい。"
-#: lib/choose_rev.tcl:317
-#, tcl-format
-msgid "Invalid revision: %s"
-msgstr "無効なリビジョン: %s"
+#: lib/branch_rename.tcl:92 lib/branch_create.tcl:154
+msgid "Please supply a branch name."
+msgstr "ブランチ名を指定して下さい。"
-#: lib/choose_rev.tcl:338
-msgid "No revision selected."
-msgstr "リビジョンが未選択です。"
+#: lib/branch_rename.tcl:112 lib/branch_create.tcl:165
+#, tcl-format
+msgid "'%s' is not an acceptable branch name."
+msgstr "'%s' はブランチ名に使えません。"
-#: lib/choose_rev.tcl:346
-msgid "Revision expression is empty."
-msgstr "リビジョン式が空です。"
+#: lib/branch_rename.tcl:123
+#, tcl-format
+msgid "Failed to rename '%s'."
+msgstr "'%s'の名前変更に失敗しました。"
-#: lib/choose_rev.tcl:531
-msgid "Updated"
-msgstr "更新しました"
+#: lib/shortcut.tcl:21 lib/shortcut.tcl:62
+msgid "Cannot write shortcut:"
+msgstr "ショートカットが書けません:"
-#: lib/choose_rev.tcl:559
-msgid "URL"
-msgstr "URL"
+#: lib/shortcut.tcl:137
+msgid "Cannot write icon:"
+msgstr "アイコンが書けません:"
-#: lib/commit.tcl:9
-msgid ""
-"There is nothing to amend.\n"
-"\n"
-"You are about to create the initial commit. There is no commit before this "
-"to amend.\n"
-msgstr ""
-"訂正するコミットがそもそもありません。\n"
-"\n"
-"これから作るのは最初のコミットです。その前にはまだ訂正するようなコミットはあ"
-"りません。\n"
+#: lib/search.tcl:48
+msgid "Find:"
+msgstr "検索:"
-#: lib/commit.tcl:18
-msgid ""
-"Cannot amend while merging.\n"
-"\n"
-"You are currently in the middle of a merge that has not been fully "
-"completed. You cannot amend the prior commit unless you first abort the "
-"current merge activity.\n"
-msgstr ""
-"マージ中にコミットの訂正はできません。\n"
-"\n"
-"現在はまだマージの途中です。先にこのマージを中止しないと、前のコミットの訂正"
-"はできません\n"
+#: lib/search.tcl:50
+msgid "Next"
+msgstr "次"
-#: lib/commit.tcl:48
-msgid "Error loading commit data for amend:"
-msgstr "訂正するコミットのデータを読めません:"
+#: lib/search.tcl:51
+msgid "Prev"
+msgstr "前"
-#: lib/commit.tcl:75
-msgid "Unable to obtain your identity:"
-msgstr "ユーザの正体を確認できません:"
+#: lib/search.tcl:52
+msgid "RegExp"
+msgstr "正規表現"
-#: lib/commit.tcl:80
-msgid "Invalid GIT_COMMITTER_IDENT:"
-msgstr "GIT_COMMITTER_IDENT が無効です:"
+#: lib/search.tcl:54
+msgid "Case"
+msgstr "大文字小文字を区別"
-#: lib/commit.tcl:129
+#: lib/status_bar.tcl:87
#, tcl-format
-msgid "warning: Tcl does not support encoding '%s'."
-msgstr "警告: Tcl はエンコーディング '%s' をサポートしていません"
-
-#: lib/commit.tcl:149
-msgid ""
-"Last scanned state does not match repository state.\n"
-"\n"
-"Another Git program has modified this repository since the last scan. A "
-"rescan must be performed before another commit can be created.\n"
-"\n"
-"The rescan will be automatically started now.\n"
-msgstr ""
-"最後にスキャンした状態はリポジトリの状態と合致しません。\n"
-"\n"
-"最後にスキャンして以後、別の Git プログラムがリポジトリを変更しています。新し"
-"くコミットする前に、再スキャンが必要です。\n"
-"\n"
-"自動的に再スキャンを開始します。\n"
+msgid "%s ... %*i of %*i %s (%3i%%)"
+msgstr "%1$s ... %4$*i %6$s 中の %2$*i (%7$3i%%)"
-#: lib/commit.tcl:172
-#, tcl-format
-msgid ""
-"Unmerged files cannot be committed.\n"
-"\n"
-"File %s has merge conflicts. You must resolve them and stage the file "
-"before committing.\n"
-msgstr ""
-"マージしていないファイルはコミットできません。\n"
-"\n"
-"ファイル %s にはマージ衝突が残っています。まず解決してコミット予定に加える必"
-"要があります。\n"
+#: lib/tools_dlg.tcl:22
+msgid "Add Tool"
+msgstr "ツールの追加"
-#: lib/commit.tcl:180
-#, tcl-format
-msgid ""
-"Unknown file state %s detected.\n"
-"\n"
-"File %s cannot be committed by this program.\n"
-msgstr ""
-"不明なファイル状態 %s です。\n"
-"\n"
-"ファイル %s は本プログラムではコミットできません。\n"
+#: lib/tools_dlg.tcl:28
+msgid "Add New Tool Command"
+msgstr "新規ツールコマンドの追加"
-#: lib/commit.tcl:188
-msgid ""
-"No changes to commit.\n"
-"\n"
-"You must stage at least 1 file before you can commit.\n"
-msgstr ""
-"コミットする変更がありません。\n"
-"\n"
-"最低一つの変更をコミット予定に加えてからコミットして下さい。\n"
+#: lib/tools_dlg.tcl:34
+msgid "Add globally"
+msgstr "全体に追加"
-#: lib/commit.tcl:203
-msgid ""
-"Please supply a commit message.\n"
-"\n"
-"A good commit message has the following format:\n"
-"\n"
-"- First line: Describe in one sentence what you did.\n"
-"- Second line: Blank\n"
-"- Remaining lines: Describe why this change is good.\n"
-msgstr ""
-"コミット・メッセージを入力して下さい。\n"
-"\n"
-"正しいコミット・メッセージは:\n"
-"\n"
-"- 第1行: 何をしたか、を1行で要約。\n"
-"- 第2行: 空白\n"
-"- 残りの行: なぜ、この変更が良い変更か、の説明。\n"
+#: lib/tools_dlg.tcl:37 lib/remote_add.tcl:30
+msgid "Add"
+msgstr "追加"
-#: lib/commit.tcl:234
-msgid "Calling pre-commit hook..."
-msgstr "ã\82³ã\83\9fã\83\83ã\83\88å\89\8dã\83\95ã\83\83ã\82¯ã\82\92å®\9fè¡\8cä¸ã\83»ã\83»ã\83»"
+#: lib/tools_dlg.tcl:46
+msgid "Tool Details"
+msgstr "ã\83\84ã\83¼ã\83«ã\81®è©³ç´°"
-#: lib/commit.tcl:249
-msgid "Commit declined by pre-commit hook."
-msgstr "コミット前フックがコミットを拒否しました"
+#: lib/tools_dlg.tcl:49
+msgid "Use '/' separators to create a submenu tree:"
+msgstr "'/' でサブメニューを区切ります:"
-#: lib/commit.tcl:272
-msgid "Calling commit-msg hook..."
-msgstr "コミット・メッセージ・フックを実行中・・・"
+#: lib/tools_dlg.tcl:51 lib/remote_add.tcl:41 lib/branch_create.tcl:44
+msgid "Name:"
+msgstr "名前:"
-#: lib/commit.tcl:287
-msgid "Commit declined by commit-msg hook."
-msgstr "ã\82³ã\83\9fã\83\83ã\83\88ã\83»ã\83¡ã\83\83ã\82»ã\83¼ã\82¸ã\83»ã\83\95ã\83\83ã\82¯ã\81\8cã\82³ã\83\9fã\83\83ã\83\88ã\82\92æ\8b\92å\90¦ã\81\97ã\81¾ã\81\97ã\81\9f"
+#: lib/tools_dlg.tcl:60
+msgid "Command:"
+msgstr "ã\82³ã\83\9eã\83³ã\83\89:"
-#: lib/commit.tcl:300
-msgid "Committing changes..."
-msgstr "変更点をコミット中・・・"
+#: lib/tools_dlg.tcl:71
+msgid "Show a dialog before running"
+msgstr "起動する前にダイアログを表示"
-#: lib/commit.tcl:316
-msgid "write-tree failed:"
-msgstr "write-tree が失敗しました:"
+#: lib/tools_dlg.tcl:77
+msgid "Ask the user to select a revision (sets $REVISION)"
+msgstr "ユーザにコミットを一つ選ばせる ($REVISION にセットします)"
-#: lib/commit.tcl:317 lib/commit.tcl:361 lib/commit.tcl:382
-msgid "Commit failed."
-msgstr "ã\82³ã\83\9fã\83\83ã\83\88ã\81«å¤±æ\95\97ã\81\97ã\81¾ã\81\97ã\81\9fã\80\82"
+#: lib/tools_dlg.tcl:82
+msgid "Ask the user for additional arguments (sets $ARGS)"
+msgstr "ã\83¦ã\83¼ã\82¶ã\81«ä»\96ã\81®å¼\95æ\95°ã\82\92追å\8a ã\81\95ã\81\9bã\82\8b ($ARGS ã\81«ã\82»ã\83\83ã\83\88ã\81\97ã\81¾ã\81\99)"
-#: lib/commit.tcl:334
+#: lib/tools_dlg.tcl:89
+msgid "Don't show the command output window"
+msgstr "コマンドからの出力ウィンドウを見せない"
+
+#: lib/tools_dlg.tcl:94
+msgid "Run only if a diff is selected ($FILENAME not empty)"
+msgstr "パッチが選ばれているときだけ動かす($FILENAME が空でない)"
+
+#: lib/tools_dlg.tcl:118
+msgid "Please supply a name for the tool."
+msgstr "ツール名を指定して下さい。"
+
+#: lib/tools_dlg.tcl:126
#, tcl-format
-msgid "Commit %s appears to be corrupt"
-msgstr "ã\82³ã\83\9fã\83\83ã\83\88 %s ã\81¯å£\8aã\82\8cã\81¦ã\81\84ã\81¾ã\81\99"
+msgid "Tool '%s' already exists."
+msgstr "ã\83\84ã\83¼ã\83« '%s' ã\81¯æ\97¢ã\81«å\98å\9c¨ã\81\97ã\81¾ã\81\99ã\80\82"
-#: lib/commit.tcl:339
+#: lib/tools_dlg.tcl:148
+#, tcl-format
msgid ""
-"No changes to commit.\n"
-"\n"
-"No files were modified by this commit and it was not a merge commit.\n"
-"\n"
-"A rescan will be automatically started now.\n"
+"Could not add tool:\n"
+"%s"
msgstr ""
-"コミットする変更がありません。\n"
-"\n"
-"マージでなく、また、一つも変更点がありません。\n"
-"\n"
-"自動的に再スキャンを開始します。\n"
+"ツールを追加できません:\n"
+"%s"
-#: lib/commit.tcl:346
-msgid "No changes to commit."
-msgstr "ã\82³ã\83\9fã\83\83ã\83\88ã\81\99ã\82\8bå¤\89æ\9b´ã\81\8cã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82"
+#: lib/tools_dlg.tcl:187
+msgid "Remove Tool"
+msgstr "ã\83\84ã\83¼ã\83«ã\81®å\89\8aé\99¤"
-#: lib/commit.tcl:360
-msgid "commit-tree failed:"
-msgstr "commit-tree が失敗しました:"
+#: lib/tools_dlg.tcl:193
+msgid "Remove Tool Commands"
+msgstr "ツールコマンドの削除"
-#: lib/commit.tcl:381
-msgid "update-ref failed:"
-msgstr "update-ref が失敗しました:"
+#: lib/tools_dlg.tcl:198
+msgid "Remove"
+msgstr "削除"
-#: lib/commit.tcl:469
-#, tcl-format
-msgid "Created commit %s: %s"
-msgstr "コミット %s を作成しました: %s"
+#: lib/tools_dlg.tcl:231
+msgid "(Blue denotes repository-local tools)"
+msgstr "(青色はローカルレポジトリのツールです)"
-#: lib/console.tcl:59
-msgid "Working... please wait..."
-msgstr "実行中…お待ち下さい…"
+#: lib/tools_dlg.tcl:292
+#, tcl-format
+msgid "Run Command: %s"
+msgstr "コマンドを起動: %s"
-#: lib/console.tcl:186
-msgid "Success"
-msgstr "成功"
+#: lib/tools_dlg.tcl:306
+msgid "Arguments"
+msgstr "引数"
-#: lib/console.tcl:200
-msgid "Error: Command Failed"
-msgstr "ã\82¨ã\83©ã\83¼: ã\82³ã\83\9eã\83³ã\83\89ã\81\8c失æ\95\97ã\81\97ã\81¾ã\81\97ã\81\9f"
+#: lib/tools_dlg.tcl:321 lib/branch_checkout.tcl:35 lib/browser.tcl:297
+msgid "Revision"
+msgstr "ã\83ªã\83\93ã\82¸ã\83§ã\83³"
-#: lib/database.tcl:43
-msgid "Number of loose objects"
-msgstr "ばらばらなオブジェクトの数"
+#: lib/tools_dlg.tcl:341
+msgid "OK"
+msgstr "OK"
-#: lib/database.tcl:44
-msgid "Disk space used by loose objects"
-msgstr "ばらばらなオブジェクトの使用するディスク量"
+#: lib/tools.tcl:75
+#, tcl-format
+msgid "Running %s requires a selected file."
+msgstr "ファイルを選択してから %s を起動してください。"
-#: lib/database.tcl:45
-msgid "Number of packed objects"
-msgstr "パックされたオブジェクトの数"
+#: lib/tools.tcl:91
+#, tcl-format
+msgid "Are you sure you want to run %1$s on file \"%2$s\"?"
+msgstr "本当にファイル \"%2$s\"で %1$s を起動しますか?"
-#: lib/database.tcl:46
-msgid "Number of packs"
-msgstr "パックの数"
+#: lib/tools.tcl:95
+#, tcl-format
+msgid "Are you sure you want to run %s?"
+msgstr "本当に %s を起動しますか?"
-#: lib/database.tcl:47
-msgid "Disk space used by packed objects"
-msgstr "パックされたオブジェクトの使用するディスク量"
+#: lib/tools.tcl:116
+#, tcl-format
+msgid "Tool: %s"
+msgstr "ツール: %s"
-#: lib/database.tcl:48
-msgid "Packed objects waiting for pruning"
-msgstr "パックに存在するので捨てて良いオブジェクトの数"
+#: lib/tools.tcl:117
+#, tcl-format
+msgid "Running: %s"
+msgstr "実行中: %s"
-#: lib/database.tcl:49
-msgid "Garbage files"
-msgstr "ゴミファイル"
+#: lib/tools.tcl:155
+#, tcl-format
+msgid "Tool completed successfully: %s"
+msgstr "ツールが完了しました: %s"
-#: lib/database.tcl:72
-msgid "Compressing the object database"
-msgstr "データベース圧縮"
+#: lib/tools.tcl:157
+#, tcl-format
+msgid "Tool failed: %s"
+msgstr "ツールが失敗しました: %s"
-#: lib/database.tcl:83
-msgid "Verifying the object database with fsck-objects"
-msgstr "fsck-objects でオブジェクト・データベースを検証しています"
+#: lib/mergetool.tcl:8
+msgid "Force resolution to the base version?"
+msgstr "共通の版を使いますか?"
-#: lib/database.tcl:107
-#, tcl-format
-msgid ""
-"This repository currently has approximately %i loose objects.\n"
-"\n"
-"To maintain optimal performance it is strongly recommended that you compress "
-"the database.\n"
-"\n"
-"Compress the database now?"
-msgstr ""
-"このリポジトリにはおおよそ %i 個の個別オブジェクトがあります\n"
-"\n"
-"最適な性能を保つために、データベースを圧縮することを推奨します\n"
-"\n"
-"データベースを圧縮しますか?"
+#: lib/mergetool.tcl:9
+msgid "Force resolution to this branch?"
+msgstr "自分の側の版を使いますか?"
-#: lib/date.tcl:25
-#, tcl-format
-msgid "Invalid date from Git: %s"
-msgstr "Git から出た無効な日付: %s"
+#: lib/mergetool.tcl:10
+msgid "Force resolution to the other branch?"
+msgstr "相手制の版を使いますか?"
-#: lib/diff.tcl:64
+#: lib/mergetool.tcl:14
#, tcl-format
msgid ""
-"No differences detected.\n"
-"\n"
-"%s has no changes.\n"
+"Note that the diff shows only conflicting changes.\n"
"\n"
-"The modification date of this file was updated by another application, but "
-"the content within the file was not changed.\n"
+"%s will be overwritten.\n"
"\n"
-"A rescan will be automatically started to find other files which may have "
-"the same state."
+"This operation can be undone only by restarting the merge."
msgstr ""
-"変更がありません。\n"
-"\n"
-"%s には変更がありません。\n"
+"競合する変更点だけが表示されていることに注意してください。\n"
"\n"
-"このファイルの変更時刻は他のアプリケーションによって更新されていますがファイ"
-"ル内容には変更がありません。\n"
+"%s は上書きされます。\n"
"\n"
-"同様な状態のファイルを探すために、自動的に再スキャンを開始します。"
+"やり直すにはマージ全体をやり直してください。"
-#: lib/diff.tcl:104
+#: lib/mergetool.tcl:45
#, tcl-format
-msgid "Loading diff of %s..."
-msgstr "%s の変更点をロード中…"
-
-#: lib/diff.tcl:125
-msgid ""
-"LOCAL: deleted\n"
-"REMOTE:\n"
+msgid "File %s seems to have unresolved conflicts, still stage?"
msgstr ""
-"LOCAL: 削除\n"
-"Remote:\n"
+"ファイル %s には解決していない競合部分がまだあるようですが、いいですか?"
-#: lib/diff.tcl:130
-msgid ""
-"REMOTE: deleted\n"
-"LOCAL:\n"
-msgstr ""
-"REMOTE: 削除\n"
-"LOCAL:\n"
+#: lib/mergetool.tcl:60
+#, tcl-format
+msgid "Adding resolution for %s"
+msgstr "%s への解決をステージします"
-#: lib/diff.tcl:137
-msgid "LOCAL:\n"
-msgstr "LOCAL:\n"
+#: lib/mergetool.tcl:141
+msgid "Cannot resolve deletion or link conflicts using a tool"
+msgstr "ツールでは削除やリンク競合は扱えません"
-#: lib/diff.tcl:140
-msgid "REMOTE:\n"
-msgstr "REMOTE\n"
+#: lib/mergetool.tcl:146
+msgid "Conflict file does not exist"
+msgstr "競合ファイルは存在しません。"
-#: lib/diff.tcl:202 lib/diff.tcl:319
+#: lib/mergetool.tcl:246
#, tcl-format
-msgid "Unable to display %s"
-msgstr "%s を表示できません"
-
-#: lib/diff.tcl:203
-msgid "Error loading file:"
-msgstr "ファイルを読む際のエラーです:"
+msgid "Not a GUI merge tool: '%s'"
+msgstr "GUI マージツールではありません: %s"
-#: lib/diff.tcl:210
-msgid "Git Repository (subproject)"
-msgstr "Git リポジトリ(サブプロジェクト)"
+#: lib/mergetool.tcl:275
+#, tcl-format
+msgid "Unsupported merge tool '%s'"
+msgstr "マージツール '%s' はサポートしていません"
-#: lib/diff.tcl:222
-msgid "* Binary file (not showing content)."
-msgstr "* バイナリファイル(内容は表示しません)"
+#: lib/mergetool.tcl:310
+msgid "Merge tool is already running, terminate it?"
+msgstr "マージツールはすでに起動しています。終了しますか?"
-#: lib/diff.tcl:227
+#: lib/mergetool.tcl:330
#, tcl-format
msgid ""
-"* Untracked file is %d bytes.\n"
-"* Showing only first %d bytes.\n"
+"Error retrieving versions:\n"
+"%s"
msgstr ""
-"* 管理外のファイルの大きさは %d バイトです。\n"
-"* 最初の %d バイトだけ表示しています。\n"
+"版の取り出し時にエラーが出ました:\n"
+"%s"
-#: lib/diff.tcl:233
+#: lib/mergetool.tcl:350
#, tcl-format
msgid ""
+"Could not start the merge tool:\n"
"\n"
-"* Untracked file clipped here by %s.\n"
-"* To see the entire file, use an external editor.\n"
+"%s"
msgstr ""
+"マージツールが起動できません:\n"
"\n"
-"\n"
-"* %s は管理外のファイルをここで切りおとしました。\n"
-"* 全体を見るには外部エディタを使ってください。\n"
-
-#: lib/diff.tcl:482
-msgid "Failed to unstage selected hunk."
-msgstr "選択されたパッチをコミット予定から外せません。"
+"%s"
-#: lib/diff.tcl:489
-msgid "Failed to stage selected hunk."
-msgstr "選択されたパッチをコミット予定に加えられません。"
+#: lib/mergetool.tcl:354
+msgid "Running merge tool..."
+msgstr "マージツールを実行しています..."
-#: lib/diff.tcl:568
-msgid "Failed to unstage selected line."
-msgstr "選択されたパッチ行をコミット予定から外せません。"
+#: lib/mergetool.tcl:382 lib/mergetool.tcl:390
+msgid "Merge tool failed."
+msgstr "マージツールが失敗しました。"
-#: lib/diff.tcl:576
-msgid "Failed to stage selected line."
-msgstr "選択されたパッチ行をコミット予定に加えられません。"
+#: lib/option.tcl:11
+#, tcl-format
+msgid "Invalid global encoding '%s'"
+msgstr "全体エンコーディングに 無効な %s が指定されています"
-#: lib/encoding.tcl:443
-msgid "Default"
-msgstr "デフォールト"
+#: lib/option.tcl:19
+#, tcl-format
+msgid "Invalid repo encoding '%s'"
+msgstr "リポジトリエンコーディングに 無効な %s が指定されています"
-#: lib/encoding.tcl:448
+#: lib/option.tcl:119
+msgid "Restore Defaults"
+msgstr "既定値に戻す"
+
+#: lib/option.tcl:123
+msgid "Save"
+msgstr "保存"
+
+#: lib/option.tcl:133
#, tcl-format
-msgid "System (%s)"
-msgstr "システム (%s)"
+msgid "%s Repository"
+msgstr "%s リポジトリ"
-#: lib/encoding.tcl:459 lib/encoding.tcl:465
-msgid "Other"
-msgstr "その他"
+#: lib/option.tcl:134
+msgid "Global (All Repositories)"
+msgstr "大域(全てのリポジトリ)"
-#: lib/error.tcl:20 lib/error.tcl:114
-msgid "error"
-msgstr "ã\82¨ã\83©ã\83¼"
+#: lib/option.tcl:140
+msgid "User Name"
+msgstr "ã\83¦ã\83¼ã\82¶å\90\8d"
-#: lib/error.tcl:36
-msgid "warning"
-msgstr "警告"
+#: lib/option.tcl:141
+msgid "Email Address"
+msgstr "電子メールアドレス"
-#: lib/error.tcl:94
-msgid "You must correct the above errors before committing."
-msgstr "ã\82³ã\83\9fã\83\83ã\83\88ã\81\99ã\82\8bå\89\8dã\81«ã\80\81以ä¸\8aã\81®ã\82¨ã\83©ã\83¼ã\82\92ä¿®æ£ã\81\97ã\81¦ä¸\8bã\81\95ã\81\84"
+#: lib/option.tcl:143
+msgid "Summarize Merge Commits"
+msgstr "ã\83\9eã\83¼ã\82¸ã\82³ã\83\9fã\83\83ã\83\88ã\81®è¦\81ç´\84"
-#: lib/index.tcl:6
-msgid "Unable to unlock the index."
-msgstr "ã\82¤ã\83³ã\83\87ã\83\83ã\82¯ã\82¹ã\82\92ã\83ã\83\83ã\82¯ã\81§ã\81\8dã\81¾ã\81\9bã\82\93"
+#: lib/option.tcl:144
+msgid "Merge Verbosity"
+msgstr "ã\83\9eã\83¼ã\82¸ã\81®å\86\97é\95·åº¦"
-#: lib/index.tcl:15
-msgid "Index Error"
-msgstr "索引エラー"
+#: lib/option.tcl:145
+msgid "Show Diffstat After Merge"
+msgstr "マージ後に diffstat を表示"
-#: lib/index.tcl:17
-msgid ""
-"Updating the Git index failed. A rescan will be automatically started to "
-"resynchronize git-gui."
-msgstr ""
-"GIT インデックスの更新が失敗しました。git-gui と同期をとるために再スキャンし"
-"ます。"
+#: lib/option.tcl:146
+msgid "Use Merge Tool"
+msgstr "マージツールを使用"
-#: lib/index.tcl:28
-msgid "Continue"
-msgstr "続行"
+#: lib/option.tcl:148
+msgid "Trust File Modification Timestamps"
+msgstr "ファイル変更時刻を信頼する"
-#: lib/index.tcl:31
-msgid "Unlock Index"
-msgstr "ã\82¤ã\83³ã\83\87ã\83\83ã\82¯ã\82¹ã\81®ã\83ã\83\83ã\82¯è§£é\99¤"
+#: lib/option.tcl:149
+msgid "Prune Tracking Branches During Fetch"
+msgstr "ã\83\95ã\82§ã\83\83ã\83\81ä¸ã\81«ã\83\88ã\83©ã\83\83ã\82ã\83³ã\82°ã\83\96ã\83©ã\83³ã\83\81ã\82\92å\88\88ã\82\8b"
-#: lib/index.tcl:289
-#, tcl-format
-msgid "Unstaging %s from commit"
-msgstr "コミットから '%s' を降ろす"
+#: lib/option.tcl:150
+msgid "Match Tracking Branches"
+msgstr "トラッキングブランチを合わせる"
-#: lib/index.tcl:328
-msgid "Ready to commit."
-msgstr "ã\82³ã\83\9fã\83\83ã\83\88æº\96å\82\99å®\8cäº\86"
+#: lib/option.tcl:151
+msgid "Use Textconv For Diffs and Blames"
+msgstr "diff ã\81¨æ³¨é\87\88ã\81« textconv ã\82\92使ã\81\86"
-#: lib/index.tcl:341
-#, tcl-format
-msgid "Adding %s"
-msgstr "コミットに %s を加えています"
+#: lib/option.tcl:152
+msgid "Blame Copy Only On Changed Files"
+msgstr "変更されたファイルのみコピー検知を行なう"
-#: lib/index.tcl:398
-#, tcl-format
-msgid "Revert changes in file %s?"
-msgstr "ファイル %s にした変更を元に戻しますか?"
+#: lib/option.tcl:153
+msgid "Maximum Length of Recent Repositories List"
+msgstr "最近使ったリポジトリ一覧の上限"
-#: lib/index.tcl:400
-#, tcl-format
-msgid "Revert changes in these %i files?"
-msgstr "これら %i 個のファイルにした変更を元に戻しますか?"
+#: lib/option.tcl:154
+msgid "Minimum Letters To Blame Copy On"
+msgstr "コピーを検知する最少文字数"
-#: lib/index.tcl:408
-msgid "Any unstaged changes will be permanently lost by the revert."
-msgstr "変更を元に戻すとコミット予定していない変更は全て失われます。"
+#: lib/option.tcl:155
+msgid "Blame History Context Radius (days)"
+msgstr "注釈する履歴半径(日数)"
-#: lib/index.tcl:411
-msgid "Do Nothing"
-msgstr "何もしない"
+#: lib/option.tcl:156
+msgid "Number of Diff Context Lines"
+msgstr "diff の文脈行数"
-#: lib/index.tcl:429
-msgid "Reverting selected files"
-msgstr "選択されたファイルにした変更を元に戻します"
+#: lib/option.tcl:157
+msgid "Additional Diff Parameters"
+msgstr "diff の追加引数"
-#: lib/index.tcl:433
-#, tcl-format
-msgid "Reverting %s"
-msgstr "%s にした変更を元に戻します"
+#: lib/option.tcl:158
+msgid "Commit Message Text Width"
+msgstr "コミットメッセージのテキスト幅"
-#: lib/merge.tcl:13
-msgid ""
-"Cannot merge while amending.\n"
-"\n"
-"You must finish amending this commit before starting any type of merge.\n"
-msgstr ""
-"訂正中にはマージできません。\n"
-"\n"
-"訂正処理を完了するまでは新たにマージを開始できません。\n"
+#: lib/option.tcl:159
+msgid "New Branch Name Template"
+msgstr "新しいブランチ名のテンプレート"
-#: lib/merge.tcl:27
-msgid ""
-"Last scanned state does not match repository state.\n"
-"\n"
-"Another Git program has modified this repository since the last scan. A "
-"rescan must be performed before a merge can be performed.\n"
-"\n"
-"The rescan will be automatically started now.\n"
-msgstr ""
-"最後にスキャンした状態はリポジトリの状態と合致しません。\n"
-"\n"
-"最後にスキャンして以後、別の Git プログラムがリポジトリを変更しています。マー"
-"ジを開始する前に、再スキャンが必要です。\n"
-"\n"
-"自動的に再スキャンを開始します。\n"
+#: lib/option.tcl:160
+msgid "Default File Contents Encoding"
+msgstr "ファイル内容のデフォールトエンコーディング"
-#: lib/merge.tcl:45
-#, tcl-format
-msgid ""
-"You are in the middle of a conflicted merge.\n"
-"\n"
-"File %s has merge conflicts.\n"
-"\n"
-"You must resolve them, stage the file, and commit to complete the current "
-"merge. Only then can you begin another merge.\n"
-msgstr ""
-"衝突のあったマージの途中です。\n"
-"\n"
-"ファイル %s にはマージ中の衝突が残っています。\n"
-"\n"
-"このファイルの衝突を解決し、コミット予定に加えて、コミットすることでマージを"
-"完了します。そうやって始めて、新たなマージを開始できるようになります。\n"
+#: lib/option.tcl:161
+msgid "Warn before committing to a detached head"
+msgstr "分離 HEAD のコミット前に警告する"
-#: lib/merge.tcl:55
-#, tcl-format
-msgid ""
-"You are in the middle of a change.\n"
-"\n"
-"File %s is modified.\n"
-"\n"
-"You should complete the current commit before starting a merge. Doing so "
-"will help you abort a failed merge, should the need arise.\n"
-msgstr ""
-"変更の途中です。\n"
-"\n"
-"ファイル %s は変更中です。\n"
-"\n"
-"現在のコミットを完了してからマージを開始して下さい。そうする方がマージに失敗"
-"したときの回復が楽です。\n"
+#: lib/option.tcl:162
+msgid "Staging of untracked files"
+msgstr "管理外のファイルをコミット予定する"
-#: lib/merge.tcl:107
-#, tcl-format
-msgid "%s of %s"
-msgstr "%s の %s ブランチ"
+#: lib/option.tcl:163
+msgid "Show untracked files"
+msgstr "管理外のファイルを表示する"
-#: lib/merge.tcl:120
-#, tcl-format
-msgid "Merging %s and %s..."
-msgstr "%s と %s をマージ中・・・"
+#: lib/option.tcl:164
+msgid "Tab spacing"
+msgstr "タブ幅"
-#: lib/merge.tcl:131
-msgid "Merge completed successfully."
-msgstr "マージが完了しました"
+#: lib/option.tcl:210
+msgid "Change"
+msgstr "変更"
-#: lib/merge.tcl:133
-msgid "Merge failed. Conflict resolution is required."
-msgstr "マージが失敗しました。衝突の解決が必要です。"
+#: lib/option.tcl:254
+msgid "Spelling Dictionary:"
+msgstr "スペルチェック辞書"
+
+#: lib/option.tcl:284
+msgid "Change Font"
+msgstr "フォントを変更"
-#: lib/merge.tcl:158
+#: lib/option.tcl:288
#, tcl-format
-msgid "Merge Into %s"
-msgstr "%s ã\81«ã\83\9eã\83¼ã\82¸"
+msgid "Choose %s"
+msgstr "%s ã\82\92é\81¸æ\8a\9e"
-#: lib/merge.tcl:177
-msgid "Revision To Merge"
-msgstr "ã\83\9eã\83¼ã\82¸ã\81\99ã\82\8bã\83ªã\83\93ã\82¸ã\83§ã\83³"
+#: lib/option.tcl:294
+msgid "pt."
+msgstr "ã\83\9dã\82¤ã\83³ã\83\88"
-#: lib/merge.tcl:212
-msgid ""
-"Cannot abort while amending.\n"
-"\n"
-"You must finish amending this commit.\n"
-msgstr ""
-"訂正中には中止できません。\n"
-"\n"
-"まず今のコミット訂正を完了させて下さい。\n"
+#: lib/option.tcl:308
+msgid "Preferences"
+msgstr "設定"
-#: lib/merge.tcl:222
-msgid ""
-"Abort merge?\n"
-"\n"
-"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
-"\n"
-"Continue with aborting the current merge?"
-msgstr ""
-"マージを中断しますか?\n"
-"\n"
-"現在のマージを中断すると、コミットしていない全ての変更が失われます。\n"
-"\n"
-"マージを中断してよろしいですか?"
+#: lib/option.tcl:310 lib/branch_checkout.tcl:39 lib/branch_create.tcl:69
+msgid "Options"
+msgstr "オプション"
-#: lib/merge.tcl:228
-msgid ""
-"Reset changes?\n"
-"\n"
-"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
-"\n"
-"Continue with resetting the current changes?"
-msgstr ""
-"変更点をリセットしますか?\n"
-"\n"
-"変更点をリセットすると、コミットしていない全ての変更が失われます。\n"
-"\n"
-"リセットしてよろしいですか?"
+#: lib/option.tcl:345
+msgid "Failed to completely save options:"
+msgstr "完全にオプションを保存できません:"
-#: lib/merge.tcl:239
-msgid "Aborting"
-msgstr "中断しています"
+#: lib/database.tcl:42
+msgid "Number of loose objects"
+msgstr "ばらばらなオブジェクトの数"
-#: lib/merge.tcl:239
-msgid "files reset"
-msgstr "ã\83ªã\82»ã\83\83ã\83\88ã\81\97ã\81\9fã\83\95ã\82¡ã\82¤ã\83«"
+#: lib/database.tcl:43
+msgid "Disk space used by loose objects"
+msgstr "ã\81°ã\82\89ã\81°ã\82\89ã\81ªã\82ªã\83\96ã\82¸ã\82§ã\82¯ã\83\88ã\81®ä½¿ç\94¨ã\81\99ã\82\8bã\83\87ã\82£ã\82¹ã\82¯é\87\8f"
-#: lib/merge.tcl:267
-msgid "Abort failed."
-msgstr "中断に失敗しました。"
+#: lib/database.tcl:44
+msgid "Number of packed objects"
+msgstr "パックされたオブジェクトの数"
-#: lib/merge.tcl:269
-msgid "Abort completed. Ready."
-msgstr "中断完了。"
+#: lib/database.tcl:45
+msgid "Number of packs"
+msgstr "パックの数"
-#: lib/mergetool.tcl:8
-msgid "Force resolution to the base version?"
-msgstr "共通の版を使いますか?"
+#: lib/database.tcl:46
+msgid "Disk space used by packed objects"
+msgstr "パックされたオブジェクトの使用するディスク量"
-#: lib/mergetool.tcl:9
-msgid "Force resolution to this branch?"
-msgstr "自分の側の版を使いますか?"
+#: lib/database.tcl:47
+msgid "Packed objects waiting for pruning"
+msgstr "パックに存在するので捨てて良いオブジェクトの数"
-#: lib/mergetool.tcl:10
-msgid "Force resolution to the other branch?"
-msgstr "相手制の版を使いますか?"
+#: lib/database.tcl:48
+msgid "Garbage files"
+msgstr "ゴミファイル"
-#: lib/mergetool.tcl:14
+#: lib/database.tcl:72
+msgid "Compressing the object database"
+msgstr "データベース圧縮"
+
+#: lib/database.tcl:83
+msgid "Verifying the object database with fsck-objects"
+msgstr "fsck-objects でオブジェクト・データベースを検証しています"
+
+#: lib/database.tcl:107
#, tcl-format
msgid ""
-"Note that the diff shows only conflicting changes.\n"
+"This repository currently has approximately %i loose objects.\n"
"\n"
-"%s will be overwritten.\n"
+"To maintain optimal performance it is strongly recommended that you compress "
+"the database.\n"
"\n"
-"This operation can be undone only by restarting the merge."
+"Compress the database now?"
msgstr ""
-"競合する変更点だけが表示されていることに注意してください。\n"
+"このリポジトリにはおおよそ %i 個の個別オブジェクトがあります\n"
"\n"
-"%s は上書きされます。\n"
+"最適な性能を保つために、データベースを圧縮することを推奨します\n"
"\n"
-"やり直すにはマージ全体をやり直してください。"
-
-#: lib/mergetool.tcl:45
-#, tcl-format
-msgid "File %s seems to have unresolved conflicts, still stage?"
-msgstr ""
-"ファイル %s には解決していない競合部分がまだあるようですが、いいですか?"
+"データベースを圧縮しますか?"
-#: lib/mergetool.tcl:60
+#: lib/transport.tcl:6 lib/remote_add.tcl:132
#, tcl-format
-msgid "Adding resolution for %s"
-msgstr "%s への解決をステージします"
-
-#: lib/mergetool.tcl:141
-msgid "Cannot resolve deletion or link conflicts using a tool"
-msgstr "ツールでは削除やリンク競合は扱えません"
-
-#: lib/mergetool.tcl:146
-msgid "Conflict file does not exist"
-msgstr "競合ファイルは存在しません。"
+msgid "fetch %s"
+msgstr "%s を取得"
-#: lib/mergetool.tcl:264
+#: lib/transport.tcl:7
#, tcl-format
-msgid "Not a GUI merge tool: '%s'"
-msgstr "GUI マージツールではありません: %s"
+msgid "Fetching new changes from %s"
+msgstr "%s から新しい変更をフェッチしています"
-#: lib/mergetool.tcl:268
+#: lib/transport.tcl:18
#, tcl-format
-msgid "Unsupported merge tool '%s'"
-msgstr "マージツール '%s' はサポートしていません"
-
-#: lib/mergetool.tcl:303
-msgid "Merge tool is already running, terminate it?"
-msgstr "マージツールはすでに起動しています。終了しますか?"
+msgid "remote prune %s"
+msgstr "リモート刈込 %s"
-#: lib/mergetool.tcl:323
+#: lib/transport.tcl:19
#, tcl-format
-msgid ""
-"Error retrieving versions:\n"
-"%s"
-msgstr ""
-"版の取り出し時にエラーが出ました:\n"
-"%s"
+msgid "Pruning tracking branches deleted from %s"
+msgstr "%s から削除されたトラッキング・ブランチを刈っています"
-#: lib/mergetool.tcl:343
-#, tcl-format
-msgid ""
-"Could not start the merge tool:\n"
-"\n"
-"%s"
-msgstr ""
-"マージツールが起動できません:\n"
-"\n"
-"%s"
+#: lib/transport.tcl:25
+msgid "fetch all remotes"
+msgstr "すべてのリモートを取得"
-#: lib/mergetool.tcl:347
-msgid "Running merge tool..."
-msgstr "ã\83\9eã\83¼ã\82¸ã\83\84ã\83¼ã\83«ã\82\92å®\9fè¡\8cã\81\97ã\81¦ã\81\84ã\81¾ã\81\99..."
+#: lib/transport.tcl:26
+msgid "Fetching new changes from all remotes"
+msgstr "ã\81\99ã\81¹ã\81¦ã\81®ã\83ªã\83¢ã\83¼ã\83\88ã\81\8bã\82\89æ\96°ã\81\97ã\81\84å¤\89æ\9b´ã\82\92ã\83\95ã\82§ã\83\83ã\83\81ã\81\97ã\81¦ã\81\84ã\81¾ã\81\99"
-#: lib/mergetool.tcl:375 lib/mergetool.tcl:383
-msgid "Merge tool failed."
-msgstr "ã\83\9eã\83¼ã\82¸ã\83\84ã\83¼ã\83«ã\81\8c失æ\95\97ã\81\97ã\81¾ã\81\97ã\81\9fã\80\82"
+#: lib/transport.tcl:40
+msgid "remote prune all remotes"
+msgstr "ã\83ªã\83¢ã\83¼ã\83\88å\88\88è¾¼ ã\81\99ã\81¹ã\81¦ã\81®ã\83ªã\83¢ã\83¼ã\83\88"
-#: lib/option.tcl:11
-#, tcl-format
-msgid "Invalid global encoding '%s'"
-msgstr "全体エンコーディングに 無効な %s が指定されています"
+#: lib/transport.tcl:41
+msgid "Pruning tracking branches deleted from all remotes"
+msgstr "すべてのリモートから削除されたトラッキング・ブランチを刈っています"
-#: lib/option.tcl:19
+#: lib/transport.tcl:54 lib/transport.tcl:92 lib/transport.tcl:110
+#: lib/remote_add.tcl:162
#, tcl-format
-msgid "Invalid repo encoding '%s'"
-msgstr "リポジトリエンコーディングに 無効な %s が指定されています"
+msgid "push %s"
+msgstr "%s をプッシュ"
-#: lib/option.tcl:117
-msgid "Restore Defaults"
-msgstr "既定値に戻す"
+#: lib/transport.tcl:55
+#, tcl-format
+msgid "Pushing changes to %s"
+msgstr "%s へ変更をプッシュしています"
-#: lib/option.tcl:121
-msgid "Save"
-msgstr "保存"
+#: lib/transport.tcl:93
+#, tcl-format
+msgid "Mirroring to %s"
+msgstr "%s へミラーしています"
-#: lib/option.tcl:131
+#: lib/transport.tcl:111
#, tcl-format
-msgid "%s Repository"
-msgstr "%s リポジトリ"
+msgid "Pushing %s %s to %s"
+msgstr "%3$s へ %1$s %2$s をプッシュしています"
-#: lib/option.tcl:132
-msgid "Global (All Repositories)"
-msgstr "大域(全てのリポジトリ)"
+#: lib/transport.tcl:132
+msgid "Push Branches"
+msgstr "ブランチをプッシュ"
-#: lib/option.tcl:138
-msgid "User Name"
-msgstr "ユーザ名"
+#: lib/transport.tcl:147
+msgid "Source Branches"
+msgstr "元のブランチ"
-#: lib/option.tcl:139
-msgid "Email Address"
-msgstr "é\9b»å\90ã\83¡ã\83¼ã\83«ã\82¢ã\83\89ã\83¬ã\82¹"
+#: lib/transport.tcl:162
+msgid "Destination Repository"
+msgstr "é\80\81ã\82\8aå\85\88ã\83ªã\83\9dã\82¸ã\83\88ã\83ª"
-#: lib/option.tcl:141
-msgid "Summarize Merge Commits"
-msgstr "マージコミットの要約"
+#: lib/transport.tcl:205
+msgid "Transfer Options"
+msgstr "通信オプション"
-#: lib/option.tcl:142
-msgid "Merge Verbosity"
-msgstr "マージの冗長度"
+#: lib/transport.tcl:207
+msgid "Force overwrite existing branch (may discard changes)"
+msgstr "既存ブランチを上書き(変更を破棄する可能性があります)"
-#: lib/option.tcl:143
-msgid "Show Diffstat After Merge"
-msgstr "マージ後に diffstat を表示"
+#: lib/transport.tcl:211
+msgid "Use thin pack (for slow network connections)"
+msgstr "Thin Pack を使う(遅いネットワーク接続)"
-#: lib/option.tcl:144
-msgid "Use Merge Tool"
-msgstr "ã\83\9eã\83¼ã\82¸ã\83\84ã\83¼ã\83«ã\82\92使ç\94¨"
+#: lib/transport.tcl:215
+msgid "Include tags"
+msgstr "ã\82¿ã\82°ã\82\92å\90«ã\82\81ã\82\8b"
-#: lib/option.tcl:146
-msgid "Trust File Modification Timestamps"
-msgstr "ファイル変更時刻を信頼する"
+#: lib/choose_font.tcl:41
+msgid "Select"
+msgstr "選択"
-#: lib/option.tcl:147
-msgid "Prune Tracking Branches During Fetch"
-msgstr "ã\83\95ã\82§ã\83\83ã\83\81ä¸ã\81«ã\83\88ã\83©ã\83\83ã\82ã\83³ã\82°ã\83\96ã\83©ã\83³ã\83\81ã\82\92å\88\88ã\82\8b"
+#: lib/choose_font.tcl:55
+msgid "Font Family"
+msgstr "ã\83\95ã\82©ã\83³ã\83\88ã\83»ã\83\95ã\82¡ã\83\9fã\83ªã\83¼"
-#: lib/option.tcl:148
-msgid "Match Tracking Branches"
-msgstr "ã\83\88ã\83©ã\83\83ã\82ã\83³ã\82°ã\83\96ã\83©ã\83³ã\83\81ã\82\92å\90\88ã\82\8fã\81\9bã\82\8b"
+#: lib/choose_font.tcl:76
+msgid "Font Size"
+msgstr "ã\83\95ã\82©ã\83³ã\83\88ã\81®å¤§ã\81\8dã\81\95"
-#: lib/option.tcl:149
-msgid "Blame Copy Only On Changed Files"
-msgstr "変更されたファイルのみコピー検知を行なう"
+#: lib/choose_font.tcl:93
+msgid "Font Example"
+msgstr "フォント・サンプル"
-#: lib/option.tcl:150
-msgid "Minimum Letters To Blame Copy On"
-msgstr "コピーを検知する最少文字数"
+#: lib/choose_font.tcl:105
+msgid ""
+"This is example text.\n"
+"If you like this text, it can be your font."
+msgstr ""
+"これはサンプル文です。\n"
+"このフォントが気に入ればお使いになれます。"
-#: lib/option.tcl:151
-msgid "Blame History Context Radius (days)"
-msgstr "註釈する履歴半径(日数)"
+#: lib/remote.tcl:200
+msgid "Push to"
+msgstr "プッシュ先"
-#: lib/option.tcl:152
-msgid "Number of Diff Context Lines"
-msgstr "diff の文脈行数"
+#: lib/remote.tcl:218
+msgid "Remove Remote"
+msgstr "リモートを削除"
-#: lib/option.tcl:153
-msgid "Commit Message Text Width"
-msgstr "ã\82³ã\83\9fã\83\83ã\83\88ã\83¡ã\83\83ã\82»ã\83¼ã\82¸ã\81®ã\83\86ã\82ã\82¹ã\83\88å¹\85"
+#: lib/remote.tcl:223
+msgid "Prune from"
+msgstr "ã\81\8bã\82\89å\88\88è¾¼ã\82\80â\80¦"
-#: lib/option.tcl:154
-msgid "New Branch Name Template"
-msgstr "新しいブランチ名のテンプレート"
+#: lib/remote.tcl:228
+msgid "Fetch from"
+msgstr "取得元"
-#: lib/option.tcl:155
-msgid "Default File Contents Encoding"
-msgstr "ファイル内容のデフォールトエンコーディング"
+#: lib/diff.tcl:77
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
+"\n"
+"A rescan will be automatically started to find other files which may have "
+"the same state."
+msgstr ""
+"変更がありません。\n"
+"\n"
+"%s には変更がありません。\n"
+"\n"
+"このファイルの変更時刻は他のアプリケーションによって更新されていますがファイ"
+"ル内容には変更がありません。\n"
+"\n"
+"同様な状態のファイルを探すために、自動的に再スキャンを開始します。"
-#: lib/option.tcl:203
-msgid "Change"
-msgstr "変更"
+#: lib/diff.tcl:117
+#, tcl-format
+msgid "Loading diff of %s..."
+msgstr "%s の変更点をロード中…"
-#: lib/option.tcl:230
-msgid "Spelling Dictionary:"
-msgstr "スペルチェック辞書"
+#: lib/diff.tcl:140
+msgid ""
+"LOCAL: deleted\n"
+"REMOTE:\n"
+msgstr ""
+"LOCAL: 削除\n"
+"Remote:\n"
-#: lib/option.tcl:254
-msgid "Change Font"
-msgstr "フォントを変更"
+#: lib/diff.tcl:145
+msgid ""
+"REMOTE: deleted\n"
+"LOCAL:\n"
+msgstr ""
+"REMOTE: 削除\n"
+"LOCAL:\n"
+
+#: lib/diff.tcl:152
+msgid "LOCAL:\n"
+msgstr "LOCAL:\n"
-#: lib/option.tcl:258
+#: lib/diff.tcl:155
+msgid "REMOTE:\n"
+msgstr "REMOTE\n"
+
+#: lib/diff.tcl:217 lib/diff.tcl:355
#, tcl-format
-msgid "Choose %s"
-msgstr "%s を選択"
+msgid "Unable to display %s"
+msgstr "%s を表示できません"
-#: lib/option.tcl:264
-msgid "pt."
-msgstr "ã\83\9dã\82¤ã\83³ã\83\88"
+#: lib/diff.tcl:218
+msgid "Error loading file:"
+msgstr "ã\83\95ã\82¡ã\82¤ã\83«ã\82\92èªã\82\80é\9a\9bã\81®ã\82¨ã\83©ã\83¼ã\81§ã\81\99:"
-#: lib/option.tcl:278
-msgid "Preferences"
-msgstr "設定"
+#: lib/diff.tcl:225
+msgid "Git Repository (subproject)"
+msgstr "Git リポジトリ(サブプロジェクト)"
-#: lib/option.tcl:314
-msgid "Failed to completely save options:"
-msgstr "完全にオプションを保存できません:"
+#: lib/diff.tcl:237
+msgid "* Binary file (not showing content)."
+msgstr "* バイナリファイル(内容は表示しません)"
-#: lib/remote.tcl:163
-msgid "Remove Remote"
-msgstr "リモートを削除"
+#: lib/diff.tcl:242
+#, tcl-format
+msgid ""
+"* Untracked file is %d bytes.\n"
+"* Showing only first %d bytes.\n"
+msgstr ""
+"* 管理外のファイルの大きさは %d バイトです。\n"
+"* 最初の %d バイトだけ表示しています。\n"
-#: lib/remote.tcl:168
-msgid "Prune from"
-msgstr "から刈込む…"
+#: lib/diff.tcl:248
+#, tcl-format
+msgid ""
+"\n"
+"* Untracked file clipped here by %s.\n"
+"* To see the entire file, use an external editor.\n"
+msgstr ""
+"\n"
+"\n"
+"* %s は管理外のファイルをここで切りおとしました。\n"
+"* 全体を見るには外部エディタを使ってください。\n"
-#: lib/remote.tcl:173
-msgid "Fetch from"
-msgstr "取得元"
+#: lib/diff.tcl:578
+msgid "Failed to unstage selected hunk."
+msgstr "選択されたパッチをコミット予定から外せません。"
-#: lib/remote.tcl:215
-msgid "Push to"
-msgstr "プッシュ先"
+#: lib/diff.tcl:585
+msgid "Failed to stage selected hunk."
+msgstr "選択されたパッチをコミット予定に加えられません。"
-#: lib/remote_add.tcl:19
-msgid "Add Remote"
-msgstr "リモートを追加"
+#: lib/diff.tcl:664
+msgid "Failed to unstage selected line."
+msgstr "選択されたパッチ行をコミット予定から外せません。"
-#: lib/remote_add.tcl:24
-msgid "Add New Remote"
-msgstr "リモートを新規に追加"
+#: lib/diff.tcl:672
+msgid "Failed to stage selected line."
+msgstr "選択されたパッチ行をコミット予定に加えられません。"
-#: lib/remote_add.tcl:28 lib/tools_dlg.tcl:36
-msgid "Add"
-msgstr "追加"
+#: lib/branch_checkout.tcl:16 lib/branch_checkout.tcl:21
+msgid "Checkout Branch"
+msgstr "ブランチをチェックアウト"
-#: lib/remote_add.tcl:37
-msgid "Remote Details"
-msgstr "ã\83ªã\83¢ã\83¼ã\83\88ã\81®è©³ç´°"
+#: lib/branch_checkout.tcl:26
+msgid "Checkout"
+msgstr "ã\83\81ã\82§ã\83\83ã\82¯ã\82¢ã\82¦ã\83\88"
-#: lib/remote_add.tcl:50
-msgid "Location:"
-msgstr "場所:"
+#: lib/branch_checkout.tcl:42 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
+msgstr "トラッキング・ブランチをフェッチ"
-#: lib/remote_add.tcl:62
-msgid "Further Action"
-msgstr "ã\81\9dã\81®ä»\96ã\81®å\8b\95ä½\9c"
+#: lib/branch_checkout.tcl:47
+msgid "Detach From Local Branch"
+msgstr "ã\83ã\83¼ã\82«ã\83«ã\83»ã\83\96ã\83©ã\83³ã\83\81ã\81\8bã\82\89å\89\8aé\99¤"
-#: lib/remote_add.tcl:65
-msgid "Fetch Immediately"
-msgstr "即座に取得"
+#: lib/index.tcl:6
+msgid "Unable to unlock the index."
+msgstr "インデックスをロックできません"
-#: lib/remote_add.tcl:71
-msgid "Initialize Remote Repository and Push"
-msgstr "リモートレポジトリを初期化してプッシュ"
+#: lib/index.tcl:17
+msgid "Index Error"
+msgstr "索引エラー"
-#: lib/remote_add.tcl:77
-msgid "Do Nothing Else Now"
-msgstr "何もしない"
+#: lib/index.tcl:19
+msgid ""
+"Updating the Git index failed. A rescan will be automatically started to "
+"resynchronize git-gui."
+msgstr ""
+"GIT インデックスの更新が失敗しました。git-gui と同期をとるために再スキャンし"
+"ます。"
+
+#: lib/index.tcl:30
+msgid "Continue"
+msgstr "続行"
-#: lib/remote_add.tcl:101
-msgid "Please supply a remote name."
-msgstr "ã\83ªã\83¢ã\83¼ã\83\88å\90\8dã\82\92æ\8c\87å®\9aã\81\97ã\81¦ä¸\8bã\81\95ã\81\84ã\80\82"
+#: lib/index.tcl:33
+msgid "Unlock Index"
+msgstr "ã\82¤ã\83³ã\83\87ã\83\83ã\82¯ã\82¹ã\81®ã\83ã\83\83ã\82¯è§£é\99¤"
-#: lib/remote_add.tcl:114
+#: lib/index.tcl:298
#, tcl-format
-msgid "'%s' is not an acceptable remote name."
-msgstr "'%s' はリモート名に使えません。"
+msgid "Unstaging %s from commit"
+msgstr "コミットから '%s' を降ろす"
-#: lib/remote_add.tcl:125
-#, tcl-format
-msgid "Failed to add remote '%s' of location '%s'."
-msgstr "場所 '%2$s' のリモート '%1$s'の名前変更に失敗しました。"
+#: lib/index.tcl:337
+msgid "Ready to commit."
+msgstr "コミット準備完了"
-#: lib/remote_add.tcl:133 lib/transport.tcl:6
+#: lib/index.tcl:350
#, tcl-format
-msgid "fetch %s"
-msgstr "%s を取得"
+msgid "Adding %s"
+msgstr "コミットに %s を加えています"
-#: lib/remote_add.tcl:134
+#: lib/index.tcl:380
#, tcl-format
-msgid "Fetching the %s"
-msgstr "%s からフェッチしています"
+msgid "Stage %d untracked files?"
+msgstr "管理外の %d ファイルをコミット予定としますか?"
-#: lib/remote_add.tcl:157
+#: lib/index.tcl:428
#, tcl-format
-msgid "Do not know how to initialize repository at location '%s'."
-msgstr "ã\83ªã\83\9dã\82¸ã\83\88ã\83ª '%s' ã\82\92å\88\9dæ\9c\9få\8c\96ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82"
+msgid "Revert changes in file %s?"
+msgstr "ã\83\95ã\82¡ã\82¤ã\83« %s ã\81«ã\81\97ã\81\9få¤\89æ\9b´ã\82\92å\85\83ã\81«æ\88»ã\81\97ã\81¾ã\81\99ã\81\8bï¼\9f"
-#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:63
-#: lib/transport.tcl:81
+#: lib/index.tcl:430
#, tcl-format
-msgid "push %s"
-msgstr "%s をプッシュ"
+msgid "Revert changes in these %i files?"
+msgstr "これら %i 個のファイルにした変更を元に戻しますか?"
-#: lib/remote_add.tcl:164
-#, tcl-format
-msgid "Setting up the %s (at %s)"
-msgstr "%2$s にある %1$s をセットアップします"
+#: lib/index.tcl:438
+msgid "Any unstaged changes will be permanently lost by the revert."
+msgstr "変更を元に戻すとコミット予定していない変更は全て失われます。"
-#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
-msgid "Delete Branch Remotely"
-msgstr "遠隔でブランチ削除"
+#: lib/index.tcl:441
+msgid "Do Nothing"
+msgstr "何もしない"
-#: lib/remote_branch_delete.tcl:47
-msgid "From Repository"
-msgstr "元のリポジトリ"
+#: lib/index.tcl:459
+msgid "Reverting selected files"
+msgstr "選択されたファイルにした変更を元に戻します"
-#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:134
-msgid "Remote:"
-msgstr "リモート:"
+#: lib/index.tcl:463
+#, tcl-format
+msgid "Reverting %s"
+msgstr "%s にした変更を元に戻します"
-#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:149
-msgid "Arbitrary Location:"
-msgstr "任意の位置:"
+#: lib/sshkey.tcl:31
+msgid "No keys found."
+msgstr "キーがありません。"
-#: lib/remote_branch_delete.tcl:84
-msgid "Branches"
-msgstr "ブランチ"
+#: lib/sshkey.tcl:34
+#, tcl-format
+msgid "Found a public key in: %s"
+msgstr "公開鍵がありました: %s"
-#: lib/remote_branch_delete.tcl:109
-msgid "Delete Only If"
-msgstr "条件付で削除"
+#: lib/sshkey.tcl:40
+msgid "Generate Key"
+msgstr "鍵を生成"
-#: lib/remote_branch_delete.tcl:111
-msgid "Merged Into:"
-msgstr "ã\83\9eã\83¼ã\82¸å\85\88:"
+#: lib/sshkey.tcl:58
+msgid "Copy To Clipboard"
+msgstr "ã\82¯ã\83ªã\83\83ã\83\97ã\83\9cã\83¼ã\83\89ã\81«ã\82³ã\83\94ã\83¼"
-#: lib/remote_branch_delete.tcl:152
-msgid "A branch is required for 'Merged Into'."
-msgstr "'マージ先' にはブランチが必要です。"
+#: lib/sshkey.tcl:72
+msgid "Your OpenSSH Public Key"
+msgstr "あなたの OpenSSH 公開鍵"
+
+#: lib/sshkey.tcl:80
+msgid "Generating..."
+msgstr "生成中..."
-#: lib/remote_branch_delete.tcl:184
+#: lib/sshkey.tcl:86
#, tcl-format
msgid ""
-"The following branches are not completely merged into %s:\n"
+"Could not start ssh-keygen:\n"
"\n"
-" - %s"
+"%s"
msgstr ""
-"以下のブランチは %s に完全にマージされていません:\n"
+"ssh-keygen を起動できません:\n"
"\n"
-" - %s"
-
-#: lib/remote_branch_delete.tcl:189
-#, tcl-format
-msgid ""
-"One or more of the merge tests failed because you have not fetched the "
-"necessary commits. Try fetching from %s first."
-msgstr ""
-"必要なコミットが不足しているために、マージ検査が失敗しました。まず %s から"
-"フェッチして下さい。"
-
-#: lib/remote_branch_delete.tcl:207
-msgid "Please select one or more branches to delete."
-msgstr "削除するブランチを選択して下さい。"
+"%s"
-#: lib/remote_branch_delete.tcl:226
-#, tcl-format
-msgid "Deleting branches from %s"
-msgstr "%s からブランチを削除しています。"
+#: lib/sshkey.tcl:113
+msgid "Generation failed."
+msgstr "生成に失敗しました。"
-#: lib/remote_branch_delete.tcl:292
-msgid "No repository selected."
-msgstr "リポジトリが選択されていません。"
+#: lib/sshkey.tcl:120
+msgid "Generation succeeded, but no keys found."
+msgstr "生成には成功しましたが、鍵が見つかりません。"
-#: lib/remote_branch_delete.tcl:297
+#: lib/sshkey.tcl:123
#, tcl-format
-msgid "Scanning %s..."
-msgstr "%s をスキャンしています…"
-
-#: lib/search.tcl:21
-msgid "Find:"
-msgstr "検索:"
-
-#: lib/search.tcl:23
-msgid "Next"
-msgstr "次"
+msgid "Your key is in: %s"
+msgstr "あなたの鍵は %s にあります"
-#: lib/search.tcl:24
-msgid "Prev"
-msgstr "前"
+#: lib/commit.tcl:9
+msgid ""
+"There is nothing to amend.\n"
+"\n"
+"You are about to create the initial commit. There is no commit before this "
+"to amend.\n"
+msgstr ""
+"訂正するコミットがそもそもありません。\n"
+"\n"
+"これから作るのは最初のコミットです。その前にはまだ訂正するようなコミットはあ"
+"りません。\n"
-#: lib/search.tcl:25
-msgid "Case-Sensitive"
-msgstr "大文字小文字を区別"
+#: lib/commit.tcl:18
+msgid ""
+"Cannot amend while merging.\n"
+"\n"
+"You are currently in the middle of a merge that has not been fully "
+"completed. You cannot amend the prior commit unless you first abort the "
+"current merge activity.\n"
+msgstr ""
+"マージ中にコミットの訂正はできません。\n"
+"\n"
+"現在はまだマージの途中です。先にこのマージを中止しないと、前のコミットの訂正"
+"はできません\n"
-#: lib/shortcut.tcl:21 lib/shortcut.tcl:62
-msgid "Cannot write shortcut:"
-msgstr "ショートカットが書けません:"
+#: lib/commit.tcl:48
+msgid "Error loading commit data for amend:"
+msgstr "訂正するコミットのデータを読めません:"
-#: lib/shortcut.tcl:137
-msgid "Cannot write icon:"
-msgstr "ã\82¢ã\82¤ã\82³ã\83³ã\81\8cæ\9b¸ã\81\91ません:"
+#: lib/commit.tcl:75
+msgid "Unable to obtain your identity:"
+msgstr "ã\83¦ã\83¼ã\82¶ã\81®æ£ä½\93ã\82\92確èª\8dã\81§ã\81\8dません:"
-#: lib/spellcheck.tcl:57
-msgid "Unsupported spell checker"
-msgstr "サポートされていないスペルチェッカーです"
+#: lib/commit.tcl:80
+msgid "Invalid GIT_COMMITTER_IDENT:"
+msgstr "GIT_COMMITTER_IDENT が無効です:"
-#: lib/spellcheck.tcl:65
-msgid "Spell checking is unavailable"
-msgstr "スペルチェック機能は使えません"
+#: lib/commit.tcl:129
+#, tcl-format
+msgid "warning: Tcl does not support encoding '%s'."
+msgstr "警告: Tcl はエンコーディング '%s' をサポートしていません"
-#: lib/spellcheck.tcl:68
-msgid "Invalid spell checking configuration"
-msgstr "スペルチェックの設定が不正です"
+#: lib/commit.tcl:149
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before another commit can be created.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"最後にスキャンした状態はリポジトリの状態と合致しません。\n"
+"\n"
+"最後にスキャンして以後、別の Git プログラムがリポジトリを変更しています。新し"
+"くコミットする前に、再スキャンが必要です。\n"
+"\n"
+"自動的に再スキャンを開始します。\n"
-#: lib/spellcheck.tcl:70
+#: lib/commit.tcl:173
#, tcl-format
-msgid "Reverting dictionary to %s."
-msgstr "辞書を %s に巻き戻します"
-
-#: lib/spellcheck.tcl:73
-msgid "Spell checker silently failed on startup"
-msgstr "スペルチェッカーの起動に失敗しました"
+msgid ""
+"Unmerged files cannot be committed.\n"
+"\n"
+"File %s has merge conflicts. You must resolve them and stage the file "
+"before committing.\n"
+msgstr ""
+"マージしていないファイルはコミットできません。\n"
+"\n"
+"ファイル %s にはマージ衝突が残っています。まず解決してコミット予定に加える必"
+"要があります。\n"
-#: lib/spellcheck.tcl:80
-msgid "Unrecognized spell checker"
-msgstr "スペルチェッカーが判別できません"
+#: lib/commit.tcl:181
+#, tcl-format
+msgid ""
+"Unknown file state %s detected.\n"
+"\n"
+"File %s cannot be committed by this program.\n"
+msgstr ""
+"不明なファイル状態 %s です。\n"
+"\n"
+"ファイル %s は本プログラムではコミットできません。\n"
-#: lib/spellcheck.tcl:186
-msgid "No Suggestions"
-msgstr "提案なし"
+#: lib/commit.tcl:189
+msgid ""
+"No changes to commit.\n"
+"\n"
+"You must stage at least 1 file before you can commit.\n"
+msgstr ""
+"コミットする変更がありません。\n"
+"\n"
+"最低一つの変更をコミット予定に加えてからコミットして下さい。\n"
-#: lib/spellcheck.tcl:388
-msgid "Unexpected EOF from spell checker"
-msgstr "スペルチェッカーが予想外の EOF を返しました"
+#: lib/commit.tcl:204
+msgid ""
+"Please supply a commit message.\n"
+"\n"
+"A good commit message has the following format:\n"
+"\n"
+"- First line: Describe in one sentence what you did.\n"
+"- Second line: Blank\n"
+"- Remaining lines: Describe why this change is good.\n"
+msgstr ""
+"コミット・メッセージを入力して下さい。\n"
+"\n"
+"正しいコミット・メッセージは:\n"
+"\n"
+"- 第1行: 何をしたか、を1行で要約。\n"
+"- 第2行: 空白\n"
+"- 残りの行: なぜ、この変更が良い変更か、の説明。\n"
-#: lib/spellcheck.tcl:392
-msgid "Spell Checker Failed"
-msgstr "ã\82¹ã\83\9aã\83«ã\83\81ã\82§ã\83\83ã\82¯å¤±æ\95\97"
+#: lib/commit.tcl:235
+msgid "Calling pre-commit hook..."
+msgstr "ã\82³ã\83\9fã\83\83ã\83\88å\89\8dã\83\95ã\83\83ã\82¯ã\82\92å®\9fè¡\8cä¸ã\83»ã\83»ã\83»"
-#: lib/sshkey.tcl:31
-msgid "No keys found."
-msgstr "ã\82ã\83¼ã\81\8cã\81\82ã\82\8aã\81¾ã\81\9bã\82\93ã\80\82"
+#: lib/commit.tcl:250
+msgid "Commit declined by pre-commit hook."
+msgstr "ã\82³ã\83\9fã\83\83ã\83\88å\89\8dã\83\95ã\83\83ã\82¯ã\81\8cã\82³ã\83\9fã\83\83ã\83\88ã\82\92æ\8b\92å\90¦ã\81\97ã\81¾ã\81\97ã\81\9f"
-#: lib/sshkey.tcl:34
-#, tcl-format
-msgid "Found a public key in: %s"
-msgstr "公開鍵がありました: %s"
+#: lib/commit.tcl:269
+msgid ""
+"You are about to commit on a detached head. This is a potentially dangerous "
+"thing to do because if you switch to another branch you will lose your "
+"changes and it can be difficult to retrieve them later from the reflog. You "
+"should probably cancel this commit and create a new branch to continue.\n"
+" \n"
+" Do you really want to proceed with your Commit?"
+msgstr ""
+"分離 HEAD での変更をコミットしようとしています。"
+"これは潜在的に危険な行為で、理由は別のブランチへの切り替えで"
+"変更が消失し、reflog からの事後復旧も困難となるためです。"
+"おそらくこのコミットはキャンセルし新しく作成したブランチで"
+"行うべきです。\n"
+"\n"
+" 本当にコミットを続行しますか?"
-#: lib/sshkey.tcl:40
-msgid "Generate Key"
-msgstr "鍵を生成"
+#: lib/commit.tcl:290
+msgid "Calling commit-msg hook..."
+msgstr "コミット・メッセージ・フックを実行中・・・"
-#: lib/sshkey.tcl:56
-msgid "Copy To Clipboard"
-msgstr "ã\82¯ã\83ªã\83\83ã\83\97ã\83\9cã\83¼ã\83\89ã\81«ã\82³ã\83\94ã\83¼"
+#: lib/commit.tcl:305
+msgid "Commit declined by commit-msg hook."
+msgstr "ã\82³ã\83\9fã\83\83ã\83\88ã\83»ã\83¡ã\83\83ã\82»ã\83¼ã\82¸ã\83»ã\83\95ã\83\83ã\82¯ã\81\8cã\82³ã\83\9fã\83\83ã\83\88ã\82\92æ\8b\92å\90¦ã\81\97ã\81¾ã\81\97ã\81\9f"
-#: lib/sshkey.tcl:70
-msgid "Your OpenSSH Public Key"
-msgstr "あなたの OpenSSH 公開鍵"
+#: lib/commit.tcl:318
+msgid "Committing changes..."
+msgstr "変更点をコミット中・・・"
-#: lib/sshkey.tcl:78
-msgid "Generating..."
-msgstr "生成中..."
+#: lib/commit.tcl:334
+msgid "write-tree failed:"
+msgstr "write-tree が失敗しました:"
+
+#: lib/commit.tcl:335 lib/commit.tcl:379 lib/commit.tcl:400
+msgid "Commit failed."
+msgstr "コミットに失敗しました。"
-#: lib/sshkey.tcl:84
+#: lib/commit.tcl:352
#, tcl-format
+msgid "Commit %s appears to be corrupt"
+msgstr "コミット %s は壊れています"
+
+#: lib/commit.tcl:357
msgid ""
-"Could not start ssh-keygen:\n"
+"No changes to commit.\n"
"\n"
-"%s"
+"No files were modified by this commit and it was not a merge commit.\n"
+"\n"
+"A rescan will be automatically started now.\n"
msgstr ""
-"ssh-keygen を起動できません:\n"
+"コミットする変更がありません。\n"
"\n"
-"%s"
-
-#: lib/sshkey.tcl:111
-msgid "Generation failed."
-msgstr "生成に失敗しました。"
+"マージでなく、また、一つも変更点がありません。\n"
+"\n"
+"自動的に再スキャンを開始します。\n"
-#: lib/sshkey.tcl:118
-msgid "Generation succeeded, but no keys found."
-msgstr "生成には成功しましたが、鍵が見つかりません。"
+#: lib/commit.tcl:364
+msgid "No changes to commit."
+msgstr "コミットする変更がありません。"
-#: lib/sshkey.tcl:121
-#, tcl-format
-msgid "Your key is in: %s"
-msgstr "あなたの鍵は %s にあります"
+#: lib/commit.tcl:378
+msgid "commit-tree failed:"
+msgstr "commit-tree が失敗しました:"
-#: lib/status_bar.tcl:83
-#, tcl-format
-msgid "%s ... %*i of %*i %s (%3i%%)"
-msgstr "%1$s ... %4$*i %6$s 中の %2$*i (%7$3i%%)"
+#: lib/commit.tcl:399
+msgid "update-ref failed:"
+msgstr "update-ref が失敗しました:"
-#: lib/tools.tcl:75
+#: lib/commit.tcl:492
#, tcl-format
-msgid "Running %s requires a selected file."
-msgstr "ã\83\95ã\82¡ã\82¤ã\83«ã\82\92é\81¸æ\8a\9eã\81\97ã\81¦ã\81\8bã\82\89 %s ã\82\92èµ·å\8b\95ã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82"
+msgid "Created commit %s: %s"
+msgstr "ã\82³ã\83\9fã\83\83ã\83\88 %s ã\82\92ä½\9cæ\88\90ã\81\97ã\81¾ã\81\97ã\81\9f: %s"
-#: lib/tools.tcl:90
-#, tcl-format
-msgid "Are you sure you want to run %s?"
-msgstr "本当に %s を起動しますか?"
+#: lib/browser.tcl:17
+msgid "Starting..."
+msgstr "起動中…"
-#: lib/tools.tcl:110
-#, tcl-format
-msgid "Tool: %s"
-msgstr "ツール: %s"
+#: lib/browser.tcl:27
+msgid "File Browser"
+msgstr "ファイル・ブラウザ"
-#: lib/tools.tcl:111
+#: lib/browser.tcl:132 lib/browser.tcl:149
#, tcl-format
-msgid "Running: %s"
-msgstr "実行中: %s"
+msgid "Loading %s..."
+msgstr "%s をロード中…"
-#: lib/tools.tcl:149
-#, tcl-format
-msgid "Tool completed successfully: %s"
-msgstr "ツールが完了しました: %s"
+#: lib/browser.tcl:193
+msgid "[Up To Parent]"
+msgstr "[上位フォルダへ]"
-#: lib/tools.tcl:151
-#, tcl-format
-msgid "Tool failed: %s"
-msgstr "ツールが失敗しました: %s"
+#: lib/browser.tcl:275 lib/browser.tcl:282
+msgid "Browse Branch Files"
+msgstr "現在のブランチのファイルを見る"
-#: lib/tools_dlg.tcl:22
-msgid "Add Tool"
-msgstr "ã\83\84ã\83¼ã\83«ã\81®追加"
+#: lib/remote_add.tcl:20
+msgid "Add Remote"
+msgstr "ã\83ªã\83¢ã\83¼ã\83\88ã\82\92追加"
-#: lib/tools_dlg.tcl:28
-msgid "Add New Tool Command"
-msgstr "新規ツールコマンドの追加"
+#: lib/remote_add.tcl:25
+msgid "Add New Remote"
+msgstr "リモートを新規に追加"
-#: lib/tools_dlg.tcl:33
-msgid "Add globally"
-msgstr "全体に追加"
+#: lib/remote_add.tcl:39
+msgid "Remote Details"
+msgstr "リモートの詳細"
-#: lib/tools_dlg.tcl:45
-msgid "Tool Details"
-msgstr "ツールの詳細"
+#: lib/remote_add.tcl:50
+msgid "Location:"
+msgstr "場所:"
-#: lib/tools_dlg.tcl:48
-msgid "Use '/' separators to create a submenu tree:"
-msgstr "'/' でサブメニューを区切ります:"
+#: lib/remote_add.tcl:60
+msgid "Further Action"
+msgstr "その他の動作"
-#: lib/tools_dlg.tcl:61
-msgid "Command:"
-msgstr "コマンド:"
+#: lib/remote_add.tcl:63
+msgid "Fetch Immediately"
+msgstr "即座に取得"
-#: lib/tools_dlg.tcl:74
-msgid "Show a dialog before running"
-msgstr "起動する前にダイアログを表示"
+#: lib/remote_add.tcl:69
+msgid "Initialize Remote Repository and Push"
+msgstr "リモートレポジトリを初期化してプッシュ"
-#: lib/tools_dlg.tcl:80
-msgid "Ask the user to select a revision (sets $REVISION)"
-msgstr "ユーザにコミットを一つ選ばせる ($REVISION にセットします)"
+#: lib/remote_add.tcl:75
+msgid "Do Nothing Else Now"
+msgstr "何もしない"
-#: lib/tools_dlg.tcl:85
-msgid "Ask the user for additional arguments (sets $ARGS)"
-msgstr "ã\83¦ã\83¼ã\82¶ã\81«ä»\96ã\81®å¼\95æ\95°ã\82\92追å\8a ã\81\95ã\81\9bã\82\8b ($ARGS ã\81«ã\82»ã\83\83ã\83\88ã\81\97ã\81¾ã\81\99)"
+#: lib/remote_add.tcl:100
+msgid "Please supply a remote name."
+msgstr "ã\83ªã\83¢ã\83¼ã\83\88å\90\8dã\82\92æ\8c\87å®\9aã\81\97ã\81¦ä¸\8bã\81\95ã\81\84ã\80\82"
-#: lib/tools_dlg.tcl:92
-msgid "Don't show the command output window"
-msgstr "コマンドからの出力ウィンドウを見せない"
+#: lib/remote_add.tcl:113
+#, tcl-format
+msgid "'%s' is not an acceptable remote name."
+msgstr "'%s' はリモート名に使えません。"
-#: lib/tools_dlg.tcl:97
-msgid "Run only if a diff is selected ($FILENAME not empty)"
-msgstr "パッチが選ばれているときだけ動かす($FILENAME が空でない)"
+#: lib/remote_add.tcl:124
+#, tcl-format
+msgid "Failed to add remote '%s' of location '%s'."
+msgstr "場所 '%2$s' のリモート '%1$s'の名前変更に失敗しました。"
-#: lib/tools_dlg.tcl:121
-msgid "Please supply a name for the tool."
-msgstr "ツール名を指定して下さい。"
+#: lib/remote_add.tcl:133
+#, tcl-format
+msgid "Fetching the %s"
+msgstr "%s からフェッチしています"
-#: lib/tools_dlg.tcl:129
+#: lib/remote_add.tcl:156
#, tcl-format
-msgid "Tool '%s' already exists."
-msgstr "ã\83\84ã\83¼ã\83« '%s' ã\81¯æ\97¢ã\81«å\98å\9c¨ã\81\97ã\81¾ã\81\99。"
+msgid "Do not know how to initialize repository at location '%s'."
+msgstr "ã\83ªã\83\9dã\82¸ã\83\88ã\83ª '%s' ã\82\92å\88\9dæ\9c\9få\8c\96ã\81§ã\81\8dã\81¾ã\81\9bã\82\93。"
-#: lib/tools_dlg.tcl:151
+#: lib/remote_add.tcl:163
#, tcl-format
-msgid ""
-"Could not add tool:\n"
-"%s"
-msgstr ""
-"ツールを追加できません:\n"
-"%s"
+msgid "Setting up the %s (at %s)"
+msgstr "%2$s にある %1$s をセットアップします"
-#: lib/tools_dlg.tcl:190
-msgid "Remove Tool"
-msgstr "ツールの削除"
+#: lib/line.tcl:17
+msgid "Goto Line:"
+msgstr "行番号"
-#: lib/tools_dlg.tcl:196
-msgid "Remove Tool Commands"
-msgstr "ツールコマンドの削除"
+#: lib/line.tcl:23
+msgid "Go"
+msgstr "移動"
-#: lib/tools_dlg.tcl:200
-msgid "Remove"
-msgstr "削除"
+#: lib/branch_create.tcl:23
+msgid "Create Branch"
+msgstr "ブランチを作成"
-#: lib/tools_dlg.tcl:236
-msgid "(Blue denotes repository-local tools)"
-msgstr "(青色はローカルレポジトリのツールです)"
+#: lib/branch_create.tcl:28
+msgid "Create New Branch"
+msgstr "ブランチを新規作成"
-#: lib/tools_dlg.tcl:297
-#, tcl-format
-msgid "Run Command: %s"
-msgstr "コマンドを起動: %s"
+#: lib/branch_create.tcl:42
+msgid "Branch Name"
+msgstr "ブランチ名"
-#: lib/tools_dlg.tcl:311
-msgid "Arguments"
-msgstr "引数"
+#: lib/branch_create.tcl:57
+msgid "Match Tracking Branch Name"
+msgstr "トラッキング・ブランチ名を合わせる"
-#: lib/tools_dlg.tcl:348
-msgid "OK"
-msgstr "OK"
+#: lib/branch_create.tcl:66
+msgid "Starting Revision"
+msgstr "初期リビジョン"
-#: lib/transport.tcl:7
-#, tcl-format
-msgid "Fetching new changes from %s"
-msgstr "%s から新しい変更をフェッチしています"
+#: lib/branch_create.tcl:72
+msgid "Update Existing Branch:"
+msgstr "既存のブランチを更新:"
-#: lib/transport.tcl:18
-#, tcl-format
-msgid "remote prune %s"
-msgstr "遠隔刈込 %s"
+#: lib/branch_create.tcl:75
+msgid "No"
+msgstr "いいえ"
-#: lib/transport.tcl:19
-#, tcl-format
-msgid "Pruning tracking branches deleted from %s"
-msgstr "%s から削除されたトラッキング・ブランチを刈っています"
+#: lib/branch_create.tcl:80
+msgid "Fast Forward Only"
+msgstr "早送りのみ"
-#: lib/transport.tcl:26
-#, tcl-format
-msgid "Pushing changes to %s"
-msgstr "%s へ変更をプッシュしています"
+#: lib/branch_create.tcl:97
+msgid "Checkout After Creation"
+msgstr "作成してすぐチェックアウト"
-#: lib/transport.tcl:64
-#, tcl-format
-msgid "Mirroring to %s"
-msgstr "%s へミラーしています"
+#: lib/branch_create.tcl:132
+msgid "Please select a tracking branch."
+msgstr "トラッキング・ブランチを選択して下さい。"
-#: lib/transport.tcl:82
+#: lib/branch_create.tcl:141
#, tcl-format
-msgid "Pushing %s %s to %s"
-msgstr "%3$s へ %1$s %2$s をプッシュしています"
+msgid "Tracking branch %s is not a branch in the remote repository."
+msgstr ""
+"トラッキング・ブランチ %s はリモートリポジトリのブランチではありません。"
-#: lib/transport.tcl:100
-msgid "Push Branches"
-msgstr "ã\83\96ã\83©ã\83³ã\83\81ã\82\92ã\83\97ã\83\83ã\82·ã\83¥"
+#: lib/spellcheck.tcl:57
+msgid "Unsupported spell checker"
+msgstr "ã\82µã\83\9dã\83¼ã\83\88ã\81\95ã\82\8cã\81¦ã\81\84ã\81ªã\81\84ã\82¹ã\83\9aã\83«ã\83\81ã\82§ã\83\83ã\82«ã\83¼ã\81§ã\81\99"
-#: lib/transport.tcl:114
-msgid "Source Branches"
-msgstr "元のブランチ"
+#: lib/spellcheck.tcl:65
+msgid "Spell checking is unavailable"
+msgstr "スペルチェック機能は使えません"
-#: lib/transport.tcl:131
-msgid "Destination Repository"
-msgstr "送り先リポジトリ"
+#: lib/spellcheck.tcl:68
+msgid "Invalid spell checking configuration"
+msgstr "スペルチェックの設定が不正です"
-#: lib/transport.tcl:169
-msgid "Transfer Options"
-msgstr "通信オプション"
+#: lib/spellcheck.tcl:70
+#, tcl-format
+msgid "Reverting dictionary to %s."
+msgstr "辞書を %s に巻き戻します"
-#: lib/transport.tcl:171
-msgid "Force overwrite existing branch (may discard changes)"
-msgstr "既存ブランチを上書き(変更を破棄する可能性があります)"
+#: lib/spellcheck.tcl:73
+msgid "Spell checker silently failed on startup"
+msgstr "スペルチェッカーの起動に失敗しました"
-#: lib/transport.tcl:175
-msgid "Use thin pack (for slow network connections)"
-msgstr "Thin Pack を使う(遅いネットワーク接続)"
+#: lib/spellcheck.tcl:80
+msgid "Unrecognized spell checker"
+msgstr "スペルチェッカーが判別できません"
-#: lib/transport.tcl:179
-msgid "Include tags"
-msgstr "タグを含める"
+#: lib/spellcheck.tcl:186
+msgid "No Suggestions"
+msgstr "提案なし"
+
+#: lib/spellcheck.tcl:388
+msgid "Unexpected EOF from spell checker"
+msgstr "スペルチェッカーが予想外の EOF を返しました"
+
+#: lib/spellcheck.tcl:392
+msgid "Spell Checker Failed"
+msgstr "スペルチェック失敗"
${wt_prefix:+--prefix "$wt_prefix"} \
${prefix:+--recursive-prefix "$prefix"} \
${update:+--update "$update"} \
- ${reference:+--reference "$reference"} \
+ ${reference:+"$reference"} \
${depth:+--depth "$depth"} \
${recommend_shallow:+"$recommend_shallow"} \
${jobs:+$jobs} \
static void handle_builtin(int argc, const char **argv)
{
+ struct argv_array args = ARGV_ARRAY_INIT;
const char *cmd;
struct cmd_struct *builtin;
strip_extension(argv);
cmd = argv[0];
- /* Turn "git cmd --help" into "git help cmd" */
+ /* Turn "git cmd --help" into "git help --exclude-guides cmd" */
if (argc > 1 && !strcmp(argv[1], "--help")) {
+ int i;
+
argv[1] = argv[0];
argv[0] = cmd = "help";
+
+ for (i = 0; i < argc; i++) {
+ argv_array_push(&args, argv[i]);
+ if (!i)
+ argv_array_push(&args, "--exclude-guides");
+ }
+
+ argc++;
+ argv = args.argv;
}
builtin = get_builtin(cmd);
if (builtin)
exit(run_builtin(builtin, argc, argv));
+ argv_array_clear(&args);
}
static void execv_dashed_external(const char **argv)
#include "commit.h"
#include "color.h"
#include "graph.h"
-#include "diff.h"
#include "revision.h"
/* Internal API */
* responsible for printing this line's graph (perhaps via
* graph_show_commit() or graph_show_oneline()) before calling
* graph_show_strbuf().
+ *
+ * Note that unlike some other graph display functions, you must pass the file
+ * handle directly. It is assumed that this is the same file handle as the
+ * file specified by the graph diff options. This is necessary so that
+ * graph_show_strbuf can be called even with a NULL graph.
*/
-static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb);
+static void graph_show_strbuf(struct git_graph *graph,
+ FILE *file,
+ struct strbuf const *sb);
/*
* TODO:
GRAPH_COLLAPSING
};
+static void graph_show_line_prefix(const struct diff_options *diffopt)
+{
+ if (!diffopt || !diffopt->line_prefix)
+ return;
+
+ fwrite(diffopt->line_prefix,
+ sizeof(char),
+ diffopt->line_prefix_length,
+ diffopt->file);
+}
+
static const char **column_colors;
static unsigned short column_colors_max;
static struct strbuf msgbuf = STRBUF_INIT;
assert(opt);
- assert(graph);
- opt->output_prefix_length = graph->width;
strbuf_reset(&msgbuf);
- graph_padding_line(graph, &msgbuf);
+ if (opt->line_prefix)
+ strbuf_add(&msgbuf, opt->line_prefix,
+ opt->line_prefix_length);
+ if (graph)
+ graph_padding_line(graph, &msgbuf);
return &msgbuf;
}
+static const struct diff_options *default_diffopt;
+
+void graph_setup_line_prefix(struct diff_options *diffopt)
+{
+ default_diffopt = diffopt;
+
+ /* setup an output prefix callback if necessary */
+ if (diffopt && !diffopt->output_prefix)
+ diffopt->output_prefix = diff_output_prefix_callback;
+}
+
+
struct git_graph *graph_init(struct rev_info *opt)
{
struct git_graph *graph = xmalloc(sizeof(struct git_graph));
*/
opt->diffopt.output_prefix = diff_output_prefix_callback;
opt->diffopt.output_prefix_data = graph;
- opt->diffopt.output_prefix_length = 0;
return graph;
}
struct strbuf msgbuf = STRBUF_INIT;
int shown_commit_line = 0;
+ graph_show_line_prefix(default_diffopt);
+
if (!graph)
return;
shown_commit_line = graph_next_line(graph, &msgbuf);
fwrite(msgbuf.buf, sizeof(char), msgbuf.len,
graph->revs->diffopt.file);
- if (!shown_commit_line)
+ if (!shown_commit_line) {
putc('\n', graph->revs->diffopt.file);
+ graph_show_line_prefix(&graph->revs->diffopt);
+ }
strbuf_setlen(&msgbuf, 0);
}
{
struct strbuf msgbuf = STRBUF_INIT;
+ graph_show_line_prefix(default_diffopt);
+
if (!graph)
return;
{
struct strbuf msgbuf = STRBUF_INIT;
+ graph_show_line_prefix(default_diffopt);
+
if (!graph)
return;
struct strbuf msgbuf = STRBUF_INIT;
int shown = 0;
+ graph_show_line_prefix(default_diffopt);
+
if (!graph)
return 0;
strbuf_setlen(&msgbuf, 0);
shown = 1;
- if (!graph_is_commit_finished(graph))
+ if (!graph_is_commit_finished(graph)) {
putc('\n', graph->revs->diffopt.file);
- else
+ graph_show_line_prefix(&graph->revs->diffopt);
+ } else {
break;
+ }
}
strbuf_release(&msgbuf);
return shown;
}
-
-static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb)
+static void graph_show_strbuf(struct git_graph *graph,
+ FILE *file,
+ struct strbuf const *sb)
{
char *p;
- if (!graph) {
- fwrite(sb->buf, sizeof(char), sb->len,
- graph->revs->diffopt.file);
- return;
- }
-
/*
* Print the strbuf line by line,
* and display the graph info before each line but the first.
} else {
len = (sb->buf + sb->len) - p;
}
- fwrite(p, sizeof(char), len, graph->revs->diffopt.file);
+ fwrite(p, sizeof(char), len, file);
if (next_p && *next_p != '\0')
graph_show_oneline(graph);
p = next_p;
}
void graph_show_commit_msg(struct git_graph *graph,
+ FILE *file,
struct strbuf const *sb)
{
int newline_terminated;
- if (!graph) {
- /*
- * If there's no graph, just print the message buffer.
- *
- * The message buffer for CMIT_FMT_ONELINE and
- * CMIT_FMT_USERFORMAT are already missing a terminating
- * newline. All of the other formats should have it.
- */
- fwrite(sb->buf, sizeof(char), sb->len,
- graph->revs->diffopt.file);
- return;
- }
-
- newline_terminated = (sb->len && sb->buf[sb->len - 1] == '\n');
-
/*
* Show the commit message
*/
- graph_show_strbuf(graph, sb);
+ graph_show_strbuf(graph, file, sb);
+
+ if (!graph)
+ return;
+
+ newline_terminated = (sb->len && sb->buf[sb->len - 1] == '\n');
/*
* If there is more output needed for this commit, show it now
* new line.
*/
if (!newline_terminated)
- putc('\n', graph->revs->diffopt.file);
+ putc('\n', file);
graph_show_remainder(graph);
* If sb ends with a newline, our output should too.
*/
if (newline_terminated)
- putc('\n', graph->revs->diffopt.file);
+ putc('\n', file);
}
}
#ifndef GRAPH_H
#define GRAPH_H
+#include "diff.h"
/* A graph is a pointer to this opaque structure */
struct git_graph;
+/*
+ * Called to setup global display of line_prefix diff option.
+ *
+ * Passed a diff_options structure which indicates the line_prefix and the
+ * file to output the prefix to. This is sort of a hack used so that the
+ * line_prefix will be honored by all flows which also honor "--graph"
+ * regardless of whether a graph has actually been setup. The normal graph
+ * flow will honor the exact diff_options passed, but a NULL graph will cause
+ * display of a line_prefix to stdout.
+ */
+void graph_setup_line_prefix(struct diff_options *diffopt);
+
/*
* Set up a custom scheme for column colors.
*
* missing a terminating newline (including if it is empty), the output
* printed by graph_show_commit_msg() will also be missing a terminating
* newline.
+ *
+ * Note that unlike some other graph display functions, you must pass the file
+ * handle directly. It is assumed that this is the same file handle as the
+ * file specified by the graph diff options. This is necessary so that
+ * graph_show_commit_msg can be called even with a NULL graph.
*/
-void graph_show_commit_msg(struct git_graph *graph, struct strbuf const *sb);
+void graph_show_commit_msg(struct git_graph *graph,
+ FILE *file,
+ struct strbuf const *sb);
#endif /* GRAPH_H */
{
int i;
for (i = 0; i < GIT_SHA1_RAWSZ; i++) {
- unsigned int val;
- /*
- * hex[1]=='\0' is caught when val is checked below,
- * but if hex[0] is NUL we have to avoid reading
- * past the end of the string:
- */
- if (!hex[0])
- return -1;
- val = (hexval(hex[0]) << 4) | hexval(hex[1]);
- if (val & ~0xff)
+ int val = hex2chr(hex);
+ if (val < 0)
return -1;
*sha1++ = val;
hex += 2;
else
opt->missing_newline = 0;
- if (opt->graph)
- graph_show_commit_msg(opt->graph, &msgbuf);
- else
- fwrite(msgbuf.buf, sizeof(char), msgbuf.len, opt->diffopt.file);
+ graph_show_commit_msg(opt->graph, opt->diffopt.file, &msgbuf);
if (opt->use_terminator && !commit_format_is_empty(opt->commit_format)) {
if (!opt->missing_newline)
graph_show_padding(opt->graph);
#include "string-list.h"
#include "dir.h"
#include "worktree.h"
+#include "submodule-config.h"
static int get_st_mode_bits(const char *path, int *mode)
{
return pathname->buf;
}
-static void do_submodule_path(struct strbuf *buf, const char *path,
- const char *fmt, va_list args)
+/* Returns 0 on success, negative on failure. */
+#define SUBMODULE_PATH_ERR_NOT_CONFIGURED -1
+static int do_submodule_path(struct strbuf *buf, const char *path,
+ const char *fmt, va_list args)
{
const char *git_dir;
struct strbuf git_submodule_common_dir = STRBUF_INIT;
struct strbuf git_submodule_dir = STRBUF_INIT;
+ const struct submodule *sub;
+ int err = 0;
strbuf_addstr(buf, path);
strbuf_complete(buf, '/');
strbuf_reset(buf);
strbuf_addstr(buf, git_dir);
}
+ if (!is_git_directory(buf->buf)) {
+ gitmodules_config();
+ sub = submodule_from_path(null_sha1, path);
+ if (!sub) {
+ err = SUBMODULE_PATH_ERR_NOT_CONFIGURED;
+ goto cleanup;
+ }
+ strbuf_reset(buf);
+ strbuf_git_path(buf, "%s/%s", "modules", sub->name);
+ }
+
strbuf_addch(buf, '/');
strbuf_addbuf(&git_submodule_dir, buf);
strbuf_cleanup_path(buf);
+cleanup:
strbuf_release(&git_submodule_dir);
strbuf_release(&git_submodule_common_dir);
+
+ return err;
}
char *git_pathdup_submodule(const char *path, const char *fmt, ...)
{
+ int err;
va_list args;
struct strbuf buf = STRBUF_INIT;
va_start(args, fmt);
- do_submodule_path(&buf, path, fmt, args);
+ err = do_submodule_path(&buf, path, fmt, args);
va_end(args);
+ if (err) {
+ strbuf_release(&buf);
+ return NULL;
+ }
return strbuf_detach(&buf, NULL);
}
-void strbuf_git_path_submodule(struct strbuf *buf, const char *path,
- const char *fmt, ...)
+int strbuf_git_path_submodule(struct strbuf *buf, const char *path,
+ const char *fmt, ...)
{
+ int err;
va_list args;
va_start(args, fmt);
- do_submodule_path(buf, path, fmt, args);
+ err = do_submodule_path(buf, path, fmt, args);
va_end(args);
+
+ return err;
}
static void do_git_common_path(struct strbuf *buf,
static int packet_length(const char *linelen)
{
- int n;
- int len = 0;
-
- for (n = 0; n < 4; n++) {
- unsigned char c = linelen[n];
- len <<= 4;
- if (c >= '0' && c <= '9') {
- len += c - '0';
- continue;
- }
- if (c >= 'a' && c <= 'f') {
- len += c - 'a' + 10;
- continue;
- }
- if (c >= 'A' && c <= 'F') {
- len += c - 'A' + 10;
- continue;
- }
- return -1;
- }
- return len;
+ int val = hex2chr(linelen);
+ return (val < 0) ? val : (val << 8) | hex2chr(linelen + 2);
}
int packet_read(int fd, char **src_buf, size_t *src_len,
Leader: Changwoo Ryu <cwryu@debian.org>
Language: pt_PT (Portuguese - Portugal)
-Repository: https://github.com/marcomsousa/git-l10n-pt_PT/
-Leader: Marco Sousa <marcomsousa AT gmail.com>
+Repository: https://github.com/vascool/git-po-pt/
+Leader: Vasco Almeida <vascomalmeida@sapo.pt>
+Members: Marco Sousa <marcomsousa AT gmail.com>
Language: ru (Russian)
Repository: https://github.com/DJm00n/git-po-ru/
msgstr ""
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2016-08-15 22:43+0800\n"
-"PO-Revision-Date: 2016-08-24 14:07+0000\n"
+"POT-Creation-Date: 2016-08-27 23:21+0800\n"
+"PO-Revision-Date: 2016-09-03 12:00+0000\n"
"Last-Translator: Vasco Almeida <vascomalmeida@sapo.pt>\n"
"Language-Team: Portuguese\n"
"Language: pt\n"
#: advice.c:83
msgid "Cherry-picking is not possible because you have unmerged files."
-msgstr "Não é possível efetuar cherry-pick porque tem ficheiros não integrados."
+msgstr ""
+"Não é possível efetuar cherry-pick porque tem ficheiros não integrados."
#: advice.c:85
msgid "Committing is not possible because you have unmerged files."
msgid "bad config line %d in %s"
msgstr "linha de configuração %d incorreta em %s"
-#: config.c:660
-#, c-format
-msgid "bad numeric config value '%s' for '%s': out of range"
-msgstr "valor numérico '%s' da configuração '%s' incorreto: fora de intervalo"
+#: config.c:655
+msgid "out of range"
+msgstr "fora de intervalo"
+
+#: config.c:655
+msgid "invalid unit"
+msgstr "unidade inválida"
#: config.c:661
#, c-format
-msgid "bad numeric config value '%s' for '%s': invalid unit"
-msgstr "valor numérico '%s' da configuração '%s' incorreto: unidade inválida"
+msgid "bad numeric config value '%s' for '%s': %s"
+msgstr "valor numérico '%s' da configuração '%s' incorreto: %s"
-#: config.c:667
+#: config.c:666
#, c-format
-msgid "bad numeric config value '%s' for '%s' in blob %s: out of range"
-msgstr ""
-"valor numérico '%s' da configuração '%s' incorreto no blob %s: fora de "
-"intervalo"
+msgid "bad numeric config value '%s' for '%s' in blob %s: %s"
+msgstr "valor numérico '%s' da configuração '%s' incorreto no blob %s: %s"
-#: config.c:668
+#: config.c:669
#, c-format
-msgid "bad numeric config value '%s' for '%s' in blob %s: invalid unit"
-msgstr ""
-"valor numérico '%s' da configuração '%s' incorreto no blob %s: unidade "
-"inválida"
+msgid "bad numeric config value '%s' for '%s' in file %s: %s"
+msgstr "valor numérico '%s' da configuração '%s' incorreto no ficheiro %s: %s"
#: config.c:672
#, c-format
-msgid "bad numeric config value '%s' for '%s' in file %s: out of range"
-msgstr ""
-"valor numérico '%s' da configuração '%s' incorreto no ficheiro %s: fora de "
-"intervalo"
-
-#: config.c:673
-#, c-format
-msgid "bad numeric config value '%s' for '%s' in file %s: invalid unit"
+msgid "bad numeric config value '%s' for '%s' in standard input: %s"
msgstr ""
-"valor numérico '%s' da configuração '%s' incorreto no ficheiro %s: unidade "
-"inválida"
+"valor numérico '%s' da configuração '%s' incorreto na entrada padrão: %s"
-#: config.c:677
+#: config.c:675
#, c-format
-msgid "bad numeric config value '%s' for '%s' in standard input: out of range"
+msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
msgstr ""
-"valor numérico '%s' da configuração '%s' incorreto na entrada padrão: fora "
-"de intervalo"
+"valor numérico '%s' da configuração '%s' incorreto no submódulo-blob %s: %s"
#: config.c:678
#, c-format
-msgid "bad numeric config value '%s' for '%s' in standard input: invalid unit"
-msgstr ""
-"valor numérico '%s' da configuração '%s' incorreto na entrada padrão: "
-"unidade inválida"
-
-#: config.c:682
-#, c-format
-msgid ""
-"bad numeric config value '%s' for '%s' in submodule-blob %s: out of range"
-msgstr ""
-"valor numérico '%s' da configuração '%s' incorreto no submódulo-blob %s: "
-"fora de intervalo"
-
-#: config.c:683
-#, c-format
-msgid ""
-"bad numeric config value '%s' for '%s' in submodule-blob %s: invalid unit"
-msgstr ""
-"valor numérico '%s' da configuração '%s' incorreto no submódulo-blob %s: "
-"unidade inválida"
-
-#: config.c:687
-#, c-format
-msgid "bad numeric config value '%s' for '%s' in command line %s: out of range"
-msgstr ""
-"valor numérico '%s' da configuração '%s' incorreto na linha de comandos %s: "
-"fora de intervalo"
-
-#: config.c:688
-#, c-format
-msgid "bad numeric config value '%s' for '%s' in command line %s: invalid unit"
+msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
msgstr ""
"valor numérico '%s' da configuração '%s' incorreto na linha de comandos %s: "
-"unidade inválida"
-
-#: config.c:692
-#, c-format
-msgid "bad numeric config value '%s' for '%s' in %s: out of range"
-msgstr ""
-"valor numérico '%s' da configuração '%s' incorreto em %s: fora de intervalo"
+"%s"
-#: config.c:693
+#: config.c:681
#, c-format
-msgid "bad numeric config value '%s' for '%s' in %s: invalid unit"
-msgstr ""
-"valor numérico '%s' da configuração '%s' incorreto em %s: unidade inválida"
+msgid "bad numeric config value '%s' for '%s' in %s: %s"
+msgstr "valor numérico '%s' da configuração '%s' incorreto em %s: %s"
-#: config.c:780
+#: config.c:768
#, c-format
msgid "failed to expand user dir in: '%s'"
msgstr "falha ao expandir diretório de utilizador em: '%s'"
-#: config.c:861 config.c:872
+#: config.c:849 config.c:860
#, c-format
msgid "bad zlib compression level %d"
msgstr "nível de compressão zlib %d incorreto"
-#: config.c:990
+#: config.c:978
#, c-format
msgid "invalid mode for object creation: %s"
msgstr "modo inválido para criação de objeto: %s"
-#: config.c:1324
+#: config.c:1312
msgid "unable to parse command-line config"
msgstr "não é possível analisar configuração de linha de comandos"
-#: config.c:1374
+#: config.c:1362
msgid "unknown error occurred while reading the configuration files"
msgstr ""
"ocorreu um erro desconhecido durante a leitura dos ficheiros de configuração"
-#: config.c:1728
+#: config.c:1716
#, c-format
msgid "unable to parse '%s' from command-line config"
msgstr "não é possível analisar '%s' da configuração de linha de comandos"
-#: config.c:1730
+#: config.c:1718
#, c-format
msgid "bad config variable '%s' in file '%s' at line %d"
msgstr "variável de configuração '%s' incorreta no ficheiro '%s' na linha %d"
-#: config.c:1789
+#: config.c:1777
#, c-format
msgid "%s has multiple values"
msgstr "%s tem múltiplos valores"
-#: config.c:2323
+#: config.c:2311
#, c-format
msgid "could not set '%s' to '%s'"
msgstr "não foi possível definir '%s' como '%s'"
-#: config.c:2325
+#: config.c:2313
#, c-format
msgid "could not unset '%s'"
msgstr "não foi possível reiniciar '%s'"
msgid "unable to write new index file"
msgstr "não foi possível escrever novo ficheiro de índice"
-#: merge-recursive.c:212
+#: merge-recursive.c:209
msgid "(bad commit)\n"
msgstr "(commit incorreto)\n"
-#: merge-recursive.c:234
+#: merge-recursive.c:231
#, c-format
msgid "addinfo_cache failed for path '%s'"
msgstr "addinfo_cache falhou no caminho '%s'"
-#: merge-recursive.c:304
+#: merge-recursive.c:301
msgid "error building trees"
msgstr "erro ao construir árvores"
-#: merge-recursive.c:723
+#: merge-recursive.c:720
#, c-format
msgid "failed to create path '%s'%s"
msgstr "falha ao criar o caminho '%s'%s"
-#: merge-recursive.c:734
+#: merge-recursive.c:731
#, c-format
msgid "Removing %s to make room for subdirectory\n"
msgstr "A remover %s para criar espaço para o subdiretório\n"
-#: merge-recursive.c:748 merge-recursive.c:767
+#: merge-recursive.c:745 merge-recursive.c:764
msgid ": perhaps a D/F conflict?"
msgstr ": talvez um conflito D/F?"
-#: merge-recursive.c:757
+#: merge-recursive.c:754
#, c-format
msgid "refusing to lose untracked file at '%s'"
msgstr "perda de ficheiro não controlado em '%s' recusada"
-#: merge-recursive.c:799
+#: merge-recursive.c:796
#, c-format
msgid "cannot read object %s '%s'"
msgstr "não é possível ler o objeto %s: '%s'"
-#: merge-recursive.c:801
+#: merge-recursive.c:798
#, c-format
msgid "blob expected for %s '%s'"
msgstr "blob para %s '%s' esperado"
-#: merge-recursive.c:825
+#: merge-recursive.c:822
#, c-format
msgid "failed to open '%s': %s"
msgstr "falha ao abrir '%s': %s"
-#: merge-recursive.c:836
+#: merge-recursive.c:833
#, c-format
msgid "failed to symlink '%s': %s"
msgstr "falha ao criar a ligação simbólica '%s': %s"
-#: merge-recursive.c:841
+#: merge-recursive.c:838
#, c-format
msgid "do not know what to do with %06o %s '%s'"
msgstr "não sei o que fazer com %06o %s '%s'"
-#: merge-recursive.c:981
+#: merge-recursive.c:978
msgid "Failed to execute internal merge"
msgstr "Falha ao executar integração interna"
-#: merge-recursive.c:985
+#: merge-recursive.c:982
#, c-format
msgid "Unable to add %s to database"
msgstr "Não é possível adicionar %s à base de dados"
-#: merge-recursive.c:1084 merge-recursive.c:1098
+#: merge-recursive.c:1081 merge-recursive.c:1095
#, c-format
msgid ""
"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
"CONFLITO (%s/eliminar): %s eliminado em %s e %s em %s. Versão de %s de %s "
"deixada na árvore."
-#: merge-recursive.c:1090 merge-recursive.c:1103
+#: merge-recursive.c:1087 merge-recursive.c:1100
#, c-format
msgid ""
"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
"CONFLITO (%s/eliminar): %s eliminado em %s e %s em %s. Versão de %s de %s "
"deixada na árvore em %s."
-#: merge-recursive.c:1146
+#: merge-recursive.c:1143
msgid "rename"
msgstr "mudar nome"
-#: merge-recursive.c:1146
+#: merge-recursive.c:1143
msgid "renamed"
msgstr "nome mudado"
-#: merge-recursive.c:1203
+#: merge-recursive.c:1200
#, c-format
msgid "%s is a directory in %s adding as %s instead"
msgstr "%s é um diretório em %s adicionando %s no seu lugar"
-#: merge-recursive.c:1228
+#: merge-recursive.c:1225
#, c-format
msgid ""
"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
"\"->\"%s\" in \"%s\"%s"
msgstr ""
-"CONFLITO (mudar nome/mudar nome): Mudar o nome \"%s\"->\"%s\" no ramo \"%s\" mudar "
-"o nome \"%s\"->\"%s\" em \"%s\"%s"
+"CONFLITO (mudar nome/mudar nome): Mudar o nome \"%s\"->\"%s\" no ramo \"%s\" "
+"mudar o nome \"%s\"->\"%s\" em \"%s\"%s"
-#: merge-recursive.c:1233
+#: merge-recursive.c:1230
msgid " (left unresolved)"
msgstr " (por resolver)"
-#: merge-recursive.c:1295
+#: merge-recursive.c:1292
#, c-format
msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
msgstr ""
-"CONFLITO (mudar nome/mudar nome): Mudar de nome %s->%s em %s. Mudar o nome %"
-"s->%s em %s"
+"CONFLITO (mudar nome/mudar nome): Mudar de nome %s->%s em %s. Mudar o nome "
+"%s->%s em %s"
-#: merge-recursive.c:1328
+#: merge-recursive.c:1325
#, c-format
msgid "Renaming %s to %s and %s to %s instead"
msgstr "A mudar o nome de %s para %s e de %s para %s, em alternativa"
-#: merge-recursive.c:1534
+#: merge-recursive.c:1531
#, c-format
msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
msgstr ""
"CONFLITO (mudar nome/adicionar): Mudar o nome %s->%s em %s. %s adicionado em "
"%s"
-#: merge-recursive.c:1549
+#: merge-recursive.c:1546
#, c-format
msgid "Adding merged %s"
msgstr "A adicionar %s integrado"
-#: merge-recursive.c:1556 merge-recursive.c:1769
+#: merge-recursive.c:1553 merge-recursive.c:1766
#, c-format
msgid "Adding as %s instead"
msgstr "A adicionar como %s, em alternativa."
-#: merge-recursive.c:1613
+#: merge-recursive.c:1610
#, c-format
msgid "cannot read object %s"
msgstr "não foi possível ler o objeto %s"
-#: merge-recursive.c:1616
+#: merge-recursive.c:1613
#, c-format
msgid "object %s is not a blob"
msgstr "o objeto %s não é um blob"
-#: merge-recursive.c:1669
+#: merge-recursive.c:1666
msgid "modify"
msgstr "modificar"
-#: merge-recursive.c:1669
+#: merge-recursive.c:1666
msgid "modified"
msgstr "modificado"
-#: merge-recursive.c:1679
+#: merge-recursive.c:1676
msgid "content"
msgstr "conteúdo"
-#: merge-recursive.c:1686
+#: merge-recursive.c:1683
msgid "add/add"
msgstr "adicionar/adicionar"
-#: merge-recursive.c:1721
+#: merge-recursive.c:1718
#, c-format
msgid "Skipped %s (merged same as existing)"
msgstr "%s ignorado (integrado é igual ao existente)"
-#: merge-recursive.c:1735
+#: merge-recursive.c:1732
#, c-format
msgid "Auto-merging %s"
msgstr "A integrar automaticamente %s"
-#: merge-recursive.c:1739 git-submodule.sh:919
+#: merge-recursive.c:1736 git-submodule.sh:919
msgid "submodule"
msgstr "submódulo"
-#: merge-recursive.c:1740
+#: merge-recursive.c:1737
#, c-format
msgid "CONFLICT (%s): Merge conflict in %s"
msgstr "CONFLITO (%s): conflito de integração em %s"
-#: merge-recursive.c:1834
+#: merge-recursive.c:1831
#, c-format
msgid "Removing %s"
msgstr "A remover %s"
-#: merge-recursive.c:1860
+#: merge-recursive.c:1857
msgid "file/directory"
msgstr "ficheiro/diretório"
-#: merge-recursive.c:1866
+#: merge-recursive.c:1863
msgid "directory/file"
msgstr "diretório/ficheiro"
-#: merge-recursive.c:1871
+#: merge-recursive.c:1868
#, c-format
msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
msgstr ""
"CONFLITO (%s): Há um diretório designado %s em %s. A adicionar %s como %s"
-#: merge-recursive.c:1880
+#: merge-recursive.c:1877
#, c-format
msgid "Adding %s"
msgstr "A adicionar %s"
-#: merge-recursive.c:1917
+#: merge-recursive.c:1914
msgid "Already up-to-date!"
msgstr "Já está atualizado!"
-#: merge-recursive.c:1926
+#: merge-recursive.c:1923
#, c-format
msgid "merging of trees %s and %s failed"
msgstr "falha ao integrar as árvores %s e %s"
-#: merge-recursive.c:2009
+#: merge-recursive.c:2006
msgid "Merging:"
msgstr "A integrar:"
-#: merge-recursive.c:2022
+#: merge-recursive.c:2019
#, c-format
msgid "found %u common ancestor:"
msgid_plural "found %u common ancestors:"
msgstr[0] "%u antecessor comum encontrado:"
msgstr[1] "%u antecessores comuns encontrados:"
-#: merge-recursive.c:2061
+#: merge-recursive.c:2058
msgid "merge returned no commit"
msgstr "a integração não retornou nenhum commit"
-#: merge-recursive.c:2124
+#: merge-recursive.c:2121
#, c-format
msgid "Could not parse object '%s'"
msgstr "Não foi possível analisar o objeto '%s'"
-#: merge-recursive.c:2138 builtin/merge.c:641 builtin/merge.c:788
+#: merge-recursive.c:2135 builtin/merge.c:641 builtin/merge.c:788
msgid "Unable to write index."
msgstr "Não é possível escrever no índice."
msgid " or: %s"
msgstr " ou: %s"
-#: parse-options.c:598
+#: parse-options.c:597
#, c-format
msgid " %s"
msgstr " %s"
msgid "malformed object name '%s'"
msgstr "nome do objeto malformado '%s'"
-#: path.c:796
+#: path.c:798
#, c-format
msgid "Could not make %s writable by group"
msgstr "Não foi possível dar permissão de escrita ao grupo a %s"
msgstr "git %s: falha ao atualizar o índice"
#: sequencer.c:705
-msgid "Cannot revert during a another revert."
+msgid "Cannot revert during another revert."
msgstr "Não é possível reverter durante outra reversão."
#: sequencer.c:706
"Your local changes to the following files would be overwritten by %s:\n"
"%%sPlease commit your changes or stash them before you %s."
msgstr ""
-"As suas alterações locais nos seguintes ficheiros seriam substituídas por %"
-"s:\n"
+"As suas alterações locais nos seguintes ficheiros seriam substituídas por "
+"%s:\n"
"%%sSubmeta as suas alterações ou esconda-as antes de efetuar %s."
#: unpack-trees.c:76
msgid "interactive picking"
msgstr "seleção interativa"
-#: builtin/add.c:257 builtin/checkout.c:1156 builtin/reset.c:286
+#: builtin/add.c:257 builtin/checkout.c:1157 builtin/reset.c:286
msgid "select hunks interactively"
msgstr "selecionar blocos interativamente"
#: builtin/branch.c:846
msgid "-a and -r options to 'git branch' do not make sense with a branch name"
-msgstr "as opções -a e -r de 'git branch' não fazem sentido com um nome de ramo"
+msgstr ""
+"as opções -a e -r de 'git branch' não fazem sentido com um nome de ramo"
#: builtin/branch.c:849
#, c-format
msgid "terminate input and output records by a NUL character"
msgstr "terminar registos da entrada e da saída com um carácter NUL"
-#: builtin/check-ignore.c:18 builtin/checkout.c:1137 builtin/gc.c:325
+#: builtin/check-ignore.c:18 builtin/checkout.c:1138 builtin/gc.c:325
msgid "suppress progress reporting"
msgstr "suprimir informação de progresso"
msgid "Can not do reflog for '%s': %s\n"
msgstr "Não é possível efetuar reflog de '%s': %s\n"
-#: builtin/checkout.c:663
+#: builtin/checkout.c:664
msgid "HEAD is now at"
msgstr "HEAD está agora em"
-#: builtin/checkout.c:667 builtin/clone.c:661
+#: builtin/checkout.c:668 builtin/clone.c:661
msgid "unable to update HEAD"
msgstr "não foi possível atualizar HEAD"
-#: builtin/checkout.c:671
+#: builtin/checkout.c:672
#, c-format
msgid "Reset branch '%s'\n"
msgstr "Repor ramo '%s'\n"
-#: builtin/checkout.c:674
+#: builtin/checkout.c:675
#, c-format
msgid "Already on '%s'\n"
msgstr "Já em '%s'\n"
-#: builtin/checkout.c:678
+#: builtin/checkout.c:679
#, c-format
msgid "Switched to and reset branch '%s'\n"
msgstr "Mudou para e repôs o ramo '%s'\n"
-#: builtin/checkout.c:680 builtin/checkout.c:1069
+#: builtin/checkout.c:681 builtin/checkout.c:1070
#, c-format
msgid "Switched to a new branch '%s'\n"
msgstr "Mudou para o novo ramo '%s'\n"
-#: builtin/checkout.c:682
+#: builtin/checkout.c:683
#, c-format
msgid "Switched to branch '%s'\n"
msgstr "Mudou para o ramo '%s'\n"
-#: builtin/checkout.c:733
+#: builtin/checkout.c:734
#, c-format
msgid " ... and %d more.\n"
msgstr " ... e mais %d.\n"
-#: builtin/checkout.c:739
+#: builtin/checkout.c:740
#, c-format
msgid ""
"Warning: you are leaving %d commit behind, not connected to\n"
"\n"
"%s\n"
-#: builtin/checkout.c:758
+#: builtin/checkout.c:759
#, c-format
msgid ""
"If you want to keep it by creating a new branch, this may be a good time\n"
" git branch <nome-do-novo-ramo> %s\n"
"\n"
-#: builtin/checkout.c:794
+#: builtin/checkout.c:795
msgid "internal error in revision walk"
msgstr "erro interno durante o curso de revisões"
-#: builtin/checkout.c:798
+#: builtin/checkout.c:799
msgid "Previous HEAD position was"
msgstr "A posição anterior de HEAD era"
-#: builtin/checkout.c:825 builtin/checkout.c:1064
+#: builtin/checkout.c:826 builtin/checkout.c:1065
msgid "You are on a branch yet to be born"
msgstr "Está num ramo ainda não criado"
-#: builtin/checkout.c:970
+#: builtin/checkout.c:971
#, c-format
msgid "only one reference expected, %d given."
msgstr "esperava-se apenas uma referência, %d fornecidas."
-#: builtin/checkout.c:1010 builtin/worktree.c:214
+#: builtin/checkout.c:1011 builtin/worktree.c:214
#, c-format
msgid "invalid reference: %s"
msgstr "referência inválida: %s"
-#: builtin/checkout.c:1039
+#: builtin/checkout.c:1040
#, c-format
msgid "reference is not a tree: %s"
msgstr "a referência não é uma árvore: %s"
-#: builtin/checkout.c:1078
+#: builtin/checkout.c:1079
msgid "paths cannot be used with switching branches"
msgstr "não podem ser usados caminhos ao mudar de ramo"
-#: builtin/checkout.c:1081 builtin/checkout.c:1085
+#: builtin/checkout.c:1082 builtin/checkout.c:1086
#, c-format
msgid "'%s' cannot be used with switching branches"
msgstr "'%s' não pode ser usado ao mudar de ramo"
-#: builtin/checkout.c:1089 builtin/checkout.c:1092 builtin/checkout.c:1097
-#: builtin/checkout.c:1100
+#: builtin/checkout.c:1090 builtin/checkout.c:1093 builtin/checkout.c:1098
+#: builtin/checkout.c:1101
#, c-format
msgid "'%s' cannot be used with '%s'"
msgstr "'%s' não pode ser usado com '%s'"
-#: builtin/checkout.c:1105
+#: builtin/checkout.c:1106
#, c-format
msgid "Cannot switch branch to a non-commit '%s'"
msgstr "Não é possível mudar de ramo para '%s', visto que não é um commit"
-#: builtin/checkout.c:1138 builtin/checkout.c:1140 builtin/clone.c:88
+#: builtin/checkout.c:1139 builtin/checkout.c:1141 builtin/clone.c:88
#: builtin/remote.c:165 builtin/remote.c:167 builtin/worktree.c:324
#: builtin/worktree.c:326
msgid "branch"
msgstr "ramo"
-#: builtin/checkout.c:1139
+#: builtin/checkout.c:1140
msgid "create and checkout a new branch"
msgstr "criar e extrair um novo ramo"
-#: builtin/checkout.c:1141
+#: builtin/checkout.c:1142
msgid "create/reset and checkout a branch"
msgstr "criar/repor e extrair um ramo"
-#: builtin/checkout.c:1142
+#: builtin/checkout.c:1143
msgid "create reflog for new branch"
msgstr "criar reflog do novo ramo"
-#: builtin/checkout.c:1143 builtin/worktree.c:328
+#: builtin/checkout.c:1144 builtin/worktree.c:328
msgid "detach HEAD at named commit"
msgstr "destacar HEAD no commit indicado"
-#: builtin/checkout.c:1144
+#: builtin/checkout.c:1145
msgid "set upstream info for new branch"
msgstr "definir a informação do ramo a montante do novo ramo"
-#: builtin/checkout.c:1146
+#: builtin/checkout.c:1147
msgid "new-branch"
msgstr "novo-ramo"
-#: builtin/checkout.c:1146
+#: builtin/checkout.c:1147
msgid "new unparented branch"
msgstr "novo ramo sem pai"
-#: builtin/checkout.c:1147
+#: builtin/checkout.c:1148
msgid "checkout our version for unmerged files"
msgstr "extrair a nossa versão dos ficheiros não integrados"
-#: builtin/checkout.c:1149
+#: builtin/checkout.c:1150
msgid "checkout their version for unmerged files"
msgstr "extrair a versão deles dos ficheiros não integrados"
-#: builtin/checkout.c:1151
+#: builtin/checkout.c:1152
msgid "force checkout (throw away local modifications)"
msgstr "forçar extração (descartar modificações locais)"
-#: builtin/checkout.c:1152
+#: builtin/checkout.c:1153
msgid "perform a 3-way merge with the new branch"
msgstr "realizar uma integração com 3 pontos com o novo ramo"
-#: builtin/checkout.c:1153 builtin/merge.c:231
+#: builtin/checkout.c:1154 builtin/merge.c:231
msgid "update ignored files (default)"
msgstr "atualizar ficheiros ignorados (predefinição)"
-#: builtin/checkout.c:1154 builtin/log.c:1459 parse-options.h:250
+#: builtin/checkout.c:1155 builtin/log.c:1459 parse-options.h:250
msgid "style"
msgstr "estilo"
-#: builtin/checkout.c:1155
+#: builtin/checkout.c:1156
msgid "conflict style (merge or diff3)"
msgstr "estilo de conflito (merge ou diff3)"
-#: builtin/checkout.c:1158
+#: builtin/checkout.c:1159
msgid "do not limit pathspecs to sparse entries only"
msgstr "não restringir especificadores de caminho a entradas esparsas"
-#: builtin/checkout.c:1160
+#: builtin/checkout.c:1161
msgid "second guess 'git checkout <no-such-branch>'"
msgstr "tentar adivinhar 'git checkout <ramo-inexistente>'"
-#: builtin/checkout.c:1162
+#: builtin/checkout.c:1163
msgid "do not check if another worktree is holding the given ref"
msgstr ""
"não verificar se outra árvore de trabalho contém a referência fornecida"
-#: builtin/checkout.c:1163 builtin/clone.c:60 builtin/fetch.c:117
+#: builtin/checkout.c:1164 builtin/clone.c:60 builtin/fetch.c:117
#: builtin/merge.c:228 builtin/pull.c:116 builtin/push.c:536
#: builtin/send-pack.c:168
msgid "force progress reporting"
msgstr "forçar informação de progresso"
-#: builtin/checkout.c:1194
+#: builtin/checkout.c:1195
msgid "-b, -B and --orphan are mutually exclusive"
msgstr "-b, -B e --orphan são mutuamente exclusivos"
-#: builtin/checkout.c:1211
+#: builtin/checkout.c:1212
msgid "--track needs a branch name"
msgstr "--track requer um nome dum ramo"
-#: builtin/checkout.c:1216
+#: builtin/checkout.c:1217
msgid "Missing branch name; try -b"
msgstr "Falta um nome dum ramo; tente -b"
-#: builtin/checkout.c:1252
+#: builtin/checkout.c:1253
msgid "invalid path specification"
msgstr "especificação de caminho inválida"
-#: builtin/checkout.c:1259
+#: builtin/checkout.c:1260
#, c-format
msgid ""
"Cannot update paths and switch to branch '%s' at the same time.\n"
"tempo.\n"
"Pretendia extrair '%s' o qual não pode ser resolvido como commit?"
-#: builtin/checkout.c:1264
+#: builtin/checkout.c:1265
#, c-format
msgid "git checkout: --detach does not take a path argument '%s'"
msgstr "git checkout: --detach não aceita um caminho como argumento '%s'"
-#: builtin/checkout.c:1268
+#: builtin/checkout.c:1269
msgid ""
"git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
"checking out of the index."
msgstr ""
"não é possível invocar unlink sobre o ficheiro sobressalente temporário"
-#: builtin/clone.c:863 builtin/receive-pack.c:1857
+#: builtin/clone.c:863 builtin/receive-pack.c:1855
msgid "Too many arguments."
msgstr "Demasiados argumentos."
#: builtin/fetch.c:108 builtin/pull.c:187
msgid "prune remote-tracking branches no longer on remote"
-msgstr "eliminar os ramos de monitorização remotos que já não existem no remoto"
+msgstr ""
+"eliminar os ramos de monitorização remotos que já não existem no remoto"
#: builtin/fetch.c:109 builtin/pull.c:190
msgid "on-demand"
msgid "no info viewer handled the request"
msgstr "nenhum visualizador de info atendeu o pedido"
-#: builtin/help.c:408
+#: builtin/help.c:401
msgid "Defining attributes per path"
msgstr "Definir atributos por caminho"
-#: builtin/help.c:409
+#: builtin/help.c:402
msgid "Everyday Git With 20 Commands Or So"
msgstr "Diário Git com mais ou menos 20 Comandos"
-#: builtin/help.c:410
+#: builtin/help.c:403
msgid "A Git glossary"
msgstr "Um Glossário do Git"
-#: builtin/help.c:411
+#: builtin/help.c:404
msgid "Specifies intentionally untracked files to ignore"
msgstr ""
"Especificar ficheiros não controlados para serem intencionalmente ignorados"
-#: builtin/help.c:412
+#: builtin/help.c:405
msgid "Defining submodule properties"
msgstr "Definir propriedades de submódulos"
-#: builtin/help.c:413
+#: builtin/help.c:406
msgid "Specifying revisions and ranges for Git"
msgstr "Especificar revisões e intervalos do Git"
-#: builtin/help.c:414
+#: builtin/help.c:407
msgid "A tutorial introduction to Git (for version 1.5.1 or newer)"
msgstr "Uma introdução ao Git (versão 1.5.1 ou mais recente)"
-#: builtin/help.c:415
+#: builtin/help.c:408
msgid "An overview of recommended workflows with Git"
msgstr "Uma descrição geral dos fluxos de trabalho recomendados para o Git"
-#: builtin/help.c:427
+#: builtin/help.c:420
msgid "The common Git guides are:\n"
msgstr "Os guias comuns do Git:\n"
-#: builtin/help.c:448 builtin/help.c:465
+#: builtin/help.c:441 builtin/help.c:458
#, c-format
msgid "usage: %s%s"
msgstr "utilização: %s%s"
-#: builtin/help.c:481
+#: builtin/help.c:474
#, c-format
msgid "`git %s' is aliased to `%s'"
msgstr "'git %s' é um alias de '%s'"
#: builtin/mv.c:72 builtin/rm.c:317
msgid "Please stage your changes to .gitmodules or stash them to proceed"
-msgstr "Prepare as suas alterações em .gitmodules ou esconda-as para prosseguir"
+msgstr ""
+"Prepare as suas alterações em .gitmodules ou esconda-as para prosseguir"
#: builtin/mv.c:90
#, c-format
"Automatic notes merge failed. Fix conflicts in %s and commit the result with "
"'git notes merge --commit', or abort the merge with 'git notes merge --"
"abort'.\n"
-msgstr "A integração automática de notas falhou. Corrija os conflitos em %s e "
+msgstr ""
+"A integração automática de notas falhou. Corrija os conflitos em %s e "
"submeta o resultado com 'git notes merge --commit' ou aborte a integração "
"com 'git notes merge --abort'.\n"
msgid "git receive-pack <git-dir>"
msgstr "git receive-pack <git-dir>"
-#: builtin/receive-pack.c:1845
+#: builtin/receive-pack.c:1843
msgid "quiet"
msgstr "silencioso"
-#: builtin/receive-pack.c:1859
+#: builtin/receive-pack.c:1857
msgid "You must specify a directory."
msgstr "Deve especificar um diretório."
#: builtin/shortlog.c:13
msgid "git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"
-msgstr "git shortlog [<opções>] [<intervalo-de-revisões>] [[--] [<caminho>...]]"
+msgstr ""
+"git shortlog [<opções>] [<intervalo-de-revisões>] [[--] [<caminho>...]]"
#: builtin/shortlog.c:242
msgid "sort output according to the number of commits per author"
#: builtin/update-ref.c:365
msgid "update <refname> not the one it points to"
msgstr ""
-"atualizar a referência <nome-da-referência>, não a referência que esta "
-"aponta"
+"atualizar a referência <nome-da-referência>, não a referência que esta aponta"
#: builtin/update-ref.c:366
msgid "stdin has NUL-terminated arguments"
#, sh-format
msgid ""
"Checking out '$start_head' failed. Try 'git bisect reset <valid-branch>'."
-msgstr "Falha ao extrair '$start_head'. Tente 'git bisect reset <ramo-válido>'."
+msgstr ""
+"Falha ao extrair '$start_head'. Tente 'git bisect reset <ramo-válido>'."
#: git-bisect.sh:177
msgid "won't bisect on cg-seek'ed tree"
msgstr ""
"Depois de resolver este problema, execute \"git rebase --continue\".\n"
"Se prefere ignorar este patch, execute \"git rebase --skip\".\n"
-"Para extrair o ramo original e interromper o rebase, execute \"git rebase "
-"--abort\"."
+"Para extrair o ramo original e interromper o rebase, execute \"git rebase --"
+"abort\"."
#: git-rebase.sh:156 git-rebase.sh:395
#, sh-format
msgid "Could not pick $sha1"
msgstr "Não foi possível apanhar $sha1"
-#: git-rebase--interactive.sh:408 git-rebase--interactive.sh:474
-msgid "This is the 1st commit message:"
-msgstr "Esta é a 1ª mensagem de commit:"
-
-#: git-rebase--interactive.sh:409
-msgid "This is the 2nd commit message:"
-msgstr "Esta é a 2ª mensagem de commit:"
-
-#: git-rebase--interactive.sh:410
-msgid "This is the 3rd commit message:"
-msgstr "Esta é a 3ª mensagem de commit:"
-
-#: git-rebase--interactive.sh:411
-msgid "This is the 4th commit message:"
-msgstr "Esta é a 4ª mensagem de commit:"
+#: git-rebase--interactive.sh:407
+#, sh-format
+msgid "This is the commit message #${n}:"
+msgstr "Esta é a mensagem de commit nº${n}:"
#: git-rebase--interactive.sh:412
-msgid "This is the 5th commit message:"
-msgstr "Esta é a 5ª mensagem de commit:"
-
-#: git-rebase--interactive.sh:413
-msgid "This is the 6th commit message:"
-msgstr "Esta é a 6ª mensagem de commit:"
-
-#: git-rebase--interactive.sh:414
-msgid "This is the 7th commit message:"
-msgstr "Esta é a 7ª mensagem de commit:"
-
-#: git-rebase--interactive.sh:415
-msgid "This is the 8th commit message:"
-msgstr "Esta é a 8ª mensagem de commit:"
-
-#: git-rebase--interactive.sh:416
-msgid "This is the 9th commit message:"
-msgstr "Esta é a 9ª mensagem de commit:"
-
-#: git-rebase--interactive.sh:417
-msgid "This is the 10th commit message:"
-msgstr "Esta é a 10ª mensagem de commit:"
-
-#. TRANSLATORS: if the language you are translating into
-#. doesn't allow you to compose a sentence in this fashion,
-#. consider translating as if this and the following few strings
-#. were "This is the commit message ${n}:"
-#: git-rebase--interactive.sh:422
#, sh-format
-msgid "This is the ${n}th commit message:"
-msgstr "Esta é a ${n}ª mensagem de commit:"
+msgid "The commit message #${n} will be skipped:"
+msgstr "A mensagem de commit nº${n} será ignorada:"
#: git-rebase--interactive.sh:423
#, sh-format
-msgid "This is the ${n}st commit message:"
-msgstr "Está é a ${n}ª mensagem de commit:"
-
-#: git-rebase--interactive.sh:424
-#, sh-format
-msgid "This is the ${n}nd commit message:"
-msgstr "Esta é a ${n}ª mensagem de commit:"
-
-#: git-rebase--interactive.sh:425
-#, sh-format
-msgid "This is the ${n}rd commit message:"
-msgstr "Esta é a ${n}ª mensagem de commit:"
-
-#: git-rebase--interactive.sh:426
-#, sh-format
-msgid "This is the commit message ${n}:"
-msgstr "Esta é a mensagem de commit ${n}:"
-
-#: git-rebase--interactive.sh:432
-msgid "The 1st commit message will be skipped:"
-msgstr "A 1ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:433
-msgid "The 2nd commit message will be skipped:"
-msgstr "A 2ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:434
-msgid "The 3rd commit message will be skipped:"
-msgstr "A 3ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:435
-msgid "The 4th commit message will be skipped:"
-msgstr "A 4ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:436
-msgid "The 5th commit message will be skipped:"
-msgstr "A 5ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:437
-msgid "The 6th commit message will be skipped:"
-msgstr "A 6ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:438
-msgid "The 7th commit message will be skipped:"
-msgstr "A 7ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:439
-msgid "The 8th commit message will be skipped:"
-msgstr "A 8ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:440
-msgid "The 9th commit message will be skipped:"
-msgstr "A 9ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:441
-msgid "The 10th commit message will be skipped:"
-msgstr "A 10ª mensagem de commit será ignorada:"
-
-#. TRANSLATORS: if the language you are translating into
-#. doesn't allow you to compose a sentence in this fashion,
-#. consider translating as if this and the following few strings
-#. were "The commit message ${n} will be skipped:"
-#: git-rebase--interactive.sh:446
-#, sh-format
-msgid "The ${n}th commit message will be skipped:"
-msgstr "A ${n}ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:447
-#, sh-format
-msgid "The ${n}st commit message will be skipped:"
-msgstr "A ${n}ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:448
-#, sh-format
-msgid "The ${n}nd commit message will be skipped:"
-msgstr "A ${n}ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:449
-#, sh-format
-msgid "The ${n}rd commit message will be skipped:"
-msgstr "A ${n}ª mensagem de commit será ignorada:"
-
-#: git-rebase--interactive.sh:450
-#, sh-format
-msgid "The commit message ${n} will be skipped:"
-msgstr "A mensagem de commit ${n} será ignorada:"
-
-#: git-rebase--interactive.sh:462
-#, sh-format
msgid "This is a combination of $count commit."
msgid_plural "This is a combination of $count commits."
msgstr[0] "Isto é a combinação de $count commit."
msgstr[1] "Isto é a combinação de $count commits."
-#: git-rebase--interactive.sh:470
+#: git-rebase--interactive.sh:431
#, sh-format
msgid "Cannot write $fixup_msg"
msgstr "Não é possível escrever $fixup_msg"
-#: git-rebase--interactive.sh:473
+#: git-rebase--interactive.sh:434
msgid "This is a combination of 2 commits."
msgstr "Isto é a combinação de 2 commits."
-#: git-rebase--interactive.sh:514 git-rebase--interactive.sh:557
-#: git-rebase--interactive.sh:560
+#: git-rebase--interactive.sh:435
+msgid "This is the 1st commit message:"
+msgstr "Esta é a 1ª mensagem de commit:"
+
+#: git-rebase--interactive.sh:475 git-rebase--interactive.sh:518
+#: git-rebase--interactive.sh:521
#, sh-format
msgid "Could not apply $sha1... $rest"
msgstr "Não foi possível aplicar $sha1... $rest"
-#: git-rebase--interactive.sh:588
+#: git-rebase--interactive.sh:549
#, sh-format
msgid ""
"Could not amend commit after successfully picking $sha1... $rest\n"
"poder\n"
"reformular a mensagem do commit."
-#: git-rebase--interactive.sh:603
+#: git-rebase--interactive.sh:564
#, sh-format
msgid "Stopped at $sha1_abbrev... $rest"
msgstr "Parou em $sha1_abbrev... $rest"
-#: git-rebase--interactive.sh:618
+#: git-rebase--interactive.sh:579
#, sh-format
msgid "Cannot '$squash_style' without a previous commit"
msgstr "Não é possível efetuar '$squash_style' sem um commit anterior"
-#: git-rebase--interactive.sh:660
+#: git-rebase--interactive.sh:621
#, sh-format
msgid "Executing: $rest"
msgstr "A executar: $rest"
-#: git-rebase--interactive.sh:668
+#: git-rebase--interactive.sh:629
#, sh-format
msgid "Execution failed: $rest"
msgstr "Falha ao executar: $rest"
-#: git-rebase--interactive.sh:670
+#: git-rebase--interactive.sh:631
msgid "and made changes to the index and/or the working tree"
msgstr "e fez alterações ao índice e/ou à árvore de trabalho"
-#: git-rebase--interactive.sh:672
+#: git-rebase--interactive.sh:633
msgid ""
"You can fix the problem, and then run\n"
"\n"
"\tgit rebase --continue"
#. TRANSLATORS: after these lines is a command to be issued by the user
-#: git-rebase--interactive.sh:685
+#: git-rebase--interactive.sh:646
#, sh-format
msgid ""
"Execution succeeded: $rest\n"
"\n"
"\tgit rebase --continue"
-#: git-rebase--interactive.sh:696
+#: git-rebase--interactive.sh:657
#, sh-format
msgid "Unknown command: $command $sha1 $rest"
msgstr "Comando desconhecido: $command $sha1 $rest"
-#: git-rebase--interactive.sh:697
+#: git-rebase--interactive.sh:658
msgid "Please fix this using 'git rebase --edit-todo'."
msgstr "Corrija-o usando 'git rebase --edit-todo'."
-#: git-rebase--interactive.sh:732
+#: git-rebase--interactive.sh:693
#, sh-format
msgid "Successfully rebased and updated $head_name."
msgstr "$head_name rebaseado e atualizado com sucesso."
-#: git-rebase--interactive.sh:779
+#: git-rebase--interactive.sh:740
msgid "Could not skip unnecessary pick commands"
msgstr "Não foi possível saltar comandos pick desnecessários"
-#: git-rebase--interactive.sh:937
+#: git-rebase--interactive.sh:898
#, sh-format
msgid ""
"Warning: the SHA-1 is missing or isn't a commit in the following line:\n"
"Aviso: falta o SHA-1 ou a seguinte linha não tem um commit:\n"
" - $line"
-#: git-rebase--interactive.sh:970
+#: git-rebase--interactive.sh:931
#, sh-format
msgid ""
"Warning: the command isn't recognized in the following line:\n"
"Aviso: o comando não é reconhecido na seguinte linha:\n"
" - $line"
-#: git-rebase--interactive.sh:1009
+#: git-rebase--interactive.sh:970
msgid "could not detach HEAD"
msgstr "não foi possível destacar HEAD"
-#: git-rebase--interactive.sh:1047
+#: git-rebase--interactive.sh:1008
msgid ""
"Warning: some commits may have been dropped accidentally.\n"
"Dropped commits (newer to older):"
"Aviso: alguns commits podem ter sido descartados acidentalmente.\n"
"Commits descartados (mais novo para o mais velho):"
-#: git-rebase--interactive.sh:1055
+#: git-rebase--interactive.sh:1016
msgid ""
"To avoid this message, use \"drop\" to explicitly remove a commit.\n"
"\n"
"warnings.\n"
"The possible behaviours are: ignore, warn, error."
msgstr ""
-"Para evitar esta mensagem, use \"drop\" para remover um commit explicitamente.\n"
+"Para evitar esta mensagem, use \"drop\" para remover um commit "
+"explicitamente.\n"
"\n"
"Use 'git config rebase.missingCommitsCheck' para mudar o nível de avisos.\n"
"O comportamentos possíveis são: ignore, warn, error."
-#: git-rebase--interactive.sh:1066
+#: git-rebase--interactive.sh:1027
#, sh-format
msgid ""
"Unrecognized setting $check_level for option rebase.missingCommitsCheck. "
"Definição $check_level desconhecida da opção rebase.missingCommitsCheck. "
"Ignorado."
-#: git-rebase--interactive.sh:1083
+#: git-rebase--interactive.sh:1044
msgid "You can fix this with 'git rebase --edit-todo'."
msgstr "Pode corrí-lo com 'git rebase --edit-todo'."
-#: git-rebase--interactive.sh:1084
+#: git-rebase--interactive.sh:1045
msgid "Or you can abort the rebase with 'git rebase --abort'."
msgstr "Ou pode abortar o rebase com 'git rebase --abort'."
-#: git-rebase--interactive.sh:1108
+#: git-rebase--interactive.sh:1069
msgid "Could not remove CHERRY_PICK_HEAD"
msgstr "Não foi possível remover CHERRY_PICK_HEAD"
-#: git-rebase--interactive.sh:1113
+#: git-rebase--interactive.sh:1074
#, sh-format
msgid ""
"You have staged changes in your working tree.\n"
"\n"
" git rebase --continue\n"
-#: git-rebase--interactive.sh:1130
+#: git-rebase--interactive.sh:1091
msgid "Error trying to find the author identity to amend commit"
msgstr "Erro ao tentar encontrar a identidade do autor para emendar o commit"
-#: git-rebase--interactive.sh:1135
+#: git-rebase--interactive.sh:1096
msgid ""
"You have uncommitted changes in your working tree. Please commit them\n"
"first and then run 'git rebase --continue' again."
"Tem alterações por submeter na árvore de trabalho. Submeta-as primeiro\n"
"e execute 'git rebase --continue' de novo."
-#: git-rebase--interactive.sh:1140 git-rebase--interactive.sh:1144
+#: git-rebase--interactive.sh:1101 git-rebase--interactive.sh:1105
msgid "Could not commit staged changes."
msgstr "Não foi possível submeter as alterações preparadas."
-#: git-rebase--interactive.sh:1168
+#: git-rebase--interactive.sh:1129
msgid ""
"\n"
"You are editing the todo file of an ongoing interactive rebase.\n"
" git rebase --continue\n"
"\n"
-#: git-rebase--interactive.sh:1176 git-rebase--interactive.sh:1337
+#: git-rebase--interactive.sh:1137 git-rebase--interactive.sh:1298
msgid "Could not execute editor"
msgstr "Não foi possível executar o editor"
-#: git-rebase--interactive.sh:1184
+#: git-rebase--interactive.sh:1145
msgid "You need to set your committer info first"
msgstr "Primeiro tem de definir a sua informação de committer"
-#: git-rebase--interactive.sh:1192
+#: git-rebase--interactive.sh:1153
#, sh-format
msgid "Could not checkout $switch_to"
msgstr "Não foi possível extrair $switch_to"
-#: git-rebase--interactive.sh:1197
+#: git-rebase--interactive.sh:1158
msgid "No HEAD?"
msgstr "Sem HEAD?"
-#: git-rebase--interactive.sh:1198
+#: git-rebase--interactive.sh:1159
#, sh-format
msgid "Could not create temporary $state_dir"
msgstr "Não foi possível criar $state_dir temporário"
-#: git-rebase--interactive.sh:1200
+#: git-rebase--interactive.sh:1161
msgid "Could not mark as interactive"
msgstr "Não foi possível marcar como interativo"
-#: git-rebase--interactive.sh:1210 git-rebase--interactive.sh:1215
+#: git-rebase--interactive.sh:1171 git-rebase--interactive.sh:1176
msgid "Could not init rewritten commits"
msgstr "Não foi possível inicializar commits reescritos"
-#: git-rebase--interactive.sh:1315
+#: git-rebase--interactive.sh:1276
#, sh-format
msgid "Rebase $shortrevisions onto $shortonto ($todocount command)"
msgid_plural "Rebase $shortrevisions onto $shortonto ($todocount commands)"
msgstr[0] "Rebase $shortrevisions sobre $shortonto ($todocount comando)"
msgstr[1] "Rebase $shortrevisions sobre $shortonto ($todocount comandos)"
-#: git-rebase--interactive.sh:1320
+#: git-rebase--interactive.sh:1281
msgid ""
"\n"
"However, if you remove everything, the rebase will be aborted.\n"
"No entanto, se remover tudo, o rebase será abortado.\n"
"\n"
-#: git-rebase--interactive.sh:1327
+#: git-rebase--interactive.sh:1288
msgid "Note that empty commits are commented out"
msgstr "Note que commits vazios são comentados"
msgid "Unable to determine absolute path of git directory"
msgstr "Não é possível determinar o caminho absoluto do diretório git"
+#~ msgid "bad numeric config value '%s' for '%s': invalid unit"
+#~ msgstr ""
+#~ "valor numérico '%s' da configuração '%s' incorreto: unidade inválida"
+
+#~ msgid "bad numeric config value '%s' for '%s' in blob %s: invalid unit"
+#~ msgstr ""
+#~ "valor numérico '%s' da configuração '%s' incorreto no blob %s: unidade "
+#~ "inválida"
+
+#~ msgid "bad numeric config value '%s' for '%s' in file %s: invalid unit"
+#~ msgstr ""
+#~ "valor numérico '%s' da configuração '%s' incorreto no ficheiro %s: "
+#~ "unidade inválida"
+
+#~ msgid ""
+#~ "bad numeric config value '%s' for '%s' in standard input: invalid unit"
+#~ msgstr ""
+#~ "valor numérico '%s' da configuração '%s' incorreto na entrada padrão: "
+#~ "unidade inválida"
+
+#~ msgid ""
+#~ "bad numeric config value '%s' for '%s' in submodule-blob %s: invalid unit"
+#~ msgstr ""
+#~ "valor numérico '%s' da configuração '%s' incorreto no submódulo-blob %s: "
+#~ "unidade inválida"
+
+#~ msgid ""
+#~ "bad numeric config value '%s' for '%s' in command line %s: invalid unit"
+#~ msgstr ""
+#~ "valor numérico '%s' da configuração '%s' incorreto na linha de comandos "
+#~ "%s: unidade inválida"
+
+#~ msgid "bad numeric config value '%s' for '%s' in %s: invalid unit"
+#~ msgstr ""
+#~ "valor numérico '%s' da configuração '%s' incorreto em %s: unidade inválida"
+
+#~ msgid "This is the 2nd commit message:"
+#~ msgstr "Esta é a 2ª mensagem de commit:"
+
+#~ msgid "This is the 3rd commit message:"
+#~ msgstr "Esta é a 3ª mensagem de commit:"
+
+#~ msgid "This is the 4th commit message:"
+#~ msgstr "Esta é a 4ª mensagem de commit:"
+
+#~ msgid "This is the 5th commit message:"
+#~ msgstr "Esta é a 5ª mensagem de commit:"
+
+#~ msgid "This is the 6th commit message:"
+#~ msgstr "Esta é a 6ª mensagem de commit:"
+
+#~ msgid "This is the 7th commit message:"
+#~ msgstr "Esta é a 7ª mensagem de commit:"
+
+#~ msgid "This is the 8th commit message:"
+#~ msgstr "Esta é a 8ª mensagem de commit:"
+
+#~ msgid "This is the 9th commit message:"
+#~ msgstr "Esta é a 9ª mensagem de commit:"
+
+#~ msgid "This is the 10th commit message:"
+#~ msgstr "Esta é a 10ª mensagem de commit:"
+
+#~ msgid "This is the ${n}th commit message:"
+#~ msgstr "Esta é a ${n}ª mensagem de commit:"
+
+#~ msgid "This is the ${n}st commit message:"
+#~ msgstr "Está é a ${n}ª mensagem de commit:"
+
+#~ msgid "This is the ${n}nd commit message:"
+#~ msgstr "Esta é a ${n}ª mensagem de commit:"
+
+#~ msgid "This is the ${n}rd commit message:"
+#~ msgstr "Esta é a ${n}ª mensagem de commit:"
+
+#~ msgid "The 1st commit message will be skipped:"
+#~ msgstr "A 1ª mensagem de commit será ignorada:"
+
+#~ msgid "The 2nd commit message will be skipped:"
+#~ msgstr "A 2ª mensagem de commit será ignorada:"
+
+#~ msgid "The 3rd commit message will be skipped:"
+#~ msgstr "A 3ª mensagem de commit será ignorada:"
+
+#~ msgid "The 4th commit message will be skipped:"
+#~ msgstr "A 4ª mensagem de commit será ignorada:"
+
+#~ msgid "The 5th commit message will be skipped:"
+#~ msgstr "A 5ª mensagem de commit será ignorada:"
+
+#~ msgid "The 6th commit message will be skipped:"
+#~ msgstr "A 6ª mensagem de commit será ignorada:"
+
+#~ msgid "The 7th commit message will be skipped:"
+#~ msgstr "A 7ª mensagem de commit será ignorada:"
+
+#~ msgid "The 8th commit message will be skipped:"
+#~ msgstr "A 8ª mensagem de commit será ignorada:"
+
+#~ msgid "The 9th commit message will be skipped:"
+#~ msgstr "A 9ª mensagem de commit será ignorada:"
+
+#~ msgid "The 10th commit message will be skipped:"
+#~ msgstr "A 10ª mensagem de commit será ignorada:"
+
+#~ msgid "The ${n}th commit message will be skipped:"
+#~ msgstr "A ${n}ª mensagem de commit será ignorada:"
+
+#~ msgid "The ${n}st commit message will be skipped:"
+#~ msgstr "A ${n}ª mensagem de commit será ignorada:"
+
+#~ msgid "The ${n}nd commit message will be skipped:"
+#~ msgstr "A ${n}ª mensagem de commit será ignorada:"
+
+#~ msgid "The ${n}rd commit message will be skipped:"
+#~ msgstr "A ${n}ª mensagem de commit será ignorada:"
+
#~ msgid "could not run gpg."
#~ msgstr "não foi possível executar gpg."
#~ "use the '--force' option. If the local git directory is not the correct "
#~ "repo"
#~ msgstr ""
-#~ "use a opção '--force'. Se o diretório git local não é o repositório correto"
+#~ "use a opção '--force'. Se o diretório git local não é o repositório "
+#~ "correto"
#~ msgid ""
#~ "or you are unsure what this means choose another name with the '--name' "
#~ "Quando push.default está definido como 'matching', o Git publica\n"
#~ "os ramos locais nos ramos remotos que já existam com o mesmo nome.\n"
#~ "\n"
-#~ "Desde a versão 2.0, o Git assume o comportamento mais conservativo 'simple',\n"
+#~ "Desde a versão 2.0, o Git assume o comportamento mais conservativo "
+#~ "'simple',\n"
#~ "publicando só o ramo atual no ramo remoto correspondente, que é usado\n"
#~ "para atualizar o ramo atual com 'git pull'.\n"
#~ "Consulte 'git help config' e procure por 'push.default' para mais "
"Project-Id-Version: Git\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
"POT-Creation-Date: 2016-08-27 23:21+0800\n"
-"PO-Revision-Date: 2016-08-31 00:11+0800\n"
+"PO-Revision-Date: 2016-09-05 23:36+0800\n"
"Last-Translator: Jiang Xin <worldhello.net@gmail.com>\n"
"Language-Team: GitHub <https://github.com/jiangxin/git/>\n"
"Language: zh_CN\n"
#: archive.c:461
msgid "Unexpected option --remote"
-msgstr "æ\84\8få¤\96ç\9a\84é\80\89项 --remote"
+msgstr "æ\9cªç\9f¥å\8f\82æ\95° --remote"
#: archive.c:463
msgid "Option --exec can only be used together with --remote"
#: bisect.c:798
#, c-format
msgid "Bisecting: a merge base must be tested\n"
-msgstr "二分查找中:合并基线必须要测试\n"
+msgstr "二分查找中:合并基线必须是经过测试的\n"
#: bisect.c:849
#, c-format
#, c-format
msgid "Bisecting: %d revision left to test after this %s\n"
msgid_plural "Bisecting: %d revisions left to test after this %s\n"
-msgstr[0] "二分查找中:在 %2$s 之后还剩下 %1$d 个版本\n"
-msgstr[1] "二分查找中:在 %2$s 之后还剩下 %1$d 个版本\n"
+msgstr[0] "二分查找中:在此之后,还剩 %d 个版本待测试 %s\n"
+msgstr[1] "二分查找中:在此之后,还剩 %d 个版本待测试 %s\n"
#: branch.c:53
#, c-format
#: config.c:528
#, c-format
msgid "bad config line %d in submodule-blob %s"
-msgstr "子模组数据 %2$s 中错误的配置行 %1$d"
+msgstr "子模组数据对象 %2$s 中错误的配置行 %1$d"
#: config.c:532
#, c-format
#: config.c:661
#, c-format
msgid "bad numeric config value '%s' for '%s': %s"
-msgstr "配置变量 '%2$s' 的数字取值 '%1$s' 设置错误: %3$s"
+msgstr "配置变量 '%2$s' 的数字取值 '%1$s' 设置错误:%3$s"
#: config.c:666
#, c-format
msgid "bad numeric config value '%s' for '%s' in blob %s: %s"
-msgstr "数据对象 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s': %4$s"
+msgstr "数据对象 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s':%4$s"
#: config.c:669
#, c-format
msgid "bad numeric config value '%s' for '%s' in file %s: %s"
-msgstr "文件 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s': %4$s"
+msgstr "文件 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s':%4$s"
#: config.c:672
#, c-format
msgid "bad numeric config value '%s' for '%s' in standard input: %s"
-msgstr "标准输入中配置变量 '%2$s' 错误的取值 '%1$s': %3$s"
+msgstr "标准输入中配置变量 '%2$s' 错误的取值 '%1$s':%3$s"
#: config.c:675
#, c-format
msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
-msgstr "子模组数据 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s': %4$s"
+msgstr "子模组数据 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s':%4$s"
#: config.c:678
#, c-format
msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
-msgstr "命令行 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s': %4$s"
+msgstr "命令行 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s':%4$s"
#: config.c:681
#, c-format
msgid "bad numeric config value '%s' for '%s' in %s: %s"
-msgstr "在 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s': %4$s"
+msgstr "在 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s':%4$s"
#: config.c:768
#, c-format
#: diff.c:3415
msgid "--follow requires exactly one pathspec"
-msgstr "--follow 参数后只跟一个 pathspec"
+msgstr "--follow 明确要求只跟一个路径规格"
#: diff.c:3578
#, c-format
"WARNING: You called a Git command named '%s', which does not exist.\n"
"Continuing under the assumption that you meant '%s'"
msgstr ""
-"è¦å\91\8aï¼\9aæ\82¨è¿\90è¡\8cä¸\80个ä¸\8då\98å\9c¨ç\9a\84 Git å\91½ä»¤ '%s'ã\80\82继ç»æ\89§è¡\8cå\81\87å®\9aæ\82¨è¦\81è¦\81è¿\90è¡\8cç\9a\84\n"
+"警告:您运行一个不存在的 Git 命令 '%s'。继续执行假定您要运行的\n"
"是 '%s'"
#: help.c:393
"Use '--' to separate paths from revisions, like this:\n"
"'git <command> [<revision>...] -- [<file>...]'"
msgstr ""
-"有歧义的参数 '%s':工作区中未知的版本或路径。\n"
+"有歧义的参数 '%s':未知的版本或路径不存在于工作区中。\n"
"使用 '--' 来分隔版本和路径,例如:\n"
"'git <command> [<revision>...] -- [<file>...]'"
"Use '--' to separate paths from revisions, like this:\n"
"'git <command> [<revision>...] -- [<file>...]'"
msgstr ""
-"有歧义的参数 '%s':两者均为版本和文件\n"
+"有歧义的参数 '%s':可同时是版本和文件\n"
"使用 '--' 来分隔版本和路径,例如:\n"
"'git <command> [<revision>...] -- [<file>...]'"
"Not a git repository (or any parent up to mount point %s)\n"
"Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)."
msgstr ""
-"不是一个 git 仓库(或者任何向上递归到挂载点 %s)\n"
+"不是一个 git 仓库(或者向上递归至挂载点 %s 的任何祖先目录)\n"
"停止在文件系统边界(未设置 GIT_DISCOVERY_ACROSS_FILESYSTEM)。"
#: setup.c:927
"Problem with core.sharedRepository filemode value (0%.3o).\n"
"The owner of files must always have read and write permissions."
msgstr ""
-"参数 core.sharedRepository 的文件权限值有错(0%.3o)。\n"
+"参数 core.sharedRepository 的文件权限值有错(0%.3o)。\n"
"文件属主必须始终拥有读写权限。"
#: sha1_file.c:1046
msgid ""
"The following submodule paths contain changes that can\n"
"not be found on any remote:\n"
-msgstr "如下的子模组路径的修改在任何远程源中都找不到:\n"
+msgstr "下列子模组路径所包含的修改在任何远程源中都找不到:\n"
#: transport.c:775
#, c-format
"\n"
"\tgit push\n"
"\n"
-"来推送到远程源。\n"
+"以推送至远程。\n"
"\n"
#: transport.c:783
#: builtin/fetch.c:610
msgid "can't fetch in current branch"
-msgstr "不能获取到当前分支"
+msgstr "当前分支下不能执行获取操作"
#: builtin/fetch.c:619
msgid "[tag update]"
#: builtin/init-db.c:407
#, c-format
msgid "Initialized empty shared Git repository in %s%s\n"
-msgstr "初始化空的共享 Git 仓库于 %s%s\n"
+msgstr "å·²å\88\9då§\8bå\8c\96空ç\9a\84å\85±äº« Git ä»\93åº\93äº\8e %s%s\n"
#: builtin/init-db.c:408
#, c-format
msgid "Initialized empty Git repository in %s%s\n"
-msgstr "初始化空的 Git 仓库于 %s%s\n"
+msgstr "å·²å\88\9då§\8bå\8c\96空ç\9a\84 Git ä»\93åº\93äº\8e %s%s\n"
#: builtin/init-db.c:455
msgid ""
#: builtin/merge.c:960
#, c-format
msgid "Bad value '%s' in environment '%s'"
-msgstr "环境 '%2$s' 坏的取值 '%1$s'"
+msgstr "环境 '%2$s' 中存在坏的取值 '%1$s'"
#: builtin/merge.c:1034
#, c-format
#: builtin/notes.c:797
msgid "Must specify a notes ref to merge"
-msgstr "您必须指定一个注解引用来合并"
+msgstr "必须指定一个注解引用来合并"
#: builtin/notes.c:821
#, c-format
#: builtin/push.c:546
msgid "option to transmit"
-msgstr "传输的选项"
+msgstr "传输选项"
#: builtin/push.c:560
msgid "--delete is incompatible with --all, --mirror and --tags"
#: builtin/submodule--helper.c:840
msgid "whether the initial clone should follow the shallow recommendation"
-msgstr "是否初始克隆应该遵守推荐的浅克隆选项"
+msgstr "初始克隆是否应该遵守推荐的浅克隆选项"
#: builtin/submodule--helper.c:841
msgid "don't print cloning progress"
#: git-bisect.sh:262
#, sh-format
msgid "Bad rev input: $arg"
-msgstr "输入坏的版本:$arg"
+msgstr "坏的输入版本:$arg"
#: git-bisect.sh:281
#, sh-format
msgid "Bad rev input: $bisected_head"
-msgstr "输入坏的版本:$bisected_head"
+msgstr "坏的输入版本:$bisected_head"
#: git-bisect.sh:290
#, sh-format
msgid "Bad rev input: $rev"
-msgstr "输入坏的版本:$rev"
+msgstr "坏的输入版本:$rev"
#: git-bisect.sh:299
#, sh-format
#: git-merge-octopus.sh:61
msgid "Automated merge did not work."
-msgstr "自动合并不工作"
+msgstr "自动合并未生效。"
#: git-merge-octopus.sh:62
msgid "Should not be doing an Octopus."
#: git-merge-octopus.sh:102
msgid "Simple merge did not work, trying automatic merge."
-msgstr "简单合并不行,尝试自动合并。"
+msgstr "简单合并未生效,尝试自动合并。"
#: git-rebase.sh:56
msgid ""
#: git-stash.sh:551
msgid "The stash is kept in case you need it again."
-msgstr "进度保存以免您再需要。"
+msgstr "暂存被保留以备您再次需要。"
#: git-stash.sh:560
#, sh-format
"(use 'rm -rf' if you really want to remove it including all of its history)"
msgstr ""
"子模组工作区 '$displaypath' 包含一个 .git 目录\n"
-"(使用 'rm -rf' 命令如果您真的想删除它及其全部历史)"
+"(如果您真的想删除它及其全部历史,使用 'rm -rf' 命令)"
#: git-submodule.sh:447
#, sh-format
msgid ""
"Unable to find current ${remote_name}/${branch} revision in submodule path "
"'$sm_path'"
-msgstr "无法在子模组路径 '$sm_path' 中找到当前 ${remote_name}/${branch} 版本"
+msgstr "无法在子模组路径 '$sm_path' 中找到当前版本 ${remote_name}/${branch}"
#: git-submodule.sh:645
#, sh-format
" x, exec = 使用 shell 运行命令(此行剩余部分)\n"
" d, drop = 删除提交\n"
"\n"
-"这些行可以重新排序,从上至下地执行。\n"
+"这些行可以被重新排序;它们会被从上至下地执行。\n"
"\n"
#: git-rebase--interactive.sh:162
msgid ""
"\n"
"If you remove a line here THAT COMMIT WILL BE LOST.\n"
-msgstr "\n如果您在这里删除一行,这个提交将会丢失。\n"
+msgstr "\n如果您在这里删除一行,对应的提交将会丢失。\n"
#: git-rebase--interactive.sh:202
#, sh-format
"\n"
"\tgit commit --amend $gpg_sign_opt_quoted\n"
"\n"
-"一旦您对变更满意,执行\n"
+"当您对变更感到满意,执行\n"
"\n"
"\tgit rebase --continue"
#: git-rebase--interactive.sh:407
#, sh-format
msgid "This is the commit message #${n}:"
-msgstr "这是提交信息 #${n}:"
+msgstr "这是提交说明 #${n}:"
#: git-rebase--interactive.sh:412
#, sh-format
msgid "The commit message #${n} will be skipped:"
-msgstr "提交信息 #${n} 将被跳过:"
+msgstr "提交说明 #${n} 将被跳过:"
#: git-rebase--interactive.sh:423
#, sh-format
#: git-rebase--interactive.sh:579
#, sh-format
msgid "Cannot '$squash_style' without a previous commit"
-msgstr "不能在没有前一个提交的情况下 '$squash_style'"
+msgstr "没有父提交的情况下不能 '$squash_style'"
#: git-rebase--interactive.sh:621
#, sh-format
#: git-rebase--interactive.sh:693
#, sh-format
msgid "Successfully rebased and updated $head_name."
-msgstr "成功变基并更新 $head_name."
+msgstr "成功变基并更新 $head_name。"
#: git-rebase--interactive.sh:740
msgid "Could not skip unnecessary pick commands"
"warnings.\n"
"The possible behaviours are: ignore, warn, error."
msgstr ""
-"为避免这条信息,使用 drop 指令显式地删除一个提交。\n"
+"为避免这条信息,使用 \"drop\" 指令显式地删除一个提交。\n"
"\n"
-"使ç\94¨ 'git config rebase.missingCommitsCheck' æ\9d¥ä¿®æ\94¹è¿\99个级å\88«ç\9a\84è¦å\91\8a。\n"
-"可以使用:ignore、warn、error。"
+"使ç\94¨ 'git config rebase.missingCommitsCheck' æ\9d¥ä¿®æ\94¹è¦å\91\8a级å\88«。\n"
+"可选值有:ignore、warn、error。"
#: git-rebase--interactive.sh:1027
#, sh-format
msgid ""
"Unrecognized setting $check_level for option rebase.missingCommitsCheck. "
"Ignoring."
-msgstr "选项 rebase.missingCommitsCheck 中无法识别的设置 $check_level。忽略。"
+msgstr "选项 rebase.missingCommitsCheck 的值 $check_level 无法被识别。已忽略。"
#: git-rebase--interactive.sh:1044
msgid "You can fix this with 'git rebase --edit-todo'."
"\n"
" git commit $gpg_sign_opt_quoted\n"
"\n"
-"两种情况下,一旦执行完毕,继续执行:\n"
+"无论哪种情况,当您完成提交,继续执行:\n"
"\n"
" git rebase --continue\n"
#: git-rebase--interactive.sh:1091
msgid "Error trying to find the author identity to amend commit"
-msgstr "å½\93å\9c¨ä¿®è¡¥æ\8f\90交ä¸æ\9f¥æ\89¾ä½\9cè\80\85ä¿¡æ\81¯æ\97¶é\81\87å\88°é\94\99误"
+msgstr "在修补提交中查找作者信息时遇到错误"
#: git-rebase--interactive.sh:1096
msgid ""
"You have uncommitted changes in your working tree. Please commit them\n"
"first and then run 'git rebase --continue' again."
-msgstr "您的工作区中有未提交的变更。请先提交然后再运行 'git rebase --continue'。"
+msgstr "您的工作区中有未提交的变更。请先提交然后再次运行 'git rebase --continue'。"
#: git-rebase--interactive.sh:1101 git-rebase--interactive.sh:1105
msgid "Could not commit staged changes."
"\n"
msgstr ""
"\n"
-"您正在修改运行中的交互式变基的 todo 文件。编辑结束后继续变基,\n"
+"您正在修改运行中的交互式变基的 todo 文件。若要在编辑结束后继续变基,\n"
"请执行:\n"
" git rebase --continue\n"
"\n"
#: git-sh-setup.sh:190
#, sh-format
msgid "Cannot chdir to $cdup, the toplevel of the working tree"
-msgstr "不能更换目录到 $cdup,工作区的顶级目录"
+msgstr "不能切换目录到 $cdup,工作区的顶级目录"
#: git-sh-setup.sh:199 git-sh-setup.sh:206
#, sh-format
const struct commit *commit = c->commit;
const char *msg = c->message;
struct commit_list *p;
- int h1, h2;
+ int ch;
/* these are independent of the commit */
switch (placeholder[0]) {
return 1;
case 'x':
/* %x00 == NUL, %x0a == LF, etc. */
- if (0 <= (h1 = hexval_table[0xff & placeholder[1]]) &&
- h1 <= 16 &&
- 0 <= (h2 = hexval_table[0xff & placeholder[2]]) &&
- h2 <= 16) {
- strbuf_addch(sb, (h1<<4)|h2);
- return 3;
- } else
+ ch = hex2chr(placeholder + 1);
+ if (ch < 0)
return 0;
+ strbuf_addch(sb, ch);
+ return 3;
case 'w':
if (placeholder[1] == '(') {
unsigned long width = 0, indent1 = 0, indent2 = 0;
qsort(array->items, array->nr, sizeof(struct ref_array_item *), compare_refs);
}
-static int hex1(char ch)
-{
- if ('0' <= ch && ch <= '9')
- return ch - '0';
- else if ('a' <= ch && ch <= 'f')
- return ch - 'a' + 10;
- else if ('A' <= ch && ch <= 'F')
- return ch - 'A' + 10;
- return -1;
-}
-static int hex2(const char *cp)
-{
- if (cp[0] && cp[1])
- return (hex1(cp[0]) << 4) | hex1(cp[1]);
- else
- return -1;
-}
-
static void append_literal(const char *cp, const char *ep, struct ref_formatting_state *state)
{
struct strbuf *s = &state->stack->output;
if (cp[1] == '%')
cp++;
else {
- int ch = hex2(cp + 1);
+ int ch = hex2chr(cp + 1);
if (0 <= ch) {
strbuf_addch(s, ch);
cp += 3;
struct strbuf refname;
struct strbuf path = STRBUF_INIT;
size_t path_baselen;
+ int err = 0;
if (*refs->name)
- strbuf_git_path_submodule(&path, refs->name, "%s", dirname);
+ err = strbuf_git_path_submodule(&path, refs->name, "%s", dirname);
else
strbuf_git_path(&path, "%s", dirname);
path_baselen = path.len;
+ if (err) {
+ strbuf_release(&path);
+ return;
+ }
+
d = opendir(path.buf);
if (!d) {
strbuf_release(&path);
#include "streaming.h"
#include "dir.h"
#include "mru.h"
+#include "list.h"
#ifndef O_NOATIME
#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
const unsigned char null_sha1[20];
const struct object_id null_oid;
+const struct object_id empty_tree_oid = {
+ EMPTY_TREE_SHA1_BIN_LITERAL
+};
+const struct object_id empty_blob_oid = {
+ EMPTY_BLOB_SHA1_BIN_LITERAL
+};
/*
* This is meant to hold a *small* number of objects that you would
free(alts);
}
+/*
+ * Compute the exact path an alternate is at and returns it. In case of
+ * error NULL is returned and the human readable error is added to `err`
+ * `path` may be relative and should point to $GITDIR.
+ * `err` must not be null.
+ */
+char *compute_alternate_path(const char *path, struct strbuf *err)
+{
+ char *ref_git = NULL;
+ const char *repo, *ref_git_s;
+ int seen_error = 0;
+
+ ref_git_s = real_path_if_valid(path);
+ if (!ref_git_s) {
+ seen_error = 1;
+ strbuf_addf(err, _("path '%s' does not exist"), path);
+ goto out;
+ } else
+ /*
+ * Beware: read_gitfile(), real_path() and mkpath()
+ * return static buffer
+ */
+ ref_git = xstrdup(ref_git_s);
+
+ repo = read_gitfile(ref_git);
+ if (!repo)
+ repo = read_gitfile(mkpath("%s/.git", ref_git));
+ if (repo) {
+ free(ref_git);
+ ref_git = xstrdup(repo);
+ }
+
+ if (!repo && is_directory(mkpath("%s/.git/objects", ref_git))) {
+ char *ref_git_git = mkpathdup("%s/.git", ref_git);
+ free(ref_git);
+ ref_git = ref_git_git;
+ } else if (!is_directory(mkpath("%s/objects", ref_git))) {
+ struct strbuf sb = STRBUF_INIT;
+ seen_error = 1;
+ if (get_common_dir(&sb, ref_git)) {
+ strbuf_addf(err,
+ _("reference repository '%s' as a linked "
+ "checkout is not supported yet."),
+ path);
+ goto out;
+ }
+
+ strbuf_addf(err, _("reference repository '%s' is not a "
+ "local repository."), path);
+ goto out;
+ }
+
+ if (!access(mkpath("%s/shallow", ref_git), F_OK)) {
+ strbuf_addf(err, _("reference repository '%s' is shallow"),
+ path);
+ seen_error = 1;
+ goto out;
+ }
+
+ if (!access(mkpath("%s/info/grafts", ref_git), F_OK)) {
+ strbuf_addf(err,
+ _("reference repository '%s' is grafted"),
+ path);
+ seen_error = 1;
+ goto out;
+ }
+
+out:
+ if (seen_error) {
+ free(ref_git);
+ ref_git = NULL;
+ }
+
+ return ref_git;
+}
+
int foreach_alt_odb(alt_odb_fn fn, void *cb)
{
struct alternate_object_database *ent;
return buffer;
}
-#define MAX_DELTA_CACHE (256)
-
+static struct hashmap delta_base_cache;
static size_t delta_base_cached;
-static struct delta_base_cache_lru_list {
- struct delta_base_cache_lru_list *prev;
- struct delta_base_cache_lru_list *next;
-} delta_base_cache_lru = { &delta_base_cache_lru, &delta_base_cache_lru };
+static LIST_HEAD(delta_base_cache_lru);
-static struct delta_base_cache_entry {
- struct delta_base_cache_lru_list lru;
- void *data;
+struct delta_base_cache_key {
struct packed_git *p;
off_t base_offset;
+};
+
+struct delta_base_cache_entry {
+ struct hashmap hash;
+ struct delta_base_cache_key key;
+ struct list_head lru;
+ void *data;
unsigned long size;
enum object_type type;
-} delta_base_cache[MAX_DELTA_CACHE];
+};
-static unsigned long pack_entry_hash(struct packed_git *p, off_t base_offset)
+static unsigned int pack_entry_hash(struct packed_git *p, off_t base_offset)
{
- unsigned long hash;
+ unsigned int hash;
- hash = (unsigned long)(intptr_t)p + (unsigned long)base_offset;
+ hash = (unsigned int)(intptr_t)p + (unsigned int)base_offset;
hash += (hash >> 8) + (hash >> 16);
- return hash % MAX_DELTA_CACHE;
+ return hash;
}
static struct delta_base_cache_entry *
get_delta_base_cache_entry(struct packed_git *p, off_t base_offset)
{
- unsigned long hash = pack_entry_hash(p, base_offset);
- return delta_base_cache + hash;
+ struct hashmap_entry entry;
+ struct delta_base_cache_key key;
+
+ if (!delta_base_cache.cmpfn)
+ return NULL;
+
+ hashmap_entry_init(&entry, pack_entry_hash(p, base_offset));
+ key.p = p;
+ key.base_offset = base_offset;
+ return hashmap_get(&delta_base_cache, &entry, &key);
+}
+
+static int delta_base_cache_key_eq(const struct delta_base_cache_key *a,
+ const struct delta_base_cache_key *b)
+{
+ return a->p == b->p && a->base_offset == b->base_offset;
}
-static int eq_delta_base_cache_entry(struct delta_base_cache_entry *ent,
- struct packed_git *p, off_t base_offset)
+static int delta_base_cache_hash_cmp(const void *va, const void *vb,
+ const void *vkey)
{
- return (ent->data && ent->p == p && ent->base_offset == base_offset);
+ const struct delta_base_cache_entry *a = va, *b = vb;
+ const struct delta_base_cache_key *key = vkey;
+ if (key)
+ return !delta_base_cache_key_eq(&a->key, key);
+ else
+ return !delta_base_cache_key_eq(&a->key, &b->key);
}
static int in_delta_base_cache(struct packed_git *p, off_t base_offset)
{
- struct delta_base_cache_entry *ent;
- ent = get_delta_base_cache_entry(p, base_offset);
- return eq_delta_base_cache_entry(ent, p, base_offset);
+ return !!get_delta_base_cache_entry(p, base_offset);
}
-static void clear_delta_base_cache_entry(struct delta_base_cache_entry *ent)
+/*
+ * Remove the entry from the cache, but do _not_ free the associated
+ * entry data. The caller takes ownership of the "data" buffer, and
+ * should copy out any fields it wants before detaching.
+ */
+static void detach_delta_base_cache_entry(struct delta_base_cache_entry *ent)
{
- ent->data = NULL;
- ent->lru.next->prev = ent->lru.prev;
- ent->lru.prev->next = ent->lru.next;
+ hashmap_remove(&delta_base_cache, ent, &ent->key);
+ list_del(&ent->lru);
delta_base_cached -= ent->size;
+ free(ent);
}
static void *cache_or_unpack_entry(struct packed_git *p, off_t base_offset,
- unsigned long *base_size, enum object_type *type, int keep_cache)
+ unsigned long *base_size, enum object_type *type)
{
struct delta_base_cache_entry *ent;
- void *ret;
ent = get_delta_base_cache_entry(p, base_offset);
-
- if (!eq_delta_base_cache_entry(ent, p, base_offset))
+ if (!ent)
return unpack_entry(p, base_offset, type, base_size);
- ret = ent->data;
-
- if (!keep_cache)
- clear_delta_base_cache_entry(ent);
- else
- ret = xmemdupz(ent->data, ent->size);
*type = ent->type;
*base_size = ent->size;
- return ret;
+ return xmemdupz(ent->data, ent->size);
}
static inline void release_delta_base_cache(struct delta_base_cache_entry *ent)
{
- if (ent->data) {
- free(ent->data);
- ent->data = NULL;
- ent->lru.next->prev = ent->lru.prev;
- ent->lru.prev->next = ent->lru.next;
- delta_base_cached -= ent->size;
- }
+ free(ent->data);
+ detach_delta_base_cache_entry(ent);
}
void clear_delta_base_cache(void)
{
- unsigned long p;
- for (p = 0; p < MAX_DELTA_CACHE; p++)
- release_delta_base_cache(&delta_base_cache[p]);
+ struct hashmap_iter iter;
+ struct delta_base_cache_entry *entry;
+ for (entry = hashmap_iter_first(&delta_base_cache, &iter);
+ entry;
+ entry = hashmap_iter_next(&iter)) {
+ release_delta_base_cache(entry);
+ }
}
static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
void *base, unsigned long base_size, enum object_type type)
{
- unsigned long hash = pack_entry_hash(p, base_offset);
- struct delta_base_cache_entry *ent = delta_base_cache + hash;
- struct delta_base_cache_lru_list *lru;
+ struct delta_base_cache_entry *ent = xmalloc(sizeof(*ent));
+ struct list_head *lru;
- release_delta_base_cache(ent);
delta_base_cached += base_size;
- for (lru = delta_base_cache_lru.next;
- delta_base_cached > delta_base_cache_limit
- && lru != &delta_base_cache_lru;
- lru = lru->next) {
- struct delta_base_cache_entry *f = (void *)lru;
- if (f->type == OBJ_BLOB)
- release_delta_base_cache(f);
- }
- for (lru = delta_base_cache_lru.next;
- delta_base_cached > delta_base_cache_limit
- && lru != &delta_base_cache_lru;
- lru = lru->next) {
- struct delta_base_cache_entry *f = (void *)lru;
+ list_for_each(lru, &delta_base_cache_lru) {
+ struct delta_base_cache_entry *f =
+ list_entry(lru, struct delta_base_cache_entry, lru);
+ if (delta_base_cached <= delta_base_cache_limit)
+ break;
release_delta_base_cache(f);
}
- ent->p = p;
- ent->base_offset = base_offset;
+ ent->key.p = p;
+ ent->key.base_offset = base_offset;
ent->type = type;
ent->data = base;
ent->size = base_size;
- ent->lru.next = &delta_base_cache_lru;
- ent->lru.prev = delta_base_cache_lru.prev;
- delta_base_cache_lru.prev->next = &ent->lru;
- delta_base_cache_lru.prev = &ent->lru;
+ list_add_tail(&ent->lru, &delta_base_cache_lru);
+
+ if (!delta_base_cache.cmpfn)
+ hashmap_init(&delta_base_cache, delta_base_cache_hash_cmp, 0);
+ hashmap_entry_init(ent, pack_entry_hash(p, base_offset));
+ hashmap_add(&delta_base_cache, ent);
}
static void *read_object(const unsigned char *sha1, enum object_type *type,
struct delta_base_cache_entry *ent;
ent = get_delta_base_cache_entry(p, curpos);
- if (eq_delta_base_cache_entry(ent, p, curpos)) {
+ if (ent) {
type = ent->type;
data = ent->data;
size = ent->size;
- clear_delta_base_cache_entry(ent);
+ detach_delta_base_cache_entry(ent);
base_from_cache = 1;
break;
}
if (!find_pack_entry(sha1, &e))
return NULL;
- data = cache_or_unpack_entry(e.p, e.offset, size, type, 1);
+ data = cache_or_unpack_entry(e.p, e.offset, size, type);
if (!data) {
/*
* We're probably in deep shit, but let's try to fetch
int ret = 0;
size_t alloc;
- strbuf_git_path_submodule(&objects_directory, path, "objects/");
+ ret = strbuf_git_path_submodule(&objects_directory, path, "objects/");
+ if (ret)
+ goto done;
if (!is_directory(objects_directory.buf)) {
ret = -1;
goto done;
static int prepare_submodule_summary(struct rev_info *rev, const char *path,
struct commit *left, struct commit *right,
- int *fast_forward, int *fast_backward)
+ struct commit_list *merge_bases)
{
- struct commit_list *merge_bases, *list;
+ struct commit_list *list;
init_revisions(rev, NULL);
setup_revisions(0, NULL, rev, NULL);
left->object.flags |= SYMMETRIC_LEFT;
add_pending_object(rev, &left->object, path);
add_pending_object(rev, &right->object, path);
- merge_bases = get_merge_bases(left, right);
- if (merge_bases) {
- if (merge_bases->item == left)
- *fast_forward = 1;
- else if (merge_bases->item == right)
- *fast_backward = 1;
- }
for (list = merge_bases; list; list = list->next) {
list->item->object.flags |= UNINTERESTING;
add_pending_object(rev, &list->item->object,
strbuf_release(&sb);
}
-void show_submodule_summary(FILE *f, const char *path,
+/* Helper function to display the submodule header line prior to the full
+ * summary output. If it can locate the submodule objects directory it will
+ * attempt to lookup both the left and right commits and put them into the
+ * left and right pointers.
+ */
+static void show_submodule_header(FILE *f, const char *path,
const char *line_prefix,
- unsigned char one[20], unsigned char two[20],
+ struct object_id *one, struct object_id *two,
unsigned dirty_submodule, const char *meta,
- const char *del, const char *add, const char *reset)
+ const char *reset,
+ struct commit **left, struct commit **right,
+ struct commit_list **merge_bases)
{
- struct rev_info rev;
- struct commit *left = NULL, *right = NULL;
const char *message = NULL;
struct strbuf sb = STRBUF_INIT;
int fast_forward = 0, fast_backward = 0;
- if (is_null_sha1(two))
- message = "(submodule deleted)";
- else if (add_submodule_odb(path))
- message = "(not checked out)";
- else if (is_null_sha1(one))
- message = "(new submodule)";
- else if (!(left = lookup_commit_reference(one)) ||
- !(right = lookup_commit_reference(two)))
- message = "(commits not present)";
- else if (prepare_submodule_summary(&rev, path, left, right,
- &fast_forward, &fast_backward))
- message = "(revision walker failed)";
-
if (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)
fprintf(f, "%sSubmodule %s contains untracked content\n",
line_prefix, path);
fprintf(f, "%sSubmodule %s contains modified content\n",
line_prefix, path);
- if (!hashcmp(one, two)) {
+ if (is_null_oid(one))
+ message = "(new submodule)";
+ else if (is_null_oid(two))
+ message = "(submodule deleted)";
+
+ if (add_submodule_odb(path)) {
+ if (!message)
+ message = "(not initialized)";
+ goto output_header;
+ }
+
+ /*
+ * Attempt to lookup the commit references, and determine if this is
+ * a fast forward or fast backwards update.
+ */
+ *left = lookup_commit_reference(one->hash);
+ *right = lookup_commit_reference(two->hash);
+
+ /*
+ * Warn about missing commits in the submodule project, but only if
+ * they aren't null.
+ */
+ if ((!is_null_oid(one) && !*left) ||
+ (!is_null_oid(two) && !*right))
+ message = "(commits not present)";
+
+ *merge_bases = get_merge_bases(*left, *right);
+ if (*merge_bases) {
+ if ((*merge_bases)->item == *left)
+ fast_forward = 1;
+ else if ((*merge_bases)->item == *right)
+ fast_backward = 1;
+ }
+
+ if (!oidcmp(one, two)) {
strbuf_release(&sb);
return;
}
+output_header:
strbuf_addf(&sb, "%s%sSubmodule %s %s..", line_prefix, meta, path,
- find_unique_abbrev(one, DEFAULT_ABBREV));
+ find_unique_abbrev(one->hash, DEFAULT_ABBREV));
if (!fast_backward && !fast_forward)
strbuf_addch(&sb, '.');
- strbuf_addf(&sb, "%s", find_unique_abbrev(two, DEFAULT_ABBREV));
+ strbuf_addf(&sb, "%s", find_unique_abbrev(two->hash, DEFAULT_ABBREV));
if (message)
strbuf_addf(&sb, " %s%s\n", message, reset);
else
strbuf_addf(&sb, "%s:%s\n", fast_backward ? " (rewind)" : "", reset);
fwrite(sb.buf, sb.len, 1, f);
- if (!message) /* only NULL if we succeeded in setting up the walk */
- print_submodule_summary(&rev, f, line_prefix, del, add, reset);
+ strbuf_release(&sb);
+}
+
+void show_submodule_summary(FILE *f, const char *path,
+ const char *line_prefix,
+ struct object_id *one, struct object_id *two,
+ unsigned dirty_submodule, const char *meta,
+ const char *del, const char *add, const char *reset)
+{
+ struct rev_info rev;
+ struct commit *left = NULL, *right = NULL;
+ struct commit_list *merge_bases = NULL;
+
+ show_submodule_header(f, path, line_prefix, one, two, dirty_submodule,
+ meta, reset, &left, &right, &merge_bases);
+
+ /*
+ * If we don't have both a left and a right pointer, there is no
+ * reason to try and display a summary. The header line should contain
+ * all the information the user needs.
+ */
+ if (!left || !right)
+ goto out;
+
+ /* Treat revision walker failure the same as missing commits */
+ if (prepare_submodule_summary(&rev, path, left, right, merge_bases)) {
+ fprintf(f, "%s(revision walker failed)\n", line_prefix);
+ goto out;
+ }
+
+ print_submodule_summary(&rev, f, line_prefix, del, add, reset);
+
+out:
+ if (merge_bases)
+ free_commit_list(merge_bases);
+ clear_commit_marks(left, ~0);
+ clear_commit_marks(right, ~0);
+}
+
+void show_submodule_inline_diff(FILE *f, const char *path,
+ const char *line_prefix,
+ struct object_id *one, struct object_id *two,
+ unsigned dirty_submodule, const char *meta,
+ const char *del, const char *add, const char *reset,
+ const struct diff_options *o)
+{
+ const struct object_id *old = &empty_tree_oid, *new = &empty_tree_oid;
+ struct commit *left = NULL, *right = NULL;
+ struct commit_list *merge_bases = NULL;
+ struct strbuf submodule_dir = STRBUF_INIT;
+ struct child_process cp = CHILD_PROCESS_INIT;
+
+ show_submodule_header(f, path, line_prefix, one, two, dirty_submodule,
+ meta, reset, &left, &right, &merge_bases);
+
+ /* We need a valid left and right commit to display a difference */
+ if (!(left || is_null_oid(one)) ||
+ !(right || is_null_oid(two)))
+ goto done;
+
+ if (left)
+ old = one;
+ if (right)
+ new = two;
+
+ fflush(f);
+ cp.git_cmd = 1;
+ cp.dir = path;
+ cp.out = dup(fileno(f));
+ cp.no_stdin = 1;
+
+ /* TODO: other options may need to be passed here. */
+ argv_array_push(&cp.args, "diff");
+ argv_array_pushf(&cp.args, "--line-prefix=%s", line_prefix);
+ if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
+ argv_array_pushf(&cp.args, "--src-prefix=%s%s/",
+ o->b_prefix, path);
+ argv_array_pushf(&cp.args, "--dst-prefix=%s%s/",
+ o->a_prefix, path);
+ } else {
+ argv_array_pushf(&cp.args, "--src-prefix=%s%s/",
+ o->a_prefix, path);
+ argv_array_pushf(&cp.args, "--dst-prefix=%s%s/",
+ o->b_prefix, path);
+ }
+ argv_array_push(&cp.args, oid_to_hex(old));
+ /*
+ * If the submodule has modified content, we will diff against the
+ * work tree, under the assumption that the user has asked for the
+ * diff format and wishes to actually see all differences even if they
+ * haven't yet been committed to the submodule yet.
+ */
+ if (!(dirty_submodule & DIRTY_SUBMODULE_MODIFIED))
+ argv_array_push(&cp.args, oid_to_hex(new));
+
+ if (run_command(&cp))
+ fprintf(f, "(diff failed)\n");
+
+done:
+ strbuf_release(&submodule_dir);
+ if (merge_bases)
+ free_commit_list(merge_bases);
if (left)
clear_commit_marks(left, ~0);
if (right)
clear_commit_marks(right, ~0);
-
- strbuf_release(&sb);
}
void set_config_fetch_recurse_submodules(int value)
if (strcmp(*var, CONFIG_DATA_ENVIRONMENT))
argv_array_push(out, *var);
}
+ argv_array_push(out, "GIT_DIR=.git");
}
void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *);
void show_submodule_summary(FILE *f, const char *path,
const char *line_prefix,
- unsigned char one[20], unsigned char two[20],
+ struct object_id *one, struct object_id *two,
unsigned dirty_submodule, const char *meta,
const char *del, const char *add, const char *reset);
+void show_submodule_inline_diff(FILE *f, const char *path,
+ const char *line_prefix,
+ struct object_id *one, struct object_id *two,
+ unsigned dirty_submodule, const char *meta,
+ const char *del, const char *add, const char *reset,
+ const struct diff_options *opt);
void set_config_fetch_recurse_submodules(int value);
void check_for_new_submodule_commits(unsigned char new_sha1[20]);
int fetch_populated_submodules(const struct argv_array *options,
--- /dev/null
+#!/bin/sh
+
+test_description='Test operations that emphasize the delta base cache.
+
+We look at both "log --raw", which should put only trees into the delta cache,
+and "log -Sfoo --raw", which should look at both trees and blobs.
+
+Any effects will be emphasized if the test repository is fully packed (loose
+objects obviously do not use the delta base cache at all). It is also
+emphasized if the pack has long delta chains (e.g., as produced by "gc
+--aggressive"), though cache is still quite noticeable even with the default
+depth of 50.
+
+The setting of core.deltaBaseCacheLimit in the source repository is also
+relevant (depending on the size of your test repo), so be sure it is consistent
+between runs.
+'
+. ./perf-lib.sh
+
+test_perf_large_repo
+
+# puts mostly trees into the delta base cache
+test_perf 'log --raw' '
+ git log --raw >/dev/null
+'
+
+test_perf 'log -S' '
+ git log --raw -Sfoo >/dev/null
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+
+test_description='help'
+
+. ./test-lib.sh
+
+configure_help () {
+ test_config help.format html &&
+
+ # Unless the path has "://" in it, Git tries to make sure
+ # the documentation directory locally exists. Avoid it as
+ # we are only interested in seeing an attempt to correctly
+ # invoke a help browser in this test.
+ test_config help.htmlpath test://html &&
+
+ # Name a custom browser
+ test_config browser.test.cmd ./test-browser &&
+ test_config help.browser test
+}
+
+test_expect_success "setup" '
+ # Just write out which page gets requested
+ write_script test-browser <<-\EOF
+ echo "$*" >test-browser.log
+ EOF
+'
+
+test_expect_success "works for commands and guides by default" '
+ configure_help &&
+ git help status &&
+ echo "test://html/git-status.html" >expect &&
+ test_cmp expect test-browser.log &&
+ git help revisions &&
+ echo "test://html/gitrevisions.html" >expect &&
+ test_cmp expect test-browser.log
+'
+
+test_expect_success "--exclude-guides does not work for guides" '
+ >test-browser.log &&
+ test_must_fail git help --exclude-guides revisions &&
+ test_must_be_empty test-browser.log
+'
+
+test_expect_success "--help does not work for guides" "
+ cat <<-EOF >expect &&
+ git: 'revisions' is not a git command. See 'git --help'.
+ EOF
+ test_must_fail git revisions --help 2>actual &&
+ test_i18ncmp expect actual
+"
+
+test_done
'
reset_to_sane
-test_expect_success 'symbolic-ref deletes HEAD' '
- git symbolic-ref -d HEAD &&
+test_expect_success 'HEAD cannot be removed' '
+ test_must_fail git symbolic-ref -d HEAD
+'
+
+reset_to_sane
+
+test_expect_success 'symbolic-ref can be deleted' '
+ git symbolic-ref NOTHEAD refs/heads/foo &&
+ git symbolic-ref -d NOTHEAD &&
test_path_is_file .git/refs/heads/foo &&
- test_path_is_missing .git/HEAD
+ test_path_is_missing .git/NOTHEAD
'
reset_to_sane
-test_expect_success 'symbolic-ref deletes dangling HEAD' '
- git symbolic-ref HEAD refs/heads/missing &&
- git symbolic-ref -d HEAD &&
+test_expect_success 'symbolic-ref can delete dangling symref' '
+ git symbolic-ref NOTHEAD refs/heads/missing &&
+ git symbolic-ref -d NOTHEAD &&
test_path_is_missing .git/refs/heads/missing &&
- test_path_is_missing .git/HEAD
+ test_path_is_missing .git/NOTHEAD
'
reset_to_sane
diff --no-index --name-status -- dir2 dir
diff --no-index dir dir3
diff master master^ side
+# Can't use spaces...
+diff --line-prefix=abc master master^ side
diff --dirstat master~1 master~2
diff --dirstat initial rearrange
diff --dirstat-by-file initial rearrange
git diff --cached -- file0 >result &&
test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--cached_--_file0" result
'
+test_expect_success 'diff --line-prefix with spaces' '
+ git diff --line-prefix="| | | " --cached -- file0 >result &&
+ test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--line-prefix_--cached_--_file0" result
+'
test_expect_success 'diff-tree --stdin with log formatting' '
cat >expect <<-\EOF &&
--- /dev/null
+$ git diff --line-prefix=abc master master^ side
+abcdiff --cc dir/sub
+abcindex cead32e,7289e35..992913c
+abc--- a/dir/sub
+abc+++ b/dir/sub
+abc@@@ -1,6 -1,4 +1,8 @@@
+abc A
+abc B
+abc +C
+abc +D
+abc +E
+abc +F
+abc+ 1
+abc+ 2
+abcdiff --cc file0
+abcindex b414108,f4615da..10a8a9f
+abc--- a/file0
+abc+++ b/file0
+abc@@@ -1,6 -1,6 +1,9 @@@
+abc 1
+abc 2
+abc 3
+abc +4
+abc +5
+abc +6
+abc+ A
+abc+ B
+abc+ C
+$
--- /dev/null
+| | | diff --git a/file0 b/file0
+| | | new file mode 100644
+| | | index 0000000..10a8a9f
+| | | --- /dev/null
+| | | +++ b/file0
+| | | @@ -0,0 +1,9 @@
+| | | +1
+| | | +2
+| | | +3
+| | | +4
+| | | +5
+| | | +6
+| | | +A
+| | | +B
+| | | +C
test_num_no_numbered $1 2
}
+test_single_cover_letter_numbered() {
+ grep "^Subject: \[PATCH 0/1\]" $1 &&
+ grep "^Subject: \[PATCH 1/1\]" $1
+}
+
test_single_numbered() {
grep "^Subject: \[PATCH 1/1\]" $1
}
grep "^Subject: \[PATCH 3/3\]" patch8
'
+test_expect_success 'single patch with cover-letter defaults to numbers' '
+ git format-patch --cover-letter --stdout HEAD~1 >patch9.single &&
+ test_single_cover_letter_numbered patch9.single
+'
+
+test_expect_success 'Use --no-numbered and --cover-letter single patch' '
+ git format-patch --no-numbered --stdout --cover-letter HEAD~1 >patch10 &&
+ test_no_numbered patch10
+'
+
+
+
test_done
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2016 Jacob Keller, based on t4041 by Jens Lehmann
+#
+
+test_description='Test for submodule diff on non-checked out submodule
+
+This test tries to verify that add_submodule_odb works when the submodule was
+initialized previously but the checkout has since been removed.
+'
+
+. ./test-lib.sh
+
+# Tested non-UTF-8 encoding
+test_encoding="ISO8859-1"
+
+# String "added" in German (translated with Google Translate), encoded in UTF-8,
+# used in sample commit log messages in add_file() function below.
+added=$(printf "hinzugef\303\274gt")
+
+add_file () {
+ (
+ cd "$1" &&
+ shift &&
+ for name
+ do
+ echo "$name" >"$name" &&
+ git add "$name" &&
+ test_tick &&
+ # "git commit -m" would break MinGW, as Windows refuse to pass
+ # $test_encoding encoded parameter to git.
+ echo "Add $name ($added $name)" | iconv -f utf-8 -t $test_encoding |
+ git -c "i18n.commitEncoding=$test_encoding" commit -F -
+ done >/dev/null &&
+ git rev-parse --short --verify HEAD
+ )
+}
+
+commit_file () {
+ test_tick &&
+ git commit "$@" -m "Commit $*" >/dev/null
+}
+
+test_expect_success 'setup - submodules' '
+ test_create_repo sm2 &&
+ add_file . foo &&
+ add_file sm2 foo1 foo2 &&
+ smhead1=$(git -C sm2 rev-parse --short --verify HEAD)
+'
+
+test_expect_success 'setup - git submodule add' '
+ git submodule add ./sm2 sm1 &&
+ commit_file sm1 .gitmodules &&
+ git diff-tree -p --no-commit-id --submodule=log HEAD -- sm1 >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 0000000...$smhead1 (new submodule)
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'submodule directory removed' '
+ rm -rf sm1 &&
+ git diff-tree -p --no-commit-id --submodule=log HEAD -- sm1 >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 0000000...$smhead1 (new submodule)
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'setup - submodule multiple commits' '
+ git submodule update --checkout sm1 &&
+ smhead2=$(add_file sm1 foo3 foo4) &&
+ commit_file sm1 &&
+ git diff-tree -p --no-commit-id --submodule=log HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $smhead1..$smhead2:
+ > Add foo4 ($added foo4)
+ > Add foo3 ($added foo3)
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'submodule removed multiple commits' '
+ rm -rf sm1 &&
+ git diff-tree -p --no-commit-id --submodule=log HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $smhead1..$smhead2:
+ > Add foo4 ($added foo4)
+ > Add foo3 ($added foo3)
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'submodule not initialized in new clone' '
+ git clone . sm3 &&
+ git -C sm3 diff-tree -p --no-commit-id --submodule=log HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $smhead1...$smhead2 (not initialized)
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'setup submodule moved' '
+ git submodule update --checkout sm1 &&
+ git mv sm1 sm4 &&
+ commit_file sm4 &&
+ git diff-tree -p --no-commit-id --submodule=log HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm4 0000000...$smhead2 (new submodule)
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'submodule moved then removed' '
+ smhead3=$(add_file sm4 foo6 foo7) &&
+ commit_file sm4 &&
+ rm -rf sm4 &&
+ git diff-tree -p --no-commit-id --submodule=log HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm4 $smhead2..$smhead3:
+ > Add foo7 ($added foo7)
+ > Add foo6 ($added foo6)
+ EOF
+ test_cmp expected actual
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2009 Jens Lehmann, based on t7401 by Ping Yin
+# Copyright (c) 2011 Alexey Shumkin (+ non-UTF-8 commit encoding tests)
+# Copyright (c) 2016 Jacob Keller (copy + convert to --submodule=diff)
+#
+
+test_description='Support for diff format verbose submodule difference in git diff
+
+This test tries to verify the sanity of --submodule=diff option of git diff.
+'
+
+. ./test-lib.sh
+
+# Tested non-UTF-8 encoding
+test_encoding="ISO8859-1"
+
+# String "added" in German (translated with Google Translate), encoded in UTF-8,
+# used in sample commit log messages in add_file() function below.
+added=$(printf "hinzugef\303\274gt")
+
+add_file () {
+ (
+ cd "$1" &&
+ shift &&
+ for name
+ do
+ echo "$name" >"$name" &&
+ git add "$name" &&
+ test_tick &&
+ # "git commit -m" would break MinGW, as Windows refuse to pass
+ # $test_encoding encoded parameter to git.
+ echo "Add $name ($added $name)" | iconv -f utf-8 -t $test_encoding |
+ git -c "i18n.commitEncoding=$test_encoding" commit -F -
+ done >/dev/null &&
+ git rev-parse --short --verify HEAD
+ )
+}
+
+commit_file () {
+ test_tick &&
+ git commit "$@" -m "Commit $*" >/dev/null
+}
+
+test_expect_success 'setup repository' '
+ test_create_repo sm1 &&
+ add_file . foo &&
+ head1=$(add_file sm1 foo1 foo2) &&
+ fullhead1=$(git -C sm1 rev-parse --verify HEAD)
+'
+
+test_expect_success 'added submodule' '
+ git add sm1 &&
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 0000000...$head1 (new submodule)
+ diff --git a/sm1/foo1 b/sm1/foo1
+ new file mode 100644
+ index 0000000..1715acd
+ --- /dev/null
+ +++ b/sm1/foo1
+ @@ -0,0 +1 @@
+ +foo1
+ diff --git a/sm1/foo2 b/sm1/foo2
+ new file mode 100644
+ index 0000000..54b060e
+ --- /dev/null
+ +++ b/sm1/foo2
+ @@ -0,0 +1 @@
+ +foo2
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'added submodule, set diff.submodule' '
+ test_config diff.submodule log &&
+ git add sm1 &&
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 0000000...$head1 (new submodule)
+ diff --git a/sm1/foo1 b/sm1/foo1
+ new file mode 100644
+ index 0000000..1715acd
+ --- /dev/null
+ +++ b/sm1/foo1
+ @@ -0,0 +1 @@
+ +foo1
+ diff --git a/sm1/foo2 b/sm1/foo2
+ new file mode 100644
+ index 0000000..54b060e
+ --- /dev/null
+ +++ b/sm1/foo2
+ @@ -0,0 +1 @@
+ +foo2
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success '--submodule=short overrides diff.submodule' '
+ test_config diff.submodule log &&
+ git add sm1 &&
+ git diff --submodule=short --cached >actual &&
+ cat >expected <<-EOF &&
+ diff --git a/sm1 b/sm1
+ new file mode 160000
+ index 0000000..$head1
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +Subproject commit $fullhead1
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'diff.submodule does not affect plumbing' '
+ test_config diff.submodule log &&
+ git diff-index -p HEAD >actual &&
+ cat >expected <<-EOF &&
+ diff --git a/sm1 b/sm1
+ new file mode 160000
+ index 0000000..$head1
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +Subproject commit $fullhead1
+ EOF
+ test_cmp expected actual
+'
+
+commit_file sm1 &&
+head2=$(add_file sm1 foo3)
+
+test_expect_success 'modified submodule(forward)' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $head1..$head2:
+ diff --git a/sm1/foo3 b/sm1/foo3
+ new file mode 100644
+ index 0000000..c1ec6c6
+ --- /dev/null
+ +++ b/sm1/foo3
+ @@ -0,0 +1 @@
+ +foo3
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'modified submodule(forward)' '
+ git diff --submodule=diff >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $head1..$head2:
+ diff --git a/sm1/foo3 b/sm1/foo3
+ new file mode 100644
+ index 0000000..c1ec6c6
+ --- /dev/null
+ +++ b/sm1/foo3
+ @@ -0,0 +1 @@
+ +foo3
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'modified submodule(forward) --submodule' '
+ git diff --submodule >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $head1..$head2:
+ > Add foo3 ($added foo3)
+ EOF
+ test_cmp expected actual
+'
+
+fullhead2=$(cd sm1; git rev-parse --verify HEAD)
+test_expect_success 'modified submodule(forward) --submodule=short' '
+ git diff --submodule=short >actual &&
+ cat >expected <<-EOF &&
+ diff --git a/sm1 b/sm1
+ index $head1..$head2 160000
+ --- a/sm1
+ +++ b/sm1
+ @@ -1 +1 @@
+ -Subproject commit $fullhead1
+ +Subproject commit $fullhead2
+ EOF
+ test_cmp expected actual
+'
+
+commit_file sm1 &&
+head3=$(
+ cd sm1 &&
+ git reset --hard HEAD~2 >/dev/null &&
+ git rev-parse --short --verify HEAD
+)
+
+test_expect_success 'modified submodule(backward)' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $head2..$head3 (rewind):
+ diff --git a/sm1/foo2 b/sm1/foo2
+ deleted file mode 100644
+ index 54b060e..0000000
+ --- a/sm1/foo2
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo2
+ diff --git a/sm1/foo3 b/sm1/foo3
+ deleted file mode 100644
+ index c1ec6c6..0000000
+ --- a/sm1/foo3
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo3
+ EOF
+ test_cmp expected actual
+'
+
+head4=$(add_file sm1 foo4 foo5)
+test_expect_success 'modified submodule(backward and forward)' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $head2...$head4:
+ diff --git a/sm1/foo2 b/sm1/foo2
+ deleted file mode 100644
+ index 54b060e..0000000
+ --- a/sm1/foo2
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo2
+ diff --git a/sm1/foo3 b/sm1/foo3
+ deleted file mode 100644
+ index c1ec6c6..0000000
+ --- a/sm1/foo3
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo3
+ diff --git a/sm1/foo4 b/sm1/foo4
+ new file mode 100644
+ index 0000000..a0016db
+ --- /dev/null
+ +++ b/sm1/foo4
+ @@ -0,0 +1 @@
+ +foo4
+ diff --git a/sm1/foo5 b/sm1/foo5
+ new file mode 100644
+ index 0000000..d6f2413
+ --- /dev/null
+ +++ b/sm1/foo5
+ @@ -0,0 +1 @@
+ +foo5
+ EOF
+ test_cmp expected actual
+'
+
+commit_file sm1 &&
+mv sm1 sm1-bak &&
+echo sm1 >sm1 &&
+head5=$(git hash-object sm1 | cut -c1-7) &&
+git add sm1 &&
+rm -f sm1 &&
+mv sm1-bak sm1
+
+test_expect_success 'typechanged submodule(submodule->blob), --cached' '
+ git diff --submodule=diff --cached >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $head4...0000000 (submodule deleted)
+ diff --git a/sm1/foo1 b/sm1/foo1
+ deleted file mode 100644
+ index 1715acd..0000000
+ --- a/sm1/foo1
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo1
+ diff --git a/sm1/foo4 b/sm1/foo4
+ deleted file mode 100644
+ index a0016db..0000000
+ --- a/sm1/foo4
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo4
+ diff --git a/sm1/foo5 b/sm1/foo5
+ deleted file mode 100644
+ index d6f2413..0000000
+ --- a/sm1/foo5
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo5
+ diff --git a/sm1 b/sm1
+ new file mode 100644
+ index 0000000..9da5fb8
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +sm1
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'typechanged submodule(submodule->blob)' '
+ git diff --submodule=diff >actual &&
+ cat >expected <<-EOF &&
+ diff --git a/sm1 b/sm1
+ deleted file mode 100644
+ index 9da5fb8..0000000
+ --- a/sm1
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -sm1
+ Submodule sm1 0000000...$head4 (new submodule)
+ diff --git a/sm1/foo1 b/sm1/foo1
+ new file mode 100644
+ index 0000000..1715acd
+ --- /dev/null
+ +++ b/sm1/foo1
+ @@ -0,0 +1 @@
+ +foo1
+ diff --git a/sm1/foo4 b/sm1/foo4
+ new file mode 100644
+ index 0000000..a0016db
+ --- /dev/null
+ +++ b/sm1/foo4
+ @@ -0,0 +1 @@
+ +foo4
+ diff --git a/sm1/foo5 b/sm1/foo5
+ new file mode 100644
+ index 0000000..d6f2413
+ --- /dev/null
+ +++ b/sm1/foo5
+ @@ -0,0 +1 @@
+ +foo5
+ EOF
+ test_cmp expected actual
+'
+
+rm -rf sm1 &&
+git checkout-index sm1
+test_expect_success 'typechanged submodule(submodule->blob)' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $head4...0000000 (submodule deleted)
+ diff --git a/sm1 b/sm1
+ new file mode 100644
+ index 0000000..9da5fb8
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +sm1
+ EOF
+ test_cmp expected actual
+'
+
+rm -f sm1 &&
+test_create_repo sm1 &&
+head6=$(add_file sm1 foo6 foo7)
+fullhead6=$(cd sm1; git rev-parse --verify HEAD)
+test_expect_success 'nonexistent commit' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $head4...$head6 (commits not present)
+ EOF
+ test_cmp expected actual
+'
+
+commit_file
+test_expect_success 'typechanged submodule(blob->submodule)' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ diff --git a/sm1 b/sm1
+ deleted file mode 100644
+ index 9da5fb8..0000000
+ --- a/sm1
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -sm1
+ Submodule sm1 0000000...$head6 (new submodule)
+ diff --git a/sm1/foo6 b/sm1/foo6
+ new file mode 100644
+ index 0000000..462398b
+ --- /dev/null
+ +++ b/sm1/foo6
+ @@ -0,0 +1 @@
+ +foo6
+ diff --git a/sm1/foo7 b/sm1/foo7
+ new file mode 100644
+ index 0000000..6e9262c
+ --- /dev/null
+ +++ b/sm1/foo7
+ @@ -0,0 +1 @@
+ +foo7
+ EOF
+ test_cmp expected actual
+'
+
+commit_file sm1 &&
+test_expect_success 'submodule is up to date' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'submodule contains untracked content' '
+ echo new > sm1/new-file &&
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 contains untracked content
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'submodule contains untracked content (untracked ignored)' '
+ git diff-index -p --ignore-submodules=untracked --submodule=diff HEAD >actual &&
+ ! test -s actual
+'
+
+test_expect_success 'submodule contains untracked content (dirty ignored)' '
+ git diff-index -p --ignore-submodules=dirty --submodule=diff HEAD >actual &&
+ ! test -s actual
+'
+
+test_expect_success 'submodule contains untracked content (all ignored)' '
+ git diff-index -p --ignore-submodules=all --submodule=diff HEAD >actual &&
+ ! test -s actual
+'
+
+test_expect_success 'submodule contains untracked and modified content' '
+ echo new > sm1/foo6 &&
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 contains untracked content
+ Submodule sm1 contains modified content
+ diff --git a/sm1/foo6 b/sm1/foo6
+ index 462398b..3e75765 100644
+ --- a/sm1/foo6
+ +++ b/sm1/foo6
+ @@ -1 +1 @@
+ -foo6
+ +new
+ EOF
+ test_cmp expected actual
+'
+
+# NOT OK
+test_expect_success 'submodule contains untracked and modified content (untracked ignored)' '
+ echo new > sm1/foo6 &&
+ git diff-index -p --ignore-submodules=untracked --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 contains modified content
+ diff --git a/sm1/foo6 b/sm1/foo6
+ index 462398b..3e75765 100644
+ --- a/sm1/foo6
+ +++ b/sm1/foo6
+ @@ -1 +1 @@
+ -foo6
+ +new
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'submodule contains untracked and modified content (dirty ignored)' '
+ echo new > sm1/foo6 &&
+ git diff-index -p --ignore-submodules=dirty --submodule=diff HEAD >actual &&
+ ! test -s actual
+'
+
+test_expect_success 'submodule contains untracked and modified content (all ignored)' '
+ echo new > sm1/foo6 &&
+ git diff-index -p --ignore-submodules --submodule=diff HEAD >actual &&
+ ! test -s actual
+'
+
+test_expect_success 'submodule contains modified content' '
+ rm -f sm1/new-file &&
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 contains modified content
+ diff --git a/sm1/foo6 b/sm1/foo6
+ index 462398b..3e75765 100644
+ --- a/sm1/foo6
+ +++ b/sm1/foo6
+ @@ -1 +1 @@
+ -foo6
+ +new
+ EOF
+ test_cmp expected actual
+'
+
+(cd sm1; git commit -mchange foo6 >/dev/null) &&
+head8=$(cd sm1; git rev-parse --short --verify HEAD) &&
+test_expect_success 'submodule is modified' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 17243c9..$head8:
+ diff --git a/sm1/foo6 b/sm1/foo6
+ index 462398b..3e75765 100644
+ --- a/sm1/foo6
+ +++ b/sm1/foo6
+ @@ -1 +1 @@
+ -foo6
+ +new
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'modified submodule contains untracked content' '
+ echo new > sm1/new-file &&
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 contains untracked content
+ Submodule sm1 17243c9..$head8:
+ diff --git a/sm1/foo6 b/sm1/foo6
+ index 462398b..3e75765 100644
+ --- a/sm1/foo6
+ +++ b/sm1/foo6
+ @@ -1 +1 @@
+ -foo6
+ +new
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'modified submodule contains untracked content (untracked ignored)' '
+ git diff-index -p --ignore-submodules=untracked --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 17243c9..$head8:
+ diff --git a/sm1/foo6 b/sm1/foo6
+ index 462398b..3e75765 100644
+ --- a/sm1/foo6
+ +++ b/sm1/foo6
+ @@ -1 +1 @@
+ -foo6
+ +new
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'modified submodule contains untracked content (dirty ignored)' '
+ git diff-index -p --ignore-submodules=dirty --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 17243c9..cfce562:
+ diff --git a/sm1/foo6 b/sm1/foo6
+ index 462398b..3e75765 100644
+ --- a/sm1/foo6
+ +++ b/sm1/foo6
+ @@ -1 +1 @@
+ -foo6
+ +new
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'modified submodule contains untracked content (all ignored)' '
+ git diff-index -p --ignore-submodules=all --submodule=diff HEAD >actual &&
+ ! test -s actual
+'
+
+test_expect_success 'modified submodule contains untracked and modified content' '
+ echo modification >> sm1/foo6 &&
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 contains untracked content
+ Submodule sm1 contains modified content
+ Submodule sm1 17243c9..cfce562:
+ diff --git a/sm1/foo6 b/sm1/foo6
+ index 462398b..dfda541 100644
+ --- a/sm1/foo6
+ +++ b/sm1/foo6
+ @@ -1 +1,2 @@
+ -foo6
+ +new
+ +modification
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'modified submodule contains untracked and modified content (untracked ignored)' '
+ echo modification >> sm1/foo6 &&
+ git diff-index -p --ignore-submodules=untracked --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 contains modified content
+ Submodule sm1 17243c9..cfce562:
+ diff --git a/sm1/foo6 b/sm1/foo6
+ index 462398b..e20e2d9 100644
+ --- a/sm1/foo6
+ +++ b/sm1/foo6
+ @@ -1 +1,3 @@
+ -foo6
+ +new
+ +modification
+ +modification
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'modified submodule contains untracked and modified content (dirty ignored)' '
+ echo modification >> sm1/foo6 &&
+ git diff-index -p --ignore-submodules=dirty --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 17243c9..cfce562:
+ diff --git a/sm1/foo6 b/sm1/foo6
+ index 462398b..3e75765 100644
+ --- a/sm1/foo6
+ +++ b/sm1/foo6
+ @@ -1 +1 @@
+ -foo6
+ +new
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'modified submodule contains untracked and modified content (all ignored)' '
+ echo modification >> sm1/foo6 &&
+ git diff-index -p --ignore-submodules --submodule=diff HEAD >actual &&
+ ! test -s actual
+'
+
+# NOT OK
+test_expect_success 'modified submodule contains modified content' '
+ rm -f sm1/new-file &&
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 contains modified content
+ Submodule sm1 17243c9..cfce562:
+ diff --git a/sm1/foo6 b/sm1/foo6
+ index 462398b..ac466ca 100644
+ --- a/sm1/foo6
+ +++ b/sm1/foo6
+ @@ -1 +1,5 @@
+ -foo6
+ +new
+ +modification
+ +modification
+ +modification
+ +modification
+ EOF
+ test_cmp expected actual
+'
+
+rm -rf sm1
+test_expect_success 'deleted submodule' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 17243c9...0000000 (submodule deleted)
+ EOF
+ test_cmp expected actual
+'
+
+test_create_repo sm2 &&
+head7=$(add_file sm2 foo8 foo9) &&
+git add sm2
+
+test_expect_success 'multiple submodules' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 17243c9...0000000 (submodule deleted)
+ Submodule sm2 0000000...a5a65c9 (new submodule)
+ diff --git a/sm2/foo8 b/sm2/foo8
+ new file mode 100644
+ index 0000000..db9916b
+ --- /dev/null
+ +++ b/sm2/foo8
+ @@ -0,0 +1 @@
+ +foo8
+ diff --git a/sm2/foo9 b/sm2/foo9
+ new file mode 100644
+ index 0000000..9c3b4f6
+ --- /dev/null
+ +++ b/sm2/foo9
+ @@ -0,0 +1 @@
+ +foo9
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'path filter' '
+ git diff-index -p --submodule=diff HEAD sm2 >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm2 0000000...a5a65c9 (new submodule)
+ diff --git a/sm2/foo8 b/sm2/foo8
+ new file mode 100644
+ index 0000000..db9916b
+ --- /dev/null
+ +++ b/sm2/foo8
+ @@ -0,0 +1 @@
+ +foo8
+ diff --git a/sm2/foo9 b/sm2/foo9
+ new file mode 100644
+ index 0000000..9c3b4f6
+ --- /dev/null
+ +++ b/sm2/foo9
+ @@ -0,0 +1 @@
+ +foo9
+ EOF
+ test_cmp expected actual
+'
+
+commit_file sm2
+test_expect_success 'given commit' '
+ git diff-index -p --submodule=diff HEAD^ >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 17243c9...0000000 (submodule deleted)
+ Submodule sm2 0000000...a5a65c9 (new submodule)
+ diff --git a/sm2/foo8 b/sm2/foo8
+ new file mode 100644
+ index 0000000..db9916b
+ --- /dev/null
+ +++ b/sm2/foo8
+ @@ -0,0 +1 @@
+ +foo8
+ diff --git a/sm2/foo9 b/sm2/foo9
+ new file mode 100644
+ index 0000000..9c3b4f6
+ --- /dev/null
+ +++ b/sm2/foo9
+ @@ -0,0 +1 @@
+ +foo9
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'setup .git file for sm2' '
+ (cd sm2 &&
+ REAL="$(pwd)/../.real" &&
+ mv .git "$REAL"
+ echo "gitdir: $REAL" >.git)
+'
+
+test_expect_success 'diff --submodule=diff with .git file' '
+ git diff --submodule=diff HEAD^ >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 17243c9...0000000 (submodule deleted)
+ Submodule sm2 0000000...a5a65c9 (new submodule)
+ diff --git a/sm2/foo8 b/sm2/foo8
+ new file mode 100644
+ index 0000000..db9916b
+ --- /dev/null
+ +++ b/sm2/foo8
+ @@ -0,0 +1 @@
+ +foo8
+ diff --git a/sm2/foo9 b/sm2/foo9
+ new file mode 100644
+ index 0000000..9c3b4f6
+ --- /dev/null
+ +++ b/sm2/foo9
+ @@ -0,0 +1 @@
+ +foo9
+ EOF
+ test_cmp expected actual
+'
+
+test_done
test_cmp expect actual
'
+cat > expect << EOF
+=== 804a787 sixth
+=== 394ef78 fifth
+=== 5d31159 fourth
+EOF
+test_expect_success 'git log --line-prefix="=== " --no-walk <commits> sorts by commit time' '
+ git log --line-prefix="=== " --no-walk --oneline 5d31159 804a787 394ef78 > actual &&
+ test_cmp expect actual
+'
+
cat > expect << EOF
5d31159 fourth
804a787 sixth
test_cmp expect actual
'
+cat > expect <<EOF
+123 * Second
+123 * sixth
+123 * fifth
+123 * fourth
+123 * third
+123 * second
+123 * initial
+EOF
+
+test_expect_success 'simple log --graph --line-prefix="123 "' '
+ git log --graph --line-prefix="123 " --pretty=tformat:%s >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'set up merge history' '
git checkout -b side HEAD~4 &&
test_commit side-1 1 1 &&
test_cmp expect actual
'
+cat > expect <<\EOF
+| | | * Merge branch 'side'
+| | | |\
+| | | | * side-2
+| | | | * side-1
+| | | * | Second
+| | | * | sixth
+| | | * | fifth
+| | | * | fourth
+| | | |/
+| | | * third
+| | | * second
+| | | * initial
+EOF
+
+test_expect_success 'log --graph --line-prefix="| | | " with merge' '
+ git log --line-prefix="| | | " --graph --date-order --pretty=tformat:%s |
+ sed "s/ *\$//" >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'log --raw --graph -m with merge' '
git log --raw --graph --oneline -m master | head -n 500 >actual &&
grep "initial" actual
test_i18ncmp expect actual.sanitized
'
+cat >expect <<\EOF
+*** * commit COMMIT_OBJECT_NAME
+*** |\ Merge: MERGE_PARENTS
+*** | | Author: A U Thor <author@example.com>
+*** | |
+*** | | Merge HEADS DESCRIPTION
+*** | |
+*** | * commit COMMIT_OBJECT_NAME
+*** | | Author: A U Thor <author@example.com>
+*** | |
+*** | | reach
+*** | | ---
+*** | | reach.t | 1 +
+*** | | 1 file changed, 1 insertion(+)
+*** | |
+*** | | diff --git a/reach.t b/reach.t
+*** | | new file mode 100644
+*** | | index 0000000..10c9591
+*** | | --- /dev/null
+*** | | +++ b/reach.t
+*** | | @@ -0,0 +1 @@
+*** | | +reach
+*** | |
+*** | \
+*** *-. \ commit COMMIT_OBJECT_NAME
+*** |\ \ \ Merge: MERGE_PARENTS
+*** | | | | Author: A U Thor <author@example.com>
+*** | | | |
+*** | | | | Merge HEADS DESCRIPTION
+*** | | | |
+*** | | * | commit COMMIT_OBJECT_NAME
+*** | | |/ Author: A U Thor <author@example.com>
+*** | | |
+*** | | | octopus-b
+*** | | | ---
+*** | | | octopus-b.t | 1 +
+*** | | | 1 file changed, 1 insertion(+)
+*** | | |
+*** | | | diff --git a/octopus-b.t b/octopus-b.t
+*** | | | new file mode 100644
+*** | | | index 0000000..d5fcad0
+*** | | | --- /dev/null
+*** | | | +++ b/octopus-b.t
+*** | | | @@ -0,0 +1 @@
+*** | | | +octopus-b
+*** | | |
+*** | * | commit COMMIT_OBJECT_NAME
+*** | |/ Author: A U Thor <author@example.com>
+*** | |
+*** | | octopus-a
+*** | | ---
+*** | | octopus-a.t | 1 +
+*** | | 1 file changed, 1 insertion(+)
+*** | |
+*** | | diff --git a/octopus-a.t b/octopus-a.t
+*** | | new file mode 100644
+*** | | index 0000000..11ee015
+*** | | --- /dev/null
+*** | | +++ b/octopus-a.t
+*** | | @@ -0,0 +1 @@
+*** | | +octopus-a
+*** | |
+*** * | commit COMMIT_OBJECT_NAME
+*** |/ Author: A U Thor <author@example.com>
+*** |
+*** | seventh
+*** | ---
+*** | seventh.t | 1 +
+*** | 1 file changed, 1 insertion(+)
+*** |
+*** | diff --git a/seventh.t b/seventh.t
+*** | new file mode 100644
+*** | index 0000000..9744ffc
+*** | --- /dev/null
+*** | +++ b/seventh.t
+*** | @@ -0,0 +1 @@
+*** | +seventh
+*** |
+*** * commit COMMIT_OBJECT_NAME
+*** |\ Merge: MERGE_PARENTS
+*** | | Author: A U Thor <author@example.com>
+*** | |
+*** | | Merge branch 'tangle'
+*** | |
+*** | * commit COMMIT_OBJECT_NAME
+*** | |\ Merge: MERGE_PARENTS
+*** | | | Author: A U Thor <author@example.com>
+*** | | |
+*** | | | Merge branch 'side' (early part) into tangle
+*** | | |
+*** | * | commit COMMIT_OBJECT_NAME
+*** | |\ \ Merge: MERGE_PARENTS
+*** | | | | Author: A U Thor <author@example.com>
+*** | | | |
+*** | | | | Merge branch 'master' (early part) into tangle
+*** | | | |
+*** | * | | commit COMMIT_OBJECT_NAME
+*** | | | | Author: A U Thor <author@example.com>
+*** | | | |
+*** | | | | tangle-a
+*** | | | | ---
+*** | | | | tangle-a | 1 +
+*** | | | | 1 file changed, 1 insertion(+)
+*** | | | |
+*** | | | | diff --git a/tangle-a b/tangle-a
+*** | | | | new file mode 100644
+*** | | | | index 0000000..7898192
+*** | | | | --- /dev/null
+*** | | | | +++ b/tangle-a
+*** | | | | @@ -0,0 +1 @@
+*** | | | | +a
+*** | | | |
+*** * | | | commit COMMIT_OBJECT_NAME
+*** |\ \ \ \ Merge: MERGE_PARENTS
+*** | | | | | Author: A U Thor <author@example.com>
+*** | | | | |
+*** | | | | | Merge branch 'side'
+*** | | | | |
+*** | * | | | commit COMMIT_OBJECT_NAME
+*** | | |_|/ Author: A U Thor <author@example.com>
+*** | |/| |
+*** | | | | side-2
+*** | | | | ---
+*** | | | | 2 | 1 +
+*** | | | | 1 file changed, 1 insertion(+)
+*** | | | |
+*** | | | | diff --git a/2 b/2
+*** | | | | new file mode 100644
+*** | | | | index 0000000..0cfbf08
+*** | | | | --- /dev/null
+*** | | | | +++ b/2
+*** | | | | @@ -0,0 +1 @@
+*** | | | | +2
+*** | | | |
+*** | * | | commit COMMIT_OBJECT_NAME
+*** | | | | Author: A U Thor <author@example.com>
+*** | | | |
+*** | | | | side-1
+*** | | | | ---
+*** | | | | 1 | 1 +
+*** | | | | 1 file changed, 1 insertion(+)
+*** | | | |
+*** | | | | diff --git a/1 b/1
+*** | | | | new file mode 100644
+*** | | | | index 0000000..d00491f
+*** | | | | --- /dev/null
+*** | | | | +++ b/1
+*** | | | | @@ -0,0 +1 @@
+*** | | | | +1
+*** | | | |
+*** * | | | commit COMMIT_OBJECT_NAME
+*** | | | | Author: A U Thor <author@example.com>
+*** | | | |
+*** | | | | Second
+*** | | | | ---
+*** | | | | one | 1 +
+*** | | | | 1 file changed, 1 insertion(+)
+*** | | | |
+*** | | | | diff --git a/one b/one
+*** | | | | new file mode 100644
+*** | | | | index 0000000..9a33383
+*** | | | | --- /dev/null
+*** | | | | +++ b/one
+*** | | | | @@ -0,0 +1 @@
+*** | | | | +case
+*** | | | |
+*** * | | | commit COMMIT_OBJECT_NAME
+*** | |_|/ Author: A U Thor <author@example.com>
+*** |/| |
+*** | | | sixth
+*** | | | ---
+*** | | | a/two | 1 -
+*** | | | 1 file changed, 1 deletion(-)
+*** | | |
+*** | | | diff --git a/a/two b/a/two
+*** | | | deleted file mode 100644
+*** | | | index 9245af5..0000000
+*** | | | --- a/a/two
+*** | | | +++ /dev/null
+*** | | | @@ -1 +0,0 @@
+*** | | | -ni
+*** | | |
+*** * | | commit COMMIT_OBJECT_NAME
+*** | | | Author: A U Thor <author@example.com>
+*** | | |
+*** | | | fifth
+*** | | | ---
+*** | | | a/two | 1 +
+*** | | | 1 file changed, 1 insertion(+)
+*** | | |
+*** | | | diff --git a/a/two b/a/two
+*** | | | new file mode 100644
+*** | | | index 0000000..9245af5
+*** | | | --- /dev/null
+*** | | | +++ b/a/two
+*** | | | @@ -0,0 +1 @@
+*** | | | +ni
+*** | | |
+*** * | | commit COMMIT_OBJECT_NAME
+*** |/ / Author: A U Thor <author@example.com>
+*** | |
+*** | | fourth
+*** | | ---
+*** | | ein | 1 +
+*** | | 1 file changed, 1 insertion(+)
+*** | |
+*** | | diff --git a/ein b/ein
+*** | | new file mode 100644
+*** | | index 0000000..9d7e69f
+*** | | --- /dev/null
+*** | | +++ b/ein
+*** | | @@ -0,0 +1 @@
+*** | | +ichi
+*** | |
+*** * | commit COMMIT_OBJECT_NAME
+*** |/ Author: A U Thor <author@example.com>
+*** |
+*** | third
+*** | ---
+*** | ichi | 1 +
+*** | one | 1 -
+*** | 2 files changed, 1 insertion(+), 1 deletion(-)
+*** |
+*** | diff --git a/ichi b/ichi
+*** | new file mode 100644
+*** | index 0000000..9d7e69f
+*** | --- /dev/null
+*** | +++ b/ichi
+*** | @@ -0,0 +1 @@
+*** | +ichi
+*** | diff --git a/one b/one
+*** | deleted file mode 100644
+*** | index 9d7e69f..0000000
+*** | --- a/one
+*** | +++ /dev/null
+*** | @@ -1 +0,0 @@
+*** | -ichi
+*** |
+*** * commit COMMIT_OBJECT_NAME
+*** | Author: A U Thor <author@example.com>
+*** |
+*** | second
+*** | ---
+*** | one | 2 +-
+*** | 1 file changed, 1 insertion(+), 1 deletion(-)
+*** |
+*** | diff --git a/one b/one
+*** | index 5626abf..9d7e69f 100644
+*** | --- a/one
+*** | +++ b/one
+*** | @@ -1 +1 @@
+*** | -one
+*** | +ichi
+*** |
+*** * commit COMMIT_OBJECT_NAME
+*** Author: A U Thor <author@example.com>
+***
+*** initial
+*** ---
+*** one | 1 +
+*** 1 file changed, 1 insertion(+)
+***
+*** diff --git a/one b/one
+*** new file mode 100644
+*** index 0000000..5626abf
+*** --- /dev/null
+*** +++ b/one
+*** @@ -0,0 +1 @@
+*** +one
+EOF
+
+test_expect_success 'log --line-prefix="*** " --graph with diff and stats' '
+ git log --line-prefix="*** " --no-renames --graph --pretty=short --stat -p >actual &&
+ sanitize_output >actual.sanitized <actual &&
+ test_i18ncmp expect actual.sanitized
+'
+
test_expect_success 'dotdot is a parent directory' '
mkdir -p a/b &&
( echo sixth && echo fifth ) >expect &&
} >obj-list
'
-rm -rf clone.git
test_expect_success 'pack without --include-tag' '
- packname_1=$(git pack-objects \
+ packname=$(git pack-objects \
--window=0 \
- test-1 <obj-list)
+ test-no-include <obj-list)
'
test_expect_success 'unpack objects' '
- (
- GIT_DIR=clone.git &&
- export GIT_DIR &&
- git init &&
- git unpack-objects -n <test-1-${packname_1}.pack &&
- git unpack-objects <test-1-${packname_1}.pack
- )
+ rm -rf clone.git &&
+ git init clone.git &&
+ git -C clone.git unpack-objects <test-no-include-${packname}.pack
'
test_expect_success 'check unpacked result (have commit, no tag)' '
git rev-list --objects $commit >list.expect &&
- (
- test_must_fail env GIT_DIR=clone.git git cat-file -e $tag &&
- git rev-list --objects $commit
- ) >list.actual &&
+ test_must_fail git -C clone.git cat-file -e $tag &&
+ git -C clone.git rev-list --objects $commit >list.actual &&
test_cmp list.expect list.actual
'
-rm -rf clone.git
test_expect_success 'pack with --include-tag' '
- packname_1=$(git pack-objects \
+ packname=$(git pack-objects \
--window=0 \
--include-tag \
- test-2 <obj-list)
+ test-include <obj-list)
'
test_expect_success 'unpack objects' '
- (
- GIT_DIR=clone.git &&
- export GIT_DIR &&
- git init &&
- git unpack-objects -n <test-2-${packname_1}.pack &&
- git unpack-objects <test-2-${packname_1}.pack
- )
+ rm -rf clone.git &&
+ git init clone.git &&
+ git -C clone.git unpack-objects <test-include-${packname}.pack
'
test_expect_success 'check unpacked result (have commit, have tag)' '
git rev-list --objects mytag >list.expect &&
- (
- GIT_DIR=clone.git &&
- export GIT_DIR &&
- git rev-list --objects $tag
- ) >list.actual &&
+ git -C clone.git rev-list --objects $tag >list.actual &&
test_cmp list.expect list.actual
'
+# A tag of a tag, where the "inner" tag is not otherwise
+# reachable, and a full peel points to a commit reachable from HEAD.
+test_expect_success 'create hidden inner tag' '
+ test_commit commit &&
+ git tag -m inner inner HEAD &&
+ git tag -m outer outer inner &&
+ git tag -d inner
+'
+
+test_expect_success 'pack explicit outer tag' '
+ packname=$(
+ {
+ echo HEAD &&
+ echo outer
+ } |
+ git pack-objects --revs test-hidden-explicit
+ )
+'
+
+test_expect_success 'unpack objects' '
+ rm -rf clone.git &&
+ git init clone.git &&
+ git -C clone.git unpack-objects <test-hidden-explicit-${packname}.pack
+'
+
+test_expect_success 'check unpacked result (have all objects)' '
+ git -C clone.git rev-list --objects $(git rev-parse outer HEAD)
+'
+
+test_expect_success 'pack implied outer tag' '
+ packname=$(
+ echo HEAD |
+ git pack-objects --revs --include-tag test-hidden-implied
+ )
+'
+
+test_expect_success 'unpack objects' '
+ rm -rf clone.git &&
+ git init clone.git &&
+ git -C clone.git unpack-objects <test-hidden-implied-${packname}.pack
+'
+
+test_expect_success 'check unpacked result (have all objects)' '
+ git -C clone.git rev-list --objects $(git rev-parse outer HEAD)
+'
+
+test_expect_success 'single-branch clone can transfer tag' '
+ rm -rf clone.git &&
+ git clone --no-local --single-branch -b master . clone.git &&
+ git -C clone.git fsck
+'
+
test_done
)
'
+test_expect_success 'fetching submodule into a broken repository' '
+ # Prepare src and src/sub nested in it
+ git init src &&
+ (
+ cd src &&
+ git init sub &&
+ git -C sub commit --allow-empty -m "initial in sub" &&
+ git submodule add -- ./sub sub &&
+ git commit -m "initial in top"
+ ) &&
+
+ # Clone the old-fashoned way
+ git clone src dst &&
+ git -C dst clone ../src/sub sub &&
+
+ # Make sure that old-fashoned layout is still supported
+ git -C dst status &&
+
+ # "diff" would find no change
+ git -C dst diff --exit-code &&
+
+ # Recursive-fetch works fine
+ git -C dst fetch --recurse-submodules &&
+
+ # Break the receiving submodule
+ rm -f dst/sub/.git/HEAD &&
+
+ # NOTE: without the fix the following tests will recurse forever!
+ # They should terminate with an error.
+
+ test_must_fail git -C dst status &&
+ test_must_fail git -C dst diff &&
+ test_must_fail git -C dst fetch --recurse-submodules
+'
+
test_done
test_tick &&
git commit -m path2 &&
HEAD=$(git rev-parse --verify HEAD) &&
- GIT_CURL_VERBOSE=1 git push -v -v 2>err &&
+ GIT_TRACE_CURL=true git push -v -v 2>err &&
! grep "Expect: 100-continue" err &&
grep "POST git-receive-pack ([0-9]* bytes)" err &&
(cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
--- /dev/null
+#!/bin/sh
+
+test_description='check receive input limits'
+. ./test-lib.sh
+
+# Let's run tests with different unpack limits: 1 and 10000
+# When the limit is 1, `git receive-pack` will call `git index-pack`.
+# When the limit is 10000, `git receive-pack` will call `git unpack-objects`.
+
+test_pack_input_limit () {
+ case "$1" in
+ index) unpack_limit=1 ;;
+ unpack) unpack_limit=10000 ;;
+ esac
+
+ test_expect_success 'prepare destination repository' '
+ rm -fr dest &&
+ git --bare init dest
+ '
+
+ test_expect_success "set unpacklimit to $unpack_limit" '
+ git --git-dir=dest config receive.unpacklimit "$unpack_limit"
+ '
+
+ test_expect_success 'setting receive.maxInputSize to 512 rejects push' '
+ git --git-dir=dest config receive.maxInputSize 512 &&
+ test_must_fail git push dest HEAD
+ '
+
+ test_expect_success 'bumping limit to 4k allows push' '
+ git --git-dir=dest config receive.maxInputSize 4k &&
+ git push dest HEAD
+ '
+
+ test_expect_success 'prepare destination repository (again)' '
+ rm -fr dest &&
+ git --bare init dest
+ '
+
+ test_expect_success 'lifting the limit allows push' '
+ git --git-dir=dest config receive.maxInputSize 0 &&
+ git push dest HEAD
+ '
+}
+
+test_expect_success "create known-size (1024 bytes) commit" '
+ test-genrandom foo 1024 >one-k &&
+ git add one-k &&
+ test_commit one-k
+'
+
+test_pack_input_limit index
+test_pack_input_limit unpack
+
+test_done
>expect
;;
?*)
- echo "Accept-Language: $1" >expect
+ echo "=> Send header: Accept-Language: $1" >expect
;;
esac &&
- GIT_CURL_VERBOSE=1 \
+ GIT_TRACE_CURL=true \
LANGUAGE=$2 \
git ls-remote "$HTTPD_URL/dumb/repo.git" >output 2>&1 &&
tr -d '\015' <output |
sort -u |
- sed -ne '/^Accept-Language:/ p' >actual &&
+ sed -ne '/^=> Send header: Accept-Language:/ p' >actual &&
test_cmp expect actual
}
'
test_expect_success 'git client does not send an empty Accept-Language' '
- GIT_CURL_VERBOSE=1 LANGUAGE= git ls-remote "$HTTPD_URL/dumb/repo.git" 2>stderr &&
- ! grep "^Accept-Language:" stderr
+ GIT_TRACE_CURL=true LANGUAGE= git ls-remote "$HTTPD_URL/dumb/repo.git" 2>stderr &&
+ ! grep "^=> Send header: Accept-Language:" stderr
'
stop_httpd
< Content-Type: application/x-git-upload-pack-result
EOF
test_expect_success 'clone http repository' '
- GIT_CURL_VERBOSE=1 git clone --quiet $HTTPD_URL/smart/repo.git clone 2>err &&
+ GIT_TRACE_CURL=true git clone --quiet $HTTPD_URL/smart/repo.git clone 2>err &&
test_cmp file clone/file &&
tr '\''\015'\'' Q <err |
sed -e "
s/Q\$//
/^[*] /d
+ /^== Info:/d
+ /^=> Send header, /d
+ /^=> Send header:$/d
+ /^<= Recv header, /d
+ /^<= Recv header:$/d
+ s/=> Send header: //
+ s/= Recv header://
+ /^<= Recv data/d
+ /^=> Send data/d
/^$/d
/^< $/d
'
test_expect_success 'large fetch-pack requests can be split across POSTs' '
- GIT_CURL_VERBOSE=1 git -c http.postbuffer=65536 \
+ GIT_TRACE_CURL=true git -c http.postbuffer=65536 \
clone --bare "$HTTPD_URL/smart/repo.git" split.git 2>err &&
- grep "^> POST" err >posts &&
+ grep "^=> Send header: POST" err >posts &&
test_line_count = 2 posts
'
git reset --hard anchor &&
write_script sleep-one-second.sh <<-\EOF &&
sleep 1 &
+ echo $! >sleep.pid
EOF
+ test_when_finished "kill \$(cat sleep.pid)" &&
test_write_lines >.gitattributes \
"* merge=ours" "text merge=sleep-one-second" &&
test_i18ncmp expected actual
'
+## Duplicate the above test and verify --porcelain=v1 arg parsing.
+test_expect_success 'status --porcelain=v1 --branch with detached HEAD' '
+ git reset --hard &&
+ git checkout master^0 &&
+ git status --branch --porcelain=v1 >actual &&
+ cat >expected <<-EOF &&
+ ## HEAD (no branch)
+ ?? .gitconfig
+ ?? actual
+ ?? expect
+ ?? expected
+ ?? mdconflict/
+ EOF
+ test_i18ncmp expected actual
+'
+
+## Verify parser error on invalid --porcelain argument.
+test_expect_success 'status --porcelain=bogus' '
+ test_must_fail git status --porcelain=bogus
+'
+
test_done
--- /dev/null
+#!/bin/sh
+
+test_description='git status --porcelain=v2
+
+This test exercises porcelain V2 output for git status.'
+
+
+. ./test-lib.sh
+
+
+test_expect_success setup '
+ test_tick &&
+ git config core.autocrlf false &&
+ echo x >file_x &&
+ echo y >file_y &&
+ echo z >file_z &&
+ mkdir dir1 &&
+ echo a >dir1/file_a &&
+ echo b >dir1/file_b
+'
+
+test_expect_success 'before initial commit, nothing added, only untracked' '
+ cat >expect <<-EOF &&
+ # branch.oid (initial)
+ # branch.head master
+ ? actual
+ ? dir1/
+ ? expect
+ ? file_x
+ ? file_y
+ ? file_z
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=normal >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'before initial commit, things added' '
+ git add file_x file_y file_z dir1 &&
+ OID_A=$(git hash-object -t blob -- dir1/file_a) &&
+ OID_B=$(git hash-object -t blob -- dir1/file_b) &&
+ OID_X=$(git hash-object -t blob -- file_x) &&
+ OID_Y=$(git hash-object -t blob -- file_y) &&
+ OID_Z=$(git hash-object -t blob -- file_z) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid (initial)
+ # branch.head master
+ 1 A. N... 000000 100644 100644 $_z40 $OID_A dir1/file_a
+ 1 A. N... 000000 100644 100644 $_z40 $OID_B dir1/file_b
+ 1 A. N... 000000 100644 100644 $_z40 $OID_X file_x
+ 1 A. N... 000000 100644 100644 $_z40 $OID_Y file_y
+ 1 A. N... 000000 100644 100644 $_z40 $OID_Z file_z
+ ? actual
+ ? expect
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'before initial commit, things added (-z)' '
+ lf_to_nul >expect <<-EOF &&
+ # branch.oid (initial)
+ # branch.head master
+ 1 A. N... 000000 100644 100644 $_z40 $OID_A dir1/file_a
+ 1 A. N... 000000 100644 100644 $_z40 $OID_B dir1/file_b
+ 1 A. N... 000000 100644 100644 $_z40 $OID_X file_x
+ 1 A. N... 000000 100644 100644 $_z40 $OID_Y file_y
+ 1 A. N... 000000 100644 100644 $_z40 $OID_Z file_z
+ ? actual
+ ? expect
+ EOF
+
+ git status -z --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'make first commit, comfirm HEAD oid and branch' '
+ git commit -m initial &&
+ H0=$(git rev-parse HEAD) &&
+ cat >expect <<-EOF &&
+ # branch.oid $H0
+ # branch.head master
+ ? actual
+ ? expect
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'after first commit, create unstaged changes' '
+ echo x >>file_x &&
+ OID_X1=$(git hash-object -t blob -- file_x) &&
+ rm file_z &&
+ H0=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $H0
+ # branch.head master
+ 1 .M N... 100644 100644 100644 $OID_X $OID_X file_x
+ 1 .D N... 100644 100644 000000 $OID_Z $OID_Z file_z
+ ? actual
+ ? expect
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'after first commit but omit untracked files and branch' '
+ cat >expect <<-EOF &&
+ 1 .M N... 100644 100644 100644 $OID_X $OID_X file_x
+ 1 .D N... 100644 100644 000000 $OID_Z $OID_Z file_z
+ EOF
+
+ git status --porcelain=v2 --untracked-files=no >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'after first commit, stage existing changes' '
+ git add file_x &&
+ git rm file_z &&
+ H0=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $H0
+ # branch.head master
+ 1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
+ 1 D. N... 100644 000000 000000 $OID_Z $_z40 file_z
+ ? actual
+ ? expect
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rename causes 2 path lines' '
+ git mv file_y renamed_y &&
+ H0=$(git rev-parse HEAD) &&
+
+ q_to_tab >expect <<-EOF &&
+ # branch.oid $H0
+ # branch.head master
+ 1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
+ 1 D. N... 100644 000000 000000 $OID_Z $_z40 file_z
+ 2 R. N... 100644 100644 100644 $OID_Y $OID_Y R100 renamed_yQfile_y
+ ? actual
+ ? expect
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rename causes 2 path lines (-z)' '
+ H0=$(git rev-parse HEAD) &&
+
+ ## Lines use NUL path separator and line terminator, so double transform here.
+ q_to_nul <<-EOF | lf_to_nul >expect &&
+ # branch.oid $H0
+ # branch.head master
+ 1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
+ 1 D. N... 100644 000000 000000 $OID_Z $_z40 file_z
+ 2 R. N... 100644 100644 100644 $OID_Y $OID_Y R100 renamed_yQfile_y
+ ? actual
+ ? expect
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all -z >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'make second commit, confirm clean and new HEAD oid' '
+ git commit -m second &&
+ H1=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $H1
+ # branch.head master
+ ? actual
+ ? expect
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'confirm ignored files are not printed' '
+ test_when_finished "rm -f x.ign .gitignore" &&
+ echo x.ign >.gitignore &&
+ echo "ignore me" >x.ign &&
+
+ cat >expect <<-EOF &&
+ ? .gitignore
+ ? actual
+ ? expect
+ EOF
+
+ git status --porcelain=v2 --untracked-files=all >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'ignored files are printed with --ignored' '
+ test_when_finished "rm -f x.ign .gitignore" &&
+ echo x.ign >.gitignore &&
+ echo "ignore me" >x.ign &&
+
+ cat >expect <<-EOF &&
+ ? .gitignore
+ ? actual
+ ? expect
+ ! x.ign
+ EOF
+
+ git status --porcelain=v2 --ignored --untracked-files=all >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'create and commit permanent ignore file' '
+ cat >.gitignore <<-EOF &&
+ actual*
+ expect*
+ EOF
+
+ git add .gitignore &&
+ git commit -m ignore_trash &&
+ H1=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $H1
+ # branch.head master
+ EOF
+
+ git status --porcelain=v2 --branch >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'verify --intent-to-add output' '
+ test_when_finished "git rm -f intent1.add intent2.add" &&
+ touch intent1.add &&
+ echo test >intent2.add &&
+
+ git add --intent-to-add intent1.add intent2.add &&
+
+ cat >expect <<-EOF &&
+ 1 AM N... 000000 100644 100644 $_z40 $EMPTY_BLOB intent1.add
+ 1 AM N... 000000 100644 100644 $_z40 $EMPTY_BLOB intent2.add
+ EOF
+
+ git status --porcelain=v2 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'verify AA (add-add) conflict' '
+ test_when_finished "git reset --hard" &&
+
+ git branch AA_A master &&
+ git checkout AA_A &&
+ echo "Branch AA_A" >conflict.txt &&
+ OID_AA_A=$(git hash-object -t blob -- conflict.txt) &&
+ git add conflict.txt &&
+ git commit -m "branch aa_a" &&
+
+ git branch AA_B master &&
+ git checkout AA_B &&
+ echo "Branch AA_B" >conflict.txt &&
+ OID_AA_B=$(git hash-object -t blob -- conflict.txt) &&
+ git add conflict.txt &&
+ git commit -m "branch aa_b" &&
+
+ git branch AA_M AA_B &&
+ git checkout AA_M &&
+ test_must_fail git merge AA_A &&
+
+ HM=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HM
+ # branch.head AA_M
+ u AA N... 000000 100644 100644 100644 $_z40 $OID_AA_B $OID_AA_A conflict.txt
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'verify UU (edit-edit) conflict' '
+ test_when_finished "git reset --hard" &&
+
+ git branch UU_ANC master &&
+ git checkout UU_ANC &&
+ echo "Ancestor" >conflict.txt &&
+ OID_UU_ANC=$(git hash-object -t blob -- conflict.txt) &&
+ git add conflict.txt &&
+ git commit -m "UU_ANC" &&
+
+ git branch UU_A UU_ANC &&
+ git checkout UU_A &&
+ echo "Branch UU_A" >conflict.txt &&
+ OID_UU_A=$(git hash-object -t blob -- conflict.txt) &&
+ git add conflict.txt &&
+ git commit -m "branch uu_a" &&
+
+ git branch UU_B UU_ANC &&
+ git checkout UU_B &&
+ echo "Branch UU_B" >conflict.txt &&
+ OID_UU_B=$(git hash-object -t blob -- conflict.txt) &&
+ git add conflict.txt &&
+ git commit -m "branch uu_b" &&
+
+ git branch UU_M UU_B &&
+ git checkout UU_M &&
+ test_must_fail git merge UU_A &&
+
+ HM=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HM
+ # branch.head UU_M
+ u UU N... 100644 100644 100644 100644 $OID_UU_ANC $OID_UU_B $OID_UU_A conflict.txt
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'verify upstream fields in branch header' '
+ git checkout master &&
+ test_when_finished "rm -rf sub_repo" &&
+ git clone . sub_repo &&
+ (
+ ## Confirm local master tracks remote master.
+ cd sub_repo &&
+ HUF=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HUF
+ # branch.head master
+ # branch.upstream origin/master
+ # branch.ab +0 -0
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual &&
+
+ ## Test ahead/behind.
+ echo xyz >file_xyz &&
+ git add file_xyz &&
+ git commit -m xyz &&
+
+ HUF=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HUF
+ # branch.head master
+ # branch.upstream origin/master
+ # branch.ab +1 -0
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual &&
+
+ ## Repeat the above but without --branch.
+ cat >expect <<-EOF &&
+ EOF
+
+ git status --porcelain=v2 --untracked-files=all >actual &&
+ test_cmp expect actual &&
+
+ ## Test upstream-gone case. Fake this by pointing origin/master at
+ ## a non-existing commit.
+ OLD=$(git rev-parse origin/master) &&
+ NEW=$_z40 &&
+ mv .git/packed-refs .git/old-packed-refs &&
+ sed "s/$OLD/$NEW/g" <.git/old-packed-refs >.git/packed-refs &&
+
+ HUF=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HUF
+ # branch.head master
+ # branch.upstream origin/master
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'create and add submodule, submodule appears clean (A. S...)' '
+ git checkout master &&
+ git clone . sub_repo &&
+ git clone . super_repo &&
+ ( cd super_repo &&
+ git submodule add ../sub_repo sub1 &&
+
+ ## Confirm stage/add of clean submodule.
+ HMOD=$(git hash-object -t blob -- .gitmodules) &&
+ HSUP=$(git rev-parse HEAD) &&
+ HSUB=$HSUP &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HSUP
+ # branch.head master
+ # branch.upstream origin/master
+ # branch.ab +0 -0
+ 1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
+ 1 A. S... 000000 160000 160000 $_z40 $HSUB sub1
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'untracked changes in added submodule (AM S..U)' '
+ ( cd super_repo &&
+ ## create untracked file in the submodule.
+ ( cd sub1 &&
+ echo "xxxx" >file_in_sub
+ ) &&
+
+ HMOD=$(git hash-object -t blob -- .gitmodules) &&
+ HSUP=$(git rev-parse HEAD) &&
+ HSUB=$HSUP &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HSUP
+ # branch.head master
+ # branch.upstream origin/master
+ # branch.ab +0 -0
+ 1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
+ 1 AM S..U 000000 160000 160000 $_z40 $HSUB sub1
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'staged changes in added submodule (AM S.M.)' '
+ ( cd super_repo &&
+ ## stage the changes in the submodule.
+ ( cd sub1 &&
+ git add file_in_sub
+ ) &&
+
+ HMOD=$(git hash-object -t blob -- .gitmodules) &&
+ HSUP=$(git rev-parse HEAD) &&
+ HSUB=$HSUP &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HSUP
+ # branch.head master
+ # branch.upstream origin/master
+ # branch.ab +0 -0
+ 1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
+ 1 AM S.M. 000000 160000 160000 $_z40 $HSUB sub1
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'staged and unstaged changes in added (AM S.M.)' '
+ ( cd super_repo &&
+ ( cd sub1 &&
+ ## make additional unstaged changes (on the same file) in the submodule.
+ ## This does not cause us to get S.MU (because the submodule does not report
+ ## a "?" line for the unstaged changes).
+ echo "more changes" >>file_in_sub
+ ) &&
+
+ HMOD=$(git hash-object -t blob -- .gitmodules) &&
+ HSUP=$(git rev-parse HEAD) &&
+ HSUB=$HSUP &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HSUP
+ # branch.head master
+ # branch.upstream origin/master
+ # branch.ab +0 -0
+ 1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
+ 1 AM S.M. 000000 160000 160000 $_z40 $HSUB sub1
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'staged and untracked changes in added submodule (AM S.MU)' '
+ ( cd super_repo &&
+ ( cd sub1 &&
+ ## stage new changes in tracked file.
+ git add file_in_sub &&
+ ## create new untracked file.
+ echo "yyyy" >>another_file_in_sub
+ ) &&
+
+ HMOD=$(git hash-object -t blob -- .gitmodules) &&
+ HSUP=$(git rev-parse HEAD) &&
+ HSUB=$HSUP &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HSUP
+ # branch.head master
+ # branch.upstream origin/master
+ # branch.ab +0 -0
+ 1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
+ 1 AM S.MU 000000 160000 160000 $_z40 $HSUB sub1
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'commit within the submodule appears as new commit in super (AM SC..)' '
+ ( cd super_repo &&
+ ( cd sub1 &&
+ ## Make a new commit in the submodule.
+ git add file_in_sub &&
+ rm -f another_file_in_sub &&
+ git commit -m "new commit"
+ ) &&
+
+ HMOD=$(git hash-object -t blob -- .gitmodules) &&
+ HSUP=$(git rev-parse HEAD) &&
+ HSUB=$HSUP &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HSUP
+ # branch.head master
+ # branch.upstream origin/master
+ # branch.ab +0 -0
+ 1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
+ 1 AM SC.. 000000 160000 160000 $_z40 $HSUB sub1
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'stage submodule in super and commit' '
+ ( cd super_repo &&
+ ## Stage the new submodule commit in the super.
+ git add sub1 &&
+ ## Commit the super so that the sub no longer appears as added.
+ git commit -m "super commit" &&
+
+ HSUP=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HSUP
+ # branch.head master
+ # branch.upstream origin/master
+ # branch.ab +1 -0
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'make unstaged changes in existing submodule (.M S.M.)' '
+ ( cd super_repo &&
+ ( cd sub1 &&
+ echo "zzzz" >>file_in_sub
+ ) &&
+
+ HSUP=$(git rev-parse HEAD) &&
+ HSUB=$(cd sub1 && git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ # branch.oid $HSUP
+ # branch.head master
+ # branch.upstream origin/master
+ # branch.ab +1 -0
+ 1 .M S.M. 160000 160000 160000 $HSUB $HSUB sub1
+ EOF
+
+ git status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_done
base_dir=$(pwd)
-U=$base_dir/UPLOAD_LOG
-
-test_expect_success 'preparing first repository' \
-'test_create_repo A && cd A &&
-echo first > file1 &&
-git add file1 &&
-git commit -m A-initial'
-
-cd "$base_dir"
-
-test_expect_success 'preparing second repository' \
-'git clone A B && cd B &&
-echo second > file2 &&
-git add file2 &&
-git commit -m B-addition &&
-git repack -a -d &&
-git prune'
-
-cd "$base_dir"
-
-test_expect_success 'preparing superproject' \
-'test_create_repo super && cd super &&
-echo file > file &&
-git add file &&
-git commit -m B-super-initial'
-
-cd "$base_dir"
-
-test_expect_success 'submodule add --reference' \
-'cd super && git submodule add --reference ../B "file://$base_dir/A" sub &&
-git commit -m B-super-added'
-
-cd "$base_dir"
-
-test_expect_success 'after add: existence of info/alternates' \
-'test_line_count = 1 super/.git/modules/sub/objects/info/alternates'
-
-cd "$base_dir"
-
-test_expect_success 'that reference gets used with add' \
-'cd super/sub &&
-echo "0 objects, 0 kilobytes" > expected &&
-git count-objects > current &&
-diff expected current'
-
-cd "$base_dir"
-
-test_expect_success 'cloning superproject' \
-'git clone super super-clone'
-
-cd "$base_dir"
-
-test_expect_success 'update with reference' \
-'cd super-clone && git submodule update --init --reference ../B'
-
-cd "$base_dir"
-
-test_expect_success 'after update: existence of info/alternates' \
-'test_line_count = 1 super-clone/.git/modules/sub/objects/info/alternates'
-
-cd "$base_dir"
-
-test_expect_success 'that reference gets used with update' \
-'cd super-clone/sub &&
-echo "0 objects, 0 kilobytes" > expected &&
-git count-objects > current &&
-diff expected current'
-
-cd "$base_dir"
+test_alternate_is_used () {
+ alternates_file="$1" &&
+ working_dir="$2" &&
+ test_line_count = 1 "$alternates_file" &&
+ echo "0 objects, 0 kilobytes" >expect &&
+ git -C "$working_dir" count-objects >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success 'preparing first repository' '
+ test_create_repo A &&
+ (
+ cd A &&
+ echo first >file1 &&
+ git add file1 &&
+ git commit -m A-initial
+ )
+'
+
+test_expect_success 'preparing second repository' '
+ git clone A B &&
+ (
+ cd B &&
+ echo second >file2 &&
+ git add file2 &&
+ git commit -m B-addition &&
+ git repack -a -d &&
+ git prune
+ )
+'
+
+test_expect_success 'preparing superproject' '
+ test_create_repo super &&
+ (
+ cd super &&
+ echo file >file &&
+ git add file &&
+ git commit -m B-super-initial
+ )
+'
+
+test_expect_success 'submodule add --reference uses alternates' '
+ (
+ cd super &&
+ git submodule add --reference ../B "file://$base_dir/A" sub &&
+ git commit -m B-super-added &&
+ git repack -ad
+ ) &&
+ test_alternate_is_used super/.git/modules/sub/objects/info/alternates super/sub
+'
+
+test_expect_success 'that reference gets used with add' '
+ (
+ cd super/sub &&
+ echo "0 objects, 0 kilobytes" >expected &&
+ git count-objects >current &&
+ diff expected current
+ )
+'
+
+# The tests up to this point, and repositories created by them
+# (A, B, super and super/sub), are about setting up the stage
+# for subsequent tests and meant to be kept throughout the
+# remainder of the test.
+# Tests from here on, if they create their own test repository,
+# are expected to clean after themselves.
+
+test_expect_success 'updating superproject keeps alternates' '
+ test_when_finished "rm -rf super-clone" &&
+ git clone super super-clone &&
+ git -C super-clone submodule update --init --reference ../B &&
+ test_alternate_is_used super-clone/.git/modules/sub/objects/info/alternates super-clone/sub
+'
+
+test_expect_success 'submodules use alternates when cloning a superproject' '
+ test_when_finished "rm -rf super-clone" &&
+ git clone --reference super --recursive super super-clone &&
+ (
+ cd super-clone &&
+ # test superproject has alternates setup correctly
+ test_alternate_is_used .git/objects/info/alternates . &&
+ # test submodule has correct setup
+ test_alternate_is_used .git/modules/sub/objects/info/alternates sub
+ )
+'
+
+test_expect_success 'missing submodule alternate fails clone and submodule update' '
+ test_when_finished "rm -rf super-clone" &&
+ git clone super super2 &&
+ test_must_fail git clone --recursive --reference super2 super2 super-clone &&
+ (
+ cd super-clone &&
+ # test superproject has alternates setup correctly
+ test_alternate_is_used .git/objects/info/alternates . &&
+ # update of the submodule succeeds
+ test_must_fail git submodule update --init &&
+ # and we have no alternates:
+ test_must_fail test_alternate_is_used .git/modules/sub/objects/info/alternates sub &&
+ test_must_fail test_path_is_file sub/file1
+ )
+'
+
+test_expect_success 'ignoring missing submodule alternates passes clone and submodule update' '
+ test_when_finished "rm -rf super-clone" &&
+ git clone --reference-if-able super2 --recursive super2 super-clone &&
+ (
+ cd super-clone &&
+ # test superproject has alternates setup correctly
+ test_alternate_is_used .git/objects/info/alternates . &&
+ # update of the submodule succeeds
+ git submodule update --init &&
+ # and we have no alternates:
+ test_must_fail test_alternate_is_used .git/modules/sub/objects/info/alternates sub &&
+ test_path_is_file sub/file1
+ )
+'
test_done
git checkout b1 &&
test_when_finished "git checkout master" &&
git rebase -i HEAD^ &&
- test_when_finished "git rebase --abort"
+ test_when_finished "git rebase --abort" &&
__git_ps1 >"$actual" &&
test_cmp expected "$actual"
'
'
}
+lf_to_nul () {
+ perl -pe 'y/\012/\000/'
+}
+
nul_to_q () {
perl -pe 'y/\000/Q/'
}
UNZIP
PERF_
CURL_VERBOSE
+ TRACE_CURL
));
my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
print join("\n", @vars);
test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
mkdir -p "$test_results_dir"
base=${0##*/}
- test_results_path="$test_results_dir/${base%.sh}-$$.counts"
+ test_results_path="$test_results_dir/${base%.sh}.counts"
- cat >>"$test_results_path" <<-EOF
+ cat >"$test_results_path" <<-EOF
total $test_count
success $test_success
fixed $test_fixed
fprintf(stderr, _("The following submodule paths contain changes that can\n"
"not be found on any remote:\n"));
for (i = 0; i < needs_pushing->nr; i++)
- printf(" %s\n", needs_pushing->items[i].string);
+ fprintf(stderr, " %s\n", needs_pushing->items[i].string);
fprintf(stderr, _("\nPlease try\n\n"
" git push --recurse-submodules=on-demand\n\n"
"or cd to the path and use\n\n"
return (url[0] == ':' && url[1] == '/' && url[2] == '/');
}
-static int url_decode_char(const char *q)
-{
- int i;
- unsigned char val = 0;
- for (i = 0; i < 2; i++) {
- unsigned char c = *q++;
- val <<= 4;
- if (c >= '0' && c <= '9')
- val += c - '0';
- else if (c >= 'a' && c <= 'f')
- val += c - 'a' + 10;
- else if (c >= 'A' && c <= 'F')
- val += c - 'A' + 10;
- else
- return -1;
- }
- return val;
-}
-
static char *url_decode_internal(const char **query, int len,
const char *stop_at, struct strbuf *out,
int decode_plus)
}
if (c == '%') {
- int val = url_decode_char(q + 1);
+ int val = hex2chr(q + 1);
if (0 <= val) {
strbuf_addch(out, val);
q += 3;
va_end(params);
}
+#undef error_errno
int error_errno(const char *fmt, ...)
{
char buf[1024];
s->display_comment_prefix = 0;
}
-static void wt_status_print_unmerged_header(struct wt_status *s)
+static void wt_longstatus_print_unmerged_header(struct wt_status *s)
{
int i;
int del_mod_conflict = 0;
status_printf_ln(s, c, "%s", "");
}
-static void wt_status_print_cached_header(struct wt_status *s)
+static void wt_longstatus_print_cached_header(struct wt_status *s)
{
const char *c = color(WT_STATUS_HEADER, s);
status_printf_ln(s, c, "%s", "");
}
-static void wt_status_print_dirty_header(struct wt_status *s,
- int has_deleted,
- int has_dirty_submodules)
+static void wt_longstatus_print_dirty_header(struct wt_status *s,
+ int has_deleted,
+ int has_dirty_submodules)
{
const char *c = color(WT_STATUS_HEADER, s);
status_printf_ln(s, c, "%s", "");
}
-static void wt_status_print_other_header(struct wt_status *s,
- const char *what,
- const char *how)
+static void wt_longstatus_print_other_header(struct wt_status *s,
+ const char *what,
+ const char *how)
{
const char *c = color(WT_STATUS_HEADER, s);
status_printf_ln(s, c, "%s:", what);
status_printf_ln(s, c, "%s", "");
}
-static void wt_status_print_trailer(struct wt_status *s)
+static void wt_longstatus_print_trailer(struct wt_status *s)
{
status_printf_ln(s, color(WT_STATUS_HEADER, s), "%s", "");
}
return result;
}
-static void wt_status_print_unmerged_data(struct wt_status *s,
- struct string_list_item *it)
+static void wt_longstatus_print_unmerged_data(struct wt_status *s,
+ struct string_list_item *it)
{
const char *c = color(WT_STATUS_UNMERGED, s);
struct wt_status_change_data *d = it->util;
strbuf_release(&onebuf);
}
-static void wt_status_print_change_data(struct wt_status *s,
- int change_type,
- struct string_list_item *it)
+static void wt_longstatus_print_change_data(struct wt_status *s,
+ int change_type,
+ struct string_list_item *it)
{
struct wt_status_change_data *d = it->util;
const char *c = color(change_type, s);
status = d->worktree_status;
break;
default:
- die("BUG: unhandled change_type %d in wt_status_print_change_data",
+ die("BUG: unhandled change_type %d in wt_longstatus_print_change_data",
change_type);
}
if (S_ISGITLINK(p->two->mode))
d->new_submodule_commits = !!oidcmp(&p->one->oid,
&p->two->oid);
+
+ switch (p->status) {
+ case DIFF_STATUS_ADDED:
+ die("BUG: worktree status add???");
+ break;
+
+ case DIFF_STATUS_DELETED:
+ d->mode_index = p->one->mode;
+ oidcpy(&d->oid_index, &p->one->oid);
+ /* mode_worktree is zero for a delete. */
+ break;
+
+ case DIFF_STATUS_MODIFIED:
+ case DIFF_STATUS_TYPE_CHANGED:
+ case DIFF_STATUS_UNMERGED:
+ d->mode_index = p->one->mode;
+ d->mode_worktree = p->two->mode;
+ oidcpy(&d->oid_index, &p->one->oid);
+ break;
+
+ case DIFF_STATUS_UNKNOWN:
+ die("BUG: worktree status unknown???");
+ break;
+ }
+
}
}
if (!d->index_status)
d->index_status = p->status;
switch (p->status) {
+ case DIFF_STATUS_ADDED:
+ /* Leave {mode,oid}_head zero for an add. */
+ d->mode_index = p->two->mode;
+ oidcpy(&d->oid_index, &p->two->oid);
+ break;
+ case DIFF_STATUS_DELETED:
+ d->mode_head = p->one->mode;
+ oidcpy(&d->oid_head, &p->one->oid);
+ /* Leave {mode,oid}_index zero for a delete. */
+ break;
+
case DIFF_STATUS_COPIED:
case DIFF_STATUS_RENAMED:
d->head_path = xstrdup(p->one->path);
+ d->score = p->score * 100 / MAX_SCORE;
+ /* fallthru */
+ case DIFF_STATUS_MODIFIED:
+ case DIFF_STATUS_TYPE_CHANGED:
+ d->mode_head = p->one->mode;
+ d->mode_index = p->two->mode;
+ oidcpy(&d->oid_head, &p->one->oid);
+ oidcpy(&d->oid_index, &p->two->oid);
break;
case DIFF_STATUS_UNMERGED:
d->stagemask = unmerged_mask(p->two->path);
+ /*
+ * Don't bother setting {mode,oid}_{head,index} since the print
+ * code will output the stage values directly and not use the
+ * values in these fields.
+ */
break;
}
}
if (ce_stage(ce)) {
d->index_status = DIFF_STATUS_UNMERGED;
d->stagemask |= (1 << (ce_stage(ce) - 1));
- }
- else
+ /*
+ * Don't bother setting {mode,oid}_{head,index} since the print
+ * code will output the stage values directly and not use the
+ * values in these fields.
+ */
+ } else {
d->index_status = DIFF_STATUS_ADDED;
+ /* Leave {mode,oid}_head zero for adds. */
+ d->mode_index = ce->ce_mode;
+ hashcpy(d->oid_index.hash, ce->sha1);
+ }
}
}
wt_status_collect_untracked(s);
}
-static void wt_status_print_unmerged(struct wt_status *s)
+static void wt_longstatus_print_unmerged(struct wt_status *s)
{
int shown_header = 0;
int i;
if (!d->stagemask)
continue;
if (!shown_header) {
- wt_status_print_unmerged_header(s);
+ wt_longstatus_print_unmerged_header(s);
shown_header = 1;
}
- wt_status_print_unmerged_data(s, it);
+ wt_longstatus_print_unmerged_data(s, it);
}
if (shown_header)
- wt_status_print_trailer(s);
+ wt_longstatus_print_trailer(s);
}
-static void wt_status_print_updated(struct wt_status *s)
+static void wt_longstatus_print_updated(struct wt_status *s)
{
int shown_header = 0;
int i;
d->index_status == DIFF_STATUS_UNMERGED)
continue;
if (!shown_header) {
- wt_status_print_cached_header(s);
+ wt_longstatus_print_cached_header(s);
s->commitable = 1;
shown_header = 1;
}
- wt_status_print_change_data(s, WT_STATUS_UPDATED, it);
+ wt_longstatus_print_change_data(s, WT_STATUS_UPDATED, it);
}
if (shown_header)
- wt_status_print_trailer(s);
+ wt_longstatus_print_trailer(s);
}
/*
return changes;
}
-static void wt_status_print_changed(struct wt_status *s)
+static void wt_longstatus_print_changed(struct wt_status *s)
{
int i, dirty_submodules;
int worktree_changes = wt_status_check_worktree_changes(s, &dirty_submodules);
if (!worktree_changes)
return;
- wt_status_print_dirty_header(s, worktree_changes < 0, dirty_submodules);
+ wt_longstatus_print_dirty_header(s, worktree_changes < 0, dirty_submodules);
for (i = 0; i < s->change.nr; i++) {
struct wt_status_change_data *d;
if (!d->worktree_status ||
d->worktree_status == DIFF_STATUS_UNMERGED)
continue;
- wt_status_print_change_data(s, WT_STATUS_CHANGED, it);
+ wt_longstatus_print_change_data(s, WT_STATUS_CHANGED, it);
}
- wt_status_print_trailer(s);
+ wt_longstatus_print_trailer(s);
}
-static void wt_status_print_submodule_summary(struct wt_status *s, int uncommitted)
+static void wt_longstatus_print_submodule_summary(struct wt_status *s, int uncommitted)
{
struct child_process sm_summary = CHILD_PROCESS_INIT;
struct strbuf cmd_stdout = STRBUF_INIT;
strbuf_release(&summary);
}
-static void wt_status_print_other(struct wt_status *s,
- struct string_list *l,
- const char *what,
- const char *how)
+static void wt_longstatus_print_other(struct wt_status *s,
+ struct string_list *l,
+ const char *what,
+ const char *how)
{
int i;
struct strbuf buf = STRBUF_INIT;
if (!l->nr)
return;
- wt_status_print_other_header(s, what, how);
+ wt_longstatus_print_other_header(s, what, how);
for (i = 0; i < l->nr; i++) {
struct string_list_item *it;
strbuf_release(&buf);
}
-static void wt_status_print_verbose(struct wt_status *s)
+static void wt_longstatus_print_verbose(struct wt_status *s)
{
struct rev_info rev;
struct setup_revision_opt opt;
if (s->verbose > 1 && s->commitable) {
/* print_updated() printed a header, so do we */
if (s->fp != stdout)
- wt_status_print_trailer(s);
+ wt_longstatus_print_trailer(s);
status_printf_ln(s, c, _("Changes to be committed:"));
rev.diffopt.a_prefix = "c/";
rev.diffopt.b_prefix = "i/";
}
}
-static void wt_status_print_tracking(struct wt_status *s)
+static void wt_longstatus_print_tracking(struct wt_status *s)
{
struct strbuf sb = STRBUF_INIT;
const char *cp, *ep, *branch_name;
status_printf_ln(s, color,
_(" (use \"git commit\" to conclude merge)"));
}
- wt_status_print_trailer(s);
+ wt_longstatus_print_trailer(s);
}
static void show_am_in_progress(struct wt_status *s,
status_printf_ln(s, color,
_(" (use \"git am --abort\" to restore the original branch)"));
}
- wt_status_print_trailer(s);
+ wt_longstatus_print_trailer(s);
}
static char *read_line_from_git_path(const char *filename)
_(" (use \"git rebase --continue\" once you are satisfied with your changes)"));
}
}
- wt_status_print_trailer(s);
+ wt_longstatus_print_trailer(s);
}
static void show_cherry_pick_in_progress(struct wt_status *s,
status_printf_ln(s, color,
_(" (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"));
}
- wt_status_print_trailer(s);
+ wt_longstatus_print_trailer(s);
}
static void show_revert_in_progress(struct wt_status *s,
status_printf_ln(s, color,
_(" (use \"git revert --abort\" to cancel the revert operation)"));
}
- wt_status_print_trailer(s);
+ wt_longstatus_print_trailer(s);
}
static void show_bisect_in_progress(struct wt_status *s,
if (s->hints)
status_printf_ln(s, color,
_(" (use \"git bisect reset\" to get back to the original branch)"));
- wt_status_print_trailer(s);
+ wt_longstatus_print_trailer(s);
}
/*
wt_status_get_detached_from(state);
}
-static void wt_status_print_state(struct wt_status *s,
- struct wt_status_state *state)
+static void wt_longstatus_print_state(struct wt_status *s,
+ struct wt_status_state *state)
{
const char *state_color = color(WT_STATUS_HEADER, s);
if (state->merge_in_progress)
show_bisect_in_progress(s, state, state_color);
}
-void wt_status_print(struct wt_status *s)
+static void wt_longstatus_print(struct wt_status *s)
{
const char *branch_color = color(WT_STATUS_ONBRANCH, s);
const char *branch_status_color = color(WT_STATUS_HEADER, s);
status_printf_more(s, branch_status_color, "%s", on_what);
status_printf_more(s, branch_color, "%s\n", branch_name);
if (!s->is_initial)
- wt_status_print_tracking(s);
+ wt_longstatus_print_tracking(s);
}
- wt_status_print_state(s, &state);
+ wt_longstatus_print_state(s, &state);
free(state.branch);
free(state.onto);
free(state.detached_from);
status_printf_ln(s, color(WT_STATUS_HEADER, s), "%s", "");
}
- wt_status_print_updated(s);
- wt_status_print_unmerged(s);
- wt_status_print_changed(s);
+ wt_longstatus_print_updated(s);
+ wt_longstatus_print_unmerged(s);
+ wt_longstatus_print_changed(s);
if (s->submodule_summary &&
(!s->ignore_submodule_arg ||
strcmp(s->ignore_submodule_arg, "all"))) {
- wt_status_print_submodule_summary(s, 0); /* staged */
- wt_status_print_submodule_summary(s, 1); /* unstaged */
+ wt_longstatus_print_submodule_summary(s, 0); /* staged */
+ wt_longstatus_print_submodule_summary(s, 1); /* unstaged */
}
if (s->show_untracked_files) {
- wt_status_print_other(s, &s->untracked, _("Untracked files"), "add");
+ wt_longstatus_print_other(s, &s->untracked, _("Untracked files"), "add");
if (s->show_ignored_files)
- wt_status_print_other(s, &s->ignored, _("Ignored files"), "add -f");
+ wt_longstatus_print_other(s, &s->ignored, _("Ignored files"), "add -f");
if (advice_status_u_option && 2000 < s->untracked_in_ms) {
status_printf_ln(s, GIT_COLOR_NORMAL, "%s", "");
status_printf_ln(s, GIT_COLOR_NORMAL,
? _(" (use -u option to show untracked files)") : "");
if (s->verbose)
- wt_status_print_verbose(s);
+ wt_longstatus_print_verbose(s);
if (!s->commitable) {
if (s->amend)
status_printf_ln(s, GIT_COLOR_NORMAL, _("No changes"));
fputc(s->null_termination ? '\0' : '\n', s->fp);
}
-void wt_shortstatus_print(struct wt_status *s)
+static void wt_shortstatus_print(struct wt_status *s)
{
int i;
}
}
-void wt_porcelain_print(struct wt_status *s)
+static void wt_porcelain_print(struct wt_status *s)
{
s->use_color = 0;
s->relative_paths = 0;
s->no_gettext = 1;
wt_shortstatus_print(s);
}
+
+/*
+ * Print branch information for porcelain v2 output. These lines
+ * are printed when the '--branch' parameter is given.
+ *
+ * # branch.oid <commit><eol>
+ * # branch.head <head><eol>
+ * [# branch.upstream <upstream><eol>
+ * [# branch.ab +<ahead> -<behind><eol>]]
+ *
+ * <commit> ::= the current commit hash or the the literal
+ * "(initial)" to indicate an initialized repo
+ * with no commits.
+ *
+ * <head> ::= <branch_name> the current branch name or
+ * "(detached)" literal when detached head or
+ * "(unknown)" when something is wrong.
+ *
+ * <upstream> ::= the upstream branch name, when set.
+ *
+ * <ahead> ::= integer ahead value, when upstream set
+ * and the commit is present (not gone).
+ *
+ * <behind> ::= integer behind value, when upstream set
+ * and commit is present.
+ *
+ *
+ * The end-of-line is defined by the -z flag.
+ *
+ * <eol> ::= NUL when -z,
+ * LF when NOT -z.
+ *
+ */
+static void wt_porcelain_v2_print_tracking(struct wt_status *s)
+{
+ struct branch *branch;
+ const char *base;
+ const char *branch_name;
+ struct wt_status_state state;
+ int ab_info, nr_ahead, nr_behind;
+ char eol = s->null_termination ? '\0' : '\n';
+
+ memset(&state, 0, sizeof(state));
+ wt_status_get_state(&state, s->branch && !strcmp(s->branch, "HEAD"));
+
+ fprintf(s->fp, "# branch.oid %s%c",
+ (s->is_initial ? "(initial)" : sha1_to_hex(s->sha1_commit)),
+ eol);
+
+ if (!s->branch)
+ fprintf(s->fp, "# branch.head %s%c", "(unknown)", eol);
+ else {
+ if (!strcmp(s->branch, "HEAD")) {
+ fprintf(s->fp, "# branch.head %s%c", "(detached)", eol);
+
+ if (state.rebase_in_progress || state.rebase_interactive_in_progress)
+ branch_name = state.onto;
+ else if (state.detached_from)
+ branch_name = state.detached_from;
+ else
+ branch_name = "";
+ } else {
+ branch_name = NULL;
+ skip_prefix(s->branch, "refs/heads/", &branch_name);
+
+ fprintf(s->fp, "# branch.head %s%c", branch_name, eol);
+ }
+
+ /* Lookup stats on the upstream tracking branch, if set. */
+ branch = branch_get(branch_name);
+ base = NULL;
+ ab_info = (stat_tracking_info(branch, &nr_ahead, &nr_behind, &base) == 0);
+ if (base) {
+ base = shorten_unambiguous_ref(base, 0);
+ fprintf(s->fp, "# branch.upstream %s%c", base, eol);
+ free((char *)base);
+
+ if (ab_info)
+ fprintf(s->fp, "# branch.ab +%d -%d%c", nr_ahead, nr_behind, eol);
+ }
+ }
+
+ free(state.branch);
+ free(state.onto);
+ free(state.detached_from);
+}
+
+/*
+ * Convert various submodule status values into a
+ * fixed-length string of characters in the buffer provided.
+ */
+static void wt_porcelain_v2_submodule_state(
+ struct wt_status_change_data *d,
+ char sub[5])
+{
+ if (S_ISGITLINK(d->mode_head) ||
+ S_ISGITLINK(d->mode_index) ||
+ S_ISGITLINK(d->mode_worktree)) {
+ sub[0] = 'S';
+ sub[1] = d->new_submodule_commits ? 'C' : '.';
+ sub[2] = (d->dirty_submodule & DIRTY_SUBMODULE_MODIFIED) ? 'M' : '.';
+ sub[3] = (d->dirty_submodule & DIRTY_SUBMODULE_UNTRACKED) ? 'U' : '.';
+ } else {
+ sub[0] = 'N';
+ sub[1] = '.';
+ sub[2] = '.';
+ sub[3] = '.';
+ }
+ sub[4] = 0;
+}
+
+/*
+ * Fix-up changed entries before we print them.
+ */
+static void wt_porcelain_v2_fix_up_changed(
+ struct string_list_item *it,
+ struct wt_status *s)
+{
+ struct wt_status_change_data *d = it->util;
+
+ if (!d->index_status) {
+ /*
+ * This entry is unchanged in the index (relative to the head).
+ * Therefore, the collect_updated_cb was never called for this
+ * entry (during the head-vs-index scan) and so the head column
+ * fields were never set.
+ *
+ * We must have data for the index column (from the
+ * index-vs-worktree scan (otherwise, this entry should not be
+ * in the list of changes)).
+ *
+ * Copy index column fields to the head column, so that our
+ * output looks complete.
+ */
+ assert(d->mode_head == 0);
+ d->mode_head = d->mode_index;
+ oidcpy(&d->oid_head, &d->oid_index);
+ }
+
+ if (!d->worktree_status) {
+ /*
+ * This entry is unchanged in the worktree (relative to the index).
+ * Therefore, the collect_changed_cb was never called for this entry
+ * (during the index-vs-worktree scan) and so the worktree column
+ * fields were never set.
+ *
+ * We must have data for the index column (from the head-vs-index
+ * scan).
+ *
+ * Copy the index column fields to the worktree column so that
+ * our output looks complete.
+ *
+ * Note that we only have a mode field in the worktree column
+ * because the scan code tries really hard to not have to compute it.
+ */
+ assert(d->mode_worktree == 0);
+ d->mode_worktree = d->mode_index;
+ }
+}
+
+/*
+ * Print porcelain v2 info for tracked entries with changes.
+ */
+static void wt_porcelain_v2_print_changed_entry(
+ struct string_list_item *it,
+ struct wt_status *s)
+{
+ struct wt_status_change_data *d = it->util;
+ struct strbuf buf_index = STRBUF_INIT;
+ struct strbuf buf_head = STRBUF_INIT;
+ const char *path_index = NULL;
+ const char *path_head = NULL;
+ char key[3];
+ char submodule_token[5];
+ char sep_char, eol_char;
+
+ wt_porcelain_v2_fix_up_changed(it, s);
+ wt_porcelain_v2_submodule_state(d, submodule_token);
+
+ key[0] = d->index_status ? d->index_status : '.';
+ key[1] = d->worktree_status ? d->worktree_status : '.';
+ key[2] = 0;
+
+ if (s->null_termination) {
+ /*
+ * In -z mode, we DO NOT C-quote pathnames. Current path is ALWAYS first.
+ * A single NUL character separates them.
+ */
+ sep_char = '\0';
+ eol_char = '\0';
+ path_index = it->string;
+ path_head = d->head_path;
+ } else {
+ /*
+ * Path(s) are C-quoted if necessary. Current path is ALWAYS first.
+ * The source path is only present when necessary.
+ * A single TAB separates them (because paths can contain spaces
+ * which are not escaped and C-quoting does escape TAB characters).
+ */
+ sep_char = '\t';
+ eol_char = '\n';
+ path_index = quote_path(it->string, s->prefix, &buf_index);
+ if (d->head_path)
+ path_head = quote_path(d->head_path, s->prefix, &buf_head);
+ }
+
+ if (path_head)
+ fprintf(s->fp, "2 %s %s %06o %06o %06o %s %s %c%d %s%c%s%c",
+ key, submodule_token,
+ d->mode_head, d->mode_index, d->mode_worktree,
+ oid_to_hex(&d->oid_head), oid_to_hex(&d->oid_index),
+ key[0], d->score,
+ path_index, sep_char, path_head, eol_char);
+ else
+ fprintf(s->fp, "1 %s %s %06o %06o %06o %s %s %s%c",
+ key, submodule_token,
+ d->mode_head, d->mode_index, d->mode_worktree,
+ oid_to_hex(&d->oid_head), oid_to_hex(&d->oid_index),
+ path_index, eol_char);
+
+ strbuf_release(&buf_index);
+ strbuf_release(&buf_head);
+}
+
+/*
+ * Print porcelain v2 status info for unmerged entries.
+ */
+static void wt_porcelain_v2_print_unmerged_entry(
+ struct string_list_item *it,
+ struct wt_status *s)
+{
+ struct wt_status_change_data *d = it->util;
+ const struct cache_entry *ce;
+ struct strbuf buf_index = STRBUF_INIT;
+ const char *path_index = NULL;
+ int pos, stage, sum;
+ struct {
+ int mode;
+ struct object_id oid;
+ } stages[3];
+ char *key;
+ char submodule_token[5];
+ char unmerged_prefix = 'u';
+ char eol_char = s->null_termination ? '\0' : '\n';
+
+ wt_porcelain_v2_submodule_state(d, submodule_token);
+
+ switch (d->stagemask) {
+ case 1: key = "DD"; break; /* both deleted */
+ case 2: key = "AU"; break; /* added by us */
+ case 3: key = "UD"; break; /* deleted by them */
+ case 4: key = "UA"; break; /* added by them */
+ case 5: key = "DU"; break; /* deleted by us */
+ case 6: key = "AA"; break; /* both added */
+ case 7: key = "UU"; break; /* both modified */
+ default:
+ die("BUG: unhandled unmerged status %x", d->stagemask);
+ }
+
+ /*
+ * Disregard d.aux.porcelain_v2 data that we accumulated
+ * for the head and index columns during the scans and
+ * replace with the actual stage data.
+ *
+ * Note that this is a last-one-wins for each the individual
+ * stage [123] columns in the event of multiple cache entries
+ * for same stage.
+ */
+ memset(stages, 0, sizeof(stages));
+ sum = 0;
+ pos = cache_name_pos(it->string, strlen(it->string));
+ assert(pos < 0);
+ pos = -pos-1;
+ while (pos < active_nr) {
+ ce = active_cache[pos++];
+ stage = ce_stage(ce);
+ if (strcmp(ce->name, it->string) || !stage)
+ break;
+ stages[stage - 1].mode = ce->ce_mode;
+ hashcpy(stages[stage - 1].oid.hash, ce->sha1);
+ sum |= (1 << (stage - 1));
+ }
+ if (sum != d->stagemask)
+ die("BUG: observed stagemask 0x%x != expected stagemask 0x%x", sum, d->stagemask);
+
+ if (s->null_termination)
+ path_index = it->string;
+ else
+ path_index = quote_path(it->string, s->prefix, &buf_index);
+
+ fprintf(s->fp, "%c %s %s %06o %06o %06o %06o %s %s %s %s%c",
+ unmerged_prefix, key, submodule_token,
+ stages[0].mode, /* stage 1 */
+ stages[1].mode, /* stage 2 */
+ stages[2].mode, /* stage 3 */
+ d->mode_worktree,
+ oid_to_hex(&stages[0].oid), /* stage 1 */
+ oid_to_hex(&stages[1].oid), /* stage 2 */
+ oid_to_hex(&stages[2].oid), /* stage 3 */
+ path_index,
+ eol_char);
+
+ strbuf_release(&buf_index);
+}
+
+/*
+ * Print porcelain V2 status info for untracked and ignored entries.
+ */
+static void wt_porcelain_v2_print_other(
+ struct string_list_item *it,
+ struct wt_status *s,
+ char prefix)
+{
+ struct strbuf buf = STRBUF_INIT;
+ const char *path;
+ char eol_char;
+
+ if (s->null_termination) {
+ path = it->string;
+ eol_char = '\0';
+ } else {
+ path = quote_path(it->string, s->prefix, &buf);
+ eol_char = '\n';
+ }
+
+ fprintf(s->fp, "%c %s%c", prefix, path, eol_char);
+
+ strbuf_release(&buf);
+}
+
+/*
+ * Print porcelain V2 status.
+ *
+ * [<v2_branch>]
+ * [<v2_changed_items>]*
+ * [<v2_unmerged_items>]*
+ * [<v2_untracked_items>]*
+ * [<v2_ignored_items>]*
+ *
+ */
+static void wt_porcelain_v2_print(struct wt_status *s)
+{
+ struct wt_status_change_data *d;
+ struct string_list_item *it;
+ int i;
+
+ if (s->show_branch)
+ wt_porcelain_v2_print_tracking(s);
+
+ for (i = 0; i < s->change.nr; i++) {
+ it = &(s->change.items[i]);
+ d = it->util;
+ if (!d->stagemask)
+ wt_porcelain_v2_print_changed_entry(it, s);
+ }
+
+ for (i = 0; i < s->change.nr; i++) {
+ it = &(s->change.items[i]);
+ d = it->util;
+ if (d->stagemask)
+ wt_porcelain_v2_print_unmerged_entry(it, s);
+ }
+
+ for (i = 0; i < s->untracked.nr; i++) {
+ it = &(s->untracked.items[i]);
+ wt_porcelain_v2_print_other(it, s, '?');
+ }
+
+ for (i = 0; i < s->ignored.nr; i++) {
+ it = &(s->ignored.items[i]);
+ wt_porcelain_v2_print_other(it, s, '!');
+ }
+}
+
+void wt_status_print(struct wt_status *s)
+{
+ switch (s->status_format) {
+ case STATUS_FORMAT_SHORT:
+ wt_shortstatus_print(s);
+ break;
+ case STATUS_FORMAT_PORCELAIN:
+ wt_porcelain_print(s);
+ break;
+ case STATUS_FORMAT_PORCELAIN_V2:
+ wt_porcelain_v2_print(s);
+ break;
+ case STATUS_FORMAT_UNSPECIFIED:
+ die("BUG: finalize_deferred_config() should have been called");
+ break;
+ case STATUS_FORMAT_NONE:
+ case STATUS_FORMAT_LONG:
+ wt_longstatus_print(s);
+ break;
+ }
+}
int worktree_status;
int index_status;
int stagemask;
+ int score;
+ int mode_head, mode_index, mode_worktree;
+ struct object_id oid_head, oid_index;
char *head_path;
unsigned dirty_submodule : 2;
unsigned new_submodule_commits : 1;
};
+enum wt_status_format {
+ STATUS_FORMAT_NONE = 0,
+ STATUS_FORMAT_LONG,
+ STATUS_FORMAT_SHORT,
+ STATUS_FORMAT_PORCELAIN,
+ STATUS_FORMAT_PORCELAIN_V2,
+
+ STATUS_FORMAT_UNSPECIFIED
+};
+
struct wt_status {
int is_initial;
char *branch;
int show_branch;
int hints;
+ enum wt_status_format status_format;
+ unsigned char sha1_commit[GIT_SHA1_RAWSZ]; /* when not Initial */
+
/* These are computed during processing of the individual sections */
int commitable;
int workdir_dirty;
int wt_status_check_bisect(const struct worktree *wt,
struct wt_status_state *state);
-void wt_shortstatus_print(struct wt_status *s);
-void wt_porcelain_print(struct wt_status *s);
-
__attribute__((format (printf, 3, 4)))
void status_printf_ln(struct wt_status *s, const char *color, const char *fmt, ...);
__attribute__((format (printf, 3, 4)))
#include "xinclude.h"
-
-
-
-static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec);
-static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb);
-
-
-
-
static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec) {
*rec = xdf->recs[ri]->ptr;