summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.mailmap9
-rw-r--r--Documentation/Makefile5
-rw-r--r--Documentation/RelNotes/1.8.0.txt257
-rw-r--r--Documentation/config.txt10
-rw-r--r--Documentation/fetch-options.txt3
-rw-r--r--Documentation/git-add.txt2
-rw-r--r--Documentation/git-branch.txt18
-rw-r--r--Documentation/git-cherry-pick.txt5
-rw-r--r--Documentation/git-clean.txt4
-rw-r--r--Documentation/git-daemon.txt16
-rw-r--r--Documentation/git-difftool.txt8
-rw-r--r--Documentation/git-grep.txt10
-rw-r--r--Documentation/git-merge-base.txt28
-rw-r--r--Documentation/git-mergetool.txt3
-rw-r--r--Documentation/git-p4.txt24
-rw-r--r--Documentation/git-push.txt10
-rw-r--r--Documentation/git-rebase.txt5
-rw-r--r--Documentation/gitattributes.txt4
-rw-r--r--Documentation/gitcli.txt12
-rw-r--r--Documentation/gitignore.txt36
-rw-r--r--Documentation/merge-strategies.txt3
-rw-r--r--Documentation/rev-list-options.txt11
-rw-r--r--Documentation/revisions.txt2
-rw-r--r--Documentation/technical/api-sha1-array.txt3
-rw-r--r--Documentation/technical/api-string-list.txt75
-rw-r--r--Documentation/urls.txt8
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--Makefile107
l---------RelNotes2
-rw-r--r--abspath.c9
-rw-r--r--archive-zip.c49
-rw-r--r--archive.c38
-rw-r--r--attr.c2
-rw-r--r--bisect.c2
-rw-r--r--builtin.h2
-rw-r--r--builtin/add.c29
-rw-r--r--builtin/apply.c2
-rw-r--r--builtin/archive.c12
-rw-r--r--builtin/bisect--helper.c6
-rw-r--r--builtin/blame.c46
-rw-r--r--builtin/branch.c150
-rw-r--r--builtin/cat-file.c20
-rw-r--r--builtin/check-attr.c12
-rw-r--r--builtin/checkout-index.c24
-rw-r--r--builtin/checkout.c312
-rw-r--r--builtin/clean.c18
-rw-r--r--builtin/clone.c60
-rw-r--r--builtin/column.c16
-rw-r--r--builtin/commit.c181
-rw-r--r--builtin/config.c56
-rw-r--r--builtin/count-objects.c4
-rw-r--r--builtin/describe.c28
-rw-r--r--builtin/fast-export.c28
-rw-r--r--builtin/fetch-pack.c169
-rw-r--r--builtin/fetch.c65
-rw-r--r--builtin/fmt-merge-msg.c16
-rw-r--r--builtin/for-each-ref.c18
-rw-r--r--builtin/fsck.c24
-rw-r--r--builtin/gc.c16
-rw-r--r--builtin/grep.c204
-rw-r--r--builtin/hash-object.c16
-rw-r--r--builtin/help.c10
-rw-r--r--builtin/index-pack.c21
-rw-r--r--builtin/init-db.c18
-rw-r--r--builtin/log.c102
-rw-r--r--builtin/ls-files.c54
-rw-r--r--builtin/ls-tree.c22
-rw-r--r--builtin/mailinfo.c28
-rw-r--r--builtin/merge-base.c34
-rw-r--r--builtin/merge-file.c20
-rw-r--r--builtin/merge.c48
-rw-r--r--builtin/mktree.c8
-rw-r--r--builtin/mv.c10
-rw-r--r--builtin/name-rev.c22
-rw-r--r--builtin/notes.c127
-rw-r--r--builtin/pack-objects.c64
-rw-r--r--builtin/pack-refs.c6
-rw-r--r--builtin/prune-packed.c6
-rw-r--r--builtin/prune.c12
-rw-r--r--builtin/push.c63
-rw-r--r--builtin/read-tree.c38
-rw-r--r--builtin/receive-pack.c8
-rw-r--r--builtin/remote.c84
-rw-r--r--builtin/replace.c12
-rw-r--r--builtin/rerere.c4
-rw-r--r--builtin/reset.c20
-rw-r--r--builtin/rev-parse.c18
-rw-r--r--builtin/revert.c38
-rw-r--r--builtin/rm.c14
-rw-r--r--builtin/shortlog.c14
-rw-r--r--builtin/show-branch.c42
-rw-r--r--builtin/show-ref.c28
-rw-r--r--builtin/symbolic-ref.c8
-rw-r--r--builtin/tag.c56
-rw-r--r--builtin/update-index.c56
-rw-r--r--builtin/update-ref.c10
-rw-r--r--builtin/update-server-info.c4
-rw-r--r--builtin/verify-pack.c6
-rw-r--r--builtin/verify-tag.c4
-rw-r--r--builtin/write-tree.c10
-rw-r--r--cache.h6
-rw-r--r--commit.c311
-rw-r--r--commit.h3
-rw-r--r--compat/mkdir.c24
-rw-r--r--compat/poll/poll.c (renamed from compat/win32/poll.c)14
-rw-r--r--compat/poll/poll.h (renamed from compat/win32/poll.h)0
-rw-r--r--config.mak.in49
-rw-r--r--configure.ac159
-rw-r--r--contrib/completion/git-completion.bash8
-rw-r--r--contrib/credential/gnome-keyring/.gitignore1
-rw-r--r--contrib/credential/gnome-keyring/Makefile24
-rw-r--r--contrib/credential/gnome-keyring/git-credential-gnome-keyring.c445
-rw-r--r--contrib/credential/wincred/Makefile14
-rw-r--r--contrib/credential/wincred/git-credential-wincred.c357
-rw-r--r--contrib/examples/builtin-fetch--tool.c2
-rw-r--r--daemon.c77
-rw-r--r--diff.c2
-rw-r--r--diff.h1
-rw-r--r--fast-import.c2
-rw-r--r--fetch-pack.h20
-rw-r--r--gettext.c15
-rw-r--r--gettext.h7
-rwxr-xr-xgit-am.sh4
-rw-r--r--git-compat-util.h33
-rwxr-xr-xgit-cvsimport.perl33
-rwxr-xr-xgit-difftool.perl305
-rw-r--r--git-mergetool--lib.sh42
-rwxr-xr-xgit-p4.py314
-rw-r--r--git-rebase--interactive.sh57
-rwxr-xr-xgit-rebase.sh13
-rwxr-xr-xgit-svn.perl92
-rwxr-xr-xgitk-git/gitk5
-rw-r--r--graph.c32
-rw-r--r--graph.h27
-rw-r--r--grep.c12
-rw-r--r--grep.h18
-rw-r--r--http-push.c3
-rw-r--r--http-walker.c4
-rw-r--r--ident.c4
-rw-r--r--ll-merge.c32
-rw-r--r--merge-recursive.c13
-rw-r--r--mergetools/codecompare25
-rw-r--r--mergetools/defaults28
-rw-r--r--notes.c14
-rw-r--r--notes.h14
-rw-r--r--parse-options.h2
-rw-r--r--path.c28
-rw-r--r--perl/Git/SVN.pm183
-rw-r--r--perl/Git/SVN/Editor.pm25
-rw-r--r--perl/Git/SVN/Fetcher.pm2
-rw-r--r--perl/Git/SVN/GlobSpec.pm4
-rw-r--r--perl/Git/SVN/Migration.pm6
-rw-r--r--perl/Git/SVN/Ra.pm94
-rw-r--r--perl/Git/SVN/Utils.pm175
-rw-r--r--po/TEAMS3
-rw-r--r--po/de.po712
-rw-r--r--po/git.pot4504
-rw-r--r--po/sv.po4702
-rw-r--r--po/vi.po1767
-rw-r--r--po/zh_CN.po4785
-rw-r--r--read-cache.c2
-rw-r--r--remote-curl.c9
-rw-r--r--rerere.c2
-rw-r--r--rerere.h1
-rw-r--r--revision.c37
-rw-r--r--sequencer.c70
-rw-r--r--sequencer.h8
-rw-r--r--sha1-array.c2
-rw-r--r--sha1-array.h1
-rw-r--r--strbuf.c13
-rw-r--r--strbuf.h4
-rw-r--r--string-list.c127
-rw-r--r--string-list.h71
-rw-r--r--submodule.c12
-rw-r--r--symlinks.c7
-rw-r--r--t/Git-SVN/Utils/add_path_to_url.t27
-rw-r--r--t/Git-SVN/Utils/canonicalize_url.t26
-rw-r--r--t/Git-SVN/Utils/collapse_dotdot.t23
-rw-r--r--t/Git-SVN/Utils/join_paths.t32
-rwxr-xr-xt/lib-credential.sh4
-rw-r--r--t/lib-git-p4.sh24
-rw-r--r--t/perf/perf-lib.sh1
-rwxr-xr-xt/t0000-basic.sh28
-rwxr-xr-xt/t0006-date.sh2
-rwxr-xr-xt/t0040-parse-options.sh34
-rwxr-xr-xt/t0060-path-utils.sh59
-rwxr-xr-xt/t0063-string-list.sh121
-rwxr-xr-xt/t1300-repo-config.sh2
-rwxr-xr-xt/t1450-fsck.sh4
-rwxr-xr-xt/t1502-rev-parse-parseopt.sh2
-rwxr-xr-xt/t2006-checkout-index-basic.sh4
-rwxr-xr-xt/t2107-update-index-basic.sh4
-rwxr-xr-xt/t3004-ls-files-basic.sh4
-rwxr-xr-xt/t3200-branch.sh74
-rwxr-xr-xt/t3300-funny-names.sh24
-rwxr-xr-xt/t3404-rebase-interactive.sh29
-rwxr-xr-xt/t3501-revert-cherry-pick.sh4
-rwxr-xr-xt/t3505-cherry-pick-empty.sh5
-rwxr-xr-xt/t3507-cherry-pick-conflict.sh32
-rwxr-xr-xt/t3510-cherry-pick-sequence.sh6
-rwxr-xr-xt/t3902-quoted.sh31
-rwxr-xr-xt/t3903-stash.sh2
-rwxr-xr-xt/t4006-diff-mode.sh8
-rwxr-xr-xt/t4012-diff-binary.sh4
-rwxr-xr-xt/t4016-diff-quote.sh20
-rwxr-xr-xt/t4018-diff-funcname.sh2
-rwxr-xr-xt/t4034-diff-words.sh1
-rw-r--r--t/t4034/ada/expect27
-rw-r--r--t/t4034/ada/post13
-rw-r--r--t/t4034/ada/pre13
-rwxr-xr-xt/t4120-apply-popt.sh4
-rwxr-xr-xt/t4133-apply-filenames.sh4
-rwxr-xr-xt/t4200-rerere.sh4
-rwxr-xr-xt/t4202-log.sh2
-rwxr-xr-xt/t4205-log-pretty-formats.sh4
-rwxr-xr-xt/t5300-pack-object.sh4
-rwxr-xr-xt/t5400-send-pack.sh5
-rwxr-xr-xt/t5500-fetch-pack.sh47
-rwxr-xr-xt/t5505-remote.sh28
-rwxr-xr-xt/t5530-upload-pack-error.sh4
-rwxr-xr-xt/t5541-http-push.sh5
-rwxr-xr-xt/t5550-http-fetch.sh2
-rwxr-xr-xt/t5551-http-fetch.sh12
-rwxr-xr-xt/t5800-remote-helpers.sh2
-rwxr-xr-xt/t6037-merge-ours-theirs.sh14
-rwxr-xr-xt/t6500-gc.sh4
-rwxr-xr-xt/t7508-status.sh2
-rwxr-xr-xt/t7600-merge.sh2
-rwxr-xr-xt/t7610-mergetool.sh13
-rwxr-xr-xt/t7800-difftool.sh11
-rwxr-xr-xt/t7810-grep.sh223
-rwxr-xr-xt/t9107-git-svn-migrate.sh6
-rwxr-xr-xt/t9118-git-svn-funky-branch-names.sh9
-rwxr-xr-xt/t9154-git-svn-fancy-glob.sh9
-rwxr-xr-xt/t9164-git-svn-dcommit-concurrent.sh (renamed from t/t9164-git-svn-dcommit-concrrent.sh)8
-rwxr-xr-xt/t9165-git-svn-fetch-merge-branch-of-branch.sh60
-rwxr-xr-xt/t9166-git-svn-fetch-merge-branch-of-branch2.sh53
-rwxr-xr-xt/t9801-git-p4-branch.sh77
-rwxr-xr-xt/t9805-git-p4-skip-submit-edit.sh2
-rwxr-xr-xt/t9807-git-p4-submit.sh65
-rwxr-xr-xt/t9809-git-p4-client-view.sh17
-rwxr-xr-xt/t9810-git-p4-rcs.sh50
-rwxr-xr-xt/t9815-git-p4-submit-fail.sh429
-rwxr-xr-xt/t9902-completion.sh60
-rw-r--r--t/test-lib-functions.sh21
-rw-r--r--t/test-lib.sh133
-rw-r--r--test-string-list.c123
-rw-r--r--trace.c2
-rw-r--r--transport.c12
-rw-r--r--transport.h1
-rw-r--r--userdiff.c9
-rw-r--r--wt-status.c52
-rw-r--r--wt-status.h2
254 files changed, 20275 insertions, 5506 deletions
diff --git a/.gitignore b/.gitignore
index 68fe464..a188a82 100644
--- a/.gitignore
+++ b/.gitignore
@@ -194,6 +194,7 @@
/test-run-command
/test-sha1
/test-sigchain
+/test-string-list
/test-subprocess
/test-svn-fe
/common-cmds.h
diff --git a/.mailmap b/.mailmap
index 6303782..bcf4f87 100644
--- a/.mailmap
+++ b/.mailmap
@@ -18,6 +18,7 @@ David Kågedal <davidk@lysator.liu.se>
David S. Miller <davem@davemloft.net>
Deskin Miller <deskinm@umich.edu>
Dirk Süsserott <newsletter@dirk.my1.cc>
+Erik Faye-Lund <kusmabite@gmail.com> <kusmabite@googlemail.com>
Fredrik Kuivinen <freku045@student.liu.se>
H. Peter Anvin <hpa@bonde.sc.orionmulti.com>
H. Peter Anvin <hpa@tazenda.sc.orionmulti.com>
@@ -26,6 +27,9 @@ Horst H. von Brand <vonbrand@inf.utfsm.cl>
İsmail Dönmez <ismail@pardus.org.tr>
Jay Soffian <jaysoffian+git@gmail.com>
Joachim Berdal Haga <cjhaga@fys.uio.no>
+Johannes Sixt <j6t@kdbg.org> <johannes.sixt@telecom.at>
+Johannes Sixt <j6t@kdbg.org> <j.sixt@viscovery.net>
+Johannes Sixt <j6t@kdbg.org> <J.Sixt@eudaptics.com>
Jon Loeliger <jdl@freescale.com>
Jon Seymour <jon@blackcubes.dyndns.org>
Jonathan Nieder <jrnieder@uchicago.edu>
@@ -43,6 +47,7 @@ Lars Doelle <lars.doelle@on-line.de>
Li Hong <leehong@pku.edu.cn>
Lukas Sandström <lukass@etek.chalmers.se>
Martin Langhoff <martin@laptop.org>
+Martin von Zweigbergk <martinvonz@gmail.com> <martin.von.zweigbergk@gmail.com>
Michael Coleman <tutufan@gmail.com>
Michael J Gruber <git@drmicha.warpmail.net> <michaeljgruber+gmane@fastmail.fm>
Michael W. Olson <mwolson@gnu.org>
@@ -51,7 +56,10 @@ Nanako Shiraishi <nanako3@bluebottle.com>
Nanako Shiraishi <nanako3@lavabit.com>
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
<nico@fluxnic.net> <nico@cam.org>
+Peter Krefting <peter@softwolves.pp.se> <peter@svarten.intern.softwolves.pp.se>
+Peter Krefting <peter@softwolves.pp.se> <peter@softwolves.pp.se>
Philippe Bruhat <book@cpan.org>
+Ralf Thielow <ralf.thielow@gmail.com> <ralf.thielow@googlemail.com>
Ramsay Allan Jones <ramsay@ramsay1.demon.co.uk>
René Scharfe <rene.scharfe@lsrfire.ath.cx>
Robert Fitzsimons <robfitz@273k.net>
@@ -61,6 +69,7 @@ Sean Estabrooks <seanlkml@sympatico.ca>
Shawn O. Pearce <spearce@spearce.org>
Steven Grimm <koreth@midwinter.com>
Theodore Ts'o <tytso@mit.edu>
+Thomas Rast <trast@inf.ethz.ch> <trast@student.ethz.ch>
Tony Luck <tony.luck@intel.com>
Uwe Kleine-König <Uwe_Zeisberger@digi.com>
Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
diff --git a/Documentation/Makefile b/Documentation/Makefile
index cf5916f..267dfe1 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -44,9 +44,10 @@ man5dir=$(mandir)/man5
man7dir=$(mandir)/man7
# DESTDIR=
-ASCIIDOC=asciidoc
+ASCIIDOC = asciidoc
ASCIIDOC_EXTRA =
MANPAGE_XSL = manpage-normal.xsl
+XMLTO = xmlto
XMLTO_EXTRA =
INSTALL?=install
RM ?= rm -f
@@ -245,7 +246,7 @@ manpage-base-url.xsl: manpage-base-url.xsl.in
%.1 %.5 %.7 : %.xml manpage-base-url.xsl
$(QUIET_XMLTO)$(RM) $@ && \
- xmlto -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
+ $(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
%.xml : %.txt
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
diff --git a/Documentation/RelNotes/1.8.0.txt b/Documentation/RelNotes/1.8.0.txt
new file mode 100644
index 0000000..6a6f323
--- /dev/null
+++ b/Documentation/RelNotes/1.8.0.txt
@@ -0,0 +1,257 @@
+Git v1.8.0 Release Notes
+========================
+
+Backward compatibility notes
+----------------------------
+
+In the next major release, we will change the behavior of the "git
+push" command. When "git push [$there]" does not say what to push, we
+have used the traditional "matching" semantics so far (all your branches were
+sent to the remote as long as there already are branches of the same
+name over there). We will now use the "simple" semantics, that pushes the
+current branch to the branch with the same name only when the current
+branch is set to integrate with that remote branch. There is a user
+preference configuration variable "push.default" to change this, and
+"git push" will warn about the upcoming change until you set this
+variable.
+
+"git branch --set-upstream" is deprecated and may be removed in a
+relatively distant future. "git branch [-u|--set-upstream-to]" has
+been introduced with a saner order of arguments.
+
+
+Updates since v1.7.12
+---------------------
+
+UI, Workflows & Features
+
+ * A credential helper for Win32 to allow access to the keychain of
+ the logged-in user has been added.
+
+ * An initial port to HP NonStop.
+
+ * A credential helper to allow access to the Gnome keyring has been
+ added.
+
+ * When "git am" sanitizes the "Subject:" line, we strip the prefix from
+ "Re: subject" and also from a less common "re: subject", but left
+ the even less common "RE: subject" intact. We strip that now, too.
+
+ * It was tempting to say "git branch --set-upstream origin/master",
+ but that tells Git to arrange the local branch "origin/master" to
+ integrate with the currently checked out branch, which is highly
+ unlikely what the user meant. The option is deprecated; use the
+ new "--set-upstream-to" (with a short-and-sweet "-u") option
+ instead.
+
+ * "git cherry-pick" learned the "--allow-empty-message" option to
+ allow it to replay a commit without any log message.
+
+ * After "git cherry-pick -s" gave control back to the user asking
+ help to resolve conflicts, concluding "git commit" used to need to
+ be run with "-s" if the user wants to sign it off; now the command
+ leaves the sign-off line in the log template.
+
+ * "git daemon" learned the "--access-hook" option to allow an
+ external command to decline service based on the client address,
+ repository path, etc.
+
+ * "git difftool --dir-diff" learned to use symbolic links to prepare
+ a temporary copy of the working tree when available.
+
+ * "git grep" learned to use a non-standard pattern type by default if
+ a configuration variable tells it to.
+
+ * "git log -g" learned the "--grep-reflog=<pattern>" option to limit
+ its output to commits with a reflog message that matches the given
+ pattern.
+
+ * "git merge-base" learned the "--is-ancestor A B" option to tell if A is
+ an ancestor of B. The result is indicated by its exit status code.
+
+ * "git mergetool" now allows users to override the actual command used
+ with the mergetool.$name.cmd configuration variable even for built-in
+ mergetool backends.
+
+ * The "-Xours" backend option to "git merge -s recursive" now takes
+ effect even on binary files.
+
+ * "git rebase -i" learned the "--edit-todo" option to open an editor
+ to edit the instruction sheet.
+
+
+Foreign Interface
+
+ * "git svn" has been updated to work with SVN 1.7.
+
+ * "git p4" learned the "--conflicts" option to specify what to do when
+ encountering a conflict during "p4 submit".
+
+
+Performance, Internal Implementation, etc. (please report possible regressions)
+
+ * Git ships with a fall-back regexp implementation for platforms with
+ buggy regexp library, but it was easy for people to keep using their
+ platform regexp by mistake. A new test has been added to check this.
+
+ * The "check-docs" build target has been updated and greatly
+ simplified.
+
+ * The test suite is run under MALLOC_CHECK_ when running with a glibc
+ that supports the feature.
+
+ * The documentation in the TeXinfo format was using indented output
+ for materials meant to be examples that are better typeset in
+ monospace.
+
+ * Compatibility wrapper around some mkdir(2) implementations that
+ reject parameters with trailing slash has been introduced.
+
+ * Compatibility wrapper for systems that lack usable setitimer() has
+ been added.
+
+ * The option parsing of "git checkout" had error checking, dwim and
+ defaulting missing options, all mixed in the code, and issuing an
+ appropriate error message with useful context was getting harder.
+ The code has been reorganized to allow giving a proper diagnosis
+ when the user says "git checkout -b -t foo bar" (e.g. "-t" is not a
+ good name for a branch).
+
+ * Many internal uses of a "git merge-base" equivalent were only to see
+ if one commit fast-forwards to the other, which did not need the
+ full set of merge bases to be computed. They have been updated to
+ use less expensive checks.
+
+ * The heuristics to detect and silently convert latin1 to utf8 when
+ we were told to use utf-8 in the log message has been transplanted
+ from "mailinfo" to "commit" and "commit-tree".
+
+ * Messages given by "git <subcommand> -h" from many subcommands have
+ been marked for translation.
+
+
+Also contains minor documentation updates and code clean-ups.
+
+
+Fixes since v1.7.12
+-------------------
+
+Unless otherwise noted, all the fixes since v1.7.12 in the
+maintenance track are contained in this release (see release notes
+to them for details).
+
+ * The attribute system may be asked for a path that itself or its
+ leading directories no longer exists in the working tree, and it is
+ fine if we cannot open .gitattribute file in such a case. Failure
+ to open per-directory .gitattributes with error status other than
+ ENOENT and ENOTDIR should be diagnosed, but it wasn't.
+
+ * When looking for $HOME/.gitconfig etc., it is OK if we cannot read
+ them because they do not exist, but we did not diagnose existing
+ files that we cannot read.
+
+ * When "git am" is fed an input that has multiple "Content-type: ..."
+ header, it did not grok charset= attribute correctly.
+
+ * "git am" mishandled a patch attached as application/octet-stream
+ (e.g. not text/*); Content-Transfer-Encoding (e.g. base64) was not
+ honored correctly.
+
+ * "git blame MAKEFILE" run in a history that has "Makefile" but not
+ "MAKEFILE" should say "No such file MAKEFILE in HEAD", but got
+ confused on a case insensitive filesystem and failed to do so.
+
+ * Even during a conflicted merge, "git blame $path" always meant to
+ blame uncommitted changes to the "working tree" version; make it
+ more useful by showing cleanly merged parts as coming from the other
+ branch that is being merged.
+
+ * It was unclear in the documentation for "git blame" that it is
+ unnecessary for users to use the "--follow" option.
+
+ * Output from "git branch -v" contains "(no branch)" that could be
+ localized, but the code to align it along with the names of
+ branches was counting in bytes, not in display columns.
+
+ * "git cherry-pick A C B" used to replay changes in A and then B and
+ then C if these three commits had committer timestamps in that
+ order, which is not what the user who said "A C B" naturally
+ expects.
+
+ * A repository created with "git clone --single" had its fetch
+ refspecs set up just like a clone without "--single", leading the
+ subsequent "git fetch" to slurp all the other branches, defeating
+ the whole point of specifying "only this branch".
+
+ * Documentation talked about "first line of commit log" when it meant
+ the title of the commit. The description was clarified by defining
+ how the title is decided and rewording the casual mention of "first
+ line" to "title".
+
+ * "git cvsimport" did not thoroughly cleanse tag names that it
+ inferred from the names of the tags it obtained from CVS, which
+ caused "git tag" to barf and stop the import in the middle.
+
+ * Earlier we made the diffstat summary line that shows the number of
+ lines added/deleted localizable, but it was found irritating having
+ to see them in various languages on a list whose discussion language
+ is English, and this change has been reverted.
+
+ * "git fetch --all", when passed "--no-tags", did not honor the
+ "--no-tags" option while fetching from individual remotes (the same
+ issue existed with "--tags", but the combination "--all --tags" makes
+ much less sense than "--all --no-tags").
+
+ * "git fetch" over http had an old workaround for an unlikely server
+ misconfiguration; it turns out that this hurts debuggability of the
+ configuration in general, and has been reverted.
+
+ * "git fetch" over http advertised that it supports "deflate", which
+ is much less common, and did not advertise the more common "gzip" on
+ its Accept-Encoding header.
+
+ * "git gc --auto" notified the user that auto-packing has triggered
+ even under the "--quiet" option.
+
+ * After "gitk" showed the contents of a tag, neither "Reread
+ references" nor "Reload" updated what is shown as the
+ contents of it when the user overwrote the tag with "git tag -f".
+
+ * "git log --all-match --grep=A --grep=B" ought to show commits that
+ mention both A and B, but when these three options are used with
+ --author or --committer, it showed commits that mention either A or
+ B (or both) instead.
+
+ * "git p4", when "--use-client-spec" and "--detect-branches" are used
+ together, misdetected branches.
+
+ * "git receive-pack" (the counterpart to "git push") did not give
+ progress output while processing objects it received to the puser
+ when run over the smart-http protocol.
+
+ * When you misspell the command name you give to the "exec" action in
+ the "git rebase -i" instruction sheet you were told that 'rebase' is not a
+ git subcommand from "git rebase --continue".
+
+ * The subcommand in "git remote" to remove a defined remote was
+ "rm" and the command did not take a fully-spelled "remove".
+
+ * The interactive prompt that "git send-email" gives was error prone. It
+ asked "What e-mail address do you want to use?" with the address it
+ guessed (correctly) the user would want to use in its prompt,
+ tempting the user to say "y". But the response was taken as "No,
+ please use 'y' as the e-mail address instead", which is most
+ certainly not what the user meant.
+
+ * "git show --format='%ci'" did not give the timestamp correctly for
+ commits created without human readable name on the "committer" line.
+
+ * "git show --quiet" ought to be a synonym for "git show -s", but
+ wasn't.
+
+ * "git submodule frotz" was not diagnosed as "frotz" being an unknown
+ subcommand to "git submodule"; the user instead got a complaint
+ that "git submodule status" was run with an unknown path "frotz".
+
+ * "git status" honored the ignore=dirty settings in .gitmodules but
+ "git commit" didn't.
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 122e3c4..11f320b 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1211,8 +1211,16 @@ gitweb.snapshot::
grep.lineNumber::
If set to true, enable '-n' option by default.
+grep.patternType::
+ Set the default matching behavior. Using a value of 'basic', 'extended',
+ 'fixed', or 'perl' will enable the '--basic-regexp', '--extended-regexp',
+ '--fixed-strings', or '--perl-regexp' option accordingly, while the
+ value 'default' will return to the default matching behavior.
+
grep.extendedRegexp::
- If set to true, enable '--extended-regexp' option by default.
+ If set to true, enable '--extended-regexp' option by default. This
+ option is ignored when the 'grep.patternType' option is set to a value
+ other than 'default'.
gpg.program::
Use this custom program instead of "gpg" found on $PATH when
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 39d326a..b4d6476 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -10,7 +10,8 @@
--depth=<depth>::
Deepen the history of a 'shallow' repository created by
`git clone` with `--depth=<depth>` option (see linkgit:git-clone[1])
- by the specified number of commits.
+ to the specified number of commits from the tip of each remote
+ branch history. Tags for the deepened commits are not fetched.
ifndef::git-pull[]
--dry-run::
diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 9c1d395..fd9e36b 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -155,7 +155,7 @@ Configuration
The optional configuration variable `core.excludesfile` indicates a path to a
file containing patterns of file names to exclude from git-add, similar to
$GIT_DIR/info/exclude. Patterns in the exclude file are used in addition to
-those in info/exclude. See linkgit:gitrepository-layout[5].
+those in info/exclude. See linkgit:gitignore[5].
EXAMPLES
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 47235be..45a225e 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -13,6 +13,8 @@ SYNOPSIS
[--column[=<options>] | --no-column]
[(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
+'git branch' (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>]
+'git branch' --unset-upstream [<branchname>]
'git branch' (-m | -M) [<oldbranch>] <newbranch>
'git branch' (-d | -D) [-r] <branchname>...
'git branch' --edit-description [<branchname>]
@@ -48,7 +50,7 @@ branch so that 'git pull' will appropriately merge from
the remote-tracking branch. This behavior may be changed via the global
`branch.autosetupmerge` configuration flag. That setting can be
overridden by using the `--track` and `--no-track` options, and
-changed later using `git branch --set-upstream`.
+changed later using `git branch --set-upstream-to`.
With a `-m` or `-M` option, <oldbranch> will be renamed to <newbranch>.
If <oldbranch> had a corresponding reflog, it is renamed to match
@@ -129,11 +131,13 @@ This option is only applicable in non-verbose mode.
use `git branch --list <pattern>` to list matching branches.
-v::
+-vv::
--verbose::
When in list mode,
show sha1 and commit subject line for each head, along with
relationship to upstream branch (if any). If given twice, print
- the name of the upstream branch, as well.
+ the name of the upstream branch, as well (see also `git remote
+ show <remote>`).
-q::
--quiet::
@@ -173,6 +177,16 @@ start-point is either a local or remote-tracking branch.
like `--track` would when creating the branch, except that where
branch points to is not changed.
+-u <upstream>::
+--set-upstream-to=<upstream>::
+ Set up <branchname>'s tracking information so <upstream> is
+ considered <branchname>'s upstream branch. If no <branchname>
+ is specified, then it defaults to the current branch.
+
+--unset-upstream::
+ Remove the upstream information for <branchname>. If no branch
+ is specified it defaults to the current branch.
+
--edit-description::
Open an editor and edit the text to explain what the branch is
for, to be used by various other commands (e.g. `request-pull`).
diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index 0e170a5..c205d23 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt
@@ -118,6 +118,11 @@ effect to your index in a row.
previous commit are dropped. To force the inclusion of those commits
use `--keep-redundant-commits`.
+--allow-empty-message::
+ By default, cherry-picking a commit with an empty message will fail.
+ This option overrides that behaviour, allowing commits with empty
+ messages to be cherry picked.
+
--keep-redundant-commits::
If a commit being cherry picked duplicates a commit already in the
current history, it will become empty. By default these
diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt
index 79fb984..9f42c0d 100644
--- a/Documentation/git-clean.txt
+++ b/Documentation/git-clean.txt
@@ -63,6 +63,10 @@ OPTIONS
Remove only files ignored by git. This may be useful to rebuild
everything from scratch, but keep manually created files.
+SEE ALSO
+--------
+linkgit:gitignore[5]
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index e8f7577..7e5098a 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -16,6 +16,7 @@ SYNOPSIS
[--reuseaddr] [--detach] [--pid-file=<file>]
[--enable=<service>] [--disable=<service>]
[--allow-override=<service>] [--forbid-override=<service>]
+ [--access-hook=<path>]
[--inetd | [--listen=<host_or_ipaddr>] [--port=<n>] [--user=<user> [--group=<group>]]
[<directory>...]
@@ -171,6 +172,21 @@ the facility of inet daemon to achieve the same before spawning
errors are not enabled, all errors report "access denied" to the
client. The default is --no-informative-errors.
+--access-hook=<path>::
+ Every time a client connects, first run an external command
+ specified by the <path> with service name (e.g. "upload-pack"),
+ path to the repository, hostname (%H), canonical hostname
+ (%CH), ip address (%IP), and tcp port (%P) as its command line
+ arguments. The external command can decide to decline the
+ service by exiting with a non-zero status (or to allow it by
+ exiting with a zero status). It can also look at the $REMOTE_ADDR
+ and $REMOTE_PORT environment variables to learn about the
+ requestor when making this decision.
++
+The external command can optionally write a single line to its
+standard output to be sent to the requestor as an error message when
+it declines the service.
+
<directory>::
A directory to add to the whitelist of allowed directories. Unless
--strict-paths is specified this will also include subdirectories
diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt
index 31fc2e3..73ca702 100644
--- a/Documentation/git-difftool.txt
+++ b/Documentation/git-difftool.txt
@@ -69,6 +69,14 @@ with custom merge tool commands and has the same value as `$MERGED`.
--tool-help::
Print a list of diff tools that may be used with `--tool`.
+--symlinks::
+--no-symlinks::
+ 'git difftool''s default behavior is create symlinks to the
+ working tree when run in `--dir-diff` mode.
++
+ Specifying `--no-symlinks` instructs 'git difftool' to create
+ copies instead. `--no-symlinks` is the default on Windows.
+
-x <command>::
--extcmd=<command>::
Specify a custom command for viewing diffs.
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index 3bec036..cfecf84 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -42,8 +42,16 @@ CONFIGURATION
grep.lineNumber::
If set to true, enable '-n' option by default.
+grep.patternType::
+ Set the default matching behavior. Using a value of 'basic', 'extended',
+ 'fixed', or 'perl' will enable the '--basic-regexp', '--extended-regexp',
+ '--fixed-strings', or '--perl-regexp' option accordingly, while the
+ value 'default' will return to the default matching behavior.
+
grep.extendedRegexp::
- If set to true, enable '--extended-regexp' option by default.
+ If set to true, enable '--extended-regexp' option by default. This
+ option is ignored when the 'grep.patternType' option is set to a value
+ other than 'default'.
OPTIONS
diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt
index b295bf8..87842e3 100644
--- a/Documentation/git-merge-base.txt
+++ b/Documentation/git-merge-base.txt
@@ -11,6 +11,7 @@ SYNOPSIS
[verse]
'git merge-base' [-a|--all] <commit> <commit>...
'git merge-base' [-a|--all] --octopus <commit>...
+'git merge-base' --is-ancestor <commit> <commit>
'git merge-base' --independent <commit>...
DESCRIPTION
@@ -50,6 +51,12 @@ from linkgit:git-show-branch[1] when used with the `--merge-base` option.
from any other. This mimics the behavior of 'git show-branch
--independent'.
+--is-ancestor::
+ Check if the first <commit> is an ancestor of the second <commit>,
+ and exit with status 0 if true, or with status 1 if not.
+ Errors are signaled by a non-zero status that is not 1.
+
+
OPTIONS
-------
-a::
@@ -110,6 +117,27 @@ both '1' and '2' are merge-bases of A and B. Neither one is better than
the other (both are 'best' merge bases). When the `--all` option is not given,
it is unspecified which best one is output.
+A common idiom to check "fast-forward-ness" between two commits A
+and B is (or at least used to be) to compute the merge base between
+A and B, and check if it is the same as A, in which case, A is an
+ancestor of B. You will see this idiom used often in older scripts.
+
+ A=$(git rev-parse --verify A)
+ if test "$A" = "$(git merge-base A B)"
+ then
+ ... A is an ancestor of B ...
+ fi
+
+In modern git, you can say this in a more direct way:
+
+ if git merge-base --is-ancestor A B
+ then
+ ... A is an ancestor of B ...
+ fi
+
+instead.
+
+
See also
--------
linkgit:git-rev-list[1],
diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt
index d7207bd..6b563c5 100644
--- a/Documentation/git-mergetool.txt
+++ b/Documentation/git-mergetool.txt
@@ -64,6 +64,9 @@ variable `mergetool.<tool>.trustExitCode` can be set to `true`.
Otherwise, 'git mergetool' will prompt the user to indicate the
success of the resolution after the custom tool has exited.
+--tool-help::
+ Print a list of merge tools that may be used with `--tool`.
+
-y::
--no-prompt::
Don't prompt before each invocation of the merge resolution
diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt
index 8228f33..beff622 100644
--- a/Documentation/git-p4.txt
+++ b/Documentation/git-p4.txt
@@ -163,7 +163,7 @@ All commands except clone accept these options.
--git-dir <dir>::
Set the 'GIT_DIR' environment variable. See linkgit:git[1].
---verbose::
+--verbose, -v::
Provide more progress information.
Sync options
@@ -269,6 +269,24 @@ These options can be used to modify 'git p4 submit' behavior.
Export tags from git as p4 labels. Tags found in git are applied
to the perforce working directory.
+--dry-run, -n::
+ Show just what commits would be submitted to p4; do not change
+ state in git or p4.
+
+--prepare-p4-only::
+ Apply a commit to the p4 workspace, opening, adding and deleting
+ files in p4 as for a normal submit operation. Do not issue the
+ final "p4 submit", but instead print a message about how to
+ submit manually or revert. This option always stops after the
+ first (oldest) commit. Git tags are not exported to p4.
+
+--conflict=(ask|skip|quit)::
+ Conflicts can occur when applying a commit to p4. When this
+ happens, the default behavior ("ask") is to prompt whether to
+ skip this commit and continue, or quit. This option can be used
+ to bypass the prompt, causing conflicting commits to be automatically
+ skipped, or to quit trying to apply commits, without prompting.
+
Rebase options
~~~~~~~~~~~~~~
These options can be used to modify 'git p4 rebase' behavior.
@@ -519,6 +537,10 @@ git-p4.labelExportRegexp::
Only p4 labels matching this regular expression will be exported. The
default value is '[a-zA-Z0-9_\-.]+$'.
+git-p4.conflict::
+ Specify submit behavior when a conflict with p4 is found, as per
+ --conflict. The default behavior is 'ask'.
+
IMPLEMENTATION DETAILS
----------------------
* Changesets from p4 are imported using git fast-import.
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index cb97cc1..22d2580 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -37,7 +37,9 @@ OPTIONS[[OPTIONS]]
`+`, followed by the source ref <src>, followed
by a colon `:`, followed by the destination ref <dst>.
It is used to specify with what <src> object the <dst> ref
- in the remote repository is to be updated.
+ in the remote repository is to be updated. If not specified,
+ the behavior of the command is controlled by the `push.default`
+ configuration variable.
+
The <src> is often the name of the branch you would want to push, but
it can be any arbitrary "SHA-1 expression", such as `master~4` or
@@ -65,7 +67,8 @@ directs git to push "matching" branches: for every branch that exists on
the local side, the remote side is updated if a branch of the same name
already exists on the remote side. This is the default operation mode
if no explicit refspec is found (that is neither on the command line
-nor in any Push line of the corresponding remotes file---see below).
+nor in any Push line of the corresponding remotes file---see below) and
+no `push.default` configuration variable is set.
--all::
Instead of naming each ref to push, specifies that all
@@ -357,7 +360,8 @@ Examples
`git push origin :`.
+
The default behavior of this command when no <refspec> is given can be
-configured by setting the `push` option of the remote.
+configured by setting the `push` option of the remote, or the `push.default`
+configuration variable.
+
For example, to default to pushing only the current branch to `origin`
use `git config remote.origin.push HEAD`. Any valid <refspec> (like
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index fd535b0..da067ec 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -12,7 +12,7 @@ SYNOPSIS
[<upstream>] [<branch>]
'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
--root [<branch>]
-'git rebase' --continue | --skip | --abort
+'git rebase' --continue | --skip | --abort | --edit-todo
DESCRIPTION
-----------
@@ -245,6 +245,9 @@ leave out at most one of A and B, in which case it defaults to HEAD.
--skip::
Restart the rebasing process by skipping the current patch.
+--edit-todo::
+ Edit the todo list during an interactive rebase.
+
-m::
--merge::
Use merging strategies to rebase. When the recursive (default) merge
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index aff760e..ba02d4d 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -516,6 +516,8 @@ configuration file (you still need to enable this with the
attribute mechanism, via `.gitattributes`). The following built in
patterns are available:
+- `ada` suitable for source code in the Ada language.
+
- `bibtex` suitable for files with BibTeX coded references.
- `cpp` suitable for source code in the C and C++ languages.
@@ -932,7 +934,7 @@ file at the toplevel (i.e. not in any subdirectory). The built-in
macro attribute "binary" is equivalent to:
------------
-[attr]binary -diff -text
+[attr]binary -diff -merge -text
------------
diff --git a/Documentation/gitcli.txt b/Documentation/gitcli.txt
index f6ba90c..3bc1500 100644
--- a/Documentation/gitcli.txt
+++ b/Documentation/gitcli.txt
@@ -93,7 +93,7 @@ ENHANCED OPTION PARSER
From the git 1.5.4 series and further, many git commands (not all of them at the
time of the writing though) come with an enhanced option parser.
-Here is an exhaustive list of the facilities provided by this option parser.
+Here is a list of the facilities provided by this option parser.
Magic Options
@@ -137,6 +137,16 @@ options. This means that you can for example use `git rm -rf` or
`git clean -fdx`.
+Abbreviating long options
+~~~~~~~~~~~~~~~~~~~~~~~~~
+Commands that support the enhanced option parser accepts unique
+prefix of a long option as if it is fully spelled out, but use this
+with a caution. For example, `git commit --amen` behaves as if you
+typed `git commit --amend`, but that is true only until a later version
+of Git introduces another option that shares the same prefix,
+e.g `git commit --amenity" option.
+
+
Separating argument from the option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can write the mandatory option parameter to an option as a separate
diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index c1f692a..1b82fe1 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -41,18 +41,24 @@ precedence, the last matching pattern decides the outcome):
variable 'core.excludesfile'.
Which file to place a pattern in depends on how the pattern is meant to
-be used. Patterns which should be version-controlled and distributed to
-other repositories via clone (i.e., files that all developers will want
-to ignore) should go into a `.gitignore` file. Patterns which are
-specific to a particular repository but which do not need to be shared
-with other related repositories (e.g., auxiliary files that live inside
-the repository but are specific to one user's workflow) should go into
-the `$GIT_DIR/info/exclude` file. Patterns which a user wants git to
-ignore in all situations (e.g., backup or temporary files generated by
-the user's editor of choice) generally go into a file specified by
-`core.excludesfile` in the user's `~/.gitconfig`. Its default value is
-$XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is either not set or empty,
-$HOME/.config/git/ignore is used instead.
+be used.
+
+ * Patterns which should be version-controlled and distributed to
+ other repositories via clone (i.e., files that all developers will want
+ to ignore) should go into a `.gitignore` file.
+
+ * Patterns which are
+ specific to a particular repository but which do not need to be shared
+ with other related repositories (e.g., auxiliary files that live inside
+ the repository but are specific to one user's workflow) should go into
+ the `$GIT_DIR/info/exclude` file.
+
+ * Patterns which a user wants git to
+ ignore in all situations (e.g., backup or temporary files generated by
+ the user's editor of choice) generally go into a file specified by
+ `core.excludesfile` in the user's `~/.gitconfig`. Its default value is
+ $XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is either not set or
+ empty, $HOME/.config/git/ignore is used instead.
The underlying git plumbing tools, such as
'git ls-files' and 'git read-tree', read
@@ -68,11 +74,15 @@ PATTERN FORMAT
for readability.
- A line starting with # serves as a comment.
+ Put a backslash ("`\`") in front of the first hash for patterns
+ that begin with a hash.
- - An optional prefix '!' which negates the pattern; any
+ - An optional prefix "`!`" which negates the pattern; any
matching file excluded by a previous pattern will become
included again. If a negated pattern matches, this will
override lower precedence patterns sources.
+ Put a backslash ("`\`") in front of the first "`!`" for patterns
+ that begin with a literal "`!`", for example, "`\!important!.txt`".
- If the pattern ends with a slash, it is removed for the
purpose of the following description, but it would only find
diff --git a/Documentation/merge-strategies.txt b/Documentation/merge-strategies.txt
index 595a3cf..66db802 100644
--- a/Documentation/merge-strategies.txt
+++ b/Documentation/merge-strategies.txt
@@ -32,13 +32,14 @@ ours;;
This option forces conflicting hunks to be auto-resolved cleanly by
favoring 'our' version. Changes from the other tree that do not
conflict with our side are reflected to the merge result.
+ For a binary file, the entire contents are taken from our side.
+
This should not be confused with the 'ours' merge strategy, which does not
even look at what the other tree contains at all. It discards everything
the other tree did, declaring 'our' history contains all that happened in it.
theirs;;
- This is opposite of 'ours'.
+ This is the opposite of 'ours'.
patience;;
With this option, 'merge-recursive' spends a little extra time
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 1fc2a18..ee49743 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -51,6 +51,14 @@ endif::git-rev-list[]
commits whose author matches any of the given patterns are
chosen (similarly for multiple `--committer=<pattern>`).
+--grep-reflog=<pattern>::
+
+ Limit the commits output to ones with reflog entries that
+ match the specified pattern (regular expression). With
+ more than one `--grep-reflog`, commits whose reflog message
+ matches any of the given patterns are chosen. It is an
+ error to use this option unless `--walk-reflogs` is in use.
+
--grep=<pattern>::
Limit the commits output to ones with log message that
@@ -58,6 +66,9 @@ endif::git-rev-list[]
more than one `--grep=<pattern>`, commits whose message
matches any of the given patterns are chosen (but see
`--all-match`).
++
+When `--show-notes` is in effect, the message from the notes as
+if it is part of the log message.
--all-match::
Limit the commits output to ones that match all given --grep,
diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index 69d996b..991fcd8 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -55,6 +55,8 @@ when you run `git cherry-pick`.
+
Note that any of the 'refs/*' cases above may come either from
the '$GIT_DIR/refs' directory or from the '$GIT_DIR/packed-refs' file.
+While the ref name encoding is unspecified, UTF-8 is prefered as
+some output processing may assume ref names in UTF-8.
'<refname>@\{<date>\}', e.g. 'master@\{yesterday\}', 'HEAD@\{5 minutes ago\}'::
A ref followed by the suffix '@' with a date specification
diff --git a/Documentation/technical/api-sha1-array.txt b/Documentation/technical/api-sha1-array.txt
index 4a4bae8..45d1c51 100644
--- a/Documentation/technical/api-sha1-array.txt
+++ b/Documentation/technical/api-sha1-array.txt
@@ -25,9 +25,6 @@ Functions
the array (but note that some operations below may lose this
ordering).
-`sha1_array_sort`::
- Sort the elements in the array.
-
`sha1_array_lookup`::
Perform a binary search of the array for a specific sha1.
If found, returns the offset (in number of elements) of the
diff --git a/Documentation/technical/api-string-list.txt b/Documentation/technical/api-string-list.txt
index 5a0c14f..94d7a2b 100644
--- a/Documentation/technical/api-string-list.txt
+++ b/Documentation/technical/api-string-list.txt
@@ -1,8 +1,9 @@
string-list API
===============
-The string_list API offers a data structure and functions to handle sorted
-and unsorted string lists.
+The string_list API offers a data structure and functions to handle
+sorted and unsorted string lists. A "sorted" list is one whose
+entries are sorted by string value in `strcmp()` order.
The 'string_list' struct used to be called 'path_list', but was renamed
because it is not specific to paths.
@@ -20,8 +21,9 @@ If you need something advanced, you can manually malloc() the `items`
member (you need this if you add things later) and you should set the
`nr` and `alloc` members in that case, too.
-. Adds new items to the list, using `string_list_append` or
- `string_list_insert`.
+. Adds new items to the list, using `string_list_append`,
+ `string_list_append_nodup`, `string_list_insert`,
+ `string_list_split`, and/or `string_list_split_in_place`.
. Can check if a string is in the list using `string_list_has_string` or
`unsorted_string_list_has_string` and get it from the list using
@@ -29,18 +31,23 @@ member (you need this if you add things later) and you should set the
. Can sort an unsorted list using `sort_string_list`.
+. Can remove duplicate items from a sorted list using
+ `string_list_remove_duplicates`.
+
. Can remove individual items of an unsorted list using
`unsorted_string_list_delete_item`.
+. Can remove items not matching a criterion from a sorted or unsorted
+ list using `filter_string_list`.
+
. Finally it should free the list using `string_list_clear`.
Example:
----
-struct string_list list;
+struct string_list list = STRING_LIST_INIT_NODUP;
int i;
-memset(&list, 0, sizeof(struct string_list));
string_list_append(&list, "foo");
string_list_append(&list, "bar");
for (i = 0; i < list.nr; i++)
@@ -60,6 +67,22 @@ Functions
* General ones (works with sorted and unsorted lists as well)
+`filter_string_list`::
+
+ Apply a function to each item in a list, retaining only the
+ items for which the function returns true. If free_util is
+ true, call free() on the util members of any items that have
+ to be deleted. Preserve the order of the items that are
+ retained.
+
+`string_list_longest_prefix`::
+
+ Return the longest string within a string_list that is a
+ prefix (in the sense of prefixcmp()) of the specified string,
+ or NULL if no such prefix exists. This function does not
+ require the string_list to be sorted (it does a linear
+ search).
+
`print_string_list`::
Dump a string_list to stdout, useful mainly for debugging purposes. It
@@ -96,15 +119,32 @@ write `string_list_insert(...)->util = ...;`.
Look up a given string in the string_list, returning the containing
string_list_item. If the string is not found, NULL is returned.
+`string_list_remove_duplicates`::
+
+ Remove all but the first of consecutive entries that have the
+ same string value. If free_util is true, call free() on the
+ util members of any items that have to be deleted.
+
* Functions for unsorted lists only
`string_list_append`::
- Append a new string to the end of the string_list.
+ Append a new string to the end of the string_list. If
+ `strdup_string` is set, then the string argument is copied;
+ otherwise the new `string_list_entry` refers to the input
+ string.
+
+`string_list_append_nodup`::
+
+ Append a new string to the end of the string_list. The new
+ `string_list_entry` always refers to the input string, even if
+ `strdup_string` is set. This function can be used to hand
+ ownership of a malloc()ed string to a `string_list` that has
+ `strdup_string` set.
`sort_string_list`::
- Make an unsorted list sorted.
+ Sort the list's entries by string value in `strcmp()` order.
`unsorted_string_list_has_string`::
@@ -124,6 +164,25 @@ counterpart for sorted lists, which performs a binary search.
is set. The third parameter controls if the `util` pointer of the
items should be freed or not.
+`string_list_split`::
+`string_list_split_in_place`::
+
+ Split a string into substrings on a delimiter character and
+ append the substrings to a `string_list`. If `maxsplit` is
+ non-negative, then split at most `maxsplit` times. Return the
+ number of substrings appended to the list.
++
+`string_list_split` requires a `string_list` that has `strdup_strings`
+set to true; it leaves the input string untouched and makes copies of
+the substrings in newly-allocated memory.
+`string_list_split_in_place` requires a `string_list` that has
+`strdup_strings` set to false; it splits the input string in place,
+overwriting the delimiter characters with NULs and creating new
+string_list_items that point into the original string (the original
+string must therefore not be modified or freed while the `string_list`
+is in use).
+
+
Data structures
---------------
diff --git a/Documentation/urls.txt b/Documentation/urls.txt
index 2890194..1d15ee7 100644
--- a/Documentation/urls.txt
+++ b/Documentation/urls.txt
@@ -6,8 +6,12 @@ address of the remote server, and the path to the repository.
Depending on the transport protocol, some of this information may be
absent.
-Git natively supports ssh, git, http, https, ftp, ftps, and rsync
-protocols. The following syntaxes may be used with them:
+Git supports ssh, git, http, and https protocols (in addition, ftp,
+and ftps can be used for fetching and rsync can be used for fetching
+and pushing, but these are inefficient and deprecated; do not use
+them).
+
+The following syntaxes may be used with them:
- ssh://{startsb}user@{endsb}host.xz{startsb}:port{endsb}/path/to/repo.git/
- git://host.xz{startsb}:port{endsb}/path/to/repo.git/
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index ecdbf90..3c0e89c 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.12.3
+DEF_VER=v1.8.0-rc2
LF='
'
diff --git a/Makefile b/Makefile
index 26b697d..f69979e 100644
--- a/Makefile
+++ b/Makefile
@@ -90,6 +90,8 @@ all::
#
# Define NO_MKDTEMP if you don't have mkdtemp in the C library.
#
+# Define MKDIR_WO_TRAILING_SLASH if your mkdir() can't deal with trailing slash.
+#
# Define NO_MKSTEMPS if you don't have mkstemps in the C library.
#
# Define NO_STRTOK_R if you don't have strtok_r in the C library.
@@ -143,6 +145,12 @@ all::
#
# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).
#
+# Define NEEDS_LIBINTL_BEFORE_LIBICONV if you need libintl before libiconv.
+#
+# Define NO_INTPTR_T if you don't have intptr_t nor uintptr_t.
+#
+# Define NO_UINTMAX_T if you don't have uintmax_t.
+#
# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
# Patrick Mauritz).
#
@@ -152,11 +160,21 @@ all::
#
# Define NO_MMAP if you want to avoid mmap.
#
+# Define NO_SYS_POLL_H if you don't have sys/poll.h.
+#
+# Define NO_POLL if you do not have or don't want to use poll().
+# This also implies NO_SYS_POLL_H.
+#
# Define NO_PTHREADS if you do not have or do not want to use Pthreads.
#
# Define NO_PREAD if you have a problem with pread() system call (e.g.
# cygwin1.dll before v1.5.22).
#
+# Define NO_SETITIMER if you don't have setitimer()
+#
+# Define NO_STRUCT_ITIMERVAL if you don't have struct itimerval
+# This also implies NO_SETITIMER
+#
# Define NO_THREAD_SAFE_PREAD if your pread() implementation is not
# thread-safe. (e.g. compat/pread.c or cygwin)
#
@@ -502,6 +520,7 @@ TEST_PROGRAMS_NEED_X += test-run-command
TEST_PROGRAMS_NEED_X += test-scrap-cache-tree
TEST_PROGRAMS_NEED_X += test-sha1
TEST_PROGRAMS_NEED_X += test-sigchain
+TEST_PROGRAMS_NEED_X += test-string-list
TEST_PROGRAMS_NEED_X += test-subprocess
TEST_PROGRAMS_NEED_X += test-svn-fe
@@ -596,10 +615,10 @@ LIB_H += compat/bswap.h
LIB_H += compat/cygwin.h
LIB_H += compat/mingw.h
LIB_H += compat/obstack.h
+LIB_H += compat/poll/poll.h
LIB_H += compat/precompose_utf8.h
LIB_H += compat/terminal.h
LIB_H += compat/win32/dirent.h
-LIB_H += compat/win32/poll.h
LIB_H += compat/win32/pthread.h
LIB_H += compat/win32/syslog.h
LIB_H += connected.h
@@ -1217,7 +1236,7 @@ ifeq ($(uname_S),Windows)
NO_PREAD = YesPlease
NEEDS_CRYPTO_WITH_SSL = YesPlease
NO_LIBGEN_H = YesPlease
- NO_SYS_POLL_H = YesPlease
+ NO_POLL = YesPlease
NO_SYMLINK_HEAD = YesPlease
NO_IPV6 = YesPlease
NO_UNIX_SOCKETS = YesPlease
@@ -1258,7 +1277,7 @@ ifeq ($(uname_S),Windows)
BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
COMPAT_OBJS = compat/msvc.o compat/winansi.o \
compat/win32/pthread.o compat/win32/syslog.o \
- compat/win32/poll.o compat/win32/dirent.o
+ compat/win32/dirent.o
COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib
@@ -1308,12 +1327,67 @@ ifeq ($(uname_S),Minix)
NO_CURL =
NO_EXPAT =
endif
+ifeq ($(uname_S),NONSTOP_KERNEL)
+ # Needs some C99 features, "inline" is just one of them.
+ # INLINE='' would just replace one set of warnings with another and
+ # still not compile in c89 mode, due to non-const array initializations.
+ CC = cc -c99
+ # Disable all optimization, seems to result in bad code, with -O or -O2
+ # or even -O1 (default), /usr/local/libexec/git-core/git-pack-objects
+ # abends on "git push". Needs more investigation.
+ CFLAGS = -g -O0
+ # We'd want it to be here.
+ prefix = /usr/local
+ # Our's are in ${prefix}/bin (perl might also be in /usr/bin/perl).
+ PERL_PATH = ${prefix}/bin/perl
+ PYTHON_PATH = ${prefix}/bin/python
+
+ # As detected by './configure'.
+ # Missdetected, hence commented out, see below.
+ #NO_CURL = YesPlease
+ # Added manually, see above.
+ NEEDS_SSL_WITH_CURL = YesPlease
+ HAVE_LIBCHARSET_H = YesPlease
+ NEEDS_LIBICONV = YesPlease
+ NEEDS_LIBINTL_BEFORE_LIBICONV = YesPlease
+ NO_SYS_SELECT_H = UnfortunatelyYes
+ NO_D_TYPE_IN_DIRENT = YesPlease
+ NO_HSTRERROR = YesPlease
+ NO_STRCASESTR = YesPlease
+ NO_FNMATCH_CASEFOLD = YesPlease
+ NO_MEMMEM = YesPlease
+ NO_STRLCPY = YesPlease
+ NO_SETENV = YesPlease
+ NO_UNSETENV = YesPlease
+ NO_MKDTEMP = YesPlease
+ NO_MKSTEMPS = YesPlease
+ # Currently libiconv-1.9.1.
+ OLD_ICONV = UnfortunatelyYes
+ NO_REGEX = YesPlease
+ NO_PTHREADS = UnfortunatelyYes
+
+ # Not detected (nor checked for) by './configure'.
+ # We don't have SA_RESTART on NonStop, unfortunalety.
+ COMPAT_CFLAGS += -DSA_RESTART=0
+ # Apparently needed in compat/fnmatch/fnmatch.c.
+ COMPAT_CFLAGS += -DHAVE_STRING_H=1
+ NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
+ NO_NSEC = YesPlease
+ NO_PREAD = YesPlease
+ NO_MMAP = YesPlease
+ NO_POLL = YesPlease
+ NO_INTPTR_T = UnfortunatelyYes
+ # Bug report 10-120822-4477 submitted to HP NonStop development.
+ MKDIR_WO_TRAILING_SLASH = YesPlease
+ # RFE 10-120912-4693 submitted to HP NonStop development.
+ NO_SETITIMER = UnfortunatelyYes
+endif
ifneq (,$(findstring MINGW,$(uname_S)))
pathsep = ;
NO_PREAD = YesPlease
NEEDS_CRYPTO_WITH_SSL = YesPlease
NO_LIBGEN_H = YesPlease
- NO_SYS_POLL_H = YesPlease
+ NO_POLL = YesPlease
NO_SYMLINK_HEAD = YesPlease
NO_UNIX_SOCKETS = YesPlease
NO_SETENV = YesPlease
@@ -1348,7 +1422,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
COMPAT_OBJS += compat/mingw.o compat/winansi.o \
compat/win32/pthread.o compat/win32/syslog.o \
- compat/win32/poll.o compat/win32/dirent.o
+ compat/win32/dirent.o
EXTLIBS += -lws2_32
PTHREAD_LIBS =
X = .exe
@@ -1544,6 +1618,9 @@ ifdef NEEDS_LIBICONV
else
ICONV_LINK =
endif
+ ifdef NEEDS_LIBINTL_BEFORE_LIBICONV
+ ICONV_LINK += -lintl
+ endif
EXTLIBS += $(ICONV_LINK) -liconv
endif
ifdef NEEDS_LIBGEN
@@ -1602,6 +1679,11 @@ ifdef NO_GETTEXT
BASIC_CFLAGS += -DNO_GETTEXT
USE_GETTEXT_SCHEME ?= fallthrough
endif
+ifdef NO_POLL
+ NO_SYS_POLL_H = YesPlease
+ COMPAT_CFLAGS += -DNO_POLL -Icompat/poll
+ COMPAT_OBJS += compat/poll/poll.o
+endif
ifdef NO_STRCASESTR
COMPAT_CFLAGS += -DNO_STRCASESTR
COMPAT_OBJS += compat/strcasestr.o
@@ -1640,6 +1722,10 @@ ifdef NO_MKDTEMP
COMPAT_CFLAGS += -DNO_MKDTEMP
COMPAT_OBJS += compat/mkdtemp.o
endif
+ifdef MKDIR_WO_TRAILING_SLASH
+ COMPAT_CFLAGS += -DMKDIR_WO_TRAILING_SLASH
+ COMPAT_OBJS += compat/mkdir.o
+endif
ifdef NO_MKSTEMPS
COMPAT_CFLAGS += -DNO_MKSTEMPS
endif
@@ -1671,6 +1757,13 @@ endif
ifdef OBJECT_CREATION_USES_RENAMES
COMPAT_CFLAGS += -DOBJECT_CREATION_MODE=1
endif
+ifdef NO_STRUCT_ITIMERVAL
+ COMPAT_CFLAGS += -DNO_STRUCT_ITIMERVAL
+ NO_SETITIMER=YesPlease
+endif
+ifdef NO_SETITIMER
+ COMPAT_CFLAGS += -DNO_SETITIMER
+endif
ifdef NO_PREAD
COMPAT_CFLAGS += -DNO_PREAD
COMPAT_OBJS += compat/pread.o
@@ -1688,6 +1781,9 @@ endif
ifdef NO_IPV6
BASIC_CFLAGS += -DNO_IPV6
endif
+ifdef NO_INTPTR_T
+ COMPAT_CFLAGS += -DNO_INTPTR_T
+endif
ifdef NO_UINTMAX_T
BASIC_CFLAGS += -Duintmax_t=uint32_t
endif
@@ -2540,6 +2636,7 @@ bin-wrappers/%: wrap-for-bin.sh
# with that.
export NO_SVN_TESTS
+export TEST_NO_MALLOC_CHECK
### Testing rules
diff --git a/RelNotes b/RelNotes
index 9cd9140..2484b38 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.7.12.3.txt \ No newline at end of file
+Documentation/RelNotes/1.8.0.txt \ No newline at end of file
diff --git a/abspath.c b/abspath.c
index f04ac18..05f2d79 100644
--- a/abspath.c
+++ b/abspath.c
@@ -35,6 +35,9 @@ const char *real_path(const char *path)
if (path == buf || path == next_buf)
return path;
+ if (!*path)
+ die("The empty string is not a valid path");
+
if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
die ("Too long path: %.*s", 60, path);
@@ -42,8 +45,8 @@ const char *real_path(const char *path)
if (!is_directory(buf)) {
char *last_slash = find_last_dir_sep(buf);
if (last_slash) {
- *last_slash = '\0';
last_elem = xstrdup(last_slash + 1);
+ last_slash[1] = '\0';
} else {
last_elem = xstrdup(buf);
*buf = '\0';
@@ -123,7 +126,9 @@ const char *absolute_path(const char *path)
{
static char buf[PATH_MAX + 1];
- if (is_absolute_path(path)) {
+ if (!*path) {
+ die("The empty string is not a valid path");
+ } else if (is_absolute_path(path)) {
if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
die("Too long path: %.*s", 60, path);
} else {
diff --git a/archive-zip.c b/archive-zip.c
index f5af81f..55f66b4 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -4,6 +4,7 @@
#include "cache.h"
#include "archive.h"
#include "streaming.h"
+#include "utf8.h"
static int zip_date;
static int zip_time;
@@ -16,7 +17,8 @@ static unsigned int zip_dir_offset;
static unsigned int zip_dir_entries;
#define ZIP_DIRECTORY_MIN_SIZE (1024 * 1024)
-#define ZIP_STREAM (8)
+#define ZIP_STREAM (1 << 3)
+#define ZIP_UTF8 (1 << 11)
struct zip_local_header {
unsigned char magic[4];
@@ -74,6 +76,14 @@ struct zip_dir_trailer {
unsigned char _end[1];
};
+struct zip_extra_mtime {
+ unsigned char magic[2];
+ unsigned char extra_size[2];
+ unsigned char flags[1];
+ unsigned char mtime[4];
+ unsigned char _end[1];
+};
+
/*
* On ARM, padding is added at the end of the struct, so a simple
* sizeof(struct ...) reports two bytes more than the payload size
@@ -83,6 +93,9 @@ struct zip_dir_trailer {
#define ZIP_DATA_DESC_SIZE offsetof(struct zip_data_desc, _end)
#define ZIP_DIR_HEADER_SIZE offsetof(struct zip_dir_header, _end)
#define ZIP_DIR_TRAILER_SIZE offsetof(struct zip_dir_trailer, _end)
+#define ZIP_EXTRA_MTIME_SIZE offsetof(struct zip_extra_mtime, _end)
+#define ZIP_EXTRA_MTIME_PAYLOAD_SIZE \
+ (ZIP_EXTRA_MTIME_SIZE - offsetof(struct zip_extra_mtime, flags))
static void copy_le16(unsigned char *dest, unsigned int n)
{
@@ -164,6 +177,17 @@ static void set_zip_header_data_desc(struct zip_local_header *header,
copy_le32(header->size, size);
}
+static int has_only_ascii(const char *s)
+{
+ for (;;) {
+ int c = *s++;
+ if (c == '\0')
+ return 1;
+ if (!isascii(c))
+ return 0;
+ }
+}
+
#define STREAM_BUFFER_SIZE (1024 * 16)
static int write_zip_entry(struct archiver_args *args,
@@ -173,6 +197,7 @@ static int write_zip_entry(struct archiver_args *args,
{
struct zip_local_header header;
struct zip_dir_header dirent;
+ struct zip_extra_mtime extra;
unsigned long attr2;
unsigned long compressed_size;
unsigned long crc;
@@ -187,6 +212,13 @@ static int write_zip_entry(struct archiver_args *args,
crc = crc32(0, NULL, 0);
+ if (!has_only_ascii(path)) {
+ if (is_utf8(path))
+ flags |= ZIP_UTF8;
+ else
+ warning("Path is not valid UTF-8: %s", path);
+ }
+
if (pathlen > 0xffff) {
return error("path too long (%d chars, SHA1: %s): %s",
(int)pathlen, sha1_to_hex(sha1), path);
@@ -246,8 +278,13 @@ static int write_zip_entry(struct archiver_args *args,
}
}
+ copy_le16(extra.magic, 0x5455);
+ copy_le16(extra.extra_size, ZIP_EXTRA_MTIME_PAYLOAD_SIZE);
+ extra.flags[0] = 1; /* just mtime */
+ copy_le32(extra.mtime, args->time);
+
/* make sure we have enough free space in the dictionary */
- direntsize = ZIP_DIR_HEADER_SIZE + pathlen;
+ direntsize = ZIP_DIR_HEADER_SIZE + pathlen + ZIP_EXTRA_MTIME_SIZE;
while (zip_dir_size < zip_dir_offset + direntsize) {
zip_dir_size += ZIP_DIRECTORY_MIN_SIZE;
zip_dir = xrealloc(zip_dir, zip_dir_size);
@@ -263,7 +300,7 @@ static int write_zip_entry(struct archiver_args *args,
copy_le16(dirent.mdate, zip_date);
set_zip_dir_data_desc(&dirent, size, compressed_size, crc);
copy_le16(dirent.filename_length, pathlen);
- copy_le16(dirent.extra_length, 0);
+ copy_le16(dirent.extra_length, ZIP_EXTRA_MTIME_SIZE);
copy_le16(dirent.comment_length, 0);
copy_le16(dirent.disk, 0);
copy_le16(dirent.attr1, 0);
@@ -281,11 +318,13 @@ static int write_zip_entry(struct archiver_args *args,
else
set_zip_header_data_desc(&header, size, compressed_size, crc);
copy_le16(header.filename_length, pathlen);
- copy_le16(header.extra_length, 0);
+ copy_le16(header.extra_length, ZIP_EXTRA_MTIME_SIZE);
write_or_die(1, &header, ZIP_LOCAL_HEADER_SIZE);
zip_offset += ZIP_LOCAL_HEADER_SIZE;
write_or_die(1, path, pathlen);
zip_offset += pathlen;
+ write_or_die(1, &extra, ZIP_EXTRA_MTIME_SIZE);
+ zip_offset += ZIP_EXTRA_MTIME_SIZE;
if (stream && method == 0) {
unsigned char buf[STREAM_BUFFER_SIZE];
ssize_t readlen;
@@ -382,6 +421,8 @@ static int write_zip_entry(struct archiver_args *args,
zip_dir_offset += ZIP_DIR_HEADER_SIZE;
memcpy(zip_dir + zip_dir_offset, path, pathlen);
zip_dir_offset += pathlen;
+ memcpy(zip_dir + zip_dir_offset, &extra, ZIP_EXTRA_MTIME_SIZE);
+ zip_dir_offset += ZIP_EXTRA_MTIME_SIZE;
zip_dir_entries++;
return 0;
diff --git a/archive.c b/archive.c
index a484433..4666404 100644
--- a/archive.c
+++ b/archive.c
@@ -7,10 +7,10 @@
#include "unpack-trees.h"
static char const * const archive_usage[] = {
- "git archive [options] <tree-ish> [<path>...]",
- "git archive --list",
- "git archive --remote <repo> [--exec <cmd>] [options] <tree-ish> [<path>...]",
- "git archive --remote <repo> [--exec <cmd>] --list",
+ N_("git archive [options] <tree-ish> [<path>...]"),
+ N_("git archive --list"),
+ N_("git archive --remote <repo> [--exec <cmd>] [options] <tree-ish> [<path>...]"),
+ N_("git archive --remote <repo> [--exec <cmd>] --list"),
NULL
};
@@ -319,16 +319,16 @@ static int parse_archive_args(int argc, const char **argv,
int worktree_attributes = 0;
struct option opts[] = {
OPT_GROUP(""),
- OPT_STRING(0, "format", &format, "fmt", "archive format"),
- OPT_STRING(0, "prefix", &base, "prefix",
- "prepend prefix to each pathname in the archive"),
- OPT_STRING('o', "output", &output, "file",
- "write the archive to this file"),
+ OPT_STRING(0, "format", &format, N_("fmt"), N_("archive format")),
+ OPT_STRING(0, "prefix", &base, N_("prefix"),
+ N_("prepend prefix to each pathname in the archive")),
+ OPT_STRING('o', "output", &output, N_("file"),
+ N_("write the archive to this file")),
OPT_BOOL(0, "worktree-attributes", &worktree_attributes,
- "read .gitattributes in working directory"),
- OPT__VERBOSE(&verbose, "report archived files on stderr"),
- OPT__COMPR('0', &compression_level, "store only", 0),
- OPT__COMPR('1', &compression_level, "compress faster", 1),
+ N_("read .gitattributes in working directory")),
+ OPT__VERBOSE(&verbose, N_("report archived files on stderr")),
+ OPT__COMPR('0', &compression_level, N_("store only"), 0),
+ OPT__COMPR('1', &compression_level, N_("compress faster"), 1),
OPT__COMPR_HIDDEN('2', &compression_level, 2),
OPT__COMPR_HIDDEN('3', &compression_level, 3),
OPT__COMPR_HIDDEN('4', &compression_level, 4),
@@ -336,15 +336,15 @@ static int parse_archive_args(int argc, const char **argv,
OPT__COMPR_HIDDEN('6', &compression_level, 6),
OPT__COMPR_HIDDEN('7', &compression_level, 7),
OPT__COMPR_HIDDEN('8', &compression_level, 8),
- OPT__COMPR('9', &compression_level, "compress better", 9),
+ OPT__COMPR('9', &compression_level, N_("compress better"), 9),
OPT_GROUP(""),
OPT_BOOL('l', "list", &list,
- "list supported archive formats"),
+ N_("list supported archive formats")),
OPT_GROUP(""),
- OPT_STRING(0, "remote", &remote, "repo",
- "retrieve the archive from remote repository <repo>"),
- OPT_STRING(0, "exec", &exec, "cmd",
- "path to the remote git-upload-archive command"),
+ OPT_STRING(0, "remote", &remote, N_("repo"),
+ N_("retrieve the archive from remote repository <repo>")),
+ OPT_STRING(0, "exec", &exec, N_("command"),
+ N_("path to the remote git-upload-archive command")),
OPT_END()
};
diff --git a/attr.c b/attr.c
index 056d702..887a9ae 100644
--- a/attr.c
+++ b/attr.c
@@ -306,7 +306,7 @@ static void free_attr_elem(struct attr_stack *e)
}
static const char *builtin_attr[] = {
- "[attr]binary -diff -text",
+ "[attr]binary -diff -merge -text",
NULL,
};
diff --git a/bisect.c b/bisect.c
index 48acf73..1aad49b 100644
--- a/bisect.c
+++ b/bisect.c
@@ -833,7 +833,7 @@ static int check_ancestors(const char *prefix)
*/
static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)
{
- char *filename = xstrdup(git_path("BISECT_ANCESTORS_OK"));
+ char *filename = git_pathdup("BISECT_ANCESTORS_OK");
struct stat st;
int fd;
diff --git a/builtin.h b/builtin.h
index 8e37752..95116b8 100644
--- a/builtin.h
+++ b/builtin.h
@@ -21,7 +21,6 @@ struct fmt_merge_msg_opts {
extern int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
struct fmt_merge_msg_opts *);
-extern void commit_notes(struct notes_tree *t, const char *msg);
struct notes_rewrite_cfg {
struct notes_tree **trees;
@@ -33,7 +32,6 @@ struct notes_rewrite_cfg {
int mode_from_env;
};
-combine_notes_fn parse_combine_notes_fn(const char *v);
struct notes_rewrite_cfg *init_copy_notes_for_rewrite(const char *cmd);
int copy_note_for_rewrite(struct notes_rewrite_cfg *c,
const unsigned char *from_obj, const unsigned char *to_obj);
diff --git a/builtin/add.c b/builtin/add.c
index 89dce56..e664100 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -16,7 +16,7 @@
#include "bulk-checkin.h"
static const char * const builtin_add_usage[] = {
- "git add [options] [--] <filepattern>...",
+ N_("git add [options] [--] <filepattern>..."),
NULL
};
static int patch_interactive, add_interactive, edit_interactive;
@@ -260,7 +260,7 @@ int interactive_add(int argc, const char **argv, const char *prefix, int patch)
static int edit_patch(int argc, const char **argv, const char *prefix)
{
- char *file = xstrdup(git_path("ADD_EDIT.patch"));
+ char *file = git_pathdup("ADD_EDIT.patch");
const char *apply_argv[] = { "apply", "--recount", "--cached",
NULL, NULL };
struct child_process child;
@@ -303,6 +303,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
die (_("Could not apply '%s'"), file);
unlink(file);
+ free(file);
return 0;
}
@@ -315,19 +316,19 @@ static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;
static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0;
static struct option builtin_add_options[] = {
- OPT__DRY_RUN(&show_only, "dry run"),
- OPT__VERBOSE(&verbose, "be verbose"),
+ OPT__DRY_RUN(&show_only, N_("dry run")),
+ OPT__VERBOSE(&verbose, N_("be verbose")),
OPT_GROUP(""),
- OPT_BOOLEAN('i', "interactive", &add_interactive, "interactive picking"),
- OPT_BOOLEAN('p', "patch", &patch_interactive, "select hunks interactively"),
- OPT_BOOLEAN('e', "edit", &edit_interactive, "edit current diff and apply"),
- OPT__FORCE(&ignored_too, "allow adding otherwise ignored files"),
- OPT_BOOLEAN('u', "update", &take_worktree_changes, "update tracked files"),
- OPT_BOOLEAN('N', "intent-to-add", &intent_to_add, "record only the fact that the path will be added later"),
- OPT_BOOLEAN('A', "all", &addremove, "add changes from all tracked and untracked files"),
- OPT_BOOLEAN( 0 , "refresh", &refresh_only, "don't add, only refresh the index"),
- OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, "just skip files which cannot be added because of errors"),
- OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, "check if - even missing - files are ignored in dry run"),
+ OPT_BOOLEAN('i', "interactive", &add_interactive, N_("interactive picking")),
+ OPT_BOOLEAN('p', "patch", &patch_interactive, N_("select hunks interactively")),
+ OPT_BOOLEAN('e', "edit", &edit_interactive, N_("edit current diff and apply")),
+ OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")),
+ OPT_BOOLEAN('u', "update", &take_worktree_changes, N_("update tracked files")),
+ OPT_BOOLEAN('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")),
+ OPT_BOOLEAN('A', "all", &addremove, N_("add changes from all tracked and untracked files")),
+ OPT_BOOLEAN( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")),
+ OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
+ OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
OPT_END(),
};
diff --git a/builtin/apply.c b/builtin/apply.c
index ca8695a..156b3ce 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -4314,7 +4314,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
OPT_NOOP_NOARG(0, "allow-binary-replacement"),
OPT_NOOP_NOARG(0, "binary"),
OPT_BOOLEAN(0, "numstat", &numstat,
- N_("shows number of added and deleted lines in decimal notation")),
+ N_("show number of added and deleted lines in decimal notation")),
OPT_BOOLEAN(0, "summary", &summary,
N_("instead of applying the patch, output a summary for the input")),
OPT_BOOLEAN(0, "check", &check,
diff --git a/builtin/archive.c b/builtin/archive.c
index 931956d..9a1cfd3 100644
--- a/builtin/archive.c
+++ b/builtin/archive.c
@@ -88,12 +88,12 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
const char *output = NULL;
const char *remote = NULL;
struct option local_opts[] = {
- OPT_STRING('o', "output", &output, "file",
- "write the archive to this file"),
- OPT_STRING(0, "remote", &remote, "repo",
- "retrieve the archive from remote repository <repo>"),
- OPT_STRING(0, "exec", &exec, "cmd",
- "path to the remote git-upload-archive command"),
+ OPT_STRING('o', "output", &output, N_("file"),
+ N_("write the archive to this file")),
+ OPT_STRING(0, "remote", &remote, N_("repo"),
+ N_("retrieve the archive from remote repository <repo>")),
+ OPT_STRING(0, "exec", &exec, N_("command"),
+ N_("path to the remote git-upload-archive command")),
OPT_END()
};
diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
index 8d325a5..e3884e3 100644
--- a/builtin/bisect--helper.c
+++ b/builtin/bisect--helper.c
@@ -4,7 +4,7 @@
#include "bisect.h"
static const char * const git_bisect_helper_usage[] = {
- "git bisect--helper --next-all [--no-checkout]",
+ N_("git bisect--helper --next-all [--no-checkout]"),
NULL
};
@@ -14,9 +14,9 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
int no_checkout = 0;
struct option options[] = {
OPT_BOOLEAN(0, "next-all", &next_all,
- "perform 'git bisect next'"),
+ N_("perform 'git bisect next'")),
OPT_BOOLEAN(0, "no-checkout", &no_checkout,
- "update BISECT_HEAD instead of checking out the current commit"),
+ N_("update BISECT_HEAD instead of checking out the current commit")),
OPT_END()
};
diff --git a/builtin/blame.c b/builtin/blame.c
index 409eb42..c27ef21 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -22,12 +22,12 @@
#include "utf8.h"
#include "userdiff.h"
-static char blame_usage[] = "git blame [options] [rev-opts] [rev] [--] file";
+static char blame_usage[] = N_("git blame [options] [rev-opts] [rev] [--] file");
static const char *blame_opt_usage[] = {
blame_usage,
"",
- "[rev-opts] are documented in git-rev-list(1)",
+ N_("[rev-opts] are documented in git-rev-list(1)"),
NULL
};
@@ -2370,27 +2370,27 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
static const char *revs_file = NULL;
static const char *contents_from = NULL;
static const struct option options[] = {
- OPT_BOOLEAN(0, "incremental", &incremental, "Show blame entries as we find them, incrementally"),
- OPT_BOOLEAN('b', NULL, &blank_boundary, "Show blank SHA-1 for boundary commits (Default: off)"),
- OPT_BOOLEAN(0, "root", &show_root, "Do not treat root commits as boundaries (Default: off)"),
- OPT_BOOLEAN(0, "show-stats", &show_stats, "Show work cost statistics"),
- OPT_BIT(0, "score-debug", &output_option, "Show output score for blame entries", OUTPUT_SHOW_SCORE),
- OPT_BIT('f', "show-name", &output_option, "Show original filename (Default: auto)", OUTPUT_SHOW_NAME),
- OPT_BIT('n', "show-number", &output_option, "Show original linenumber (Default: off)", OUTPUT_SHOW_NUMBER),
- OPT_BIT('p', "porcelain", &output_option, "Show in a format designed for machine consumption", OUTPUT_PORCELAIN),
- OPT_BIT(0, "line-porcelain", &output_option, "Show porcelain format with per-line commit information", OUTPUT_PORCELAIN|OUTPUT_LINE_PORCELAIN),
- OPT_BIT('c', NULL, &output_option, "Use the same output mode as git-annotate (Default: off)", OUTPUT_ANNOTATE_COMPAT),
- OPT_BIT('t', NULL, &output_option, "Show raw timestamp (Default: off)", OUTPUT_RAW_TIMESTAMP),
- OPT_BIT('l', NULL, &output_option, "Show long commit SHA1 (Default: off)", OUTPUT_LONG_OBJECT_NAME),
- OPT_BIT('s', NULL, &output_option, "Suppress author name and timestamp (Default: off)", OUTPUT_NO_AUTHOR),
- OPT_BIT('e', "show-email", &output_option, "Show author email instead of name (Default: off)", OUTPUT_SHOW_EMAIL),
- OPT_BIT('w', NULL, &xdl_opts, "Ignore whitespace differences", XDF_IGNORE_WHITESPACE),
- OPT_BIT(0, "minimal", &xdl_opts, "Spend extra cycles to find better match", XDF_NEED_MINIMAL),
- OPT_STRING('S', NULL, &revs_file, "file", "Use revisions from <file> instead of calling git-rev-list"),
- OPT_STRING(0, "contents", &contents_from, "file", "Use <file>'s contents as the final image"),
- { OPTION_CALLBACK, 'C', NULL, &opt, "score", "Find line copies within and across files", PARSE_OPT_OPTARG, blame_copy_callback },
- { OPTION_CALLBACK, 'M', NULL, &opt, "score", "Find line movements within and across files", PARSE_OPT_OPTARG, blame_move_callback },
- OPT_CALLBACK('L', NULL, &bottomtop, "n,m", "Process only line range n,m, counting from 1", blame_bottomtop_callback),
+ OPT_BOOLEAN(0, "incremental", &incremental, N_("Show blame entries as we find them, incrementally")),
+ OPT_BOOLEAN('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: off)")),
+ OPT_BOOLEAN(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")),
+ OPT_BOOLEAN(0, "show-stats", &show_stats, N_("Show work cost statistics")),
+ OPT_BIT(0, "score-debug", &output_option, N_("Show output score for blame entries"), OUTPUT_SHOW_SCORE),
+ OPT_BIT('f', "show-name", &output_option, N_("Show original filename (Default: auto)"), OUTPUT_SHOW_NAME),
+ OPT_BIT('n', "show-number", &output_option, N_("Show original linenumber (Default: off)"), OUTPUT_SHOW_NUMBER),
+ OPT_BIT('p', "porcelain", &output_option, N_("Show in a format designed for machine consumption"), OUTPUT_PORCELAIN),
+ OPT_BIT(0, "line-porcelain", &output_option, N_("Show porcelain format with per-line commit information"), OUTPUT_PORCELAIN|OUTPUT_LINE_PORCELAIN),
+ OPT_BIT('c', NULL, &output_option, N_("Use the same output mode as git-annotate (Default: off)"), OUTPUT_ANNOTATE_COMPAT),
+ OPT_BIT('t', NULL, &output_option, N_("Show raw timestamp (Default: off)"), OUTPUT_RAW_TIMESTAMP),
+ OPT_BIT('l', NULL, &output_option, N_("Show long commit SHA1 (Default: off)"), OUTPUT_LONG_OBJECT_NAME),
+ OPT_BIT('s', NULL, &output_option, N_("Suppress author name and timestamp (Default: off)"), OUTPUT_NO_AUTHOR),
+ OPT_BIT('e', "show-email", &output_option, N_("Show author email instead of name (Default: off)"), OUTPUT_SHOW_EMAIL),
+ OPT_BIT('w', NULL, &xdl_opts, N_("Ignore whitespace differences"), XDF_IGNORE_WHITESPACE),
+ OPT_BIT(0, "minimal", &xdl_opts, N_("Spend extra cycles to find better match"), XDF_NEED_MINIMAL),
+ OPT_STRING('S', NULL, &revs_file, N_("file"), N_("Use revisions from <file> instead of calling git-rev-list")),
+ OPT_STRING(0, "contents", &contents_from, N_("file"), N_("Use <file>'s contents as the final image")),
+ { OPTION_CALLBACK, 'C', NULL, &opt, N_("score"), N_("Find line copies within and across files"), PARSE_OPT_OPTARG, blame_copy_callback },
+ { OPTION_CALLBACK, 'M', NULL, &opt, N_("score"), N_("Find line movements within and across files"), PARSE_OPT_OPTARG, blame_move_callback },
+ OPT_CALLBACK('L', NULL, &bottomtop, N_("n,m"), N_("Process only line range n,m, counting from 1"), blame_bottomtop_callback),
OPT__ABBREV(&abbrev),
OPT_END()
};
diff --git a/builtin/branch.c b/builtin/branch.c
index 0e060f2..ffd2684 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -17,12 +17,13 @@
#include "revision.h"
#include "string-list.h"
#include "column.h"
+#include "utf8.h"
static const char * const builtin_branch_usage[] = {
- "git branch [options] [-r | -a] [--merged | --no-merged]",
- "git branch [options] [-l] [-f] <branchname> [<start-point>]",
- "git branch [options] [-r] (-d | -D) <branchname>...",
- "git branch [options] (-m | -M) [<oldbranch>] <newbranch>",
+ N_("git branch [options] [-r | -a] [--merged | --no-merged]"),
+ N_("git branch [options] [-l] [-f] <branchname> [<start-point>]"),
+ N_("git branch [options] [-r] (-d | -D) <branchname>..."),
+ N_("git branch [options] (-m | -M) [<oldbranch>] <newbranch>"),
NULL
};
@@ -129,7 +130,7 @@ static int branch_merged(int kind, const char *name,
if (!reference_rev)
reference_rev = head_rev;
- merged = in_merge_bases(rev, &reference_rev, 1);
+ merged = in_merge_bases(rev, reference_rev);
/*
* After the safety valve is fully redefined to "check with
@@ -139,7 +140,7 @@ static int branch_merged(int kind, const char *name,
* a gentle reminder is in order.
*/
if ((head_rev != reference_rev) &&
- in_merge_bases(rev, &head_rev, 1) != merged) {
+ in_merge_bases(rev, head_rev) != merged) {
if (merged)
warning(_("deleting branch '%s' that has been merged to\n"
" '%s', but not yet merged to HEAD."),
@@ -196,7 +197,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
free(name);
- name = xstrdup(mkpath(fmt, bname.buf));
+ name = mkpathdup(fmt, bname.buf);
if (read_ref(name, sha1)) {
error(remote_branch
? _("remote branch '%s' not found.")
@@ -249,7 +250,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
struct ref_item {
char *name;
char *dest;
- unsigned int kind, len;
+ unsigned int kind, width;
struct commit *commit;
};
@@ -354,14 +355,14 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
newitem->name = xstrdup(refname);
newitem->kind = kind;
newitem->commit = commit;
- newitem->len = strlen(refname);
+ newitem->width = utf8_strwidth(refname);
newitem->dest = resolve_symref(orig_refname, prefix);
/* adjust for "remotes/" */
if (newitem->kind == REF_REMOTE_BRANCH &&
ref_list->kinds != REF_REMOTE_BRANCH)
- newitem->len += 8;
- if (newitem->len > ref_list->maxwidth)
- ref_list->maxwidth = newitem->len;
+ newitem->width += 8;
+ if (newitem->width > ref_list->maxwidth)
+ ref_list->maxwidth = newitem->width;
return 0;
}
@@ -490,11 +491,12 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
}
strbuf_addf(&name, "%s%s", prefix, item->name);
- if (verbose)
+ if (verbose) {
+ int utf8_compensation = strlen(name.buf) - utf8_strwidth(name.buf);
strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color),
- maxwidth, name.buf,
+ maxwidth + utf8_compensation, name.buf,
branch_get_color(BRANCH_COLOR_RESET));
- else
+ } else
strbuf_addf(&out, "%c %s%s%s", c, branch_get_color(color),
name.buf, branch_get_color(BRANCH_COLOR_RESET));
@@ -519,8 +521,8 @@ static int calc_maxwidth(struct ref_list *refs)
for (i = 0; i < refs->index; i++) {
if (!matches_merge_filter(refs->list[i].commit))
continue;
- if (refs->list[i].len > w)
- w = refs->list[i].len;
+ if (refs->list[i].width > w)
+ w = refs->list[i].width;
}
return w;
}
@@ -533,12 +535,12 @@ static void show_detached(struct ref_list *ref_list)
if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) {
struct ref_item item;
item.name = xstrdup(_("(no branch)"));
- item.len = strlen(item.name);
+ item.width = utf8_strwidth(item.name);
item.kind = REF_LOCAL_BRANCH;
item.dest = NULL;
item.commit = head_commit;
- if (item.len > ref_list->maxwidth)
- ref_list->maxwidth = item.len;
+ if (item.width > ref_list->maxwidth)
+ ref_list->maxwidth = item.width;
print_ref_item(&item, ref_list->maxwidth, ref_list->verbose, ref_list->abbrev, 1, "");
free(item.name);
}
@@ -712,62 +714,65 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
int delete = 0, rename = 0, force_create = 0, list = 0;
int verbose = 0, abbrev = -1, detached = 0;
int reflog = 0, edit_description = 0;
- int quiet = 0;
+ int quiet = 0, unset_upstream = 0;
+ const char *new_upstream = NULL;
enum branch_track track;
int kinds = REF_LOCAL_BRANCH;
struct commit_list *with_commit = NULL;
struct option options[] = {
- OPT_GROUP("Generic options"),
+ OPT_GROUP(N_("Generic options")),
OPT__VERBOSE(&verbose,
- "show hash and subject, give twice for upstream branch"),
- OPT__QUIET(&quiet, "suppress informational messages"),
- OPT_SET_INT('t', "track", &track, "set up tracking mode (see git-pull(1))",
+ N_("show hash and subject, give twice for upstream branch")),
+ OPT__QUIET(&quiet, N_("suppress informational messages")),
+ OPT_SET_INT('t', "track", &track, N_("set up tracking mode (see git-pull(1))"),
BRANCH_TRACK_EXPLICIT),
- OPT_SET_INT( 0, "set-upstream", &track, "change upstream info",
+ OPT_SET_INT( 0, "set-upstream", &track, N_("change upstream info"),
BRANCH_TRACK_OVERRIDE),
- OPT__COLOR(&branch_use_color, "use colored output"),
- OPT_SET_INT('r', "remotes", &kinds, "act on remote-tracking branches",
+ OPT_STRING('u', "set-upstream-to", &new_upstream, "upstream", "change the upstream info"),
+ OPT_BOOLEAN(0, "unset-upstream", &unset_upstream, "Unset the upstream info"),
+ OPT__COLOR(&branch_use_color, N_("use colored output")),
+ OPT_SET_INT('r', "remotes", &kinds, N_("act on remote-tracking branches"),
REF_REMOTE_BRANCH),
{
- OPTION_CALLBACK, 0, "contains", &with_commit, "commit",
- "print only branches that contain the commit",
+ OPTION_CALLBACK, 0, "contains", &with_commit, N_("commit"),
+ N_("print only branches that contain the commit"),
PARSE_OPT_LASTARG_DEFAULT,
parse_opt_with_commit, (intptr_t)"HEAD",
},
{
- OPTION_CALLBACK, 0, "with", &with_commit, "commit",
- "print only branches that contain the commit",
+ OPTION_CALLBACK, 0, "with", &with_commit, N_("commit"),
+ N_("print only branches that contain the commit"),
PARSE_OPT_HIDDEN | PARSE_OPT_LASTARG_DEFAULT,
parse_opt_with_commit, (intptr_t) "HEAD",
},
OPT__ABBREV(&abbrev),
- OPT_GROUP("Specific git-branch actions:"),
- OPT_SET_INT('a', "all", &kinds, "list both remote-tracking and local branches",
+ OPT_GROUP(N_("Specific git-branch actions:")),
+ OPT_SET_INT('a', "all", &kinds, N_("list both remote-tracking and local branches"),
REF_REMOTE_BRANCH | REF_LOCAL_BRANCH),
- OPT_BIT('d', "delete", &delete, "delete fully merged branch", 1),
- OPT_BIT('D', NULL, &delete, "delete branch (even if not merged)", 2),
- OPT_BIT('m', "move", &rename, "move/rename a branch and its reflog", 1),
- OPT_BIT('M', NULL, &rename, "move/rename a branch, even if target exists", 2),
- OPT_BOOLEAN(0, "list", &list, "list branch names"),
- OPT_BOOLEAN('l', "create-reflog", &reflog, "create the branch's reflog"),
+ OPT_BIT('d', "delete", &delete, N_("delete fully merged branch"), 1),
+ OPT_BIT('D', NULL, &delete, N_("delete branch (even if not merged)"), 2),
+ OPT_BIT('m', "move", &rename, N_("move/rename a branch and its reflog"), 1),
+ OPT_BIT('M', NULL, &rename, N_("move/rename a branch, even if target exists"), 2),
+ OPT_BOOLEAN(0, "list", &list, N_("list branch names")),
+ OPT_BOOLEAN('l', "create-reflog", &reflog, N_("create the branch's reflog")),
OPT_BOOLEAN(0, "edit-description", &edit_description,
- "edit the description for the branch"),
- OPT__FORCE(&force_create, "force creation (when already exists)"),
+ N_("edit the description for the branch")),
+ OPT__FORCE(&force_create, N_("force creation (when already exists)")),
{
OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref,
- "commit", "print only not merged branches",
+ N_("commit"), N_("print only not merged branches"),
PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG,
opt_parse_merge_filter, (intptr_t) "HEAD",
},
{
OPTION_CALLBACK, 0, "merged", &merge_filter_ref,
- "commit", "print only merged branches",
+ N_("commit"), N_("print only merged branches"),
PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG,
opt_parse_merge_filter, (intptr_t) "HEAD",
},
- OPT_COLUMN(0, "column", &colopts, "list branches in columns"),
+ OPT_COLUMN(0, "column", &colopts, N_("list branches in columns")),
OPT_END(),
};
@@ -794,10 +799,10 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
0);
- if (!delete && !rename && !edit_description && argc == 0)
+ if (!delete && !rename && !edit_description && !new_upstream && !unset_upstream && argc == 0)
list = 1;
- if (!!delete + !!rename + !!force_create + !!list > 1)
+ if (!!delete + !!rename + !!force_create + !!list + !!new_upstream + !!unset_upstream > 1)
usage_with_options(builtin_branch_usage, options);
if (abbrev == -1)
@@ -852,11 +857,62 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
rename_branch(argv[0], argv[1], rename > 1);
else
usage_with_options(builtin_branch_usage, options);
+ } else if (new_upstream) {
+ struct branch *branch = branch_get(argv[0]);
+
+ if (!ref_exists(branch->refname))
+ die(_("branch '%s' does not exist"), branch->name);
+
+ /*
+ * create_branch takes care of setting up the tracking
+ * info and making sure new_upstream is correct
+ */
+ create_branch(head, branch->name, new_upstream, 0, 0, 0, quiet, BRANCH_TRACK_OVERRIDE);
+ } else if (unset_upstream) {
+ struct branch *branch = branch_get(argv[0]);
+ struct strbuf buf = STRBUF_INIT;
+
+ if (!branch_has_merge_config(branch)) {
+ die(_("Branch '%s' has no upstream information"), branch->name);
+ }
+
+ strbuf_addf(&buf, "branch.%s.remote", branch->name);
+ git_config_set_multivar(buf.buf, NULL, NULL, 1);
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "branch.%s.merge", branch->name);
+ git_config_set_multivar(buf.buf, NULL, NULL, 1);
+ strbuf_release(&buf);
} else if (argc > 0 && argc <= 2) {
+ struct branch *branch = branch_get(argv[0]);
+ int branch_existed = 0, remote_tracking = 0;
+ struct strbuf buf = STRBUF_INIT;
+
if (kinds != REF_LOCAL_BRANCH)
die(_("-a and -r options to 'git branch' do not make sense with a branch name"));
+
+ if (track == BRANCH_TRACK_OVERRIDE)
+ fprintf(stderr, _("The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to\n"));
+
+ strbuf_addf(&buf, "refs/remotes/%s", branch->name);
+ remote_tracking = ref_exists(buf.buf);
+ strbuf_release(&buf);
+
+ branch_existed = ref_exists(branch->refname);
create_branch(head, argv[0], (argc == 2) ? argv[1] : head,
force_create, reflog, 0, quiet, track);
+
+ /*
+ * We only show the instructions if the user gave us
+ * one branch which doesn't exist locally, but is the
+ * name of a remote-tracking branch.
+ */
+ if (argc == 1 && track == BRANCH_TRACK_OVERRIDE &&
+ !branch_existed && remote_tracking) {
+ fprintf(stderr, _("\nIf you wanted to make '%s' track '%s', do this:\n\n"), head, branch->name);
+ fprintf(stderr, _(" git branch -d %s\n"), branch->name);
+ fprintf(stderr, _(" git branch --set-upstream-to %s\n"), branch->name);
+ }
+
} else
usage_with_options(builtin_branch_usage, options);
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 0eca2d7..00528dd 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -244,8 +244,8 @@ static int batch_objects(int print_contents)
}
static const char * const cat_file_usage[] = {
- "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>",
- "git cat-file (--batch|--batch-check) < <list_of_objects>",
+ N_("git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>"),
+ N_("git cat-file (--batch|--batch-check) < <list_of_objects>"),
NULL
};
@@ -263,19 +263,19 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
const char *exp_type = NULL, *obj_name = NULL;
const struct option options[] = {
- OPT_GROUP("<type> can be one of: blob, tree, commit, tag"),
- OPT_SET_INT('t', NULL, &opt, "show object type", 't'),
- OPT_SET_INT('s', NULL, &opt, "show object size", 's'),
+ OPT_GROUP(N_("<type> can be one of: blob, tree, commit, tag")),
+ OPT_SET_INT('t', NULL, &opt, N_("show object type"), 't'),
+ OPT_SET_INT('s', NULL, &opt, N_("show object size"), 's'),
OPT_SET_INT('e', NULL, &opt,
- "exit with zero when there's no error", 'e'),
- OPT_SET_INT('p', NULL, &opt, "pretty-print object's content", 'p'),
+ N_("exit with zero when there's no error"), 'e'),
+ OPT_SET_INT('p', NULL, &opt, N_("pretty-print object's content"), 'p'),
OPT_SET_INT(0, "textconv", &opt,
- "for blob objects, run textconv on object's content", 'c'),
+ N_("for blob objects, run textconv on object's content"), 'c'),
OPT_SET_INT(0, "batch", &batch,
- "show info and content of objects fed from the standard input",
+ N_("show info and content of objects fed from the standard input"),
BATCH),
OPT_SET_INT(0, "batch-check", &batch,
- "show info about objects fed from the standard input",
+ N_("show info about objects fed from the standard input"),
BATCH_CHECK),
OPT_END()
};
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 9000c2d..075d01d 100644
--- a/builtin/check-attr.c
+++ b/builtin/check-attr.c
@@ -8,19 +8,19 @@ static int all_attrs;
static int cached_attrs;
static int stdin_paths;
static const char * const check_attr_usage[] = {
-"git check-attr [-a | --all | attr...] [--] pathname...",
-"git check-attr --stdin [-z] [-a | --all | attr...] < <list-of-paths>",
+N_("git check-attr [-a | --all | attr...] [--] pathname..."),
+N_("git check-attr --stdin [-z] [-a | --all | attr...] < <list-of-paths>"),
NULL
};
static int null_term_line;
static const struct option check_attr_options[] = {
- OPT_BOOLEAN('a', "all", &all_attrs, "report all attributes set on file"),
- OPT_BOOLEAN(0, "cached", &cached_attrs, "use .gitattributes only from the index"),
- OPT_BOOLEAN(0 , "stdin", &stdin_paths, "read file names from stdin"),
+ OPT_BOOLEAN('a', "all", &all_attrs, N_("report all attributes set on file")),
+ OPT_BOOLEAN(0, "cached", &cached_attrs, N_("use .gitattributes only from the index")),
+ OPT_BOOLEAN(0 , "stdin", &stdin_paths, N_("read file names from stdin")),
OPT_BOOLEAN('z', NULL, &null_term_line,
- "input paths are terminated by a null character"),
+ N_("input paths are terminated by a null character")),
OPT_END()
};
diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c
index c16d82b..b1feda7 100644
--- a/builtin/checkout-index.c
+++ b/builtin/checkout-index.c
@@ -123,7 +123,7 @@ static void checkout_all(const char *prefix, int prefix_length)
}
static const char * const builtin_checkout_index_usage[] = {
- "git checkout-index [options] [--] [<file>...]",
+ N_("git checkout-index [options] [--] [<file>...]"),
NULL
};
@@ -184,27 +184,27 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
int force = 0, quiet = 0, not_new = 0;
struct option builtin_checkout_index_options[] = {
OPT_BOOLEAN('a', "all", &all,
- "checks out all files in the index"),
- OPT__FORCE(&force, "forces overwrite of existing files"),
+ N_("check out all files in the index")),
+ OPT__FORCE(&force, N_("force overwrite of existing files")),
OPT__QUIET(&quiet,
- "no warning for existing files and files not in index"),
+ N_("no warning for existing files and files not in index")),
OPT_BOOLEAN('n', "no-create", &not_new,
- "don't checkout new files"),
+ N_("don't checkout new files")),
{ OPTION_CALLBACK, 'u', "index", &newfd, NULL,
- "update stat information in the index file",
+ N_("update stat information in the index file"),
PARSE_OPT_NOARG, option_parse_u },
{ OPTION_CALLBACK, 'z', NULL, NULL, NULL,
- "paths are separated with NUL character",
+ N_("paths are separated with NUL character"),
PARSE_OPT_NOARG, option_parse_z },
OPT_BOOLEAN(0, "stdin", &read_from_stdin,
- "read list of paths from the standard input"),
+ N_("read list of paths from the standard input")),
OPT_BOOLEAN(0, "temp", &to_tempfile,
- "write the content to temporary files"),
- OPT_CALLBACK(0, "prefix", NULL, "string",
- "when creating files, prepend <string>",
+ N_("write the content to temporary files")),
+ OPT_CALLBACK(0, "prefix", NULL, N_("string"),
+ N_("when creating files, prepend <string>"),
option_parse_prefix),
OPT_CALLBACK(0, "stage", NULL, NULL,
- "copy out the files from named stage",
+ N_("copy out the files from named stage"),
option_parse_stage),
OPT_END()
};
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 7d922c6..781295b 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -22,29 +22,31 @@
#include "argv-array.h"
static const char * const checkout_usage[] = {
- "git checkout [options] <branch>",
- "git checkout [options] [<branch>] -- <file>...",
+ N_("git checkout [options] <branch>"),
+ N_("git checkout [options] [<branch>] -- <file>..."),
NULL,
};
struct checkout_opts {
+ int patch_mode;
int quiet;
int merge;
int force;
int force_detach;
int writeout_stage;
- int writeout_error;
int overwrite_ignore;
- /* not set by parse_options */
- int branch_exists;
-
const char *new_branch;
const char *new_branch_force;
const char *new_orphan_branch;
int new_branch_log;
enum branch_track track;
struct diff_options diff_options;
+
+ int branch_exists;
+ const char *prefix;
+ const char **pathspec;
+ struct tree *source_tree;
};
static int post_checkout_hook(struct commit *old, struct commit *new,
@@ -215,8 +217,8 @@ static int checkout_merged(int pos, struct checkout *state)
return status;
}
-static int checkout_paths(struct tree *source_tree, const char **pathspec,
- const char *prefix, struct checkout_opts *opts)
+static int checkout_paths(const struct checkout_opts *opts,
+ const char *revision)
{
int pos;
struct checkout state;
@@ -228,37 +230,65 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
int stage = opts->writeout_stage;
int merge = opts->merge;
int newfd;
- struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
+ struct lock_file *lock_file;
+
+ if (opts->track != BRANCH_TRACK_UNSPECIFIED)
+ die(_("'%s' cannot be used with updating paths"), "--track");
+
+ if (opts->new_branch_log)
+ die(_("'%s' cannot be used with updating paths"), "-l");
+
+ if (opts->force && opts->patch_mode)
+ die(_("'%s' cannot be used with updating paths"), "-f");
+
+ if (opts->force_detach)
+ die(_("'%s' cannot be used with updating paths"), "--detach");
+
+ if (opts->merge && opts->patch_mode)
+ die(_("'%s' cannot be used with %s"), "--merge", "--patch");
+
+ if (opts->force && opts->merge)
+ die(_("'%s' cannot be used with %s"), "-f", "-m");
+
+ if (opts->new_branch)
+ die(_("Cannot update paths and switch to branch '%s' at the same time."),
+ opts->new_branch);
+
+ if (opts->patch_mode)
+ return run_add_interactive(revision, "--patch=checkout",
+ opts->pathspec);
+
+ lock_file = xcalloc(1, sizeof(struct lock_file));
newfd = hold_locked_index(lock_file, 1);
- if (read_cache_preload(pathspec) < 0)
+ if (read_cache_preload(opts->pathspec) < 0)
return error(_("corrupt index file"));
- if (source_tree)
- read_tree_some(source_tree, pathspec);
+ if (opts->source_tree)
+ read_tree_some(opts->source_tree, opts->pathspec);
- for (pos = 0; pathspec[pos]; pos++)
+ for (pos = 0; opts->pathspec[pos]; pos++)
;
ps_matched = xcalloc(1, pos);
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
- if (source_tree && !(ce->ce_flags & CE_UPDATE))
+ if (opts->source_tree && !(ce->ce_flags & CE_UPDATE))
continue;
- match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
+ match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
}
- if (report_path_error(ps_matched, pathspec, prefix))
+ if (report_path_error(ps_matched, opts->pathspec, opts->prefix))
return 1;
/* "checkout -m path" to recreate conflicted state */
if (opts->merge)
- unmerge_cache(pathspec);
+ unmerge_cache(opts->pathspec);
/* Any unmerged paths? */
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
- if (match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
+ if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
if (!ce_stage(ce))
continue;
if (opts->force) {
@@ -283,9 +313,9 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
state.refresh_cache = 1;
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
- if (source_tree && !(ce->ce_flags & CE_UPDATE))
+ if (opts->source_tree && !(ce->ce_flags & CE_UPDATE))
continue;
- if (match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
+ if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
if (!ce_stage(ce)) {
errs |= checkout_entry(ce, &state, NULL);
continue;
@@ -309,7 +339,8 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
return errs;
}
-static void show_local_changes(struct object *head, struct diff_options *opts)
+static void show_local_changes(struct object *head,
+ const struct diff_options *opts)
{
struct rev_info rev;
/* I think we want full paths, even if we're in a subdirectory. */
@@ -331,7 +362,8 @@ static void describe_detached_head(const char *msg, struct commit *commit)
strbuf_release(&sb);
}
-static int reset_tree(struct tree *tree, struct checkout_opts *o, int worktree)
+static int reset_tree(struct tree *tree, const struct checkout_opts *o,
+ int worktree, int *writeout_error)
{
struct unpack_trees_options opts;
struct tree_desc tree_desc;
@@ -350,7 +382,7 @@ static int reset_tree(struct tree *tree, struct checkout_opts *o, int worktree)
init_tree_desc(&tree_desc, tree->buffer, tree->size);
switch (unpack_trees(1, &tree_desc, &opts)) {
case -2:
- o->writeout_error = 1;
+ *writeout_error = 1;
/*
* We return 0 nevertheless, as the index is all right
* and more importantly we have made best efforts to
@@ -381,8 +413,10 @@ static void setup_branch_path(struct branch_info *branch)
branch->path = strbuf_detach(&buf, NULL);
}
-static int merge_working_tree(struct checkout_opts *opts,
- struct branch_info *old, struct branch_info *new)
+static int merge_working_tree(const struct checkout_opts *opts,
+ struct branch_info *old,
+ struct branch_info *new,
+ int *writeout_error)
{
int ret;
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
@@ -393,7 +427,7 @@ static int merge_working_tree(struct checkout_opts *opts,
resolve_undo_clear();
if (opts->force) {
- ret = reset_tree(new->commit->tree, opts, 1);
+ ret = reset_tree(new->commit->tree, opts, 1, writeout_error);
if (ret)
return ret;
} else {
@@ -479,7 +513,8 @@ static int merge_working_tree(struct checkout_opts *opts,
o.verbosity = 0;
work = write_tree_from_memory(&o);
- ret = reset_tree(new->commit->tree, opts, 1);
+ ret = reset_tree(new->commit->tree, opts, 1,
+ writeout_error);
if (ret)
return ret;
o.ancestor = old->name;
@@ -487,7 +522,8 @@ static int merge_working_tree(struct checkout_opts *opts,
o.branch2 = "local";
merge_trees(&o, new->commit->tree, work,
old->commit->tree, &result);
- ret = reset_tree(new->commit->tree, opts, 0);
+ ret = reset_tree(new->commit->tree, opts, 0,
+ writeout_error);
if (ret)
return ret;
}
@@ -514,7 +550,7 @@ static void report_tracking(struct branch_info *new)
strbuf_release(&sb);
}
-static void update_refs_for_switch(struct checkout_opts *opts,
+static void update_refs_for_switch(const struct checkout_opts *opts,
struct branch_info *old,
struct branch_info *new)
{
@@ -701,13 +737,14 @@ static void orphaned_commit_warning(struct commit *old, struct commit *new)
free(refs.objects);
}
-static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
+static int switch_branches(const struct checkout_opts *opts,
+ struct branch_info *new)
{
int ret = 0;
struct branch_info old;
void *path_to_free;
unsigned char rev[20];
- int flag;
+ int flag, writeout_error = 0;
memset(&old, 0, sizeof(old));
old.path = path_to_free = resolve_refdup("HEAD", rev, 0, &flag);
old.commit = lookup_commit_reference_gently(rev, 1);
@@ -725,7 +762,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
parse_commit(new->commit);
}
- ret = merge_working_tree(opts, &old, new);
+ ret = merge_working_tree(opts, &old, new, &writeout_error);
if (ret) {
free(path_to_free);
return ret;
@@ -738,7 +775,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
ret = post_checkout_hook(old.commit, new->commit, 1);
free(path_to_free);
- return ret || opts->writeout_error;
+ return ret || writeout_error;
}
static int git_checkout_config(const char *var, const char *value, void *cb)
@@ -755,12 +792,6 @@ static int git_checkout_config(const char *var, const char *value, void *cb)
return git_xmerge_config(var, value, NULL);
}
-static int interactive_checkout(const char *revision, const char **pathspec,
- struct checkout_opts *opts)
-{
- return run_add_interactive(revision, "--patch=checkout", pathspec);
-}
-
struct tracking_name_data {
const char *name;
char *remote;
@@ -910,7 +941,7 @@ static int parse_branchname_arg(int argc, const char **argv,
return argcount;
}
-static int switch_unborn_to_new_branch(struct checkout_opts *opts)
+static int switch_unborn_to_new_branch(const struct checkout_opts *opts)
{
int status;
struct strbuf branch_ref = STRBUF_INIT;
@@ -923,38 +954,80 @@ static int switch_unborn_to_new_branch(struct checkout_opts *opts)
return status;
}
+static int checkout_branch(struct checkout_opts *opts,
+ struct branch_info *new)
+{
+ if (opts->pathspec)
+ die(_("paths cannot be used with switching branches"));
+
+ if (opts->patch_mode)
+ die(_("'%s' cannot be used with switching branches"),
+ "--patch");
+
+ if (opts->writeout_stage)
+ die(_("'%s' cannot be used with switching branches"),
+ "--ours/--theirs");
+
+ if (opts->force && opts->merge)
+ die(_("'%s' cannot be used with '%s'"), "-f", "-m");
+
+ if (opts->force_detach && opts->new_branch)
+ die(_("'%s' cannot be used with '%s'"),
+ "--detach", "-b/-B/--orphan");
+
+ if (opts->new_orphan_branch) {
+ if (opts->track != BRANCH_TRACK_UNSPECIFIED)
+ die(_("'%s' cannot be used with '%s'"), "--orphan", "-t");
+ } else if (opts->force_detach) {
+ if (opts->track != BRANCH_TRACK_UNSPECIFIED)
+ die(_("'%s' cannot be used with '%s'"), "--detach", "-t");
+ } else if (opts->track == BRANCH_TRACK_UNSPECIFIED)
+ opts->track = git_branch_track;
+
+ if (new->name && !new->commit)
+ die(_("Cannot switch branch to a non-commit '%s'"),
+ new->name);
+
+ if (!new->commit && opts->new_branch) {
+ unsigned char rev[20];
+ int flag;
+
+ if (!read_ref_full("HEAD", rev, 0, &flag) &&
+ (flag & REF_ISSYMREF) && is_null_sha1(rev))
+ return switch_unborn_to_new_branch(opts);
+ }
+ return switch_branches(opts, new);
+}
+
int cmd_checkout(int argc, const char **argv, const char *prefix)
{
struct checkout_opts opts;
- unsigned char rev[20];
struct branch_info new;
- struct tree *source_tree = NULL;
char *conflict_style = NULL;
- int patch_mode = 0;
int dwim_new_local_branch = 1;
struct option options[] = {
- OPT__QUIET(&opts.quiet, "suppress progress reporting"),
- OPT_STRING('b', NULL, &opts.new_branch, "branch",
- "create and checkout a new branch"),
- OPT_STRING('B', NULL, &opts.new_branch_force, "branch",
- "create/reset and checkout a branch"),
- OPT_BOOLEAN('l', NULL, &opts.new_branch_log, "create reflog for new branch"),
- OPT_BOOLEAN(0, "detach", &opts.force_detach, "detach the HEAD at named commit"),
- OPT_SET_INT('t', "track", &opts.track, "set upstream info for new branch",
+ OPT__QUIET(&opts.quiet, N_("suppress progress reporting")),
+ OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
+ N_("create and checkout a new branch")),
+ OPT_STRING('B', NULL, &opts.new_branch_force, N_("branch"),
+ N_("create/reset and checkout a branch")),
+ OPT_BOOLEAN('l', NULL, &opts.new_branch_log, N_("create reflog for new branch")),
+ OPT_BOOLEAN(0, "detach", &opts.force_detach, N_("detach the HEAD at named commit")),
+ OPT_SET_INT('t', "track", &opts.track, N_("set upstream info for new branch"),
BRANCH_TRACK_EXPLICIT),
- OPT_STRING(0, "orphan", &opts.new_orphan_branch, "new branch", "new unparented branch"),
- OPT_SET_INT('2', "ours", &opts.writeout_stage, "checkout our version for unmerged files",
+ OPT_STRING(0, "orphan", &opts.new_orphan_branch, N_("new branch"), N_("new unparented branch")),
+ OPT_SET_INT('2', "ours", &opts.writeout_stage, N_("checkout our version for unmerged files"),
2),
- OPT_SET_INT('3', "theirs", &opts.writeout_stage, "checkout their version for unmerged files",
+ OPT_SET_INT('3', "theirs", &opts.writeout_stage, N_("checkout their version for unmerged files"),
3),
- OPT__FORCE(&opts.force, "force checkout (throw away local modifications)"),
- OPT_BOOLEAN('m', "merge", &opts.merge, "perform a 3-way merge with the new branch"),
- OPT_BOOLEAN(0, "overwrite-ignore", &opts.overwrite_ignore, "update ignored files (default)"),
- OPT_STRING(0, "conflict", &conflict_style, "style",
- "conflict style (merge or diff3)"),
- OPT_BOOLEAN('p', "patch", &patch_mode, "select hunks interactively"),
+ OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)")),
+ OPT_BOOLEAN('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")),
+ OPT_BOOLEAN(0, "overwrite-ignore", &opts.overwrite_ignore, N_("update ignored files (default)")),
+ OPT_STRING(0, "conflict", &conflict_style, N_("style"),
+ N_("conflict style (merge or diff3)")),
+ OPT_BOOLEAN('p', "patch", &opts.patch_mode, N_("select hunks interactively")),
{ OPTION_BOOLEAN, 0, "guess", &dwim_new_local_branch, NULL,
- "second guess 'git checkout no-such-branch'",
+ N_("second guess 'git checkout no-such-branch'"),
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
OPT_END(),
};
@@ -962,6 +1035,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
memset(&opts, 0, sizeof(opts));
memset(&new, 0, sizeof(new));
opts.overwrite_ignore = 1;
+ opts.prefix = prefix;
gitmodules_config();
git_config(git_checkout_config, &opts);
@@ -971,26 +1045,27 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, checkout_usage,
PARSE_OPT_KEEP_DASHDASH);
- /* we can assume from now on new_branch = !new_branch_force */
- if (opts.new_branch && opts.new_branch_force)
- die(_("-B cannot be used with -b"));
+ if (conflict_style) {
+ opts.merge = 1; /* implied */
+ git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
+ }
+
+ if ((!!opts.new_branch + !!opts.new_branch_force + !!opts.new_orphan_branch) > 1)
+ die(_("-b, -B and --orphan are mutually exclusive"));
- /* copy -B over to -b, so that we can just check the latter */
+ /*
+ * From here on, new_branch will contain the branch to be checked out,
+ * and new_branch_force and new_orphan_branch will tell us which one of
+ * -b/-B/--orphan is being used.
+ */
if (opts.new_branch_force)
opts.new_branch = opts.new_branch_force;
- if (patch_mode && (opts.track > 0 || opts.new_branch
- || opts.new_branch_log || opts.merge || opts.force
- || opts.force_detach))
- die (_("--patch is incompatible with all other options"));
-
- if (opts.force_detach && (opts.new_branch || opts.new_orphan_branch))
- die(_("--detach cannot be used with -b/-B/--orphan"));
- if (opts.force_detach && 0 < opts.track)
- die(_("--detach cannot be used with -t"));
+ if (opts.new_orphan_branch)
+ opts.new_branch = opts.new_orphan_branch;
- /* --track without -b should DWIM */
- if (0 < opts.track && !opts.new_branch) {
+ /* --track without -b/-B/--orphan should DWIM */
+ if (opts.track != BRANCH_TRACK_UNSPECIFIED && !opts.new_branch) {
const char *argv0 = argv[0];
if (!argc || !strcmp(argv0, "--"))
die (_("--track needs a branch name"));
@@ -1004,22 +1079,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
opts.new_branch = argv0 + 1;
}
- if (opts.new_orphan_branch) {
- if (opts.new_branch)
- die(_("--orphan and -b|-B are mutually exclusive"));
- if (opts.track > 0)
- die(_("--orphan cannot be used with -t"));
- opts.new_branch = opts.new_orphan_branch;
- }
-
- if (conflict_style) {
- opts.merge = 1; /* implied */
- git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
- }
-
- if (opts.force && opts.merge)
- die(_("git checkout: -f and -m are incompatible"));
-
/*
* Extract branch name from command line arguments, so
* all that is left is pathspecs.
@@ -1034,73 +1093,56 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
* remote branches, erroring out for invalid or ambiguous cases.
*/
if (argc) {
+ unsigned char rev[20];
int dwim_ok =
- !patch_mode &&
+ !opts.patch_mode &&
dwim_new_local_branch &&
opts.track == BRANCH_TRACK_UNSPECIFIED &&
!opts.new_branch;
int n = parse_branchname_arg(argc, argv, dwim_ok,
- &new, &source_tree, rev, &opts.new_branch);
+ &new, &opts.source_tree,
+ rev, &opts.new_branch);
argv += n;
argc -= n;
}
- if (opts.track == BRANCH_TRACK_UNSPECIFIED)
- opts.track = git_branch_track;
-
if (argc) {
- const char **pathspec = get_pathspec(prefix, argv);
+ opts.pathspec = get_pathspec(prefix, argv);
- if (!pathspec)
+ if (!opts.pathspec)
die(_("invalid path specification"));
- if (patch_mode)
- return interactive_checkout(new.name, pathspec, &opts);
-
- /* Checkout paths */
- if (opts.new_branch) {
- if (argc == 1) {
- die(_("git checkout: updating paths is incompatible with switching branches.\nDid you intend to checkout '%s' which can not be resolved as commit?"), argv[0]);
- } else {
- die(_("git checkout: updating paths is incompatible with switching branches."));
- }
- }
+ /*
+ * Try to give more helpful suggestion.
+ * new_branch && argc > 1 will be caught later.
+ */
+ if (opts.new_branch && argc == 1)
+ die(_("Cannot update paths and switch to branch '%s' at the same time.\n"
+ "Did you intend to checkout '%s' which can not be resolved as commit?"),
+ opts.new_branch, argv[0]);
if (opts.force_detach)
- die(_("git checkout: --detach does not take a path argument"));
+ die(_("git checkout: --detach does not take a path argument '%s'"),
+ argv[0]);
if (1 < !!opts.writeout_stage + !!opts.force + !!opts.merge)
- die(_("git checkout: --ours/--theirs, --force and --merge are incompatible when\nchecking out of the index."));
-
- return checkout_paths(source_tree, pathspec, prefix, &opts);
+ die(_("git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
+ "checking out of the index."));
}
- if (patch_mode)
- return interactive_checkout(new.name, NULL, &opts);
-
if (opts.new_branch) {
struct strbuf buf = STRBUF_INIT;
- opts.branch_exists = validate_new_branchname(opts.new_branch, &buf,
- !!opts.new_branch_force,
- !!opts.new_branch_force);
+ opts.branch_exists =
+ validate_new_branchname(opts.new_branch, &buf,
+ !!opts.new_branch_force,
+ !!opts.new_branch_force);
strbuf_release(&buf);
}
- if (new.name && !new.commit) {
- die(_("Cannot switch branch to a non-commit."));
- }
- if (opts.writeout_stage)
- die(_("--ours/--theirs is incompatible with switching branches."));
-
- if (!new.commit && opts.new_branch) {
- unsigned char rev[20];
- int flag;
-
- if (!read_ref_full("HEAD", rev, 0, &flag) &&
- (flag & REF_ISSYMREF) && is_null_sha1(rev))
- return switch_unborn_to_new_branch(&opts);
- }
- return switch_branches(&opts, &new);
+ if (opts.patch_mode || opts.pathspec)
+ return checkout_paths(&opts, new.name);
+ else
+ return checkout_branch(&opts, &new);
}
diff --git a/builtin/clean.c b/builtin/clean.c
index 0c7b3d0..69c1cda 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -16,7 +16,7 @@
static int force = -1; /* unset */
static const char *const builtin_clean_usage[] = {
- "git clean [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>...",
+ N_("git clean [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."),
NULL
};
@@ -48,16 +48,16 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
const char *qname;
char *seen = NULL;
struct option options[] = {
- OPT__QUIET(&quiet, "do not print names of files removed"),
- OPT__DRY_RUN(&show_only, "dry run"),
- OPT__FORCE(&force, "force"),
+ OPT__QUIET(&quiet, N_("do not print names of files removed")),
+ OPT__DRY_RUN(&show_only, N_("dry run")),
+ OPT__FORCE(&force, N_("force")),
OPT_BOOLEAN('d', NULL, &remove_directories,
- "remove whole directories"),
- { OPTION_CALLBACK, 'e', "exclude", &exclude_list, "pattern",
- "add <pattern> to ignore rules", PARSE_OPT_NONEG, exclude_cb },
- OPT_BOOLEAN('x', NULL, &ignored, "remove ignored files, too"),
+ N_("remove whole directories")),
+ { OPTION_CALLBACK, 'e', "exclude", &exclude_list, N_("pattern"),
+ N_("add <pattern> to ignore rules"), PARSE_OPT_NONEG, exclude_cb },
+ OPT_BOOLEAN('x', NULL, &ignored, N_("remove ignored files, too")),
OPT_BOOLEAN('X', NULL, &ignored_only,
- "remove only ignored files"),
+ N_("remove only ignored files")),
OPT_END()
};
diff --git a/builtin/clone.c b/builtin/clone.c
index 0d663e3..ec2f75b 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -33,7 +33,7 @@
*
*/
static const char * const builtin_clone_usage[] = {
- "git clone [options] [--] <repo> [<dir>]",
+ N_("git clone [options] [--] <repo> [<dir>]"),
NULL
};
@@ -61,43 +61,43 @@ static int opt_parse_reference(const struct option *opt, const char *arg, int un
static struct option builtin_clone_options[] = {
OPT__VERBOSITY(&option_verbosity),
OPT_BOOL(0, "progress", &option_progress,
- "force progress reporting"),
+ N_("force progress reporting")),
OPT_BOOLEAN('n', "no-checkout", &option_no_checkout,
- "don't create a checkout"),
- OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"),
+ N_("don't create a checkout")),
+ OPT_BOOLEAN(0, "bare", &option_bare, N_("create a bare repository")),
{ OPTION_BOOLEAN, 0, "naked", &option_bare, NULL,
- "create a bare repository",
+ N_("create a bare repository"),
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
OPT_BOOLEAN(0, "mirror", &option_mirror,
- "create a mirror repository (implies bare)"),
+ N_("create a mirror repository (implies bare)")),
OPT_BOOL('l', "local", &option_local,
- "to clone from a local repository"),
+ N_("to clone from a local repository")),
OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks,
- "don't use local hardlinks, always copy"),
+ N_("don't use local hardlinks, always copy")),
OPT_BOOLEAN('s', "shared", &option_shared,
- "setup as shared repository"),
+ N_("setup as shared repository")),
OPT_BOOLEAN(0, "recursive", &option_recursive,
- "initialize submodules in the clone"),
+ N_("initialize submodules in the clone")),
OPT_BOOLEAN(0, "recurse-submodules", &option_recursive,
- "initialize submodules in the clone"),
- OPT_STRING(0, "template", &option_template, "template-directory",
- "directory from which templates will be used"),
- OPT_CALLBACK(0 , "reference", &option_reference, "repo",
- "reference repository", &opt_parse_reference),
- OPT_STRING('o', "origin", &option_origin, "name",
- "use <name> instead of 'origin' to track upstream"),
- OPT_STRING('b', "branch", &option_branch, "branch",
- "checkout <branch> instead of the remote's HEAD"),
- OPT_STRING('u', "upload-pack", &option_upload_pack, "path",
- "path to git-upload-pack on the remote"),
- OPT_STRING(0, "depth", &option_depth, "depth",
- "create a shallow clone of that depth"),
+ N_("initialize submodules in the clone")),
+ OPT_STRING(0, "template", &option_template, N_("template-directory"),
+ N_("directory from which templates will be used")),
+ OPT_CALLBACK(0 , "reference", &option_reference, N_("repo"),
+ N_("reference repository"), &opt_parse_reference),
+ OPT_STRING('o', "origin", &option_origin, N_("name"),
+ N_("use <name> instead of 'origin' to track upstream")),
+ OPT_STRING('b', "branch", &option_branch, N_("branch"),
+ N_("checkout <branch> instead of the remote's HEAD")),
+ OPT_STRING('u', "upload-pack", &option_upload_pack, N_("path"),
+ N_("path to git-upload-pack on the remote")),
+ OPT_STRING(0, "depth", &option_depth, N_("depth"),
+ N_("create a shallow clone of that depth")),
OPT_BOOL(0, "single-branch", &option_single_branch,
- "clone only one branch, HEAD or --branch"),
- OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
- "separate git dir from working tree"),
- OPT_STRING_LIST('c', "config", &option_config, "key=value",
- "set config inside the new repository"),
+ N_("clone only one branch, HEAD or --branch")),
+ OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
+ N_("separate git dir from working tree")),
+ OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
+ N_("set config inside the new repository")),
OPT_END()
};
@@ -236,7 +236,7 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)
/* Beware: real_path() and mkpath() return static buffer */
ref_git = xstrdup(real_path(item->string));
if (is_directory(mkpath("%s/.git/objects", ref_git))) {
- char *ref_git_git = xstrdup(mkpath("%s/.git", 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)))
@@ -748,7 +748,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
git_dir = xstrdup(dir);
else {
work_tree = dir;
- git_dir = xstrdup(mkpath("%s/.git", dir));
+ git_dir = mkpathdup("%s/.git", dir);
}
if (!option_bare) {
diff --git a/builtin/column.c b/builtin/column.c
index 5ea798a..e125a55 100644
--- a/builtin/column.c
+++ b/builtin/column.c
@@ -6,7 +6,7 @@
#include "column.h"
static const char * const builtin_column_usage[] = {
- "git column [options]",
+ N_("git column [options]"),
NULL
};
static unsigned int colopts;
@@ -23,13 +23,13 @@ int cmd_column(int argc, const char **argv, const char *prefix)
struct column_options copts;
const char *command = NULL, *real_command = NULL;
struct option options[] = {
- OPT_STRING(0, "command", &real_command, "name", "lookup config vars"),
- OPT_COLUMN(0, "mode", &colopts, "layout to use"),
- OPT_INTEGER(0, "raw-mode", &colopts, "layout to use"),
- OPT_INTEGER(0, "width", &copts.width, "Maximum width"),
- OPT_STRING(0, "indent", &copts.indent, "string", "Padding space on left border"),
- OPT_INTEGER(0, "nl", &copts.nl, "Padding space on right border"),
- OPT_INTEGER(0, "padding", &copts.padding, "Padding space between columns"),
+ OPT_STRING(0, "command", &real_command, N_("name"), N_("lookup config vars")),
+ OPT_COLUMN(0, "mode", &colopts, N_("layout to use")),
+ OPT_INTEGER(0, "raw-mode", &colopts, N_("layout to use")),
+ OPT_INTEGER(0, "width", &copts.width, N_("Maximum width")),
+ OPT_STRING(0, "indent", &copts.indent, N_("string"), N_("Padding space on left border")),
+ OPT_INTEGER(0, "nl", &copts.nl, N_("Padding space on right border")),
+ OPT_INTEGER(0, "padding", &copts.padding, N_("Padding space between columns")),
OPT_END()
};
diff --git a/builtin/commit.c b/builtin/commit.c
index 7a83cae..a17a5df 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -28,14 +28,15 @@
#include "submodule.h"
#include "gpg-interface.h"
#include "column.h"
+#include "sequencer.h"
static const char * const builtin_commit_usage[] = {
- "git commit [options] [--] <filepattern>...",
+ N_("git commit [options] [--] <filepattern>..."),
NULL
};
static const char * const builtin_status_usage[] = {
- "git status [options] [--] <filepattern>...",
+ N_("git status [options] [--] <filepattern>..."),
NULL
};
@@ -466,8 +467,6 @@ static int is_a_merge(const struct commit *current_head)
return !!(current_head->parents && current_head->parents->next);
}
-static const char sign_off_header[] = "Signed-off-by: ";
-
static void export_one(const char *var, const char *s, const char *e, int hack)
{
struct strbuf buf = STRBUF_INIT;
@@ -552,47 +551,6 @@ static void determine_author_info(struct strbuf *author_ident)
}
}
-static int ends_rfc2822_footer(struct strbuf *sb)
-{
- int ch;
- int hit = 0;
- int i, j, k;
- int len = sb->len;
- int first = 1;
- const char *buf = sb->buf;
-
- for (i = len - 1; i > 0; i--) {
- if (hit && buf[i] == '\n')
- break;
- hit = (buf[i] == '\n');
- }
-
- while (i < len - 1 && buf[i] == '\n')
- i++;
-
- for (; i < len; i = k) {
- for (k = i; k < len && buf[k] != '\n'; k++)
- ; /* do nothing */
- k++;
-
- if ((buf[k] == ' ' || buf[k] == '\t') && !first)
- continue;
-
- first = 0;
-
- for (j = 0; i + j < len; j++) {
- ch = buf[i + j];
- if (ch == ':')
- break;
- if (isalnum(ch) ||
- (ch == '-'))
- continue;
- return 0;
- }
- }
- return 1;
-}
-
static char *cut_ident_timestamp_part(char *string)
{
char *ket = strrchr(string, '>');
@@ -717,21 +675,30 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
stripspace(&sb, 0);
if (signoff) {
- struct strbuf sob = STRBUF_INIT;
- int i;
-
- strbuf_addstr(&sob, sign_off_header);
- strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
- getenv("GIT_COMMITTER_EMAIL")));
- strbuf_addch(&sob, '\n');
- for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
- ; /* do nothing */
- if (prefixcmp(sb.buf + i, sob.buf)) {
- if (!i || !ends_rfc2822_footer(&sb))
- strbuf_addch(&sb, '\n');
- strbuf_addbuf(&sb, &sob);
+ /*
+ * See if we have a Conflicts: block at the end. If yes, count
+ * its size, so we can ignore it.
+ */
+ int ignore_footer = 0;
+ int i, eol, previous = 0;
+ const char *nl;
+
+ for (i = 0; i < sb.len; i++) {
+ nl = memchr(sb.buf + i, '\n', sb.len - i);
+ if (nl)
+ eol = nl - sb.buf;
+ else
+ eol = sb.len;
+ if (!prefixcmp(sb.buf + previous, "\nConflicts:\n")) {
+ ignore_footer = sb.len - previous;
+ break;
+ }
+ while (i < eol)
+ i++;
+ previous = eol;
}
- strbuf_release(&sob);
+
+ append_signoff(&sb, ignore_footer);
}
if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len)
@@ -1184,26 +1151,26 @@ int cmd_status(int argc, const char **argv, const char *prefix)
int fd;
unsigned char sha1[20];
static struct option builtin_status_options[] = {
- OPT__VERBOSE(&verbose, "be verbose"),
+ OPT__VERBOSE(&verbose, N_("be verbose")),
OPT_SET_INT('s', "short", &status_format,
- "show status concisely", STATUS_FORMAT_SHORT),
+ N_("show status concisely"), STATUS_FORMAT_SHORT),
OPT_BOOLEAN('b', "branch", &s.show_branch,
- "show branch information"),
+ N_("show branch information")),
OPT_SET_INT(0, "porcelain", &status_format,
- "machine-readable output",
+ N_("machine-readable output"),
STATUS_FORMAT_PORCELAIN),
OPT_BOOLEAN('z', "null", &s.null_termination,
- "terminate entries with NUL"),
+ N_("terminate entries with NUL")),
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
- "mode",
- "show untracked files, optional modes: all, normal, no. (Default: all)",
+ N_("mode"),
+ N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
OPT_BOOLEAN(0, "ignored", &show_ignored_in_status,
- "show ignored files"),
- { OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, "when",
- "ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)",
+ N_("show ignored files")),
+ { OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, N_("when"),
+ N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
- OPT_COLUMN(0, "column", &s.colopts, "list untracked files in columns"),
+ OPT_COLUMN(0, "column", &s.colopts, N_("list untracked files in columns")),
OPT_END(),
};
@@ -1384,53 +1351,53 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
{
static struct wt_status s;
static struct option builtin_commit_options[] = {
- OPT__QUIET(&quiet, "suppress summary after successful commit"),
- OPT__VERBOSE(&verbose, "show diff in commit message template"),
-
- OPT_GROUP("Commit message options"),
- OPT_FILENAME('F', "file", &logfile, "read message from file"),
- OPT_STRING(0, "author", &force_author, "author", "override author for commit"),
- OPT_STRING(0, "date", &force_date, "date", "override date for commit"),
- OPT_CALLBACK('m', "message", &message, "message", "commit message", opt_parse_m),
- OPT_STRING('c', "reedit-message", &edit_message, "commit", "reuse and edit message from specified commit"),
- OPT_STRING('C', "reuse-message", &use_message, "commit", "reuse message from specified commit"),
- OPT_STRING(0, "fixup", &fixup_message, "commit", "use autosquash formatted message to fixup specified commit"),
- OPT_STRING(0, "squash", &squash_message, "commit", "use autosquash formatted message to squash specified commit"),
- OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C/-c/--amend)"),
- OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
- OPT_FILENAME('t', "template", &template_file, "use specified template file"),
- OPT_BOOL('e', "edit", &edit_flag, "force edit of commit"),
- OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
- OPT_BOOLEAN(0, "status", &include_status, "include status in commit message template"),
- { OPTION_STRING, 'S', "gpg-sign", &sign_commit, "key id",
- "GPG sign commit", PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
+ OPT__QUIET(&quiet, N_("suppress summary after successful commit")),
+ OPT__VERBOSE(&verbose, N_("show diff in commit message template")),
+
+ OPT_GROUP(N_("Commit message options")),
+ OPT_FILENAME('F', "file", &logfile, N_("read message from file")),
+ OPT_STRING(0, "author", &force_author, N_("author"), N_("override author for commit")),
+ OPT_STRING(0, "date", &force_date, N_("date"), N_("override date for commit")),
+ OPT_CALLBACK('m', "message", &message, N_("message"), N_("commit message"), opt_parse_m),
+ OPT_STRING('c', "reedit-message", &edit_message, N_("commit"), N_("reuse and edit message from specified commit")),
+ OPT_STRING('C', "reuse-message", &use_message, N_("commit"), N_("reuse message from specified commit")),
+ OPT_STRING(0, "fixup", &fixup_message, N_("commit"), N_("use autosquash formatted message to fixup specified commit")),
+ OPT_STRING(0, "squash", &squash_message, N_("commit"), N_("use autosquash formatted message to squash specified commit")),
+ OPT_BOOLEAN(0, "reset-author", &renew_authorship, N_("the commit is authored by me now (used with -C/-c/--amend)")),
+ OPT_BOOLEAN('s', "signoff", &signoff, N_("add Signed-off-by:")),
+ OPT_FILENAME('t', "template", &template_file, N_("use specified template file")),
+ OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")),
+ OPT_STRING(0, "cleanup", &cleanup_arg, N_("default"), N_("how to strip spaces and #comments from message")),
+ OPT_BOOLEAN(0, "status", &include_status, N_("include status in commit message template")),
+ { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"),
+ N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
/* end commit message options */
- OPT_GROUP("Commit contents options"),
- OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
- OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
- OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
- OPT_BOOLEAN('p', "patch", &patch_interactive, "interactively add changes"),
- OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
- OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
- OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
- OPT_SET_INT(0, "short", &status_format, "show status concisely",
+ OPT_GROUP(N_("Commit contents options")),
+ OPT_BOOLEAN('a', "all", &all, N_("commit all changed files")),
+ OPT_BOOLEAN('i', "include", &also, N_("add specified files to index for commit")),
+ OPT_BOOLEAN(0, "interactive", &interactive, N_("interactively add files")),
+ OPT_BOOLEAN('p', "patch", &patch_interactive, N_("interactively add changes")),
+ OPT_BOOLEAN('o', "only", &only, N_("commit only specified files")),
+ OPT_BOOLEAN('n', "no-verify", &no_verify, N_("bypass pre-commit hook")),
+ OPT_BOOLEAN(0, "dry-run", &dry_run, N_("show what would be committed")),
+ OPT_SET_INT(0, "short", &status_format, N_("show status concisely"),
STATUS_FORMAT_SHORT),
- OPT_BOOLEAN(0, "branch", &s.show_branch, "show branch information"),
+ OPT_BOOLEAN(0, "branch", &s.show_branch, N_("show branch information")),
OPT_SET_INT(0, "porcelain", &status_format,
- "machine-readable output", STATUS_FORMAT_PORCELAIN),
+ N_("machine-readable output"), STATUS_FORMAT_PORCELAIN),
OPT_BOOLEAN('z', "null", &s.null_termination,
- "terminate entries with NUL"),
- OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
- OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"),
- { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
+ N_("terminate entries with NUL")),
+ OPT_BOOLEAN(0, "amend", &amend, N_("amend previous commit")),
+ OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")),
+ { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
/* end commit contents options */
{ OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL,
- "ok to record an empty change",
+ N_("ok to record an empty change"),
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
{ OPTION_BOOLEAN, 0, "allow-empty-message", &allow_empty_message, NULL,
- "ok to record a change with an empty message",
+ N_("ok to record a change with an empty message"),
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
OPT_END()
diff --git a/builtin/config.c b/builtin/config.c
index 442ccc2..e1c33e0 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -4,7 +4,7 @@
#include "parse-options.h"
static const char *const builtin_config_usage[] = {
- "git config [options]",
+ N_("git config [options]"),
NULL
};
@@ -49,33 +49,33 @@ static int respect_includes = -1;
#define TYPE_PATH (1<<3)
static struct option builtin_config_options[] = {
- OPT_GROUP("Config file location"),
- OPT_BOOLEAN(0, "global", &use_global_config, "use global config file"),
- OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
- OPT_BOOLEAN(0, "local", &use_local_config, "use repository config file"),
- OPT_STRING('f', "file", &given_config_file, "file", "use given config file"),
- OPT_GROUP("Action"),
- OPT_BIT(0, "get", &actions, "get value: name [value-regex]", ACTION_GET),
- OPT_BIT(0, "get-all", &actions, "get all values: key [value-regex]", ACTION_GET_ALL),
- OPT_BIT(0, "get-regexp", &actions, "get values for regexp: name-regex [value-regex]", ACTION_GET_REGEXP),
- OPT_BIT(0, "replace-all", &actions, "replace all matching variables: name value [value_regex]", ACTION_REPLACE_ALL),
- OPT_BIT(0, "add", &actions, "adds a new variable: name value", ACTION_ADD),
- OPT_BIT(0, "unset", &actions, "removes a variable: name [value-regex]", ACTION_UNSET),
- OPT_BIT(0, "unset-all", &actions, "removes all matches: name [value-regex]", ACTION_UNSET_ALL),
- OPT_BIT(0, "rename-section", &actions, "rename section: old-name new-name", ACTION_RENAME_SECTION),
- OPT_BIT(0, "remove-section", &actions, "remove a section: name", ACTION_REMOVE_SECTION),
- OPT_BIT('l', "list", &actions, "list all", ACTION_LIST),
- OPT_BIT('e', "edit", &actions, "opens an editor", ACTION_EDIT),
- OPT_STRING(0, "get-color", &get_color_slot, "slot", "find the color configured: [default]"),
- OPT_STRING(0, "get-colorbool", &get_colorbool_slot, "slot", "find the color setting: [stdout-is-tty]"),
- OPT_GROUP("Type"),
- OPT_BIT(0, "bool", &types, "value is \"true\" or \"false\"", TYPE_BOOL),
- OPT_BIT(0, "int", &types, "value is decimal number", TYPE_INT),
- OPT_BIT(0, "bool-or-int", &types, "value is --bool or --int", TYPE_BOOL_OR_INT),
- OPT_BIT(0, "path", &types, "value is a path (file or directory name)", TYPE_PATH),
- OPT_GROUP("Other"),
- OPT_BOOLEAN('z', "null", &end_null, "terminate values with NUL byte"),
- OPT_BOOL(0, "includes", &respect_includes, "respect include directives on lookup"),
+ OPT_GROUP(N_("Config file location")),
+ OPT_BOOLEAN(0, "global", &use_global_config, N_("use global config file")),
+ OPT_BOOLEAN(0, "system", &use_system_config, N_("use system config file")),
+ OPT_BOOLEAN(0, "local", &use_local_config, N_("use repository config file")),
+ OPT_STRING('f', "file", &given_config_file, N_("file"), N_("use given config file")),
+ OPT_GROUP(N_("Action")),
+ OPT_BIT(0, "get", &actions, N_("get value: name [value-regex]"), ACTION_GET),
+ OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-regex]"), ACTION_GET_ALL),
+ OPT_BIT(0, "get-regexp", &actions, N_("get values for regexp: name-regex [value-regex]"), ACTION_GET_REGEXP),
+ OPT_BIT(0, "replace-all", &actions, N_("replace all matching variables: name value [value_regex]"), ACTION_REPLACE_ALL),
+ OPT_BIT(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD),
+ OPT_BIT(0, "unset", &actions, N_("remove a variable: name [value-regex]"), ACTION_UNSET),
+ OPT_BIT(0, "unset-all", &actions, N_("remove all matches: name [value-regex]"), ACTION_UNSET_ALL),
+ OPT_BIT(0, "rename-section", &actions, N_("rename section: old-name new-name"), ACTION_RENAME_SECTION),
+ OPT_BIT(0, "remove-section", &actions, N_("remove a section: name"), ACTION_REMOVE_SECTION),
+ OPT_BIT('l', "list", &actions, N_("list all"), ACTION_LIST),
+ OPT_BIT('e', "edit", &actions, N_("open an editor"), ACTION_EDIT),
+ OPT_STRING(0, "get-color", &get_color_slot, N_("slot"), N_("find the color configured: [default]")),
+ OPT_STRING(0, "get-colorbool", &get_colorbool_slot, N_("slot"), N_("find the color setting: [stdout-is-tty]")),
+ OPT_GROUP(N_("Type")),
+ OPT_BIT(0, "bool", &types, N_("value is \"true\" or \"false\""), TYPE_BOOL),
+ OPT_BIT(0, "int", &types, N_("value is decimal number"), TYPE_INT),
+ OPT_BIT(0, "bool-or-int", &types, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
+ OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
+ OPT_GROUP(N_("Other")),
+ OPT_BOOLEAN('z', "null", &end_null, N_("terminate values with NUL byte")),
+ OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")),
OPT_END(),
};
diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index c37cb98..9afaa88 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -66,7 +66,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose,
}
static char const * const count_objects_usage[] = {
- "git count-objects [-v]",
+ N_("git count-objects [-v]"),
NULL
};
@@ -79,7 +79,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
unsigned long loose = 0, packed = 0, packed_loose = 0, garbage = 0;
off_t loose_size = 0;
struct option opts[] = {
- OPT__VERBOSE(&verbose, "be verbose"),
+ OPT__VERBOSE(&verbose, N_("be verbose")),
OPT_END(),
};
diff --git a/builtin/describe.c b/builtin/describe.c
index 9f63067..9fe11ed 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -12,8 +12,8 @@
#define MAX_TAGS (FLAG_BITS - 1)
static const char * const describe_usage[] = {
- "git describe [options] <committish>*",
- "git describe [options] --dirty",
+ N_("git describe [options] <committish>*"),
+ N_("git describe [options] --dirty"),
NULL
};
@@ -400,22 +400,22 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
{
int contains = 0;
struct option options[] = {
- OPT_BOOLEAN(0, "contains", &contains, "find the tag that comes after the commit"),
- OPT_BOOLEAN(0, "debug", &debug, "debug search strategy on stderr"),
- OPT_BOOLEAN(0, "all", &all, "use any ref in .git/refs"),
- OPT_BOOLEAN(0, "tags", &tags, "use any tag in .git/refs/tags"),
- OPT_BOOLEAN(0, "long", &longformat, "always use long format"),
+ OPT_BOOLEAN(0, "contains", &contains, N_("find the tag that comes after the commit")),
+ OPT_BOOLEAN(0, "debug", &debug, N_("debug search strategy on stderr")),
+ OPT_BOOLEAN(0, "all", &all, N_("use any ref in .git/refs")),
+ OPT_BOOLEAN(0, "tags", &tags, N_("use any tag in .git/refs/tags")),
+ OPT_BOOLEAN(0, "long", &longformat, N_("always use long format")),
OPT__ABBREV(&abbrev),
OPT_SET_INT(0, "exact-match", &max_candidates,
- "only output exact matches", 0),
+ N_("only output exact matches"), 0),
OPT_INTEGER(0, "candidates", &max_candidates,
- "consider <n> most recent tags (default: 10)"),
- OPT_STRING(0, "match", &pattern, "pattern",
- "only consider tags matching <pattern>"),
+ N_("consider <n> most recent tags (default: 10)")),
+ OPT_STRING(0, "match", &pattern, N_("pattern"),
+ N_("only consider tags matching <pattern>")),
OPT_BOOLEAN(0, "always", &always,
- "show abbreviated commit object as fallback"),
- {OPTION_STRING, 0, "dirty", &dirty, "mark",
- "append <mark> on dirty working tree (default: \"-dirty\")",
+ N_("show abbreviated commit object as fallback")),
+ {OPTION_STRING, 0, "dirty", &dirty, N_("mark"),
+ N_("append <mark> on dirty working tree (default: \"-dirty\")"),
PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"},
OPT_END(),
};
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 9ab6db3..12220ad 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -19,7 +19,7 @@
#include "quote.h"
static const char *fast_export_usage[] = {
- "git fast-export [rev-list-opts]",
+ N_("git fast-export [rev-list-opts]"),
NULL
};
@@ -632,24 +632,24 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
char *export_filename = NULL, *import_filename = NULL;
struct option options[] = {
OPT_INTEGER(0, "progress", &progress,
- "show progress after <n> objects"),
- OPT_CALLBACK(0, "signed-tags", &signed_tag_mode, "mode",
- "select handling of signed tags",
+ N_("show progress after <n> objects")),
+ OPT_CALLBACK(0, "signed-tags", &signed_tag_mode, N_("mode"),
+ N_("select handling of signed tags"),
parse_opt_signed_tag_mode),
- OPT_CALLBACK(0, "tag-of-filtered-object", &tag_of_filtered_mode, "mode",
- "select handling of tags that tag filtered objects",
+ OPT_CALLBACK(0, "tag-of-filtered-object", &tag_of_filtered_mode, N_("mode"),
+ N_("select handling of tags that tag filtered objects"),
parse_opt_tag_of_filtered_mode),
- OPT_STRING(0, "export-marks", &export_filename, "file",
- "Dump marks to this file"),
- OPT_STRING(0, "import-marks", &import_filename, "file",
- "Import marks from this file"),
+ OPT_STRING(0, "export-marks", &export_filename, N_("file"),
+ N_("Dump marks to this file")),
+ OPT_STRING(0, "import-marks", &import_filename, N_("file"),
+ N_("Import marks from this file")),
OPT_BOOLEAN(0, "fake-missing-tagger", &fake_missing_tagger,
- "Fake a tagger when tags lack one"),
+ N_("Fake a tagger when tags lack one")),
OPT_BOOLEAN(0, "full-tree", &full_tree,
- "Output full tree for each commit"),
+ N_("Output full tree for each commit")),
OPT_BOOLEAN(0, "use-done-feature", &use_done_feature,
- "Use the done feature to terminate the stream"),
- OPT_BOOL(0, "no-data", &no_data, "Skip output of blob data"),
+ N_("Use the done feature to terminate the stream")),
+ OPT_BOOL(0, "no-data", &no_data, N_("Skip output of blob data")),
OPT_END()
};
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index fdda36f..e644398 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -525,72 +525,59 @@ static void mark_recent_complete_commits(unsigned long cutoff)
}
}
-static void filter_refs(struct ref **refs, int nr_match, char **match)
+static int non_matching_ref(struct string_list_item *item, void *unused)
+{
+ if (item->util) {
+ item->util = NULL;
+ return 0;
+ }
+ else
+ return 1;
+}
+
+static void filter_refs(struct ref **refs, struct string_list *sought)
{
- struct ref **return_refs;
struct ref *newlist = NULL;
struct ref **newtail = &newlist;
struct ref *ref, *next;
- struct ref *fastarray[32];
- int match_pos;
-
- if (nr_match && !args.fetch_all) {
- if (ARRAY_SIZE(fastarray) < nr_match)
- return_refs = xcalloc(nr_match, sizeof(struct ref *));
- else {
- return_refs = fastarray;
- memset(return_refs, 0, sizeof(struct ref *) * nr_match);
- }
- }
- else
- return_refs = NULL;
+ int sought_pos;
- match_pos = 0;
+ sought_pos = 0;
for (ref = *refs; ref; ref = next) {
+ int keep = 0;
next = ref->next;
if (!memcmp(ref->name, "refs/", 5) &&
check_refname_format(ref->name + 5, 0))
; /* trash */
- else if (args.fetch_all &&
- (!args.depth || prefixcmp(ref->name, "refs/tags/") )) {
- *newtail = ref;
- ref->next = NULL;
- newtail = &ref->next;
- continue;
- }
else {
- int cmp = -1;
- while (match_pos < nr_match) {
- cmp = strcmp(ref->name, match[match_pos]);
- if (cmp < 0) /* definitely do not have it */
- break;
- else if (cmp == 0) { /* definitely have it */
- match[match_pos][0] = '\0';
- return_refs[match_pos] = ref;
+ while (sought_pos < sought->nr) {
+ int cmp = strcmp(ref->name, sought->items[sought_pos].string);
+ if (cmp < 0)
+ break; /* definitely do not have it */
+ else if (cmp == 0) {
+ keep = 1; /* definitely have it */
+ sought->items[sought_pos++].util = "matched";
break;
}
- else /* might have it; keep looking */
- match_pos++;
+ else
+ sought_pos++; /* might have it; keep looking */
}
- if (!cmp)
- continue; /* we will link it later */
}
- free(ref);
- }
- if (!args.fetch_all) {
- int i;
- for (i = 0; i < nr_match; i++) {
- ref = return_refs[i];
- if (ref) {
- *newtail = ref;
- ref->next = NULL;
- newtail = &ref->next;
- }
+ if (! keep && args.fetch_all &&
+ (!args.depth || prefixcmp(ref->name, "refs/tags/")))
+ keep = 1;
+
+ if (keep) {
+ *newtail = ref;
+ ref->next = NULL;
+ newtail = &ref->next;
+ } else {
+ free(ref);
}
- if (return_refs != fastarray)
- free(return_refs);
}
+
+ filter_string_list(sought, 0, non_matching_ref, NULL);
*refs = newlist;
}
@@ -599,7 +586,7 @@ static void mark_alternate_complete(const struct ref *ref, void *unused)
mark_complete(NULL, ref->old_sha1, 0, NULL);
}
-static int everything_local(struct ref **refs, int nr_match, char **match)
+static int everything_local(struct ref **refs, struct string_list *sought)
{
struct ref *ref;
int retval;
@@ -650,7 +637,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
}
}
- filter_refs(refs, nr_match, match);
+ filter_refs(refs, sought);
for (retval = 1, ref = *refs; ref ; ref = ref->next) {
const unsigned char *remote = ref->old_sha1;
@@ -781,8 +768,7 @@ static int get_pack(int xd[2], char **pack_lockfile)
static struct ref *do_fetch_pack(int fd[2],
const struct ref *orig_ref,
- int nr_match,
- char **match,
+ struct string_list *sought,
char **pack_lockfile)
{
struct ref *ref = copy_ref_list(orig_ref);
@@ -839,7 +825,7 @@ static struct ref *do_fetch_pack(int fd[2],
agent_len, agent_feature);
}
- if (everything_local(&ref, nr_match, match)) {
+ if (everything_local(&ref, sought)) {
packet_flush(fd[1]);
goto all_done;
}
@@ -859,19 +845,6 @@ static struct ref *do_fetch_pack(int fd[2],
return ref;
}
-static int remove_duplicates(int nr_heads, char **heads)
-{
- int src, dst;
-
- if (!nr_heads)
- return 0;
-
- for (src = dst = 1; src < nr_heads; src++)
- if (strcmp(heads[src], heads[dst-1]))
- heads[dst++] = heads[src];
- return dst;
-}
-
static int fetch_pack_config(const char *var, const char *value, void *cb)
{
if (strcmp(var, "fetch.unpacklimit") == 0) {
@@ -922,8 +895,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
int i, ret;
struct ref *ref = NULL;
const char *dest = NULL;
- int alloc_heads = 0, nr_heads = 0;
- char **heads = NULL;
+ struct string_list sought = STRING_LIST_INIT_DUP;
int fd[2];
char *pack_lockfile = NULL;
char **pack_lockfile_ptr = NULL;
@@ -1000,9 +972,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
* Copy refs from cmdline to growable list, then append any
* refs from the standard input:
*/
- ALLOC_GROW(heads, argc - i, alloc_heads);
for (; i < argc; i++)
- heads[nr_heads++] = xstrdup(argv[i]);
+ string_list_append(&sought, xstrdup(argv[i]));
if (args.stdin_refs) {
if (args.stateless_rpc) {
/* in stateless RPC mode we use pkt-line to read
@@ -1015,17 +986,14 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
break;
if (line[n-1] == '\n')
n--;
- ALLOC_GROW(heads, nr_heads + 1, alloc_heads);
- heads[nr_heads++] = xmemdupz(line, n);
+ string_list_append(&sought, xmemdupz(line, n));
}
}
else {
/* read from stdin one ref per line, until EOF */
struct strbuf line = STRBUF_INIT;
- while (strbuf_getline(&line, stdin, '\n') != EOF) {
- ALLOC_GROW(heads, nr_heads + 1, alloc_heads);
- heads[nr_heads++] = strbuf_detach(&line, NULL);
- }
+ while (strbuf_getline(&line, stdin, '\n') != EOF)
+ string_list_append(&sought, strbuf_detach(&line, NULL));
strbuf_release(&line);
}
}
@@ -1042,7 +1010,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
get_remote_heads(fd[0], &ref, 0, NULL);
ref = fetch_pack(&args, fd, conn, ref, dest,
- nr_heads, heads, pack_lockfile_ptr);
+ &sought, pack_lockfile_ptr);
if (pack_lockfile) {
printf("lock %s\n", pack_lockfile);
fflush(stdout);
@@ -1050,21 +1018,18 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
close(fd[0]);
close(fd[1]);
if (finish_connect(conn))
- ref = NULL;
- ret = !ref;
-
- if (!ret && nr_heads) {
- /* If the heads to pull were given, we should have
- * consumed all of them by matching the remote.
- * Otherwise, 'git fetch remote no-such-ref' would
- * silently succeed without issuing an error.
- */
- for (i = 0; i < nr_heads; i++)
- if (heads[i] && heads[i][0]) {
- error("no such remote ref %s", heads[i]);
- ret = 1;
- }
- }
+ return 1;
+
+ ret = !ref || sought.nr;
+
+ /*
+ * If the heads to pull were given, we should have consumed
+ * all of them by matching the remote. Otherwise, 'git fetch
+ * remote no-such-ref' would silently succeed without issuing
+ * an error.
+ */
+ for (i = 0; i < sought.nr; i++)
+ error("no such remote ref %s", sought.items[i].string);
while (ref) {
printf("%s %s\n",
sha1_to_hex(ref->old_sha1), ref->name);
@@ -1074,18 +1039,12 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
return ret;
}
-static int compare_heads(const void *a, const void *b)
-{
- return strcmp(*(const char **)a, *(const char **)b);
-}
-
struct ref *fetch_pack(struct fetch_pack_args *my_args,
int fd[], struct child_process *conn,
const struct ref *ref,
- const char *dest,
- int nr_heads,
- char **heads,
- char **pack_lockfile)
+ const char *dest,
+ struct string_list *sought,
+ char **pack_lockfile)
{
struct stat st;
struct ref *ref_cpy;
@@ -1098,16 +1057,16 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
st.st_mtime = 0;
}
- if (heads && nr_heads) {
- qsort(heads, nr_heads, sizeof(*heads), compare_heads);
- nr_heads = remove_duplicates(nr_heads, heads);
+ if (sought->nr) {
+ sort_string_list(sought);
+ string_list_remove_duplicates(sought, 0);
}
if (!ref) {
packet_flush(fd[1]);
die("no matching remote head");
}
- ref_cpy = do_fetch_pack(fd, ref, nr_heads, heads, pack_lockfile);
+ ref_cpy = do_fetch_pack(fd, ref, sought, pack_lockfile);
if (args.depth > 0) {
struct cache_time mtime;
diff --git a/builtin/fetch.c b/builtin/fetch.c
index f483352..4b5a898 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -17,10 +17,10 @@
#include "argv-array.h"
static const char * const builtin_fetch_usage[] = {
- "git fetch [<options>] [<repository> [<refspec>...]]",
- "git fetch [<options>] <group>",
- "git fetch --multiple [<options>] [(<repository> | <group>)...]",
- "git fetch --all [<options>]",
+ N_("git fetch [<options>] [<repository> [<refspec>...]]"),
+ N_("git fetch [<options>] <group>"),
+ N_("git fetch --multiple [<options>] [(<repository> | <group>)...]"),
+ N_("git fetch --all [<options>]"),
NULL
};
@@ -57,36 +57,36 @@ static int option_parse_recurse_submodules(const struct option *opt,
static struct option builtin_fetch_options[] = {
OPT__VERBOSITY(&verbosity),
OPT_BOOLEAN(0, "all", &all,
- "fetch from all remotes"),
+ N_("fetch from all remotes")),
OPT_BOOLEAN('a', "append", &append,
- "append to .git/FETCH_HEAD instead of overwriting"),
- OPT_STRING(0, "upload-pack", &upload_pack, "path",
- "path to upload pack on remote end"),
- OPT__FORCE(&force, "force overwrite of local branch"),
+ N_("append to .git/FETCH_HEAD instead of overwriting")),
+ OPT_STRING(0, "upload-pack", &upload_pack, N_("path"),
+ N_("path to upload pack on remote end")),
+ OPT__FORCE(&force, N_("force overwrite of local branch")),
OPT_BOOLEAN('m', "multiple", &multiple,
- "fetch from multiple remotes"),
+ N_("fetch from multiple remotes")),
OPT_SET_INT('t', "tags", &tags,
- "fetch all tags and associated objects", TAGS_SET),
+ N_("fetch all tags and associated objects"), TAGS_SET),
OPT_SET_INT('n', NULL, &tags,
- "do not fetch all tags (--no-tags)", TAGS_UNSET),
+ N_("do not fetch all tags (--no-tags)"), TAGS_UNSET),
OPT_BOOLEAN('p', "prune", &prune,
- "prune remote-tracking branches no longer on remote"),
- { OPTION_CALLBACK, 0, "recurse-submodules", NULL, "on-demand",
- "control recursive fetching of submodules",
+ N_("prune remote-tracking branches no longer on remote")),
+ { OPTION_CALLBACK, 0, "recurse-submodules", NULL, N_("on-demand"),
+ N_("control recursive fetching of submodules"),
PARSE_OPT_OPTARG, option_parse_recurse_submodules },
OPT_BOOLEAN(0, "dry-run", &dry_run,
- "dry run"),
- OPT_BOOLEAN('k', "keep", &keep, "keep downloaded pack"),
+ N_("dry run")),
+ OPT_BOOLEAN('k', "keep", &keep, N_("keep downloaded pack")),
OPT_BOOLEAN('u', "update-head-ok", &update_head_ok,
- "allow updating of HEAD ref"),
- OPT_BOOL(0, "progress", &progress, "force progress reporting"),
- OPT_STRING(0, "depth", &depth, "depth",
- "deepen history of shallow clone"),
- { OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, "dir",
- "prepend this to submodule path output", PARSE_OPT_HIDDEN },
+ N_("allow updating of HEAD ref")),
+ OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
+ OPT_STRING(0, "depth", &depth, N_("depth"),
+ N_("deepen history of shallow clone")),
+ { OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
+ N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
{ OPTION_STRING, 0, "recurse-submodules-default",
&recurse_submodules_default, NULL,
- "default mode for recursion", PARSE_OPT_HIDDEN },
+ N_("default mode for recursion"), PARSE_OPT_HIDDEN },
OPT_END()
};
@@ -256,9 +256,8 @@ static int update_local_ref(struct ref *ref,
if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
if (verbosity > 0)
strbuf_addf(display, "= %-*s %-*s -> %s",
- TRANSPORT_SUMMARY_WIDTH,
- _("[up to date]"), REFCOL_WIDTH,
- remote, pretty_ref);
+ TRANSPORT_SUMMARY(_("[up to date]")),
+ REFCOL_WIDTH, remote, pretty_ref);
return 0;
}
@@ -272,7 +271,7 @@ static int update_local_ref(struct ref *ref,
*/
strbuf_addf(display,
_("! %-*s %-*s -> %s (can't fetch in current branch)"),
- TRANSPORT_SUMMARY_WIDTH, _("[rejected]"),
+ TRANSPORT_SUMMARY(_("[rejected]")),
REFCOL_WIDTH, remote, pretty_ref);
return 1;
}
@@ -283,7 +282,7 @@ static int update_local_ref(struct ref *ref,
r = s_update_ref("updating tag", ref, 0);
strbuf_addf(display, "%c %-*s %-*s -> %s%s",
r ? '!' : '-',
- TRANSPORT_SUMMARY_WIDTH, _("[tag update]"),
+ TRANSPORT_SUMMARY(_("[tag update]")),
REFCOL_WIDTH, remote, pretty_ref,
r ? _(" (unable to update local ref)") : "");
return r;
@@ -318,13 +317,13 @@ static int update_local_ref(struct ref *ref,
r = s_update_ref(msg, ref, 0);
strbuf_addf(display, "%c %-*s %-*s -> %s%s",
r ? '!' : '*',
- TRANSPORT_SUMMARY_WIDTH, what,
+ TRANSPORT_SUMMARY(what),
REFCOL_WIDTH, remote, pretty_ref,
r ? _(" (unable to update local ref)") : "");
return r;
}
- if (in_merge_bases(current, &updated, 1)) {
+ if (in_merge_bases(current, updated)) {
char quickref[83];
int r;
strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
@@ -358,7 +357,7 @@ static int update_local_ref(struct ref *ref,
return r;
} else {
strbuf_addf(display, "! %-*s %-*s -> %s %s",
- TRANSPORT_SUMMARY_WIDTH, _("[rejected]"),
+ TRANSPORT_SUMMARY(_("[rejected]")),
REFCOL_WIDTH, remote, pretty_ref,
_("(non-fast-forward)"));
return 1;
@@ -555,7 +554,7 @@ static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map)
result |= delete_ref(ref->name, NULL, 0);
if (verbosity >= 0) {
fprintf(stderr, " x %-*s %-*s -> %s\n",
- TRANSPORT_SUMMARY_WIDTH, _("[deleted]"),
+ TRANSPORT_SUMMARY(_("[deleted]")),
REFCOL_WIDTH, _("(none)"), prettify_refname(ref->name));
warn_dangling_symref(stderr, dangling_msg, ref->name);
}
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index 2c4d435..e2e27b2 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -10,7 +10,7 @@
#include "gpg-interface.h"
static const char * const fmt_merge_msg_usage[] = {
- "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]",
+ N_("git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]"),
NULL
};
@@ -650,16 +650,16 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
const char *message = NULL;
int shortlog_len = -1;
struct option options[] = {
- { OPTION_INTEGER, 0, "log", &shortlog_len, "n",
- "populate log with at most <n> entries from shortlog",
+ { OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"),
+ N_("populate log with at most <n> entries from shortlog"),
PARSE_OPT_OPTARG, NULL, DEFAULT_MERGE_LOG_LEN },
- { OPTION_INTEGER, 0, "summary", &shortlog_len, "n",
- "alias for --log (deprecated)",
+ { OPTION_INTEGER, 0, "summary", &shortlog_len, N_("n"),
+ N_("alias for --log (deprecated)"),
PARSE_OPT_OPTARG | PARSE_OPT_HIDDEN, NULL,
DEFAULT_MERGE_LOG_LEN },
- OPT_STRING('m', "message", &message, "text",
- "use <text> as start of message"),
- OPT_FILENAME('F', "file", &inpath, "file to read from"),
+ OPT_STRING('m', "message", &message, N_("text"),
+ N_("use <text> as start of message")),
+ OPT_FILENAME('F', "file", &inpath, N_("file to read from")),
OPT_END()
};
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index 0c5294e..7f059c3 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -976,7 +976,7 @@ static int opt_parse_sort(const struct option *opt, const char *arg, int unset)
}
static char const * const for_each_ref_usage[] = {
- "git for-each-ref [options] [<pattern>]",
+ N_("git for-each-ref [options] [<pattern>]"),
NULL
};
@@ -991,19 +991,19 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
struct option opts[] = {
OPT_BIT('s', "shell", &quote_style,
- "quote placeholders suitably for shells", QUOTE_SHELL),
+ N_("quote placeholders suitably for shells"), QUOTE_SHELL),
OPT_BIT('p', "perl", &quote_style,
- "quote placeholders suitably for perl", QUOTE_PERL),
+ N_("quote placeholders suitably for perl"), QUOTE_PERL),
OPT_BIT(0 , "python", &quote_style,
- "quote placeholders suitably for python", QUOTE_PYTHON),
+ N_("quote placeholders suitably for python"), QUOTE_PYTHON),
OPT_BIT(0 , "tcl", &quote_style,
- "quote placeholders suitably for tcl", QUOTE_TCL),
+ N_("quote placeholders suitably for tcl"), QUOTE_TCL),
OPT_GROUP(""),
- OPT_INTEGER( 0 , "count", &maxcount, "show only <n> matched refs"),
- OPT_STRING( 0 , "format", &format, "format", "format to use for the output"),
- OPT_CALLBACK(0 , "sort", sort_tail, "key",
- "field name to sort on", &opt_parse_sort),
+ OPT_INTEGER( 0 , "count", &maxcount, N_("show only <n> matched refs")),
+ OPT_STRING( 0 , "format", &format, N_("format"), N_("format to use for the output")),
+ OPT_CALLBACK(0 , "sort", sort_tail, N_("key"),
+ N_("field name to sort on"), &opt_parse_sort),
OPT_END(),
};
diff --git a/builtin/fsck.c b/builtin/fsck.c
index a710227..bb9a2cd 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -605,23 +605,23 @@ static int fsck_cache_tree(struct cache_tree *it)
}
static char const * const fsck_usage[] = {
- "git fsck [options] [<object>...]",
+ N_("git fsck [options] [<object>...]"),
NULL
};
static struct option fsck_opts[] = {
- OPT__VERBOSE(&verbose, "be verbose"),
- OPT_BOOLEAN(0, "unreachable", &show_unreachable, "show unreachable objects"),
- OPT_BOOL(0, "dangling", &show_dangling, "show dangling objects"),
- OPT_BOOLEAN(0, "tags", &show_tags, "report tags"),
- OPT_BOOLEAN(0, "root", &show_root, "report root nodes"),
- OPT_BOOLEAN(0, "cache", &keep_cache_objects, "make index objects head nodes"),
- OPT_BOOLEAN(0, "reflogs", &include_reflogs, "make reflogs head nodes (default)"),
- OPT_BOOLEAN(0, "full", &check_full, "also consider packs and alternate objects"),
- OPT_BOOLEAN(0, "strict", &check_strict, "enable more strict checking"),
+ OPT__VERBOSE(&verbose, N_("be verbose")),
+ OPT_BOOLEAN(0, "unreachable", &show_unreachable, N_("show unreachable objects")),
+ OPT_BOOL(0, "dangling", &show_dangling, N_("show dangling objects")),
+ OPT_BOOLEAN(0, "tags", &show_tags, N_("report tags")),
+ OPT_BOOLEAN(0, "root", &show_root, N_("report root nodes")),
+ OPT_BOOLEAN(0, "cache", &keep_cache_objects, N_("make index objects head nodes")),
+ OPT_BOOLEAN(0, "reflogs", &include_reflogs, N_("make reflogs head nodes (default)")),
+ OPT_BOOLEAN(0, "full", &check_full, N_("also consider packs and alternate objects")),
+ OPT_BOOLEAN(0, "strict", &check_strict, N_("enable more strict checking")),
OPT_BOOLEAN(0, "lost-found", &write_lost_and_found,
- "write dangling objects in .git/lost-found"),
- OPT_BOOL(0, "progress", &show_progress, "show progress"),
+ N_("write dangling objects in .git/lost-found")),
+ OPT_BOOL(0, "progress", &show_progress, N_("show progress")),
OPT_END(),
};
diff --git a/builtin/gc.c b/builtin/gc.c
index 9b4232c..6be6c8d 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -19,7 +19,7 @@
#define FAILED_RUN "failed to run %s"
static const char * const builtin_gc_usage[] = {
- "git gc [options]",
+ N_("git gc [options]"),
NULL
};
@@ -174,12 +174,12 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
int quiet = 0;
struct option builtin_gc_options[] = {
- OPT__QUIET(&quiet, "suppress progress reporting"),
- { OPTION_STRING, 0, "prune", &prune_expire, "date",
- "prune unreferenced objects",
+ OPT__QUIET(&quiet, N_("suppress progress reporting")),
+ { OPTION_STRING, 0, "prune", &prune_expire, N_("date"),
+ N_("prune unreferenced objects"),
PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire },
- OPT_BOOLEAN(0, "aggressive", &aggressive, "be more thorough (increased runtime)"),
- OPT_BOOLEAN(0, "auto", &auto_gc, "enable auto-gc mode"),
+ OPT_BOOLEAN(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")),
+ OPT_BOOLEAN(0, "auto", &auto_gc, N_("enable auto-gc mode")),
OPT_END()
};
@@ -217,9 +217,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
*/
if (!need_to_gc())
return 0;
- if (quiet)
- fprintf(stderr, _("Auto packing the repository for optimum performance.\n"));
- else
+ if (!quiet)
fprintf(stderr,
_("Auto packing the repository for optimum performance. You may also\n"
"run \"git gc\" manually. See "
diff --git a/builtin/grep.c b/builtin/grep.c
index 0654e0b..82530a6 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -19,7 +19,7 @@
#include "dir.h"
static char const * const grep_usage[] = {
- "git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]",
+ N_("git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]"),
NULL
};
@@ -261,6 +261,53 @@ static int wait_all(void)
}
#endif
+static int parse_pattern_type_arg(const char *opt, const char *arg)
+{
+ if (!strcmp(arg, "default"))
+ return GREP_PATTERN_TYPE_UNSPECIFIED;
+ else if (!strcmp(arg, "basic"))
+ return GREP_PATTERN_TYPE_BRE;
+ else if (!strcmp(arg, "extended"))
+ return GREP_PATTERN_TYPE_ERE;
+ else if (!strcmp(arg, "fixed"))
+ return GREP_PATTERN_TYPE_FIXED;
+ else if (!strcmp(arg, "perl"))
+ return GREP_PATTERN_TYPE_PCRE;
+ die("bad %s argument: %s", opt, arg);
+}
+
+static void grep_pattern_type_options(const int pattern_type, struct grep_opt *opt)
+{
+ switch (pattern_type) {
+ case GREP_PATTERN_TYPE_UNSPECIFIED:
+ /* fall through */
+
+ case GREP_PATTERN_TYPE_BRE:
+ opt->fixed = 0;
+ opt->pcre = 0;
+ opt->regflags &= ~REG_EXTENDED;
+ break;
+
+ case GREP_PATTERN_TYPE_ERE:
+ opt->fixed = 0;
+ opt->pcre = 0;
+ opt->regflags |= REG_EXTENDED;
+ break;
+
+ case GREP_PATTERN_TYPE_FIXED:
+ opt->fixed = 1;
+ opt->pcre = 0;
+ opt->regflags &= ~REG_EXTENDED;
+ break;
+
+ case GREP_PATTERN_TYPE_PCRE:
+ opt->fixed = 0;
+ opt->pcre = 1;
+ opt->regflags &= ~REG_EXTENDED;
+ break;
+ }
+}
+
static int grep_config(const char *var, const char *value, void *cb)
{
struct grep_opt *opt = cb;
@@ -271,12 +318,17 @@ static int grep_config(const char *var, const char *value, void *cb)
if (!strcmp(var, "grep.extendedregexp")) {
if (git_config_bool(var, value))
- opt->regflags |= REG_EXTENDED;
+ opt->extended_regexp_option = 1;
else
- opt->regflags &= ~REG_EXTENDED;
+ opt->extended_regexp_option = 0;
return 0;
}
+ if (!strcmp(var, "grep.patterntype")) {
+ opt->pattern_type_option = parse_pattern_type_arg(var, value);
+ return 0;
+ }
+
if (!strcmp(var, "grep.linenumber")) {
opt->linenum = git_config_bool(var, value);
return 0;
@@ -670,95 +722,88 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
int i;
int dummy;
int use_index = 1;
- enum {
- pattern_type_unspecified = 0,
- pattern_type_bre,
- pattern_type_ere,
- pattern_type_fixed,
- pattern_type_pcre,
- };
- int pattern_type = pattern_type_unspecified;
+ int pattern_type_arg = GREP_PATTERN_TYPE_UNSPECIFIED;
struct option options[] = {
OPT_BOOLEAN(0, "cached", &cached,
- "search in index instead of in the work tree"),
+ N_("search in index instead of in the work tree")),
OPT_NEGBIT(0, "no-index", &use_index,
- "finds in contents not managed by git", 1),
+ N_("find in contents not managed by git"), 1),
OPT_BOOLEAN(0, "untracked", &untracked,
- "search in both tracked and untracked files"),
+ N_("search in both tracked and untracked files")),
OPT_SET_INT(0, "exclude-standard", &opt_exclude,
- "search also in ignored files", 1),
+ N_("search also in ignored files"), 1),
OPT_GROUP(""),
OPT_BOOLEAN('v', "invert-match", &opt.invert,
- "show non-matching lines"),
+ N_("show non-matching lines")),
OPT_BOOLEAN('i', "ignore-case", &opt.ignore_case,
- "case insensitive matching"),
+ N_("case insensitive matching")),
OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp,
- "match patterns only at word boundaries"),
+ N_("match patterns only at word boundaries")),
OPT_SET_INT('a', "text", &opt.binary,
- "process binary files as text", GREP_BINARY_TEXT),
+ N_("process binary files as text"), GREP_BINARY_TEXT),
OPT_SET_INT('I', NULL, &opt.binary,
- "don't match patterns in binary files",
+ N_("don't match patterns in binary files"),
GREP_BINARY_NOMATCH),
- { OPTION_INTEGER, 0, "max-depth", &opt.max_depth, "depth",
- "descend at most <depth> levels", PARSE_OPT_NONEG,
+ { OPTION_INTEGER, 0, "max-depth", &opt.max_depth, N_("depth"),
+ N_("descend at most <depth> levels"), PARSE_OPT_NONEG,
NULL, 1 },
OPT_GROUP(""),
- OPT_SET_INT('E', "extended-regexp", &pattern_type,
- "use extended POSIX regular expressions",
- pattern_type_ere),
- OPT_SET_INT('G', "basic-regexp", &pattern_type,
- "use basic POSIX regular expressions (default)",
- pattern_type_bre),
- OPT_SET_INT('F', "fixed-strings", &pattern_type,
- "interpret patterns as fixed strings",
- pattern_type_fixed),
- OPT_SET_INT('P', "perl-regexp", &pattern_type,
- "use Perl-compatible regular expressions",
- pattern_type_pcre),
+ OPT_SET_INT('E', "extended-regexp", &pattern_type_arg,
+ N_("use extended POSIX regular expressions"),
+ GREP_PATTERN_TYPE_ERE),
+ OPT_SET_INT('G', "basic-regexp", &pattern_type_arg,
+ N_("use basic POSIX regular expressions (default)"),
+ GREP_PATTERN_TYPE_BRE),
+ OPT_SET_INT('F', "fixed-strings", &pattern_type_arg,
+ N_("interpret patterns as fixed strings"),
+ GREP_PATTERN_TYPE_FIXED),
+ OPT_SET_INT('P', "perl-regexp", &pattern_type_arg,
+ N_("use Perl-compatible regular expressions"),
+ GREP_PATTERN_TYPE_PCRE),
OPT_GROUP(""),
- OPT_BOOLEAN('n', "line-number", &opt.linenum, "show line numbers"),
- OPT_NEGBIT('h', NULL, &opt.pathname, "don't show filenames", 1),
- OPT_BIT('H', NULL, &opt.pathname, "show filenames", 1),
+ OPT_BOOLEAN('n', "line-number", &opt.linenum, N_("show line numbers")),
+ OPT_NEGBIT('h', NULL, &opt.pathname, N_("don't show filenames"), 1),
+ OPT_BIT('H', NULL, &opt.pathname, N_("show filenames"), 1),
OPT_NEGBIT(0, "full-name", &opt.relative,
- "show filenames relative to top directory", 1),
+ N_("show filenames relative to top directory"), 1),
OPT_BOOLEAN('l', "files-with-matches", &opt.name_only,
- "show only filenames instead of matching lines"),
+ N_("show only filenames instead of matching lines")),
OPT_BOOLEAN(0, "name-only", &opt.name_only,
- "synonym for --files-with-matches"),
+ N_("synonym for --files-with-matches")),
OPT_BOOLEAN('L', "files-without-match",
&opt.unmatch_name_only,
- "show only the names of files without match"),
+ N_("show only the names of files without match")),
OPT_BOOLEAN('z', "null", &opt.null_following_name,
- "print NUL after filenames"),
+ N_("print NUL after filenames")),
OPT_BOOLEAN('c', "count", &opt.count,
- "show the number of matches instead of matching lines"),
- OPT__COLOR(&opt.color, "highlight matches"),
+ N_("show the number of matches instead of matching lines")),
+ OPT__COLOR(&opt.color, N_("highlight matches")),
OPT_BOOLEAN(0, "break", &opt.file_break,
- "print empty line between matches from different files"),
+ N_("print empty line between matches from different files")),
OPT_BOOLEAN(0, "heading", &opt.heading,
- "show filename only once above matches from same file"),
+ N_("show filename only once above matches from same file")),
OPT_GROUP(""),
- OPT_CALLBACK('C', "context", &opt, "n",
- "show <n> context lines before and after matches",
+ OPT_CALLBACK('C', "context", &opt, N_("n"),
+ N_("show <n> context lines before and after matches"),
context_callback),
OPT_INTEGER('B', "before-context", &opt.pre_context,
- "show <n> context lines before matches"),
+ N_("show <n> context lines before matches")),
OPT_INTEGER('A', "after-context", &opt.post_context,
- "show <n> context lines after matches"),
- OPT_NUMBER_CALLBACK(&opt, "shortcut for -C NUM",
+ N_("show <n> context lines after matches")),
+ OPT_NUMBER_CALLBACK(&opt, N_("shortcut for -C NUM"),
context_callback),
OPT_BOOLEAN('p', "show-function", &opt.funcname,
- "show a line with the function name before matches"),
+ N_("show a line with the function name before matches")),
OPT_BOOLEAN('W', "function-context", &opt.funcbody,
- "show the surrounding function"),
+ N_("show the surrounding function")),
OPT_GROUP(""),
- OPT_CALLBACK('f', NULL, &opt, "file",
- "read patterns from file", file_callback),
- { OPTION_CALLBACK, 'e', NULL, &opt, "pattern",
- "match <pattern>", PARSE_OPT_NONEG, pattern_callback },
+ OPT_CALLBACK('f', NULL, &opt, N_("file"),
+ N_("read patterns from file"), file_callback),
+ { OPTION_CALLBACK, 'e', NULL, &opt, N_("pattern"),
+ N_("match <pattern>"), PARSE_OPT_NONEG, pattern_callback },
{ OPTION_CALLBACK, 0, "and", &opt, NULL,
- "combine patterns specified with -e",
+ N_("combine patterns specified with -e"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, and_callback },
OPT_BOOLEAN(0, "or", &dummy, ""),
{ OPTION_CALLBACK, 0, "not", &opt, NULL, "",
@@ -770,19 +815,19 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
close_callback },
OPT__QUIET(&opt.status_only,
- "indicate hit with exit status without output"),
+ N_("indicate hit with exit status without output")),
OPT_BOOLEAN(0, "all-match", &opt.all_match,
- "show only matches from files that match all patterns"),
+ N_("show only matches from files that match all patterns")),
{ OPTION_SET_INT, 0, "debug", &opt.debug, NULL,
- "show parse tree for grep expression",
+ N_("show parse tree for grep expression"),
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1 },
OPT_GROUP(""),
{ OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager,
- "pager", "show matching files in the pager",
+ N_("pager"), N_("show matching files in the pager"),
PARSE_OPT_OPTARG, NULL, (intptr_t)default_pager },
OPT_BOOLEAN(0, "ext-grep", &external_grep_allowed__ignored,
- "allow calling of grep(1) (ignored by this build)"),
- { OPTION_CALLBACK, 0, "help-all", &options, NULL, "show usage",
+ N_("allow calling of grep(1) (ignored by this build)")),
+ { OPTION_CALLBACK, 0, "help-all", &options, NULL, N_("show usage"),
PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback },
OPT_END()
};
@@ -803,6 +848,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
opt.header_tail = &opt.header_list;
opt.regflags = REG_NEWLINE;
opt.max_depth = -1;
+ opt.pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED;
+ opt.extended_regexp_option = 0;
strcpy(opt.color_context, "");
strcpy(opt.color_filename, "");
@@ -828,28 +875,13 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
PARSE_OPT_KEEP_DASHDASH |
PARSE_OPT_STOP_AT_NON_OPTION |
PARSE_OPT_NO_INTERNAL_HELP);
- switch (pattern_type) {
- case pattern_type_fixed:
- opt.fixed = 1;
- opt.pcre = 0;
- break;
- case pattern_type_bre:
- opt.fixed = 0;
- opt.pcre = 0;
- opt.regflags &= ~REG_EXTENDED;
- break;
- case pattern_type_ere:
- opt.fixed = 0;
- opt.pcre = 0;
- opt.regflags |= REG_EXTENDED;
- break;
- case pattern_type_pcre:
- opt.fixed = 0;
- opt.pcre = 1;
- break;
- default:
- break; /* nothing */
- }
+
+ if (pattern_type_arg != GREP_PATTERN_TYPE_UNSPECIFIED)
+ grep_pattern_type_options(pattern_type_arg, &opt);
+ else if (opt.pattern_type_option != GREP_PATTERN_TYPE_UNSPECIFIED)
+ grep_pattern_type_options(opt.pattern_type_option, &opt);
+ else if (opt.extended_regexp_option)
+ grep_pattern_type_options(GREP_PATTERN_TYPE_ERE, &opt);
if (use_index && !startup_info->have_repository)
/* die the same way as if we did it at the beginning */
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index 33911fd..8d184f1 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -57,8 +57,8 @@ static void hash_stdin_paths(const char *type, int write_objects)
}
static const char * const hash_object_usage[] = {
- "git hash-object [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin] [--] <file>...",
- "git hash-object --stdin-paths < <list-of-paths>",
+ N_("git hash-object [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin] [--] <file>..."),
+ N_("git hash-object --stdin-paths < <list-of-paths>"),
NULL
};
@@ -69,12 +69,12 @@ static int stdin_paths;
static const char *vpath;
static const struct option hash_object_options[] = {
- OPT_STRING('t', NULL, &type, "type", "object type"),
- OPT_BOOLEAN('w', NULL, &write_object, "write the object into the object database"),
- OPT_BOOLEAN( 0 , "stdin", &hashstdin, "read the object from stdin"),
- OPT_BOOLEAN( 0 , "stdin-paths", &stdin_paths, "read file names from stdin"),
- OPT_BOOLEAN( 0 , "no-filters", &no_filters, "store file as is without filters"),
- OPT_STRING( 0 , "path", &vpath, "file", "process file as it were from this path"),
+ OPT_STRING('t', NULL, &type, N_("type"), N_("object type")),
+ OPT_BOOLEAN('w', NULL, &write_object, N_("write the object into the object database")),
+ OPT_BOOLEAN( 0 , "stdin", &hashstdin, N_("read the object from stdin")),
+ OPT_BOOLEAN( 0 , "stdin-paths", &stdin_paths, N_("read file names from stdin")),
+ OPT_BOOLEAN( 0 , "no-filters", &no_filters, N_("store file as is without filters")),
+ OPT_STRING( 0 , "path", &vpath, N_("file"), N_("process file as it were from this path")),
OPT_END()
};
diff --git a/builtin/help.c b/builtin/help.c
index efea4f5..bd86253 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -40,17 +40,17 @@ static int show_all = 0;
static unsigned int colopts;
static enum help_format help_format = HELP_FORMAT_NONE;
static struct option builtin_help_options[] = {
- OPT_BOOLEAN('a', "all", &show_all, "print all available commands"),
- OPT_SET_INT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN),
- OPT_SET_INT('w', "web", &help_format, "show manual in web browser",
+ OPT_BOOLEAN('a', "all", &show_all, N_("print all available commands")),
+ 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"),
HELP_FORMAT_WEB),
- OPT_SET_INT('i', "info", &help_format, "show info page",
+ OPT_SET_INT('i', "info", &help_format, N_("show info page"),
HELP_FORMAT_INFO),
OPT_END(),
};
static const char * const builtin_help_usage[] = {
- "git help [--all] [--man|--web|--info] [command]",
+ N_("git help [--all] [--man|--web|--info] [command]"),
NULL
};
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 953dd30..43d364b 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -291,7 +291,7 @@ static void parse_pack_header(void)
if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
die(_("pack signature mismatch"));
if (!pack_version_ok(hdr->hdr_version))
- die("pack version %"PRIu32" unsupported",
+ die(_("pack version %"PRIu32" unsupported"),
ntohl(hdr->hdr_version));
nr_objects = ntohl(hdr->hdr_entries);
@@ -1061,7 +1061,8 @@ static void resolve_deltas(void)
int ret = pthread_create(&thread_data[i].thread, NULL,
threaded_second_pass, thread_data + i);
if (ret)
- die("unable to create thread: %s", strerror(ret));
+ die(_("unable to create thread: %s"),
+ strerror(ret));
}
for (i = 0; i < nr_threads; i++)
pthread_join(thread_data[i].thread, NULL);
@@ -1108,7 +1109,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
* sizeof(*objects));
f = sha1fd(output_fd, curr_pack);
fix_unresolved_deltas(f, nr_unresolved);
- sprintf(msg, "completed with %d local objects",
+ sprintf(msg, _("completed with %d local objects"),
nr_objects - nr_objects_initial);
stop_progress_msg(&progress, msg);
sha1close(f, tail_sha1, 0);
@@ -1117,8 +1118,8 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
curr_pack, nr_objects,
read_sha1, consumed_bytes-20);
if (hashcmp(read_sha1, tail_sha1) != 0)
- die("Unexpected tail checksum for %s "
- "(disk corruption?)", curr_pack);
+ die(_("Unexpected tail checksum for %s "
+ "(disk corruption?)"), curr_pack);
}
if (nr_deltas != nr_resolved_deltas)
die(Q_("pack has %d unresolved delta",
@@ -1327,17 +1328,17 @@ static int git_index_pack_config(const char *k, const char *v, void *cb)
if (!strcmp(k, "pack.indexversion")) {
opts->version = git_config_int(k, v);
if (opts->version > 2)
- die("bad pack.indexversion=%"PRIu32, opts->version);
+ die(_("bad pack.indexversion=%"PRIu32), opts->version);
return 0;
}
if (!strcmp(k, "pack.threads")) {
nr_threads = git_config_int(k, v);
if (nr_threads < 0)
- die("invalid number of threads specified (%d)",
+ die(_("invalid number of threads specified (%d)"),
nr_threads);
#ifdef NO_PTHREADS
if (nr_threads != 1)
- warning("no threads support, ignoring %s", k);
+ warning(_("no threads support, ignoring %s"), k);
nr_threads = 1;
#endif
return 0;
@@ -1510,8 +1511,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
usage(index_pack_usage);
#ifdef NO_PTHREADS
if (nr_threads != 1)
- warning("no threads support, "
- "ignoring %s", arg);
+ warning(_("no threads support, "
+ "ignoring %s"), arg);
nr_threads = 1;
#endif
} else if (!prefixcmp(arg, "--pack_header=")) {
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 244fb7f..78aa387 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -464,7 +464,7 @@ static int shared_callback(const struct option *opt, const char *arg, int unset)
}
static const char *const init_db_usage[] = {
- "git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]] [directory]",
+ N_("git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]] [directory]"),
NULL
};
@@ -482,17 +482,17 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
const char *template_dir = NULL;
unsigned int flags = 0;
const struct option init_db_options[] = {
- OPT_STRING(0, "template", &template_dir, "template-directory",
- "directory from which templates will be used"),
+ OPT_STRING(0, "template", &template_dir, N_("template-directory"),
+ N_("directory from which templates will be used")),
OPT_SET_INT(0, "bare", &is_bare_repository_cfg,
- "create a bare repository", 1),
+ N_("create a bare repository"), 1),
{ OPTION_CALLBACK, 0, "shared", &init_shared_repository,
- "permissions",
- "specify that the git repository is to be shared amongst several users",
+ N_("permissions"),
+ N_("specify that the git repository is to be shared amongst several users"),
PARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0},
- OPT_BIT('q', "quiet", &flags, "be quiet", INIT_DB_QUIET),
- OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
- "separate git dir from working tree"),
+ OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
+ OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
+ N_("separate git dir from working tree")),
OPT_END()
};
diff --git a/builtin/log.c b/builtin/log.c
index dff7921..09cf43e 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -34,8 +34,8 @@ static const char *fmt_patch_subject_prefix = "PATCH";
static const char *fmt_pretty;
static const char * const builtin_log_usage[] = {
- "git log [<options>] [<since>..<until>] [[--] <path>...]\n"
- " or: git show [options] <object>...",
+ N_("git log [<options>] [<since>..<until>] [[--] <path>...]\n")
+ N_(" or: git show [options] <object>..."),
NULL
};
@@ -97,9 +97,9 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
int quiet = 0, source = 0;
const struct option builtin_log_options[] = {
- OPT_BOOLEAN(0, "quiet", &quiet, "suppress diff output"),
- OPT_BOOLEAN(0, "source", &source, "show source"),
- { OPTION_CALLBACK, 0, "decorate", NULL, NULL, "decorate options",
+ OPT_BOOLEAN(0, "quiet", &quiet, N_("suppress diff output")),
+ OPT_BOOLEAN(0, "source", &source, N_("show source")),
+ { OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"),
PARSE_OPT_OPTARG, decorate_callback},
OPT_END()
};
@@ -696,7 +696,7 @@ static int reopen_stdout(struct commit *commit, const char *subject,
return 0;
}
-static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const char *prefix)
+static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids)
{
struct rev_info check_rev;
struct commit *commit;
@@ -717,7 +717,8 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const cha
init_patch_ids(ids);
/* given a range a..b get all patch ids for b..a */
- init_revisions(&check_rev, prefix);
+ init_revisions(&check_rev, rev->prefix);
+ check_rev.max_parents = 1;
o1->flags ^= UNINTERESTING;
o2->flags ^= UNINTERESTING;
add_pending_object(&check_rev, o1, "o1");
@@ -726,10 +727,6 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const cha
die(_("revision walk setup failed"));
while ((commit = get_revision(&check_rev)) != NULL) {
- /* ignore merges */
- if (commit->parents && commit->parents->next)
- continue;
-
add_commit_patch_id(commit, ids);
}
@@ -890,7 +887,7 @@ static const char *set_outdir(const char *prefix, const char *output_directory)
}
static const char * const builtin_format_patch_usage[] = {
- "git format-patch [options] [<since> | <revision range>]",
+ N_("git format-patch [options] [<since> | <revision range>]"),
NULL
};
@@ -1063,61 +1060,61 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
char *branch_name = NULL;
const struct option builtin_format_patch_options[] = {
{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
- "use [PATCH n/m] even with a single patch",
+ N_("use [PATCH n/m] even with a single patch"),
PARSE_OPT_NOARG, numbered_callback },
{ OPTION_CALLBACK, 'N', "no-numbered", &numbered, NULL,
- "use [PATCH] even with multiple patches",
+ N_("use [PATCH] even with multiple patches"),
PARSE_OPT_NOARG, no_numbered_callback },
- OPT_BOOLEAN('s', "signoff", &do_signoff, "add Signed-off-by:"),
+ OPT_BOOLEAN('s', "signoff", &do_signoff, N_("add Signed-off-by:")),
OPT_BOOLEAN(0, "stdout", &use_stdout,
- "print patches to standard out"),
+ N_("print patches to standard out")),
OPT_BOOLEAN(0, "cover-letter", &cover_letter,
- "generate a cover letter"),
+ N_("generate a cover letter")),
OPT_BOOLEAN(0, "numbered-files", &numbered_files,
- "use simple number sequence for output file names"),
- OPT_STRING(0, "suffix", &fmt_patch_suffix, "sfx",
- "use <sfx> instead of '.patch'"),
+ N_("use simple number sequence for output file names")),
+ OPT_STRING(0, "suffix", &fmt_patch_suffix, N_("sfx"),
+ N_("use <sfx> instead of '.patch'")),
OPT_INTEGER(0, "start-number", &start_number,
- "start numbering patches at <n> instead of 1"),
- { OPTION_CALLBACK, 0, "subject-prefix", &rev, "prefix",
- "Use [<prefix>] instead of [PATCH]",
+ N_("start numbering patches at <n> instead of 1")),
+ { OPTION_CALLBACK, 0, "subject-prefix", &rev, N_("prefix"),
+ N_("Use [<prefix>] instead of [PATCH]"),
PARSE_OPT_NONEG, subject_prefix_callback },
{ OPTION_CALLBACK, 'o', "output-directory", &output_directory,
- "dir", "store resulting files in <dir>",
+ N_("dir"), N_("store resulting files in <dir>"),
PARSE_OPT_NONEG, output_directory_callback },
{ OPTION_CALLBACK, 'k', "keep-subject", &rev, NULL,
- "don't strip/add [PATCH]",
+ N_("don't strip/add [PATCH]"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback },
OPT_BOOLEAN(0, "no-binary", &no_binary_diff,
- "don't output binary diffs"),
+ N_("don't output binary diffs")),
OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
- "don't include a patch matching a commit upstream"),
+ N_("don't include a patch matching a commit upstream")),
{ OPTION_BOOLEAN, 'p', "no-stat", &use_patch_format, NULL,
- "show patch format instead of default (patch + stat)",
+ N_("show patch format instead of default (patch + stat)"),
PARSE_OPT_NONEG | PARSE_OPT_NOARG },
- OPT_GROUP("Messaging"),
- { OPTION_CALLBACK, 0, "add-header", NULL, "header",
- "add email header", 0, header_callback },
- { OPTION_CALLBACK, 0, "to", NULL, "email", "add To: header",
+ OPT_GROUP(N_("Messaging")),
+ { OPTION_CALLBACK, 0, "add-header", NULL, N_("header"),
+ N_("add email header"), 0, header_callback },
+ { OPTION_CALLBACK, 0, "to", NULL, N_("email"), N_("add To: header"),
0, to_callback },
- { OPTION_CALLBACK, 0, "cc", NULL, "email", "add Cc: header",
+ { OPTION_CALLBACK, 0, "cc", NULL, N_("email"), N_("add Cc: header"),
0, cc_callback },
- OPT_STRING(0, "in-reply-to", &in_reply_to, "message-id",
- "make first mail a reply to <message-id>"),
- { OPTION_CALLBACK, 0, "attach", &rev, "boundary",
- "attach the patch", PARSE_OPT_OPTARG,
+ OPT_STRING(0, "in-reply-to", &in_reply_to, N_("message-id"),
+ N_("make first mail a reply to <message-id>")),
+ { OPTION_CALLBACK, 0, "attach", &rev, N_("boundary"),
+ N_("attach the patch"), PARSE_OPT_OPTARG,
attach_callback },
- { OPTION_CALLBACK, 0, "inline", &rev, "boundary",
- "inline the patch",
+ { OPTION_CALLBACK, 0, "inline", &rev, N_("boundary"),
+ N_("inline the patch"),
PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
inline_callback },
- { OPTION_CALLBACK, 0, "thread", &thread, "style",
- "enable message threading, styles: shallow, deep",
+ { OPTION_CALLBACK, 0, "thread", &thread, N_("style"),
+ N_("enable message threading, styles: shallow, deep"),
PARSE_OPT_OPTARG, thread_callback },
- OPT_STRING(0, "signature", &signature, "signature",
- "add a signature"),
+ OPT_STRING(0, "signature", &signature, N_("signature"),
+ N_("add a signature")),
OPT_BOOLEAN(0, "quiet", &quiet,
- "don't print the patch filenames"),
+ N_("don't print the patch filenames")),
OPT_END()
};
@@ -1306,7 +1303,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (hashcmp(o[0].item->sha1, o[1].item->sha1) == 0)
return 0;
}
- get_patch_ids(&rev, &ids, prefix);
+ get_patch_ids(&rev, &ids);
}
if (!use_stdout)
@@ -1443,7 +1440,7 @@ static int add_pending_commit(const char *arg, struct rev_info *revs, int flags)
}
static const char * const cherry_usage[] = {
- "git cherry [-v] [<upstream> [<head> [<limit>]]]",
+ N_("git cherry [-v] [<upstream> [<head> [<limit>]]]"),
NULL
};
@@ -1477,7 +1474,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
struct option options[] = {
OPT__ABBREV(&abbrev),
- OPT__VERBOSE(&verbose, "be verbose"),
+ OPT__VERBOSE(&verbose, N_("be verbose")),
OPT_END()
};
@@ -1508,10 +1505,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
}
init_revisions(&revs, prefix);
- revs.diff = 1;
- revs.combine_merges = 0;
- revs.ignore_merges = 1;
- DIFF_OPT_SET(&revs.diffopt, RECURSIVE);
+ revs.max_parents = 1;
if (add_pending_commit(head, &revs, 0))
die(_("Unknown commit %s"), head);
@@ -1525,7 +1519,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
return 0;
}
- get_patch_ids(&revs, &ids, prefix);
+ get_patch_ids(&revs, &ids);
if (limit && add_pending_commit(limit, &revs, UNINTERESTING))
die(_("Unknown commit %s"), limit);
@@ -1534,10 +1528,6 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
if (prepare_revision_walk(&revs))
die(_("revision walk setup failed"));
while ((commit = get_revision(&revs)) != NULL) {
- /* ignore merges */
- if (commit->parents && commit->parents->next)
- continue;
-
commit_list_insert(commit, &list);
}
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 31b3f2d..b5434af 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -405,7 +405,7 @@ int report_path_error(const char *ps_matched, const char **pathspec, const char
}
static const char * const ls_files_usage[] = {
- "git ls-files [options] [<file>...]",
+ N_("git ls-files [options] [<file>...]"),
NULL
};
@@ -457,57 +457,57 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
struct dir_struct dir;
struct option builtin_ls_files_options[] = {
{ OPTION_CALLBACK, 'z', NULL, NULL, NULL,
- "paths are separated with NUL character",
+ N_("paths are separated with NUL character"),
PARSE_OPT_NOARG, option_parse_z },
OPT_BOOLEAN('t', NULL, &show_tag,
- "identify the file status with tags"),
+ N_("identify the file status with tags")),
OPT_BOOLEAN('v', NULL, &show_valid_bit,
- "use lowercase letters for 'assume unchanged' files"),
+ N_("use lowercase letters for 'assume unchanged' files")),
OPT_BOOLEAN('c', "cached", &show_cached,
- "show cached files in the output (default)"),
+ N_("show cached files in the output (default)")),
OPT_BOOLEAN('d', "deleted", &show_deleted,
- "show deleted files in the output"),
+ N_("show deleted files in the output")),
OPT_BOOLEAN('m', "modified", &show_modified,
- "show modified files in the output"),
+ N_("show modified files in the output")),
OPT_BOOLEAN('o', "others", &show_others,
- "show other files in the output"),
+ N_("show other files in the output")),
OPT_BIT('i', "ignored", &dir.flags,
- "show ignored files in the output",
+ N_("show ignored files in the output"),
DIR_SHOW_IGNORED),
OPT_BOOLEAN('s', "stage", &show_stage,
- "show staged contents' object name in the output"),
+ N_("show staged contents' object name in the output")),
OPT_BOOLEAN('k', "killed", &show_killed,
- "show files on the filesystem that need to be removed"),
+ N_("show files on the filesystem that need to be removed")),
OPT_BIT(0, "directory", &dir.flags,
- "show 'other' directories' name only",
+ N_("show 'other' directories' name only"),
DIR_SHOW_OTHER_DIRECTORIES),
OPT_NEGBIT(0, "empty-directory", &dir.flags,
- "don't show empty directories",
+ N_("don't show empty directories"),
DIR_HIDE_EMPTY_DIRECTORIES),
OPT_BOOLEAN('u', "unmerged", &show_unmerged,
- "show unmerged files in the output"),
+ N_("show unmerged files in the output")),
OPT_BOOLEAN(0, "resolve-undo", &show_resolve_undo,
- "show resolve-undo information"),
- { OPTION_CALLBACK, 'x', "exclude", &dir.exclude_list[EXC_CMDL], "pattern",
- "skip files matching pattern",
+ N_("show resolve-undo information")),
+ { OPTION_CALLBACK, 'x', "exclude", &dir.exclude_list[EXC_CMDL], N_("pattern"),
+ N_("skip files matching pattern"),
0, option_parse_exclude },
- { OPTION_CALLBACK, 'X', "exclude-from", &dir, "file",
- "exclude patterns are read from <file>",
+ { OPTION_CALLBACK, 'X', "exclude-from", &dir, N_("file"),
+ N_("exclude patterns are read from <file>"),
0, option_parse_exclude_from },
- OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, "file",
- "read additional per-directory exclude patterns in <file>"),
+ OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, N_("file"),
+ N_("read additional per-directory exclude patterns in <file>")),
{ OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL,
- "add the standard git exclusions",
+ N_("add the standard git exclusions"),
PARSE_OPT_NOARG, option_parse_exclude_standard },
{ OPTION_SET_INT, 0, "full-name", &prefix_len, NULL,
- "make the output relative to the project top directory",
+ N_("make the output relative to the project top directory"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL },
OPT_BOOLEAN(0, "error-unmatch", &error_unmatch,
- "if any <file> is not in the index, treat this as an error"),
- OPT_STRING(0, "with-tree", &with_tree, "tree-ish",
- "pretend that paths removed since <tree-ish> are still present"),
+ N_("if any <file> is not in the index, treat this as an error")),
+ OPT_STRING(0, "with-tree", &with_tree, N_("tree-ish"),
+ N_("pretend that paths removed since <tree-ish> are still present")),
OPT__ABBREV(&abbrev),
- OPT_BOOLEAN(0, "debug", &debug_mode, "show debugging data"),
+ OPT_BOOLEAN(0, "debug", &debug_mode, N_("show debugging data")),
OPT_END()
};
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 6b666e1..235c17c 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -24,7 +24,7 @@ static int chomp_prefix;
static const char *ls_tree_prefix;
static const char * const ls_tree_usage[] = {
- "git ls-tree [<options>] <tree-ish> [<path>...]",
+ N_("git ls-tree [<options>] <tree-ish> [<path>...]"),
NULL
};
@@ -122,25 +122,25 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
struct tree *tree;
int i, full_tree = 0;
const struct option ls_tree_options[] = {
- OPT_BIT('d', NULL, &ls_options, "only show trees",
+ OPT_BIT('d', NULL, &ls_options, N_("only show trees"),
LS_TREE_ONLY),
- OPT_BIT('r', NULL, &ls_options, "recurse into subtrees",
+ OPT_BIT('r', NULL, &ls_options, N_("recurse into subtrees"),
LS_RECURSIVE),
- OPT_BIT('t', NULL, &ls_options, "show trees when recursing",
+ OPT_BIT('t', NULL, &ls_options, N_("show trees when recursing"),
LS_SHOW_TREES),
OPT_SET_INT('z', NULL, &line_termination,
- "terminate entries with NUL byte", 0),
- OPT_BIT('l', "long", &ls_options, "include object size",
+ N_("terminate entries with NUL byte"), 0),
+ OPT_BIT('l', "long", &ls_options, N_("include object size"),
LS_SHOW_SIZE),
- OPT_BIT(0, "name-only", &ls_options, "list only filenames",
+ OPT_BIT(0, "name-only", &ls_options, N_("list only filenames"),
LS_NAME_ONLY),
- OPT_BIT(0, "name-status", &ls_options, "list only filenames",
+ OPT_BIT(0, "name-status", &ls_options, N_("list only filenames"),
LS_NAME_ONLY),
OPT_SET_INT(0, "full-name", &chomp_prefix,
- "use full path names", 0),
+ N_("use full path names"), 0),
OPT_BOOLEAN(0, "full-tree", &full_tree,
- "list entire tree; not just current directory "
- "(implies --full-name)"),
+ N_("list entire tree; not just current directory "
+ "(implies --full-name)")),
OPT__ABBREV(&abbrev),
OPT_END()
};
diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c
index fe12857..da23140 100644
--- a/builtin/mailinfo.c
+++ b/builtin/mailinfo.c
@@ -477,36 +477,12 @@ static struct strbuf *decode_b_segment(const struct strbuf *b_seg)
return out;
}
-/*
- * When there is no known charset, guess.
- *
- * Right now we assume that if the target is UTF-8 (the default),
- * and it already looks like UTF-8 (which includes US-ASCII as its
- * subset, of course) then that is what it is and there is nothing
- * to do.
- *
- * Otherwise, we default to assuming it is Latin1 for historical
- * reasons.
- */
-static const char *guess_charset(const struct strbuf *line, const char *target_charset)
-{
- if (is_encoding_utf8(target_charset)) {
- if (is_utf8(line->buf))
- return NULL;
- }
- return "ISO8859-1";
-}
-
static void convert_to_utf8(struct strbuf *line, const char *charset)
{
char *out;
- if (!charset || !*charset) {
- charset = guess_charset(line, metainfo_charset);
- if (!charset)
- return;
- }
-
+ if (!charset || !*charset)
+ return;
if (!strcasecmp(metainfo_charset, charset))
return;
out = reencode_string(line->buf, metainfo_charset, charset);
diff --git a/builtin/merge-base.c b/builtin/merge-base.c
index 4f30f1b..1bc7991 100644
--- a/builtin/merge-base.c
+++ b/builtin/merge-base.c
@@ -23,9 +23,10 @@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
}
static const char * const merge_base_usage[] = {
- "git merge-base [-a|--all] <commit> <commit>...",
- "git merge-base [-a|--all] --octopus <commit>...",
- "git merge-base --independent <commit>...",
+ N_("git merge-base [-a|--all] <commit> <commit>..."),
+ N_("git merge-base [-a|--all] --octopus <commit>..."),
+ N_("git merge-base --independent <commit>..."),
+ N_("git merge-base --is-ancestor <commit> <commit>"),
NULL
};
@@ -70,6 +71,20 @@ static int handle_octopus(int count, const char **args, int reduce, int show_all
return 0;
}
+static int handle_is_ancestor(int argc, const char **argv)
+{
+ struct commit *one, *two;
+
+ if (argc != 2)
+ die("--is-ancestor takes exactly two commits");
+ one = get_commit_reference(argv[0]);
+ two = get_commit_reference(argv[1]);
+ if (in_merge_bases(one, two))
+ return 0;
+ else
+ return 1;
+}
+
int cmd_merge_base(int argc, const char **argv, const char *prefix)
{
struct commit **rev;
@@ -77,11 +92,14 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)
int show_all = 0;
int octopus = 0;
int reduce = 0;
+ int is_ancestor = 0;
struct option options[] = {
- OPT_BOOLEAN('a', "all", &show_all, "output all common ancestors"),
- OPT_BOOLEAN(0, "octopus", &octopus, "find ancestors for a single n-way merge"),
- OPT_BOOLEAN(0, "independent", &reduce, "list revs not reachable from others"),
+ OPT_BOOLEAN('a', "all", &show_all, N_("output all common ancestors")),
+ OPT_BOOLEAN(0, "octopus", &octopus, N_("find ancestors for a single n-way merge")),
+ OPT_BOOLEAN(0, "independent", &reduce, N_("list revs not reachable from others")),
+ OPT_BOOLEAN(0, "is-ancestor", &is_ancestor,
+ N_("is the first one ancestor of the other?")),
OPT_END()
};
@@ -89,6 +107,10 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, merge_base_usage, 0);
if (!octopus && !reduce && argc < 2)
usage_with_options(merge_base_usage, options);
+ if (is_ancestor && (show_all | octopus | reduce))
+ die("--is-ancestor cannot be used with other options");
+ if (is_ancestor)
+ return handle_is_ancestor(argc, argv);
if (reduce && (show_all || octopus))
die("--independent cannot be used with other options");
diff --git a/builtin/merge-file.c b/builtin/merge-file.c
index 6f0efef..c0570f2 100644
--- a/builtin/merge-file.c
+++ b/builtin/merge-file.c
@@ -5,7 +5,7 @@
#include "parse-options.h"
static const char *const merge_file_usage[] = {
- "git merge-file [options] [-L name1 [-L orig [-L name2]]] file1 orig_file file2",
+ N_("git merge-file [options] [-L name1 [-L orig [-L name2]]] file1 orig_file file2"),
NULL
};
@@ -30,19 +30,19 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
int quiet = 0;
int prefixlen = 0;
struct option options[] = {
- OPT_BOOLEAN('p', "stdout", &to_stdout, "send results to standard output"),
- OPT_SET_INT(0, "diff3", &xmp.style, "use a diff3 based merge", XDL_MERGE_DIFF3),
- OPT_SET_INT(0, "ours", &xmp.favor, "for conflicts, use our version",
+ OPT_BOOLEAN('p', "stdout", &to_stdout, N_("send results to standard output")),
+ OPT_SET_INT(0, "diff3", &xmp.style, N_("use a diff3 based merge"), XDL_MERGE_DIFF3),
+ OPT_SET_INT(0, "ours", &xmp.favor, N_("for conflicts, use our version"),
XDL_MERGE_FAVOR_OURS),
- OPT_SET_INT(0, "theirs", &xmp.favor, "for conflicts, use their version",
+ OPT_SET_INT(0, "theirs", &xmp.favor, N_("for conflicts, use their version"),
XDL_MERGE_FAVOR_THEIRS),
- OPT_SET_INT(0, "union", &xmp.favor, "for conflicts, use a union version",
+ OPT_SET_INT(0, "union", &xmp.favor, N_("for conflicts, use a union version"),
XDL_MERGE_FAVOR_UNION),
OPT_INTEGER(0, "marker-size", &xmp.marker_size,
- "for conflicts, use this marker size"),
- OPT__QUIET(&quiet, "do not warn about conflicts"),
- OPT_CALLBACK('L', NULL, names, "name",
- "set labels for file1/orig_file/file2", &label_cb),
+ N_("for conflicts, use this marker size")),
+ OPT__QUIET(&quiet, N_("do not warn about conflicts")),
+ OPT_CALLBACK('L', NULL, names, N_("name"),
+ N_("set labels for file1/orig_file/file2"), &label_cb),
OPT_END(),
};
diff --git a/builtin/merge.c b/builtin/merge.c
index e81fde6..0ec8f0d 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -40,9 +40,9 @@ struct strategy {
};
static const char * const builtin_merge_usage[] = {
- "git merge [options] [<commit>...]",
- "git merge [options] <msg> HEAD <commit>",
- "git merge --abort",
+ N_("git merge [options] [<commit>...]"),
+ N_("git merge [options] <msg> HEAD <commit>"),
+ N_("git merge --abort"),
NULL
};
@@ -180,39 +180,39 @@ static int option_parse_n(const struct option *opt,
static struct option builtin_merge_options[] = {
{ OPTION_CALLBACK, 'n', NULL, NULL, NULL,
- "do not show a diffstat at the end of the merge",
+ N_("do not show a diffstat at the end of the merge"),
PARSE_OPT_NOARG, option_parse_n },
OPT_BOOLEAN(0, "stat", &show_diffstat,
- "show a diffstat at the end of the merge"),
- OPT_BOOLEAN(0, "summary", &show_diffstat, "(synonym to --stat)"),
- { OPTION_INTEGER, 0, "log", &shortlog_len, "n",
- "add (at most <n>) entries from shortlog to merge commit message",
+ N_("show a diffstat at the end of the merge")),
+ OPT_BOOLEAN(0, "summary", &show_diffstat, N_("(synonym to --stat)")),
+ { OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"),
+ N_("add (at most <n>) entries from shortlog to merge commit message"),
PARSE_OPT_OPTARG, NULL, DEFAULT_MERGE_LOG_LEN },
OPT_BOOLEAN(0, "squash", &squash,
- "create a single commit instead of doing a merge"),
+ N_("create a single commit instead of doing a merge")),
OPT_BOOLEAN(0, "commit", &option_commit,
- "perform a commit if the merge succeeds (default)"),
+ N_("perform a commit if the merge succeeds (default)")),
OPT_BOOL('e', "edit", &option_edit,
- "edit message before committing"),
+ N_("edit message before committing")),
OPT_BOOLEAN(0, "ff", &allow_fast_forward,
- "allow fast-forward (default)"),
+ N_("allow fast-forward (default)")),
OPT_BOOLEAN(0, "ff-only", &fast_forward_only,
- "abort if fast-forward is not possible"),
+ N_("abort if fast-forward is not possible")),
OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
- OPT_CALLBACK('s', "strategy", &use_strategies, "strategy",
- "merge strategy to use", option_parse_strategy),
- OPT_CALLBACK('X', "strategy-option", &xopts, "option=value",
- "option for selected merge strategy", option_parse_x),
- OPT_CALLBACK('m', "message", &merge_msg, "message",
- "merge commit message (for a non-fast-forward merge)",
+ OPT_CALLBACK('s', "strategy", &use_strategies, N_("strategy"),
+ N_("merge strategy to use"), option_parse_strategy),
+ OPT_CALLBACK('X', "strategy-option", &xopts, N_("option=value"),
+ N_("option for selected merge strategy"), option_parse_x),
+ OPT_CALLBACK('m', "message", &merge_msg, N_("message"),
+ N_("merge commit message (for a non-fast-forward merge)"),
option_parse_message),
OPT__VERBOSITY(&verbosity),
OPT_BOOLEAN(0, "abort", &abort_current_merge,
- "abort the current in-progress merge"),
- OPT_SET_INT(0, "progress", &show_progress, "force progress reporting", 1),
- { OPTION_STRING, 'S', "gpg-sign", &sign_commit, "key id",
- "GPG sign commit", PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
- OPT_BOOLEAN(0, "overwrite-ignore", &overwrite_ignore, "update ignored files (default)"),
+ N_("abort the current in-progress merge")),
+ OPT_SET_INT(0, "progress", &show_progress, N_("force progress reporting"), 1),
+ { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"),
+ N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
+ OPT_BOOLEAN(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
OPT_END()
};
diff --git a/builtin/mktree.c b/builtin/mktree.c
index 4ae1c41..f92ba40 100644
--- a/builtin/mktree.c
+++ b/builtin/mktree.c
@@ -64,7 +64,7 @@ static void write_tree(unsigned char *sha1)
}
static const char *mktree_usage[] = {
- "git mktree [-z] [--missing] [--batch]",
+ N_("git mktree [-z] [--missing] [--batch]"),
NULL
};
@@ -150,9 +150,9 @@ int cmd_mktree(int ac, const char **av, const char *prefix)
int got_eof = 0;
const struct option option[] = {
- OPT_SET_INT('z', NULL, &line_termination, "input is NUL terminated", '\0'),
- OPT_SET_INT( 0 , "missing", &allow_missing, "allow missing objects", 1),
- OPT_SET_INT( 0 , "batch", &is_batch_mode, "allow creation of more than one tree", 1),
+ OPT_SET_INT('z', NULL, &line_termination, N_("input is NUL terminated"), '\0'),
+ OPT_SET_INT( 0 , "missing", &allow_missing, N_("allow missing objects"), 1),
+ OPT_SET_INT( 0 , "batch", &is_batch_mode, N_("allow creation of more than one tree"), 1),
OPT_END()
};
diff --git a/builtin/mv.c b/builtin/mv.c
index 2a144b0..034fec9 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -11,7 +11,7 @@
#include "parse-options.h"
static const char * const builtin_mv_usage[] = {
- "git mv [options] <source>... <destination>",
+ N_("git mv [options] <source>... <destination>"),
NULL
};
@@ -59,10 +59,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
int i, newfd;
int verbose = 0, show_only = 0, force = 0, ignore_errors = 0;
struct option builtin_mv_options[] = {
- OPT__VERBOSE(&verbose, "be verbose"),
- OPT__DRY_RUN(&show_only, "dry run"),
- OPT__FORCE(&force, "force move/rename even if target exists"),
- OPT_BOOLEAN('k', NULL, &ignore_errors, "skip move/rename errors"),
+ OPT__VERBOSE(&verbose, N_("be verbose")),
+ OPT__DRY_RUN(&show_only, N_("dry run")),
+ OPT__FORCE(&force, N_("force move/rename even if target exists")),
+ OPT_BOOLEAN('k', NULL, &ignore_errors, N_("skip move/rename errors")),
OPT_END(),
};
const char **source, **destination, **dest_path;
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 1b37458..6238247 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -172,9 +172,9 @@ static void show_name(const struct object *obj,
}
static char const * const name_rev_usage[] = {
- "git name-rev [options] <commit>...",
- "git name-rev [options] --all",
- "git name-rev [options] --stdin",
+ N_("git name-rev [options] <commit>..."),
+ N_("git name-rev [options] --all"),
+ N_("git name-rev [options] --stdin"),
NULL
};
@@ -226,16 +226,16 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
int all = 0, transform_stdin = 0, allow_undefined = 1, always = 0;
struct name_ref_data data = { 0, 0, NULL };
struct option opts[] = {
- OPT_BOOLEAN(0, "name-only", &data.name_only, "print only names (no SHA-1)"),
- OPT_BOOLEAN(0, "tags", &data.tags_only, "only use tags to name the commits"),
- OPT_STRING(0, "refs", &data.ref_filter, "pattern",
- "only use refs matching <pattern>"),
+ OPT_BOOLEAN(0, "name-only", &data.name_only, N_("print only names (no SHA-1)")),
+ OPT_BOOLEAN(0, "tags", &data.tags_only, N_("only use tags to name the commits")),
+ OPT_STRING(0, "refs", &data.ref_filter, N_("pattern"),
+ N_("only use refs matching <pattern>")),
OPT_GROUP(""),
- OPT_BOOLEAN(0, "all", &all, "list all commits reachable from all refs"),
- OPT_BOOLEAN(0, "stdin", &transform_stdin, "read from stdin"),
- OPT_BOOLEAN(0, "undefined", &allow_undefined, "allow to print `undefined` names"),
+ OPT_BOOLEAN(0, "all", &all, N_("list all commits reachable from all refs")),
+ OPT_BOOLEAN(0, "stdin", &transform_stdin, N_("read from stdin")),
+ OPT_BOOLEAN(0, "undefined", &allow_undefined, N_("allow to print `undefined` names")),
OPT_BOOLEAN(0, "always", &always,
- "show abbreviated commit object as fallback"),
+ N_("show abbreviated commit object as fallback")),
OPT_END(),
};
diff --git a/builtin/notes.c b/builtin/notes.c
index 3644d14..453457a 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -19,72 +19,75 @@
#include "string-list.h"
#include "notes-merge.h"
+static void commit_notes(struct notes_tree *t, const char *msg);
+static combine_notes_fn parse_combine_notes_fn(const char *v);
+
static const char * const git_notes_usage[] = {
- "git notes [--ref <notes_ref>] [list [<object>]]",
- "git notes [--ref <notes_ref>] add [-f] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]",
- "git notes [--ref <notes_ref>] copy [-f] <from-object> <to-object>",
- "git notes [--ref <notes_ref>] append [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]",
- "git notes [--ref <notes_ref>] edit [<object>]",
- "git notes [--ref <notes_ref>] show [<object>]",
- "git notes [--ref <notes_ref>] merge [-v | -q] [-s <strategy> ] <notes_ref>",
- "git notes merge --commit [-v | -q]",
- "git notes merge --abort [-v | -q]",
- "git notes [--ref <notes_ref>] remove [<object>...]",
- "git notes [--ref <notes_ref>] prune [-n | -v]",
- "git notes [--ref <notes_ref>] get-ref",
+ N_("git notes [--ref <notes_ref>] [list [<object>]]"),
+ N_("git notes [--ref <notes_ref>] add [-f] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
+ N_("git notes [--ref <notes_ref>] copy [-f] <from-object> <to-object>"),
+ N_("git notes [--ref <notes_ref>] append [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
+ N_("git notes [--ref <notes_ref>] edit [<object>]"),
+ N_("git notes [--ref <notes_ref>] show [<object>]"),
+ N_("git notes [--ref <notes_ref>] merge [-v | -q] [-s <strategy> ] <notes_ref>"),
+ N_("git notes merge --commit [-v | -q]"),
+ N_("git notes merge --abort [-v | -q]"),
+ N_("git notes [--ref <notes_ref>] remove [<object>...]"),
+ N_("git notes [--ref <notes_ref>] prune [-n | -v]"),
+ N_("git notes [--ref <notes_ref>] get-ref"),
NULL
};
static const char * const git_notes_list_usage[] = {
- "git notes [list [<object>]]",
+ N_("git notes [list [<object>]]"),
NULL
};
static const char * const git_notes_add_usage[] = {
- "git notes add [<options>] [<object>]",
+ N_("git notes add [<options>] [<object>]"),
NULL
};
static const char * const git_notes_copy_usage[] = {
- "git notes copy [<options>] <from-object> <to-object>",
- "git notes copy --stdin [<from-object> <to-object>]...",
+ N_("git notes copy [<options>] <from-object> <to-object>"),
+ N_("git notes copy --stdin [<from-object> <to-object>]..."),
NULL
};
static const char * const git_notes_append_usage[] = {
- "git notes append [<options>] [<object>]",
+ N_("git notes append [<options>] [<object>]"),
NULL
};
static const char * const git_notes_edit_usage[] = {
- "git notes edit [<object>]",
+ N_("git notes edit [<object>]"),
NULL
};
static const char * const git_notes_show_usage[] = {
- "git notes show [<object>]",
+ N_("git notes show [<object>]"),
NULL
};
static const char * const git_notes_merge_usage[] = {
- "git notes merge [<options>] <notes_ref>",
- "git notes merge --commit [<options>]",
- "git notes merge --abort [<options>]",
+ N_("git notes merge [<options>] <notes_ref>"),
+ N_("git notes merge --commit [<options>]"),
+ N_("git notes merge --abort [<options>]"),
NULL
};
static const char * const git_notes_remove_usage[] = {
- "git notes remove [<object>]",
+ N_("git notes remove [<object>]"),
NULL
};
static const char * const git_notes_prune_usage[] = {
- "git notes prune [<options>]",
+ N_("git notes prune [<options>]"),
NULL
};
static const char * const git_notes_get_ref_usage[] = {
- "git notes get-ref",
+ N_("git notes get-ref"),
NULL
};
@@ -288,7 +291,7 @@ static int parse_reedit_arg(const struct option *opt, const char *arg, int unset
return parse_reuse_arg(opt, arg, unset);
}
-void commit_notes(struct notes_tree *t, const char *msg)
+static void commit_notes(struct notes_tree *t, const char *msg)
{
struct strbuf buf = STRBUF_INIT;
unsigned char commit_sha1[20];
@@ -312,7 +315,7 @@ void commit_notes(struct notes_tree *t, const char *msg)
strbuf_release(&buf);
}
-combine_notes_fn parse_combine_notes_fn(const char *v)
+static combine_notes_fn parse_combine_notes_fn(const char *v)
{
if (!strcasecmp(v, "overwrite"))
return combine_notes_overwrite;
@@ -531,19 +534,19 @@ static int add(int argc, const char **argv, const char *prefix)
const unsigned char *note;
struct msg_arg msg = { 0, 0, STRBUF_INIT };
struct option options[] = {
- { OPTION_CALLBACK, 'm', "message", &msg, "msg",
- "note contents as a string", PARSE_OPT_NONEG,
+ { OPTION_CALLBACK, 'm', "message", &msg, N_("message"),
+ N_("note contents as a string"), PARSE_OPT_NONEG,
parse_msg_arg},
- { OPTION_CALLBACK, 'F', "file", &msg, "file",
- "note contents in a file", PARSE_OPT_NONEG,
+ { OPTION_CALLBACK, 'F', "file", &msg, N_("file"),
+ N_("note contents in a file"), PARSE_OPT_NONEG,
parse_file_arg},
- { OPTION_CALLBACK, 'c', "reedit-message", &msg, "object",
- "reuse and edit specified note object", PARSE_OPT_NONEG,
+ { OPTION_CALLBACK, 'c', "reedit-message", &msg, N_("object"),
+ N_("reuse and edit specified note object"), PARSE_OPT_NONEG,
parse_reedit_arg},
- { OPTION_CALLBACK, 'C', "reuse-message", &msg, "object",
- "reuse specified note object", PARSE_OPT_NONEG,
+ { OPTION_CALLBACK, 'C', "reuse-message", &msg, N_("object"),
+ N_("reuse specified note object"), PARSE_OPT_NONEG,
parse_reuse_arg},
- OPT__FORCE(&force, "replace existing notes"),
+ OPT__FORCE(&force, N_("replace existing notes")),
OPT_END()
};
@@ -611,11 +614,11 @@ static int copy(int argc, const char **argv, const char *prefix)
struct notes_tree *t;
const char *rewrite_cmd = NULL;
struct option options[] = {
- OPT__FORCE(&force, "replace existing notes"),
- OPT_BOOLEAN(0, "stdin", &from_stdin, "read objects from stdin"),
- OPT_STRING(0, "for-rewrite", &rewrite_cmd, "command",
- "load rewriting config for <command> (implies "
- "--stdin)"),
+ OPT__FORCE(&force, N_("replace existing notes")),
+ OPT_BOOLEAN(0, "stdin", &from_stdin, N_("read objects from stdin")),
+ OPT_STRING(0, "for-rewrite", &rewrite_cmd, N_("command"),
+ N_("load rewriting config for <command> (implies "
+ "--stdin)")),
OPT_END()
};
@@ -688,17 +691,17 @@ static int append_edit(int argc, const char **argv, const char *prefix)
const char * const *usage;
struct msg_arg msg = { 0, 0, STRBUF_INIT };
struct option options[] = {
- { OPTION_CALLBACK, 'm', "message", &msg, "msg",
- "note contents as a string", PARSE_OPT_NONEG,
+ { OPTION_CALLBACK, 'm', "message", &msg, N_("message"),
+ N_("note contents as a string"), PARSE_OPT_NONEG,
parse_msg_arg},
- { OPTION_CALLBACK, 'F', "file", &msg, "file",
- "note contents in a file", PARSE_OPT_NONEG,
+ { OPTION_CALLBACK, 'F', "file", &msg, N_("file"),
+ N_("note contents in a file"), PARSE_OPT_NONEG,
parse_file_arg},
- { OPTION_CALLBACK, 'c', "reedit-message", &msg, "object",
- "reuse and edit specified note object", PARSE_OPT_NONEG,
+ { OPTION_CALLBACK, 'c', "reedit-message", &msg, N_("object"),
+ N_("reuse and edit specified note object"), PARSE_OPT_NONEG,
parse_reedit_arg},
- { OPTION_CALLBACK, 'C', "reuse-message", &msg, "object",
- "reuse specified note object", PARSE_OPT_NONEG,
+ { OPTION_CALLBACK, 'C', "reuse-message", &msg, N_("object"),
+ N_("reuse specified note object"), PARSE_OPT_NONEG,
parse_reuse_arg},
OPT_END()
};
@@ -861,19 +864,19 @@ static int merge(int argc, const char **argv, const char *prefix)
int verbosity = 0, result;
const char *strategy = NULL;
struct option options[] = {
- OPT_GROUP("General options"),
+ OPT_GROUP(N_("General options")),
OPT__VERBOSITY(&verbosity),
- OPT_GROUP("Merge options"),
- OPT_STRING('s', "strategy", &strategy, "strategy",
- "resolve notes conflicts using the given strategy "
- "(manual/ours/theirs/union/cat_sort_uniq)"),
- OPT_GROUP("Committing unmerged notes"),
+ OPT_GROUP(N_("Merge options")),
+ OPT_STRING('s', "strategy", &strategy, N_("strategy"),
+ N_("resolve notes conflicts using the given strategy "
+ "(manual/ours/theirs/union/cat_sort_uniq)")),
+ OPT_GROUP(N_("Committing unmerged notes")),
{ OPTION_BOOLEAN, 0, "commit", &do_commit, NULL,
- "finalize notes merge by committing unmerged notes",
+ N_("finalize notes merge by committing unmerged notes"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG },
- OPT_GROUP("Aborting notes merge resolution"),
+ OPT_GROUP(N_("Aborting notes merge resolution")),
{ OPTION_BOOLEAN, 0, "abort", &do_abort, NULL,
- "abort notes merge",
+ N_("abort notes merge"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG },
OPT_END()
};
@@ -980,10 +983,10 @@ static int remove_cmd(int argc, const char **argv, const char *prefix)
int from_stdin = 0;
struct option options[] = {
OPT_BIT(0, "ignore-missing", &flag,
- "attempt to remove non-existent note is not an error",
+ N_("attempt to remove non-existent note is not an error"),
IGNORE_MISSING),
OPT_BOOLEAN(0, "stdin", &from_stdin,
- "read object names from the standard input"),
+ N_("read object names from the standard input")),
OPT_END()
};
struct notes_tree *t;
@@ -1064,8 +1067,8 @@ int cmd_notes(int argc, const char **argv, const char *prefix)
int result;
const char *override_notes_ref = NULL;
struct option options[] = {
- OPT_STRING(0, "ref", &override_notes_ref, "notes_ref",
- "use notes from <notes_ref>"),
+ OPT_STRING(0, "ref", &override_notes_ref, N_("notes_ref"),
+ N_("use notes from <notes_ref>")),
OPT_END()
};
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 782e7d0..5e14064 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -20,8 +20,8 @@
#include "thread-utils.h"
static const char *pack_usage[] = {
- "git pack-objects --stdout [options...] [< ref-list | < object-list]",
- "git pack-objects [options...] base-name [< ref-list | < object-list]",
+ N_("git pack-objects --stdout [options...] [< ref-list | < object-list]"),
+ N_("git pack-objects [options...] base-name [< ref-list | < object-list]"),
NULL
};
@@ -2445,67 +2445,67 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
int rev_list_unpacked = 0, rev_list_all = 0, rev_list_reflog = 0;
struct option pack_objects_options[] = {
OPT_SET_INT('q', "quiet", &progress,
- "do not show progress meter", 0),
+ N_("do not show progress meter"), 0),
OPT_SET_INT(0, "progress", &progress,
- "show progress meter", 1),
+ N_("show progress meter"), 1),
OPT_SET_INT(0, "all-progress", &progress,
- "show progress meter during object writing phase", 2),
+ N_("show progress meter during object writing phase"), 2),
OPT_BOOL(0, "all-progress-implied",
&all_progress_implied,
- "similar to --all-progress when progress meter is shown"),
- { OPTION_CALLBACK, 0, "index-version", NULL, "version[,offset]",
- "write the pack index file in the specified idx format version",
+ N_("similar to --all-progress when progress meter is shown")),
+ { OPTION_CALLBACK, 0, "index-version", NULL, N_("version[,offset]"),
+ N_("write the pack index file in the specified idx format version"),
0, option_parse_index_version },
OPT_ULONG(0, "max-pack-size", &pack_size_limit,
- "maximum size of each output pack file"),
+ N_("maximum size of each output pack file")),
OPT_BOOL(0, "local", &local,
- "ignore borrowed objects from alternate object store"),
+ N_("ignore borrowed objects from alternate object store")),
OPT_BOOL(0, "incremental", &incremental,
- "ignore packed objects"),
+ N_("ignore packed objects")),
OPT_INTEGER(0, "window", &window,
- "limit pack window by objects"),
+ N_("limit pack window by objects")),
OPT_ULONG(0, "window-memory", &window_memory_limit,
- "limit pack window by memory in addition to object limit"),
+ N_("limit pack window by memory in addition to object limit")),
OPT_INTEGER(0, "depth", &depth,
- "maximum length of delta chain allowed in the resulting pack"),
+ N_("maximum length of delta chain allowed in the resulting pack")),
OPT_BOOL(0, "reuse-delta", &reuse_delta,
- "reuse existing deltas"),
+ N_("reuse existing deltas")),
OPT_BOOL(0, "reuse-object", &reuse_object,
- "reuse existing objects"),
+ N_("reuse existing objects")),
OPT_BOOL(0, "delta-base-offset", &allow_ofs_delta,
- "use OFS_DELTA objects"),
+ N_("use OFS_DELTA objects")),
OPT_INTEGER(0, "threads", &delta_search_threads,
- "use threads when searching for best delta matches"),
+ N_("use threads when searching for best delta matches")),
OPT_BOOL(0, "non-empty", &non_empty,
- "do not create an empty pack output"),
+ N_("do not create an empty pack output")),
OPT_BOOL(0, "revs", &use_internal_rev_list,
- "read revision arguments from standard input"),
+ N_("read revision arguments from standard input")),
{ OPTION_SET_INT, 0, "unpacked", &rev_list_unpacked, NULL,
- "limit the objects to those that are not yet packed",
+ N_("limit the objects to those that are not yet packed"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
{ OPTION_SET_INT, 0, "all", &rev_list_all, NULL,
- "include objects reachable from any reference",
+ N_("include objects reachable from any reference"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
{ OPTION_SET_INT, 0, "reflog", &rev_list_reflog, NULL,
- "include objects referred by reflog entries",
+ N_("include objects referred by reflog entries"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
OPT_BOOL(0, "stdout", &pack_to_stdout,
- "output pack to stdout"),
+ N_("output pack to stdout")),
OPT_BOOL(0, "include-tag", &include_tag,
- "include tag objects that refer to objects to be packed"),
+ N_("include tag objects that refer to objects to be packed")),
OPT_BOOL(0, "keep-unreachable", &keep_unreachable,
- "keep unreachable objects"),
- { OPTION_CALLBACK, 0, "unpack-unreachable", NULL, "time",
- "unpack unreachable objects newer than <time>",
+ N_("keep unreachable objects")),
+ { OPTION_CALLBACK, 0, "unpack-unreachable", NULL, N_("time"),
+ N_("unpack unreachable objects newer than <time>"),
PARSE_OPT_OPTARG, option_parse_unpack_unreachable },
OPT_BOOL(0, "thin", &thin,
- "create thin packs"),
+ N_("create thin packs")),
OPT_BOOL(0, "honor-pack-keep", &ignore_packed_keep,
- "ignore packs that have companion .keep file"),
+ N_("ignore packs that have companion .keep file")),
OPT_INTEGER(0, "compression", &pack_compression_level,
- "pack compression level"),
+ N_("pack compression level")),
OPT_SET_INT(0, "keep-true-parents", &grafts_replace_parents,
- "do not hide commits by grafts", 0),
+ N_("do not hide commits by grafts"), 0),
OPT_END(),
};
diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c
index 39a9d89..b5a0f88 100644
--- a/builtin/pack-refs.c
+++ b/builtin/pack-refs.c
@@ -3,7 +3,7 @@
#include "pack-refs.h"
static char const * const pack_refs_usage[] = {
- "git pack-refs [options]",
+ N_("git pack-refs [options]"),
NULL
};
@@ -11,8 +11,8 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix)
{
unsigned int flags = PACK_REFS_PRUNE;
struct option opts[] = {
- OPT_BIT(0, "all", &flags, "pack everything", PACK_REFS_ALL),
- OPT_BIT(0, "prune", &flags, "prune loose refs (default)", PACK_REFS_PRUNE),
+ OPT_BIT(0, "all", &flags, N_("pack everything"), PACK_REFS_ALL),
+ OPT_BIT(0, "prune", &flags, N_("prune loose refs (default)"), PACK_REFS_PRUNE),
OPT_END(),
};
if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0))
diff --git a/builtin/prune-packed.c b/builtin/prune-packed.c
index b58a2e1..83382c1 100644
--- a/builtin/prune-packed.c
+++ b/builtin/prune-packed.c
@@ -4,7 +4,7 @@
#include "parse-options.h"
static const char * const prune_packed_usage[] = {
- "git prune-packed [-n|--dry-run] [-q|--quiet]",
+ N_("git prune-packed [-n|--dry-run] [-q|--quiet]"),
NULL
};
@@ -73,8 +73,8 @@ int cmd_prune_packed(int argc, const char **argv, const char *prefix)
{
int opts = isatty(2) ? VERBOSE : 0;
const struct option prune_packed_options[] = {
- OPT_BIT('n', "dry-run", &opts, "dry run", DRY_RUN),
- OPT_NEGBIT('q', "quiet", &opts, "be quiet", VERBOSE),
+ OPT_BIT('n', "dry-run", &opts, N_("dry run"), DRY_RUN),
+ OPT_NEGBIT('q', "quiet", &opts, N_("be quiet"), VERBOSE),
OPT_END()
};
diff --git a/builtin/prune.c b/builtin/prune.c
index 6cb9944..8cb8b91 100644
--- a/builtin/prune.c
+++ b/builtin/prune.c
@@ -9,7 +9,7 @@
#include "dir.h"
static const char * const prune_usage[] = {
- "git prune [-n] [-v] [--expire <time>] [--] [<head>...]",
+ N_("git prune [-n] [-v] [--expire <time>] [--] [<head>...]"),
NULL
};
static int show_only;
@@ -129,11 +129,11 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
struct rev_info revs;
struct progress *progress = NULL;
const struct option options[] = {
- OPT__DRY_RUN(&show_only, "do not remove, show only"),
- OPT__VERBOSE(&verbose, "report pruned objects"),
- OPT_BOOL(0, "progress", &show_progress, "show progress"),
+ OPT__DRY_RUN(&show_only, N_("do not remove, show only")),
+ OPT__VERBOSE(&verbose, N_("report pruned objects")),
+ OPT_BOOL(0, "progress", &show_progress, N_("show progress")),
OPT_DATE(0, "expire", &expire,
- "expire objects older than <time>"),
+ N_("expire objects older than <time>")),
OPT_END()
};
char *s;
@@ -169,7 +169,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
prune_packed_objects(show_only);
remove_temporary_files(get_object_directory());
- s = xstrdup(mkpath("%s/pack", get_object_directory()));
+ s = mkpathdup("%s/pack", get_object_directory());
remove_temporary_files(s);
free(s);
return 0;
diff --git a/builtin/push.c b/builtin/push.c
index fdfcc6c..db9ba30 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -11,7 +11,7 @@
#include "submodule.h"
static const char * const push_usage[] = {
- "git push [<options>] [<repository> [<refspec>...]]",
+ N_("git push [<options>] [<repository> [<refspec>...]]"),
NULL,
};
@@ -147,12 +147,37 @@ static void setup_push_upstream(struct remote *remote, int simple)
add_refspec(refspec.buf);
}
+static char warn_unspecified_push_default_msg[] =
+N_("push.default is unset; its implicit value is changing in\n"
+ "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
+ "and maintain the current behavior after the default changes, use:\n"
+ "\n"
+ " git config --global push.default matching\n"
+ "\n"
+ "To squelch this message and adopt the new behavior now, use:\n"
+ "\n"
+ " git config --global push.default simple\n"
+ "\n"
+ "See 'git help config' and search for 'push.default' for further information.\n"
+ "(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode\n"
+ "'current' instead of 'simple' if you sometimes use older versions of Git)");
+
+static void warn_unspecified_push_default_configuration(void)
+{
+ static int warn_once;
+
+ if (warn_once++)
+ return;
+ warning("%s\n", _(warn_unspecified_push_default_msg));
+}
+
static void setup_default_push_refspecs(struct remote *remote)
{
switch (push_default) {
default:
case PUSH_DEFAULT_UNSPECIFIED:
default_matching_used = 1;
+ warn_unspecified_push_default_configuration();
/* fallthru */
case PUSH_DEFAULT_MATCHING:
add_refspec(":");
@@ -186,8 +211,8 @@ static const char message_advice_pull_before_push[] =
static const char message_advice_use_upstream[] =
N_("Updates were rejected because a pushed branch tip is behind its remote\n"
"counterpart. If you did not intend to push that branch, you may want to\n"
- "specify branches to push or set the 'push.default' configuration\n"
- "variable to 'current' or 'upstream' to push only the current branch.");
+ "specify branches to push or set the 'push.default' configuration variable\n"
+ "to 'simple', 'current' or 'upstream' to push only the current branch.");
static const char message_advice_checkout_pull_push[] =
N_("Updates were rejected because a pushed branch tip is behind its remote\n"
@@ -354,25 +379,25 @@ int cmd_push(int argc, const char **argv, const char *prefix)
const char *repo = NULL; /* default repository */
struct option options[] = {
OPT__VERBOSITY(&verbosity),
- OPT_STRING( 0 , "repo", &repo, "repository", "repository"),
- OPT_BIT( 0 , "all", &flags, "push all refs", TRANSPORT_PUSH_ALL),
- OPT_BIT( 0 , "mirror", &flags, "mirror all refs",
+ OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")),
+ OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL),
+ OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"),
(TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
- OPT_BOOLEAN( 0, "delete", &deleterefs, "delete refs"),
- OPT_BOOLEAN( 0 , "tags", &tags, "push tags (can't be used with --all or --mirror)"),
- OPT_BIT('n' , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN),
- OPT_BIT( 0, "porcelain", &flags, "machine-readable output", TRANSPORT_PUSH_PORCELAIN),
- OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE),
- { OPTION_CALLBACK, 0, "recurse-submodules", &flags, "check",
- "controls recursive pushing of submodules",
+ OPT_BOOLEAN( 0, "delete", &deleterefs, N_("delete refs")),
+ OPT_BOOLEAN( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")),
+ OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN),
+ OPT_BIT( 0, "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN),
+ OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE),
+ { OPTION_CALLBACK, 0, "recurse-submodules", &flags, N_("check"),
+ N_("control recursive pushing of submodules"),
PARSE_OPT_OPTARG, option_parse_recurse_submodules },
- OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"),
- OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"),
- OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"),
- OPT_BIT('u', "set-upstream", &flags, "set upstream for git pull/status",
+ OPT_BOOLEAN( 0 , "thin", &thin, N_("use thin pack")),
+ OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", N_("receive pack program")),
+ OPT_STRING( 0 , "exec", &receivepack, "receive-pack", N_("receive pack program")),
+ OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git pull/status"),
TRANSPORT_PUSH_SET_UPSTREAM),
- OPT_BOOL(0, "progress", &progress, "force progress reporting"),
- OPT_BIT(0, "prune", &flags, "prune locally removed refs",
+ OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
+ OPT_BIT(0, "prune", &flags, N_("prune locally removed refs"),
TRANSPORT_PUSH_PRUNE),
OPT_END()
};
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index df6c4c8..042ac1b 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -33,7 +33,7 @@ static int list_tree(unsigned char *sha1)
}
static const char * const read_tree_usage[] = {
- "git read-tree [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--index-output=<file>] (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])",
+ N_("git read-tree [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--index-output=<file>] (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"),
NULL
};
@@ -104,37 +104,37 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
struct unpack_trees_options opts;
int prefix_set = 0;
const struct option read_tree_options[] = {
- { OPTION_CALLBACK, 0, "index-output", NULL, "file",
- "write resulting index to <file>",
+ { OPTION_CALLBACK, 0, "index-output", NULL, N_("file"),
+ N_("write resulting index to <file>"),
PARSE_OPT_NONEG, index_output_cb },
OPT_SET_INT(0, "empty", &read_empty,
- "only empty the index", 1),
- OPT__VERBOSE(&opts.verbose_update, "be verbose"),
- OPT_GROUP("Merging"),
+ N_("only empty the index"), 1),
+ OPT__VERBOSE(&opts.verbose_update, N_("be verbose")),
+ OPT_GROUP(N_("Merging")),
OPT_SET_INT('m', NULL, &opts.merge,
- "perform a merge in addition to a read", 1),
+ N_("perform a merge in addition to a read"), 1),
OPT_SET_INT(0, "trivial", &opts.trivial_merges_only,
- "3-way merge if no file level merging required", 1),
+ N_("3-way merge if no file level merging required"), 1),
OPT_SET_INT(0, "aggressive", &opts.aggressive,
- "3-way merge in presence of adds and removes", 1),
+ N_("3-way merge in presence of adds and removes"), 1),
OPT_SET_INT(0, "reset", &opts.reset,
- "same as -m, but discard unmerged entries", 1),
- { OPTION_STRING, 0, "prefix", &opts.prefix, "<subdirectory>/",
- "read the tree into the index under <subdirectory>/",
+ N_("same as -m, but discard unmerged entries"), 1),
+ { OPTION_STRING, 0, "prefix", &opts.prefix, N_("<subdirectory>/"),
+ N_("read the tree into the index under <subdirectory>/"),
PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP },
OPT_SET_INT('u', NULL, &opts.update,
- "update working tree with merge result", 1),
+ N_("update working tree with merge result"), 1),
{ OPTION_CALLBACK, 0, "exclude-per-directory", &opts,
- "gitignore",
- "allow explicitly ignored files to be overwritten",
+ N_("gitignore"),
+ N_("allow explicitly ignored files to be overwritten"),
PARSE_OPT_NONEG, exclude_per_directory_cb },
OPT_SET_INT('i', NULL, &opts.index_only,
- "don't check the working tree after merging", 1),
- OPT__DRY_RUN(&opts.dry_run, "don't update the index or the work tree"),
+ N_("don't check the working tree after merging"), 1),
+ OPT__DRY_RUN(&opts.dry_run, N_("don't update the index or the work tree")),
OPT_SET_INT(0, "no-sparse-checkout", &opts.skip_sparse_checkout,
- "skip applying sparse checkout filter", 1),
+ N_("skip applying sparse checkout filter"), 1),
OPT_SET_INT(0, "debug-unpack", &opts.debug_unpack,
- "debug unpack-trees", 1),
+ N_("debug unpack-trees"), 1),
OPT_END()
};
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 165a633..ff781fe 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -480,7 +480,6 @@ static const char *update(struct command *cmd)
!prefixcmp(name, "refs/heads/")) {
struct object *old_object, *new_object;
struct commit *old_commit, *new_commit;
- struct commit_list *bases, *ent;
old_object = parse_object(old_sha1);
new_object = parse_object(new_sha1);
@@ -493,12 +492,7 @@ static const char *update(struct command *cmd)
}
old_commit = (struct commit *)old_object;
new_commit = (struct commit *)new_object;
- bases = get_merge_bases(old_commit, new_commit, 1);
- for (ent = bases; ent; ent = ent->next)
- if (!hashcmp(old_sha1, ent->item->object.sha1))
- break;
- free_commit_list(bases);
- if (!ent) {
+ if (!in_merge_bases(old_commit, new_commit)) {
rp_error("denying non-fast-forward %s"
" (you should pull first)", name);
return "non-fast-forward";
diff --git a/builtin/remote.c b/builtin/remote.c
index 357d59d..a5a4b23 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -8,66 +8,66 @@
#include "refs.h"
static const char * const builtin_remote_usage[] = {
- "git remote [-v | --verbose]",
- "git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>",
- "git remote rename <old> <new>",
- "git remote remove <name>",
- "git remote set-head <name> (-a | -d | <branch>)",
- "git remote [-v | --verbose] show [-n] <name>",
- "git remote prune [-n | --dry-run] <name>",
- "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]",
- "git remote set-branches [--add] <name> <branch>...",
- "git remote set-url [--push] <name> <newurl> [<oldurl>]",
- "git remote set-url --add <name> <newurl>",
- "git remote set-url --delete <name> <url>",
+ N_("git remote [-v | --verbose]"),
+ N_("git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>"),
+ N_("git remote rename <old> <new>"),
+ N_("git remote remove <name>"),
+ N_("git remote set-head <name> (-a | -d | <branch>)"),
+ N_("git remote [-v | --verbose] show [-n] <name>"),
+ N_("git remote prune [-n | --dry-run] <name>"),
+ N_("git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"),
+ N_("git remote set-branches [--add] <name> <branch>..."),
+ N_("git remote set-url [--push] <name> <newurl> [<oldurl>]"),
+ N_("git remote set-url --add <name> <newurl>"),
+ N_("git remote set-url --delete <name> <url>"),
NULL
};
static const char * const builtin_remote_add_usage[] = {
- "git remote add [<options>] <name> <url>",
+ N_("git remote add [<options>] <name> <url>"),
NULL
};
static const char * const builtin_remote_rename_usage[] = {
- "git remote rename <old> <new>",
+ N_("git remote rename <old> <new>"),
NULL
};
static const char * const builtin_remote_rm_usage[] = {
- "git remote remove <name>",
+ N_("git remote remove <name>"),
NULL
};
static const char * const builtin_remote_sethead_usage[] = {
- "git remote set-head <name> (-a | -d | <branch>])",
+ N_("git remote set-head <name> (-a | -d | <branch>])"),
NULL
};
static const char * const builtin_remote_setbranches_usage[] = {
- "git remote set-branches <name> <branch>...",
- "git remote set-branches --add <name> <branch>...",
+ N_("git remote set-branches <name> <branch>..."),
+ N_("git remote set-branches --add <name> <branch>..."),
NULL
};
static const char * const builtin_remote_show_usage[] = {
- "git remote show [<options>] <name>",
+ N_("git remote show [<options>] <name>"),
NULL
};
static const char * const builtin_remote_prune_usage[] = {
- "git remote prune [<options>] <name>",
+ N_("git remote prune [<options>] <name>"),
NULL
};
static const char * const builtin_remote_update_usage[] = {
- "git remote update [<options>] [<group> | <remote>]...",
+ N_("git remote update [<options>] [<group> | <remote>]..."),
NULL
};
static const char * const builtin_remote_seturl_usage[] = {
- "git remote set-url [--push] <name> <newurl> [<oldurl>]",
- "git remote set-url --add <name> <newurl>",
- "git remote set-url --delete <name> <url>",
+ N_("git remote set-url [--push] <name> <newurl> [<oldurl>]"),
+ N_("git remote set-url --add <name> <newurl>"),
+ N_("git remote set-url --delete <name> <url>"),
NULL
};
@@ -160,17 +160,17 @@ static int add(int argc, const char **argv)
int i;
struct option options[] = {
- OPT_BOOLEAN('f', "fetch", &fetch, "fetch the remote branches"),
+ OPT_BOOLEAN('f', "fetch", &fetch, N_("fetch the remote branches")),
OPT_SET_INT(0, "tags", &fetch_tags,
- "import all tags and associated objects when fetching",
+ N_("import all tags and associated objects when fetching"),
TAGS_SET),
OPT_SET_INT(0, NULL, &fetch_tags,
- "or do not fetch any tag at all (--no-tags)", TAGS_UNSET),
- OPT_STRING_LIST('t', "track", &track, "branch",
- "branch(es) to track"),
- OPT_STRING('m', "master", &master, "branch", "master branch"),
- { OPTION_CALLBACK, 0, "mirror", &mirror, "push|fetch",
- "set up remote as a mirror to push to or fetch from",
+ N_("or do not fetch any tag at all (--no-tags)"), TAGS_UNSET),
+ OPT_STRING_LIST('t', "track", &track, N_("branch"),
+ N_("branch(es) to track")),
+ OPT_STRING('m', "master", &master, N_("branch"), N_("master branch")),
+ { OPTION_CALLBACK, 0, "mirror", &mirror, N_("push|fetch"),
+ N_("set up remote as a mirror to push to or fetch from"),
PARSE_OPT_OPTARG, parse_mirror_opt },
OPT_END()
};
@@ -1088,7 +1088,7 @@ static int show(int argc, const char **argv)
{
int no_query = 0, result = 0, query_flag = 0;
struct option options[] = {
- OPT_BOOLEAN('n', NULL, &no_query, "do not query remotes"),
+ OPT_BOOLEAN('n', NULL, &no_query, N_("do not query remotes")),
OPT_END()
};
struct ref_states states;
@@ -1196,9 +1196,9 @@ static int set_head(int argc, const char **argv)
struct option options[] = {
OPT_BOOLEAN('a', "auto", &opt_a,
- "set refs/remotes/<name>/HEAD according to remote"),
+ N_("set refs/remotes/<name>/HEAD according to remote")),
OPT_BOOLEAN('d', "delete", &opt_d,
- "delete refs/remotes/<name>/HEAD"),
+ N_("delete refs/remotes/<name>/HEAD")),
OPT_END()
};
argc = parse_options(argc, argv, NULL, options, builtin_remote_sethead_usage,
@@ -1250,7 +1250,7 @@ static int prune(int argc, const char **argv)
{
int dry_run = 0, result = 0;
struct option options[] = {
- OPT__DRY_RUN(&dry_run, "dry run"),
+ OPT__DRY_RUN(&dry_run, N_("dry run")),
OPT_END()
};
@@ -1318,7 +1318,7 @@ static int update(int argc, const char **argv)
int i, prune = 0;
struct option options[] = {
OPT_BOOLEAN('p', "prune", &prune,
- "prune remotes after fetching"),
+ N_("prune remotes after fetching")),
OPT_END()
};
const char **fetch_argv;
@@ -1404,7 +1404,7 @@ static int set_branches(int argc, const char **argv)
{
int add_mode = 0;
struct option options[] = {
- OPT_BOOLEAN('\0', "add", &add_mode, "add branch"),
+ OPT_BOOLEAN('\0', "add", &add_mode, N_("add branch")),
OPT_END()
};
@@ -1433,11 +1433,11 @@ static int set_url(int argc, const char **argv)
struct strbuf name_buf = STRBUF_INIT;
struct option options[] = {
OPT_BOOLEAN('\0', "push", &push_mode,
- "manipulate push URLs"),
+ N_("manipulate push URLs")),
OPT_BOOLEAN('\0', "add", &add_mode,
- "add URL"),
+ N_("add URL")),
OPT_BOOLEAN('\0', "delete", &delete_mode,
- "delete URLs"),
+ N_("delete URLs")),
OPT_END()
};
argc = parse_options(argc, argv, NULL, options, builtin_remote_seturl_usage,
@@ -1566,7 +1566,7 @@ static int show_all(void)
int cmd_remote(int argc, const char **argv, const char *prefix)
{
struct option options[] = {
- OPT__VERBOSE(&verbose, "be verbose; must be placed before a subcommand"),
+ OPT__VERBOSE(&verbose, N_("be verbose; must be placed before a subcommand")),
OPT_END()
};
int result;
diff --git a/builtin/replace.c b/builtin/replace.c
index 4a8970e..e3aaf70 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -14,9 +14,9 @@
#include "parse-options.h"
static const char * const git_replace_usage[] = {
- "git replace [-f] <object> <replacement>",
- "git replace -d <object>...",
- "git replace -l [<pattern>]",
+ N_("git replace [-f] <object> <replacement>"),
+ N_("git replace -d <object>..."),
+ N_("git replace -l [<pattern>]"),
NULL
};
@@ -115,9 +115,9 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
{
int list = 0, delete = 0, force = 0;
struct option options[] = {
- OPT_BOOLEAN('l', NULL, &list, "list replace refs"),
- OPT_BOOLEAN('d', NULL, &delete, "delete replace refs"),
- OPT_BOOLEAN('f', NULL, &force, "replace the ref if it exists"),
+ OPT_BOOLEAN('l', NULL, &list, N_("list replace refs")),
+ OPT_BOOLEAN('d', NULL, &delete, N_("delete replace refs")),
+ OPT_BOOLEAN('f', NULL, &force, N_("replace the ref if it exists")),
OPT_END()
};
diff --git a/builtin/rerere.c b/builtin/rerere.c
index 08213c7..dc1708e 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -8,7 +8,7 @@
#include "xdiff-interface.h"
static const char * const rerere_usage[] = {
- "git rerere [clear | forget path... | status | remaining | diff | gc]",
+ N_("git rerere [clear | forget path... | status | remaining | diff | gc]"),
NULL,
};
@@ -53,7 +53,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
struct option options[] = {
OPT_SET_INT(0, "rerere-autoupdate", &autoupdate,
- "register clean resolutions in index", 1),
+ N_("register clean resolutions in index"), 1),
OPT_END(),
};
diff --git a/builtin/reset.c b/builtin/reset.c
index 74442bd..915cc9f 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -22,9 +22,9 @@
#include "cache-tree.h"
static const char * const git_reset_usage[] = {
- "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]",
- "git reset [-q] <commit> [--] <paths>...",
- "git reset --patch [<commit>] [--] [<paths>...]",
+ N_("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"),
+ N_("git reset [-q] <commit> [--] <paths>..."),
+ N_("git reset --patch [<commit>] [--] [<paths>...]"),
NULL
};
@@ -235,17 +235,17 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
struct commit *commit;
struct strbuf msg = STRBUF_INIT;
const struct option options[] = {
- OPT__QUIET(&quiet, "be quiet, only report errors"),
+ OPT__QUIET(&quiet, N_("be quiet, only report errors")),
OPT_SET_INT(0, "mixed", &reset_type,
- "reset HEAD and index", MIXED),
- OPT_SET_INT(0, "soft", &reset_type, "reset only HEAD", SOFT),
+ N_("reset HEAD and index"), MIXED),
+ OPT_SET_INT(0, "soft", &reset_type, N_("reset only HEAD"), SOFT),
OPT_SET_INT(0, "hard", &reset_type,
- "reset HEAD, index and working tree", HARD),
+ N_("reset HEAD, index and working tree"), HARD),
OPT_SET_INT(0, "merge", &reset_type,
- "reset HEAD, index and working tree", MERGE),
+ N_("reset HEAD, index and working tree"), MERGE),
OPT_SET_INT(0, "keep", &reset_type,
- "reset HEAD but keep local changes", KEEP),
- OPT_BOOLEAN('p', "patch", &patch_mode, "select hunks interactively"),
+ N_("reset HEAD but keep local changes"), KEEP),
+ OPT_BOOLEAN('p', "patch", &patch_mode, N_("select hunks interactively")),
OPT_END()
};
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 25e225f..f267a1d 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -336,15 +336,15 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
{
static int keep_dashdash = 0, stop_at_non_option = 0;
static char const * const parseopt_usage[] = {
- "git rev-parse --parseopt [options] -- [<args>...]",
+ N_("git rev-parse --parseopt [options] -- [<args>...]"),
NULL
};
static struct option parseopt_opts[] = {
OPT_BOOLEAN(0, "keep-dashdash", &keep_dashdash,
- "keep the `--` passed as an arg"),
+ N_("keep the `--` passed as an arg")),
OPT_BOOLEAN(0, "stop-at-non-option", &stop_at_non_option,
- "stop parsing after the "
- "first non-option argument"),
+ N_("stop parsing after the "
+ "first non-option argument")),
OPT_END(),
};
@@ -461,11 +461,11 @@ static void die_no_single_rev(int quiet)
}
static const char builtin_rev_parse_usage[] =
-"git rev-parse --parseopt [options] -- [<args>...]\n"
-" or: git rev-parse --sq-quote [<arg>...]\n"
-" or: git rev-parse [options] [<arg>...]\n"
-"\n"
-"Run \"git rev-parse --parseopt -h\" for more information on the first usage.";
+N_("git rev-parse --parseopt [options] -- [<args>...]\n"
+ " or: git rev-parse --sq-quote [<arg>...]\n"
+ " or: git rev-parse [options] [<arg>...]\n"
+ "\n"
+ "Run \"git rev-parse --parseopt -h\" for more information on the first usage.");
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{
diff --git a/builtin/revert.c b/builtin/revert.c
index 98ad641..c5e36b9 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -19,14 +19,14 @@
*/
static const char * const revert_usage[] = {
- "git revert [options] <commit-ish>",
- "git revert <subcommand>",
+ N_("git revert [options] <commit-ish>"),
+ N_("git revert <subcommand>"),
NULL
};
static const char * const cherry_pick_usage[] = {
- "git cherry-pick [options] <commit-ish>",
- "git cherry-pick <subcommand>",
+ N_("git cherry-pick [options] <commit-ish>"),
+ N_("git cherry-pick <subcommand>"),
NULL
};
@@ -100,18 +100,19 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
int contin = 0;
int rollback = 0;
struct option options[] = {
- OPT_BOOLEAN(0, "quit", &remove_state, "end revert or cherry-pick sequence"),
- OPT_BOOLEAN(0, "continue", &contin, "resume revert or cherry-pick sequence"),
- OPT_BOOLEAN(0, "abort", &rollback, "cancel revert or cherry-pick sequence"),
- OPT_BOOLEAN('n', "no-commit", &opts->no_commit, "don't automatically commit"),
- OPT_BOOLEAN('e', "edit", &opts->edit, "edit the commit message"),
+ OPT_BOOLEAN(0, "quit", &remove_state, N_("end revert or cherry-pick sequence")),
+ OPT_BOOLEAN(0, "continue", &contin, N_("resume revert or cherry-pick sequence")),
+ OPT_BOOLEAN(0, "abort", &rollback, N_("cancel revert or cherry-pick sequence")),
+ OPT_BOOLEAN('n', "no-commit", &opts->no_commit, N_("don't automatically commit")),
+ OPT_BOOLEAN('e', "edit", &opts->edit, N_("edit the commit message")),
OPT_NOOP_NOARG('r', NULL),
- OPT_BOOLEAN('s', "signoff", &opts->signoff, "add Signed-off-by:"),
- OPT_INTEGER('m', "mainline", &opts->mainline, "parent number"),
+ OPT_BOOLEAN('s', "signoff", &opts->signoff, N_("add Signed-off-by:")),
+ OPT_INTEGER('m', "mainline", &opts->mainline, N_("parent number")),
OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto),
- OPT_STRING(0, "strategy", &opts->strategy, "strategy", "merge strategy"),
- OPT_CALLBACK('X', "strategy-option", &opts, "option",
- "option for merge strategy", option_parse_x),
+ OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")),
+ OPT_CALLBACK('X', "strategy-option", &opts, N_("option"),
+ N_("option for merge strategy"), option_parse_x),
+ OPT_END(),
OPT_END(),
OPT_END(),
OPT_END(),
@@ -121,10 +122,11 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
if (opts->action == REPLAY_PICK) {
struct option cp_extra[] = {
- OPT_BOOLEAN('x', NULL, &opts->record_origin, "append commit name"),
- OPT_BOOLEAN(0, "ff", &opts->allow_ff, "allow fast-forward"),
- OPT_BOOLEAN(0, "allow-empty", &opts->allow_empty, "preserve initially empty commits"),
- OPT_BOOLEAN(0, "keep-redundant-commits", &opts->keep_redundant_commits, "keep redundant, empty commits"),
+ OPT_BOOLEAN('x', NULL, &opts->record_origin, N_("append commit name")),
+ OPT_BOOLEAN(0, "ff", &opts->allow_ff, N_("allow fast-forward")),
+ OPT_BOOLEAN(0, "allow-empty", &opts->allow_empty, N_("preserve initially empty commits")),
+ OPT_BOOLEAN(0, "allow-empty-message", &opts->allow_empty_message, N_("allow commits with empty messages")),
+ OPT_BOOLEAN(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")),
OPT_END(),
};
if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))
diff --git a/builtin/rm.c b/builtin/rm.c
index 90c8a50..b384c4c 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -11,7 +11,7 @@
#include "parse-options.h"
static const char * const builtin_rm_usage[] = {
- "git rm [options] [--] <file>...",
+ N_("git rm [options] [--] <file>..."),
NULL
};
@@ -130,13 +130,13 @@ static int show_only = 0, force = 0, index_only = 0, recursive = 0, quiet = 0;
static int ignore_unmatch = 0;
static struct option builtin_rm_options[] = {
- OPT__DRY_RUN(&show_only, "dry run"),
- OPT__QUIET(&quiet, "do not list removed files"),
- OPT_BOOLEAN( 0 , "cached", &index_only, "only remove from the index"),
- OPT__FORCE(&force, "override the up-to-date check"),
- OPT_BOOLEAN('r', NULL, &recursive, "allow recursive removal"),
+ OPT__DRY_RUN(&show_only, N_("dry run")),
+ OPT__QUIET(&quiet, N_("do not list removed files")),
+ OPT_BOOLEAN( 0 , "cached", &index_only, N_("only remove from the index")),
+ OPT__FORCE(&force, N_("override the up-to-date check")),
+ OPT_BOOLEAN('r', NULL, &recursive, N_("allow recursive removal")),
OPT_BOOLEAN( 0 , "ignore-unmatch", &ignore_unmatch,
- "exit with a zero status even if nothing matched"),
+ N_("exit with a zero status even if nothing matched")),
OPT_END(),
};
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 37f3193..b316cf3 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -10,9 +10,9 @@
#include "parse-options.h"
static char const * const shortlog_usage[] = {
- "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]",
+ N_("git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]"),
"",
- "[rev-opts] are documented in git-rev-list(1)",
+ N_("[rev-opts] are documented in git-rev-list(1)"),
NULL
};
@@ -250,13 +250,13 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
static const struct option options[] = {
OPT_BOOLEAN('n', "numbered", &log.sort_by_number,
- "sort output according to the number of commits per author"),
+ N_("sort output according to the number of commits per author")),
OPT_BOOLEAN('s', "summary", &log.summary,
- "Suppress commit descriptions, only provides commit count"),
+ N_("Suppress commit descriptions, only provides commit count")),
OPT_BOOLEAN('e', "email", &log.email,
- "Show the email address of each author"),
- { OPTION_CALLBACK, 'w', NULL, &log, "w[,i1[,i2]]",
- "Linewrap output", PARSE_OPT_OPTARG, &parse_wrap_args },
+ N_("Show the email address of each author")),
+ { OPTION_CALLBACK, 'w', NULL, &log, N_("w[,i1[,i2]]"),
+ N_("Linewrap output"), PARSE_OPT_OPTARG, &parse_wrap_args },
OPT_END(),
};
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index a59e088..d208fd6 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -6,8 +6,8 @@
#include "parse-options.h"
static const char* show_branch_usage[] = {
- "git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--current] [--color[=<when>] | --no-color] [--sparse] [--more=<n> | --list | --independent | --merge-base] [--no-name | --sha1-name] [--topics] [(<rev> | <glob>)...]",
- "git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]",
+ N_("git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--current] [--color[=<when>] | --no-color] [--sparse] [--more=<n> | --list | --independent | --merge-base] [--no-name | --sha1-name] [--topics] [(<rev> | <glob>)...]"),
+ N_("git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]"),
NULL
};
@@ -648,36 +648,36 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
const char *reflog_base = NULL;
struct option builtin_show_branch_options[] = {
OPT_BOOLEAN('a', "all", &all_heads,
- "show remote-tracking and local branches"),
+ N_("show remote-tracking and local branches")),
OPT_BOOLEAN('r', "remotes", &all_remotes,
- "show remote-tracking branches"),
+ N_("show remote-tracking branches")),
OPT__COLOR(&showbranch_use_color,
- "color '*!+-' corresponding to the branch"),
- { OPTION_INTEGER, 0, "more", &extra, "n",
- "show <n> more commits after the common ancestor",
+ N_("color '*!+-' corresponding to the branch")),
+ { OPTION_INTEGER, 0, "more", &extra, N_("n"),
+ N_("show <n> more commits after the common ancestor"),
PARSE_OPT_OPTARG, NULL, (intptr_t)1 },
- OPT_SET_INT(0, "list", &extra, "synonym to more=-1", -1),
- OPT_BOOLEAN(0, "no-name", &no_name, "suppress naming strings"),
+ OPT_SET_INT(0, "list", &extra, N_("synonym to more=-1"), -1),
+ OPT_BOOLEAN(0, "no-name", &no_name, N_("suppress naming strings")),
OPT_BOOLEAN(0, "current", &with_current_branch,
- "include the current branch"),
+ N_("include the current branch")),
OPT_BOOLEAN(0, "sha1-name", &sha1_name,
- "name commits with their object names"),
+ N_("name commits with their object names")),
OPT_BOOLEAN(0, "merge-base", &merge_base,
- "show possible merge bases"),
+ N_("show possible merge bases")),
OPT_BOOLEAN(0, "independent", &independent,
- "show refs unreachable from any other ref"),
+ N_("show refs unreachable from any other ref")),
OPT_BOOLEAN(0, "topo-order", &lifo,
- "show commits in topological order"),
+ N_("show commits in topological order")),
OPT_BOOLEAN(0, "topics", &topics,
- "show only commits not on the first branch"),
+ N_("show only commits not on the first branch")),
OPT_SET_INT(0, "sparse", &dense,
- "show merges reachable from only one tip", 0),
+ N_("show merges reachable from only one tip"), 0),
OPT_SET_INT(0, "date-order", &lifo,
- "show commits where no parent comes before its "
- "children", 0),
- { OPTION_CALLBACK, 'g', "reflog", &reflog_base, "<n>[,<base>]",
- "show <n> most recent ref-log entries starting at "
- "base",
+ N_("show commits where no parent comes before its "
+ "children"), 0),
+ { OPTION_CALLBACK, 'g', "reflog", &reflog_base, N_("<n>[,<base>]"),
+ N_("show <n> most recent ref-log entries starting at "
+ "base"),
PARSE_OPT_OPTARG | PARSE_OPT_LITERAL_ARGHELP,
parse_reflog_param },
OPT_END()
diff --git a/builtin/show-ref.c b/builtin/show-ref.c
index 3911661..4eb016d 100644
--- a/builtin/show-ref.c
+++ b/builtin/show-ref.c
@@ -7,8 +7,8 @@
#include "parse-options.h"
static const char * const show_ref_usage[] = {
- "git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [pattern*] ",
- "git show-ref --exclude-existing[=pattern] < ref-list",
+ N_("git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [pattern*] "),
+ N_("git show-ref --exclude-existing[=pattern] < ref-list"),
NULL
};
@@ -179,26 +179,26 @@ static int help_callback(const struct option *opt, const char *arg, int unset)
}
static const struct option show_ref_options[] = {
- OPT_BOOLEAN(0, "tags", &tags_only, "only show tags (can be combined with heads)"),
- OPT_BOOLEAN(0, "heads", &heads_only, "only show heads (can be combined with tags)"),
- OPT_BOOLEAN(0, "verify", &verify, "stricter reference checking, "
- "requires exact ref path"),
+ OPT_BOOLEAN(0, "tags", &tags_only, N_("only show tags (can be combined with heads)")),
+ OPT_BOOLEAN(0, "heads", &heads_only, N_("only show heads (can be combined with tags)")),
+ OPT_BOOLEAN(0, "verify", &verify, N_("stricter reference checking, "
+ "requires exact ref path")),
{ OPTION_BOOLEAN, 'h', NULL, &show_head, NULL,
- "show the HEAD reference",
+ N_("show the HEAD reference"),
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
- OPT_BOOLEAN(0, "head", &show_head, "show the HEAD reference"),
+ OPT_BOOLEAN(0, "head", &show_head, N_("show the HEAD reference")),
OPT_BOOLEAN('d', "dereference", &deref_tags,
- "dereference tags into object IDs"),
- { OPTION_CALLBACK, 's', "hash", &abbrev, "n",
- "only show SHA1 hash using <n> digits",
+ N_("dereference tags into object IDs")),
+ { OPTION_CALLBACK, 's', "hash", &abbrev, N_("n"),
+ N_("only show SHA1 hash using <n> digits"),
PARSE_OPT_OPTARG, &hash_callback },
OPT__ABBREV(&abbrev),
OPT__QUIET(&quiet,
- "do not print results to stdout (useful with --verify)"),
+ N_("do not print results to stdout (useful with --verify)")),
{ OPTION_CALLBACK, 0, "exclude-existing", &exclude_existing_arg,
- "pattern", "show refs from stdin that aren't in local repository",
+ N_("pattern"), N_("show refs from stdin that aren't in local repository"),
PARSE_OPT_OPTARG | PARSE_OPT_NONEG, exclude_existing_callback },
- { OPTION_CALLBACK, 0, "help-all", NULL, NULL, "show usage",
+ { OPTION_CALLBACK, 0, "help-all", NULL, NULL, N_("show usage"),
PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback },
OPT_END()
};
diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c
index 801d62e..9e92828 100644
--- a/builtin/symbolic-ref.c
+++ b/builtin/symbolic-ref.c
@@ -4,7 +4,7 @@
#include "parse-options.h"
static const char * const git_symbolic_ref_usage[] = {
- "git symbolic-ref [options] name [ref]",
+ N_("git symbolic-ref [options] name [ref]"),
NULL
};
@@ -35,9 +35,9 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)
const char *msg = NULL;
struct option options[] = {
OPT__QUIET(&quiet,
- "suppress error message for non-symbolic (detached) refs"),
- OPT_BOOL(0, "short", &shorten, "shorten ref output"),
- OPT_STRING('m', NULL, &msg, "reason", "reason of the update"),
+ N_("suppress error message for non-symbolic (detached) refs")),
+ OPT_BOOL(0, "short", &shorten, N_("shorten ref output")),
+ OPT_STRING('m', NULL, &msg, N_("reason"), N_("reason of the update")),
OPT_END(),
};
diff --git a/builtin/tag.c b/builtin/tag.c
index 7b1be85..9c3e067 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -19,11 +19,11 @@
#include "column.h"
static const char * const git_tag_usage[] = {
- "git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
- "git tag -d <tagname>...",
- "git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>] "
- "\n\t\t[<pattern>...]",
- "git tag -v <tagname>...",
+ N_("git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]"),
+ N_("git tag -d <tagname>..."),
+ N_("git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>] "
+ "\n\t\t[<pattern>...]"),
+ N_("git tag -v <tagname>..."),
NULL
};
@@ -444,37 +444,37 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
struct msg_arg msg = { 0, STRBUF_INIT };
struct commit_list *with_commit = NULL;
struct option options[] = {
- OPT_BOOLEAN('l', "list", &list, "list tag names"),
- { OPTION_INTEGER, 'n', NULL, &lines, "n",
- "print <n> lines of each tag message",
+ OPT_BOOLEAN('l', "list", &list, N_("list tag names")),
+ { OPTION_INTEGER, 'n', NULL, &lines, N_("n"),
+ N_("print <n> lines of each tag message"),
PARSE_OPT_OPTARG, NULL, 1 },
- OPT_BOOLEAN('d', "delete", &delete, "delete tags"),
- OPT_BOOLEAN('v', "verify", &verify, "verify tags"),
+ OPT_BOOLEAN('d', "delete", &delete, N_("delete tags")),
+ OPT_BOOLEAN('v', "verify", &verify, N_("verify tags")),
- OPT_GROUP("Tag creation options"),
+ OPT_GROUP(N_("Tag creation options")),
OPT_BOOLEAN('a', "annotate", &annotate,
- "annotated tag, needs a message"),
- OPT_CALLBACK('m', "message", &msg, "message",
- "tag message", parse_msg_arg),
- OPT_FILENAME('F', "file", &msgfile, "read message from file"),
- OPT_BOOLEAN('s', "sign", &opt.sign, "annotated and GPG-signed tag"),
- OPT_STRING(0, "cleanup", &cleanup_arg, "mode",
- "how to strip spaces and #comments from message"),
- OPT_STRING('u', "local-user", &keyid, "key-id",
- "use another key to sign the tag"),
- OPT__FORCE(&force, "replace the tag if exists"),
- OPT_COLUMN(0, "column", &colopts, "show tag list in columns"),
-
- OPT_GROUP("Tag listing options"),
+ N_("annotated tag, needs a message")),
+ OPT_CALLBACK('m', "message", &msg, N_("message"),
+ N_("tag message"), parse_msg_arg),
+ OPT_FILENAME('F', "file", &msgfile, N_("read message from file")),
+ OPT_BOOLEAN('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")),
+ OPT_STRING(0, "cleanup", &cleanup_arg, N_("mode"),
+ N_("how to strip spaces and #comments from message")),
+ OPT_STRING('u', "local-user", &keyid, N_("key id"),
+ N_("use another key to sign the tag")),
+ OPT__FORCE(&force, N_("replace the tag if exists")),
+ OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),
+
+ OPT_GROUP(N_("Tag listing options")),
{
- OPTION_CALLBACK, 0, "contains", &with_commit, "commit",
- "print only tags that contain the commit",
+ OPTION_CALLBACK, 0, "contains", &with_commit, N_("commit"),
+ N_("print only tags that contain the commit"),
PARSE_OPT_LASTARG_DEFAULT,
parse_opt_with_commit, (intptr_t)"HEAD",
},
{
- OPTION_CALLBACK, 0, "points-at", NULL, "object",
- "print only tags of the object", 0, parse_opt_points_at
+ OPTION_CALLBACK, 0, "points-at", NULL, N_("object"),
+ N_("print only tags of the object"), 0, parse_opt_points_at
},
OPT_END()
};
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 4ce341c..74986bf 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -398,7 +398,7 @@ static void read_index_info(int line_termination)
}
static const char * const update_index_usage[] = {
- "git update-index [options] [--] [<file>...]",
+ N_("git update-index [options] [--] [<file>...]"),
NULL
};
@@ -714,83 +714,83 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
int parseopt_state = PARSE_OPT_UNKNOWN;
struct option options[] = {
OPT_BIT('q', NULL, &refresh_args.flags,
- "continue refresh even when index needs update",
+ N_("continue refresh even when index needs update"),
REFRESH_QUIET),
OPT_BIT(0, "ignore-submodules", &refresh_args.flags,
- "refresh: ignore submodules",
+ N_("refresh: ignore submodules"),
REFRESH_IGNORE_SUBMODULES),
OPT_SET_INT(0, "add", &allow_add,
- "do not ignore new files", 1),
+ N_("do not ignore new files"), 1),
OPT_SET_INT(0, "replace", &allow_replace,
- "let files replace directories and vice-versa", 1),
+ N_("let files replace directories and vice-versa"), 1),
OPT_SET_INT(0, "remove", &allow_remove,
- "notice files missing from worktree", 1),
+ N_("notice files missing from worktree"), 1),
OPT_BIT(0, "unmerged", &refresh_args.flags,
- "refresh even if index contains unmerged entries",
+ N_("refresh even if index contains unmerged entries"),
REFRESH_UNMERGED),
{OPTION_CALLBACK, 0, "refresh", &refresh_args, NULL,
- "refresh stat information",
+ N_("refresh stat information"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG,
refresh_callback},
{OPTION_CALLBACK, 0, "really-refresh", &refresh_args, NULL,
- "like --refresh, but ignore assume-unchanged setting",
+ N_("like --refresh, but ignore assume-unchanged setting"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG,
really_refresh_callback},
{OPTION_LOWLEVEL_CALLBACK, 0, "cacheinfo", NULL,
- "<mode> <object> <path>",
- "add the specified entry to the index",
+ N_("<mode> <object> <path>"),
+ N_("add the specified entry to the index"),
PARSE_OPT_NOARG | /* disallow --cacheinfo=<mode> form */
PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
(parse_opt_cb *) cacheinfo_callback},
- {OPTION_CALLBACK, 0, "chmod", &set_executable_bit, "(+/-)x",
- "override the executable bit of the listed files",
+ {OPTION_CALLBACK, 0, "chmod", &set_executable_bit, N_("(+/-)x"),
+ N_("override the executable bit of the listed files"),
PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
chmod_callback},
{OPTION_SET_INT, 0, "assume-unchanged", &mark_valid_only, NULL,
- "mark files as \"not changing\"",
+ N_("mark files as \"not changing\""),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, MARK_FLAG},
{OPTION_SET_INT, 0, "no-assume-unchanged", &mark_valid_only, NULL,
- "clear assumed-unchanged bit",
+ N_("clear assumed-unchanged bit"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, UNMARK_FLAG},
{OPTION_SET_INT, 0, "skip-worktree", &mark_skip_worktree_only, NULL,
- "mark files as \"index-only\"",
+ N_("mark files as \"index-only\""),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, MARK_FLAG},
{OPTION_SET_INT, 0, "no-skip-worktree", &mark_skip_worktree_only, NULL,
- "clear skip-worktree bit",
+ N_("clear skip-worktree bit"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, UNMARK_FLAG},
OPT_SET_INT(0, "info-only", &info_only,
- "add to index only; do not add content to object database", 1),
+ N_("add to index only; do not add content to object database"), 1),
OPT_SET_INT(0, "force-remove", &force_remove,
- "remove named paths even if present in worktree", 1),
+ N_("remove named paths even if present in worktree"), 1),
OPT_SET_INT('z', NULL, &line_termination,
- "with --stdin: input lines are terminated by null bytes", '\0'),
+ N_("with --stdin: input lines are terminated by null bytes"), '\0'),
{OPTION_LOWLEVEL_CALLBACK, 0, "stdin", &read_from_stdin, NULL,
- "read list of paths to be updated from standard input",
+ N_("read list of paths to be updated from standard input"),
PARSE_OPT_NONEG | PARSE_OPT_NOARG,
(parse_opt_cb *) stdin_callback},
{OPTION_LOWLEVEL_CALLBACK, 0, "index-info", &line_termination, NULL,
- "add entries from standard input to the index",
+ N_("add entries from standard input to the index"),
PARSE_OPT_NONEG | PARSE_OPT_NOARG,
(parse_opt_cb *) stdin_cacheinfo_callback},
{OPTION_LOWLEVEL_CALLBACK, 0, "unresolve", &has_errors, NULL,
- "repopulate stages #2 and #3 for the listed paths",
+ N_("repopulate stages #2 and #3 for the listed paths"),
PARSE_OPT_NONEG | PARSE_OPT_NOARG,
(parse_opt_cb *) unresolve_callback},
{OPTION_LOWLEVEL_CALLBACK, 'g', "again", &has_errors, NULL,
- "only update entries that differ from HEAD",
+ N_("only update entries that differ from HEAD"),
PARSE_OPT_NONEG | PARSE_OPT_NOARG,
(parse_opt_cb *) reupdate_callback},
OPT_BIT(0, "ignore-missing", &refresh_args.flags,
- "ignore files missing from worktree",
+ N_("ignore files missing from worktree"),
REFRESH_IGNORE_MISSING),
OPT_SET_INT(0, "verbose", &verbose,
- "report actions to standard output", 1),
+ N_("report actions to standard output"), 1),
{OPTION_CALLBACK, 0, "clear-resolve-undo", NULL, NULL,
- "(for porcelains) forget saved unresolved conflicts",
+ N_("(for porcelains) forget saved unresolved conflicts"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG,
resolve_undo_clear_callback},
OPT_INTEGER(0, "index-version", &preferred_index_format,
- "write index in this format"),
+ N_("write index in this format")),
OPT_END()
};
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 835c62a..51d2684 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -4,8 +4,8 @@
#include "parse-options.h"
static const char * const git_update_ref_usage[] = {
- "git update-ref [options] -d <refname> [<oldval>]",
- "git update-ref [options] <refname> <newval> [<oldval>]",
+ N_("git update-ref [options] -d <refname> [<oldval>]"),
+ N_("git update-ref [options] <refname> <newval> [<oldval>]"),
NULL
};
@@ -15,10 +15,10 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
unsigned char sha1[20], oldsha1[20];
int delete = 0, no_deref = 0, flags = 0;
struct option options[] = {
- OPT_STRING( 'm', NULL, &msg, "reason", "reason of the update"),
- OPT_BOOLEAN('d', NULL, &delete, "deletes the reference"),
+ OPT_STRING( 'm', NULL, &msg, N_("reason"), N_("reason of the update")),
+ OPT_BOOLEAN('d', NULL, &delete, N_("delete the reference")),
OPT_BOOLEAN( 0 , "no-deref", &no_deref,
- "update <refname> not the one it points to"),
+ N_("update <refname> not the one it points to")),
OPT_END(),
};
diff --git a/builtin/update-server-info.c b/builtin/update-server-info.c
index 0d63c44..6c8cc3e 100644
--- a/builtin/update-server-info.c
+++ b/builtin/update-server-info.c
@@ -3,7 +3,7 @@
#include "parse-options.h"
static const char * const update_server_info_usage[] = {
- "git update-server-info [--force]",
+ N_("git update-server-info [--force]"),
NULL
};
@@ -11,7 +11,7 @@ int cmd_update_server_info(int argc, const char **argv, const char *prefix)
{
int force = 0;
struct option options[] = {
- OPT__FORCE(&force, "update the info files from scratch"),
+ OPT__FORCE(&force, N_("update the info files from scratch")),
OPT_END()
};
diff --git a/builtin/verify-pack.c b/builtin/verify-pack.c
index e841b4a..66cd2df 100644
--- a/builtin/verify-pack.c
+++ b/builtin/verify-pack.c
@@ -53,7 +53,7 @@ static int verify_one_pack(const char *path, unsigned int flags)
}
static const char * const verify_pack_usage[] = {
- "git verify-pack [-v|--verbose] [-s|--stat-only] <pack>...",
+ N_("git verify-pack [-v|--verbose] [-s|--stat-only] <pack>..."),
NULL
};
@@ -63,9 +63,9 @@ int cmd_verify_pack(int argc, const char **argv, const char *prefix)
unsigned int flags = 0;
int i;
const struct option verify_pack_options[] = {
- OPT_BIT('v', "verbose", &flags, "verbose",
+ OPT_BIT('v', "verbose", &flags, N_("verbose"),
VERIFY_PACK_VERBOSE),
- OPT_BIT('s', "stat-only", &flags, "show statistics only",
+ OPT_BIT('s', "stat-only", &flags, N_("show statistics only"),
VERIFY_PACK_STAT_ONLY),
OPT_END()
};
diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c
index 986789f..a8eee88 100644
--- a/builtin/verify-tag.c
+++ b/builtin/verify-tag.c
@@ -14,7 +14,7 @@
#include "gpg-interface.h"
static const char * const verify_tag_usage[] = {
- "git verify-tag [-v|--verbose] <tag>...",
+ N_("git verify-tag [-v|--verbose] <tag>..."),
NULL
};
@@ -70,7 +70,7 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
{
int i = 1, verbose = 0, had_error = 0;
const struct option verify_tag_options[] = {
- OPT__VERBOSE(&verbose, "print tag contents"),
+ OPT__VERBOSE(&verbose, N_("print tag contents")),
OPT_END()
};
diff --git a/builtin/write-tree.c b/builtin/write-tree.c
index b223af4..084c0df 100644
--- a/builtin/write-tree.c
+++ b/builtin/write-tree.c
@@ -10,7 +10,7 @@
#include "parse-options.h"
static const char * const write_tree_usage[] = {
- "git write-tree [--missing-ok] [--prefix=<prefix>/]",
+ N_("git write-tree [--missing-ok] [--prefix=<prefix>/]"),
NULL
};
@@ -21,13 +21,13 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
unsigned char sha1[20];
const char *me = "git-write-tree";
struct option write_tree_options[] = {
- OPT_BIT(0, "missing-ok", &flags, "allow missing objects",
+ OPT_BIT(0, "missing-ok", &flags, N_("allow missing objects"),
WRITE_TREE_MISSING_OK),
- { OPTION_STRING, 0, "prefix", &prefix, "<prefix>/",
- "write tree object for a subdirectory <prefix>" ,
+ { OPTION_STRING, 0, "prefix", &prefix, N_("<prefix>/"),
+ N_("write tree object for a subdirectory <prefix>") ,
PARSE_OPT_LITERAL_ARGHELP },
{ OPTION_BIT, 0, "ignore-cache-tree", &flags, NULL,
- "only useful for debugging",
+ N_("only useful for debugging"),
PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, NULL,
WRITE_TREE_IGNORE_CACHE_TREE },
OPT_END()
diff --git a/cache.h b/cache.h
index eb4a031..a58df84 100644
--- a/cache.h
+++ b/cache.h
@@ -442,7 +442,6 @@ extern int discard_index(struct index_state *);
extern int unmerged_index(const struct index_state *);
extern int verify_path(const char *path);
extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase);
-extern int index_name_stage_pos(const struct index_state *, const char *name, int namelen, int stage);
extern int index_name_pos(const struct index_state *, const char *name, int namelen);
#define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */
#define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */
@@ -902,9 +901,7 @@ extern const char *git_author_info(int);
extern const char *git_committer_info(int);
extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int);
extern const char *fmt_name(const char *name, const char *email);
-extern const char *ident_default_name(void);
extern const char *ident_default_email(void);
-extern const char *ident_default_date(void);
extern const char *git_editor(void);
extern const char *git_pager(int stdout_is_tty);
extern int git_ident_config(const char *, const char *, void *);
@@ -947,9 +944,7 @@ struct cache_def {
extern int has_symlink_leading_path(const char *name, int len);
extern int threaded_has_symlink_leading_path(struct cache_def *, const char *, int);
extern int check_leading_path(const char *name, int len);
-extern int threaded_check_leading_path(struct cache_def *cache, const char *name, int len);
extern int has_dirs_only_path(const char *name, int len, int prefix_len);
-extern int threaded_has_dirs_only_path(struct cache_def *cache, const char *name, int len, int prefix_len);
extern void schedule_dir_for_removal(const char *name, int len);
extern void remove_scheduled_dirs(void);
@@ -1208,7 +1203,6 @@ extern void alloc_report(void);
/* trace.c */
__attribute__((format (printf, 1, 2)))
extern void trace_printf(const char *format, ...);
-extern void trace_vprintf(const char *key, const char *format, va_list ap);
__attribute__((format (printf, 2, 3)))
extern void trace_argv_printf(const char **argv, const char *format, ...);
extern void trace_repo_setup(const char *prefix);
diff --git a/commit.c b/commit.c
index 42af4c1..213bc98 100644
--- a/commit.c
+++ b/commit.c
@@ -9,6 +9,8 @@
#include "gpg-interface.h"
#include "mergesort.h"
+static struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);
+
int save_commit_buffer = 1;
const char *commit_type = "commit";
@@ -607,30 +609,17 @@ static struct commit *interesting(struct commit_list *list)
return NULL;
}
-static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)
+/* all input commits in one and twos[] must have been parsed! */
+static struct commit_list *paint_down_to_common(struct commit *one, int n, struct commit **twos)
{
struct commit_list *list = NULL;
struct commit_list *result = NULL;
int i;
- for (i = 0; i < n; i++) {
- if (one == twos[i])
- /*
- * We do not mark this even with RESULT so we do not
- * have to clean it up.
- */
- return commit_list_insert(one, &result);
- }
-
- if (parse_commit(one))
- return NULL;
- for (i = 0; i < n; i++) {
- if (parse_commit(twos[i]))
- return NULL;
- }
-
one->object.flags |= PARENT1;
commit_list_insert_by_date(one, &list);
+ if (!n)
+ return list;
for (i = 0; i < n; i++) {
twos[i]->object.flags |= PARENT2;
commit_list_insert_by_date(twos[i], &list);
@@ -669,9 +658,34 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co
}
}
- /* Clean up the result to remove stale ones */
free_commit_list(list);
- list = result; result = NULL;
+ return result;
+}
+
+static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)
+{
+ struct commit_list *list = NULL;
+ struct commit_list *result = NULL;
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (one == twos[i])
+ /*
+ * We do not mark this even with RESULT so we do not
+ * have to clean it up.
+ */
+ return commit_list_insert(one, &result);
+ }
+
+ if (parse_commit(one))
+ return NULL;
+ for (i = 0; i < n; i++) {
+ if (parse_commit(twos[i]))
+ return NULL;
+ }
+
+ list = paint_down_to_common(one, n, twos);
+
while (list) {
struct commit_list *next = list->next;
if (!(list->item->object.flags & STALE))
@@ -709,6 +723,62 @@ struct commit_list *get_octopus_merge_bases(struct commit_list *in)
return ret;
}
+static int remove_redundant(struct commit **array, int cnt)
+{
+ /*
+ * Some commit in the array may be an ancestor of
+ * another commit. Move such commit to the end of
+ * the array, and return the number of commits that
+ * are independent from each other.
+ */
+ struct commit **work;
+ unsigned char *redundant;
+ int *filled_index;
+ int i, j, filled;
+
+ work = xcalloc(cnt, sizeof(*work));
+ redundant = xcalloc(cnt, 1);
+ filled_index = xmalloc(sizeof(*filled_index) * (cnt - 1));
+
+ for (i = 0; i < cnt; i++)
+ parse_commit(array[i]);
+ for (i = 0; i < cnt; i++) {
+ struct commit_list *common;
+
+ if (redundant[i])
+ continue;
+ for (j = filled = 0; j < cnt; j++) {
+ if (i == j || redundant[j])
+ continue;
+ filled_index[filled] = j;
+ work[filled++] = array[j];
+ }
+ common = paint_down_to_common(array[i], filled, work);
+ if (array[i]->object.flags & PARENT2)
+ redundant[i] = 1;
+ for (j = 0; j < filled; j++)
+ if (work[j]->object.flags & PARENT1)
+ redundant[filled_index[j]] = 1;
+ clear_commit_marks(array[i], all_flags);
+ for (j = 0; j < filled; j++)
+ clear_commit_marks(work[j], all_flags);
+ free_commit_list(common);
+ }
+
+ /* Now collect the result */
+ memcpy(work, array, sizeof(*array) * cnt);
+ for (i = filled = 0; i < cnt; i++)
+ if (!redundant[i])
+ array[filled++] = work[i];
+ for (j = filled, i = 0; i < cnt; i++)
+ if (redundant[i])
+ array[j++] = work[i];
+ free(work);
+ free(redundant);
+ free(filled_index);
+ return filled;
+}
+
struct commit_list *get_merge_bases_many(struct commit *one,
int n,
struct commit **twos,
@@ -717,7 +787,7 @@ struct commit_list *get_merge_bases_many(struct commit *one,
struct commit_list *list;
struct commit **rslt;
struct commit_list *result;
- int cnt, i, j;
+ int cnt, i;
result = merge_bases_many(one, n, twos);
for (i = 0; i < n; i++) {
@@ -748,28 +818,11 @@ struct commit_list *get_merge_bases_many(struct commit *one,
clear_commit_marks(one, all_flags);
for (i = 0; i < n; i++)
clear_commit_marks(twos[i], all_flags);
- for (i = 0; i < cnt - 1; i++) {
- for (j = i+1; j < cnt; j++) {
- if (!rslt[i] || !rslt[j])
- continue;
- result = merge_bases_many(rslt[i], 1, &rslt[j]);
- clear_commit_marks(rslt[i], all_flags);
- clear_commit_marks(rslt[j], all_flags);
- for (list = result; list; list = list->next) {
- if (rslt[i] == list->item)
- rslt[i] = NULL;
- if (rslt[j] == list->item)
- rslt[j] = NULL;
- }
- }
- }
- /* Surviving ones in rslt[] are the independent results */
+ cnt = remove_redundant(rslt, cnt);
result = NULL;
- for (i = 0; i < cnt; i++) {
- if (rslt[i])
- commit_list_insert_by_date(rslt[i], &result);
- }
+ for (i = 0; i < cnt; i++)
+ commit_list_insert_by_date(rslt[i], &result);
free(rslt);
return result;
}
@@ -780,6 +833,9 @@ struct commit_list *get_merge_bases(struct commit *one, struct commit *two,
return get_merge_bases_many(one, 1, &two, cleanup);
}
+/*
+ * Is "commit" a decendant of one of the elements on the "with_commit" list?
+ */
int is_descendant_of(struct commit *commit, struct commit_list *with_commit)
{
if (!with_commit)
@@ -789,28 +845,28 @@ int is_descendant_of(struct commit *commit, struct commit_list *with_commit)
other = with_commit->item;
with_commit = with_commit->next;
- if (in_merge_bases(other, &commit, 1))
+ if (in_merge_bases(other, commit))
return 1;
}
return 0;
}
-int in_merge_bases(struct commit *commit, struct commit **reference, int num)
+/*
+ * Is "commit" an ancestor of (i.e. reachable from) the "reference"?
+ */
+int in_merge_bases(struct commit *commit, struct commit *reference)
{
- struct commit_list *bases, *b;
+ struct commit_list *bases;
int ret = 0;
- if (num == 1)
- bases = get_merge_bases(commit, *reference, 1);
- else
- die("not yet");
- for (b = bases; b; b = b->next) {
- if (!hashcmp(commit->object.sha1, b->item->object.sha1)) {
- ret = 1;
- break;
- }
- }
+ if (parse_commit(commit) || parse_commit(reference))
+ return ret;
+ bases = paint_down_to_common(commit, 1, &reference);
+ if (commit->object.flags & PARENT2)
+ ret = 1;
+ clear_commit_marks(commit, all_flags);
+ clear_commit_marks(reference, all_flags);
free_commit_list(bases);
return ret;
}
@@ -819,51 +875,31 @@ struct commit_list *reduce_heads(struct commit_list *heads)
{
struct commit_list *p;
struct commit_list *result = NULL, **tail = &result;
- struct commit **other;
- size_t num_head, num_other;
+ struct commit **array;
+ int num_head, i;
if (!heads)
return NULL;
- /* Avoid unnecessary reallocations */
- for (p = heads, num_head = 0; p; p = p->next)
- num_head++;
- other = xcalloc(sizeof(*other), num_head);
-
- /* For each commit, see if it can be reached by others */
- for (p = heads; p; p = p->next) {
- struct commit_list *q, *base;
-
- /* Do we already have this in the result? */
- for (q = result; q; q = q->next)
- if (p->item == q->item)
- break;
- if (q)
+ /* Uniquify */
+ for (p = heads; p; p = p->next)
+ p->item->object.flags &= ~STALE;
+ for (p = heads, num_head = 0; p; p = p->next) {
+ if (p->item->object.flags & STALE)
continue;
-
- num_other = 0;
- for (q = heads; q; q = q->next) {
- if (p->item == q->item)
- continue;
- other[num_other++] = q->item;
+ p->item->object.flags |= STALE;
+ num_head++;
+ }
+ array = xcalloc(sizeof(*array), num_head);
+ for (p = heads, i = 0; p; p = p->next) {
+ if (p->item->object.flags & STALE) {
+ array[i++] = p->item;
+ p->item->object.flags &= ~STALE;
}
- if (num_other)
- base = get_merge_bases_many(p->item, num_other, other, 1);
- else
- base = NULL;
- /*
- * If p->item does not have anything common with other
- * commits, there won't be any merge base. If it is
- * reachable from some of the others, p->item will be
- * the merge base. If its history is connected with
- * others, but p->item is not reachable by others, we
- * will get something other than p->item back.
- */
- if (!base || (base->item != p->item))
- tail = &(commit_list_insert(p->item, tail)->next);
- free_commit_list(base);
}
- free(other);
+ num_head = remove_redundant(array, num_head);
+ for (i = 0; i < num_head; i++)
+ tail = &commit_list_insert(array[i], tail)->next;
return result;
}
@@ -1044,8 +1080,9 @@ static int excluded_header_field(const char *field, size_t len, const char **exc
return 0;
}
-struct commit_extra_header *read_commit_extra_header_lines(const char *buffer, size_t size,
- const char **exclude)
+static struct commit_extra_header *read_commit_extra_header_lines(
+ const char *buffer, size_t size,
+ const char **exclude)
{
struct commit_extra_header *extra = NULL, **tail = &extra, *it = NULL;
const char *line, *next, *eof, *eob;
@@ -1112,8 +1149,92 @@ int commit_tree(const struct strbuf *msg, unsigned char *tree,
return result;
}
+static int find_invalid_utf8(const char *buf, int len)
+{
+ int offset = 0;
+
+ while (len) {
+ unsigned char c = *buf++;
+ int bytes, bad_offset;
+
+ len--;
+ offset++;
+
+ /* Simple US-ASCII? No worries. */
+ if (c < 0x80)
+ continue;
+
+ bad_offset = offset-1;
+
+ /*
+ * Count how many more high bits set: that's how
+ * many more bytes this sequence should have.
+ */
+ bytes = 0;
+ while (c & 0x40) {
+ c <<= 1;
+ bytes++;
+ }
+
+ /* Must be between 1 and 5 more bytes */
+ if (bytes < 1 || bytes > 5)
+ return bad_offset;
+
+ /* Do we *have* that many bytes? */
+ if (len < bytes)
+ return bad_offset;
+
+ offset += bytes;
+ len -= bytes;
+
+ /* And verify that they are good continuation bytes */
+ do {
+ if ((*buf++ & 0xc0) != 0x80)
+ return bad_offset;
+ } while (--bytes);
+
+ /* We could/should check the value and length here too */
+ }
+ return -1;
+}
+
+/*
+ * This verifies that the buffer is in proper utf8 format.
+ *
+ * If it isn't, it assumes any non-utf8 characters are Latin1,
+ * and does the conversion.
+ *
+ * Fixme: we should probably also disallow overlong forms and
+ * invalid characters. But we don't do that currently.
+ */
+static int verify_utf8(struct strbuf *buf)
+{
+ int ok = 1;
+ long pos = 0;
+
+ for (;;) {
+ int bad;
+ unsigned char c;
+ unsigned char replace[2];
+
+ bad = find_invalid_utf8(buf->buf + pos, buf->len - pos);
+ if (bad < 0)
+ return ok;
+ pos += bad;
+ ok = 0;
+ c = buf->buf[pos];
+ strbuf_remove(buf, pos, 1);
+
+ /* We know 'c' must be in the range 128-255 */
+ replace[0] = 0xc0 + (c >> 6);
+ replace[1] = 0x80 + (c & 0x3f);
+ strbuf_insert(buf, pos, replace, 2);
+ pos += 2;
+ }
+}
+
static const char commit_utf8_warn[] =
-"Warning: commit message does not conform to UTF-8.\n"
+"Warning: commit message did not conform to UTF-8.\n"
"You may want to amend it after fixing the message, or set the config\n"
"variable i18n.commitencoding to the encoding your project uses.\n";
@@ -1170,7 +1291,7 @@ int commit_tree_extended(const struct strbuf *msg, unsigned char *tree,
strbuf_addbuf(&buffer, msg);
/* And check the encoding */
- if (encoding_is_utf8 && !is_utf8(buffer.buf))
+ if (encoding_is_utf8 && !verify_utf8(&buffer))
fprintf(stderr, commit_utf8_warn);
if (sign_commit && do_sign_commit(&buffer, sign_commit))
diff --git a/commit.h b/commit.h
index d617fa3..9f21313 100644
--- a/commit.h
+++ b/commit.h
@@ -171,7 +171,7 @@ extern struct commit_list *get_shallow_commits(struct object_array *heads,
int depth, int shallow_flag, int not_shallow_flag);
int is_descendant_of(struct commit *, struct commit_list *);
-int in_merge_bases(struct commit *, struct commit **, int);
+int in_merge_bases(struct commit *, struct commit *);
extern int interactive_add(int argc, const char **argv, const char *prefix, int patch);
extern int run_add_interactive(const char *revision, const char *patch_mode,
@@ -204,7 +204,6 @@ extern int commit_tree_extended(const struct strbuf *msg, unsigned char *tree,
struct commit_extra_header *);
extern struct commit_extra_header *read_commit_extra_headers(struct commit *, const char **);
-extern struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);
extern void free_commit_extra_headers(struct commit_extra_header *extra);
diff --git a/compat/mkdir.c b/compat/mkdir.c
new file mode 100644
index 0000000..9e253fb
--- /dev/null
+++ b/compat/mkdir.c
@@ -0,0 +1,24 @@
+#include "../git-compat-util.h"
+#undef mkdir
+
+/* for platforms that can't deal with a trailing '/' */
+int compat_mkdir_wo_trailing_slash(const char *dir, mode_t mode)
+{
+ int retval;
+ char *tmp_dir = NULL;
+ size_t len = strlen(dir);
+
+ if (len && dir[len-1] == '/') {
+ if ((tmp_dir = strdup(dir)) == NULL)
+ return -1;
+ tmp_dir[len-1] = '\0';
+ }
+ else
+ tmp_dir = (char *)dir;
+
+ retval = mkdir(tmp_dir, mode);
+ if (tmp_dir != dir)
+ free(tmp_dir);
+
+ return retval;
+}
diff --git a/compat/win32/poll.c b/compat/poll/poll.c
index 403eaa7..7d226ec 100644
--- a/compat/win32/poll.c
+++ b/compat/poll/poll.c
@@ -24,7 +24,9 @@
# pragma GCC diagnostic ignored "-Wtype-limits"
#endif
-#include <malloc.h>
+#if defined(WIN32)
+# include <malloc.h>
+#endif
#include <sys/types.h>
@@ -48,7 +50,9 @@
#else
# include <sys/time.h>
# include <sys/socket.h>
-# include <sys/select.h>
+# ifndef NO_SYS_SELECT_H
+# include <sys/select.h>
+# endif
# include <unistd.h>
#endif
@@ -302,6 +306,10 @@ compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
|| socket_errno == ECONNABORTED || socket_errno == ENETRESET)
happened |= POLLHUP;
+ /* some systems can't use recv() on non-socket, including HP NonStop */
+ else if (/* (r == -1) && */ socket_errno == ENOTSOCK)
+ happened |= (POLLIN | POLLRDNORM) & sought;
+
else
happened |= POLLERR;
}
@@ -349,7 +357,7 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
/* EFAULT is not necessary to implement, but let's do it in the
simplest case. */
- if (!pfd)
+ if (!pfd && nfd)
{
errno = EFAULT;
return -1;
diff --git a/compat/win32/poll.h b/compat/poll/poll.h
index b7aa59d..b7aa59d 100644
--- a/compat/win32/poll.h
+++ b/compat/poll/poll.h
diff --git a/config.mak.in b/config.mak.in
index 802d342..69d4838 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -5,12 +5,10 @@ CC = @CC@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
-CC_LD_DYNPATH = @CC_LD_DYNPATH@
AR = @AR@
TAR = @TAR@
DIFF = @DIFF@
#INSTALL = @INSTALL@ # needs install-sh or install.sh in sources
-TCLTK_PATH = @TCLTK_PATH@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -27,50 +25,3 @@ VPATH = @srcdir@
export exec_prefix mandir
export srcdir VPATH
-
-NEEDS_SSL_WITH_CRYPTO=@NEEDS_SSL_WITH_CRYPTO@
-NO_OPENSSL=@NO_OPENSSL@
-NO_CURL=@NO_CURL@
-NO_EXPAT=@NO_EXPAT@
-NO_LIBGEN_H=@NO_LIBGEN_H@
-HAVE_PATHS_H=@HAVE_PATHS_H@
-HAVE_LIBCHARSET_H=@HAVE_LIBCHARSET_H@
-NO_GETTEXT=@NO_GETTEXT@
-LIBC_CONTAINS_LIBINTL=@LIBC_CONTAINS_LIBINTL@
-NEEDS_LIBICONV=@NEEDS_LIBICONV@
-NEEDS_SOCKET=@NEEDS_SOCKET@
-NEEDS_RESOLV=@NEEDS_RESOLV@
-NEEDS_LIBGEN=@NEEDS_LIBGEN@
-NO_SYS_SELECT_H=@NO_SYS_SELECT_H@
-NO_D_INO_IN_DIRENT=@NO_D_INO_IN_DIRENT@
-NO_D_TYPE_IN_DIRENT=@NO_D_TYPE_IN_DIRENT@
-NO_SOCKADDR_STORAGE=@NO_SOCKADDR_STORAGE@
-NO_IPV6=@NO_IPV6@
-NO_HSTRERROR=@NO_HSTRERROR@
-NO_STRCASESTR=@NO_STRCASESTR@
-NO_STRTOK_R=@NO_STRTOK_R@
-NO_FNMATCH=@NO_FNMATCH@
-NO_FNMATCH_CASEFOLD=@NO_FNMATCH_CASEFOLD@
-NO_MEMMEM=@NO_MEMMEM@
-NO_STRLCPY=@NO_STRLCPY@
-NO_UINTMAX_T=@NO_UINTMAX_T@
-NO_STRTOUMAX=@NO_STRTOUMAX@
-NO_SETENV=@NO_SETENV@
-NO_UNSETENV=@NO_UNSETENV@
-NO_MKDTEMP=@NO_MKDTEMP@
-NO_MKSTEMPS=@NO_MKSTEMPS@
-NO_INET_NTOP=@NO_INET_NTOP@
-NO_INET_PTON=@NO_INET_PTON@
-NO_ICONV=@NO_ICONV@
-OLD_ICONV=@OLD_ICONV@
-NO_REGEX=@NO_REGEX@
-USE_LIBPCRE=@USE_LIBPCRE@
-NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
-INLINE=@INLINE@
-SOCKLEN_T=@SOCKLEN_T@
-FREAD_READS_DIRECTORIES=@FREAD_READS_DIRECTORIES@
-SNPRINTF_RETURNS_BOGUS=@SNPRINTF_RETURNS_BOGUS@
-NO_PTHREADS=@NO_PTHREADS@
-PTHREAD_CFLAGS=@PTHREAD_CFLAGS@
-PTHREAD_LIBS=@PTHREAD_LIBS@
-CHARSET_LIB=@CHARSET_LIB@
diff --git a/configure.ac b/configure.ac
index df7e376..c85888c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,8 +7,9 @@
# ------------------------
# Cause the line "VAR=VAL" to be eventually appended to ${config_file}.
AC_DEFUN([GIT_CONF_SUBST],
- [AC_REQUIRE([GIT_CONF_SUBST_INIT])
- config_appended_defs="$config_appended_defs${newline}$1=$2"])
+[AC_REQUIRE([GIT_CONF_SUBST_INIT])
+config_appended_defs="$config_appended_defs${newline}dnl
+$1=m4_if([$#],[1],[${$1}],[$2])"])
# GIT_CONF_SUBST_INIT
# -------------------
@@ -179,7 +180,7 @@ AC_ARG_WITH([lib],
else
lib=$withval
AC_MSG_NOTICE([Setting lib to '$lib'])
- GIT_CONF_SUBST([lib], [$withval])
+ GIT_CONF_SUBST([lib])
fi])
if test -z "$lib"; then
@@ -215,7 +216,7 @@ AC_ARG_ENABLE([jsmin],
[
JSMIN=$enableval;
AC_MSG_NOTICE([Setting JSMIN to '$JSMIN' to enable JavaScript minifying])
- GIT_CONF_SUBST([JSMIN], [$enableval])
+ GIT_CONF_SUBST([JSMIN])
])
# Define option to enable CSS minification
@@ -225,7 +226,7 @@ AC_ARG_ENABLE([cssmin],
[
CSSMIN=$enableval;
AC_MSG_NOTICE([Setting CSSMIN to '$CSSMIN' to enable CSS minifying])
- GIT_CONF_SUBST([CSSMIN], [$enableval])
+ GIT_CONF_SUBST([CSSMIN])
])
## Site configuration (override autodetection)
@@ -265,8 +266,10 @@ AS_HELP_STRING([], [ARG can be also prefix for libpcre library and hea
else
USE_LIBPCRE=YesPlease
LIBPCREDIR=$withval
- AC_MSG_NOTICE([Setting LIBPCREDIR to $withval])
- GIT_CONF_SUBST([LIBPCREDIR], [$withval])
+ AC_MSG_NOTICE([Setting LIBPCREDIR to $LIBPCREDIR])
+ dnl USE_LIBPCRE can still be modified below, so don't substitute
+ dnl it yet.
+ GIT_CONF_SUBST([LIBPCREDIR])
fi)
#
# Define NO_CURL if you do not have curl installed. git-http-pull and
@@ -386,9 +389,10 @@ AC_MSG_NOTICE([CHECKS for programs])
AC_PROG_CC([cc gcc])
AC_C_INLINE
case $ac_cv_c_inline in
- inline | yes | no) ;;
- *) AC_SUBST([INLINE], [$ac_cv_c_inline]) ;;
+ inline | yes | no) INLINE='';;
+ *) INLINE=$ac_cv_c_inline ;;
esac
+GIT_CONF_SUBST([INLINE])
# which switch to pass runtime path to dynamic libraries to the linker
AC_CACHE_CHECK([if linker supports -R], git_cv_ld_dashr, [
@@ -398,7 +402,7 @@ AC_CACHE_CHECK([if linker supports -R], git_cv_ld_dashr, [
LDFLAGS="${SAVE_LDFLAGS}"
])
if test "$git_cv_ld_dashr" = "yes"; then
- AC_SUBST(CC_LD_DYNPATH, [-R])
+ CC_LD_DYNPATH=-R
else
AC_CACHE_CHECK([if linker supports -Wl,-rpath,], git_cv_ld_wl_rpath, [
SAVE_LDFLAGS="${LDFLAGS}"
@@ -407,7 +411,7 @@ else
LDFLAGS="${SAVE_LDFLAGS}"
])
if test "$git_cv_ld_wl_rpath" = "yes"; then
- AC_SUBST(CC_LD_DYNPATH, [-Wl,-rpath,])
+ CC_LD_DYNPATH=-Wl,-rpath,
else
AC_CACHE_CHECK([if linker supports -rpath], git_cv_ld_rpath, [
SAVE_LDFLAGS="${LDFLAGS}"
@@ -416,32 +420,35 @@ else
LDFLAGS="${SAVE_LDFLAGS}"
])
if test "$git_cv_ld_rpath" = "yes"; then
- AC_SUBST(CC_LD_DYNPATH, [-rpath])
+ CC_LD_DYNPATH=-rpath
else
+ CC_LD_DYNPATH=
AC_MSG_WARN([linker does not support runtime path to dynamic libraries])
fi
fi
fi
+GIT_CONF_SUBST([CC_LD_DYNPATH])
#AC_PROG_INSTALL # needs install-sh or install.sh in sources
AC_CHECK_TOOLS(AR, [gar ar], :)
AC_CHECK_PROGS(TAR, [gtar tar])
AC_CHECK_PROGS(DIFF, [gnudiff gdiff diff])
# TCLTK_PATH will be set to some value if we want Tcl/Tk
# or will be empty otherwise.
-if test -z "$NO_TCLTK"; then
+if test -n "$NO_TCLTK"; then
+ TCLTK_PATH=
+else
if test "$with_tcltk" = ""; then
# No Tcl/Tk switches given. Do not check for Tcl/Tk, use bare 'wish'.
TCLTK_PATH=wish
- AC_SUBST(TCLTK_PATH)
elif test "$with_tcltk" = "yes"; then
# Tcl/Tk check requested.
AC_CHECK_PROGS(TCLTK_PATH, [wish], )
else
AC_MSG_RESULT([Using Tcl/Tk interpreter $with_tcltk])
TCLTK_PATH="$with_tcltk"
- AC_SUBST(TCLTK_PATH)
fi
fi
+GIT_CONF_SUBST([TCLTK_PATH])
AC_CHECK_PROGS(ASCIIDOC, [asciidoc])
if test -n "$ASCIIDOC"; then
AC_MSG_CHECKING([for asciidoc version])
@@ -468,13 +475,13 @@ GIT_STASH_FLAGS($OPENSSLDIR)
AC_CHECK_LIB([crypto], [SHA1_Init],
[NEEDS_SSL_WITH_CRYPTO=],
[AC_CHECK_LIB([ssl], [SHA1_Init],
- [NEEDS_SSL_WITH_CRYPTO=YesPlease],
- [NEEDS_SSL_WITH_CRYPTO= NO_OPENSSL=YesPlease])])
+ [NEEDS_SSL_WITH_CRYPTO=YesPlease NO_OPENSSL=],
+ [NEEDS_SSL_WITH_CRYPTO= NO_OPENSSL=YesPlease])])
GIT_UNSTASH_FLAGS($OPENSSLDIR)
-AC_SUBST(NEEDS_SSL_WITH_CRYPTO)
-AC_SUBST(NO_OPENSSL)
+GIT_CONF_SUBST([NEEDS_SSL_WITH_CRYPTO])
+GIT_CONF_SUBST([NO_OPENSSL])
#
# Define USE_LIBPCRE if you have and want to use libpcre. git-grep will be
@@ -491,7 +498,7 @@ AC_CHECK_LIB([pcre], [pcre_version],
GIT_UNSTASH_FLAGS($LIBPCREDIR)
-AC_SUBST(USE_LIBPCRE)
+GIT_CONF_SUBST([USE_LIBPCRE])
fi
@@ -508,7 +515,7 @@ AC_CHECK_LIB([curl], [curl_global_init],
GIT_UNSTASH_FLAGS($CURLDIR)
-AC_SUBST(NO_CURL)
+GIT_CONF_SUBST([NO_CURL])
#
# Define NO_EXPAT if you do not have expat installed. git-http-push is
@@ -522,7 +529,7 @@ AC_CHECK_LIB([expat], [XML_ParserCreate],
GIT_UNSTASH_FLAGS($EXPATDIR)
-AC_SUBST(NO_EXPAT)
+GIT_CONF_SUBST([NO_EXPAT])
#
# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin and
@@ -568,8 +575,8 @@ LIBS="$old_LIBS"
GIT_UNSTASH_FLAGS($ICONVDIR)
-AC_SUBST(NEEDS_LIBICONV)
-AC_SUBST(NO_ICONV)
+GIT_CONF_SUBST([NEEDS_LIBICONV])
+GIT_CONF_SUBST([NO_ICONV])
if test -n "$NO_ICONV"; then
NEEDS_LIBICONV=
@@ -596,7 +603,7 @@ LIBS="$old_LIBS"
GIT_UNSTASH_FLAGS($ZLIB_PATH)
-AC_SUBST(NO_DEFLATE_BOUND)
+GIT_CONF_SUBST([NO_DEFLATE_BOUND])
#
# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
@@ -604,7 +611,7 @@ AC_SUBST(NO_DEFLATE_BOUND)
AC_CHECK_LIB([c], [socket],
[NEEDS_SOCKET=],
[NEEDS_SOCKET=YesPlease])
-AC_SUBST(NEEDS_SOCKET)
+GIT_CONF_SUBST([NEEDS_SOCKET])
test -n "$NEEDS_SOCKET" && LIBS="$LIBS -lsocket"
#
@@ -612,40 +619,43 @@ test -n "$NEEDS_SOCKET" && LIBS="$LIBS -lsocket"
# libresolv provides some of the functions we would normally get
# from libc.
NEEDS_RESOLV=
-AC_SUBST(NEEDS_RESOLV)
#
# Define NO_INET_NTOP if linking with -lresolv is not enough.
# Solaris 2.7 in particular hos inet_ntop in -lresolv.
NO_INET_NTOP=
-AC_SUBST(NO_INET_NTOP)
AC_CHECK_FUNC([inet_ntop],
- [],
+ [],
[AC_CHECK_LIB([resolv], [inet_ntop],
- [NEEDS_RESOLV=YesPlease],
+ [NEEDS_RESOLV=YesPlease],
[NO_INET_NTOP=YesPlease])
])
+GIT_CONF_SUBST([NO_INET_NTOP])
#
# Define NO_INET_PTON if linking with -lresolv is not enough.
# Solaris 2.7 in particular hos inet_pton in -lresolv.
NO_INET_PTON=
-AC_SUBST(NO_INET_PTON)
AC_CHECK_FUNC([inet_pton],
- [],
+ [],
[AC_CHECK_LIB([resolv], [inet_pton],
- [NEEDS_RESOLV=YesPlease],
+ [NEEDS_RESOLV=YesPlease],
[NO_INET_PTON=YesPlease])
])
+GIT_CONF_SUBST([NO_INET_PTON])
#
# Define NO_HSTRERROR if linking with -lresolv is not enough.
# Solaris 2.6 in particular has no hstrerror, even in -lresolv.
NO_HSTRERROR=
AC_CHECK_FUNC([hstrerror],
- [],
+ [],
[AC_CHECK_LIB([resolv], [hstrerror],
- [NEEDS_RESOLV=YesPlease],
+ [NEEDS_RESOLV=YesPlease],
[NO_HSTRERROR=YesPlease])
])
-AC_SUBST(NO_HSTRERROR)
+GIT_CONF_SUBST([NO_HSTRERROR])
+
+dnl This must go after all the possible places for its initialization,
+dnl in the AC_CHECK_FUNC invocations above.
+GIT_CONF_SUBST([NEEDS_RESOLV])
#
# If any of the above tests determined that -lresolv is needed at
# build-time, also set it here for remaining configure-time checks.
@@ -654,13 +664,13 @@ test -n "$NEEDS_RESOLV" && LIBS="$LIBS -lresolv"
AC_CHECK_LIB([c], [basename],
[NEEDS_LIBGEN=],
[NEEDS_LIBGEN=YesPlease])
-AC_SUBST(NEEDS_LIBGEN)
+GIT_CONF_SUBST([NEEDS_LIBGEN])
test -n "$NEEDS_LIBGEN" && LIBS="$LIBS -lgen"
AC_CHECK_LIB([c], [gettext],
[LIBC_CONTAINS_LIBINTL=YesPlease],
[LIBC_CONTAINS_LIBINTL=])
-AC_SUBST(LIBC_CONTAINS_LIBINTL)
+GIT_CONF_SUBST([LIBC_CONTAINS_LIBINTL])
#
# Define NO_GETTEXT if you don't want Git output to be translated.
@@ -668,7 +678,7 @@ AC_SUBST(LIBC_CONTAINS_LIBINTL)
AC_CHECK_HEADER([libintl.h],
[NO_GETTEXT=],
[NO_GETTEXT=YesPlease])
-AC_SUBST(NO_GETTEXT)
+GIT_CONF_SUBST([NO_GETTEXT])
if test -z "$NO_GETTEXT"; then
test -n "$LIBC_CONTAINS_LIBINTL" || LIBS="$LIBS -lintl"
@@ -681,19 +691,19 @@ AC_MSG_NOTICE([CHECKS for header files])
AC_CHECK_HEADER([sys/select.h],
[NO_SYS_SELECT_H=],
[NO_SYS_SELECT_H=UnfortunatelyYes])
-AC_SUBST(NO_SYS_SELECT_H)
+GIT_CONF_SUBST([NO_SYS_SELECT_H])
#
# Define NO_SYS_POLL_H if you don't have sys/poll.h
AC_CHECK_HEADER([sys/poll.h],
[NO_SYS_POLL_H=],
[NO_SYS_POLL_H=UnfortunatelyYes])
-AC_SUBST(NO_SYS_POLL_H)
+GIT_CONF_SUBST([NO_SYS_POLL_H])
#
# Define NO_INTTYPES_H if you don't have inttypes.h
AC_CHECK_HEADER([inttypes.h],
[NO_INTTYPES_H=],
[NO_INTTYPES_H=UnfortunatelyYes])
-AC_SUBST(NO_INTTYPES_H)
+GIT_CONF_SUBST([NO_INTTYPES_H])
#
# Define OLD_ICONV if your library has an old iconv(), where the second
# (input buffer pointer) parameter is declared with type (const char **).
@@ -716,23 +726,24 @@ AC_COMPILE_IFELSE([OLDICONVTEST_SRC],
GIT_UNSTASH_FLAGS($ICONVDIR)
-AC_SUBST(OLD_ICONV)
+GIT_CONF_SUBST([OLD_ICONV])
## Checks for typedefs, structures, and compiler characteristics.
AC_MSG_NOTICE([CHECKS for typedefs, structures, and compiler characteristics])
#
TYPE_SOCKLEN_T
case $ac_cv_type_socklen_t in
- yes) ;;
- *) AC_SUBST([SOCKLEN_T], [$git_cv_socklen_t_equiv]) ;;
+ yes) SOCKLEN_T='';;
+ *) SOCKLEN_T=$git_cv_socklen_t_equiv;;
esac
+GIT_CONF_SUBST([SOCKLEN_T])
# Define NO_D_INO_IN_DIRENT if you don't have d_ino in your struct dirent.
AC_CHECK_MEMBER(struct dirent.d_ino,
[NO_D_INO_IN_DIRENT=],
[NO_D_INO_IN_DIRENT=YesPlease],
[#include <dirent.h>])
-AC_SUBST(NO_D_INO_IN_DIRENT)
+GIT_CONF_SUBST([NO_D_INO_IN_DIRENT])
#
# Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks
# d_type in struct dirent (latest Cygwin -- will be fixed soonish).
@@ -740,7 +751,7 @@ AC_CHECK_MEMBER(struct dirent.d_type,
[NO_D_TYPE_IN_DIRENT=],
[NO_D_TYPE_IN_DIRENT=YesPlease],
[#include <dirent.h>])
-AC_SUBST(NO_D_TYPE_IN_DIRENT)
+GIT_CONF_SUBST([NO_D_TYPE_IN_DIRENT])
#
# Define NO_SOCKADDR_STORAGE if your platform does not have struct
# sockaddr_storage.
@@ -750,7 +761,7 @@ AC_CHECK_TYPE(struct sockaddr_storage,
#include <sys/types.h>
#include <sys/socket.h>
])
-AC_SUBST(NO_SOCKADDR_STORAGE)
+GIT_CONF_SUBST([NO_SOCKADDR_STORAGE])
#
# Define NO_IPV6 if you lack IPv6 support and getaddrinfo().
AC_CHECK_TYPE([struct addrinfo],[
@@ -762,7 +773,7 @@ AC_CHECK_TYPE([struct addrinfo],[
#include <sys/socket.h>
#include <netdb.h>
])
-AC_SUBST(NO_IPV6)
+GIT_CONF_SUBST([NO_IPV6])
#
# Define NO_REGEX if you have no or inferior regex support in your C library.
AC_CACHE_CHECK([whether the platform regex can handle null bytes],
@@ -783,7 +794,7 @@ if test $ac_cv_c_excellent_regex = yes; then
else
NO_REGEX=YesPlease
fi
-AC_SUBST(NO_REGEX)
+GIT_CONF_SUBST([NO_REGEX])
#
# Define FREAD_READS_DIRECTORIES if your are on a system which succeeds
# when attempting to read from an fopen'ed directory.
@@ -803,7 +814,7 @@ if test $ac_cv_fread_reads_directories = yes; then
else
FREAD_READS_DIRECTORIES=
fi
-AC_SUBST(FREAD_READS_DIRECTORIES)
+GIT_CONF_SUBST([FREAD_READS_DIRECTORIES])
#
# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf()
# or vsnprintf() return -1 instead of number of characters which would
@@ -837,7 +848,7 @@ if test $ac_cv_snprintf_returns_bogus = yes; then
else
SNPRINTF_RETURNS_BOGUS=
fi
-AC_SUBST(SNPRINTF_RETURNS_BOGUS)
+GIT_CONF_SUBST([SNPRINTF_RETURNS_BOGUS])
## Checks for library functions.
@@ -848,47 +859,45 @@ AC_MSG_NOTICE([CHECKS for library functions])
AC_CHECK_HEADER([libgen.h],
[NO_LIBGEN_H=],
[NO_LIBGEN_H=YesPlease])
-AC_SUBST(NO_LIBGEN_H)
+GIT_CONF_SUBST([NO_LIBGEN_H])
#
# Define HAVE_PATHS_H if you have paths.h.
AC_CHECK_HEADER([paths.h],
[HAVE_PATHS_H=YesPlease],
[HAVE_PATHS_H=])
-AC_SUBST(HAVE_PATHS_H)
+GIT_CONF_SUBST([HAVE_PATHS_H])
#
# Define HAVE_LIBCHARSET_H if have libcharset.h
AC_CHECK_HEADER([libcharset.h],
[HAVE_LIBCHARSET_H=YesPlease],
[HAVE_LIBCHARSET_H=])
-AC_SUBST(HAVE_LIBCHARSET_H)
+GIT_CONF_SUBST([HAVE_LIBCHARSET_H])
# Define CHARSET_LIB if libiconv does not export the locale_charset symbol
# and libcharset does
CHARSET_LIB=
AC_CHECK_LIB([iconv], [locale_charset],
[],
[AC_CHECK_LIB([charset], [locale_charset],
- [CHARSET_LIB=-lcharset])
- ]
-)
-AC_SUBST(CHARSET_LIB)
+ [CHARSET_LIB=-lcharset])])
+GIT_CONF_SUBST([CHARSET_LIB])
#
# Define NO_STRCASESTR if you don't have strcasestr.
GIT_CHECK_FUNC(strcasestr,
[NO_STRCASESTR=],
[NO_STRCASESTR=YesPlease])
-AC_SUBST(NO_STRCASESTR)
+GIT_CONF_SUBST([NO_STRCASESTR])
#
# Define NO_STRTOK_R if you don't have strtok_r
GIT_CHECK_FUNC(strtok_r,
[NO_STRTOK_R=],
[NO_STRTOK_R=YesPlease])
-AC_SUBST(NO_STRTOK_R)
+GIT_CONF_SUBST([NO_STRTOK_R])
#
# Define NO_FNMATCH if you don't have fnmatch
GIT_CHECK_FUNC(fnmatch,
[NO_FNMATCH=],
[NO_FNMATCH=YesPlease])
-AC_SUBST(NO_FNMATCH)
+GIT_CONF_SUBST([NO_FNMATCH])
#
# Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the
# FNM_CASEFOLD GNU extension.
@@ -910,19 +919,19 @@ if test $ac_cv_c_excellent_fnmatch = yes; then
else
NO_FNMATCH_CASEFOLD=YesPlease
fi
-AC_SUBST(NO_FNMATCH_CASEFOLD)
+GIT_CONF_SUBST([NO_FNMATCH_CASEFOLD])
#
# Define NO_MEMMEM if you don't have memmem.
GIT_CHECK_FUNC(memmem,
[NO_MEMMEM=],
[NO_MEMMEM=YesPlease])
-AC_SUBST(NO_MEMMEM)
+GIT_CONF_SUBST([NO_MEMMEM])
#
# Define NO_STRLCPY if you don't have strlcpy.
GIT_CHECK_FUNC(strlcpy,
[NO_STRLCPY=],
[NO_STRLCPY=YesPlease])
-AC_SUBST(NO_STRLCPY)
+GIT_CONF_SUBST([NO_STRLCPY])
#
# Define NO_UINTMAX_T if your platform does not have uintmax_t
AC_CHECK_TYPE(uintmax_t,
@@ -930,43 +939,43 @@ AC_CHECK_TYPE(uintmax_t,
[NO_UINTMAX_T=YesPlease],[
#include <inttypes.h>
])
-AC_SUBST(NO_UINTMAX_T)
+GIT_CONF_SUBST([NO_UINTMAX_T])
#
# Define NO_STRTOUMAX if you don't have strtoumax in the C library.
GIT_CHECK_FUNC(strtoumax,
[NO_STRTOUMAX=],
[NO_STRTOUMAX=YesPlease])
-AC_SUBST(NO_STRTOUMAX)
+GIT_CONF_SUBST([NO_STRTOUMAX])
#
# Define NO_SETENV if you don't have setenv in the C library.
GIT_CHECK_FUNC(setenv,
[NO_SETENV=],
[NO_SETENV=YesPlease])
-AC_SUBST(NO_SETENV)
+GIT_CONF_SUBST([NO_SETENV])
#
# Define NO_UNSETENV if you don't have unsetenv in the C library.
GIT_CHECK_FUNC(unsetenv,
[NO_UNSETENV=],
[NO_UNSETENV=YesPlease])
-AC_SUBST(NO_UNSETENV)
+GIT_CONF_SUBST([NO_UNSETENV])
#
# Define NO_MKDTEMP if you don't have mkdtemp in the C library.
GIT_CHECK_FUNC(mkdtemp,
[NO_MKDTEMP=],
[NO_MKDTEMP=YesPlease])
-AC_SUBST(NO_MKDTEMP)
+GIT_CONF_SUBST([NO_MKDTEMP])
#
# Define NO_MKSTEMPS if you don't have mkstemps in the C library.
GIT_CHECK_FUNC(mkstemps,
[NO_MKSTEMPS=],
[NO_MKSTEMPS=YesPlease])
-AC_SUBST(NO_MKSTEMPS)
+GIT_CONF_SUBST([NO_MKSTEMPS])
#
# Define NO_INITGROUPS if you don't have initgroups in the C library.
GIT_CHECK_FUNC(initgroups,
[NO_INITGROUPS=],
[NO_INITGROUPS=YesPlease])
-AC_SUBST(NO_INITGROUPS)
+GIT_CONF_SUBST([NO_INITGROUPS])
#
#
# Define NO_MMAP if you want to avoid mmap.
@@ -1048,9 +1057,9 @@ fi
CFLAGS="$old_CFLAGS"
-AC_SUBST(PTHREAD_CFLAGS)
-AC_SUBST(PTHREAD_LIBS)
-AC_SUBST(NO_PTHREADS)
+GIT_CONF_SUBST([PTHREAD_CFLAGS])
+GIT_CONF_SUBST([PTHREAD_LIBS])
+GIT_CONF_SUBST([NO_PTHREADS])
## Output files
AC_CONFIG_FILES(["${config_file}":"${config_in}"])
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 5b255cb..be800e0 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -875,11 +875,15 @@ _git_branch ()
done
case "$cur" in
+ --set-upstream-to=*)
+ __gitcomp "$(__git_refs)" "" "${cur##--set-upstream-to=}"
+ ;;
--*)
__gitcomp "
--color --no-color --verbose --abbrev= --no-abbrev
--track --no-track --contains --merged --no-merged
- --set-upstream --edit-description --list
+ --set-upstream-to= --edit-description --list
+ --unset-upstream
"
;;
*)
@@ -1072,7 +1076,7 @@ _git_diff ()
}
__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
- tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3
+ tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3 codecompare
"
_git_difftool ()
diff --git a/contrib/credential/gnome-keyring/.gitignore b/contrib/credential/gnome-keyring/.gitignore
new file mode 100644
index 0000000..88d8fcd
--- /dev/null
+++ b/contrib/credential/gnome-keyring/.gitignore
@@ -0,0 +1 @@
+git-credential-gnome-keyring
diff --git a/contrib/credential/gnome-keyring/Makefile b/contrib/credential/gnome-keyring/Makefile
new file mode 100644
index 0000000..e6561d8
--- /dev/null
+++ b/contrib/credential/gnome-keyring/Makefile
@@ -0,0 +1,24 @@
+MAIN:=git-credential-gnome-keyring
+all:: $(MAIN)
+
+CC = gcc
+RM = rm -f
+CFLAGS = -g -O2 -Wall
+
+-include ../../../config.mak.autogen
+-include ../../../config.mak
+
+INCS:=$(shell pkg-config --cflags gnome-keyring-1)
+LIBS:=$(shell pkg-config --libs gnome-keyring-1)
+
+SRCS:=$(MAIN).c
+OBJS:=$(SRCS:.c=.o)
+
+%.o: %.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(INCS) -o $@ -c $<
+
+$(MAIN): $(OBJS)
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+clean:
+ @$(RM) $(MAIN) $(OBJS)
diff --git a/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c b/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c
new file mode 100644
index 0000000..41f61c5
--- /dev/null
+++ b/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2011 John Szakmeister <john@szakmeister.net>
+ * 2012 Philipp A. Hartmann <pah@qo.cx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Credits:
+ * - GNOME Keyring API handling originally written by John Szakmeister
+ * - ported to credential helper API by Philipp A. Hartmann
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <gnome-keyring.h>
+
+/*
+ * This credential struct and API is simplified from git's credential.{h,c}
+ */
+struct credential
+{
+ char *protocol;
+ char *host;
+ unsigned short port;
+ char *path;
+ char *username;
+ char *password;
+};
+
+#define CREDENTIAL_INIT \
+ { NULL,NULL,0,NULL,NULL,NULL }
+
+void credential_init(struct credential *c);
+void credential_clear(struct credential *c);
+int credential_read(struct credential *c);
+void credential_write(const struct credential *c);
+
+typedef int (*credential_op_cb)(struct credential*);
+
+struct credential_operation
+{
+ char *name;
+ credential_op_cb op;
+};
+
+#define CREDENTIAL_OP_END \
+ { NULL,NULL }
+
+/*
+ * Table with operation callbacks is defined in concrete
+ * credential helper implementation and contains entries
+ * like { "get", function_to_get_credential } terminated
+ * by CREDENTIAL_OP_END.
+ */
+struct credential_operation const credential_helper_ops[];
+
+/* ---------------- common helper functions ----------------- */
+
+static inline void free_password(char *password)
+{
+ char *c = password;
+ if (!password)
+ return;
+
+ while (*c) *c++ = '\0';
+ free(password);
+}
+
+static inline void warning(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(stderr, "warning: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n" );
+ va_end(ap);
+}
+
+static inline void error(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(stderr, "error: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n" );
+ va_end(ap);
+}
+
+static inline void die(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap,fmt);
+ error(fmt, ap);
+ va_end(ap);
+ exit(EXIT_FAILURE);
+}
+
+static inline void die_errno(int err)
+{
+ error("%s", strerror(err));
+ exit(EXIT_FAILURE);
+}
+
+static inline char *xstrdup(const char *str)
+{
+ char *ret = strdup(str);
+ if (!ret)
+ die_errno(errno);
+
+ return ret;
+}
+
+/* ----------------- GNOME Keyring functions ----------------- */
+
+/* create a special keyring option string, if path is given */
+static char* keyring_object(struct credential *c)
+{
+ char* object = NULL;
+
+ if (!c->path)
+ return object;
+
+ object = (char*) malloc(strlen(c->host)+strlen(c->path)+8);
+ if(!object)
+ die_errno(errno);
+
+ if(c->port)
+ sprintf(object,"%s:%hd/%s",c->host,c->port,c->path);
+ else
+ sprintf(object,"%s/%s",c->host,c->path);
+
+ return object;
+}
+
+int keyring_get(struct credential *c)
+{
+ char* object = NULL;
+ GList *entries;
+ GnomeKeyringNetworkPasswordData *password_data;
+ GnomeKeyringResult result;
+
+ if (!c->protocol || !(c->host || c->path))
+ return EXIT_FAILURE;
+
+ object = keyring_object(c);
+
+ result = gnome_keyring_find_network_password_sync(
+ c->username,
+ NULL /* domain */,
+ c->host,
+ object,
+ c->protocol,
+ NULL /* authtype */,
+ c->port,
+ &entries);
+
+ free(object);
+
+ if (result == GNOME_KEYRING_RESULT_NO_MATCH)
+ return EXIT_SUCCESS;
+
+ if (result == GNOME_KEYRING_RESULT_CANCELLED)
+ return EXIT_SUCCESS;
+
+ if (result != GNOME_KEYRING_RESULT_OK) {
+ error("%s",gnome_keyring_result_to_message(result));
+ return EXIT_FAILURE;
+ }
+
+ /* pick the first one from the list */
+ password_data = (GnomeKeyringNetworkPasswordData *) entries->data;
+
+ free_password(c->password);
+ c->password = xstrdup(password_data->password);
+
+ if (!c->username)
+ c->username = xstrdup(password_data->user);
+
+ gnome_keyring_network_password_list_free(entries);
+
+ return EXIT_SUCCESS;
+}
+
+
+int keyring_store(struct credential *c)
+{
+ guint32 item_id;
+ char *object = NULL;
+
+ /*
+ * Sanity check that what we are storing is actually sensible.
+ * In particular, we can't make a URL without a protocol field.
+ * Without either a host or pathname (depending on the scheme),
+ * we have no primary key. And without a username and password,
+ * we are not actually storing a credential.
+ */
+ if (!c->protocol || !(c->host || c->path) ||
+ !c->username || !c->password)
+ return EXIT_FAILURE;
+
+ object = keyring_object(c);
+
+ gnome_keyring_set_network_password_sync(
+ GNOME_KEYRING_DEFAULT,
+ c->username,
+ NULL /* domain */,
+ c->host,
+ object,
+ c->protocol,
+ NULL /* authtype */,
+ c->port,
+ c->password,
+ &item_id);
+
+ free(object);
+ return EXIT_SUCCESS;
+}
+
+int keyring_erase(struct credential *c)
+{
+ char *object = NULL;
+ GList *entries;
+ GnomeKeyringNetworkPasswordData *password_data;
+ GnomeKeyringResult result;
+
+ /*
+ * Sanity check that we actually have something to match
+ * against. The input we get is a restrictive pattern,
+ * so technically a blank credential means "erase everything".
+ * But it is too easy to accidentally send this, since it is equivalent
+ * to empty input. So explicitly disallow it, and require that the
+ * pattern have some actual content to match.
+ */
+ if (!c->protocol && !c->host && !c->path && !c->username)
+ return EXIT_FAILURE;
+
+ object = keyring_object(c);
+
+ result = gnome_keyring_find_network_password_sync(
+ c->username,
+ NULL /* domain */,
+ c->host,
+ object,
+ c->protocol,
+ NULL /* authtype */,
+ c->port,
+ &entries);
+
+ free(object);
+
+ if (result == GNOME_KEYRING_RESULT_NO_MATCH)
+ return EXIT_SUCCESS;
+
+ if (result == GNOME_KEYRING_RESULT_CANCELLED)
+ return EXIT_SUCCESS;
+
+ if (result != GNOME_KEYRING_RESULT_OK)
+ {
+ error("%s",gnome_keyring_result_to_message(result));
+ return EXIT_FAILURE;
+ }
+
+ /* pick the first one from the list (delete all matches?) */
+ password_data = (GnomeKeyringNetworkPasswordData *) entries->data;
+
+ result = gnome_keyring_item_delete_sync(
+ password_data->keyring, password_data->item_id);
+
+ gnome_keyring_network_password_list_free(entries);
+
+ if (result != GNOME_KEYRING_RESULT_OK)
+ {
+ error("%s",gnome_keyring_result_to_message(result));
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+/*
+ * Table with helper operation callbacks, used by generic
+ * credential helper main function.
+ */
+struct credential_operation const credential_helper_ops[] =
+{
+ { "get", keyring_get },
+ { "store", keyring_store },
+ { "erase", keyring_erase },
+ CREDENTIAL_OP_END
+};
+
+/* ------------------ credential functions ------------------ */
+
+void credential_init(struct credential *c)
+{
+ memset(c, 0, sizeof(*c));
+}
+
+void credential_clear(struct credential *c)
+{
+ free(c->protocol);
+ free(c->host);
+ free(c->path);
+ free(c->username);
+ free_password(c->password);
+
+ credential_init(c);
+}
+
+int credential_read(struct credential *c)
+{
+ char buf[1024];
+ ssize_t line_len = 0;
+ char *key = buf;
+ char *value;
+
+ while (fgets(buf, sizeof(buf), stdin))
+ {
+ line_len = strlen(buf);
+
+ if(buf[line_len-1]=='\n')
+ buf[--line_len]='\0';
+
+ if(!line_len)
+ break;
+
+ value = strchr(buf,'=');
+ if(!value) {
+ warning("invalid credential line: %s", key);
+ return -1;
+ }
+ *value++ = '\0';
+
+ if (!strcmp(key, "protocol")) {
+ free(c->protocol);
+ c->protocol = xstrdup(value);
+ } else if (!strcmp(key, "host")) {
+ free(c->host);
+ c->host = xstrdup(value);
+ value = strrchr(c->host,':');
+ if (value) {
+ *value++ = '\0';
+ c->port = atoi(value);
+ }
+ } else if (!strcmp(key, "path")) {
+ free(c->path);
+ c->path = xstrdup(value);
+ } else if (!strcmp(key, "username")) {
+ free(c->username);
+ c->username = xstrdup(value);
+ } else if (!strcmp(key, "password")) {
+ free_password(c->password);
+ c->password = xstrdup(value);
+ while (*value) *value++ = '\0';
+ }
+ /*
+ * Ignore other lines; we don't know what they mean, but
+ * this future-proofs us when later versions of git do
+ * learn new lines, and the helpers are updated to match.
+ */
+ }
+ return 0;
+}
+
+void credential_write_item(FILE *fp, const char *key, const char *value)
+{
+ if (!value)
+ return;
+ fprintf(fp, "%s=%s\n", key, value);
+}
+
+void credential_write(const struct credential *c)
+{
+ /* only write username/password, if set */
+ credential_write_item(stdout, "username", c->username);
+ credential_write_item(stdout, "password", c->password);
+}
+
+static void usage(const char *name)
+{
+ struct credential_operation const *try_op = credential_helper_ops;
+ const char *basename = strrchr(name,'/');
+
+ basename = (basename) ? basename + 1 : name;
+ fprintf(stderr, "Usage: %s <", basename);
+ while(try_op->name) {
+ fprintf(stderr,"%s",(try_op++)->name);
+ if(try_op->name)
+ fprintf(stderr,"%s","|");
+ }
+ fprintf(stderr,"%s",">\n");
+}
+
+int main(int argc, char *argv[])
+{
+ int ret = EXIT_SUCCESS;
+
+ struct credential_operation const *try_op = credential_helper_ops;
+ struct credential cred = CREDENTIAL_INIT;
+
+ if (!argv[1]) {
+ usage(argv[0]);
+ goto out;
+ }
+
+ /* lookup operation callback */
+ while(try_op->name && strcmp(argv[1], try_op->name))
+ try_op++;
+
+ /* unsupported operation given -- ignore silently */
+ if(!try_op->name || !try_op->op)
+ goto out;
+
+ ret = credential_read(&cred);
+ if(ret)
+ goto out;
+
+ /* perform credential operation */
+ ret = (*try_op->op)(&cred);
+
+ credential_write(&cred);
+
+out:
+ credential_clear(&cred);
+ return ret;
+}
diff --git a/contrib/credential/wincred/Makefile b/contrib/credential/wincred/Makefile
new file mode 100644
index 0000000..bad45ca
--- /dev/null
+++ b/contrib/credential/wincred/Makefile
@@ -0,0 +1,14 @@
+all: git-credential-wincred.exe
+
+CC = gcc
+RM = rm -f
+CFLAGS = -O2 -Wall
+
+-include ../../../config.mak.autogen
+-include ../../../config.mak
+
+git-credential-wincred.exe : git-credential-wincred.c
+ $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
+
+clean:
+ $(RM) git-credential-wincred.exe
diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c
new file mode 100644
index 0000000..cbaec5f
--- /dev/null
+++ b/contrib/credential/wincred/git-credential-wincred.c
@@ -0,0 +1,357 @@
+/*
+ * A git credential helper that interface with Windows' Credential Manager
+ *
+ */
+#include <windows.h>
+#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
+
+/* common helpers */
+
+static void die(const char *err, ...)
+{
+ char msg[4096];
+ va_list params;
+ va_start(params, err);
+ vsnprintf(msg, sizeof(msg), err, params);
+ fprintf(stderr, "%s\n", msg);
+ va_end(params);
+ exit(1);
+}
+
+static void *xmalloc(size_t size)
+{
+ void *ret = malloc(size);
+ if (!ret && !size)
+ ret = malloc(1);
+ if (!ret)
+ die("Out of memory");
+ return ret;
+}
+
+static char *xstrdup(const char *str)
+{
+ char *ret = strdup(str);
+ if (!ret)
+ die("Out of memory");
+ return ret;
+}
+
+/* MinGW doesn't have wincred.h, so we need to define stuff */
+
+typedef struct _CREDENTIAL_ATTRIBUTEW {
+ LPWSTR Keyword;
+ DWORD Flags;
+ DWORD ValueSize;
+ LPBYTE Value;
+} CREDENTIAL_ATTRIBUTEW, *PCREDENTIAL_ATTRIBUTEW;
+
+typedef struct _CREDENTIALW {
+ DWORD Flags;
+ DWORD Type;
+ LPWSTR TargetName;
+ LPWSTR Comment;
+ FILETIME LastWritten;
+ DWORD CredentialBlobSize;
+ LPBYTE CredentialBlob;
+ DWORD Persist;
+ DWORD AttributeCount;
+ PCREDENTIAL_ATTRIBUTEW Attributes;
+ LPWSTR TargetAlias;
+ LPWSTR UserName;
+} CREDENTIALW, *PCREDENTIALW;
+
+#define CRED_TYPE_GENERIC 1
+#define CRED_PERSIST_LOCAL_MACHINE 2
+#define CRED_MAX_ATTRIBUTES 64
+
+typedef BOOL (WINAPI *CredWriteWT)(PCREDENTIALW, DWORD);
+typedef BOOL (WINAPI *CredUnPackAuthenticationBufferWT)(DWORD, PVOID, DWORD,
+ LPWSTR, DWORD *, LPWSTR, DWORD *, LPWSTR, DWORD *);
+typedef BOOL (WINAPI *CredEnumerateWT)(LPCWSTR, DWORD, DWORD *,
+ PCREDENTIALW **);
+typedef BOOL (WINAPI *CredPackAuthenticationBufferWT)(DWORD, LPWSTR, LPWSTR,
+ PBYTE, DWORD *);
+typedef VOID (WINAPI *CredFreeT)(PVOID);
+typedef BOOL (WINAPI *CredDeleteWT)(LPCWSTR, DWORD, DWORD);
+
+static HMODULE advapi, credui;
+static CredWriteWT CredWriteW;
+static CredUnPackAuthenticationBufferWT CredUnPackAuthenticationBufferW;
+static CredEnumerateWT CredEnumerateW;
+static CredPackAuthenticationBufferWT CredPackAuthenticationBufferW;
+static CredFreeT CredFree;
+static CredDeleteWT CredDeleteW;
+
+static void load_cred_funcs(void)
+{
+ /* load DLLs */
+ advapi = LoadLibrary("advapi32.dll");
+ credui = LoadLibrary("credui.dll");
+ if (!advapi || !credui)
+ die("failed to load DLLs");
+
+ /* get function pointers */
+ CredWriteW = (CredWriteWT)GetProcAddress(advapi, "CredWriteW");
+ CredUnPackAuthenticationBufferW = (CredUnPackAuthenticationBufferWT)
+ GetProcAddress(credui, "CredUnPackAuthenticationBufferW");
+ CredEnumerateW = (CredEnumerateWT)GetProcAddress(advapi,
+ "CredEnumerateW");
+ CredPackAuthenticationBufferW = (CredPackAuthenticationBufferWT)
+ GetProcAddress(credui, "CredPackAuthenticationBufferW");
+ CredFree = (CredFreeT)GetProcAddress(advapi, "CredFree");
+ CredDeleteW = (CredDeleteWT)GetProcAddress(advapi, "CredDeleteW");
+ if (!CredWriteW || !CredUnPackAuthenticationBufferW ||
+ !CredEnumerateW || !CredPackAuthenticationBufferW || !CredFree ||
+ !CredDeleteW)
+ die("failed to load functions");
+}
+
+static char target_buf[1024];
+static char *protocol, *host, *path, *username;
+static WCHAR *wusername, *password, *target;
+
+static void write_item(const char *what, WCHAR *wbuf)
+{
+ char *buf;
+ int len = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, NULL, 0, NULL,
+ FALSE);
+ buf = xmalloc(len);
+
+ if (!WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, len, NULL, FALSE))
+ die("WideCharToMultiByte failed!");
+
+ printf("%s=", what);
+ fwrite(buf, 1, len - 1, stdout);
+ putchar('\n');
+ free(buf);
+}
+
+static int match_attr(const CREDENTIALW *cred, const WCHAR *keyword,
+ const char *want)
+{
+ int i;
+ if (!want)
+ return 1;
+
+ for (i = 0; i < cred->AttributeCount; ++i)
+ if (!wcscmp(cred->Attributes[i].Keyword, keyword))
+ return !strcmp((const char *)cred->Attributes[i].Value,
+ want);
+
+ return 0; /* not found */
+}
+
+static int match_cred(const CREDENTIALW *cred)
+{
+ return (!wusername || !wcscmp(wusername, cred->UserName)) &&
+ match_attr(cred, L"git_protocol", protocol) &&
+ match_attr(cred, L"git_host", host) &&
+ match_attr(cred, L"git_path", path);
+}
+
+static void get_credential(void)
+{
+ WCHAR *user_buf, *pass_buf;
+ DWORD user_buf_size = 0, pass_buf_size = 0;
+ CREDENTIALW **creds, *cred = NULL;
+ DWORD num_creds;
+ int i;
+
+ if (!CredEnumerateW(L"git:*", 0, &num_creds, &creds))
+ return;
+
+ /* search for the first credential that matches username */
+ for (i = 0; i < num_creds; ++i)
+ if (match_cred(creds[i])) {
+ cred = creds[i];
+ break;
+ }
+ if (!cred)
+ return;
+
+ CredUnPackAuthenticationBufferW(0, cred->CredentialBlob,
+ cred->CredentialBlobSize, NULL, &user_buf_size, NULL, NULL,
+ NULL, &pass_buf_size);
+
+ user_buf = xmalloc(user_buf_size * sizeof(WCHAR));
+ pass_buf = xmalloc(pass_buf_size * sizeof(WCHAR));
+
+ if (!CredUnPackAuthenticationBufferW(0, cred->CredentialBlob,
+ cred->CredentialBlobSize, user_buf, &user_buf_size, NULL, NULL,
+ pass_buf, &pass_buf_size))
+ die("CredUnPackAuthenticationBuffer failed");
+
+ CredFree(creds);
+
+ /* zero-terminate (sizes include zero-termination) */
+ user_buf[user_buf_size - 1] = L'\0';
+ pass_buf[pass_buf_size - 1] = L'\0';
+
+ write_item("username", user_buf);
+ write_item("password", pass_buf);
+
+ free(user_buf);
+ free(pass_buf);
+}
+
+static void write_attr(CREDENTIAL_ATTRIBUTEW *attr, const WCHAR *keyword,
+ const char *value)
+{
+ attr->Keyword = (LPWSTR)keyword;
+ attr->Flags = 0;
+ attr->ValueSize = strlen(value) + 1; /* store zero-termination */
+ attr->Value = (LPBYTE)value;
+}
+
+static void store_credential(void)
+{
+ CREDENTIALW cred;
+ BYTE *auth_buf;
+ DWORD auth_buf_size = 0;
+ CREDENTIAL_ATTRIBUTEW attrs[CRED_MAX_ATTRIBUTES];
+
+ if (!wusername || !password)
+ return;
+
+ /* query buffer size */
+ CredPackAuthenticationBufferW(0, wusername, password,
+ NULL, &auth_buf_size);
+
+ auth_buf = xmalloc(auth_buf_size);
+
+ if (!CredPackAuthenticationBufferW(0, wusername, password,
+ auth_buf, &auth_buf_size))
+ die("CredPackAuthenticationBuffer failed");
+
+ cred.Flags = 0;
+ cred.Type = CRED_TYPE_GENERIC;
+ cred.TargetName = target;
+ cred.Comment = L"saved by git-credential-wincred";
+ cred.CredentialBlobSize = auth_buf_size;
+ cred.CredentialBlob = auth_buf;
+ cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
+ cred.AttributeCount = 1;
+ cred.Attributes = attrs;
+ cred.TargetAlias = NULL;
+ cred.UserName = wusername;
+
+ write_attr(attrs, L"git_protocol", protocol);
+
+ if (host) {
+ write_attr(attrs + cred.AttributeCount, L"git_host", host);
+ cred.AttributeCount++;
+ }
+
+ if (path) {
+ write_attr(attrs + cred.AttributeCount, L"git_path", path);
+ cred.AttributeCount++;
+ }
+
+ if (!CredWriteW(&cred, 0))
+ die("CredWrite failed");
+}
+
+static void erase_credential(void)
+{
+ CREDENTIALW **creds;
+ DWORD num_creds;
+ int i;
+
+ if (!CredEnumerateW(L"git:*", 0, &num_creds, &creds))
+ return;
+
+ for (i = 0; i < num_creds; ++i) {
+ if (match_cred(creds[i]))
+ CredDeleteW(creds[i]->TargetName, creds[i]->Type, 0);
+ }
+
+ CredFree(creds);
+}
+
+static WCHAR *utf8_to_utf16_dup(const char *str)
+{
+ int wlen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
+ WCHAR *wstr = xmalloc(sizeof(WCHAR) * wlen);
+ MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, wlen);
+ return wstr;
+}
+
+static void read_credential(void)
+{
+ char buf[1024];
+
+ while (fgets(buf, sizeof(buf), stdin)) {
+ char *v;
+
+ if (!strcmp(buf, "\n"))
+ break;
+ buf[strlen(buf)-1] = '\0';
+
+ v = strchr(buf, '=');
+ if (!v)
+ die("bad input: %s", buf);
+ *v++ = '\0';
+
+ if (!strcmp(buf, "protocol"))
+ protocol = xstrdup(v);
+ else if (!strcmp(buf, "host"))
+ host = xstrdup(v);
+ else if (!strcmp(buf, "path"))
+ path = xstrdup(v);
+ else if (!strcmp(buf, "username")) {
+ username = xstrdup(v);
+ wusername = utf8_to_utf16_dup(v);
+ } else if (!strcmp(buf, "password"))
+ password = utf8_to_utf16_dup(v);
+ else
+ die("unrecognized input");
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ const char *usage =
+ "Usage: git credential-wincred <get|store|erase>\n";
+
+ if (!argv[1])
+ die(usage);
+
+ /* git use binary pipes to avoid CRLF-issues */
+ _setmode(_fileno(stdin), _O_BINARY);
+ _setmode(_fileno(stdout), _O_BINARY);
+
+ read_credential();
+
+ load_cred_funcs();
+
+ if (!protocol || !(host || path))
+ return 0;
+
+ /* prepare 'target', the unique key for the credential */
+ strncat(target_buf, "git:", sizeof(target_buf));
+ strncat(target_buf, protocol, sizeof(target_buf));
+ strncat(target_buf, "://", sizeof(target_buf));
+ if (username) {
+ strncat(target_buf, username, sizeof(target_buf));
+ strncat(target_buf, "@", sizeof(target_buf));
+ }
+ if (host)
+ strncat(target_buf, host, sizeof(target_buf));
+ if (path) {
+ strncat(target_buf, "/", sizeof(target_buf));
+ strncat(target_buf, path, sizeof(target_buf));
+ }
+
+ target = utf8_to_utf16_dup(target_buf);
+
+ if (!strcmp(argv[1], "get"))
+ get_credential();
+ else if (!strcmp(argv[1], "store"))
+ store_credential();
+ else if (!strcmp(argv[1], "erase"))
+ erase_credential();
+ /* otherwise, ignore unknown action */
+ return 0;
+}
diff --git a/contrib/examples/builtin-fetch--tool.c b/contrib/examples/builtin-fetch--tool.c
index 0d54aa7..8bc8c75 100644
--- a/contrib/examples/builtin-fetch--tool.c
+++ b/contrib/examples/builtin-fetch--tool.c
@@ -96,7 +96,7 @@ static int update_local_ref(const char *name,
strcpy(oldh, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
strcpy(newh, find_unique_abbrev(sha1_new, DEFAULT_ABBREV));
- if (in_merge_bases(current, &updated, 1)) {
+ if (in_merge_bases(current, updated)) {
fprintf(stderr, "* %s: fast-forward to %s\n",
name, note);
fprintf(stderr, " old..new: %s..%s\n", oldh, newh);
diff --git a/daemon.c b/daemon.c
index ab21e66..4602b46 100644
--- a/daemon.c
+++ b/daemon.c
@@ -30,6 +30,7 @@ static const char daemon_usage[] =
" [--interpolated-path=<path>]\n"
" [--reuseaddr] [--pid-file=<file>]\n"
" [--(enable|disable|allow-override|forbid-override)=<service>]\n"
+" [--access-hook=<path>]\n"
" [--inetd | [--listen=<host_or_ipaddr>] [--port=<n>]\n"
" [--detach] [--user=<user> [--group=<group>]]\n"
" [<directory>...]";
@@ -256,6 +257,71 @@ static int daemon_error(const char *dir, const char *msg)
return -1;
}
+static char *access_hook;
+
+static int run_access_hook(struct daemon_service *service, const char *dir, const char *path)
+{
+ struct child_process child;
+ struct strbuf buf = STRBUF_INIT;
+ const char *argv[8];
+ const char **arg = argv;
+ char *eol;
+ int seen_errors = 0;
+
+#define STRARG(x) ((x) ? (x) : "")
+ *arg++ = access_hook;
+ *arg++ = service->name;
+ *arg++ = path;
+ *arg++ = STRARG(hostname);
+ *arg++ = STRARG(canon_hostname);
+ *arg++ = STRARG(ip_address);
+ *arg++ = STRARG(tcp_port);
+ *arg = NULL;
+#undef STRARG
+
+ memset(&child, 0, sizeof(child));
+ child.use_shell = 1;
+ child.argv = argv;
+ child.no_stdin = 1;
+ child.no_stderr = 1;
+ child.out = -1;
+ if (start_command(&child)) {
+ logerror("daemon access hook '%s' failed to start",
+ access_hook);
+ goto error_return;
+ }
+ if (strbuf_read(&buf, child.out, 0) < 0) {
+ logerror("failed to read from pipe to daemon access hook '%s'",
+ access_hook);
+ strbuf_reset(&buf);
+ seen_errors = 1;
+ }
+ if (close(child.out) < 0) {
+ logerror("failed to close pipe to daemon access hook '%s'",
+ access_hook);
+ seen_errors = 1;
+ }
+ if (finish_command(&child))
+ seen_errors = 1;
+
+ if (!seen_errors) {
+ strbuf_release(&buf);
+ return 0;
+ }
+
+error_return:
+ strbuf_ltrim(&buf);
+ if (!buf.len)
+ strbuf_addstr(&buf, "service rejected");
+ eol = strchr(buf.buf, '\n');
+ if (eol)
+ *eol = '\0';
+ errno = EACCES;
+ daemon_error(dir, buf.buf);
+ strbuf_release(&buf);
+ return -1;
+}
+
static int run_service(char *dir, struct daemon_service *service)
{
const char *path;
@@ -304,6 +370,13 @@ static int run_service(char *dir, struct daemon_service *service)
}
/*
+ * Optionally, a hook can choose to deny access to the
+ * repository depending on the phase of the moon.
+ */
+ if (access_hook && run_access_hook(service, dir, path))
+ return -1;
+
+ /*
* We'll ignore SIGTERM from now on, we have a
* good client.
*/
@@ -1142,6 +1215,10 @@ int main(int argc, char **argv)
export_all_trees = 1;
continue;
}
+ if (!prefixcmp(arg, "--access-hook=")) {
+ access_hook = arg + 14;
+ continue;
+ }
if (!prefixcmp(arg, "--timeout=")) {
timeout = atoi(arg+10);
continue;
diff --git a/diff.c b/diff.c
index 32142db..35d3f07 100644
--- a/diff.c
+++ b/diff.c
@@ -25,7 +25,7 @@
static int diff_detect_rename_default;
static int diff_rename_limit_default = 400;
static int diff_suppress_blank_empty;
-int diff_use_color_default = -1;
+static int diff_use_color_default = -1;
static const char *diff_word_regex_cfg;
static const char *external_diff_cmd_cfg;
int diff_auto_refresh_index = 1;
diff --git a/diff.h b/diff.h
index e25addb..a658f85 100644
--- a/diff.h
+++ b/diff.h
@@ -243,7 +243,6 @@ extern int parse_long_opt(const char *opt, const char **argv,
extern int git_diff_basic_config(const char *var, const char *value, void *cb);
extern int git_diff_ui_config(const char *var, const char *value, void *cb);
-extern int diff_use_color_default;
extern void diff_setup(struct diff_options *);
extern int diff_opt_parse(struct diff_options *, const char **, int);
extern void diff_setup_done(struct diff_options *);
diff --git a/fast-import.c b/fast-import.c
index eed97c8..c2a814e 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1691,7 +1691,7 @@ static int update_branch(struct branch *b)
return error("Branch %s is missing commits.", b->name);
}
- if (!in_merge_bases(old_cmit, &new_cmit, 1)) {
+ if (!in_merge_bases(old_cmit, new_cmit)) {
unlock_ref(lock);
warning("Not updating %s"
" (new tip %s does not contain %s)",
diff --git a/fetch-pack.h b/fetch-pack.h
index 7c2069c..cb14871 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -1,6 +1,8 @@
#ifndef FETCH_PACK_H
#define FETCH_PACK_H
+#include "string-list.h"
+
struct fetch_pack_args {
const char *uploadpack;
int unpacklimit;
@@ -17,12 +19,18 @@ struct fetch_pack_args {
stateless_rpc:1;
};
+/*
+ * sought contains the full names of remote references that should be
+ * updated from. On return, the names that were found on the remote
+ * will have been removed from the list. The util members of the
+ * string_list_items are used internally; they must be NULL on entry
+ * (and will be NULL on exit).
+ */
struct ref *fetch_pack(struct fetch_pack_args *args,
- int fd[], struct child_process *conn,
- const struct ref *ref,
- const char *dest,
- int nr_heads,
- char **heads,
- char **pack_lockfile);
+ int fd[], struct child_process *conn,
+ const struct ref *ref,
+ const char *dest,
+ struct string_list *sought,
+ char **pack_lockfile);
#endif
diff --git a/gettext.c b/gettext.c
index f75bca7..71e9545 100644
--- a/gettext.c
+++ b/gettext.c
@@ -4,6 +4,8 @@
#include "git-compat-util.h"
#include "gettext.h"
+#include "strbuf.h"
+#include "utf8.h"
#ifndef NO_GETTEXT
# include <locale.h>
@@ -27,10 +29,9 @@ int use_gettext_poison(void)
#endif
#ifndef NO_GETTEXT
+static const char *charset;
static void init_gettext_charset(const char *domain)
{
- const char *charset;
-
/*
This trick arranges for messages to be emitted in the user's
requested encoding, but avoids setting LC_CTYPE from the
@@ -128,4 +129,14 @@ void git_setup_gettext(void)
init_gettext_charset("git");
textdomain("git");
}
+
+/* return the number of columns of string 's' in current locale */
+int gettext_width(const char *s)
+{
+ static int is_utf8 = -1;
+ if (is_utf8 == -1)
+ is_utf8 = !strcmp(charset, "UTF-8");
+
+ return is_utf8 ? utf8_strwidth(s) : strlen(s);
+}
#endif
diff --git a/gettext.h b/gettext.h
index 57ba8bb..7671d09 100644
--- a/gettext.h
+++ b/gettext.h
@@ -30,10 +30,15 @@
#ifndef NO_GETTEXT
extern void git_setup_gettext(void);
+extern int gettext_width(const char *s);
#else
static inline void git_setup_gettext(void)
{
}
+static inline int gettext_width(const char *s)
+{
+ return strlen(s);
+}
#endif
#ifdef GETTEXT_POISON
@@ -44,6 +49,8 @@ extern int use_gettext_poison(void);
static inline FORMAT_PRESERVING(1) const char *_(const char *msgid)
{
+ if (!*msgid)
+ return "";
return use_gettext_poison() ? "# GETTEXT POISON #" : gettext(msgid);
}
diff --git a/git-am.sh b/git-am.sh
index bd9620c..c682d34 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -855,8 +855,8 @@ did you forget to use 'git add'?"
eval_gettextln 'Patch failed at $msgnum $FIRSTLINE'
if test "$(git config --bool advice.amworkdir)" != false
then
- eval_gettextln "The copy of the patch that failed is found in:
- $dotest/patch"
+ eval_gettextln 'The copy of the patch that failed is found in:
+ $dotest/patch'
fi
stop_here_user_resolve $this
fi
diff --git a/git-compat-util.h b/git-compat-util.h
index 000042d..2fbf1fd 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -74,7 +74,8 @@
# define _XOPEN_SOURCE 500
# endif
#elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && \
- !defined(_M_UNIX) && !defined(__sgi) && !defined(__DragonFly__)
+ !defined(_M_UNIX) && !defined(__sgi) && !defined(__DragonFly__) && \
+ !defined(__TANDEM)
#define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
#define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
#endif
@@ -98,6 +99,9 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
+#ifdef __TANDEM /* or HAVE_STRINGS_H or !NO_STRINGS_H? */
+#include <strings.h> /* for strcasecmp() */
+#endif
#include <errno.h>
#include <limits.h>
#include <sys/param.h>
@@ -141,6 +145,17 @@
#else
#include <stdint.h>
#endif
+#ifdef NO_INTPTR_T
+/*
+ * On I16LP32, ILP32 and LP64 "long" is the save bet, however
+ * on LLP86, IL33LLP64 and P64 it needs to be "long long",
+ * while on IP16 and IP16L32 it is "int" (resp. "short")
+ * Size needs to match (or exceed) 'sizeof(void *)'.
+ * We can't take "long long" here as not everybody has it.
+ */
+typedef long intptr_t;
+typedef unsigned long uintptr_t;
+#endif
#if defined(__CYGWIN__)
#undef _XOPEN_SOURCE
#include <grp.h>
@@ -162,6 +177,22 @@
#define probe_utf8_pathname_composition(a,b)
#endif
+#ifdef MKDIR_WO_TRAILING_SLASH
+#define mkdir(a,b) compat_mkdir_wo_trailing_slash((a),(b))
+extern int compat_mkdir_wo_trailing_slash(const char*, mode_t);
+#endif
+
+#ifdef NO_STRUCT_ITIMERVAL
+struct itimerval {
+ struct timeval it_interval;
+ struct timeval it_value;
+}
+#endif
+
+#ifdef NO_SETITIMER
+#define setitimer(which,value,ovalue)
+#endif
+
#ifndef NO_LIBGEN_H
#include <libgen.h>
#else
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 8d41610..8032f23 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -889,10 +889,37 @@ sub commit {
$xtag =~ s/\s+\*\*.*$//; # Remove stuff like ** INVALID ** and ** FUNKY **
$xtag =~ tr/_/\./ if ( $opt_u );
$xtag =~ s/[\/]/$opt_s/g;
- $xtag =~ s/\[//g;
- system('git' , 'tag', '-f', $xtag, $cid) == 0
- or die "Cannot create tag $xtag: $!\n";
+ # See refs.c for these rules.
+ # Tag cannot contain bad chars. (See bad_ref_char in refs.c.)
+ $xtag =~ s/[ ~\^:\\\*\?\[]//g;
+ # Other bad strings for tags:
+ # (See check_refname_component in refs.c.)
+ 1 while $xtag =~ s/
+ (?: \.\. # Tag cannot contain '..'.
+ | \@{ # Tag cannot contain '@{'.
+ | ^ - # Tag cannot begin with '-'.
+ | \.lock $ # Tag cannot end with '.lock'.
+ | ^ \. # Tag cannot begin...
+ | \. $ # ...or end with '.'
+ )//xg;
+ # Tag cannot be empty.
+ if ($xtag eq '') {
+ warn("warning: ignoring tag '$tag'",
+ " with invalid tagname\n");
+ return;
+ }
+
+ if (system('git' , 'tag', '-f', $xtag, $cid) != 0) {
+ # We did our best to sanitize the tag, but still failed
+ # for whatever reason. Bail out, and give the user
+ # enough information to understand if/how we should
+ # improve the translation in the future.
+ if ($tag ne $xtag) {
+ print "Translated '$tag' tag to '$xtag'\n";
+ }
+ die "Cannot create tag $xtag: $!\n";
+ }
print "Created tag '$xtag' on '$branch'\n" if $opt_v;
}
diff --git a/git-difftool.perl b/git-difftool.perl
index c079854..edd0493 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -18,17 +18,11 @@ use File::Copy;
use File::Compare;
use File::Find;
use File::stat;
-use File::Path qw(mkpath);
+use File::Path qw(mkpath rmtree);
use File::Temp qw(tempdir);
use Getopt::Long qw(:config pass_through);
use Git;
-my @tools;
-my @working_tree;
-my $rc;
-my $repo = Git->repository();
-my $repo_path = $repo->repo_path();
-
sub usage
{
my $exitcode = shift;
@@ -45,6 +39,8 @@ USAGE
sub find_worktree
{
+ my ($repo) = @_;
+
# Git->repository->wc_path() does not honor changes to the working
# tree location made by $ENV{GIT_WORK_TREE} or the 'core.worktree'
# config variable.
@@ -63,10 +59,9 @@ sub find_worktree
return $worktree;
}
-my $workdir = find_worktree();
-
sub filter_tool_scripts
{
+ my ($tools) = @_;
if (-d $_) {
if ($_ ne ".") {
# Ignore files in subdirectories
@@ -74,17 +69,17 @@ sub filter_tool_scripts
}
} else {
if ((-f $_) && ($_ ne "defaults")) {
- push(@tools, $_);
+ push(@$tools, $_);
}
}
}
sub print_tool_help
{
- my ($cmd, @found, @notfound);
+ my ($cmd, @found, @notfound, @tools);
my $gitpath = Git::exec_path();
- find(\&filter_tool_scripts, "$gitpath/mergetools");
+ find(sub { filter_tool_scripts(\@tools) }, "$gitpath/mergetools");
foreach my $tool (@tools) {
$cmd = "TOOL_MODE=diff";
@@ -98,34 +93,52 @@ sub print_tool_help
}
}
- print "'git difftool --tool=<tool>' may be set to one of the following:\n";
+ print << 'EOF';
+'git difftool --tool=<tool>' may be set to one of the following:
+EOF
print "\t$_\n" for (sort(@found));
- print "\nThe following tools are valid, but not currently available:\n";
+ print << 'EOF';
+
+The following tools are valid, but not currently available:
+EOF
print "\t$_\n" for (sort(@notfound));
- print "\nNOTE: Some of the tools listed above only work in a windowed\n";
- print "environment. If run in a terminal-only session, they will fail.\n";
+ print << 'EOF';
+NOTE: Some of the tools listed above only work in a windowed
+environment. If run in a terminal-only session, they will fail.
+EOF
exit(0);
}
+sub exit_cleanup
+{
+ my ($tmpdir, $status) = @_;
+ my $errno = $!;
+ rmtree($tmpdir);
+ if ($status and $errno) {
+ my ($package, $file, $line) = caller();
+ warn "$file line $line: $errno\n";
+ }
+ exit($status | ($status >> 8));
+}
+
sub setup_dir_diff
{
+ my ($repo, $workdir, $symlinks) = @_;
+
# Run the diff; exit immediately if no diff found
# 'Repository' and 'WorkingCopy' must be explicitly set to insure that
# if $GIT_DIR and $GIT_WORK_TREE are set in ENV, they are actually used
# by Git->repository->command*.
- my $diffrepo = Git->repository(Repository => $repo_path, WorkingCopy => $workdir);
- my $diffrtn = $diffrepo->command_oneline('diff', '--raw', '--no-abbrev', '-z', @ARGV);
- exit(0) if (length($diffrtn) == 0);
+ my $repo_path = $repo->repo_path();
+ my %repo_args = (Repository => $repo_path, WorkingCopy => $workdir);
+ my $diffrepo = Git->repository(%repo_args);
- # Setup temp directories
- my $tmpdir = tempdir('git-diffall.XXXXX', CLEANUP => 1, TMPDIR => 1);
- my $ldir = "$tmpdir/left";
- my $rdir = "$tmpdir/right";
- mkpath($ldir) or die $!;
- mkpath($rdir) or die $!;
+ my @gitargs = ('diff', '--raw', '--no-abbrev', '-z', @ARGV);
+ my $diffrtn = $diffrepo->command_oneline(@gitargs);
+ exit(0) unless defined($diffrtn);
# Build index info for left and right sides of the diff
my $submodule_mode = '160000';
@@ -136,16 +149,21 @@ sub setup_dir_diff
my $rindex = '';
my %submodule;
my %symlink;
+ my @working_tree = ();
my @rawdiff = split('\0', $diffrtn);
my $i = 0;
while ($i < $#rawdiff) {
if ($rawdiff[$i] =~ /^::/) {
- print "Combined diff formats ('-c' and '--cc') are not supported in directory diff mode.\n";
+ warn << 'EOF';
+Combined diff formats ('-c' and '--cc') are not supported in
+directory diff mode ('-d' and '--dir-diff').
+EOF
exit(1);
}
- my ($lmode, $rmode, $lsha1, $rsha1, $status) = split(' ', substr($rawdiff[$i], 1));
+ my ($lmode, $rmode, $lsha1, $rsha1, $status) =
+ split(' ', substr($rawdiff[$i], 1));
my $src_path = $rawdiff[$i + 1];
my $dst_path;
@@ -157,7 +175,7 @@ sub setup_dir_diff
$i += 2;
}
- if (($lmode eq $submodule_mode) or ($rmode eq $submodule_mode)) {
+ if ($lmode eq $submodule_mode or $rmode eq $submodule_mode) {
$submodule{$src_path}{left} = $lsha1;
if ($lsha1 ne $rsha1) {
$submodule{$dst_path}{right} = $rsha1;
@@ -168,14 +186,16 @@ sub setup_dir_diff
}
if ($lmode eq $symlink_mode) {
- $symlink{$src_path}{left} = $diffrepo->command_oneline('show', "$lsha1");
+ $symlink{$src_path}{left} =
+ $diffrepo->command_oneline('show', "$lsha1");
}
if ($rmode eq $symlink_mode) {
- $symlink{$dst_path}{right} = $diffrepo->command_oneline('show', "$rsha1");
+ $symlink{$dst_path}{right} =
+ $diffrepo->command_oneline('show', "$rsha1");
}
- if (($lmode ne $null_mode) and ($status !~ /^C/)) {
+ if ($lmode ne $null_mode and $status !~ /^C/) {
$lindex .= "$lmode $lsha1\t$src_path\0";
}
@@ -188,6 +208,13 @@ sub setup_dir_diff
}
}
+ # Setup temp directories
+ my $tmpdir = tempdir('git-difftool.XXXXX', CLEANUP => 0, TMPDIR => 1);
+ my $ldir = "$tmpdir/left";
+ my $rdir = "$tmpdir/right";
+ mkpath($ldir) or exit_cleanup($tmpdir, 1);
+ mkpath($rdir) or exit_cleanup($tmpdir, 1);
+
# If $GIT_DIR is not set prior to calling 'git update-index' and
# 'git checkout-index', then those commands will fail if difftool
# is called from a directory other than the repo root.
@@ -200,18 +227,22 @@ sub setup_dir_diff
# Populate the left and right directories based on each index file
my ($inpipe, $ctx);
$ENV{GIT_INDEX_FILE} = "$tmpdir/lindex";
- ($inpipe, $ctx) = $repo->command_input_pipe(qw/update-index -z --index-info/);
+ ($inpipe, $ctx) =
+ $repo->command_input_pipe(qw(update-index -z --index-info));
print($inpipe $lindex);
$repo->command_close_pipe($inpipe, $ctx);
- $rc = system('git', 'checkout-index', '--all', "--prefix=$ldir/");
- exit($rc | ($rc >> 8)) if ($rc != 0);
+
+ my $rc = system('git', 'checkout-index', '--all', "--prefix=$ldir/");
+ exit_cleanup($tmpdir, $rc) if $rc != 0;
$ENV{GIT_INDEX_FILE} = "$tmpdir/rindex";
- ($inpipe, $ctx) = $repo->command_input_pipe(qw/update-index -z --index-info/);
+ ($inpipe, $ctx) =
+ $repo->command_input_pipe(qw(update-index -z --index-info));
print($inpipe $rindex);
$repo->command_close_pipe($inpipe, $ctx);
+
$rc = system('git', 'checkout-index', '--all', "--prefix=$rdir/");
- exit($rc | ($rc >> 8)) if ($rc != 0);
+ exit_cleanup($tmpdir, $rc) if $rc != 0;
# If $GIT_DIR was explicitly set just for the update/checkout
# commands, then it should be unset before continuing.
@@ -223,37 +254,55 @@ sub setup_dir_diff
for my $file (@working_tree) {
my $dir = dirname($file);
unless (-d "$rdir/$dir") {
- mkpath("$rdir/$dir") or die $!;
+ mkpath("$rdir/$dir") or
+ exit_cleanup($tmpdir, 1);
+ }
+ if ($symlinks) {
+ symlink("$workdir/$file", "$rdir/$file") or
+ exit_cleanup($tmpdir, 1);
+ } else {
+ copy("$workdir/$file", "$rdir/$file") or
+ exit_cleanup($tmpdir, 1);
+
+ my $mode = stat("$workdir/$file")->mode;
+ chmod($mode, "$rdir/$file") or
+ exit_cleanup($tmpdir, 1);
}
- copy("$workdir/$file", "$rdir/$file") or die $!;
- chmod(stat("$workdir/$file")->mode, "$rdir/$file") or die $!;
}
# Changes to submodules require special treatment. This loop writes a
# temporary file to both the left and right directories to show the
# change in the recorded SHA1 for the submodule.
for my $path (keys %submodule) {
+ my $ok;
if (defined($submodule{$path}{left})) {
- write_to_file("$ldir/$path", "Subproject commit $submodule{$path}{left}");
+ $ok = write_to_file("$ldir/$path",
+ "Subproject commit $submodule{$path}{left}");
}
if (defined($submodule{$path}{right})) {
- write_to_file("$rdir/$path", "Subproject commit $submodule{$path}{right}");
+ $ok = write_to_file("$rdir/$path",
+ "Subproject commit $submodule{$path}{right}");
}
+ exit_cleanup($tmpdir, 1) if not $ok;
}
# Symbolic links require special treatment. The standard "git diff"
# shows only the link itself, not the contents of the link target.
# This loop replicates that behavior.
for my $path (keys %symlink) {
+ my $ok;
if (defined($symlink{$path}{left})) {
- write_to_file("$ldir/$path", $symlink{$path}{left});
+ $ok = write_to_file("$ldir/$path",
+ $symlink{$path}{left});
}
if (defined($symlink{$path}{right})) {
- write_to_file("$rdir/$path", $symlink{$path}{right});
+ $ok = write_to_file("$rdir/$path",
+ $symlink{$path}{right});
}
+ exit_cleanup($tmpdir, 1) if not $ok;
}
- return ($ldir, $rdir);
+ return ($ldir, $rdir, $tmpdir, @working_tree);
}
sub write_to_file
@@ -264,85 +313,141 @@ sub write_to_file
# Make sure the path to the file exists
my $dir = dirname($path);
unless (-d "$dir") {
- mkpath("$dir") or die $!;
+ mkpath("$dir") or return 0;
}
# If the file already exists in that location, delete it. This
# is required in the case of symbolic links.
- unlink("$path");
+ unlink($path);
- open(my $fh, '>', "$path") or die $!;
+ open(my $fh, '>', $path) or return 0;
print($fh $value);
close($fh);
-}
-# parse command-line options. all unrecognized options and arguments
-# are passed through to the 'git diff' command.
-my ($difftool_cmd, $dirdiff, $extcmd, $gui, $help, $prompt, $tool_help);
-GetOptions('g|gui!' => \$gui,
- 'd|dir-diff' => \$dirdiff,
- 'h' => \$help,
- 'prompt!' => \$prompt,
- 'y' => sub { $prompt = 0; },
- 't|tool:s' => \$difftool_cmd,
- 'tool-help' => \$tool_help,
- 'x|extcmd:s' => \$extcmd);
-
-if (defined($help)) {
- usage(0);
-}
-if (defined($tool_help)) {
- print_tool_help();
+ return 1;
}
-if (defined($difftool_cmd)) {
- if (length($difftool_cmd) > 0) {
- $ENV{GIT_DIFF_TOOL} = $difftool_cmd;
- } else {
- print "No <tool> given for --tool=<tool>\n";
- usage(1);
+
+sub main
+{
+ # parse command-line options. all unrecognized options and arguments
+ # are passed through to the 'git diff' command.
+ my %opts = (
+ difftool_cmd => undef,
+ dirdiff => undef,
+ extcmd => undef,
+ gui => undef,
+ help => undef,
+ prompt => undef,
+ symlinks => $^O ne 'cygwin' &&
+ $^O ne 'MSWin32' && $^O ne 'msys',
+ tool_help => undef,
+ );
+ GetOptions('g|gui!' => \$opts{gui},
+ 'd|dir-diff' => \$opts{dirdiff},
+ 'h' => \$opts{help},
+ 'prompt!' => \$opts{prompt},
+ 'y' => sub { $opts{prompt} = 0; },
+ 'symlinks' => \$opts{symlinks},
+ 'no-symlinks' => sub { $opts{symlinks} = 0; },
+ 't|tool:s' => \$opts{difftool_cmd},
+ 'tool-help' => \$opts{tool_help},
+ 'x|extcmd:s' => \$opts{extcmd});
+
+ if (defined($opts{help})) {
+ usage(0);
}
-}
-if (defined($extcmd)) {
- if (length($extcmd) > 0) {
- $ENV{GIT_DIFFTOOL_EXTCMD} = $extcmd;
- } else {
- print "No <cmd> given for --extcmd=<cmd>\n";
- usage(1);
+ if (defined($opts{tool_help})) {
+ print_tool_help();
}
-}
-if ($gui) {
- my $guitool = '';
- $guitool = Git::config('diff.guitool');
- if (length($guitool) > 0) {
- $ENV{GIT_DIFF_TOOL} = $guitool;
+ if (defined($opts{difftool_cmd})) {
+ if (length($opts{difftool_cmd}) > 0) {
+ $ENV{GIT_DIFF_TOOL} = $opts{difftool_cmd};
+ } else {
+ print "No <tool> given for --tool=<tool>\n";
+ usage(1);
+ }
+ }
+ if (defined($opts{extcmd})) {
+ if (length($opts{extcmd}) > 0) {
+ $ENV{GIT_DIFFTOOL_EXTCMD} = $opts{extcmd};
+ } else {
+ print "No <cmd> given for --extcmd=<cmd>\n";
+ usage(1);
+ }
+ }
+ if ($opts{gui}) {
+ my $guitool = Git::config('diff.guitool');
+ if (length($guitool) > 0) {
+ $ENV{GIT_DIFF_TOOL} = $guitool;
+ }
+ }
+
+ # In directory diff mode, 'git-difftool--helper' is called once
+ # to compare the a/b directories. In file diff mode, 'git diff'
+ # will invoke a separate instance of 'git-difftool--helper' for
+ # each file that changed.
+ if (defined($opts{dirdiff})) {
+ dir_diff($opts{extcmd}, $opts{symlinks});
+ } else {
+ file_diff($opts{prompt});
}
}
-# In directory diff mode, 'git-difftool--helper' is called once
-# to compare the a/b directories. In file diff mode, 'git diff'
-# will invoke a separate instance of 'git-difftool--helper' for
-# each file that changed.
-if (defined($dirdiff)) {
- my ($a, $b) = setup_dir_diff();
+sub dir_diff
+{
+ my ($extcmd, $symlinks) = @_;
+ my $rc;
+ my $error = 0;
+ my $repo = Git->repository();
+ my $workdir = find_worktree($repo);
+ my ($a, $b, $tmpdir, @worktree) =
+ setup_dir_diff($repo, $workdir, $symlinks);
+
if (defined($extcmd)) {
$rc = system($extcmd, $a, $b);
} else {
$ENV{GIT_DIFFTOOL_DIRDIFF} = 'true';
$rc = system('git', 'difftool--helper', $a, $b);
}
-
- exit($rc | ($rc >> 8)) if ($rc != 0);
-
# If the diff including working copy files and those
# files were modified during the diff, then the changes
- # should be copied back to the working tree
- for my $file (@working_tree) {
- if (-e "$b/$file" && compare("$b/$file", "$workdir/$file")) {
- copy("$b/$file", "$workdir/$file") or die $!;
- chmod(stat("$b/$file")->mode, "$workdir/$file") or die $!;
+ # should be copied back to the working tree.
+ # Do not copy back files when symlinks are used and the
+ # external tool did not replace the original link with a file.
+ for my $file (@worktree) {
+ next if $symlinks && -l "$b/$file";
+ next if ! -f "$b/$file";
+
+ my $diff = compare("$b/$file", "$workdir/$file");
+ if ($diff == 0) {
+ next;
+ } elsif ($diff == -1) {
+ my $errmsg = "warning: Could not compare ";
+ $errmsg += "'$b/$file' with '$workdir/$file'\n";
+ warn $errmsg;
+ $error = 1;
+ } elsif ($diff == 1) {
+ my $mode = stat("$b/$file")->mode;
+ copy("$b/$file", "$workdir/$file") or
+ exit_cleanup($tmpdir, 1);
+
+ chmod($mode, "$workdir/$file") or
+ exit_cleanup($tmpdir, 1);
}
}
-} else {
+ if ($error) {
+ warn "warning: Temporary files exist in '$tmpdir'.\n";
+ warn "warning: You may want to cleanup or recover these.\n";
+ exit(1);
+ } else {
+ exit_cleanup($tmpdir, $rc);
+ }
+}
+
+sub file_diff
+{
+ my ($prompt) = @_;
+
if (defined($prompt)) {
if ($prompt) {
$ENV{GIT_DIFFTOOL_PROMPT} = 'true';
@@ -362,3 +467,5 @@ if (defined($dirdiff)) {
my $rc = system('git', 'diff', @ARGV);
exit($rc | ($rc >> 8));
}
+
+main();
diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh
index f730253..f013a03 100644
--- a/git-mergetool--lib.sh
+++ b/git-mergetool--lib.sh
@@ -104,13 +104,49 @@ run_merge_tool () {
if merge_mode
then
- merge_cmd "$1"
+ run_merge_cmd "$1"
else
- diff_cmd "$1"
+ run_diff_cmd "$1"
fi
return $status
}
+# Run a either a configured or built-in diff tool
+run_diff_cmd () {
+ merge_tool_cmd="$(get_merge_tool_cmd "$1")"
+ if test -n "$merge_tool_cmd"
+ then
+ ( eval $merge_tool_cmd )
+ status=$?
+ return $status
+ else
+ diff_cmd "$1"
+ fi
+}
+
+# Run a either a configured or built-in merge tool
+run_merge_cmd () {
+ merge_tool_cmd="$(get_merge_tool_cmd "$1")"
+ if test -n "$merge_tool_cmd"
+ then
+ trust_exit_code="$(git config --bool \
+ mergetool."$1".trustExitCode || echo false)"
+ if test "$trust_exit_code" = "false"
+ then
+ touch "$BACKUP"
+ ( eval $merge_tool_cmd )
+ status=$?
+ check_unchanged
+ else
+ ( eval $merge_tool_cmd )
+ status=$?
+ fi
+ return $status
+ else
+ merge_cmd "$1"
+ fi
+}
+
list_merge_tool_candidates () {
if merge_mode
then
@@ -126,7 +162,7 @@ list_merge_tool_candidates () {
else
tools="opendiff kdiff3 tkdiff xxdiff meld $tools"
fi
- tools="$tools gvimdiff diffuse ecmerge p4merge araxis bc3"
+ tools="$tools gvimdiff diffuse ecmerge p4merge araxis bc3 codecompare"
fi
case "${VISUAL:-$EDITOR}" in
*vim*)
diff --git a/git-p4.py b/git-p4.py
index e67d37d..882b1bb 100755
--- a/git-p4.py
+++ b/git-p4.py
@@ -844,6 +844,9 @@ class P4RollBack(Command):
return True
class P4Submit(Command, P4UserMap):
+
+ conflict_behavior_choices = ("ask", "skip", "quit")
+
def __init__(self):
Command.__init__(self)
P4UserMap.__init__(self)
@@ -853,12 +856,19 @@ class P4Submit(Command, P4UserMap):
# preserve the user, requires relevant p4 permissions
optparse.make_option("--preserve-user", dest="preserveUser", action="store_true"),
optparse.make_option("--export-labels", dest="exportLabels", action="store_true"),
+ optparse.make_option("--dry-run", "-n", dest="dry_run", action="store_true"),
+ optparse.make_option("--prepare-p4-only", dest="prepare_p4_only", action="store_true"),
+ optparse.make_option("--conflict", dest="conflict_behavior",
+ choices=self.conflict_behavior_choices)
]
self.description = "Submit changes from git to the perforce depot."
self.usage += " [name of git branch to submit into perforce depot]"
self.origin = ""
self.detectRenames = False
self.preserveUser = gitConfig("git-p4.preserveUser").lower() == "true"
+ self.dry_run = False
+ self.prepare_p4_only = False
+ self.conflict_behavior = None
self.isWindows = (platform.system() == "Windows")
self.exportLabels = False
self.p4HasMoveCommand = p4_has_command("move")
@@ -1088,7 +1098,10 @@ class P4Submit(Command, P4UserMap):
return False
def applyCommit(self, id):
- print "Applying %s" % (read_pipe("git log --max-count=1 --pretty=oneline %s" % id))
+ """Apply one commit, return True if it succeeded."""
+
+ print "Applying", read_pipe(["git", "show", "-s",
+ "--format=format:%h %s", id])
(p4User, gitEmail) = self.p4UserForCommit(id)
@@ -1195,34 +1208,13 @@ class P4Submit(Command, P4UserMap):
patch_succeeded = True
if not patch_succeeded:
- print "What do you want to do?"
- response = "x"
- while response != "s" and response != "a" and response != "w":
- response = raw_input("[s]kip this patch / [a]pply the patch forcibly "
- "and with .rej files / [w]rite the patch to a file (patch.txt) ")
- if response == "s":
- print "Skipping! Good luck with the next patches..."
- for f in editedFiles:
- p4_revert(f)
- for f in filesToAdd:
- os.remove(f)
- return
- elif response == "a":
- os.system(applyPatchCmd)
- if len(filesToAdd) > 0:
- print "You may also want to call p4 add on the following files:"
- print " ".join(filesToAdd)
- if len(filesToDelete):
- print "The following files should be scheduled for deletion with p4 delete:"
- print " ".join(filesToDelete)
- die("Please resolve and submit the conflict manually and "
- + "continue afterwards with git p4 submit --continue")
- elif response == "w":
- system(diffcmd + " > patch.txt")
- print "Patch saved to patch.txt in %s !" % self.clientPath
- die("Please resolve and submit the conflict manually and "
- "continue afterwards with git p4 submit --continue")
+ for f in editedFiles:
+ p4_revert(f)
+ return False
+ #
+ # Apply the patch for real, and do add/delete/+x handling.
+ #
system(applyPatchCmd)
for f in filesToAdd:
@@ -1236,6 +1228,10 @@ class P4Submit(Command, P4UserMap):
mode = filesToChangeExecBit[f]
setP4ExecBit(f, mode)
+ #
+ # Build p4 change description, starting with the contents
+ # of the git commit message.
+ #
logMessage = extractLogMessageFromGitCommit(id)
logMessage = logMessage.strip()
(logMessage, jobs) = self.separate_jobs_from_description(logMessage)
@@ -1244,8 +1240,16 @@ class P4Submit(Command, P4UserMap):
submitTemplate = self.prepareLogMessage(template, logMessage, jobs)
if self.preserveUser:
- submitTemplate = submitTemplate + ("\n######## Actual user %s, modified after commit\n" % p4User)
+ submitTemplate += "\n######## Actual user %s, modified after commit\n" % p4User
+
+ if self.checkAuthorship and not self.p4UserIsMe(p4User):
+ submitTemplate += "######## git author %s does not match your p4 account.\n" % gitEmail
+ submitTemplate += "######## Use option --preserve-user to modify authorship.\n"
+ submitTemplate += "######## Variable git-p4.skipUserNameCheck hides this message.\n"
+ separatorLine = "######## everything below this line is just the diff #######\n"
+
+ # diff
if os.environ.has_key("P4DIFF"):
del(os.environ["P4DIFF"])
diff = ""
@@ -1253,6 +1257,7 @@ class P4Submit(Command, P4UserMap):
diff += p4_read_pipe(['diff', '-du',
wildcard_encode(editedFile)])
+ # new file diff
newdiff = ""
for newFile in filesToAdd:
newdiff += "==== new file ====\n"
@@ -1263,13 +1268,7 @@ class P4Submit(Command, P4UserMap):
newdiff += "+" + line
f.close()
- if self.checkAuthorship and not self.p4UserIsMe(p4User):
- submitTemplate += "######## git author %s does not match your p4 account.\n" % gitEmail
- submitTemplate += "######## Use option --preserve-user to modify authorship.\n"
- submitTemplate += "######## Variable git-p4.skipUserNameCheck hides this message.\n"
-
- separatorLine = "######## everything below this line is just the diff #######\n"
-
+ # change description file: submitTemplate, separatorLine, diff, newdiff
(handle, fileName) = tempfile.mkstemp()
tmpFile = os.fdopen(handle, "w+")
if self.isWindows:
@@ -1279,8 +1278,47 @@ class P4Submit(Command, P4UserMap):
tmpFile.write(submitTemplate + separatorLine + diff + newdiff)
tmpFile.close()
+ if self.prepare_p4_only:
+ #
+ # Leave the p4 tree prepared, and the submit template around
+ # and let the user decide what to do next
+ #
+ print
+ print "P4 workspace prepared for submission."
+ print "To submit or revert, go to client workspace"
+ print " " + self.clientPath
+ print
+ print "To submit, use \"p4 submit\" to write a new description,"
+ print "or \"p4 submit -i %s\" to use the one prepared by" \
+ " \"git p4\"." % fileName
+ print "You can delete the file \"%s\" when finished." % fileName
+
+ if self.preserveUser and p4User and not self.p4UserIsMe(p4User):
+ print "To preserve change ownership by user %s, you must\n" \
+ "do \"p4 change -f <change>\" after submitting and\n" \
+ "edit the User field."
+ if pureRenameCopy:
+ print "After submitting, renamed files must be re-synced."
+ print "Invoke \"p4 sync -f\" on each of these files:"
+ for f in pureRenameCopy:
+ print " " + f
+
+ print
+ print "To revert the changes, use \"p4 revert ...\", and delete"
+ print "the submit template file \"%s\"" % fileName
+ if filesToAdd:
+ print "Since the commit adds new files, they must be deleted:"
+ for f in filesToAdd:
+ print " " + f
+ print
+ return True
+
+ #
+ # Let the user edit the change description, then submit it.
+ #
if self.edit_template(fileName):
# read the edited message and submit
+ ret = True
tmpFile = open(fileName, "rb")
message = tmpFile.read()
tmpFile.close()
@@ -1304,14 +1342,18 @@ class P4Submit(Command, P4UserMap):
else:
# skip this patch
+ ret = False
print "Submission cancelled, undoing p4 changes."
for f in editedFiles:
p4_revert(f)
for f in filesToAdd:
p4_revert(f)
os.remove(f)
+ for f in filesToDelete:
+ p4_revert(f)
os.remove(fileName)
+ return ret
# Export git tags as p4 labels. Create a p4 label and then tag
# with that.
@@ -1369,14 +1411,20 @@ class P4Submit(Command, P4UserMap):
for mapping in clientSpec.mappings:
labelTemplate += "\t%s\n" % mapping.depot_side.path
- p4_write_pipe(["label", "-i"], labelTemplate)
+ if self.dry_run:
+ print "Would create p4 label %s for tag" % name
+ elif self.prepare_p4_only:
+ print "Not creating p4 label %s for tag due to option" \
+ " --prepare-p4-only" % name
+ else:
+ p4_write_pipe(["label", "-i"], labelTemplate)
- # Use the label
- p4_system(["tag", "-l", name] +
- ["%s@%s" % (mapping.depot_side.path, changelist) for mapping in clientSpec.mappings])
+ # Use the label
+ p4_system(["tag", "-l", name] +
+ ["%s@%s" % (mapping.depot_side.path, changelist) for mapping in clientSpec.mappings])
- if verbose:
- print "created p4 label for tag %s" % name
+ if verbose:
+ print "created p4 label for tag %s" % name
def run(self, args):
if len(args) == 0:
@@ -1403,6 +1451,16 @@ class P4Submit(Command, P4UserMap):
if not self.canChangeChangelists():
die("Cannot preserve user names without p4 super-user or admin permissions")
+ # if not set from the command line, try the config file
+ if self.conflict_behavior is None:
+ val = gitConfig("git-p4.conflict")
+ if val:
+ if val not in self.conflict_behavior_choices:
+ die("Invalid value '%s' for config git-p4.conflict" % val)
+ else:
+ val = "ask"
+ self.conflict_behavior = val
+
if self.verbose:
print "Origin branch is " + self.origin
@@ -1435,12 +1493,15 @@ class P4Submit(Command, P4UserMap):
os.makedirs(self.clientPath)
chdir(self.clientPath)
- print "Synchronizing p4 checkout..."
- if new_client_dir:
- # old one was destroyed, and maybe nobody told p4
- p4_sync("...", "-f")
+ if self.dry_run:
+ print "Would synchronize p4 checkout in %s" % self.clientPath
else:
- p4_sync("...")
+ print "Synchronizing p4 checkout..."
+ if new_client_dir:
+ # old one was destroyed, and maybe nobody told p4
+ p4_sync("...", "-f")
+ else:
+ p4_sync("...")
self.check()
commits = []
@@ -1487,14 +1548,64 @@ class P4Submit(Command, P4UserMap):
if gitConfig("git-p4.detectCopiesHarder", "--bool") == "true":
self.diffOpts += " --find-copies-harder"
- while len(commits) > 0:
- commit = commits[0]
- commits = commits[1:]
- self.applyCommit(commit)
+ #
+ # Apply the commits, one at a time. On failure, ask if should
+ # continue to try the rest of the patches, or quit.
+ #
+ if self.dry_run:
+ print "Would apply"
+ applied = []
+ last = len(commits) - 1
+ for i, commit in enumerate(commits):
+ if self.dry_run:
+ print " ", read_pipe(["git", "show", "-s",
+ "--format=format:%h %s", commit])
+ ok = True
+ else:
+ ok = self.applyCommit(commit)
+ if ok:
+ applied.append(commit)
+ else:
+ if self.prepare_p4_only and i < last:
+ print "Processing only the first commit due to option" \
+ " --prepare-p4-only"
+ break
+ if i < last:
+ quit = False
+ while True:
+ # prompt for what to do, or use the option/variable
+ if self.conflict_behavior == "ask":
+ print "What do you want to do?"
+ response = raw_input("[s]kip this commit but apply"
+ " the rest, or [q]uit? ")
+ if not response:
+ continue
+ elif self.conflict_behavior == "skip":
+ response = "s"
+ elif self.conflict_behavior == "quit":
+ response = "q"
+ else:
+ die("Unknown conflict_behavior '%s'" %
+ self.conflict_behavior)
+
+ if response[0] == "s":
+ print "Skipping this commit, but applying the rest"
+ break
+ if response[0] == "q":
+ print "Quitting"
+ quit = True
+ break
+ if quit:
+ break
+
+ chdir(self.oldWorkingDirectory)
- if len(commits) == 0:
- print "All changes applied!"
- chdir(self.oldWorkingDirectory)
+ if self.dry_run:
+ pass
+ elif self.prepare_p4_only:
+ pass
+ elif len(commits) == len(applied):
+ print "All commits applied!"
sync = P4Sync()
sync.run([])
@@ -1502,6 +1613,20 @@ class P4Submit(Command, P4UserMap):
rebase = P4Rebase()
rebase.rebase()
+ else:
+ if len(applied) == 0:
+ print "No commits applied."
+ else:
+ print "Applied only the commits marked with '*':"
+ for c in commits:
+ if c in applied:
+ star = "*"
+ else:
+ star = " "
+ print star, read_pipe(["git", "show", "-s",
+ "--format=format:%h %s", c])
+ print "You will have to do 'git p4 sync' and rebase."
+
if gitConfig("git-p4.exportLabels", "--bool") == "true":
self.exportLabels = True
@@ -1512,6 +1637,10 @@ class P4Submit(Command, P4UserMap):
missingGitTags = gitTags - p4Labels
self.exportGitTags(missingGitTags)
+ # exit with error unless everything applied perfecly
+ if len(commits) != len(applied):
+ sys.exit(1)
+
return True
class View(object):
@@ -1818,19 +1947,41 @@ class P4Sync(Command, P4UserMap):
return files
def stripRepoPath(self, path, prefixes):
- if self.useClientSpec:
- return self.clientSpecDirs.map_in_client(path)
+ """When streaming files, this is called to map a p4 depot path
+ to where it should go in git. The prefixes are either
+ self.depotPaths, or self.branchPrefixes in the case of
+ branch detection."""
- if self.keepRepoPath:
- prefixes = [re.sub("^(//[^/]+/).*", r'\1', prefixes[0])]
+ if self.useClientSpec:
+ # branch detection moves files up a level (the branch name)
+ # from what client spec interpretation gives
+ path = self.clientSpecDirs.map_in_client(path)
+ if self.detectBranches:
+ for b in self.knownBranches:
+ if path.startswith(b + "/"):
+ path = path[len(b)+1:]
+
+ elif self.keepRepoPath:
+ # Preserve everything in relative path name except leading
+ # //depot/; just look at first prefix as they all should
+ # be in the same depot.
+ depot = re.sub("^(//[^/]+/).*", r'\1', prefixes[0])
+ if p4PathStartsWith(path, depot):
+ path = path[len(depot):]
- for p in prefixes:
- if p4PathStartsWith(path, p):
- path = path[len(p):]
+ else:
+ for p in prefixes:
+ if p4PathStartsWith(path, p):
+ path = path[len(p):]
+ break
+ path = wildcard_decode(path)
return path
def splitFilesIntoBranches(self, commit):
+ """Look at each depotFile in the commit to figure out to what
+ branch it belongs."""
+
branches = {}
fnum = 0
while commit.has_key("depotFile%s" % fnum):
@@ -1848,12 +1999,16 @@ class P4Sync(Command, P4UserMap):
file["type"] = commit["type%s" % fnum]
fnum = fnum + 1
- relPath = self.stripRepoPath(path, self.depotPaths)
- relPath = wildcard_decode(relPath)
+ # start with the full relative path where this file would
+ # go in a p4 client
+ if self.useClientSpec:
+ relPath = self.clientSpecDirs.map_in_client(path)
+ else:
+ relPath = self.stripRepoPath(path, self.depotPaths)
for branch in self.knownBranches.keys():
-
- # add a trailing slash so that a commit into qt/4.2foo doesn't end up in qt/4.2
+ # add a trailing slash so that a commit into qt/4.2foo
+ # doesn't end up in qt/4.2, e.g.
if relPath.startswith(branch + "/"):
if branch not in branches:
branches[branch] = []
@@ -1867,7 +2022,6 @@ class P4Sync(Command, P4UserMap):
def streamOneP4File(self, file, contents):
relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)
- relPath = wildcard_decode(relPath)
if verbose:
sys.stderr.write("%s\n" % relPath)
@@ -1936,7 +2090,6 @@ class P4Sync(Command, P4UserMap):
def streamOneP4Deletion(self, file):
relPath = self.stripRepoPath(file['path'], self.branchPrefixes)
- relPath = wildcard_decode(relPath)
if verbose:
sys.stderr.write("delete %s\n" % relPath)
self.gitStream.write("D %s\n" % relPath)
@@ -2041,10 +2194,9 @@ class P4Sync(Command, P4UserMap):
gitStream.write(description)
gitStream.write("\n")
- def commit(self, details, files, branch, branchPrefixes, parent = ""):
+ def commit(self, details, files, branch, parent = ""):
epoch = details["time"]
author = details["user"]
- self.branchPrefixes = branchPrefixes
if self.verbose:
print "commit into %s" % branch
@@ -2053,7 +2205,7 @@ class P4Sync(Command, P4UserMap):
# create a commit.
new_files = []
for f in files:
- if [p for p in branchPrefixes if p4PathStartsWith(f['path'], p)]:
+ if [p for p in self.branchPrefixes if p4PathStartsWith(f['path'], p)]:
new_files.append (f)
else:
sys.stderr.write("Ignoring file outside of prefix: %s\n" % f['path'])
@@ -2070,8 +2222,8 @@ class P4Sync(Command, P4UserMap):
self.gitStream.write("data <<EOT\n")
self.gitStream.write(details["desc"])
- self.gitStream.write("\n[git-p4: depot-paths = \"%s\": change = %s"
- % (','.join (branchPrefixes), details["change"]))
+ self.gitStream.write("\n[git-p4: depot-paths = \"%s\": change = %s" %
+ (','.join(self.branchPrefixes), details["change"]))
if len(details['options']) > 0:
self.gitStream.write(": options = %s" % details['options'])
self.gitStream.write("]\nEOT\n\n")
@@ -2094,7 +2246,7 @@ class P4Sync(Command, P4UserMap):
print "Change %s is labelled %s" % (change, labelDetails)
files = p4CmdList(["files"] + ["%s...@%s" % (p, change)
- for p in branchPrefixes])
+ for p in self.branchPrefixes])
if len(files) == len(labelRevisions):
@@ -2405,6 +2557,7 @@ class P4Sync(Command, P4UserMap):
for branch in branches.keys():
## HACK --hwn
branchPrefix = self.depotPaths[0] + branch + "/"
+ self.branchPrefixes = [ branchPrefix ]
parent = ""
@@ -2449,19 +2602,19 @@ class P4Sync(Command, P4UserMap):
tempBranch = os.path.join(self.tempBranchLocation, "%d" % (change))
if self.verbose:
print "Creating temporary branch: " + tempBranch
- self.commit(description, filesForCommit, tempBranch, [branchPrefix])
+ self.commit(description, filesForCommit, tempBranch)
self.tempBranches.append(tempBranch)
self.checkpoint()
blob = self.searchParent(parent, branch, tempBranch)
if blob:
- self.commit(description, filesForCommit, branch, [branchPrefix], blob)
+ self.commit(description, filesForCommit, branch, blob)
else:
if self.verbose:
print "Parent of %s not found. Committing into head of %s" % (branch, parent)
- self.commit(description, filesForCommit, branch, [branchPrefix], parent)
+ self.commit(description, filesForCommit, branch, parent)
else:
files = self.extractFilesFromCommit(description)
- self.commit(description, files, self.branch, self.depotPaths,
+ self.commit(description, files, self.branch,
self.initialParent)
self.initialParent = ""
except IOError:
@@ -2525,7 +2678,7 @@ class P4Sync(Command, P4UserMap):
self.updateOptionDict(details)
try:
- self.commit(details, self.extractFilesFromCommit(details), self.branch, self.depotPaths)
+ self.commit(details, self.extractFilesFromCommit(details), self.branch)
except IOError:
print "IO error with git fast-import. Is your git version recent enough?"
print self.gitError.read()
@@ -2683,6 +2836,9 @@ class P4Sync(Command, P4UserMap):
self.depotPaths = newPaths
+ # --detect-branches may change this for each branch
+ self.branchPrefixes = self.depotPaths
+
self.loadUserMapFromCache()
self.labels = {}
if self.detectLabels:
@@ -2988,7 +3144,7 @@ def main():
args = sys.argv[2:]
- options.append(optparse.make_option("--verbose", dest="verbose", action="store_true"))
+ options.append(optparse.make_option("--verbose", "-v", dest="verbose", action="store_true"))
if cmd.needsGit:
options.append(optparse.make_option("--git-dir", dest="gitdir"))
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index a09e842..44901d5 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -115,6 +115,23 @@ mark_action_done () {
fi
}
+append_todo_help () {
+ cat >> "$todo" << EOF
+#
+# Commands:
+# p, pick = use commit
+# r, reword = use commit, but edit the commit message
+# e, edit = use commit, but stop for amending
+# s, squash = use commit, but meld into previous commit
+# f, fixup = like "squash", but discard this commit's log message
+# x, exec = run command (the rest of the line) using shell
+#
+# These lines can be re-ordered; they are executed from top to bottom.
+#
+# If you remove a line here THAT COMMIT WILL BE LOST.
+EOF
+}
+
make_patch () {
sha1_and_parents="$(git rev-list --parents -1 "$1")"
case "$sha1_and_parents" in
@@ -544,6 +561,10 @@ do_next () {
warn
warn " git rebase --continue"
warn
+ if test $status -eq 127 # command not found
+ then
+ status=1
+ fi
exit "$status"
elif test "$dirty" = t
then
@@ -558,11 +579,12 @@ do_next () {
;;
*)
warn "Unknown command: $command $sha1 $rest"
+ fixtodo="Please fix this using 'git rebase --edit-todo'."
if git rev-parse --verify -q "$sha1" >/dev/null
then
- die_with_patch $sha1 "Please fix this in the file $todo."
+ die_with_patch $sha1 "$fixtodo"
else
- die "Please fix this in the file $todo."
+ die "$fixtodo"
fi
;;
esac
@@ -775,6 +797,23 @@ skip)
do_rest
;;
+edit-todo)
+ sed -e '/^#/d' < "$todo" > "$todo".new
+ mv -f "$todo".new "$todo"
+ append_todo_help
+ cat >> "$todo" << EOF
+#
+# You are editing the todo file of an ongoing interactive rebase.
+# To continue rebase after editing, run:
+# git rebase --continue
+#
+EOF
+
+ git_sequence_editor "$todo" ||
+ die "Could not execute editor"
+
+ exit
+ ;;
esac
git var GIT_COMMITTER_IDENT >/dev/null ||
@@ -901,18 +940,10 @@ test -n "$cmd" && add_exec_commands "$todo"
cat >> "$todo" << EOF
# Rebase $shortrevisions onto $shortonto
+EOF
+append_todo_help
+cat >> "$todo" << EOF
#
-# Commands:
-# p, pick = use commit
-# r, reword = use commit, but edit the commit message
-# e, edit = use commit, but stop for amending
-# s, squash = use commit, but meld into previous commit
-# f, fixup = like "squash", but discard this commit's log message
-# x, exec = run command (the rest of the line) using shell
-#
-# These lines can be re-ordered; they are executed from top to bottom.
-#
-# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
EOF
diff --git a/git-rebase.sh b/git-rebase.sh
index 15da926..b2f1c76 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -8,7 +8,7 @@ OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
-git-rebase [-i] --continue | --abort | --skip
+git-rebase --continue | --abort | --skip | --edit-todo
--
Available options are
v,verbose! display a diffstat of what changed upstream
@@ -38,6 +38,7 @@ C=! passed to 'git apply'
continue! continue
abort! abort and check out the original branch
skip! skip current patch and continue
+edit-todo! edit the todo list during an interactive rebase
"
. git-sh-setup
. git-sh-i18n
@@ -190,7 +191,7 @@ do
--verify)
ok_to_skip_pre_rebase=
;;
- --continue|--skip|--abort)
+ --continue|--skip|--abort|--edit-todo)
test $total_argc -eq 2 || usage
action=${1##--}
;;
@@ -306,6 +307,11 @@ then
fi
fi
+if test "$action" = "edit-todo" && test "$type" != "interactive"
+then
+ die "$(gettext "The --edit-todo action can only be used during interactive rebase.")"
+fi
+
case "$action" in
continue)
# Sanity check
@@ -338,6 +344,9 @@ abort)
rm -r "$state_dir"
exit
;;
+edit-todo)
+ run_specific_rebase
+ ;;
esac
# Make sure no rebase is in progress
diff --git a/git-svn.perl b/git-svn.perl
index 828b8f0..bd5266c 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -29,7 +29,16 @@ use Git::SVN::Prompt;
use Git::SVN::Log;
use Git::SVN::Migration;
-use Git::SVN::Utils qw(fatal can_compress);
+use Git::SVN::Utils qw(
+ fatal
+ can_compress
+ canonicalize_path
+ canonicalize_url
+ join_paths
+ add_path_to_url
+ join_paths
+);
+
use Git qw(
git_cmd_try
command
@@ -1231,7 +1240,7 @@ sub cmd_show_ignore {
my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
$gs ||= Git::SVN->new;
my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
- $gs->prop_walk($gs->{path}, $r, sub {
+ $gs->prop_walk($gs->path, $r, sub {
my ($gs, $path, $props) = @_;
print STDOUT "\n# $path\n";
my $s = $props->{'svn:ignore'} or return;
@@ -1247,7 +1256,7 @@ sub cmd_show_externals {
my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
$gs ||= Git::SVN->new;
my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
- $gs->prop_walk($gs->{path}, $r, sub {
+ $gs->prop_walk($gs->path, $r, sub {
my ($gs, $path, $props) = @_;
print STDOUT "\n# $path\n";
my $s = $props->{'svn:externals'} or return;
@@ -1262,7 +1271,7 @@ sub cmd_create_ignore {
my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
$gs ||= Git::SVN->new;
my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
- $gs->prop_walk($gs->{path}, $r, sub {
+ $gs->prop_walk($gs->path, $r, sub {
my ($gs, $path, $props) = @_;
# $path is of the form /path/to/dir/
$path = '.' . $path;
@@ -1292,31 +1301,6 @@ sub cmd_mkdirs {
$gs->mkemptydirs($_revision);
}
-sub canonicalize_path {
- my ($path) = @_;
- my $dot_slash_added = 0;
- if (substr($path, 0, 1) ne "/") {
- $path = "./" . $path;
- $dot_slash_added = 1;
- }
- # File::Spec->canonpath doesn't collapse x/../y into y (for a
- # good reason), so let's do this manually.
- $path =~ s#/+#/#g;
- $path =~ s#/\.(?:/|$)#/#g;
- $path =~ s#/[^/]+/\.\.##g;
- $path =~ s#/$##g;
- $path =~ s#^\./## if $dot_slash_added;
- $path =~ s#^/##;
- $path =~ s#^\.$##;
- return $path;
-}
-
-sub canonicalize_url {
- my ($url) = @_;
- $url =~ s#^([^:]+://[^/]*/)(.*)$#$1 . canonicalize_path($2)#e;
- return $url;
-}
-
# get_svnprops(PATH)
# ------------------
# Helper for cmd_propget and cmd_proplist below.
@@ -1330,7 +1314,7 @@ sub get_svnprops {
$path = $cmd_dir_prefix . $path;
fatal("No such file or directory: $path") unless -e $path;
my $is_dir = -d $path ? 1 : 0;
- $path = $gs->{path} . '/' . $path;
+ $path = join_paths($gs->path, $path);
# canonicalize the path (otherwise libsvn will abort or fail to
# find the file)
@@ -1431,8 +1415,8 @@ sub cmd_commit_diff {
fatal("Needed URL or usable git-svn --id in ",
"the command-line\n", $usage);
}
- $url = $gs->{url};
- $svn_path = $gs->{path};
+ $url = $gs->url;
+ $svn_path = $gs->path;
}
unless (defined $_revision) {
fatal("-r|--revision is a required argument\n", $usage);
@@ -1466,24 +1450,6 @@ sub cmd_commit_diff {
}
}
-sub escape_uri_only {
- my ($uri) = @_;
- my @tmp;
- foreach (split m{/}, $uri) {
- s/([^~\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
- push @tmp, $_;
- }
- join('/', @tmp);
-}
-
-sub escape_url {
- my ($url) = @_;
- if ($url =~ m#^([^:]+)://([^/]*)(.*)$#) {
- my ($scheme, $domain, $uri) = ($1, $2, escape_uri_only($3));
- $url = "$scheme://$domain$uri";
- }
- $url;
-}
sub cmd_info {
my $path = canonicalize_path(defined($_[0]) ? $_[0] : ".");
@@ -1508,21 +1474,21 @@ sub cmd_info {
# canonicalize_path() will return "" to make libsvn 1.5.x happy,
$path = "." if $path eq "";
- my $full_url = $url . ($fullpath eq "" ? "" : "/$fullpath");
+ my $full_url = canonicalize_url( add_path_to_url( $url, $fullpath ) );
if ($_url) {
- print escape_url($full_url), "\n";
+ print "$full_url\n";
return;
}
my $result = "Path: $path\n";
$result .= "Name: " . basename($path) . "\n" if $file_type ne "dir";
- $result .= "URL: " . escape_url($full_url) . "\n";
+ $result .= "URL: $full_url\n";
eval {
my $repos_root = $gs->repos_root;
Git::SVN::remove_username($repos_root);
- $result .= "Repository Root: " . escape_url($repos_root) . "\n";
+ $result .= "Repository Root: " . canonicalize_url($repos_root) . "\n";
};
if ($@) {
$result .= "Repository Root: (offline)\n";
@@ -1669,7 +1635,9 @@ sub post_fetch_checkout {
sub complete_svn_url {
my ($url, $path) = @_;
- $path =~ s#/+$##;
+ $path = canonicalize_path($path);
+
+ # If the path is not a URL...
if ($path !~ m#^[a-z\+]+://#) {
if (!defined $url || $url !~ m#^[a-z\+]+://#) {
fatal("E: '$path' is not a complete URL ",
@@ -1686,7 +1654,7 @@ sub complete_url_ls_init {
print STDERR "W: $switch not specified\n";
return;
}
- $repo_path =~ s#/+$##;
+ $repo_path = canonicalize_path($repo_path);
if ($repo_path =~ m#^[a-z\+]+://#) {
$ra = Git::SVN::Ra->new($repo_path);
$repo_path = '';
@@ -1697,18 +1665,18 @@ sub complete_url_ls_init {
"and a separate URL is not specified");
}
}
- my $url = $ra->{url};
+ my $url = $ra->url;
my $gs = Git::SVN->init($url, undef, undef, undef, 1);
my $k = "svn-remote.$gs->{repo_id}.url";
my $orig_url = eval { command_oneline(qw/config --get/, $k) };
- if ($orig_url && ($orig_url ne $gs->{url})) {
+ if ($orig_url && ($orig_url ne $gs->url)) {
die "$k already set: $orig_url\n",
- "wanted to set to: $gs->{url}\n";
+ "wanted to set to: $gs->url\n";
}
- command_oneline('config', $k, $gs->{url}) unless $orig_url;
- my $remote_path = "$gs->{path}/$repo_path";
+ command_oneline('config', $k, $gs->url) unless $orig_url;
+
+ my $remote_path = join_paths( $gs->path, $repo_path );
$remote_path =~ s{%([0-9A-F]{2})}{chr hex($1)}ieg;
- $remote_path =~ s#/+#/#g;
$remote_path =~ s#^/##g;
$remote_path .= "/*" if $remote_path !~ /\*/;
my ($n) = ($switch =~ /^--(\w+)/);
diff --git a/gitk-git/gitk b/gitk-git/gitk
index 6f24f53..d93bd99 100755
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -11533,6 +11533,11 @@ if {[catch {package require Tk 8.4} err]} {
exit 1
}
+# Unset GIT_TRACE var if set
+if { [info exists ::env(GIT_TRACE)] } {
+ unset ::env(GIT_TRACE)
+}
+
# defaults...
set wrcomcmd "git diff-tree --stdin -p --pretty"
diff --git a/graph.c b/graph.c
index 7e0a099..e864fe2 100644
--- a/graph.c
+++ b/graph.c
@@ -8,6 +8,34 @@
/* Internal API */
/*
+ * Output the next line for a graph.
+ * This formats the next graph line into the specified strbuf. It is not
+ * terminated with a newline.
+ *
+ * Returns 1 if the line includes the current commit, and 0 otherwise.
+ * graph_next_line() will return 1 exactly once for each time
+ * graph_update() is called.
+ */
+static int graph_next_line(struct git_graph *graph, struct strbuf *sb);
+
+/*
+ * Set up a custom scheme for column colors.
+ *
+ * The default column color scheme inserts ANSI color escapes to colorize
+ * the graph. The various color escapes are stored in an array of strings
+ * where each entry corresponds to a color, except for the last entry,
+ * which denotes the escape for resetting the color back to the default.
+ * When generating the graph, strings from this array are inserted before
+ * and after the various column characters.
+ *
+ * This function allows you to enable a custom array of color escapes.
+ * The 'colors_max' argument is the index of the last "reset" entry.
+ *
+ * This functions must be called BEFORE graph_init() is called.
+ */
+static void graph_set_column_colors(const char **colors, unsigned short colors_max);
+
+/*
* Output a padding line in the graph.
* This is similar to graph_next_line(). However, it is guaranteed to
* never print the current commit line. Instead, if the commit line is
@@ -62,7 +90,7 @@ enum graph_state {
static const char **column_colors;
static unsigned short column_colors_max;
-void graph_set_column_colors(const char **colors, unsigned short colors_max)
+static void graph_set_column_colors(const char **colors, unsigned short colors_max)
{
column_colors = colors;
column_colors_max = colors_max;
@@ -1116,7 +1144,7 @@ static void graph_output_collapsing_line(struct git_graph *graph, struct strbuf
graph_update_state(graph, GRAPH_PADDING);
}
-int graph_next_line(struct git_graph *graph, struct strbuf *sb)
+static int graph_next_line(struct git_graph *graph, struct strbuf *sb)
{
switch (graph->state) {
case GRAPH_PADDING:
diff --git a/graph.h b/graph.h
index aff960c..19b0f66 100644
--- a/graph.h
+++ b/graph.h
@@ -4,22 +4,6 @@
/* A graph is a pointer to this opaque structure */
struct git_graph;
-/*
- * Set up a custom scheme for column colors.
- *
- * The default column color scheme inserts ANSI color escapes to colorize
- * the graph. The various color escapes are stored in an array of strings
- * where each entry corresponds to a color, except for the last entry,
- * which denotes the escape for resetting the color back to the default.
- * When generating the graph, strings from this array are inserted before
- * and after the various column characters.
- *
- * This function allows you to enable a custom array of color escapes.
- * The 'colors_max' argument is the index of the last "reset" entry.
- *
- * This functions must be called BEFORE graph_init() is called.
- */
-void graph_set_column_colors(const char **colors, unsigned short colors_max);
/*
* Create a new struct git_graph.
@@ -49,17 +33,6 @@ void graph_update(struct git_graph *graph, struct commit *commit);
*/
int graph_is_commit_finished(struct git_graph const *graph);
-/*
- * Output the next line for a graph.
- * This formats the next graph line into the specified strbuf. It is not
- * terminated with a newline.
- *
- * Returns 1 if the line includes the current commit, and 0 otherwise.
- * graph_next_line() will return 1 exactly once for each time
- * graph_update() is called.
- */
-int graph_next_line(struct git_graph *graph, struct strbuf *sb);
-
/*
* graph_show_*: helper functions for printing to stdout
diff --git a/grep.c b/grep.c
index 898be6e..edc7776 100644
--- a/grep.c
+++ b/grep.c
@@ -64,6 +64,8 @@ void append_header_grep_pattern(struct grep_opt *opt,
{
struct grep_pat *p = create_grep_pat(pat, strlen(pat), "header", 0,
GREP_PATTERN_HEAD, field);
+ if (field == GREP_HEADER_REFLOG)
+ opt->use_reflog_filter = 1;
do_append_grep_pat(&opt->header_tail, p);
}
@@ -697,6 +699,7 @@ static struct {
} header_field[] = {
{ "author ", 7 },
{ "committer ", 10 },
+ { "reflog ", 7 },
};
static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
@@ -720,7 +723,14 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
if (strncmp(bol, field, len))
return 0;
bol += len;
- saved_ch = strip_timestamp(bol, &eol);
+ switch (p->field) {
+ case GREP_HEADER_AUTHOR:
+ case GREP_HEADER_COMMITTER:
+ saved_ch = strip_timestamp(bol, &eol);
+ break;
+ default:
+ break;
+ }
}
again:
diff --git a/grep.h b/grep.h
index d66b197..c256ac6 100644
--- a/grep.h
+++ b/grep.h
@@ -29,9 +29,12 @@ enum grep_context {
enum grep_header_field {
GREP_HEADER_AUTHOR = 0,
- GREP_HEADER_COMMITTER
+ GREP_HEADER_COMMITTER,
+ GREP_HEADER_REFLOG,
+
+ /* Must be at the end of the enum */
+ GREP_HEADER_FIELD_MAX
};
-#define GREP_HEADER_FIELD_MAX (GREP_HEADER_COMMITTER + 1)
struct grep_pat {
struct grep_pat *next;
@@ -58,6 +61,14 @@ enum grep_expr_node {
GREP_NODE_OR
};
+enum grep_pattern_type {
+ GREP_PATTERN_TYPE_UNSPECIFIED = 0,
+ GREP_PATTERN_TYPE_BRE,
+ GREP_PATTERN_TYPE_ERE,
+ GREP_PATTERN_TYPE_FIXED,
+ GREP_PATTERN_TYPE_PCRE
+};
+
struct grep_expr {
enum grep_expr_node node;
unsigned hit;
@@ -96,6 +107,7 @@ struct grep_opt {
#define GREP_BINARY_TEXT 2
int binary;
int extended;
+ int use_reflog_filter;
int pcre;
int relative;
int pathname;
@@ -104,6 +116,8 @@ struct grep_opt {
int max_depth;
int funcname;
int funcbody;
+ int extended_regexp_option;
+ int pattern_type_option;
char color_context[COLOR_MAXLEN];
char color_filename[COLOR_MAXLEN];
char color_function[COLOR_MAXLEN];
diff --git a/http-push.c b/http-push.c
index a832ca7..8701c12 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1610,9 +1610,8 @@ static int verify_merge_base(unsigned char *head_sha1, struct ref *remote)
{
struct commit *head = lookup_commit_or_die(head_sha1, "HEAD");
struct commit *branch = lookup_commit_or_die(remote->old_sha1, remote->name);
- struct commit_list *merge_bases = get_merge_bases(head, branch, 1);
- return (merge_bases && !merge_bases->next && merge_bases->item == branch);
+ return in_merge_bases(branch, head);
}
static int delete_remote_branch(const char *pattern, int force)
diff --git a/http-walker.c b/http-walker.c
index 51a906e..1516c5e 100644
--- a/http-walker.c
+++ b/http-walker.c
@@ -396,7 +396,7 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)
return ret;
}
-static int fetch_pack(struct walker *walker, struct alt_base *repo, unsigned char *sha1)
+static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigned char *sha1)
{
struct packed_git *target;
int ret;
@@ -524,7 +524,7 @@ static int fetch(struct walker *walker, unsigned char *sha1)
if (!fetch_object(walker, altbase, sha1))
return 0;
while (altbase) {
- if (!fetch_pack(walker, altbase, sha1))
+ if (!http_fetch_pack(walker, altbase, sha1))
return 0;
fetch_alternates(walker, data->alt->base);
altbase = altbase->next;
diff --git a/ident.c b/ident.c
index 484e0a9..a4bf206 100644
--- a/ident.c
+++ b/ident.c
@@ -93,7 +93,7 @@ static void copy_email(const struct passwd *pw, struct strbuf *email)
add_domainname(email);
}
-const char *ident_default_name(void)
+static const char *ident_default_name(void)
{
if (!git_default_name.len) {
copy_gecos(xgetpwuid_self(), &git_default_name);
@@ -117,7 +117,7 @@ const char *ident_default_email(void)
return git_default_email.buf;
}
-const char *ident_default_date(void)
+static const char *ident_default_date(void)
{
if (!git_default_date[0])
datestamp(git_default_date, sizeof(git_default_date));
diff --git a/ll-merge.c b/ll-merge.c
index f3f7692..acea33b 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -35,7 +35,7 @@ struct ll_merge_driver {
*/
static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
mmbuffer_t *result,
- const char *path_unused,
+ const char *path,
mmfile_t *orig, const char *orig_name,
mmfile_t *src1, const char *name1,
mmfile_t *src2, const char *name2,
@@ -46,16 +46,34 @@ static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
assert(opts);
/*
- * The tentative merge result is "ours" for the final round,
- * or common ancestor for an internal merge. Still return
- * "conflicted merge" status.
+ * The tentative merge result is the or common ancestor for an internal merge.
*/
- stolen = opts->virtual_ancestor ? orig : src1;
+ if (opts->virtual_ancestor) {
+ stolen = orig;
+ } else {
+ switch (opts->variant) {
+ default:
+ warning("Cannot merge binary files: %s (%s vs. %s)",
+ path, name1, name2);
+ /* fallthru */
+ case XDL_MERGE_FAVOR_OURS:
+ stolen = src1;
+ break;
+ case XDL_MERGE_FAVOR_THEIRS:
+ stolen = src2;
+ break;
+ }
+ }
result->ptr = stolen->ptr;
result->size = stolen->size;
stolen->ptr = NULL;
- return 1;
+
+ /*
+ * With -Xtheirs or -Xours, we have cleanly merged;
+ * otherwise we got a conflict.
+ */
+ return (opts->variant ? 0 : 1);
}
static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
@@ -73,8 +91,6 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
if (buffer_is_binary(orig->ptr, orig->size) ||
buffer_is_binary(src1->ptr, src1->size) ||
buffer_is_binary(src2->ptr, src2->size)) {
- warning("Cannot merge binary files: %s (%s vs. %s)",
- path, name1, name2);
return ll_binary_merge(drv_unused, result,
path,
orig, orig_name,
diff --git a/merge-recursive.c b/merge-recursive.c
index 7866ca1..d882060 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -844,14 +844,14 @@ static int merge_3way(struct merge_options *o,
if (strcmp(a->path, b->path) ||
(o->ancestor != NULL && strcmp(a->path, one->path) != 0)) {
base_name = o->ancestor == NULL ? NULL :
- xstrdup(mkpath("%s:%s", o->ancestor, one->path));
- name1 = xstrdup(mkpath("%s:%s", branch1, a->path));
- name2 = xstrdup(mkpath("%s:%s", branch2, b->path));
+ mkpathdup("%s:%s", o->ancestor, one->path);
+ name1 = mkpathdup("%s:%s", branch1, a->path);
+ name2 = mkpathdup("%s:%s", branch2, b->path);
} else {
base_name = o->ancestor == NULL ? NULL :
- xstrdup(mkpath("%s", o->ancestor));
- name1 = xstrdup(mkpath("%s", branch1));
- name2 = xstrdup(mkpath("%s", branch2));
+ mkpathdup("%s", o->ancestor);
+ name1 = mkpathdup("%s", branch1);
+ name2 = mkpathdup("%s", branch2);
}
read_mmblob(&orig, one->sha1);
@@ -861,6 +861,7 @@ static int merge_3way(struct merge_options *o,
merge_status = ll_merge(result_buf, a->path, &orig, base_name,
&src1, name1, &src2, name2, &ll_opts);
+ free(base_name);
free(name1);
free(name2);
free(orig.ptr);
diff --git a/mergetools/codecompare b/mergetools/codecompare
new file mode 100644
index 0000000..3f0486b
--- /dev/null
+++ b/mergetools/codecompare
@@ -0,0 +1,25 @@
+diff_cmd () {
+ "$merge_tool_path" "$LOCAL" "$REMOTE"
+}
+
+merge_cmd () {
+ touch "$BACKUP"
+ if $base_present
+ then
+ "$merge_tool_path" -MF="$LOCAL" -TF="$REMOTE" -BF="$BASE" \
+ -RF="$MERGED"
+ else
+ "$merge_tool_path" -MF="$LOCAL" -TF="$REMOTE" \
+ -RF="$MERGED"
+ fi
+ check_unchanged
+}
+
+translate_merge_tool_path() {
+ if merge_mode
+ then
+ echo CodeMerge
+ else
+ echo CodeCompare
+ fi
+}
diff --git a/mergetools/defaults b/mergetools/defaults
index 1d8f2a3..21e63ec 100644
--- a/mergetools/defaults
+++ b/mergetools/defaults
@@ -8,36 +8,12 @@ can_diff () {
}
diff_cmd () {
- merge_tool_cmd="$(get_merge_tool_cmd "$1")"
- if test -z "$merge_tool_cmd"
- then
- status=1
- break
- fi
- ( eval $merge_tool_cmd )
- status=$?
+ status=1
return $status
}
merge_cmd () {
- merge_tool_cmd="$(get_merge_tool_cmd "$1")"
- if test -z "$merge_tool_cmd"
- then
- status=1
- break
- fi
- trust_exit_code="$(git config --bool \
- mergetool."$1".trustExitCode || echo false)"
- if test "$trust_exit_code" = "false"
- then
- touch "$BACKUP"
- ( eval $merge_tool_cmd )
- status=$?
- check_unchanged
- else
- ( eval $merge_tool_cmd )
- status=$?
- fi
+ status=1
return $status
}
diff --git a/notes.c b/notes.c
index 93e9868..bc454e1 100644
--- a/notes.c
+++ b/notes.c
@@ -1196,8 +1196,18 @@ void free_notes(struct notes_tree *t)
memset(t, 0, sizeof(struct notes_tree));
}
-void format_note(struct notes_tree *t, const unsigned char *object_sha1,
- struct strbuf *sb, const char *output_encoding, int flags)
+/*
+ * Fill the given strbuf with the notes associated with the given object.
+ *
+ * If the given notes_tree structure is not initialized, it will be auto-
+ * initialized to the default value (see documentation for init_notes() above).
+ * If the given notes_tree is NULL, the internal/default notes_tree will be
+ * used instead.
+ *
+ * 'flags' is a bitwise combination of the flags for format_display_notes.
+ */
+static void format_note(struct notes_tree *t, const unsigned char *object_sha1,
+ struct strbuf *sb, const char *output_encoding, int flags)
{
static const char utf8[] = "utf-8";
const unsigned char *sha1;
diff --git a/notes.h b/notes.h
index c716694..3592b19 100644
--- a/notes.h
+++ b/notes.h
@@ -241,20 +241,6 @@ void free_notes(struct notes_tree *t);
#define NOTES_SHOW_HEADER 1
#define NOTES_INDENT 2
-/*
- * Fill the given strbuf with the notes associated with the given object.
- *
- * If the given notes_tree structure is not initialized, it will be auto-
- * initialized to the default value (see documentation for init_notes() above).
- * If the given notes_tree is NULL, the internal/default notes_tree will be
- * used instead.
- *
- * 'flags' is a bitwise combination of the above formatting flags.
- */
-void format_note(struct notes_tree *t, const unsigned char *object_sha1,
- struct strbuf *sb, const char *output_encoding, int flags);
-
-
struct string_list;
struct display_notes_opt {
diff --git a/parse-options.h b/parse-options.h
index 77a4a8b..71a39c6 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -238,6 +238,6 @@ extern int parse_opt_noop_cb(const struct option *, const char *, int);
#define OPT__COLOR(var, h) \
OPT_COLOR_FLAG(0, "color", (var), (h))
#define OPT_COLUMN(s, l, v, h) \
- { OPTION_CALLBACK, (s), (l), (v), "style", (h), PARSE_OPT_OPTARG, parseopt_column_callback }
+ { OPTION_CALLBACK, (s), (l), (v), N_("style"), (h), PARSE_OPT_OPTARG, parseopt_column_callback }
#endif
diff --git a/path.c b/path.c
index 66acd24..cbbdf7d 100644
--- a/path.c
+++ b/path.c
@@ -48,7 +48,7 @@ char *mksnpath(char *buf, size_t n, const char *fmt, ...)
return cleanup_path(buf);
}
-static char *git_vsnpath(char *buf, size_t n, const char *fmt, va_list args)
+static char *vsnpath(char *buf, size_t n, const char *fmt, va_list args)
{
const char *git_dir = get_git_dir();
size_t len;
@@ -70,21 +70,22 @@ bad:
char *git_snpath(char *buf, size_t n, const char *fmt, ...)
{
+ char *ret;
va_list args;
va_start(args, fmt);
- (void)git_vsnpath(buf, n, fmt, args);
+ ret = vsnpath(buf, n, fmt, args);
va_end(args);
- return buf;
+ return ret;
}
char *git_pathdup(const char *fmt, ...)
{
- char path[PATH_MAX];
+ char path[PATH_MAX], *ret;
va_list args;
va_start(args, fmt);
- (void)git_vsnpath(path, sizeof(path), fmt, args);
+ ret = vsnpath(path, sizeof(path), fmt, args);
va_end(args);
- return xstrdup(path);
+ return xstrdup(ret);
}
char *mkpathdup(const char *fmt, ...)
@@ -118,23 +119,14 @@ char *mkpath(const char *fmt, ...)
char *git_path(const char *fmt, ...)
{
- const char *git_dir = get_git_dir();
char *pathname = get_pathname();
va_list args;
- unsigned len;
+ char *ret;
- len = strlen(git_dir);
- if (len > PATH_MAX-100)
- return bad_path;
- memcpy(pathname, git_dir, len);
- if (len && git_dir[len-1] != '/')
- pathname[len++] = '/';
va_start(args, fmt);
- len += vsnprintf(pathname + len, PATH_MAX - len, fmt, args);
+ ret = vsnpath(pathname, PATH_MAX, fmt, args);
va_end(args);
- if (len >= PATH_MAX)
- return bad_path;
- return cleanup_path(pathname);
+ return ret;
}
void home_config_paths(char **global, char **xdg, char *file)
diff --git a/perl/Git/SVN.pm b/perl/Git/SVN.pm
index 8478d0c..59215fa 100644
--- a/perl/Git/SVN.pm
+++ b/perl/Git/SVN.pm
@@ -23,7 +23,14 @@ use Git qw(
command_output_pipe
command_close_pipe
);
-use Git::SVN::Utils qw(fatal can_compress);
+use Git::SVN::Utils qw(
+ fatal
+ can_compress
+ join_paths
+ canonicalize_path
+ canonicalize_url
+ add_path_to_url
+);
my $can_use_yaml;
BEGIN {
@@ -195,9 +202,9 @@ sub read_all_remotes {
} elsif (m!^(.+)\.usesvmprops=\s*(.*)\s*$!) {
$r->{$1}->{svm} = {};
} elsif (m!^(.+)\.url=\s*(.*)\s*$!) {
- $r->{$1}->{url} = $2;
+ $r->{$1}->{url} = canonicalize_url($2);
} elsif (m!^(.+)\.pushurl=\s*(.*)\s*$!) {
- $r->{$1}->{pushurl} = $2;
+ $r->{$1}->{pushurl} = canonicalize_url($2);
} elsif (m!^(.+)\.ignore-refs=\s*(.*)\s*$!) {
$r->{$1}->{ignore_refs_regex} = $2;
} elsif (m!^(.+)\.(branches|tags)=$svn_refspec$!) {
@@ -290,7 +297,7 @@ sub find_existing_remote {
sub init_remote_config {
my ($self, $url, $no_write) = @_;
- $url =~ s!/+$!!; # strip trailing slash
+ $url = canonicalize_url($url);
my $r = read_all_remotes();
my $existing = find_existing_remote($url, $r);
if ($existing) {
@@ -314,12 +321,10 @@ sub init_remote_config {
print STDERR "Using higher level of URL: ",
"$url => $min_url\n";
}
- my $old_path = $self->{path};
- $self->{path} = $url;
- $self->{path} =~ s!^\Q$min_url\E(/|$)!!;
- if (length $old_path) {
- $self->{path} .= "/$old_path";
- }
+ my $old_path = $self->path;
+ $url =~ s!^\Q$min_url\E(/|$)!!;
+ $url = join_paths($url, $old_path);
+ $self->path($url);
$url = $min_url;
}
}
@@ -343,18 +348,22 @@ sub init_remote_config {
unless ($no_write) {
command_noisy('config',
"svn-remote.$self->{repo_id}.url", $url);
- $self->{path} =~ s{^/}{};
- $self->{path} =~ s{%([0-9A-F]{2})}{chr hex($1)}ieg;
+ my $path = $self->path;
+ $path =~ s{^/}{};
+ $path =~ s{%([0-9A-F]{2})}{chr hex($1)}ieg;
+ $self->path($path);
command_noisy('config', '--add',
"svn-remote.$self->{repo_id}.fetch",
- "$self->{path}:".$self->refname);
+ $self->path.":".$self->refname);
}
- $self->{url} = $url;
+ $self->url($url);
}
sub find_by_url { # repos_root and, path are optional
my ($class, $full_url, $repos_root, $path) = @_;
+ $full_url = canonicalize_url($full_url);
+
return undef unless defined $full_url;
remove_username($full_url);
remove_username($repos_root) if defined $repos_root;
@@ -393,6 +402,11 @@ sub find_by_url { # repos_root and, path are optional
}
$p =~ s#^\Q$z\E(?:/|$)#$prefix# or next;
}
+
+ # remote fetch paths are not URI escaped. Decode ours
+ # so they match
+ $p = uri_decode($p);
+
foreach my $f (keys %$fetch) {
next if $f ne $p;
return Git::SVN->new($fetch->{$f}, $repo_id, $f);
@@ -435,20 +449,25 @@ sub new {
}
}
my $self = _new($class, $repo_id, $ref_id, $path);
- if (!defined $self->{path} || !length $self->{path}) {
+ if (!defined $self->path || !length $self->path) {
my $fetch = command_oneline('config', '--get',
"svn-remote.$repo_id.fetch",
":$ref_id\$") or
die "Failed to read \"svn-remote.$repo_id.fetch\" ",
"\":$ref_id\$\" in config\n";
- ($self->{path}, undef) = split(/\s*:\s*/, $fetch);
+ my($path) = split(/\s*:\s*/, $fetch);
+ $self->path($path);
}
- $self->{path} =~ s{/+}{/}g;
- $self->{path} =~ s{\A/}{};
- $self->{path} =~ s{/\z}{};
- $self->{url} = command_oneline('config', '--get',
- "svn-remote.$repo_id.url") or
+ {
+ my $path = $self->path;
+ $path =~ s{\A/}{};
+ $path =~ s{/\z}{};
+ $self->path($path);
+ }
+ my $url = command_oneline('config', '--get',
+ "svn-remote.$repo_id.url") or
die "Failed to read \"svn-remote.$repo_id.url\" in config\n";
+ $self->url($url);
$self->{pushurl} = eval { command_oneline('config', '--get',
"svn-remote.$repo_id.pushurl") };
$self->rebuild;
@@ -552,8 +571,7 @@ sub _set_svm_vars {
# username is of no interest
$src =~ s{(^[a-z\+]*://)[^/@]*@}{$1};
- my $replace = $ra->{url};
- $replace .= "/$path" if length $path;
+ my $replace = add_path_to_url($ra->url, $path);
my $section = "svn-remote.$self->{repo_id}";
tmp_config("$section.svm-source", $src);
@@ -567,20 +585,21 @@ sub _set_svm_vars {
}
my $r = $ra->get_latest_revnum;
- my $path = $self->{path};
+ my $path = $self->path;
my %tried;
while (length $path) {
- unless ($tried{"$self->{url}/$path"}) {
+ my $try = add_path_to_url($self->url, $path);
+ unless ($tried{$try}) {
return $ra if $self->read_svm_props($ra, $path, $r);
- $tried{"$self->{url}/$path"} = 1;
+ $tried{$try} = 1;
}
$path =~ s#/?[^/]+$##;
}
die "Path: '$path' should be ''\n" if $path ne '';
return $ra if $self->read_svm_props($ra, $path, $r);
- $tried{"$self->{url}/$path"} = 1;
+ $tried{ add_path_to_url($self->url, $path) } = 1;
- if ($ra->{repos_root} eq $self->{url}) {
+ if ($ra->{repos_root} eq $self->url) {
die @err, (map { " $_\n" } keys %tried), "\n";
}
@@ -590,20 +609,21 @@ sub _set_svm_vars {
$path = $ra->{svn_path};
$ra = Git::SVN::Ra->new($ra->{repos_root});
while (length $path) {
- unless ($tried{"$ra->{url}/$path"}) {
+ my $try = add_path_to_url($ra->url, $path);
+ unless ($tried{$try}) {
$ok = $self->read_svm_props($ra, $path, $r);
last if $ok;
- $tried{"$ra->{url}/$path"} = 1;
+ $tried{$try} = 1;
}
$path =~ s#/?[^/]+$##;
}
die "Path: '$path' should be ''\n" if $path ne '';
$ok ||= $self->read_svm_props($ra, $path, $r);
- $tried{"$ra->{url}/$path"} = 1;
+ $tried{ add_path_to_url($ra->url, $path) } = 1;
if (!$ok) {
die @err, (map { " $_\n" } keys %tried), "\n";
}
- Git::SVN::Ra->new($self->{url});
+ Git::SVN::Ra->new($self->url);
}
sub svnsync {
@@ -670,7 +690,7 @@ sub ra_uuid {
if (!$@ && $uuid && $uuid =~ /^([a-f\d\-]{30,})$/i) {
$self->{ra_uuid} = $uuid;
} else {
- die "ra_uuid called without URL\n" unless $self->{url};
+ die "ra_uuid called without URL\n" unless $self->url;
$self->{ra_uuid} = $self->ra->get_uuid;
tmp_config('--add', $key, $self->{ra_uuid});
}
@@ -694,7 +714,7 @@ sub repos_root {
sub ra {
my ($self) = shift;
- my $ra = Git::SVN::Ra->new($self->{url});
+ my $ra = Git::SVN::Ra->new($self->url);
$self->_set_repos_root($ra->{repos_root});
if ($self->use_svm_props && !$self->{svm}) {
if ($self->no_metadata) {
@@ -728,7 +748,7 @@ sub prop_walk {
$path =~ s#^/*#/#g;
my $p = $path;
# Strip the irrelevant part of the path.
- $p =~ s#^/+\Q$self->{path}\E(/|$)#/#;
+ $p =~ s#^/+\Q@{[$self->path]}\E(/|$)#/#;
# Ensure the path is terminated by a `/'.
$p =~ s#/*$#/#;
@@ -749,7 +769,7 @@ sub prop_walk {
foreach (sort keys %$dirent) {
next if $dirent->{$_}->{kind} != $SVN::Node::dir;
- $self->prop_walk($self->{path} . $p . $_, $rev, $sub);
+ $self->prop_walk($self->path . $p . $_, $rev, $sub);
}
}
@@ -919,20 +939,19 @@ sub rewrite_uuid {
sub metadata_url {
my ($self) = @_;
- ($self->rewrite_root || $self->{url}) .
- (length $self->{path} ? '/' . $self->{path} : '');
+ my $url = $self->rewrite_root || $self->url;
+ return canonicalize_url( add_path_to_url( $url, $self->path ) );
}
sub full_url {
my ($self) = @_;
- $self->{url} . (length $self->{path} ? '/' . $self->{path} : '');
+ return canonicalize_url( add_path_to_url( $self->url, $self->path ) );
}
sub full_pushurl {
my ($self) = @_;
if ($self->{pushurl}) {
- return $self->{pushurl} . (length $self->{path} ? '/' .
- $self->{path} : '');
+ return canonicalize_url( add_path_to_url( $self->{pushurl}, $self->path ) );
} else {
return $self->full_url;
}
@@ -1048,20 +1067,20 @@ sub do_git_commit {
sub match_paths {
my ($self, $paths, $r) = @_;
- return 1 if $self->{path} eq '';
- if (my $path = $paths->{"/$self->{path}"}) {
+ return 1 if $self->path eq '';
+ if (my $path = $paths->{"/".$self->path}) {
return ($path->{action} eq 'D') ? 0 : 1;
}
- $self->{path_regex} ||= qr/^\/\Q$self->{path}\E\//;
+ $self->{path_regex} ||= qr{^/\Q@{[$self->path]}\E/};
if (grep /$self->{path_regex}/, keys %$paths) {
return 1;
}
my $c = '';
- foreach (split m#/#, $self->{path}) {
+ foreach (split m#/#, $self->path) {
$c .= "/$_";
next unless ($paths->{$c} &&
($paths->{$c}->{action} =~ /^[AR]$/));
- if ($self->ra->check_path($self->{path}, $r) ==
+ if ($self->ra->check_path($self->path, $r) ==
$SVN::Node::dir) {
return 1;
}
@@ -1075,14 +1094,14 @@ sub find_parent_branch {
unless (defined $paths) {
my $err_handler = $SVN::Error::handler;
$SVN::Error::handler = \&Git::SVN::Ra::skip_unknown_revs;
- $self->ra->get_log([$self->{path}], $rev, $rev, 0, 1, 1,
+ $self->ra->get_log([$self->path], $rev, $rev, 0, 1, 1,
sub { $paths = $_[0] });
$SVN::Error::handler = $err_handler;
}
return undef unless defined $paths;
# look for a parent from another branch:
- my @b_path_components = split m#/#, $self->{path};
+ my @b_path_components = split m#/#, $self->path;
my @a_path_components;
my $i;
while (@b_path_components) {
@@ -1099,8 +1118,8 @@ sub find_parent_branch {
}
my $r = $i->{copyfrom_rev};
my $repos_root = $self->ra->{repos_root};
- my $url = $self->ra->{url};
- my $new_url = $url . $branch_from;
+ my $url = $self->ra->url;
+ my $new_url = canonicalize_url( add_path_to_url( $url, $branch_from ) );
print STDERR "Found possible branch point: ",
"$new_url => ", $self->full_url, ", $r\n"
unless $::_q > 1;
@@ -1114,7 +1133,7 @@ sub find_parent_branch {
($base, $head) = parse_revision_argument(0, $r);
} else {
if ($r0 < $r) {
- $gs->ra->get_log([$gs->{path}], $r0 + 1, $r, 1,
+ $gs->ra->get_log([$gs->path], $r0 + 1, $r, 1,
0, 1, sub { $base = $_[1] - 1 });
}
}
@@ -1136,7 +1155,7 @@ sub find_parent_branch {
# at the moment), so we can't rely on it
$self->{last_rev} = $r0;
$self->{last_commit} = $parent;
- $ed = Git::SVN::Fetcher->new($self, $gs->{path});
+ $ed = Git::SVN::Fetcher->new($self, $gs->path);
$gs->ra->gs_do_switch($r0, $rev, $gs,
$self->full_url, $ed)
or die "SVN connection failed somewhere...\n";
@@ -1235,7 +1254,7 @@ sub mkemptydirs {
close $fh;
}
- my $strip = qr/\A\Q$self->{path}\E(?:\/|$)/;
+ my $strip = qr/\A\Q@{[$self->path]}\E(?:\/|$)/;
foreach my $d (sort keys %empty_dirs) {
$d = uri_decode($d);
$d =~ s/$strip//;
@@ -1429,12 +1448,11 @@ sub find_extra_svk_parents {
for my $ticket ( @tickets ) {
my ($uuid, $path, $rev) = split /:/, $ticket;
if ( $uuid eq $self->ra_uuid ) {
- my $url = $self->{url};
- my $repos_root = $url;
+ my $repos_root = $self->url;
my $branch_from = $path;
$branch_from =~ s{^/}{};
- my $gs = $self->other_gs($repos_root."/".$branch_from,
- $url,
+ my $gs = $self->other_gs(add_path_to_url( $repos_root, $branch_from ),
+ $repos_root,
$branch_from,
$rev,
$self->{ref_id});
@@ -1661,7 +1679,6 @@ sub parents_exclude {
if ( $commit eq $excluded ) {
push @excluded, $commit;
$found++;
- last;
}
else {
push @new, $commit;
@@ -1693,16 +1710,16 @@ sub find_extra_svn_parents {
# are now marked as merge, we can add the tip as a parent.
my @merges = split "\n", $mergeinfo;
my @merge_tips;
- my $url = $self->{url};
+ my $url = $self->url;
my $uuid = $self->ra_uuid;
- my %ranges;
+ my @all_ranges;
for my $merge ( @merges ) {
my ($tip_commit, @ranges) =
lookup_svn_merge( $uuid, $url, $merge );
unless (!$tip_commit or
grep { $_ eq $tip_commit } @$parents ) {
push @merge_tips, $tip_commit;
- $ranges{$tip_commit} = \@ranges;
+ push @all_ranges, @ranges;
} else {
push @merge_tips, undef;
}
@@ -1717,8 +1734,6 @@ sub find_extra_svn_parents {
my $spec = shift @merges;
next unless $merge_tip and $excluded{$merge_tip};
- my $ranges = $ranges{$merge_tip};
-
# check out 'new' tips
my $merge_base;
eval {
@@ -1740,7 +1755,7 @@ sub find_extra_svn_parents {
my (@incomplete) = check_cherry_pick(
$merge_base, $merge_tip,
$parents,
- @$ranges,
+ @all_ranges,
);
if ( @incomplete ) {
@@ -1875,8 +1890,9 @@ sub make_log_entry {
$email ||= "$author\@$uuid";
$commit_email ||= "$author\@$uuid";
} elsif ($self->use_svnsync_props) {
- my $full_url = $self->svnsync->{url};
- $full_url .= "/$self->{path}" if length $self->{path};
+ my $full_url = canonicalize_url(
+ add_path_to_url( $self->svnsync->{url}, $self->path )
+ );
remove_username($full_url);
my $uuid = $self->svnsync->{uuid};
$log_entry{metadata} = "$full_url\@$rev $uuid";
@@ -1923,7 +1939,7 @@ sub set_tree {
tree_b => $tree,
editor_cb => sub {
$self->set_tree_cb($log_entry, $tree, @_) },
- svn_path => $self->{path} );
+ svn_path => $self->path );
if (!Git::SVN::Editor->new(\%ed_opts)->apply_diff) {
print "No changes\nr$self->{last_rev} = $tree\n";
}
@@ -2299,10 +2315,39 @@ sub _new {
$_[3] = $path = '' unless (defined $path);
mkpath([$dir]);
- bless {
+ my $obj = bless {
ref_id => $ref_id, dir => $dir, index => "$dir/index",
- path => $path, config => "$ENV{GIT_DIR}/svn/config",
+ config => "$ENV{GIT_DIR}/svn/config",
map_root => "$dir/.rev_map", repo_id => $repo_id }, $class;
+
+ # Ensure it gets canonicalized
+ $obj->path($path);
+
+ return $obj;
+}
+
+sub path {
+ my $self = shift;
+
+ if (@_) {
+ my $path = shift;
+ $self->{_path} = canonicalize_path($path);
+ return;
+ }
+
+ return $self->{_path};
+}
+
+sub url {
+ my $self = shift;
+
+ if (@_) {
+ my $url = shift;
+ $self->{url} = canonicalize_url($url);
+ return;
+ }
+
+ return $self->{url};
}
# for read-only access of old .rev_db formats
diff --git a/perl/Git/SVN/Editor.pm b/perl/Git/SVN/Editor.pm
index 755092f..3bbc20a 100644
--- a/perl/Git/SVN/Editor.pm
+++ b/perl/Git/SVN/Editor.pm
@@ -345,7 +345,30 @@ sub M {
$self->close_file($fbat,undef,$self->{pool});
}
-sub T { shift->M(@_) }
+sub T {
+ my ($self, $m, $deletions) = @_;
+
+ # Work around subversion issue 4091: toggling the "is a
+ # symlink" property requires removing and re-adding a
+ # file or else "svn up" on affected clients trips an
+ # assertion and aborts.
+ if (($m->{mode_b} =~ /^120/ && $m->{mode_a} !~ /^120/) ||
+ ($m->{mode_b} !~ /^120/ && $m->{mode_a} =~ /^120/)) {
+ $self->D({
+ mode_a => $m->{mode_a}, mode_b => '000000',
+ sha1_a => $m->{sha1_a}, sha1_b => '0' x 40,
+ chg => 'D', file_b => $m->{file_b}
+ });
+ $self->A({
+ mode_a => '000000', mode_b => $m->{mode_b},
+ sha1_a => '0' x 40, sha1_b => $m->{sha1_b},
+ chg => 'A', file_b => $m->{file_b}
+ });
+ return;
+ }
+
+ $self->M($m, $deletions);
+}
sub change_file_prop {
my ($self, $fbat, $pname, $pval) = @_;
diff --git a/perl/Git/SVN/Fetcher.pm b/perl/Git/SVN/Fetcher.pm
index 76fae9b..046a7a2 100644
--- a/perl/Git/SVN/Fetcher.pm
+++ b/perl/Git/SVN/Fetcher.pm
@@ -83,7 +83,7 @@ sub _mark_empty_symlinks {
chomp(my $empty_blob = `git hash-object -t blob --stdin < /dev/null`);
my ($ls, $ctx) = command_output_pipe(qw/ls-tree -r -z/, $cmt);
local $/ = "\0";
- my $pfx = defined($switch_path) ? $switch_path : $git_svn->{path};
+ my $pfx = defined($switch_path) ? $switch_path : $git_svn->path;
$pfx .= '/' if length($pfx);
while (<$ls>) {
chomp;
diff --git a/perl/Git/SVN/GlobSpec.pm b/perl/Git/SVN/GlobSpec.pm
index 96cfd98..c95f5d7 100644
--- a/perl/Git/SVN/GlobSpec.pm
+++ b/perl/Git/SVN/GlobSpec.pm
@@ -44,7 +44,9 @@ sub new {
my $right = join('/', @right);
$re = join('/', @patterns);
$re = join('\/',
- grep(length, quotemeta($left), "($re)", quotemeta($right)));
+ grep(length, quotemeta($left),
+ "($re)(?=/|\$)",
+ quotemeta($right)));
my $left_re = qr/^\/\Q$left\E(\/|$)/;
bless { left => $left, right => $right, left_regex => $left_re,
regex => qr/$re/, glob => $glob, depth => $depth }, $class;
diff --git a/perl/Git/SVN/Migration.pm b/perl/Git/SVN/Migration.pm
index 75d7429..30daf35 100644
--- a/perl/Git/SVN/Migration.pm
+++ b/perl/Git/SVN/Migration.pm
@@ -177,14 +177,14 @@ sub minimize_connections {
my $ra = Git::SVN::Ra->new($url);
# skip existing cases where we already connect to the root
- if (($ra->{url} eq $ra->{repos_root}) ||
+ if (($ra->url eq $ra->{repos_root}) ||
($ra->{repos_root} eq $repo_id)) {
- $root_repos->{$ra->{url}} = $repo_id;
+ $root_repos->{$ra->url} = $repo_id;
next;
}
my $root_ra = Git::SVN::Ra->new($ra->{repos_root});
- my $root_path = $ra->{url};
+ my $root_path = $ra->url;
$root_path =~ s#^\Q$ra->{repos_root}\E(/|$)##;
foreach my $path (keys %$fetch) {
my $ref_id = $fetch->{$path};
diff --git a/perl/Git/SVN/Ra.pm b/perl/Git/SVN/Ra.pm
index 23ff43e..049c97b 100644
--- a/perl/Git/SVN/Ra.pm
+++ b/perl/Git/SVN/Ra.pm
@@ -3,6 +3,12 @@ use vars qw/@ISA $config_dir $_ignore_refs_regex $_log_window_size/;
use strict;
use warnings;
use SVN::Client;
+use Git::SVN::Utils qw(
+ canonicalize_url
+ canonicalize_path
+ add_path_to_url
+);
+
use SVN::Ra;
BEGIN {
@ISA = qw(SVN::Ra);
@@ -62,29 +68,11 @@ sub _auth_providers () {
\@rv;
}
-sub escape_uri_only {
- my ($uri) = @_;
- my @tmp;
- foreach (split m{/}, $uri) {
- s/([^~\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
- push @tmp, $_;
- }
- join('/', @tmp);
-}
-
-sub escape_url {
- my ($url) = @_;
- if ($url =~ m#^(https?)://([^/]+)(.*)$#) {
- my ($scheme, $domain, $uri) = ($1, $2, escape_uri_only($3));
- $url = "$scheme://$domain$uri";
- }
- $url;
-}
sub new {
my ($class, $url) = @_;
- $url =~ s!/+$!!;
- return $RA if ($RA && $RA->{url} eq $url);
+ $url = canonicalize_url($url);
+ return $RA if ($RA && $RA->url eq $url);
::_req_svn();
@@ -115,17 +103,34 @@ sub new {
$Git::SVN::Prompt::_no_auth_cache = 1;
}
} # no warnings 'once'
- my $self = SVN::Ra->new(url => escape_url($url), auth => $baton,
+
+ my $self = SVN::Ra->new(url => $url, auth => $baton,
config => $config,
pool => SVN::Pool->new,
auth_provider_callbacks => $callbacks);
- $self->{url} = $url;
+ $RA = bless $self, $class;
+
+ # Make sure its canonicalized
+ $self->url($url);
$self->{svn_path} = $url;
$self->{repos_root} = $self->get_repos_root;
$self->{svn_path} =~ s#^\Q$self->{repos_root}\E(/|$)##;
$self->{cache} = { check_path => { r => 0, data => {} },
get_dir => { r => 0, data => {} } };
- $RA = bless $self, $class;
+
+ return $RA;
+}
+
+sub url {
+ my $self = shift;
+
+ if (@_) {
+ my $url = shift;
+ $self->{url} = canonicalize_url($url);
+ return;
+ }
+
+ return $self->{url};
}
sub check_path {
@@ -195,6 +200,7 @@ sub get_log {
qw/copyfrom_path copyfrom_rev action/;
if ($s{'copyfrom_path'}) {
$s{'copyfrom_path'} =~ s/$prefix_regex//;
+ $s{'copyfrom_path'} = canonicalize_path($s{'copyfrom_path'});
}
$_[0]{$p} = \%s;
}
@@ -246,7 +252,7 @@ sub get_commit_editor {
sub gs_do_update {
my ($self, $rev_a, $rev_b, $gs, $editor) = @_;
my $new = ($rev_a == $rev_b);
- my $path = $gs->{path};
+ my $path = $gs->path;
if ($new && -e $gs->{index}) {
unlink $gs->{index} or die
@@ -282,30 +288,33 @@ sub gs_do_update {
# svn_ra_reparent didn't work before 1.4)
sub gs_do_switch {
my ($self, $rev_a, $rev_b, $gs, $url_b, $editor) = @_;
- my $path = $gs->{path};
+ my $path = $gs->path;
my $pool = SVN::Pool->new;
- my $full_url = $self->{url};
- my $old_url = $full_url;
- $full_url .= '/' . $path if length $path;
+ my $old_url = $self->url;
+ my $full_url = add_path_to_url( $self->url, $path );
my ($ra, $reparented);
if ($old_url =~ m#^svn(\+ssh)?://# ||
($full_url =~ m#^https?://# &&
- escape_url($full_url) ne $full_url)) {
+ canonicalize_url($full_url) ne $full_url)) {
$_[0] = undef;
$self = undef;
$RA = undef;
$ra = Git::SVN::Ra->new($full_url);
$ra_invalid = 1;
} elsif ($old_url ne $full_url) {
- SVN::_Ra::svn_ra_reparent($self->{session}, $full_url, $pool);
- $self->{url} = $full_url;
+ SVN::_Ra::svn_ra_reparent(
+ $self->{session},
+ canonicalize_url($full_url),
+ $pool
+ );
+ $self->url($full_url);
$reparented = 1;
}
$ra ||= $self;
- $url_b = escape_url($url_b);
+ $url_b = canonicalize_url($url_b);
my $reporter = $ra->do_switch($rev_b, '', 1, $url_b, $editor, $pool);
my @lock = (::compare_svn_version('1.2.0') >= 0) ? (undef) : ();
$reporter->set_path('', $rev_a, 0, @lock, $pool);
@@ -313,7 +322,7 @@ sub gs_do_switch {
if ($reparented) {
SVN::_Ra::svn_ra_reparent($self->{session}, $old_url, $pool);
- $self->{url} = $old_url;
+ $self->url($old_url);
}
$pool->clear;
@@ -326,7 +335,7 @@ sub longest_common_path {
my $common_max = scalar @$gsv;
foreach my $gs (@$gsv) {
- my @tmp = split m#/#, $gs->{path};
+ my @tmp = split m#/#, $gs->path;
my $p = '';
foreach (@tmp) {
$p .= length($p) ? "/$_" : $_;
@@ -362,7 +371,7 @@ sub gs_fetch_loop_common {
my $inc = $_log_window_size;
my ($min, $max) = ($base, $head < $base + $inc ? $head : $base + $inc);
my $longest_path = longest_common_path($gsv, $globs);
- my $ra_url = $self->{url};
+ my $ra_url = $self->url;
my $find_trailing_edge;
while (1) {
my %revs;
@@ -407,7 +416,7 @@ sub gs_fetch_loop_common {
}
$SVN::Error::handler = $err_handler;
- my %exists = map { $_->{path} => $_ } @$gsv;
+ my %exists = map { $_->path => $_ } @$gsv;
foreach my $r (sort {$a <=> $b} keys %revs) {
my ($paths, $logged) = @{$revs{$r}};
@@ -508,7 +517,7 @@ sub match_globs {
($self->check_path($p, $r) !=
$SVN::Node::dir));
next unless $p =~ /$g->{path}->{regex}/;
- $exists->{$p} = Git::SVN->init($self->{url}, $p, undef,
+ $exists->{$p} = Git::SVN->init($self->url, $p, undef,
$g->{ref}->full_path($de), 1);
}
}
@@ -532,7 +541,7 @@ sub match_globs {
next if ($self->check_path($pathname, $r) !=
$SVN::Node::dir);
$exists->{$pathname} = Git::SVN->init(
- $self->{url}, $pathname, undef,
+ $self->url, $pathname, undef,
$g->{ref}->full_path($p), 1);
}
my $c = '';
@@ -548,19 +557,20 @@ sub match_globs {
sub minimize_url {
my ($self) = @_;
- return $self->{url} if ($self->{url} eq $self->{repos_root});
+ return $self->url if ($self->url eq $self->{repos_root});
my $url = $self->{repos_root};
my @components = split(m!/!, $self->{svn_path});
my $c = '';
do {
- $url .= "/$c" if length $c;
+ $url = add_path_to_url($url, $c);
eval {
my $ra = (ref $self)->new($url);
my $latest = $ra->get_latest_revnum;
$ra->get_log("", $latest, 0, 1, 0, 1, sub {});
};
} while ($@ && ($c = shift @components));
- $url;
+
+ return canonicalize_url($url);
}
sub can_do_switch {
@@ -568,7 +578,7 @@ sub can_do_switch {
unless (defined $can_do_switch) {
my $pool = SVN::Pool->new;
my $rep = eval {
- $self->do_switch(1, '', 0, $self->{url},
+ $self->do_switch(1, '', 0, $self->url,
SVN::Delta::Editor->new, $pool);
};
if ($@) {
diff --git a/perl/Git/SVN/Utils.pm b/perl/Git/SVN/Utils.pm
index 496006b..8b8cf37 100644
--- a/perl/Git/SVN/Utils.pm
+++ b/perl/Git/SVN/Utils.pm
@@ -3,9 +3,18 @@ package Git::SVN::Utils;
use strict;
use warnings;
+use SVN::Core;
+
use base qw(Exporter);
-our @EXPORT_OK = qw(fatal can_compress);
+our @EXPORT_OK = qw(
+ fatal
+ can_compress
+ canonicalize_path
+ canonicalize_url
+ join_paths
+ add_path_to_url
+);
=head1 NAME
@@ -56,4 +65,168 @@ sub can_compress {
}
+=head3 canonicalize_path
+
+ my $canoncalized_path = canonicalize_path($path);
+
+Converts $path into a canonical form which is safe to pass to the SVN
+API as a file path.
+
+=cut
+
+# Turn foo/../bar into bar
+sub _collapse_dotdot {
+ my $path = shift;
+
+ 1 while $path =~ s{/[^/]+/+\.\.}{};
+ 1 while $path =~ s{[^/]+/+\.\./}{};
+ 1 while $path =~ s{[^/]+/+\.\.}{};
+
+ return $path;
+}
+
+
+sub canonicalize_path {
+ my $path = shift;
+ my $rv;
+
+ # The 1.7 way to do it
+ if ( defined &SVN::_Core::svn_dirent_canonicalize ) {
+ $path = _collapse_dotdot($path);
+ $rv = SVN::_Core::svn_dirent_canonicalize($path);
+ }
+ # The 1.6 way to do it
+ # This can return undef on subversion-perl-1.4.2-2.el5 (CentOS 5.2)
+ elsif ( defined &SVN::_Core::svn_path_canonicalize ) {
+ $path = _collapse_dotdot($path);
+ $rv = SVN::_Core::svn_path_canonicalize($path);
+ }
+
+ return $rv if defined $rv;
+
+ # No SVN API canonicalization is available, or the SVN API
+ # didn't return a successful result, do it ourselves
+ return _canonicalize_path_ourselves($path);
+}
+
+
+sub _canonicalize_path_ourselves {
+ my ($path) = @_;
+ my $dot_slash_added = 0;
+ if (substr($path, 0, 1) ne "/") {
+ $path = "./" . $path;
+ $dot_slash_added = 1;
+ }
+ $path =~ s#/+#/#g;
+ $path =~ s#/\.(?:/|$)#/#g;
+ $path = _collapse_dotdot($path);
+ $path =~ s#/$##g;
+ $path =~ s#^\./## if $dot_slash_added;
+ $path =~ s#^\.$##;
+ return $path;
+}
+
+
+=head3 canonicalize_url
+
+ my $canonicalized_url = canonicalize_url($url);
+
+Converts $url into a canonical form which is safe to pass to the SVN
+API as a URL.
+
+=cut
+
+sub canonicalize_url {
+ my $url = shift;
+
+ # The 1.7 way to do it
+ if ( defined &SVN::_Core::svn_uri_canonicalize ) {
+ return SVN::_Core::svn_uri_canonicalize($url);
+ }
+ # There wasn't a 1.6 way to do it, so we do it ourself.
+ else {
+ return _canonicalize_url_ourselves($url);
+ }
+}
+
+
+sub _canonicalize_url_path {
+ my ($uri_path) = @_;
+
+ my @parts;
+ foreach my $part (split m{/+}, $uri_path) {
+ $part =~ s/([^~\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
+ push @parts, $part;
+ }
+
+ return join('/', @parts);
+}
+
+sub _canonicalize_url_ourselves {
+ my ($url) = @_;
+ if ($url =~ m#^([^:]+)://([^/]*)(.*)$#) {
+ my ($scheme, $domain, $uri) = ($1, $2, _canonicalize_url_path(canonicalize_path($3)));
+ $url = "$scheme://$domain$uri";
+ }
+ $url;
+}
+
+
+=head3 join_paths
+
+ my $new_path = join_paths(@paths);
+
+Appends @paths together into a single path. Any empty paths are ignored.
+
+=cut
+
+sub join_paths {
+ my @paths = @_;
+
+ @paths = grep { defined $_ && length $_ } @paths;
+
+ return '' unless @paths;
+ return $paths[0] if @paths == 1;
+
+ my $new_path = shift @paths;
+ $new_path =~ s{/+$}{};
+
+ my $last_path = pop @paths;
+ $last_path =~ s{^/+}{};
+
+ for my $path (@paths) {
+ $path =~ s{^/+}{};
+ $path =~ s{/+$}{};
+ $new_path .= "/$path";
+ }
+
+ return $new_path .= "/$last_path";
+}
+
+
+=head3 add_path_to_url
+
+ my $new_url = add_path_to_url($url, $path);
+
+Appends $path onto the $url. If $path is empty, $url is returned unchanged.
+
+=cut
+
+sub add_path_to_url {
+ my($url, $path) = @_;
+
+ return $url if !defined $path or !length $path;
+
+ # Strip trailing and leading slashes so we don't
+ # wind up with http://x.com///path
+ $url =~ s{/+$}{};
+ $path =~ s{^/+}{};
+
+ # If a path has a % in it, URI escape it so it's not
+ # mistaken for a URI escape later.
+ $path =~ s{%}{%25}g;
+
+ return join '/', $url, $path;
+}
+
1;
diff --git a/po/TEAMS b/po/TEAMS
index e9ebc8c..1b9e994 100644
--- a/po/TEAMS
+++ b/po/TEAMS
@@ -33,8 +33,9 @@ Repository: https://github.com/nafmo/git-l10n-sv/
Leader: Peter Krefting <peter@softwolves.pp.se>
Language: vi (Vietnamese)
-Repository: https://github.com/vnwildman/git.git
+Repository: https://github.com/vnwildman/git/
Leader: Trần Ngọc Quân <vnwildman AT gmail.com>
+Members: Nguyễn Thái Ngọc Duy <pclouds AT gmail.com>
Language: zh_CN (Simplified Chinese)
Repository: https://github.com/gotgit/git-po-zh_CN/
diff --git a/po/de.po b/po/de.po
index 9e9f2da..0db9a9b 100644
--- a/po/de.po
+++ b/po/de.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: git 1.7.12\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-08-06 23:47+0800\n"
+"POT-Creation-Date: 2012-09-05 06:20+0800\n"
"PO-Revision-Date: 2012-03-28 18:46+0200\n"
"Last-Translator: Ralf Thielow <ralf.thielow@googlemail.com>\n"
"Language-Team: German\n"
@@ -58,7 +58,7 @@ msgid "Repository lacks these prerequisite commits:"
msgstr "Dem Projektarchiv fehlen folgende vorausgesetzte Versionen:"
#: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
-#: builtin/log.c:726 builtin/log.c:1316 builtin/log.c:1535 builtin/merge.c:347
+#: builtin/log.c:727 builtin/log.c:1313 builtin/log.c:1529 builtin/merge.c:347
#: builtin/shortlog.c:181
msgid "revision walk setup failed"
msgstr "Einrichtung des Revisionsgangs fehlgeschlagen"
@@ -85,7 +85,7 @@ msgstr[1] "Das Paket benötigt diese %d Referenzen"
msgid "rev-list died"
msgstr "\"rev-list\" abgebrochen"
-#: bundle.c:300 builtin/log.c:1212 builtin/shortlog.c:284
+#: bundle.c:300 builtin/log.c:1209 builtin/shortlog.c:284
#, c-format
msgid "unrecognized argument: %s"
msgstr "nicht erkanntes Argument: %s"
@@ -231,32 +231,32 @@ msgstr ""
"Fehler in 'diff.dirstat' Konfigurationsvariable gefunden:\n"
"%s"
-#: diff.c:1400
+#: diff.c:1401
msgid " 0 files changed"
msgstr " 0 Dateien geändert"
-#: diff.c:1404
+#: diff.c:1405
#, c-format
msgid " %d file changed"
msgid_plural " %d files changed"
msgstr[0] " %d Datei geändert"
msgstr[1] " %d Dateien geändert"
-#: diff.c:1421
+#: diff.c:1422
#, c-format
msgid ", %d insertion(+)"
msgid_plural ", %d insertions(+)"
msgstr[0] ", %d Zeile hinzugefügt(+)"
msgstr[1] ", %d Zeilen hinzugefügt(+)"
-#: diff.c:1432
+#: diff.c:1433
#, c-format
msgid ", %d deletion(-)"
msgid_plural ", %d deletions(-)"
msgstr[0] ", %d Zeile entfernt(-)"
msgstr[1] ", %d Zeilen entfernt(-)"
-#: diff.c:3461
+#: diff.c:3460
#, c-format
msgid ""
"Failed to parse --dirstat/-X option parameter:\n"
@@ -361,74 +361,66 @@ msgstr "addinfo_cache für Pfad '%s' fehlgeschlagen"
msgid "error building trees"
msgstr "Fehler beim Erstellen der Bäume"
-#: merge-recursive.c:497
-msgid "diff setup failed"
-msgstr "diff_setup_done fehlgeschlagen"
-
-#: merge-recursive.c:627
-msgid "merge-recursive: disk full?"
-msgstr "merge-recursive: Festplatte voll?"
-
-#: merge-recursive.c:690
+#: merge-recursive.c:672
#, c-format
msgid "failed to create path '%s'%s"
msgstr "Fehler beim Erstellen des Pfades '%s'%s"
-#: merge-recursive.c:701
+#: merge-recursive.c:683
#, c-format
msgid "Removing %s to make room for subdirectory\n"
msgstr "Entferne %s um Platz für Unterverzeichnis zu schaffen\n"
#. something else exists
#. .. but not some other error (who really cares what?)
-#: merge-recursive.c:715 merge-recursive.c:736
+#: merge-recursive.c:697 merge-recursive.c:718
msgid ": perhaps a D/F conflict?"
msgstr ": vielleicht ein Verzeichnis/Datei-Konflikt?"
-#: merge-recursive.c:726
+#: merge-recursive.c:708
#, c-format
msgid "refusing to lose untracked file at '%s'"
msgstr "verweigere, da unbeobachtete Dateien in '%s' verloren gehen würden"
-#: merge-recursive.c:766
+#: merge-recursive.c:748
#, c-format
msgid "cannot read object %s '%s'"
msgstr "kann Objekt %s '%s' nicht lesen"
-#: merge-recursive.c:768
+#: merge-recursive.c:750
#, c-format
msgid "blob expected for %s '%s'"
msgstr "Blob erwartet für %s '%s'"
-#: merge-recursive.c:791 builtin/clone.c:302
+#: merge-recursive.c:773 builtin/clone.c:302
#, c-format
msgid "failed to open '%s'"
msgstr "Fehler beim Öffnen von '%s'"
-#: merge-recursive.c:799
+#: merge-recursive.c:781
#, c-format
msgid "failed to symlink '%s'"
msgstr "Fehler beim Erstellen einer symbolischen Verknüpfung für '%s'"
-#: merge-recursive.c:802
+#: merge-recursive.c:784
#, c-format
msgid "do not know what to do with %06o %s '%s'"
msgstr "weiß nicht was mit %06o %s '%s' zu machen ist"
-#: merge-recursive.c:939
+#: merge-recursive.c:921
msgid "Failed to execute internal merge"
msgstr "Fehler bei Ausführung der internen Zusammenführung"
-#: merge-recursive.c:943
+#: merge-recursive.c:925
#, c-format
msgid "Unable to add %s to database"
msgstr "Konnte %s nicht zur Datenbank hinzufügen"
-#: merge-recursive.c:959
+#: merge-recursive.c:941
msgid "unsupported object type in the tree"
msgstr "nicht unterstützter Objekttyp im Baum"
-#: merge-recursive.c:1038 merge-recursive.c:1052
+#: merge-recursive.c:1020 merge-recursive.c:1034
#, c-format
msgid ""
"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -437,7 +429,7 @@ msgstr ""
"KONFLIKT (%s/löschen): %s gelöscht in %s und %s in %s. Stand %s von %s wurde "
"im Arbeitsbereich gelassen."
-#: merge-recursive.c:1044 merge-recursive.c:1057
+#: merge-recursive.c:1026 merge-recursive.c:1039
#, c-format
msgid ""
"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -446,20 +438,20 @@ msgstr ""
"KONFLIKT (%s/löschen): %s gelöscht in %s und %s in %s. Stand %s von %s wurde "
"im Arbeitsbereich bei %s gelassen."
-#: merge-recursive.c:1098
+#: merge-recursive.c:1080
msgid "rename"
msgstr "umbenennen"
-#: merge-recursive.c:1098
+#: merge-recursive.c:1080
msgid "renamed"
msgstr "umbenannt"
-#: merge-recursive.c:1154
+#: merge-recursive.c:1136
#, c-format
msgid "%s is a directory in %s adding as %s instead"
msgstr "%s ist ein Verzeichnis in %s, füge es stattdessen als %s hinzu"
-#: merge-recursive.c:1176
+#: merge-recursive.c:1158
#, c-format
msgid ""
"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
@@ -468,148 +460,148 @@ msgstr ""
"KONFLIKT (umbenennen/umbenennen): Benenne um \"%s\"->\"%s\" in Zweig \"%s\" "
"und \"%s\"->\"%s\" in Zweig \"%s\"%s"
-#: merge-recursive.c:1181
+#: merge-recursive.c:1163
msgid " (left unresolved)"
msgstr " (bleibt unaufgelöst)"
-#: merge-recursive.c:1235
+#: merge-recursive.c:1217
#, c-format
msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
msgstr ""
"KONFLIKT (umbenennen/umbenennen): Benenne um %s->%s in %s. Benenne um %s->%s "
"in %s"
-#: merge-recursive.c:1265
+#: merge-recursive.c:1247
#, c-format
msgid "Renaming %s to %s and %s to %s instead"
msgstr "Benenne stattdessen %s nach %s und %s nach %s um"
-#: merge-recursive.c:1464
+#: merge-recursive.c:1446
#, c-format
msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
msgstr ""
"KONFLIKT (umbenennen/hinzufügen): Benenne um %s->%s in %s. %s hinzugefügt in "
"%s"
-#: merge-recursive.c:1474
+#: merge-recursive.c:1456
#, c-format
msgid "Adding merged %s"
msgstr "Füge zusammengeführte Datei %s hinzu"
-#: merge-recursive.c:1479 merge-recursive.c:1677
+#: merge-recursive.c:1461 merge-recursive.c:1659
#, c-format
msgid "Adding as %s instead"
msgstr "Füge stattdessen als %s hinzu"
-#: merge-recursive.c:1530
+#: merge-recursive.c:1512
#, c-format
msgid "cannot read object %s"
msgstr "kann Objekt %s nicht lesen"
-#: merge-recursive.c:1533
+#: merge-recursive.c:1515
#, c-format
msgid "object %s is not a blob"
msgstr "Objekt %s ist kein Blob"
-#: merge-recursive.c:1581
+#: merge-recursive.c:1563
msgid "modify"
msgstr "ändern"
-#: merge-recursive.c:1581
+#: merge-recursive.c:1563
msgid "modified"
msgstr "geändert"
-#: merge-recursive.c:1591
+#: merge-recursive.c:1573
msgid "content"
msgstr "Inhalt"
-#: merge-recursive.c:1598
+#: merge-recursive.c:1580
msgid "add/add"
msgstr "hinzufügen/hinzufügen"
-#: merge-recursive.c:1632
+#: merge-recursive.c:1614
#, c-format
msgid "Skipped %s (merged same as existing)"
msgstr "%s ausgelassen (Ergebnis der Zusammenführung existiert bereits)"
-#: merge-recursive.c:1646
+#: merge-recursive.c:1628
#, c-format
msgid "Auto-merging %s"
msgstr "automatische Zusammenführung von %s"
-#: merge-recursive.c:1650 git-submodule.sh:844
+#: merge-recursive.c:1632 git-submodule.sh:869
msgid "submodule"
msgstr "Unterprojekt"
-#: merge-recursive.c:1651
+#: merge-recursive.c:1633
#, c-format
msgid "CONFLICT (%s): Merge conflict in %s"
msgstr "KONFLIKT (%s): Zusammenführungskonflikt in %s"
-#: merge-recursive.c:1741
+#: merge-recursive.c:1723
#, c-format
msgid "Removing %s"
msgstr "Entferne %s"
-#: merge-recursive.c:1766
+#: merge-recursive.c:1748
msgid "file/directory"
msgstr "Datei/Verzeichnis"
-#: merge-recursive.c:1772
+#: merge-recursive.c:1754
msgid "directory/file"
msgstr "Verzeichnis/Datei"
-#: merge-recursive.c:1777
+#: merge-recursive.c:1759
#, c-format
msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
msgstr ""
"KONFLIKT (%s): Es existiert bereits ein Verzeichnis %s in %s. Füge %s als %s "
"hinzu."
-#: merge-recursive.c:1787
+#: merge-recursive.c:1769
#, c-format
msgid "Adding %s"
msgstr "Füge %s hinzu"
-#: merge-recursive.c:1804
+#: merge-recursive.c:1786
msgid "Fatal merge failure, shouldn't happen."
msgstr "Fataler Fehler bei der Zusammenführung. Sollte nicht passieren."
-#: merge-recursive.c:1823
+#: merge-recursive.c:1805
msgid "Already up-to-date!"
msgstr "Bereits aktuell!"
-#: merge-recursive.c:1832
+#: merge-recursive.c:1814
#, c-format
msgid "merging of trees %s and %s failed"
msgstr "Zusammenführen der Bäume %s und %s fehlgeschlagen"
-#: merge-recursive.c:1862
+#: merge-recursive.c:1844
#, c-format
msgid "Unprocessed path??? %s"
msgstr "unverarbeiteter Pfad??? %s"
-#: merge-recursive.c:1907
+#: merge-recursive.c:1889
msgid "Merging:"
msgstr "Zusammenführung:"
-#: merge-recursive.c:1920
+#: merge-recursive.c:1902
#, c-format
msgid "found %u common ancestor:"
msgid_plural "found %u common ancestors:"
msgstr[0] "%u gemeinsamen Vorfahren gefunden"
msgstr[1] "%u gemeinsame Vorfahren gefunden"
-#: merge-recursive.c:1957
+#: merge-recursive.c:1939
msgid "merge returned no commit"
msgstr "Zusammenführung hat keine Version zurückgegeben"
-#: merge-recursive.c:2014
+#: merge-recursive.c:1996
#, c-format
msgid "Could not parse object '%s'"
msgstr "Konnte Objekt '%s' nicht parsen."
-#: merge-recursive.c:2026 builtin/merge.c:697
+#: merge-recursive.c:2008 builtin/merge.c:696
msgid "Unable to write index."
msgstr "Konnte Bereitstellung nicht schreiben."
@@ -667,14 +659,14 @@ msgstr[1] ""
"Dein Zweig und '%s' sind divergiert,\n"
"und haben jeweils %d und %d unterschiedliche Versionen.\n"
-#: sequencer.c:121 builtin/merge.c:865 builtin/merge.c:978
-#: builtin/merge.c:1088 builtin/merge.c:1098
+#: sequencer.c:121 builtin/merge.c:864 builtin/merge.c:977
+#: builtin/merge.c:1087 builtin/merge.c:1097
#, c-format
msgid "Could not open '%s' for writing"
msgstr "Konnte '%s' nicht zum Schreiben öffnen."
-#: sequencer.c:123 builtin/merge.c:333 builtin/merge.c:868
-#: builtin/merge.c:1090 builtin/merge.c:1103
+#: sequencer.c:123 builtin/merge.c:333 builtin/merge.c:867
+#: builtin/merge.c:1089 builtin/merge.c:1102
#, c-format
msgid "Could not write to '%s'"
msgstr "Konnte nicht nach '%s' schreiben."
@@ -880,7 +872,7 @@ msgstr "kann Zweigspitze (HEAD) nicht auflösen"
msgid "cannot abort from a branch yet to be born"
msgstr "kann nicht abbrechen: bin auf einem Zweig, der noch geboren wird"
-#: sequencer.c:805 builtin/apply.c:3988
+#: sequencer.c:805 builtin/apply.c:3987
#, c-format
msgid "cannot open %s: %s"
msgstr "Kann %s nicht öffnen: %s"
@@ -1293,6 +1285,11 @@ msgstr "voraus "
msgid ", behind "
msgstr ", hinterher "
+#: compat/precompose_utf8.c:58 builtin/clone.c:341
+#, c-format
+msgid "failed to unlink '%s'"
+msgstr "Konnte '%s' nicht entfernen"
+
#: builtin/add.c:62
#, c-format
msgid "unexpected diff status %c"
@@ -1397,7 +1394,7 @@ msgstr "Wolltest du vielleicht 'git add .' sagen?\n"
msgid "index file corrupt"
msgstr "Bereitstellungsdatei beschädigt"
-#: builtin/add.c:480 builtin/apply.c:4433 builtin/mv.c:229 builtin/rm.c:260
+#: builtin/add.c:480 builtin/apply.c:4432 builtin/mv.c:229 builtin/rm.c:260
msgid "Unable to write new index file"
msgstr "Konnte neue Bereitstellungsdatei nicht schreiben."
@@ -1415,56 +1412,56 @@ msgstr "nicht erkannte Option für Leerzeichen: '%s'"
msgid "unrecognized whitespace ignore option '%s'"
msgstr "nicht erkannte Option zum Ignorieren von Leerzeichen: '%s'"
-#: builtin/apply.c:824
+#: builtin/apply.c:823
#, c-format
msgid "Cannot prepare timestamp regexp %s"
msgstr "Kann regulären Ausdruck für Zeitstempel %s nicht verarbeiten"
-#: builtin/apply.c:833
+#: builtin/apply.c:832
#, c-format
msgid "regexec returned %d for input: %s"
msgstr "Ausführung des regulären Ausdrucks gab %d zurück. Eingabe: %s"
-#: builtin/apply.c:914
+#: builtin/apply.c:913
#, c-format
msgid "unable to find filename in patch at line %d"
msgstr "Konnte keinen Dateinamen in Zeile %d des Patches finden."
-#: builtin/apply.c:946
+#: builtin/apply.c:945
#, c-format
msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
msgstr ""
"git apply: ungültiges 'git-diff' - erwartete /dev/null, erhielt %s in Zeile "
"%d"
-#: builtin/apply.c:950
+#: builtin/apply.c:949
#, c-format
msgid "git apply: bad git-diff - inconsistent new filename on line %d"
msgstr ""
"git apply: ungültiges 'git-diff' - Inkonsistenter neuer Dateiname in Zeile %d"
-#: builtin/apply.c:951
+#: builtin/apply.c:950
#, c-format
msgid "git apply: bad git-diff - inconsistent old filename on line %d"
msgstr ""
"git apply: ungültiges 'git-diff' - Inkonsistenter alter Dateiname in Zeile %d"
-#: builtin/apply.c:958
+#: builtin/apply.c:957
#, c-format
msgid "git apply: bad git-diff - expected /dev/null on line %d"
msgstr "git apply: ungültiges 'git-diff' - erwartete /dev/null in Zeile %d"
-#: builtin/apply.c:1403
+#: builtin/apply.c:1402
#, c-format
msgid "recount: unexpected line: %.*s"
msgstr "recount: unerwartete Zeile: %.*s"
-#: builtin/apply.c:1460
+#: builtin/apply.c:1459
#, c-format
msgid "patch fragment without header at line %d: %.*s"
msgstr "Patch-Fragment ohne Kopfbereich bei Zeile %d: %.*s"
-#: builtin/apply.c:1477
+#: builtin/apply.c:1476
#, c-format
msgid ""
"git diff header lacks filename information when removing %d leading pathname "
@@ -1479,70 +1476,70 @@ msgstr[1] ""
"Dem Kopfbereich von \"git diff\" fehlen Informationen zum Dateinamen, wenn "
"%d vorangestellte Teile des Pfades entfernt werden (Zeile %d)"
-#: builtin/apply.c:1637
+#: builtin/apply.c:1636
msgid "new file depends on old contents"
msgstr "neue Datei hängt von alten Inhalten ab"
-#: builtin/apply.c:1639
+#: builtin/apply.c:1638
msgid "deleted file still has contents"
msgstr "entfernte Datei hat noch Inhalte"
-#: builtin/apply.c:1665
+#: builtin/apply.c:1664
#, c-format
msgid "corrupt patch at line %d"
msgstr "fehlerhafter Patch bei Zeile %d"
-#: builtin/apply.c:1701
+#: builtin/apply.c:1700
#, c-format
msgid "new file %s depends on old contents"
msgstr "neue Datei %s hängt von alten Inhalten ab"
-#: builtin/apply.c:1703
+#: builtin/apply.c:1702
#, c-format
msgid "deleted file %s still has contents"
msgstr "entfernte Datei %s hat noch Inhalte"
-#: builtin/apply.c:1706
+#: builtin/apply.c:1705
#, c-format
msgid "** warning: file %s becomes empty but is not deleted"
msgstr "** Warnung: Datei %s wird leer, aber nicht entfernt."
-#: builtin/apply.c:1852
+#: builtin/apply.c:1851
#, c-format
msgid "corrupt binary patch at line %d: %.*s"
msgstr "fehlerhafter Binär-Patch bei Zeile %d: %.*s"
#. there has to be one hunk (forward hunk)
-#: builtin/apply.c:1881
+#: builtin/apply.c:1880
#, c-format
msgid "unrecognized binary patch at line %d"
msgstr "nicht erkannter Binär-Patch bei Zeile %d"
-#: builtin/apply.c:1967
+#: builtin/apply.c:1966
#, c-format
msgid "patch with only garbage at line %d"
msgstr "Patch mit nutzlosen Informationen bei Zeile %d"
-#: builtin/apply.c:2057
+#: builtin/apply.c:2056
#, c-format
msgid "unable to read symlink %s"
msgstr "konnte symbolische Verknüpfung %s nicht lesen"
-#: builtin/apply.c:2061
+#: builtin/apply.c:2060
#, c-format
msgid "unable to open or read %s"
msgstr "konnte %s nicht öffnen oder lesen"
-#: builtin/apply.c:2132
+#: builtin/apply.c:2131
msgid "oops"
msgstr "Ups"
-#: builtin/apply.c:2654
+#: builtin/apply.c:2653
#, c-format
msgid "invalid start of line: '%c'"
msgstr "Ungültiger Zeilenanfang: '%c'"
-#: builtin/apply.c:2772
+#: builtin/apply.c:2771
#, c-format
msgid "Hunk #%d succeeded at %d (offset %d line)."
msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
@@ -1550,12 +1547,12 @@ msgstr[0] "Patch-Bereich #%d erfolgreich angewendet bei %d (%d Zeile versetzt)"
msgstr[1] ""
"Patch-Bereich #%d erfolgreich angewendet bei %d (%d Zeilen versetzt)"
-#: builtin/apply.c:2784
+#: builtin/apply.c:2783
#, c-format
msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
msgstr "Kontext reduziert zu (%ld/%ld) um Patch-Bereich bei %d anzuwenden"
-#: builtin/apply.c:2790
+#: builtin/apply.c:2789
#, c-format
msgid ""
"while searching for:\n"
@@ -1564,339 +1561,339 @@ msgstr ""
"bei der Suche nach:\n"
"%.*s"
-#: builtin/apply.c:2809
+#: builtin/apply.c:2808
#, c-format
msgid "missing binary patch data for '%s'"
msgstr "keine Daten in Binär-Patch für '%s'"
-#: builtin/apply.c:2912
+#: builtin/apply.c:2911
#, c-format
msgid "binary patch does not apply to '%s'"
msgstr "Konnte Binär-Patch nicht auf '%s' anwenden"
-#: builtin/apply.c:2918
+#: builtin/apply.c:2917
#, c-format
msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
msgstr ""
"Binär-Patch für '%s' erzeugt falsches Ergebnis (erwartete %s, bekam %s)"
-#: builtin/apply.c:2939
+#: builtin/apply.c:2938
#, c-format
msgid "patch failed: %s:%ld"
msgstr "Anwendung des Patches fehlgeschlagen: %s:%ld"
-#: builtin/apply.c:3061
+#: builtin/apply.c:3060
#, c-format
msgid "cannot checkout %s"
msgstr "kann %s nicht auschecken"
-#: builtin/apply.c:3106 builtin/apply.c:3115 builtin/apply.c:3159
+#: builtin/apply.c:3105 builtin/apply.c:3114 builtin/apply.c:3158
#, c-format
msgid "read of %s failed"
msgstr "Konnte %s nicht lesen"
-#: builtin/apply.c:3139 builtin/apply.c:3361
+#: builtin/apply.c:3138 builtin/apply.c:3360
#, c-format
msgid "path %s has been renamed/deleted"
msgstr "Pfad %s wurde umbenannt/gelöscht"
-#: builtin/apply.c:3220 builtin/apply.c:3375
+#: builtin/apply.c:3219 builtin/apply.c:3374
#, c-format
msgid "%s: does not exist in index"
msgstr "%s ist nicht bereitgestellt"
-#: builtin/apply.c:3224 builtin/apply.c:3367 builtin/apply.c:3389
+#: builtin/apply.c:3223 builtin/apply.c:3366 builtin/apply.c:3388
#, c-format
msgid "%s: %s"
msgstr "%s: %s"
-#: builtin/apply.c:3229 builtin/apply.c:3383
+#: builtin/apply.c:3228 builtin/apply.c:3382
#, c-format
msgid "%s: does not match index"
msgstr "%s entspricht nicht der Bereitstellung"
-#: builtin/apply.c:3331
+#: builtin/apply.c:3330
msgid "removal patch leaves file contents"
msgstr "Lösch-Patch hinterlässt Dateiinhalte"
-#: builtin/apply.c:3400
+#: builtin/apply.c:3399
#, c-format
msgid "%s: wrong type"
msgstr "%s: falscher Typ"
-#: builtin/apply.c:3402
+#: builtin/apply.c:3401
#, c-format
msgid "%s has type %o, expected %o"
msgstr "%s ist vom Typ %o, erwartete %o"
-#: builtin/apply.c:3503
+#: builtin/apply.c:3502
#, c-format
msgid "%s: already exists in index"
msgstr "%s ist bereits bereitgestellt"
-#: builtin/apply.c:3506
+#: builtin/apply.c:3505
#, c-format
msgid "%s: already exists in working directory"
msgstr "%s existiert bereits im Arbeitsverzeichnis"
-#: builtin/apply.c:3526
+#: builtin/apply.c:3525
#, c-format
msgid "new mode (%o) of %s does not match old mode (%o)"
msgstr "neuer Modus (%o) von %s entspricht nicht dem alten Modus (%o)"
-#: builtin/apply.c:3531
+#: builtin/apply.c:3530
#, c-format
msgid "new mode (%o) of %s does not match old mode (%o) of %s"
msgstr "neuer Modus (%o) von %s entspricht nicht dem alten Modus (%o) von %s"
-#: builtin/apply.c:3539
+#: builtin/apply.c:3538
#, c-format
msgid "%s: patch does not apply"
msgstr "%s: Patch konnte nicht angewendet werden"
-#: builtin/apply.c:3552
+#: builtin/apply.c:3551
#, c-format
msgid "Checking patch %s..."
msgstr "Prüfe Patch %s..."
-#: builtin/apply.c:3607 builtin/checkout.c:213 builtin/reset.c:158
+#: builtin/apply.c:3606 builtin/checkout.c:213 builtin/reset.c:158
#, c-format
msgid "make_cache_entry failed for path '%s'"
msgstr "make_cache_entry für Pfad '%s' fehlgeschlagen"
-#: builtin/apply.c:3750
+#: builtin/apply.c:3749
#, c-format
msgid "unable to remove %s from index"
msgstr "konnte %s nicht aus der Bereitstellung entfernen"
-#: builtin/apply.c:3778
+#: builtin/apply.c:3777
#, c-format
msgid "corrupt patch for subproject %s"
msgstr "fehlerhafter Patch für Unterprojekt %s"
-#: builtin/apply.c:3782
+#: builtin/apply.c:3781
#, c-format
msgid "unable to stat newly created file '%s'"
msgstr "konnte neu erstellte Datei '%s' nicht lesen"
-#: builtin/apply.c:3787
+#: builtin/apply.c:3786
#, c-format
msgid "unable to create backing store for newly created file %s"
msgstr "kann internen Speicher für eben erstellte Datei %s nicht erzeugen"
-#: builtin/apply.c:3790 builtin/apply.c:3898
+#: builtin/apply.c:3789 builtin/apply.c:3897
#, c-format
msgid "unable to add cache entry for %s"
msgstr "kann für %s keinen Eintrag in den Zwischenspeicher hinzufügen"
-#: builtin/apply.c:3823
+#: builtin/apply.c:3822
#, c-format
msgid "closing file '%s'"
msgstr "schließe Datei '%s'"
-#: builtin/apply.c:3872
+#: builtin/apply.c:3871
#, c-format
msgid "unable to write file '%s' mode %o"
msgstr "konnte Datei '%s' mit Modus %o nicht schreiben"
-#: builtin/apply.c:3959
+#: builtin/apply.c:3958
#, c-format
msgid "Applied patch %s cleanly."
msgstr "Patch %s sauber angewendet"
-#: builtin/apply.c:3967
+#: builtin/apply.c:3966
msgid "internal error"
msgstr "interner Fehler"
#. Say this even without --verbose
-#: builtin/apply.c:3970
+#: builtin/apply.c:3969
#, c-format
msgid "Applying patch %%s with %d reject..."
msgid_plural "Applying patch %%s with %d rejects..."
msgstr[0] "Wende Patch %%s mit %d Zurückweisung an..."
msgstr[1] "Wende Patch %%s mit %d Zurückweisungen an..."
-#: builtin/apply.c:3980
+#: builtin/apply.c:3979
#, c-format
msgid "truncating .rej filename to %.*s.rej"
msgstr "Verkürze Name von .rej Datei zu %.*s.rej"
-#: builtin/apply.c:4001
+#: builtin/apply.c:4000
#, c-format
msgid "Hunk #%d applied cleanly."
msgstr "Patch-Bereich #%d sauber angewendet."
-#: builtin/apply.c:4004
+#: builtin/apply.c:4003
#, c-format
msgid "Rejected hunk #%d."
msgstr "Patch-Bereich #%d zurückgewiesen."
-#: builtin/apply.c:4154
+#: builtin/apply.c:4153
msgid "unrecognized input"
msgstr "nicht erkannte Eingabe"
-#: builtin/apply.c:4165
+#: builtin/apply.c:4164
msgid "unable to read index file"
msgstr "Konnte Bereitstellungsdatei nicht lesen"
-#: builtin/apply.c:4284 builtin/apply.c:4287
+#: builtin/apply.c:4283 builtin/apply.c:4286
msgid "path"
msgstr "Pfad"
-#: builtin/apply.c:4285
+#: builtin/apply.c:4284
msgid "don't apply changes matching the given path"
msgstr "wendet keine Änderungen im angegebenen Pfad an"
-#: builtin/apply.c:4288
+#: builtin/apply.c:4287
msgid "apply changes matching the given path"
msgstr "wendet Änderungen nur im angegebenen Pfad an"
-#: builtin/apply.c:4290
+#: builtin/apply.c:4289
msgid "num"
msgstr "Anzahl"
-#: builtin/apply.c:4291
+#: builtin/apply.c:4290
msgid "remove <num> leading slashes from traditional diff paths"
msgstr ""
"entfernt <Anzahl> vorangestellte Schrägstriche von herkömmlichen "
"Differenzpfaden"
-#: builtin/apply.c:4294
+#: builtin/apply.c:4293
msgid "ignore additions made by the patch"
msgstr "ignoriert hinzugefügte Zeilen des Patches"
-#: builtin/apply.c:4296
+#: builtin/apply.c:4295
msgid "instead of applying the patch, output diffstat for the input"
msgstr ""
"anstatt der Anwendung des Patches, wird der \"diffstat\" für die Eingabe "
"ausgegeben"
-#: builtin/apply.c:4300
+#: builtin/apply.c:4299
msgid "shows number of added and deleted lines in decimal notation"
msgstr ""
"zeigt die Anzahl von hinzugefügten/entfernten Zeilen in Dezimalnotation"
-#: builtin/apply.c:4302
+#: builtin/apply.c:4301
msgid "instead of applying the patch, output a summary for the input"
msgstr ""
"anstatt der Anwendung des Patches, wird eine Zusammenfassung für die Eingabe "
"ausgegeben"
-#: builtin/apply.c:4304
+#: builtin/apply.c:4303
msgid "instead of applying the patch, see if the patch is applicable"
msgstr ""
"anstatt der Anwendung des Patches, zeige ob Patch angewendet werden kann"
-#: builtin/apply.c:4306
+#: builtin/apply.c:4305
msgid "make sure the patch is applicable to the current index"
msgstr ""
"stellt sicher, dass der Patch in der aktuellen Bereitstellung angewendet "
"werden kann"
-#: builtin/apply.c:4308
+#: builtin/apply.c:4307
msgid "apply a patch without touching the working tree"
msgstr "wendet einen Patch an, ohne Änderungen im Arbeitszweig vorzunehmen"
-#: builtin/apply.c:4310
+#: builtin/apply.c:4309
msgid "also apply the patch (use with --stat/--summary/--check)"
msgstr "wendet den Patch an (Benutzung mit --stat/--summary/--check)"
-#: builtin/apply.c:4312
+#: builtin/apply.c:4311
msgid "attempt three-way merge if a patch does not apply"
msgstr ""
"versucht 3-Wege-Zusammenführung, wenn der Patch nicht angewendet werden "
"konnte"
-#: builtin/apply.c:4314
+#: builtin/apply.c:4313
msgid "build a temporary index based on embedded index information"
msgstr ""
"erstellt eine temporäre Bereitstellung basierend auf den integrierten "
"Bereitstellungsinformationen"
-#: builtin/apply.c:4316
+#: builtin/apply.c:4315
msgid "paths are separated with NUL character"
msgstr "Pfade sind getrennt durch NUL Zeichen"
-#: builtin/apply.c:4319
+#: builtin/apply.c:4318
msgid "ensure at least <n> lines of context match"
msgstr ""
"stellt sicher, dass mindestens <Anzahl> Zeilen des Kontextes übereinstimmen"
-#: builtin/apply.c:4320
+#: builtin/apply.c:4319
msgid "action"
msgstr "Aktion"
-#: builtin/apply.c:4321
+#: builtin/apply.c:4320
msgid "detect new or modified lines that have whitespace errors"
msgstr "ermittelt neue oder geänderte Zeilen die Fehler in Leerzeichen haben"
-#: builtin/apply.c:4324 builtin/apply.c:4327
+#: builtin/apply.c:4323 builtin/apply.c:4326
msgid "ignore changes in whitespace when finding context"
msgstr "ignoriert Änderungen in Leerzeichen bei der Suche des Kontextes"
-#: builtin/apply.c:4330
+#: builtin/apply.c:4329
msgid "apply the patch in reverse"
msgstr "wendet den Patch in umgekehrter Reihenfolge an"
-#: builtin/apply.c:4332
+#: builtin/apply.c:4331
msgid "don't expect at least one line of context"
msgstr "erwartet keinen Kontext"
-#: builtin/apply.c:4334
+#: builtin/apply.c:4333
msgid "leave the rejected hunks in corresponding *.rej files"
msgstr ""
"hinterlässt zurückgewiesene Patch-Bereiche in den entsprechenden *.rej "
"Dateien"
-#: builtin/apply.c:4336
+#: builtin/apply.c:4335
msgid "allow overlapping hunks"
msgstr "erlaubt sich überlappende Patch-Bereiche"
-#: builtin/apply.c:4337
+#: builtin/apply.c:4336
msgid "be verbose"
msgstr "erweiterte Ausgaben"
-#: builtin/apply.c:4339
+#: builtin/apply.c:4338
msgid "tolerate incorrectly detected missing new-line at the end of file"
msgstr "toleriert fehlerhaft erkannten fehlenden Zeilenumbruch am Dateiende"
-#: builtin/apply.c:4342
+#: builtin/apply.c:4341
msgid "do not trust the line counts in the hunk headers"
msgstr "vertraut nicht den Zeilennummern im Kopf des Patch-Bereiches"
-#: builtin/apply.c:4344
+#: builtin/apply.c:4343
msgid "root"
msgstr "Wurzelverzeichnis"
-#: builtin/apply.c:4345
+#: builtin/apply.c:4344
msgid "prepend <root> to all filenames"
msgstr "stellt <Wurzelverzeichnis> vor alle Dateinamen"
-#: builtin/apply.c:4367
+#: builtin/apply.c:4366
msgid "--3way outside a repository"
msgstr "--3way außerhalb eines Projektarchivs"
-#: builtin/apply.c:4375
+#: builtin/apply.c:4374
msgid "--index outside a repository"
msgstr "--index außerhalb eines Projektarchivs"
-#: builtin/apply.c:4378
+#: builtin/apply.c:4377
msgid "--cached outside a repository"
msgstr "--cached außerhalb eines Projektarchivs"
-#: builtin/apply.c:4394
+#: builtin/apply.c:4393
#, c-format
msgid "can't open patch '%s'"
msgstr "kann Patch '%s' nicht öffnen"
-#: builtin/apply.c:4408
+#: builtin/apply.c:4407
#, c-format
msgid "squelched %d whitespace error"
msgid_plural "squelched %d whitespace errors"
msgstr[0] "unterdrückte %d Fehler in Leerzeichen"
msgstr[1] "unterdrückte %d Fehler in Leerzeichen"
-#: builtin/apply.c:4414 builtin/apply.c:4424
+#: builtin/apply.c:4413 builtin/apply.c:4423
#, c-format
msgid "%d line adds whitespace errors."
msgid_plural "%d lines add whitespace errors."
@@ -2163,7 +2160,7 @@ msgstr "Pfad '%s': kann nicht zusammenführen"
msgid "Unable to add merge result for '%s'"
msgstr "Konnte Ergebnis der Zusammenführung von '%s' nicht hinzufügen."
-#: builtin/checkout.c:235 builtin/checkout.c:393
+#: builtin/checkout.c:235 builtin/checkout.c:392
msgid "corrupt index file"
msgstr "beschädigte Bereitstellungsdatei"
@@ -2172,60 +2169,56 @@ msgstr "beschädigte Bereitstellungsdatei"
msgid "path '%s' is unmerged"
msgstr "Pfad '%s' ist nicht zusammengeführt."
-#: builtin/checkout.c:303 builtin/checkout.c:499 builtin/clone.c:586
-#: builtin/merge.c:812
+#: builtin/checkout.c:303 builtin/checkout.c:498 builtin/clone.c:586
+#: builtin/merge.c:811
msgid "unable to write new index file"
msgstr "Konnte neue Bereitstellungsdatei nicht schreiben."
-#: builtin/checkout.c:320 builtin/diff.c:302 builtin/merge.c:408
-msgid "diff_setup_done failed"
-msgstr "diff_setup_done fehlgeschlagen"
-
-#: builtin/checkout.c:415
+#: builtin/checkout.c:414
msgid "you need to resolve your current index first"
msgstr "Du musst zuerst deine aktuelle Bereitstellung auflösen."
-#: builtin/checkout.c:534
+#: builtin/checkout.c:533
#, c-format
msgid "Can not do reflog for '%s'\n"
msgstr "Konnte \"reflog\" für '%s' nicht durchführen\n"
-#: builtin/checkout.c:567
+#: builtin/checkout.c:566
msgid "HEAD is now at"
msgstr "Zweigspitze (HEAD) ist jetzt bei"
-#: builtin/checkout.c:574
+#: builtin/checkout.c:573
#, c-format
msgid "Reset branch '%s'\n"
msgstr "Setze Zweig '%s' zurück\n"
-#: builtin/checkout.c:577
+#: builtin/checkout.c:576
#, c-format
msgid "Already on '%s'\n"
msgstr "Bereits auf '%s'\n"
-#: builtin/checkout.c:581
+#: builtin/checkout.c:580
#, c-format
msgid "Switched to and reset branch '%s'\n"
msgstr "Gewechselt zu zurückgesetztem Zweig '%s'\n"
-#: builtin/checkout.c:583
+#: builtin/checkout.c:582
#, c-format
msgid "Switched to a new branch '%s'\n"
msgstr "Gewechselt zu einem neuen Zweig '%s'\n"
-#: builtin/checkout.c:585
+#: builtin/checkout.c:584
#, c-format
msgid "Switched to branch '%s'\n"
msgstr "Gewechselt zu Zweig '%s'\n"
-#: builtin/checkout.c:641
+#: builtin/checkout.c:640
#, c-format
msgid " ... and %d more.\n"
msgstr " ... und %d weitere.\n"
#. The singular version
-#: builtin/checkout.c:647
+#: builtin/checkout.c:646
#, c-format
msgid ""
"Warning: you are leaving %d commit behind, not connected to\n"
@@ -2248,7 +2241,7 @@ msgstr[1] ""
"\n"
"%s\n"
-#: builtin/checkout.c:665
+#: builtin/checkout.c:664
#, c-format
msgid ""
"If you want to keep them by creating a new branch, this may be a good time\n"
@@ -2263,71 +2256,71 @@ msgstr ""
" git branch neuer_zweig_name %s\n"
"\n"
-#: builtin/checkout.c:695
+#: builtin/checkout.c:694
msgid "internal error in revision walk"
msgstr "interner Fehler im Revisionsgang"
-#: builtin/checkout.c:699
+#: builtin/checkout.c:698
msgid "Previous HEAD position was"
msgstr "Vorherige Position der Zweigspitze (HEAD) war"
-#: builtin/checkout.c:725 builtin/checkout.c:920
+#: builtin/checkout.c:724 builtin/checkout.c:919
msgid "You are on a branch yet to be born"
msgstr "du bist auf einem Zweig, der noch geboren wird"
#. case (1)
-#: builtin/checkout.c:856
+#: builtin/checkout.c:855
#, c-format
msgid "invalid reference: %s"
msgstr "Ungültige Referenz: %s"
#. case (1): want a tree
-#: builtin/checkout.c:895
+#: builtin/checkout.c:894
#, c-format
msgid "reference is not a tree: %s"
msgstr "Referenz ist kein Baum: %s"
-#: builtin/checkout.c:977
+#: builtin/checkout.c:976
msgid "-B cannot be used with -b"
msgstr "-B kann nicht mit -b benutzt werden"
-#: builtin/checkout.c:986
+#: builtin/checkout.c:985
msgid "--patch is incompatible with all other options"
msgstr "--patch ist inkompatibel mit allen anderen Optionen"
-#: builtin/checkout.c:989
+#: builtin/checkout.c:988
msgid "--detach cannot be used with -b/-B/--orphan"
msgstr "--detach kann nicht mit -b/-B/--orphan benutzt werden"
-#: builtin/checkout.c:991
+#: builtin/checkout.c:990
msgid "--detach cannot be used with -t"
msgstr "--detach kann nicht mit -t benutzt werden"
-#: builtin/checkout.c:997
+#: builtin/checkout.c:996
msgid "--track needs a branch name"
msgstr "--track benötigt einen Zweignamen"
-#: builtin/checkout.c:1004
+#: builtin/checkout.c:1003
msgid "Missing branch name; try -b"
msgstr "Vermisse Zweignamen; versuche -b"
-#: builtin/checkout.c:1010
+#: builtin/checkout.c:1009
msgid "--orphan and -b|-B are mutually exclusive"
msgstr "--orphan und -b|-B sind gegenseitig exklusiv"
-#: builtin/checkout.c:1012
+#: builtin/checkout.c:1011
msgid "--orphan cannot be used with -t"
msgstr "--orphan kann nicht mit -t benutzt werden"
-#: builtin/checkout.c:1022
+#: builtin/checkout.c:1021
msgid "git checkout: -f and -m are incompatible"
msgstr "git checkout: -f und -m sind inkompatibel"
-#: builtin/checkout.c:1056
+#: builtin/checkout.c:1055
msgid "invalid path specification"
msgstr "ungültige Pfadspezifikation"
-#: builtin/checkout.c:1064
+#: builtin/checkout.c:1063
#, c-format
msgid ""
"git checkout: updating paths is incompatible with switching branches.\n"
@@ -2338,17 +2331,17 @@ msgstr ""
"Hast du beabsichtigt '%s' auszuchecken, welcher nicht als Version aufgelöst "
"werden kann?"
-#: builtin/checkout.c:1066
+#: builtin/checkout.c:1065
msgid "git checkout: updating paths is incompatible with switching branches."
msgstr ""
"git checkout: Die Aktualisierung von Pfaden ist inkompatibel mit dem Wechsel "
"von Zweigen."
-#: builtin/checkout.c:1071
+#: builtin/checkout.c:1070
msgid "git checkout: --detach does not take a path argument"
msgstr "git checkout: --detach nimmt kein Pfad-Argument"
-#: builtin/checkout.c:1074
+#: builtin/checkout.c:1073
msgid ""
"git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
"checking out of the index."
@@ -2356,11 +2349,11 @@ msgstr ""
"git checkout: --ours/--theirs, --force und --merge sind inkompatibel wenn\n"
"du aus der Bereitstellung auscheckst."
-#: builtin/checkout.c:1093
+#: builtin/checkout.c:1092
msgid "Cannot switch branch to a non-commit."
msgstr "Kann Zweig nur zu einer Version wechseln."
-#: builtin/checkout.c:1096
+#: builtin/checkout.c:1095
msgid "--ours/--theirs is incompatible with switching branches."
msgstr "--ours/--theirs ist inkompatibel mit den Wechseln von Zweigen."
@@ -2418,7 +2411,7 @@ msgstr "Referenziertes Projektarchiv '%s' ist kein lokales Verzeichnis."
msgid "failed to create directory '%s'"
msgstr "Fehler beim Erstellen von Verzeichnis '%s'"
-#: builtin/clone.c:308 builtin/diff.c:75
+#: builtin/clone.c:308 builtin/diff.c:77
#, c-format
msgid "failed to stat '%s'"
msgstr "Konnte '%s' nicht lesen"
@@ -2433,11 +2426,6 @@ msgstr "%s existiert und ist kein Verzeichnis"
msgid "failed to stat %s\n"
msgstr "Konnte %s nicht lesen\n"
-#: builtin/clone.c:341
-#, c-format
-msgid "failed to unlink '%s'"
-msgstr "Konnte '%s' nicht entfernen"
-
#: builtin/clone.c:346
#, c-format
msgid "failed to create link '%s'"
@@ -2843,7 +2831,7 @@ msgstr " (Basis-Version)"
msgid "could not parse HEAD commit"
msgstr "Konnte Version der Zweigspitze (HEAD) nicht analysieren."
-#: builtin/commit.c:1487 builtin/merge.c:509
+#: builtin/commit.c:1487 builtin/merge.c:508
#, c-format
msgid "could not open '%s' for reading"
msgstr "Konnte '%s' nicht zum Lesen öffnen."
@@ -2872,7 +2860,7 @@ msgstr "Eintragung abgebrochen; du hast die Beschreibung nicht editiert.\n"
msgid "Aborting commit due to empty commit message.\n"
msgstr "Eintragung aufgrund leerer Versionsbeschreibung abgebrochen.\n"
-#: builtin/commit.c:1554 builtin/merge.c:936 builtin/merge.c:961
+#: builtin/commit.c:1554 builtin/merge.c:935 builtin/merge.c:960
msgid "failed to write commit object"
msgstr "Fehler beim Schreiben des Versionsobjektes."
@@ -2979,36 +2967,36 @@ msgstr "Keine Namen gefunden, kann nichts beschreiben."
msgid "--dirty is incompatible with committishes"
msgstr "--dirty ist inkompatibel mit Versionen"
-#: builtin/diff.c:77
+#: builtin/diff.c:79
#, c-format
msgid "'%s': not a regular file or symlink"
msgstr "'%s': keine reguläre Datei oder symbolischer Link"
-#: builtin/diff.c:220
+#: builtin/diff.c:224
#, c-format
msgid "invalid option: %s"
msgstr "Ungültige Option: %s"
-#: builtin/diff.c:297
+#: builtin/diff.c:301
msgid "Not a git repository"
msgstr "Kein Git-Projektarchiv"
-#: builtin/diff.c:341
+#: builtin/diff.c:344
#, c-format
msgid "invalid object '%s' given."
msgstr "Objekt '%s' ist ungültig."
-#: builtin/diff.c:346
+#: builtin/diff.c:349
#, c-format
msgid "more than %d trees given: '%s'"
msgstr "Mehr als %d Zweige angegeben: '%s'"
-#: builtin/diff.c:356
+#: builtin/diff.c:359
#, c-format
msgid "more than two blobs given: '%s'"
msgstr "Mehr als zwei Blobs angegeben: '%s'"
-#: builtin/diff.c:364
+#: builtin/diff.c:367
#, c-format
msgid "unhandled object '%s' given."
msgstr "unbehandeltes Objekt '%s' angegeben"
@@ -3212,58 +3200,58 @@ msgstr ""
msgid "grep: failed to create thread: %s"
msgstr "grep: Fehler beim Erzeugen eines Thread: %s"
-#: builtin/grep.c:402
+#: builtin/grep.c:454
#, c-format
msgid "Failed to chdir: %s"
msgstr "Fehler beim Verzeichniswechsel: %s"
-#: builtin/grep.c:478 builtin/grep.c:512
+#: builtin/grep.c:530 builtin/grep.c:564
#, c-format
msgid "unable to read tree (%s)"
msgstr "konnte Zweig (%s) nicht lesen"
-#: builtin/grep.c:526
+#: builtin/grep.c:578
#, c-format
msgid "unable to grep from object of type %s"
msgstr "kann \"grep\" nicht mit Objekten des Typs %s durchführen"
-#: builtin/grep.c:584
+#: builtin/grep.c:636
#, c-format
msgid "switch `%c' expects a numerical value"
msgstr "Schalter '%c' erwartet einen numerischen Wert"
-#: builtin/grep.c:601
+#: builtin/grep.c:653
#, c-format
msgid "cannot open '%s'"
msgstr "kann '%s' nicht öffnen"
-#: builtin/grep.c:885
+#: builtin/grep.c:917
msgid "no pattern given."
msgstr "keine Muster angegeben"
-#: builtin/grep.c:899
+#: builtin/grep.c:931
#, c-format
msgid "bad object %s"
msgstr "ungültiges Objekt %s"
-#: builtin/grep.c:940
+#: builtin/grep.c:972
msgid "--open-files-in-pager only works on the worktree"
msgstr "--open-files-in-pager arbeitet nur innerhalb des Arbeitsbaums"
-#: builtin/grep.c:963
+#: builtin/grep.c:995
msgid "--cached or --untracked cannot be used with --no-index."
msgstr "--cached oder --untracked kann nicht mit --no-index benutzt werden"
-#: builtin/grep.c:968
+#: builtin/grep.c:1000
msgid "--no-index or --untracked cannot be used with revs."
msgstr "--no-index oder --untracked kann nicht mit Versionen benutzt werden"
-#: builtin/grep.c:971
+#: builtin/grep.c:1003
msgid "--[no-]exclude-standard cannot be used for tracked contents."
msgstr ""
"--[no-]exlude-standard kann nicht mit beobachteten Inhalten benutzt werden"
-#: builtin/grep.c:979
+#: builtin/grep.c:1011
msgid "both --cached and trees are given."
msgstr "sowohl --cached als auch Zweige gegeben"
@@ -3758,58 +3746,58 @@ msgstr "Brauche genau einen Versionsbereich."
msgid "Not a range."
msgstr "Kein Versionsbereich."
-#: builtin/log.c:792
+#: builtin/log.c:789
msgid "Cover letter needs email format"
msgstr "Anschreiben benötigt E-Mail-Format"
-#: builtin/log.c:865
+#: builtin/log.c:862
#, c-format
msgid "insane in-reply-to: %s"
msgstr "ungültiges in-reply-to: %s"
-#: builtin/log.c:938
+#: builtin/log.c:935
msgid "Two output directories?"
msgstr "Zwei Ausgabeverzeichnisse?"
-#: builtin/log.c:1160
+#: builtin/log.c:1157
#, c-format
msgid "bogus committer info %s"
msgstr "unechte Einreicher-Informationen %s"
-#: builtin/log.c:1205
+#: builtin/log.c:1202
msgid "-n and -k are mutually exclusive."
msgstr "-n und -k schließen sich gegenseitig aus"
-#: builtin/log.c:1207
+#: builtin/log.c:1204
msgid "--subject-prefix and -k are mutually exclusive."
msgstr "--subject-prefix und -k schließen sich gegenseitig aus"
-#: builtin/log.c:1215
+#: builtin/log.c:1212
msgid "--name-only does not make sense"
msgstr "--name-only macht keinen Sinn"
-#: builtin/log.c:1217
+#: builtin/log.c:1214
msgid "--name-status does not make sense"
msgstr "--name-status macht keinen Sinn"
-#: builtin/log.c:1219
+#: builtin/log.c:1216
msgid "--check does not make sense"
msgstr "--check macht keinen Sinn"
-#: builtin/log.c:1242
+#: builtin/log.c:1239
msgid "standard output, or directory, which one?"
msgstr "Standard-Ausgabe oder Verzeichnis, welches von beidem?"
-#: builtin/log.c:1244
+#: builtin/log.c:1241
#, c-format
msgid "Could not create directory '%s'"
msgstr "Konnte Verzeichnis '%s' nicht erstellen."
-#: builtin/log.c:1397
+#: builtin/log.c:1394
msgid "Failed to create output files"
msgstr "Fehler beim Erstellen der Ausgabedateien."
-#: builtin/log.c:1501
+#: builtin/log.c:1498
#, c-format
msgid ""
"Could not find a tracked remote branch, please specify <upstream> manually.\n"
@@ -3817,7 +3805,7 @@ msgstr ""
"Konnte gefolgten, externen Zweig nicht finden, bitte gebe <upstream> manuell "
"an.\n"
-#: builtin/log.c:1517 builtin/log.c:1519 builtin/log.c:1531
+#: builtin/log.c:1511 builtin/log.c:1513 builtin/log.c:1525
#, c-format
msgid "Unknown commit %s"
msgstr "Unbekannte Version %s"
@@ -3882,51 +3870,51 @@ msgstr ""
"Keine Zusammenführungsbeschreibung -- Zweigspitze (HEAD) wird nicht "
"aktualisiert\n"
-#: builtin/merge.c:437
+#: builtin/merge.c:436
#, c-format
msgid "'%s' does not point to a commit"
msgstr "'%s' zeigt auf keine Version"
-#: builtin/merge.c:536
+#: builtin/merge.c:535
#, c-format
msgid "Bad branch.%s.mergeoptions string: %s"
msgstr "Ungültiger branch.%s.mergeoptions String: %s"
-#: builtin/merge.c:629
+#: builtin/merge.c:628
msgid "git write-tree failed to write a tree"
msgstr "\"git write-tree\" schlug beim Schreiben eines Baumes fehl"
-#: builtin/merge.c:679
+#: builtin/merge.c:678
msgid "failed to read the cache"
msgstr "Lesen des Zwischenspeichers fehlgeschlagen"
-#: builtin/merge.c:710
+#: builtin/merge.c:709
msgid "Not handling anything other than two heads merge."
msgstr "Es wird nur die Zusammenführung von zwei Zweigen behandelt."
-#: builtin/merge.c:724
+#: builtin/merge.c:723
#, c-format
msgid "Unknown option for merge-recursive: -X%s"
msgstr "Unbekannte Option für merge-recursive: -X%s"
-#: builtin/merge.c:738
+#: builtin/merge.c:737
#, c-format
msgid "unable to write %s"
msgstr "konnte %s nicht schreiben"
-#: builtin/merge.c:877
+#: builtin/merge.c:876
#, c-format
msgid "Could not read from '%s'"
msgstr "konnte nicht von '%s' lesen"
-#: builtin/merge.c:886
+#: builtin/merge.c:885
#, c-format
msgid "Not committing merge; use 'git commit' to complete the merge.\n"
msgstr ""
"Zusammenführung wurde nicht eingetragen; benutze 'git commit' um die "
"Zusammenführung abzuschließen.\n"
-#: builtin/merge.c:892
+#: builtin/merge.c:891
msgid ""
"Please enter a commit message to explain why this merge is necessary,\n"
"especially if it merges an updated upstream into a topic branch.\n"
@@ -3942,56 +3930,56 @@ msgstr ""
"Zeilen beginnend mit '#' werden ignoriert, und eine leere Beschreibung "
"bricht die Eintragung ab.\n"
-#: builtin/merge.c:916
+#: builtin/merge.c:915
msgid "Empty commit message."
msgstr "Leere Versionsbeschreibung"
-#: builtin/merge.c:928
+#: builtin/merge.c:927
#, c-format
msgid "Wonderful.\n"
msgstr "Wunderbar.\n"
-#: builtin/merge.c:993
+#: builtin/merge.c:992
#, c-format
msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
msgstr ""
"Automatische Zusammenführung fehlgeschlagen; behebe die Konflikte und trage "
"dann das Ergebnis ein.\n"
-#: builtin/merge.c:1009
+#: builtin/merge.c:1008
#, c-format
msgid "'%s' is not a commit"
msgstr "'%s' ist keine Version"
-#: builtin/merge.c:1050
+#: builtin/merge.c:1049
msgid "No current branch."
msgstr "Du befindest dich auf keinem Zweig."
-#: builtin/merge.c:1052
+#: builtin/merge.c:1051
msgid "No remote for the current branch."
msgstr "Kein externes Archiv für den aktuellen Zweig."
-#: builtin/merge.c:1054
+#: builtin/merge.c:1053
msgid "No default upstream defined for the current branch."
msgstr ""
"Es ist kein externes Standard-Projektarchiv für den aktuellen Zweig "
"definiert."
-#: builtin/merge.c:1059
+#: builtin/merge.c:1058
#, c-format
msgid "No remote tracking branch for %s from %s"
msgstr "Kein externer Übernahmezweig für %s von %s"
-#: builtin/merge.c:1146 builtin/merge.c:1303
+#: builtin/merge.c:1145 builtin/merge.c:1302
#, c-format
msgid "%s - not something we can merge"
msgstr "%s - nichts was wir zusammenführen können"
-#: builtin/merge.c:1214
+#: builtin/merge.c:1213
msgid "There is no merge to abort (MERGE_HEAD missing)."
msgstr "Es gibt keine Zusammenführung zum Abbrechen (vermisse MERGE_HEAD)"
-#: builtin/merge.c:1230 git-pull.sh:31
+#: builtin/merge.c:1229 git-pull.sh:31
msgid ""
"You have not concluded your merge (MERGE_HEAD exists).\n"
"Please, commit your changes before you can merge."
@@ -3999,12 +3987,12 @@ msgstr ""
"Du hast deine Zusammenführung nicht abgeschlossen (MERGE_HEAD existiert).\n"
"Bitte trage deine Änderungen ein, bevor du zusammenführen kannst."
-#: builtin/merge.c:1233 git-pull.sh:34
+#: builtin/merge.c:1232 git-pull.sh:34
msgid "You have not concluded your merge (MERGE_HEAD exists)."
msgstr ""
"Du hast deine Zusammenführung nicht abgeschlossen (MERGE_HEAD existiert)."
-#: builtin/merge.c:1237
+#: builtin/merge.c:1236
msgid ""
"You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
"Please, commit your changes before you can merge."
@@ -4012,80 +4000,80 @@ msgstr ""
"Du hast \"cherry-pick\" nicht abgeschlossen (CHERRY_PICK_HEAD existiert).\n"
"Bitte trage deine Änderungen ein, bevor du zusammenführen kannst."
-#: builtin/merge.c:1240
+#: builtin/merge.c:1239
msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
msgstr ""
"Du hast \"cherry-pick\" nicht abgeschlossen (CHERRY_PICK_HEAD existiert)."
-#: builtin/merge.c:1249
+#: builtin/merge.c:1248
msgid "You cannot combine --squash with --no-ff."
msgstr "Du kannst --squash nicht mit --no-ff kombinieren."
-#: builtin/merge.c:1254
+#: builtin/merge.c:1253
msgid "You cannot combine --no-ff with --ff-only."
msgstr "Du kannst --no-ff nicht mit --ff--only kombinieren."
-#: builtin/merge.c:1261
+#: builtin/merge.c:1260
msgid "No commit specified and merge.defaultToUpstream not set."
msgstr "Keine Version angegeben und merge.defaultToUpstream ist nicht gesetzt."
-#: builtin/merge.c:1293
+#: builtin/merge.c:1292
msgid "Can merge only exactly one commit into empty head"
msgstr "Kann nur exakt eine Version in einem leeren Zweig zusammenführen."
-#: builtin/merge.c:1296
+#: builtin/merge.c:1295
msgid "Squash commit into empty head not supported yet"
msgstr "Bin auf einem Zweig, der noch geboren wird; kann nicht quetschen."
-#: builtin/merge.c:1298
+#: builtin/merge.c:1297
msgid "Non-fast-forward commit does not make sense into an empty head"
msgstr "nicht vorzuspulende Version macht in einem leeren Zweig keinen Sinn"
-#: builtin/merge.c:1413
+#: builtin/merge.c:1412
#, c-format
msgid "Updating %s..%s\n"
msgstr "Aktualisiere %s..%s\n"
-#: builtin/merge.c:1451
+#: builtin/merge.c:1450
#, c-format
msgid "Trying really trivial in-index merge...\n"
msgstr "Probiere wirklich triviale \"in-index\"-Zusammenführung...\n"
-#: builtin/merge.c:1458
+#: builtin/merge.c:1457
#, c-format
msgid "Nope.\n"
msgstr "Nein.\n"
-#: builtin/merge.c:1490
+#: builtin/merge.c:1489
msgid "Not possible to fast-forward, aborting."
msgstr "Vorspulen nicht möglich, breche ab."
-#: builtin/merge.c:1513 builtin/merge.c:1592
+#: builtin/merge.c:1512 builtin/merge.c:1591
#, c-format
msgid "Rewinding the tree to pristine...\n"
msgstr "Rücklauf des Zweiges bis zum Ursprung...\n"
-#: builtin/merge.c:1517
+#: builtin/merge.c:1516
#, c-format
msgid "Trying merge strategy %s...\n"
msgstr "Probiere Zusammenführungsstrategie %s...\n"
-#: builtin/merge.c:1583
+#: builtin/merge.c:1582
#, c-format
msgid "No merge strategy handled the merge.\n"
msgstr "Keine Zusammenführungsstrategie behandelt diese Zusammenführung.\n"
-#: builtin/merge.c:1585
+#: builtin/merge.c:1584
#, c-format
msgid "Merge with strategy %s failed.\n"
msgstr "Zusammenführung mit Strategie %s fehlgeschlagen.\n"
-#: builtin/merge.c:1594
+#: builtin/merge.c:1593
#, c-format
msgid "Using the %s to prepare resolving by hand.\n"
msgstr "Benutze \"%s\" um die Auflösung per Hand vorzubereiten.\n"
-#: builtin/merge.c:1606
+#: builtin/merge.c:1605
#, c-format
msgid "Automatic merge went well; stopped before committing as requested\n"
msgstr ""
@@ -4426,14 +4414,49 @@ msgstr ""
"aktuellen Zweiges '%s' ist, ohne mir mitzuteilen, was ich versenden\n"
"soll, um welchen externen Zweig zu aktualisieren."
-#: builtin/push.c:174
+#: builtin/push.c:151
+msgid ""
+"push.default is unset; its implicit value is changing in\n"
+"Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
+"and maintain the current behavior after the default changes, use:\n"
+"\n"
+" git config --global push.default matching\n"
+"\n"
+"To squelch this message and adopt the new behavior now, use:\n"
+"\n"
+" git config --global push.default simple\n"
+"\n"
+"See 'git help config' and search for 'push.default' for further "
+"information.\n"
+"(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode\n"
+"'current' instead of 'simple' if you sometimes use older versions of Git)"
+msgstr ""
+"'push.default' ist nicht gesetzt; der implizit gesetzte Wert\n"
+"wird in Git 2.0 von 'matching' nach 'simple' geändert. Um diese Meldung zu\n"
+"unterdrücken und das aktuelle Verhalten nach Änderung des Standardwertes\n"
+"beizubehalten, benutze:"
+"\n"
+" git config --global push.default matching\n"
+"\n"
+"Um diese Meldung zu unterdrücken und das neue Verhalten jetzt zu übernehmen,\n"
+"benutze:\n"
+"\n"
+" git config --global push.default simple\n"
+"\n"
+"Führe 'git help config' aus und suche nach 'push.default' für weitere "
+"Informationen.\n"
+"(Der Modus 'simple' wurde in Git 1.7.11 eingeführt. Benutze den ähnlichen"
+" Modus 'current' anstatt 'simple', falls du gelegentlich ältere Versionen von"
+" Git benutzt.)"
+
+#: builtin/push.c:199
msgid ""
"You didn't specify any refspecs to push, and push.default is \"nothing\"."
msgstr ""
"Du hast keine Referenzspezifikationen zum Versenden angegeben, und push."
"default ist \"nothing\"."
-#: builtin/push.c:181
+#: builtin/push.c:206
msgid ""
"Updates were rejected because the tip of your current branch is behind\n"
"its remote counterpart. Merge the remote changes (e.g. 'git pull')\n"
@@ -4446,22 +4469,22 @@ msgstr ""
"Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help'\n"
"für weitere Details."
-#: builtin/push.c:187
+#: builtin/push.c:212
msgid ""
"Updates were rejected because a pushed branch tip is behind its remote\n"
"counterpart. If you did not intend to push that branch, you may want to\n"
-"specify branches to push or set the 'push.default' configuration\n"
-"variable to 'current' or 'upstream' to push only the current branch."
+"specify branches to push or set the 'push.default' configuration variable\n"
+"to 'simple', 'current' or 'upstream' to push only the current branch."
msgstr ""
"Aktualisierungen wurden zurückgewiesen, weil die Spitze eines versendeten\n"
"Zweiges hinter seinem externen Gegenstück zurückgefallen ist. Wenn du nicht\n"
"beabsichtigt hast, diesen Zweig zu versenden, kannst du auch den zu "
"versendenden\n"
"Zweig spezifizieren oder die Konfigurationsvariable 'push.default' zu "
-"'current'\n"
+"'simple', 'current'\n"
"oder 'upstream' setzen, um nur den aktuellen Zweig zu versenden."
-#: builtin/push.c:193
+#: builtin/push.c:218
msgid ""
"Updates were rejected because a pushed branch tip is behind its remote\n"
"counterpart. Check out this branch and merge the remote changes\n"
@@ -4475,22 +4498,22 @@ msgstr ""
"Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help'\n"
"für weitere Details."
-#: builtin/push.c:233
+#: builtin/push.c:258
#, c-format
msgid "Pushing to %s\n"
msgstr "Versende nach %s\n"
-#: builtin/push.c:237
+#: builtin/push.c:262
#, c-format
msgid "failed to push some refs to '%s'"
msgstr "Fehler beim Versenden einiger Referenzen nach '%s'"
-#: builtin/push.c:269
+#: builtin/push.c:294
#, c-format
msgid "bad repository '%s'"
msgstr "ungültiges Projektarchiv '%s'"
-#: builtin/push.c:270
+#: builtin/push.c:295
msgid ""
"No configured push destination.\n"
"Either specify the URL from the command-line or configure a remote "
@@ -4512,31 +4535,31 @@ msgstr ""
"\n"
" git push <Name>\n"
-#: builtin/push.c:285
+#: builtin/push.c:310
msgid "--all and --tags are incompatible"
msgstr "--all und --tags sind inkompatibel"
-#: builtin/push.c:286
+#: builtin/push.c:311
msgid "--all can't be combined with refspecs"
msgstr "--all kann nicht mit Referenzspezifikationen kombiniert werden"
-#: builtin/push.c:291
+#: builtin/push.c:316
msgid "--mirror and --tags are incompatible"
msgstr "--mirror und --tags sind inkompatibel"
-#: builtin/push.c:292
+#: builtin/push.c:317
msgid "--mirror can't be combined with refspecs"
msgstr "--mirror kann nicht mit Referenzspezifikationen kombiniert werden"
-#: builtin/push.c:297
+#: builtin/push.c:322
msgid "--all and --mirror are incompatible"
msgstr "--all und --mirror sind inkompatibel"
-#: builtin/push.c:385
+#: builtin/push.c:410
msgid "--delete is incompatible with --all, --mirror and --tags"
msgstr "--delete ist inkompatibel mit --all, --mirror und --tags"
-#: builtin/push.c:387
+#: builtin/push.c:412
msgid "--delete doesn't make sense without any refs"
msgstr "--delete macht ohne irgendeine Referenz keinen Sinn"
@@ -5952,34 +5975,34 @@ msgstr "(Zur Wiederherstellung gebe \"git stash apply\" ein)"
msgid "cannot strip one component off url '$remoteurl'"
msgstr "Kann eine Komponente von URL '$remoteurl' nicht extrahieren"
-#: git-submodule.sh:145
+#: git-submodule.sh:167
#, sh-format
msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
msgstr ""
"Keine Unterprojekt-Zuordnung in .gitmodules für Pfad '$sm_path' gefunden"
-#: git-submodule.sh:189
+#: git-submodule.sh:211
#, sh-format
msgid "Clone of '$url' into submodule path '$sm_path' failed"
msgstr "Klonen von '$url' in Unterprojekt-Pfad '$sm_path' fehlgeschlagen"
-#: git-submodule.sh:201
+#: git-submodule.sh:223
#, sh-format
msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
msgstr ""
"Git-Verzeichnis '$a' ist Teil des Unterprojekt-Pfades '$b', oder umgekehrt"
-#: git-submodule.sh:290
+#: git-submodule.sh:312
#, sh-format
msgid "repo URL: '$repo' must be absolute or begin with ./|../"
msgstr "repo URL: '$repo' muss absolut sein oder mit ./|../ beginnen"
-#: git-submodule.sh:307
+#: git-submodule.sh:329
#, sh-format
msgid "'$sm_path' already exists in the index"
msgstr "'$sm_path' existiert bereits in der Bereitstellung"
-#: git-submodule.sh:311
+#: git-submodule.sh:333
#, sh-format
msgid ""
"The following path is ignored by one of your .gitignore files:\n"
@@ -5990,65 +6013,65 @@ msgstr ""
"$sm_path\n"
"Benutze -f wenn du diesen wirklich hinzufügen möchtest."
-#: git-submodule.sh:322
+#: git-submodule.sh:344
#, sh-format
msgid "Adding existing repo at '$sm_path' to the index"
msgstr ""
"Füge existierendes Projektarchiv in '$sm_path' der Bereitstellung hinzu."
-#: git-submodule.sh:324
+#: git-submodule.sh:346
#, sh-format
msgid "'$sm_path' already exists and is not a valid git repo"
msgstr "'$sm_path' existiert bereits und ist kein gültiges Git-Projektarchiv"
-#: git-submodule.sh:338
+#: git-submodule.sh:360
#, sh-format
msgid "Unable to checkout submodule '$sm_path'"
msgstr "Unfähig Unterprojekt '$sm_path' auszuchecken"
-#: git-submodule.sh:343
+#: git-submodule.sh:365
#, sh-format
msgid "Failed to add submodule '$sm_path'"
msgstr "Hinzufügen von Unterprojekt '$sm_path' fehlgeschlagen"
-#: git-submodule.sh:348
+#: git-submodule.sh:370
#, sh-format
msgid "Failed to register submodule '$sm_path'"
msgstr "Registierung von Unterprojekt '$sm_path' fehlgeschlagen"
-#: git-submodule.sh:390
+#: git-submodule.sh:413
#, sh-format
msgid "Entering '$prefix$sm_path'"
msgstr "Betrete '$prefix$sm_path'"
-#: git-submodule.sh:404
+#: git-submodule.sh:427
#, sh-format
msgid "Stopping at '$sm_path'; script returned non-zero status."
msgstr "Stoppe bei '$sm_path'; Skript gab nicht-Null Status zurück."
-#: git-submodule.sh:447
+#: git-submodule.sh:471
#, sh-format
msgid "No url found for submodule path '$sm_path' in .gitmodules"
msgstr "Keine URL für Unterprojekt-Pfad '$sm_path' in .gitmodules gefunden"
-#: git-submodule.sh:456
+#: git-submodule.sh:480
#, sh-format
msgid "Failed to register url for submodule path '$sm_path'"
msgstr "Registrierung der URL für Unterprojekt-Pfad '$sm_path' fehlgeschlagen"
-#: git-submodule.sh:458
+#: git-submodule.sh:482
#, sh-format
msgid "Submodule '$name' ($url) registered for path '$sm_path'"
msgstr "Unterprojekt '$name' ($url) ist für Pfad '$sm_path' registriert"
-#: git-submodule.sh:466
+#: git-submodule.sh:490
#, sh-format
msgid "Failed to register update mode for submodule path '$sm_path'"
msgstr ""
"Registrierung des Aktualisierungsmodus für Unterprojekt-Pfad '$sm_path' "
"fehlgeschlagen"
-#: git-submodule.sh:565
+#: git-submodule.sh:590
#, sh-format
msgid ""
"Submodule path '$sm_path' not initialized\n"
@@ -6057,95 +6080,104 @@ msgstr ""
"Unterprojekt-Pfad '$sm_path' ist nicht initialisiert\n"
"Vielleicht möchtest du 'update --init' benutzen?"
-#: git-submodule.sh:578
+#: git-submodule.sh:603
#, sh-format
msgid "Unable to find current revision in submodule path '$sm_path'"
msgstr "Konnte aktuelle Version in Unterprojekt-Pfad '$sm_path' nicht finden"
-#: git-submodule.sh:597
+#: git-submodule.sh:622
#, sh-format
msgid "Unable to fetch in submodule path '$sm_path'"
msgstr "Konnte in Unterprojekt-Pfad '$sm_path' nicht anfordern"
-#: git-submodule.sh:611
+#: git-submodule.sh:636
#, sh-format
msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
msgstr "Neuaufbau von '$sha1' in Unterprojekt-Pfad '$sm_path' nicht möglich"
-#: git-submodule.sh:612
+#: git-submodule.sh:637
#, sh-format
msgid "Submodule path '$sm_path': rebased into '$sha1'"
msgstr "Unterprojekt-Pfad '$sm_path': neu aufgebaut in '$sha1'"
-#: git-submodule.sh:617
+#: git-submodule.sh:642
#, sh-format
msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
msgstr ""
"Zusammenführung von '$sha1' in Unterprojekt-Pfad '$sm_path' fehlgeschlagen"
-#: git-submodule.sh:618
+#: git-submodule.sh:643
#, sh-format
msgid "Submodule path '$sm_path': merged in '$sha1'"
msgstr "Unterprojekt-Pfad '$sm_path': zusammengeführt in '$sha1'"
-#: git-submodule.sh:623
+#: git-submodule.sh:648
#, sh-format
msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
msgstr "Konnte '$sha1' in Unterprojekt-Pfad '$sm_path' nicht auschecken."
-#: git-submodule.sh:624
+#: git-submodule.sh:649
#, sh-format
msgid "Submodule path '$sm_path': checked out '$sha1'"
msgstr "Unterprojekt-Pfad: '$sm_path': '$sha1' ausgecheckt"
-#: git-submodule.sh:646 git-submodule.sh:969
+#: git-submodule.sh:671 git-submodule.sh:995
#, sh-format
msgid "Failed to recurse into submodule path '$sm_path'"
msgstr "Fehler bei Rekursion in Unterprojekt-Pfad '$sm_path'"
-#: git-submodule.sh:754
+#: git-submodule.sh:779
msgid "The --cached option cannot be used with the --files option"
msgstr "Die --cached Option kann nicht mit der --files Option benutzt werden"
#. unexpected type
-#: git-submodule.sh:794
+#: git-submodule.sh:819
#, sh-format
msgid "unexpected mode $mod_dst"
msgstr "unerwarteter Modus $mod_dst"
-#: git-submodule.sh:812
+#: git-submodule.sh:837
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_src"
msgstr " Warnung: $name beinhaltet nicht Version $sha1_src"
-#: git-submodule.sh:815
+#: git-submodule.sh:840
#, sh-format
msgid " Warn: $name doesn't contain commit $sha1_dst"
msgstr " Warnung: $name beinhaltet nicht Version $sha1_dst"
-#: git-submodule.sh:818
+#: git-submodule.sh:843
#, sh-format
msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
msgstr ""
" Warnung: $name beinhaltet nicht die Versionen $sha1_src und $sha1_dst"
-#: git-submodule.sh:843
+#: git-submodule.sh:868
msgid "blob"
msgstr "Blob"
-#: git-submodule.sh:881
+#: git-submodule.sh:906
msgid "# Submodules changed but not updated:"
msgstr "# Unterprojekte geändert, aber nicht aktualisiert:"
-#: git-submodule.sh:883
+#: git-submodule.sh:908
msgid "# Submodule changes to be committed:"
msgstr "# Änderungen in Unterprojekt zum Eintragen:"
-#: git-submodule.sh:1027
+#: git-submodule.sh:1054
#, sh-format
msgid "Synchronizing submodule url for '$name'"
msgstr "Synchronisiere Unterprojekt-URL für '$name'"
+#~ msgid "diff setup failed"
+#~ msgstr "diff_setup_done fehlgeschlagen"
+
+#~ msgid "merge-recursive: disk full?"
+#~ msgstr "merge-recursive: Festplatte voll?"
+
+#~ msgid "diff_setup_done failed"
+#~ msgstr "diff_setup_done fehlgeschlagen"
+
#~ msgid "-d option is no longer supported. Do not use."
#~ msgstr "-d Option wird nicht länger unterstützt. Nicht benutzen."
diff --git a/po/git.pot b/po/git.pot
index 5c586d6..05177d6 100644
--- a/po/git.pot
+++ b/po/git.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-08-06 23:47+0800\n"
+"POT-Creation-Date: 2012-09-15 10:21+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -35,6 +35,91 @@ msgid ""
"or use 'git commit -a'."
msgstr ""
+#: archive.c:10
+msgid "git archive [options] <tree-ish> [<path>...]"
+msgstr ""
+
+#: archive.c:11
+msgid "git archive --list"
+msgstr ""
+
+#: archive.c:12
+msgid ""
+"git archive --remote <repo> [--exec <cmd>] [options] <tree-ish> [<path>...]"
+msgstr ""
+
+#: archive.c:13
+msgid "git archive --remote <repo> [--exec <cmd>] --list"
+msgstr ""
+
+#: archive.c:322
+msgid "fmt"
+msgstr ""
+
+#: archive.c:322
+msgid "archive format"
+msgstr ""
+
+#: archive.c:323 builtin/log.c:1079
+msgid "prefix"
+msgstr ""
+
+#: archive.c:324
+msgid "prepend prefix to each pathname in the archive"
+msgstr ""
+
+#: archive.c:325 builtin/archive.c:91 builtin/blame.c:2332
+#: builtin/blame.c:2333 builtin/config.c:56 builtin/fast-export.c:642
+#: builtin/fast-export.c:644 builtin/grep.c:800 builtin/hash-object.c:77
+#: builtin/ls-files.c:494 builtin/ls-files.c:497 builtin/notes.c:537
+#: builtin/notes.c:694 builtin/read-tree.c:107 parse-options.h:149
+msgid "file"
+msgstr ""
+
+#: archive.c:326 builtin/archive.c:92
+msgid "write the archive to this file"
+msgstr ""
+
+#: archive.c:328
+msgid "read .gitattributes in working directory"
+msgstr ""
+
+#: archive.c:329
+msgid "report archived files on stderr"
+msgstr ""
+
+#: archive.c:330
+msgid "store only"
+msgstr ""
+
+#: archive.c:331
+msgid "compress faster"
+msgstr ""
+
+#: archive.c:339
+msgid "compress better"
+msgstr ""
+
+#: archive.c:342
+msgid "list supported archive formats"
+msgstr ""
+
+#: archive.c:344 builtin/archive.c:93 builtin/clone.c:85
+msgid "repo"
+msgstr ""
+
+#: archive.c:345 builtin/archive.c:94
+msgid "retrieve the archive from remote repository <repo>"
+msgstr ""
+
+#: archive.c:346 builtin/archive.c:95 builtin/notes.c:616
+msgid "command"
+msgstr ""
+
+#: archive.c:347 builtin/archive.c:96
+msgid "path to the remote git-upload-archive command"
+msgstr ""
+
#: bundle.c:36
#, c-format
msgid "'%s' does not look like a v2 bundle file"
@@ -45,7 +130,7 @@ msgstr ""
msgid "unrecognized header: %s%s (%d)"
msgstr ""
-#: bundle.c:89 builtin/commit.c:699
+#: bundle.c:89 builtin/commit.c:714
#, c-format
msgid "could not open '%s'"
msgstr ""
@@ -54,8 +139,8 @@ msgstr ""
msgid "Repository lacks these prerequisite commits:"
msgstr ""
-#: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
-#: builtin/log.c:726 builtin/log.c:1316 builtin/log.c:1535 builtin/merge.c:347
+#: bundle.c:164 sequencer.c:557 sequencer.c:989 builtin/log.c:290
+#: builtin/log.c:727 builtin/log.c:1313 builtin/log.c:1529 builtin/merge.c:347
#: builtin/shortlog.c:181
msgid "revision walk setup failed"
msgstr ""
@@ -82,7 +167,7 @@ msgstr[1] ""
msgid "rev-list died"
msgstr ""
-#: bundle.c:300 builtin/log.c:1212 builtin/shortlog.c:284
+#: bundle.c:300 builtin/log.c:1209 builtin/shortlog.c:284
#, c-format
msgid "unrecognized argument: %s"
msgstr ""
@@ -225,32 +310,32 @@ msgid ""
"%s"
msgstr ""
-#: diff.c:1400
+#: diff.c:1401
msgid " 0 files changed"
msgstr ""
-#: diff.c:1404
+#: diff.c:1405
#, c-format
msgid " %d file changed"
msgid_plural " %d files changed"
msgstr[0] ""
msgstr[1] ""
-#: diff.c:1421
+#: diff.c:1422
#, c-format
msgid ", %d insertion(+)"
msgid_plural ", %d insertions(+)"
msgstr[0] ""
msgstr[1] ""
-#: diff.c:1432
+#: diff.c:1433
#, c-format
msgid ", %d deletion(-)"
msgid_plural ", %d deletions(-)"
msgstr[0] ""
msgstr[1] ""
-#: diff.c:3461
+#: diff.c:3460
#, c-format
msgid ""
"Failed to parse --dirstat/-X option parameter:\n"
@@ -345,243 +430,235 @@ msgstr ""
msgid "error building trees"
msgstr ""
-#: merge-recursive.c:497
-msgid "diff setup failed"
-msgstr ""
-
-#: merge-recursive.c:627
-msgid "merge-recursive: disk full?"
-msgstr ""
-
-#: merge-recursive.c:690
+#: merge-recursive.c:672
#, c-format
msgid "failed to create path '%s'%s"
msgstr ""
-#: merge-recursive.c:701
+#: merge-recursive.c:683
#, c-format
msgid "Removing %s to make room for subdirectory\n"
msgstr ""
#. something else exists
#. .. but not some other error (who really cares what?)
-#: merge-recursive.c:715 merge-recursive.c:736
+#: merge-recursive.c:697 merge-recursive.c:718
msgid ": perhaps a D/F conflict?"
msgstr ""
-#: merge-recursive.c:726
+#: merge-recursive.c:708
#, c-format
msgid "refusing to lose untracked file at '%s'"
msgstr ""
-#: merge-recursive.c:766
+#: merge-recursive.c:748
#, c-format
msgid "cannot read object %s '%s'"
msgstr ""
-#: merge-recursive.c:768
+#: merge-recursive.c:750
#, c-format
msgid "blob expected for %s '%s'"
msgstr ""
-#: merge-recursive.c:791 builtin/clone.c:302
+#: merge-recursive.c:773 builtin/clone.c:302
#, c-format
msgid "failed to open '%s'"
msgstr ""
-#: merge-recursive.c:799
+#: merge-recursive.c:781
#, c-format
msgid "failed to symlink '%s'"
msgstr ""
-#: merge-recursive.c:802
+#: merge-recursive.c:784
#, c-format
msgid "do not know what to do with %06o %s '%s'"
msgstr ""
-#: merge-recursive.c:939
+#: merge-recursive.c:922
msgid "Failed to execute internal merge"
msgstr ""
-#: merge-recursive.c:943
+#: merge-recursive.c:926
#, c-format
msgid "Unable to add %s to database"
msgstr ""
-#: merge-recursive.c:959
+#: merge-recursive.c:942
msgid "unsupported object type in the tree"
msgstr ""
-#: merge-recursive.c:1038 merge-recursive.c:1052
+#: merge-recursive.c:1021 merge-recursive.c:1035
#, c-format
msgid ""
"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
"in tree."
msgstr ""
-#: merge-recursive.c:1044 merge-recursive.c:1057
+#: merge-recursive.c:1027 merge-recursive.c:1040
#, c-format
msgid ""
"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
"in tree at %s."
msgstr ""
-#: merge-recursive.c:1098
+#: merge-recursive.c:1081
msgid "rename"
msgstr ""
-#: merge-recursive.c:1098
+#: merge-recursive.c:1081
msgid "renamed"
msgstr ""
-#: merge-recursive.c:1154
+#: merge-recursive.c:1137
#, c-format
msgid "%s is a directory in %s adding as %s instead"
msgstr ""
-#: merge-recursive.c:1176
+#: merge-recursive.c:1159
#, c-format
msgid ""
"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
"\"->\"%s\" in \"%s\"%s"
msgstr ""
-#: merge-recursive.c:1181
+#: merge-recursive.c:1164
msgid " (left unresolved)"
msgstr ""
-#: merge-recursive.c:1235
+#: merge-recursive.c:1218
#, c-format
msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
msgstr ""
-#: merge-recursive.c:1265
+#: merge-recursive.c:1248
#, c-format
msgid "Renaming %s to %s and %s to %s instead"
msgstr ""
-#: merge-recursive.c:1464
+#: merge-recursive.c:1447
#, c-format
msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
msgstr ""
-#: merge-recursive.c:1474
+#: merge-recursive.c:1457
#, c-format
msgid "Adding merged %s"
msgstr ""
-#: merge-recursive.c:1479 merge-recursive.c:1677
+#: merge-recursive.c:1462 merge-recursive.c:1660
#, c-format
msgid "Adding as %s instead"
msgstr ""
-#: merge-recursive.c:1530
+#: merge-recursive.c:1513
#, c-format
msgid "cannot read object %s"
msgstr ""
-#: merge-recursive.c:1533
+#: merge-recursive.c:1516
#, c-format
msgid "object %s is not a blob"
msgstr ""
-#: merge-recursive.c:1581
+#: merge-recursive.c:1564
msgid "modify"
msgstr ""
-#: merge-recursive.c:1581
+#: merge-recursive.c:1564
msgid "modified"
msgstr ""
-#: merge-recursive.c:1591
+#: merge-recursive.c:1574
msgid "content"
msgstr ""
-#: merge-recursive.c:1598
+#: merge-recursive.c:1581
msgid "add/add"
msgstr ""
-#: merge-recursive.c:1632
+#: merge-recursive.c:1615
#, c-format
msgid "Skipped %s (merged same as existing)"
msgstr ""
-#: merge-recursive.c:1646
+#: merge-recursive.c:1629
#, c-format
msgid "Auto-merging %s"
msgstr ""
-#: merge-recursive.c:1650 git-submodule.sh:844
+#: merge-recursive.c:1633 git-submodule.sh:869
msgid "submodule"
msgstr ""
-#: merge-recursive.c:1651
+#: merge-recursive.c:1634
#, c-format
msgid "CONFLICT (%s): Merge conflict in %s"
msgstr ""
-#: merge-recursive.c:1741
+#: merge-recursive.c:1724
#, c-format
msgid "Removing %s"
msgstr ""
-#: merge-recursive.c:1766
+#: merge-recursive.c:1749
msgid "file/directory"
msgstr ""
-#: merge-recursive.c:1772
+#: merge-recursive.c:1755
msgid "directory/file"
msgstr ""
-#: merge-recursive.c:1777
+#: merge-recursive.c:1760
#, c-format
msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
msgstr ""
-#: merge-recursive.c:1787
+#: merge-recursive.c:1770
#, c-format
msgid "Adding %s"
msgstr ""
-#: merge-recursive.c:1804
+#: merge-recursive.c:1787
msgid "Fatal merge failure, shouldn't happen."
msgstr ""
-#: merge-recursive.c:1823
+#: merge-recursive.c:1806
msgid "Already up-to-date!"
msgstr ""
-#: merge-recursive.c:1832
+#: merge-recursive.c:1815
#, c-format
msgid "merging of trees %s and %s failed"
msgstr ""
-#: merge-recursive.c:1862
+#: merge-recursive.c:1845
#, c-format
msgid "Unprocessed path??? %s"
msgstr ""
-#: merge-recursive.c:1907
+#: merge-recursive.c:1890
msgid "Merging:"
msgstr ""
-#: merge-recursive.c:1920
+#: merge-recursive.c:1903
#, c-format
msgid "found %u common ancestor:"
msgid_plural "found %u common ancestors:"
msgstr[0] ""
msgstr[1] ""
-#: merge-recursive.c:1957
+#: merge-recursive.c:1940
msgid "merge returned no commit"
msgstr ""
-#: merge-recursive.c:2014
+#: merge-recursive.c:1997
#, c-format
msgid "Could not parse object '%s'"
msgstr ""
-#: merge-recursive.c:2026 builtin/merge.c:697
+#: merge-recursive.c:2009 builtin/merge.c:696
msgid "Unable to write index."
msgstr ""
@@ -632,14 +709,14 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: sequencer.c:121 builtin/merge.c:865 builtin/merge.c:978
-#: builtin/merge.c:1088 builtin/merge.c:1098
+#: sequencer.c:121 builtin/merge.c:864 builtin/merge.c:977
+#: builtin/merge.c:1087 builtin/merge.c:1097
#, c-format
msgid "Could not open '%s' for writing"
msgstr ""
-#: sequencer.c:123 builtin/merge.c:333 builtin/merge.c:868
-#: builtin/merge.c:1090 builtin/merge.c:1103
+#: sequencer.c:123 builtin/merge.c:333 builtin/merge.c:867
+#: builtin/merge.c:1089 builtin/merge.c:1102
#, c-format
msgid "Could not write to '%s'"
msgstr ""
@@ -657,7 +734,7 @@ msgid ""
"and commit the result with 'git commit'"
msgstr ""
-#: sequencer.c:160 sequencer.c:758 sequencer.c:841
+#: sequencer.c:160 sequencer.c:765 sequencer.c:848
#, c-format
msgid "Could not write to %s"
msgstr ""
@@ -693,178 +770,178 @@ msgstr ""
msgid "Unable to update cache tree\n"
msgstr ""
-#: sequencer.c:324
+#: sequencer.c:327
#, c-format
msgid "Could not parse commit %s\n"
msgstr ""
-#: sequencer.c:329
+#: sequencer.c:332
#, c-format
msgid "Could not parse parent commit %s\n"
msgstr ""
-#: sequencer.c:395
+#: sequencer.c:398
msgid "Your index file is unmerged."
msgstr ""
-#: sequencer.c:398
+#: sequencer.c:401
msgid "You do not have a valid HEAD"
msgstr ""
-#: sequencer.c:413
+#: sequencer.c:416
#, c-format
msgid "Commit %s is a merge but no -m option was given."
msgstr ""
-#: sequencer.c:421
+#: sequencer.c:424
#, c-format
msgid "Commit %s does not have parent %d"
msgstr ""
-#: sequencer.c:425
+#: sequencer.c:428
#, c-format
msgid "Mainline was specified but commit %s is not a merge."
msgstr ""
#. TRANSLATORS: The first %s will be "revert" or
#. "cherry-pick", the second %s a SHA1
-#: sequencer.c:436
+#: sequencer.c:439
#, c-format
msgid "%s: cannot parse parent commit %s"
msgstr ""
-#: sequencer.c:440
+#: sequencer.c:443
#, c-format
msgid "Cannot get commit message for %s"
msgstr ""
-#: sequencer.c:524
+#: sequencer.c:527
#, c-format
msgid "could not revert %s... %s"
msgstr ""
-#: sequencer.c:525
+#: sequencer.c:528
#, c-format
msgid "could not apply %s... %s"
msgstr ""
-#: sequencer.c:553
+#: sequencer.c:560
msgid "empty commit set passed"
msgstr ""
-#: sequencer.c:561
+#: sequencer.c:568
#, c-format
msgid "git %s: failed to read the index"
msgstr ""
-#: sequencer.c:566
+#: sequencer.c:573
#, c-format
msgid "git %s: failed to refresh the index"
msgstr ""
-#: sequencer.c:624
+#: sequencer.c:631
#, c-format
msgid "Cannot %s during a %s"
msgstr ""
-#: sequencer.c:646
+#: sequencer.c:653
#, c-format
msgid "Could not parse line %d."
msgstr ""
-#: sequencer.c:651
+#: sequencer.c:658
msgid "No commits parsed."
msgstr ""
-#: sequencer.c:664
+#: sequencer.c:671
#, c-format
msgid "Could not open %s"
msgstr ""
-#: sequencer.c:668
+#: sequencer.c:675
#, c-format
msgid "Could not read %s."
msgstr ""
-#: sequencer.c:675
+#: sequencer.c:682
#, c-format
msgid "Unusable instruction sheet: %s"
msgstr ""
-#: sequencer.c:703
+#: sequencer.c:710
#, c-format
msgid "Invalid key: %s"
msgstr ""
-#: sequencer.c:706
+#: sequencer.c:713
#, c-format
msgid "Invalid value for %s: %s"
msgstr ""
-#: sequencer.c:718
+#: sequencer.c:725
#, c-format
msgid "Malformed options sheet: %s"
msgstr ""
-#: sequencer.c:739
+#: sequencer.c:746
msgid "a cherry-pick or revert is already in progress"
msgstr ""
-#: sequencer.c:740
+#: sequencer.c:747
msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
msgstr ""
-#: sequencer.c:744
+#: sequencer.c:751
#, c-format
msgid "Could not create sequencer directory %s"
msgstr ""
-#: sequencer.c:760 sequencer.c:845
+#: sequencer.c:767 sequencer.c:852
#, c-format
msgid "Error wrapping up %s."
msgstr ""
-#: sequencer.c:779 sequencer.c:913
+#: sequencer.c:786 sequencer.c:920
msgid "no cherry-pick or revert in progress"
msgstr ""
-#: sequencer.c:781
+#: sequencer.c:788
msgid "cannot resolve HEAD"
msgstr ""
-#: sequencer.c:783
+#: sequencer.c:790
msgid "cannot abort from a branch yet to be born"
msgstr ""
-#: sequencer.c:805 builtin/apply.c:3988
+#: sequencer.c:812 builtin/apply.c:4005
#, c-format
msgid "cannot open %s: %s"
msgstr ""
-#: sequencer.c:808
+#: sequencer.c:815
#, c-format
msgid "cannot read %s: %s"
msgstr ""
-#: sequencer.c:809
+#: sequencer.c:816
msgid "unexpected end of file"
msgstr ""
-#: sequencer.c:815
+#: sequencer.c:822
#, c-format
msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
msgstr ""
-#: sequencer.c:838
+#: sequencer.c:845
#, c-format
msgid "Could not format %s."
msgstr ""
-#: sequencer.c:1000
+#: sequencer.c:1007
msgid "Can't revert as initial commit"
msgstr ""
-#: sequencer.c:1001
+#: sequencer.c:1008
msgid "Can't cherry-pick into empty head"
msgstr ""
@@ -887,12 +964,17 @@ msgstr ""
msgid "Upstream branch '%s' not stored as a remote-tracking branch"
msgstr ""
-#: wrapper.c:413
+#: wrapper.c:408
+#, c-format
+msgid "unable to access '%s': %s"
+msgstr ""
+
+#: wrapper.c:426
#, c-format
msgid "unable to look up current user in the passwd file: %s"
msgstr ""
-#: wrapper.c:414
+#: wrapper.c:427
msgid "no such user"
msgstr ""
@@ -946,11 +1028,6 @@ msgstr ""
msgid " (commit or discard the untracked or modified content in submodules)"
msgstr ""
-#: wt-status.c:224
-#, c-format
-msgid "%s files:"
-msgstr ""
-
#: wt-status.c:227
#, c-format
msgid " (use \"git %s <file>...\" to include in what will be committed)"
@@ -1151,11 +1228,11 @@ msgid "Initial commit"
msgstr ""
#: wt-status.c:1011
-msgid "Untracked"
+msgid "Untracked files"
msgstr ""
#: wt-status.c:1013
-msgid "Ignored"
+msgid "Ignored files"
msgstr ""
#: wt-status.c:1015
@@ -1171,61 +1248,77 @@ msgstr ""
msgid "No changes"
msgstr ""
-#: wt-status.c:1027
+#: wt-status.c:1028
#, c-format
-msgid "no changes added to commit%s\n"
+msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
msgstr ""
-#: wt-status.c:1029
-msgid " (use \"git add\" and/or \"git commit -a\")"
+#: wt-status.c:1031
+#, c-format
+msgid "no changes added to commit\n"
msgstr ""
-#: wt-status.c:1031
+#: wt-status.c:1034
#, c-format
-msgid "nothing added to commit but untracked files present%s\n"
+msgid ""
+"nothing added to commit but untracked files present (use \"git add\" to "
+"track)\n"
msgstr ""
-#: wt-status.c:1033
-msgid " (use \"git add\" to track)"
+#: wt-status.c:1037
+#, c-format
+msgid "nothing added to commit but untracked files present\n"
msgstr ""
-#: wt-status.c:1035 wt-status.c:1038 wt-status.c:1041
+#: wt-status.c:1040
#, c-format
-msgid "nothing to commit%s\n"
+msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
msgstr ""
-#: wt-status.c:1036
-msgid " (create/copy files and use \"git add\" to track)"
+#: wt-status.c:1043 wt-status.c:1048
+#, c-format
+msgid "nothing to commit\n"
msgstr ""
-#: wt-status.c:1039
-msgid " (use -u to show untracked files)"
+#: wt-status.c:1046
+#, c-format
+msgid "nothing to commit (use -u to show untracked files)\n"
msgstr ""
-#: wt-status.c:1042
-msgid " (working directory clean)"
+#: wt-status.c:1050
+#, c-format
+msgid "nothing to commit, working directory clean\n"
msgstr ""
-#: wt-status.c:1150
+#: wt-status.c:1158
msgid "HEAD (no branch)"
msgstr ""
-#: wt-status.c:1156
+#: wt-status.c:1164
msgid "Initial commit on "
msgstr ""
-#: wt-status.c:1171
+#: wt-status.c:1179
msgid "behind "
msgstr ""
-#: wt-status.c:1174 wt-status.c:1177
+#: wt-status.c:1182 wt-status.c:1185
msgid "ahead "
msgstr ""
-#: wt-status.c:1179
+#: wt-status.c:1187
msgid ", behind "
msgstr ""
+#: compat/precompose_utf8.c:58 builtin/clone.c:341
+#, c-format
+msgid "failed to unlink '%s'"
+msgstr ""
+
+#: builtin/add.c:19
+msgid "git add [options] [--] <filepattern>..."
+msgstr ""
+
#: builtin/add.c:62
#, c-format
msgid "unexpected diff status %c"
@@ -1249,7 +1342,7 @@ msgstr ""
msgid "Unstaged changes after refreshing the index:"
msgstr ""
-#: builtin/add.c:195 builtin/add.c:459 builtin/rm.c:186
+#: builtin/add.c:195 builtin/add.c:460 builtin/rm.c:186
#, c-format
msgid "pathspec '%s' did not match any files"
msgstr ""
@@ -1286,47 +1379,99 @@ msgstr ""
msgid "Could not apply '%s'"
msgstr ""
-#: builtin/add.c:312
+#: builtin/add.c:313
msgid "The following paths are ignored by one of your .gitignore files:\n"
msgstr ""
-#: builtin/add.c:352
+#: builtin/add.c:319 builtin/clean.c:52 builtin/fetch.c:78 builtin/mv.c:63
+#: builtin/prune-packed.c:76 builtin/push.c:388 builtin/remote.c:1253
+#: builtin/rm.c:133
+msgid "dry run"
+msgstr ""
+
+#: builtin/add.c:320 builtin/apply.c:4354 builtin/commit.c:1187
+#: builtin/count-objects.c:82 builtin/fsck.c:613 builtin/log.c:1477
+#: builtin/mv.c:62 builtin/read-tree.c:112
+msgid "be verbose"
+msgstr ""
+
+#: builtin/add.c:322
+msgid "interactive picking"
+msgstr ""
+
+#: builtin/add.c:323 builtin/checkout.c:1028 builtin/reset.c:248
+msgid "select hunks interactively"
+msgstr ""
+
+#: builtin/add.c:324
+msgid "edit current diff and apply"
+msgstr ""
+
+#: builtin/add.c:325
+msgid "allow adding otherwise ignored files"
+msgstr ""
+
+#: builtin/add.c:326
+msgid "update tracked files"
+msgstr ""
+
+#: builtin/add.c:327
+msgid "record only the fact that the path will be added later"
+msgstr ""
+
+#: builtin/add.c:328
+msgid "add changes from all tracked and untracked files"
+msgstr ""
+
+#: builtin/add.c:329
+msgid "don't add, only refresh the index"
+msgstr ""
+
+#: builtin/add.c:330
+msgid "just skip files which cannot be added because of errors"
+msgstr ""
+
+#: builtin/add.c:331
+msgid "check if - even missing - files are ignored in dry run"
+msgstr ""
+
+#: builtin/add.c:353
#, c-format
msgid "Use -f if you really want to add them.\n"
msgstr ""
-#: builtin/add.c:353
+#: builtin/add.c:354
msgid "no files added"
msgstr ""
-#: builtin/add.c:359
+#: builtin/add.c:360
msgid "adding files failed"
msgstr ""
-#: builtin/add.c:391
+#: builtin/add.c:392
msgid "-A and -u are mutually incompatible"
msgstr ""
-#: builtin/add.c:393
+#: builtin/add.c:394
msgid "Option --ignore-missing can only be used together with --dry-run"
msgstr ""
-#: builtin/add.c:413
+#: builtin/add.c:414
#, c-format
msgid "Nothing specified, nothing added.\n"
msgstr ""
-#: builtin/add.c:414
+#: builtin/add.c:415
#, c-format
msgid "Maybe you wanted to say 'git add .'?\n"
msgstr ""
-#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:289 builtin/mv.c:82
+#: builtin/add.c:421 builtin/clean.c:95 builtin/commit.c:289 builtin/mv.c:82
#: builtin/rm.c:162
msgid "index file corrupt"
msgstr ""
-#: builtin/add.c:480 builtin/apply.c:4433 builtin/mv.c:229 builtin/rm.c:260
+#: builtin/add.c:481 builtin/apply.c:4450 builtin/mv.c:229 builtin/rm.c:260
msgid "Unable to write new index file"
msgstr ""
@@ -1344,52 +1489,52 @@ msgstr ""
msgid "unrecognized whitespace ignore option '%s'"
msgstr ""
-#: builtin/apply.c:824
+#: builtin/apply.c:823
#, c-format
msgid "Cannot prepare timestamp regexp %s"
msgstr ""
-#: builtin/apply.c:833
+#: builtin/apply.c:832
#, c-format
msgid "regexec returned %d for input: %s"
msgstr ""
-#: builtin/apply.c:914
+#: builtin/apply.c:913
#, c-format
msgid "unable to find filename in patch at line %d"
msgstr ""
-#: builtin/apply.c:946
+#: builtin/apply.c:945
#, c-format
msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
msgstr ""
-#: builtin/apply.c:950
+#: builtin/apply.c:949
#, c-format
msgid "git apply: bad git-diff - inconsistent new filename on line %d"
msgstr ""
-#: builtin/apply.c:951
+#: builtin/apply.c:950
#, c-format
msgid "git apply: bad git-diff - inconsistent old filename on line %d"
msgstr ""
-#: builtin/apply.c:958
+#: builtin/apply.c:957
#, c-format
msgid "git apply: bad git-diff - expected /dev/null on line %d"
msgstr ""
-#: builtin/apply.c:1403
+#: builtin/apply.c:1420
#, c-format
msgid "recount: unexpected line: %.*s"
msgstr ""
-#: builtin/apply.c:1460
+#: builtin/apply.c:1477
#, c-format
msgid "patch fragment without header at line %d: %.*s"
msgstr ""
-#: builtin/apply.c:1477
+#: builtin/apply.c:1494
#, c-format
msgid ""
"git diff header lacks filename information when removing %d leading pathname "
@@ -1400,403 +1545,400 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: builtin/apply.c:1637
+#: builtin/apply.c:1654
msgid "new file depends on old contents"
msgstr ""
-#: builtin/apply.c:1639
+#: builtin/apply.c:1656
msgid "deleted file still has contents"
msgstr ""
-#: builtin/apply.c:1665
+#: builtin/apply.c:1682
#, c-format
msgid "corrupt patch at line %d"
msgstr ""
-#: builtin/apply.c:1701
+#: builtin/apply.c:1718
#, c-format
msgid "new file %s depends on old contents"
msgstr ""
-#: builtin/apply.c:1703
+#: builtin/apply.c:1720
#, c-format
msgid "deleted file %s still has contents"
msgstr ""
-#: builtin/apply.c:1706
+#: builtin/apply.c:1723
#, c-format
msgid "** warning: file %s becomes empty but is not deleted"
msgstr ""
-#: builtin/apply.c:1852
+#: builtin/apply.c:1869
#, c-format
msgid "corrupt binary patch at line %d: %.*s"
msgstr ""
#. there has to be one hunk (forward hunk)
-#: builtin/apply.c:1881
+#: builtin/apply.c:1898
#, c-format
msgid "unrecognized binary patch at line %d"
msgstr ""
-#: builtin/apply.c:1967
+#: builtin/apply.c:1984
#, c-format
msgid "patch with only garbage at line %d"
msgstr ""
-#: builtin/apply.c:2057
+#: builtin/apply.c:2074
#, c-format
msgid "unable to read symlink %s"
msgstr ""
-#: builtin/apply.c:2061
+#: builtin/apply.c:2078
#, c-format
msgid "unable to open or read %s"
msgstr ""
-#: builtin/apply.c:2132
+#: builtin/apply.c:2149
msgid "oops"
msgstr ""
-#: builtin/apply.c:2654
+#: builtin/apply.c:2671
#, c-format
msgid "invalid start of line: '%c'"
msgstr ""
-#: builtin/apply.c:2772
+#: builtin/apply.c:2789
#, c-format
msgid "Hunk #%d succeeded at %d (offset %d line)."
msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
msgstr[0] ""
msgstr[1] ""
-#: builtin/apply.c:2784
+#: builtin/apply.c:2801
#, c-format
msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
msgstr ""
-#: builtin/apply.c:2790
+#: builtin/apply.c:2807
#, c-format
msgid ""
"while searching for:\n"
"%.*s"
msgstr ""
-#: builtin/apply.c:2809
+#: builtin/apply.c:2826
#, c-format
msgid "missing binary patch data for '%s'"
msgstr ""
-#: builtin/apply.c:2912
+#: builtin/apply.c:2929
#, c-format
msgid "binary patch does not apply to '%s'"
msgstr ""
-#: builtin/apply.c:2918
+#: builtin/apply.c:2935
#, c-format
msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
msgstr ""
-#: builtin/apply.c:2939
+#: builtin/apply.c:2956
#, c-format
msgid "patch failed: %s:%ld"
msgstr ""
-#: builtin/apply.c:3061
+#: builtin/apply.c:3078
#, c-format
msgid "cannot checkout %s"
msgstr ""
-#: builtin/apply.c:3106 builtin/apply.c:3115 builtin/apply.c:3159
+#: builtin/apply.c:3123 builtin/apply.c:3132 builtin/apply.c:3176
#, c-format
msgid "read of %s failed"
msgstr ""
-#: builtin/apply.c:3139 builtin/apply.c:3361
+#: builtin/apply.c:3156 builtin/apply.c:3378
#, c-format
msgid "path %s has been renamed/deleted"
msgstr ""
-#: builtin/apply.c:3220 builtin/apply.c:3375
+#: builtin/apply.c:3237 builtin/apply.c:3392
#, c-format
msgid "%s: does not exist in index"
msgstr ""
-#: builtin/apply.c:3224 builtin/apply.c:3367 builtin/apply.c:3389
+#: builtin/apply.c:3241 builtin/apply.c:3384 builtin/apply.c:3406
#, c-format
msgid "%s: %s"
msgstr ""
-#: builtin/apply.c:3229 builtin/apply.c:3383
+#: builtin/apply.c:3246 builtin/apply.c:3400
#, c-format
msgid "%s: does not match index"
msgstr ""
-#: builtin/apply.c:3331
+#: builtin/apply.c:3348
msgid "removal patch leaves file contents"
msgstr ""
-#: builtin/apply.c:3400
+#: builtin/apply.c:3417
#, c-format
msgid "%s: wrong type"
msgstr ""
-#: builtin/apply.c:3402
+#: builtin/apply.c:3419
#, c-format
msgid "%s has type %o, expected %o"
msgstr ""
-#: builtin/apply.c:3503
+#: builtin/apply.c:3520
#, c-format
msgid "%s: already exists in index"
msgstr ""
-#: builtin/apply.c:3506
+#: builtin/apply.c:3523
#, c-format
msgid "%s: already exists in working directory"
msgstr ""
-#: builtin/apply.c:3526
+#: builtin/apply.c:3543
#, c-format
msgid "new mode (%o) of %s does not match old mode (%o)"
msgstr ""
-#: builtin/apply.c:3531
+#: builtin/apply.c:3548
#, c-format
msgid "new mode (%o) of %s does not match old mode (%o) of %s"
msgstr ""
-#: builtin/apply.c:3539
+#: builtin/apply.c:3556
#, c-format
msgid "%s: patch does not apply"
msgstr ""
-#: builtin/apply.c:3552
+#: builtin/apply.c:3569
#, c-format
msgid "Checking patch %s..."
msgstr ""
-#: builtin/apply.c:3607 builtin/checkout.c:213 builtin/reset.c:158
+#: builtin/apply.c:3624 builtin/checkout.c:215 builtin/reset.c:158
#, c-format
msgid "make_cache_entry failed for path '%s'"
msgstr ""
-#: builtin/apply.c:3750
+#: builtin/apply.c:3767
#, c-format
msgid "unable to remove %s from index"
msgstr ""
-#: builtin/apply.c:3778
+#: builtin/apply.c:3795
#, c-format
msgid "corrupt patch for subproject %s"
msgstr ""
-#: builtin/apply.c:3782
+#: builtin/apply.c:3799
#, c-format
msgid "unable to stat newly created file '%s'"
msgstr ""
-#: builtin/apply.c:3787
+#: builtin/apply.c:3804
#, c-format
msgid "unable to create backing store for newly created file %s"
msgstr ""
-#: builtin/apply.c:3790 builtin/apply.c:3898
+#: builtin/apply.c:3807 builtin/apply.c:3915
#, c-format
msgid "unable to add cache entry for %s"
msgstr ""
-#: builtin/apply.c:3823
+#: builtin/apply.c:3840
#, c-format
msgid "closing file '%s'"
msgstr ""
-#: builtin/apply.c:3872
+#: builtin/apply.c:3889
#, c-format
msgid "unable to write file '%s' mode %o"
msgstr ""
-#: builtin/apply.c:3959
+#: builtin/apply.c:3976
#, c-format
msgid "Applied patch %s cleanly."
msgstr ""
-#: builtin/apply.c:3967
+#: builtin/apply.c:3984
msgid "internal error"
msgstr ""
#. Say this even without --verbose
-#: builtin/apply.c:3970
+#: builtin/apply.c:3987
#, c-format
msgid "Applying patch %%s with %d reject..."
msgid_plural "Applying patch %%s with %d rejects..."
msgstr[0] ""
msgstr[1] ""
-#: builtin/apply.c:3980
+#: builtin/apply.c:3997
#, c-format
msgid "truncating .rej filename to %.*s.rej"
msgstr ""
-#: builtin/apply.c:4001
+#: builtin/apply.c:4018
#, c-format
msgid "Hunk #%d applied cleanly."
msgstr ""
-#: builtin/apply.c:4004
+#: builtin/apply.c:4021
#, c-format
msgid "Rejected hunk #%d."
msgstr ""
-#: builtin/apply.c:4154
+#: builtin/apply.c:4171
msgid "unrecognized input"
msgstr ""
-#: builtin/apply.c:4165
+#: builtin/apply.c:4182
msgid "unable to read index file"
msgstr ""
-#: builtin/apply.c:4284 builtin/apply.c:4287
+#: builtin/apply.c:4301 builtin/apply.c:4304 builtin/clone.c:91
+#: builtin/fetch.c:63
msgid "path"
msgstr ""
-#: builtin/apply.c:4285
+#: builtin/apply.c:4302
msgid "don't apply changes matching the given path"
msgstr ""
-#: builtin/apply.c:4288
+#: builtin/apply.c:4305
msgid "apply changes matching the given path"
msgstr ""
-#: builtin/apply.c:4290
+#: builtin/apply.c:4307
msgid "num"
msgstr ""
-#: builtin/apply.c:4291
+#: builtin/apply.c:4308
msgid "remove <num> leading slashes from traditional diff paths"
msgstr ""
-#: builtin/apply.c:4294
+#: builtin/apply.c:4311
msgid "ignore additions made by the patch"
msgstr ""
-#: builtin/apply.c:4296
+#: builtin/apply.c:4313
msgid "instead of applying the patch, output diffstat for the input"
msgstr ""
-#: builtin/apply.c:4300
-msgid "shows number of added and deleted lines in decimal notation"
+#: builtin/apply.c:4317
+msgid "show number of added and deleted lines in decimal notation"
msgstr ""
-#: builtin/apply.c:4302
+#: builtin/apply.c:4319
msgid "instead of applying the patch, output a summary for the input"
msgstr ""
-#: builtin/apply.c:4304
+#: builtin/apply.c:4321
msgid "instead of applying the patch, see if the patch is applicable"
msgstr ""
-#: builtin/apply.c:4306
+#: builtin/apply.c:4323
msgid "make sure the patch is applicable to the current index"
msgstr ""
-#: builtin/apply.c:4308
+#: builtin/apply.c:4325
msgid "apply a patch without touching the working tree"
msgstr ""
-#: builtin/apply.c:4310
+#: builtin/apply.c:4327
msgid "also apply the patch (use with --stat/--summary/--check)"
msgstr ""
-#: builtin/apply.c:4312
+#: builtin/apply.c:4329
msgid "attempt three-way merge if a patch does not apply"
msgstr ""
-#: builtin/apply.c:4314
+#: builtin/apply.c:4331
msgid "build a temporary index based on embedded index information"
msgstr ""
-#: builtin/apply.c:4316
+#: builtin/apply.c:4333 builtin/checkout-index.c:197 builtin/ls-files.c:460
msgid "paths are separated with NUL character"
msgstr ""
-#: builtin/apply.c:4319
+#: builtin/apply.c:4336
msgid "ensure at least <n> lines of context match"
msgstr ""
-#: builtin/apply.c:4320
+#: builtin/apply.c:4337
msgid "action"
msgstr ""
-#: builtin/apply.c:4321
+#: builtin/apply.c:4338
msgid "detect new or modified lines that have whitespace errors"
msgstr ""
-#: builtin/apply.c:4324 builtin/apply.c:4327
+#: builtin/apply.c:4341 builtin/apply.c:4344
msgid "ignore changes in whitespace when finding context"
msgstr ""
-#: builtin/apply.c:4330
+#: builtin/apply.c:4347
msgid "apply the patch in reverse"
msgstr ""
-#: builtin/apply.c:4332
+#: builtin/apply.c:4349
msgid "don't expect at least one line of context"
msgstr ""
-#: builtin/apply.c:4334
+#: builtin/apply.c:4351
msgid "leave the rejected hunks in corresponding *.rej files"
msgstr ""
-#: builtin/apply.c:4336
+#: builtin/apply.c:4353
msgid "allow overlapping hunks"
msgstr ""
-#: builtin/apply.c:4337
-msgid "be verbose"
-msgstr ""
-
-#: builtin/apply.c:4339
+#: builtin/apply.c:4356
msgid "tolerate incorrectly detected missing new-line at the end of file"
msgstr ""
-#: builtin/apply.c:4342
+#: builtin/apply.c:4359
msgid "do not trust the line counts in the hunk headers"
msgstr ""
-#: builtin/apply.c:4344
+#: builtin/apply.c:4361
msgid "root"
msgstr ""
-#: builtin/apply.c:4345
+#: builtin/apply.c:4362
msgid "prepend <root> to all filenames"
msgstr ""
-#: builtin/apply.c:4367
+#: builtin/apply.c:4384
msgid "--3way outside a repository"
msgstr ""
-#: builtin/apply.c:4375
+#: builtin/apply.c:4392
msgid "--index outside a repository"
msgstr ""
-#: builtin/apply.c:4378
+#: builtin/apply.c:4395
msgid "--cached outside a repository"
msgstr ""
-#: builtin/apply.c:4394
+#: builtin/apply.c:4411
#, c-format
msgid "can't open patch '%s'"
msgstr ""
-#: builtin/apply.c:4408
+#: builtin/apply.c:4425
#, c-format
msgid "squelched %d whitespace error"
msgid_plural "squelched %d whitespace errors"
msgstr[0] ""
msgstr[1] ""
-#: builtin/apply.c:4414 builtin/apply.c:4424
+#: builtin/apply.c:4431 builtin/apply.c:4441
#, c-format
msgid "%d line adds whitespace errors."
msgid_plural "%d lines add whitespace errors."
@@ -1838,175 +1980,428 @@ msgstr ""
msgid "git archive: expected a flush"
msgstr ""
-#: builtin/branch.c:144
+#: builtin/bisect--helper.c:7
+msgid "git bisect--helper --next-all [--no-checkout]"
+msgstr ""
+
+#: builtin/bisect--helper.c:17
+msgid "perform 'git bisect next'"
+msgstr ""
+
+#: builtin/bisect--helper.c:19
+msgid "update BISECT_HEAD instead of checking out the current commit"
+msgstr ""
+
+#: builtin/blame.c:25
+msgid "git blame [options] [rev-opts] [rev] [--] file"
+msgstr ""
+
+#: builtin/blame.c:30 builtin/shortlog.c:15
+msgid "[rev-opts] are documented in git-rev-list(1)"
+msgstr ""
+
+#: builtin/blame.c:2316
+msgid "Show blame entries as we find them, incrementally"
+msgstr ""
+
+#: builtin/blame.c:2317
+msgid "Show blank SHA-1 for boundary commits (Default: off)"
+msgstr ""
+
+#: builtin/blame.c:2318
+msgid "Do not treat root commits as boundaries (Default: off)"
+msgstr ""
+
+#: builtin/blame.c:2319
+msgid "Show work cost statistics"
+msgstr ""
+
+#: builtin/blame.c:2320
+msgid "Show output score for blame entries"
+msgstr ""
+
+#: builtin/blame.c:2321
+msgid "Show original filename (Default: auto)"
+msgstr ""
+
+#: builtin/blame.c:2322
+msgid "Show original linenumber (Default: off)"
+msgstr ""
+
+#: builtin/blame.c:2323
+msgid "Show in a format designed for machine consumption"
+msgstr ""
+
+#: builtin/blame.c:2324
+msgid "Show porcelain format with per-line commit information"
+msgstr ""
+
+#: builtin/blame.c:2325
+msgid "Use the same output mode as git-annotate (Default: off)"
+msgstr ""
+
+#: builtin/blame.c:2326
+msgid "Show raw timestamp (Default: off)"
+msgstr ""
+
+#: builtin/blame.c:2327
+msgid "Show long commit SHA1 (Default: off)"
+msgstr ""
+
+#: builtin/blame.c:2328
+msgid "Suppress author name and timestamp (Default: off)"
+msgstr ""
+
+#: builtin/blame.c:2329
+msgid "Show author email instead of name (Default: off)"
+msgstr ""
+
+#: builtin/blame.c:2330
+msgid "Ignore whitespace differences"
+msgstr ""
+
+#: builtin/blame.c:2331
+msgid "Spend extra cycles to find better match"
+msgstr ""
+
+#: builtin/blame.c:2332
+msgid "Use revisions from <file> instead of calling git-rev-list"
+msgstr ""
+
+#: builtin/blame.c:2333
+msgid "Use <file>'s contents as the final image"
+msgstr ""
+
+#: builtin/blame.c:2334 builtin/blame.c:2335
+msgid "score"
+msgstr ""
+
+#: builtin/blame.c:2334
+msgid "Find line copies within and across files"
+msgstr ""
+
+#: builtin/blame.c:2335
+msgid "Find line movements within and across files"
+msgstr ""
+
+#: builtin/blame.c:2336
+msgid "n,m"
+msgstr ""
+
+#: builtin/blame.c:2336
+msgid "Process only line range n,m, counting from 1"
+msgstr ""
+
+#: builtin/branch.c:23
+msgid "git branch [options] [-r | -a] [--merged | --no-merged]"
+msgstr ""
+
+#: builtin/branch.c:24
+msgid "git branch [options] [-l] [-f] <branchname> [<start-point>]"
+msgstr ""
+
+#: builtin/branch.c:25
+msgid "git branch [options] [-r] (-d | -D) <branchname>..."
+msgstr ""
+
+#: builtin/branch.c:26
+msgid "git branch [options] (-m | -M) [<oldbranch>] <newbranch>"
+msgstr ""
+
+#: builtin/branch.c:145
#, c-format
msgid ""
"deleting branch '%s' that has been merged to\n"
" '%s', but not yet merged to HEAD."
msgstr ""
-#: builtin/branch.c:148
+#: builtin/branch.c:149
#, c-format
msgid ""
"not deleting branch '%s' that is not yet merged to\n"
" '%s', even though it is merged to HEAD."
msgstr ""
-#: builtin/branch.c:180
+#: builtin/branch.c:181
msgid "cannot use -a with -d"
msgstr ""
-#: builtin/branch.c:186
+#: builtin/branch.c:187
msgid "Couldn't look up commit object for HEAD"
msgstr ""
-#: builtin/branch.c:191
+#: builtin/branch.c:192
#, c-format
msgid "Cannot delete the branch '%s' which you are currently on."
msgstr ""
-#: builtin/branch.c:202
+#: builtin/branch.c:203
#, c-format
msgid "remote branch '%s' not found."
msgstr ""
-#: builtin/branch.c:203
+#: builtin/branch.c:204
#, c-format
msgid "branch '%s' not found."
msgstr ""
-#: builtin/branch.c:210
+#: builtin/branch.c:211
#, c-format
msgid "Couldn't look up commit object for '%s'"
msgstr ""
-#: builtin/branch.c:216
+#: builtin/branch.c:217
#, c-format
msgid ""
"The branch '%s' is not fully merged.\n"
"If you are sure you want to delete it, run 'git branch -D %s'."
msgstr ""
-#: builtin/branch.c:225
+#: builtin/branch.c:226
#, c-format
msgid "Error deleting remote branch '%s'"
msgstr ""
-#: builtin/branch.c:226
+#: builtin/branch.c:227
#, c-format
msgid "Error deleting branch '%s'"
msgstr ""
-#: builtin/branch.c:233
+#: builtin/branch.c:234
#, c-format
msgid "Deleted remote branch %s (was %s).\n"
msgstr ""
-#: builtin/branch.c:234
+#: builtin/branch.c:235
#, c-format
msgid "Deleted branch %s (was %s).\n"
msgstr ""