From: Junio C Hamano Date: Sat, 15 Sep 2012 04:39:27 +0000 (-0700) Subject: Merge branch 'jc/mailinfo-RE' X-Git-Tag: v1.8.0-rc0~53 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/cd14f3e17cf60c478ef4e921fc622b6164cb2f25?hp=d5b4d80d1cc056d5cc4a18f457133b2de8fc685a Merge branch 'jc/mailinfo-RE' We strip the prefix from "Re: subject" and also from a less common "re: subject", but left even less common "RE: subject" intact. * jc/mailinfo-RE: mailinfo: strip "RE: " prefix --- diff --git a/.gitignore b/.gitignore index bb5c91e712..68fe464090 100644 --- a/.gitignore +++ b/.gitignore @@ -189,6 +189,7 @@ /test-mktemp /test-parse-options /test-path-utils +/test-regex /test-revision-walking /test-run-command /test-sha1 diff --git a/.mailmap b/.mailmap index 6303782106..bcf4f8770f 100644 --- a/.mailmap +++ b/.mailmap @@ -18,6 +18,7 @@ David KÃ¥gedal David S. Miller Deskin Miller Dirk Süsserott +Erik Faye-Lund Fredrik Kuivinen H. Peter Anvin H. Peter Anvin @@ -26,6 +27,9 @@ Horst H. von Brand İsmail Dönmez Jay Soffian Joachim Berdal Haga +Johannes Sixt +Johannes Sixt +Johannes Sixt Jon Loeliger Jon Seymour Jonathan Nieder @@ -43,6 +47,7 @@ Lars Doelle Li Hong Lukas Sandström Martin Langhoff +Martin von Zweigbergk Michael Coleman Michael J Gruber Michael W. Olson @@ -51,7 +56,10 @@ Nanako Shiraishi Nanako Shiraishi Nguyễn Thái Ngọc Duy +Peter Krefting +Peter Krefting Philippe Bruhat +Ralf Thielow Ramsay Allan Jones René Scharfe Robert Fitzsimons @@ -61,6 +69,7 @@ Sean Estabrooks Shawn O. Pearce Steven Grimm Theodore Ts'o +Thomas Rast Tony Luck Uwe Kleine-König Uwe Kleine-König diff --git a/Documentation/Makefile b/Documentation/Makefile index 063fa696c9..cf5916fe8b 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -344,4 +344,7 @@ require-htmlrepo:: quick-install-html: require-htmlrepo '$(SHELL_PATH_SQ)' ./install-doc-quick.sh $(HTML_REPO) $(DESTDIR)$(htmldir) +print-man1: + @for i in $(MAN1_TXT); do echo $$i; done + .PHONY: FORCE diff --git a/Documentation/RelNotes/1.7.11.6.txt b/Documentation/RelNotes/1.7.11.6.txt index e548a59824..ba7d3c3966 100644 --- a/Documentation/RelNotes/1.7.11.6.txt +++ b/Documentation/RelNotes/1.7.11.6.txt @@ -4,31 +4,81 @@ Git v1.7.11.6 Release Notes Fixes since v1.7.11.5 --------------------- -This is primarily documentation and low-impact code clarification. - - - "ciabot" script (in contrib/) has been updated with extensive + * "ciabot" script (in contrib/) has been updated with extensive documentation. - - The "--rebase" option to "git pull" can be abbreviated to "-r", - but we didn't document it. + * "git foo" errored out with "Not a directory" when the user had a + non-directory on $PATH, and worse yet it masked an alias "foo" from + running. - - It was generally understood that "--long-option"s to many of our - subcommands can be abbreviated to the unique prefix, but it was not - easy to find it described for new readers of the documentation set. + * When the user exports a non-default IFS without HT, scripts that + rely on being able to parse "ls-files -s | while read a b c..." + started to fail. Protect them from such a misconfiguration. - - The "--topo-order", "--date-order" (and the lack of either means - the default order) options to "rev-list" and "log" family of - commands were poorly described in the documentation. + * When the user gives an argument that can be taken as both a + revision name and a pathname without disambiguating with "--", we + used to give a help message "Use '--' to separate". The message + has been clarified to show where that '--' goes on the command + line. + + * Documentation for the configuration file format had a confusing + example. - - Older parts of the documentation described as if having a regular + * Older parts of the documentation described as if having a regular file in .git/refs/ hierarchy were the only way to have branches and tags, which is not true for quite some time. - - A utility shell function test_seq has been added as a replacement - for the 'seq' utility found on some platforms. + * It was generally understood that "--long-option"s to many of our + subcommands can be abbreviated to the unique prefix, but it was not + easy to find it described for new readers of the documentation set. - - Fallback 'getpass' implementation made unportable use of stdio API. + * The "--topo-order", "--date-order" (and the lack of either means + the default order) options to "rev-list" and "log" family of + commands were poorly described in the documentation. - - "git commit --amend" let the user edit the log message and then + * "git commit --amend" let the user edit the log message and then died when the human-readable committer name was given insufficiently by getpwent(3). + + * The exit status code from "git config" was way overspecified while + being incorrect. The implementation has been updated to give the + documented status for a case that was documented, and introduce a + new code for "all other errors". + + * The output from "git diff -B" for a file that ends with an + incomplete line did not put "\ No newline..." on a line of its own. + + * "git diff" had a confusion between taking data from a path in the + working tree and taking data from an object that happens to have + name 0{40} recorded in a tree. + + * The "--rebase" option to "git pull" can be abbreviated to "-r", + but we didn't document it. + + * When "git push" triggered the automatic gc on the receiving end, a + message from "git prune" that said it was removing cruft leaked to + the standard output, breaking the communication protocol. + + * The reflog entries left by "git rebase" and "git rebase -i" were + inconsistent (the interactive one gave an abbreviated object name). + + * "git send-email" did not unquote encoded words that appear on the + header correctly, and lost "_" from strings. + + * "git stash apply/pop" did not trigger "rerere" upon conflicts + unlike other mergy operations. + + * "git submodule path" did not error out when the path to the + submodule was misspelt. + + * "git submodule update -f" did not update paths in the working tree + that has local changes. + (merge 01d4721 sz/submodule-force-update later to maint). + + * "gitweb" when used with PATH_INFO failed to notice directories with + SP (and other characters that need URL-style quoting) in them. + + * Fallback 'getpass' implementation made unportable use of stdio API. + + * A utility shell function test_seq has been added as a replacement + for the 'seq' utility found on some platforms. diff --git a/Documentation/RelNotes/1.7.11.7.txt b/Documentation/RelNotes/1.7.11.7.txt new file mode 100644 index 0000000000..e7e79d999b --- /dev/null +++ b/Documentation/RelNotes/1.7.11.7.txt @@ -0,0 +1,46 @@ +Git v1.7.11.7 Release Notes +=========================== + +Fixes since v1.7.11.6 +--------------------- + + * The synopsis said "checkout [-B branch]" to make it clear the + branch name is a parameter to the option, but the heading for the + option description was "-B::", not "-B branch::", making the + documentation misleading. + + * 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. A new test has been added to check this. + + * "git apply -p0" did not parse pathnames on "diff --git" line + correctly. This caused patches that had pathnames in no other + places to be mistakenly rejected (most notably, binary patch that + does not rename nor change mode). Textual patches, renames or mode + changes have preimage and postimage pathnames in different places + in a form that can be parsed unambiguously and did not suffer from + this problem. + + * After "gitk" showed the contents of a tag, neither "Reread + references" nor "Reload" did not update what is shown as the + contents of it, when the user overwrote the tag with "git tag -f". + + * "git for-each-ref" did not currectly support more than one --sort + option. + + * "git log .." errored out saying it is both rev range and a path + when there is no disambiguating "--" is on the command line. + Update the command line parser to interpret ".." as a path in such + a case. + + * Pushing to smart HTTP server with recent Git fails without having + the username in the URL to force authentication, if the server is + configured to allow GET anonymously, while requiring authentication + for POST. + + * "git show --format='%ci'" did not give timestamp correctly for + commits created without human readable name on "committer" line. + (merge e27ddb6 jc/maint-ident-missing-human-name later to maint). + + * "git show --quiet" ought to be a synonym for "git show -s", but + wasn't. diff --git a/Documentation/RelNotes/1.7.12.1.txt b/Documentation/RelNotes/1.7.12.1.txt new file mode 100644 index 0000000000..671e3d2eb5 --- /dev/null +++ b/Documentation/RelNotes/1.7.12.1.txt @@ -0,0 +1,123 @@ +Git 1.7.12.1 Release Notes +========================== + +Fixes since v1.7.12 +------------------- + + * "git apply -p0" did not parse pathnames on "diff --git" line + correctly. This caused patches that had pathnames in no other + places to be mistakenly rejected (most notably, binary patch that + does not rename nor change mode). Textual patches, renames or mode + changes have preimage and postimage pathnames in different places + in a form that can be parsed unambiguously and did not suffer from + this problem. + + * "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. + + * "git commit --amend" let the user edit the log message and then + died when the human-readable committer name was given + insufficiently by getpwent(3). + + * Some capabilities were asked by fetch-pack even when upload-pack + did not advertise that they are available. fetch-pack has been + fixed not to do so. + + * "git diff" had a confusion between taking data from a path in the + working tree and taking data from an object that happens to have + name 0{40} recorded in a tree. + + * "git for-each-ref" did not correctly support more than one --sort + option. + + * "git log .." errored out saying it is both rev range and a path + when there is no disambiguating "--" is on the command line. + Update the command line parser to interpret ".." as a path in such + a case. + + * The "--topo-order", "--date-order" (and the lack of either means + the default order) options to "rev-list" and "log" family of + commands were poorly described in the documentation. + + * "git prune" without "-v" used to warn about leftover temporary + files (which is an indication of an earlier aborted operation). + + * Pushing to smart HTTP server with recent Git fails without having + the username in the URL to force authentication, if the server is + configured to allow GET anonymously, while requiring authentication + for POST. + + * The reflog entries left by "git rebase" and "git rebase -i" were + inconsistent (the interactive one gave an abbreviated object name). + + * When "git push" triggered the automatic gc on the receiving end, a + message from "git prune" that said it was removing cruft leaked to + the standard output, breaking the communication protocol. + + * "git show --quiet" ought to be a synonym for "git show -s", but + wasn't. + + * "git show --format='%ci'" did not give timestamp correctly for + commits created without human readable name on "committer" line. + + * "git send-email" did not unquote encoded words that appear on the + header correctly, and lost "_" from strings. + + * The interactive prompt "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. + + * "gitweb" when used with PATH_INFO failed to notice directories with + SP (and other characters that need URL-style quoting) in them. + + * When the user gives an argument that can be taken as both a + revision name and a pathname without disambiguating with "--", we + used to give a help message "Use '--' to separate". The message + has been clarified to show where that '--' goes on the command + line. + + * When the user exports a non-default IFS without HT, scripts that + rely on being able to parse "ls-files -s | while read a b c..." + started to fail. Protect them from such a misconfiguration. + + * After "gitk" showed the contents of a tag, neither "Reread + references" nor "Reload" did not update what is shown as the + contents of it, when the user overwrote the tag with "git tag -f". + + * "ciabot" script (in contrib/) has been updated with extensive + documentation. + + * Older parts of the documentation described as if having a regular + file in .git/refs/ hierarchy were the only way to have branches and + tags, which is not true for quite some time. + + * A utility shell function test_seq has been added as a replacement + for the 'seq' utility found on some platforms. + + * Compatibility wrapper to learn the maximum number of file + descriptors we can open around sysconf(_SC_OPEN_MAX) and + getrlimit(RLIMIT_NO_FILE) has been introduced for portability. + + * We used curl_easy_strerror() without checking version of cURL, + breaking the build for versions before curl 7.12.0. + + * Code to work around MacOS X UTF-8 gotcha has been cleaned up. + + * Fallback 'getpass' implementation made unportable use of stdio API. + + * The "--rebase" option to "git pull" can be abbreviated to "-r", + but we didn't document it. + + * It was generally understood that "--long-option"s to many of our + subcommands can be abbreviated to the unique prefix, but it was not + easy to find it described for new readers of the documentation set. + + * The synopsis said "checkout [-B branch]" to make it clear the + branch name is a parameter to the option, but the heading for the + option description was "-B::", not "-B branch::", making the + documentation misleading. diff --git a/Documentation/RelNotes/1.8.0.txt b/Documentation/RelNotes/1.8.0.txt new file mode 100644 index 0000000000..9714422dee --- /dev/null +++ b/Documentation/RelNotes/1.8.0.txt @@ -0,0 +1,163 @@ +Git v1.8.0 Release Notes +======================== + +Backward compatibility notes +---------------------------- + +In the next major release, we will change the behaviour of the "git +push" command. When "git push [$there]" does not say what to push, we +have used the traditional "matching" semantics (all your branches were +sent to the remote as long as there already are branches of the same +name over there). We will 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. + + * A credential helper to allow access to the Gnome keyring has been + added. + + * 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. + + * "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 + 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 merge-base" learned "--is-ancestor A B" option to tell if A is + an ancestor of B. The result is indicated by its exit status code. + + +Foreign Interface + + * "git svn" has been updated to work with SVN 1.7. + + +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. A new test has been added to check this. + + * The "check-docs" build target has been updated and greatly + simplified. + + * 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 parameter 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 "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 -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). + + * "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 combination "--all --tags" makes + much less sense than "--all --no-tags"). + (merge 8556646 dj/fetch-all-tags later to maint). + + * The subcommand in "git remote" to remove a defined remote was + "rm" and the command did not take a fully-spelled "remove". + (merge e17dba8 nd/maint-remote-remove later to maint). + + * After "gitk" showed the contents of a tag, neither "Reread + references" nor "Reload" did not update what is shown as the + contents of it, when the user overwrote the tag with "git tag -f". + + * "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. + + * "git show --format='%ci'" did not give timestamp correctly for + commits created without human readable name on "committer" line. + (merge e27ddb6 jc/maint-ident-missing-human-name later to maint). + + * "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. + (merge a73e22e mz/cherry-pick-cmdline-order later to maint). + + * "git show --quiet" ought to be a synonym for "git show -s", but + wasn't. + (merge f9c75d8 jk/maint-quiet-is-synonym-to-s-in-log later to maint). + + * "git p4", when "--use-client-spec" and "--detect-branches" are used + together, misdetected branches. + (merge 21ef5df pw/p4-use-client-spec-branch-detection later to maint). + + * Output from "git branch -v" contains "(no branch)" that could be + localized, but the code to align it along with the names of + branches were counting in bytes, not in display columns. + (merge 1452bd6 nd/branch-v-alignment later to maint). + + * 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. + + * The interactive prompt "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. + (merge 6183749 sb/send-email-reconfirm-fix later to maint). diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf index a26d245ab4..1273a85c8a 100644 --- a/Documentation/asciidoc.conf +++ b/Documentation/asciidoc.conf @@ -36,7 +36,7 @@ ifndef::git-asciidoc-no-roff[] # v1.72 breaks with this because it replaces dots not in roff requests. [listingblock] {title} - + ifdef::doctype-manpage[] .ft C endif::doctype-manpage[] @@ -53,7 +53,7 @@ ifdef::doctype-manpage[] # The following two small workarounds insert a simple paragraph after screen [listingblock] {title} - + | {title#} diff --git a/Documentation/config.txt b/Documentation/config.txt index a95e5a4ac9..6416cae511 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1210,8 +1210,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/git-branch.txt b/Documentation/git-branch.txt index 47235bea04..9c1d2f1781 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.txt @@ -13,6 +13,8 @@ SYNOPSIS [--column[=] | --no-column] [(--merged | --no-merged | --contains) []] [...] 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] [] +'git branch' (--set-upstream-to= | -u ) [] +'git branch' --unset-upstream [] 'git branch' (-m | -M) [] 'git branch' (-d | -D) [-r] ... 'git branch' --edit-description [] @@ -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, will be renamed to . If had a corresponding reflog, it is renamed to match @@ -173,6 +175,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 :: +--set-upstream-to=:: + Set up 's tracking information so is + considered 's upstream branch. If no + is specified, then it defaults to the current branch. + +--unset-upstream:: + Remove the upstream information for . 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-checkout.txt b/Documentation/git-checkout.txt index 63a251612a..7958a47006 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -84,11 +84,11 @@ entries; instead, unmerged entries are ignored. When checking out paths from the index, check out stage #2 ('ours') or #3 ('theirs') for unmerged paths. --b:: +-b :: Create a new branch named and start it at ; see linkgit:git-branch[1] for details. --B:: +-B :: Creates the branch and start it at ; if it already exists, then reset it to . This is equivalent to running "git branch" with "-f"; see @@ -124,7 +124,7 @@ explicitly give a name with '-b' in such a case. is not a branch name. See the "DETACHED HEAD" section below for details. ---orphan:: +--orphan :: Create a new 'orphan' branch, named , started from and switch to it. The first commit made on this new branch will have no parents and it will be the root of a new @@ -367,6 +367,18 @@ $ git checkout hello.c <3> <2> take a file out of another commit <3> restore hello.c from the index + +If you want to check out _all_ C source files out of the index, +you can say ++ +------------ +$ git checkout -- '*.c' +------------ ++ +Note the quotes around `*.c`. The file `hello.c` will also be +checked out, even though it is no longer in the working tree, +because the file globbing is used to match entries in the index +(not in the working tree by the shell). ++ If you have an unfortunate branch that is named `hello.c`, this step would be confused as an instruction to switch to that branch. You should instead write: diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt index 0e170a51ca..c205d2363e 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-config.txt b/Documentation/git-config.txt index 2d6ef32a08..eaea079165 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -54,16 +54,16 @@ configuration file by default, and options '--system', '--global', '--file ' can be used to tell the command to write to that location (you can say '--local' but that is the default). -This command will fail (with exit code ret) if: +This command will fail with non-zero status upon error. Some exit +codes are: . The config file is invalid (ret=3), . can not write to the config file (ret=4), . no section or name was provided (ret=2), . the section or key is invalid (ret=1), . you try to unset an option which does not exist (ret=5), -. you try to unset/set an option for which multiple lines match (ret=5), -. you try to use an invalid regexp (ret=6), or -. you use '--global' option without $HOME being properly set (ret=128). +. you try to unset/set an option for which multiple lines match (ret=5), or +. you try to use an invalid regexp (ret=6). On success, the command returns the exit code 0. @@ -267,7 +267,7 @@ Given a .git/config like this: ; Proxy settings [core] - gitproxy="proxy-command" for kernel.org + gitproxy=proxy-command for kernel.org gitproxy=default-proxy ; for all the rest you can set the filemode to true with @@ -342,7 +342,7 @@ To actually match only values with an exclamation mark, you have to To add a new proxy, without altering any of the existing ones, use ------------ -% git config core.gitproxy '"proxy-command" for example.com' +% git config --add core.gitproxy '"proxy-command" for example.com' ------------ An example to use customized color from the configuration in your diff --git a/Documentation/git-credential-cache--daemon.txt b/Documentation/git-credential-cache--daemon.txt index 11edc5a173..d15db42d43 100644 --- a/Documentation/git-credential-cache--daemon.txt +++ b/Documentation/git-credential-cache--daemon.txt @@ -3,7 +3,7 @@ git-credential-cache--daemon(1) NAME ---- -git-credential-cache--daemon - temporarily store user credentials in memory +git-credential-cache--daemon - Temporarily store user credentials in memory SYNOPSIS -------- diff --git a/Documentation/git-credential-cache.txt b/Documentation/git-credential-cache.txt index f3d09c5d51..eeff5fa989 100644 --- a/Documentation/git-credential-cache.txt +++ b/Documentation/git-credential-cache.txt @@ -3,7 +3,7 @@ git-credential-cache(1) NAME ---- -git-credential-cache - helper to temporarily store passwords in memory +git-credential-cache - Helper to temporarily store passwords in memory SYNOPSIS -------- diff --git a/Documentation/git-credential-store.txt b/Documentation/git-credential-store.txt index 31093467d1..b27c03c361 100644 --- a/Documentation/git-credential-store.txt +++ b/Documentation/git-credential-store.txt @@ -3,7 +3,7 @@ git-credential-store(1) NAME ---- -git-credential-store - helper to store credentials on disk +git-credential-store - Helper to store credentials on disk SYNOPSIS -------- diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt index e8f757704c..7e5098a95e 100644 --- a/Documentation/git-daemon.txt +++ b/Documentation/git-daemon.txt @@ -16,6 +16,7 @@ SYNOPSIS [--reuseaddr] [--detach] [--pid-file=] [--enable=] [--disable=] [--allow-override=] [--forbid-override=] + [--access-hook=] [--inetd | [--listen=] [--port=] [--user= [--group=]] [...] @@ -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=:: + Every time a client connects, first run an external command + specified by the 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. + :: 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 31fc2e3aed..73ca7025a3 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 :: --extcmd=:: Specify a custom command for viewing diffs. diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index 3bec036883..cfecf848fb 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-log.txt b/Documentation/git-log.txt index 1f906208f9..585dac40ba 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -24,10 +24,6 @@ each commit introduces are shown. OPTIONS ------- --:: - Limits the number of commits to show. - Note that this is a commit limiting option, see below. - ..:: Show only commits between the named two commits. When either or is omitted, it defaults to @@ -137,6 +133,8 @@ Examples This makes sense only when following a strict policy of merging all topic branches when staying on a single integration branch. +`git log -3`:: + Limits the number of commits to show to 3. Discussion ---------- diff --git a/Documentation/git-ls-remote.txt b/Documentation/git-ls-remote.txt index 7a9b86a58a..774de5e9d9 100644 --- a/Documentation/git-ls-remote.txt +++ b/Documentation/git-ls-remote.txt @@ -42,6 +42,11 @@ OPTIONS it successfully talked with the remote repository, whether it found any matching refs. +--get-url:: + Expand the URL of the given remote repository taking into account any + "url..insteadOf" config setting (See linkgit:git-config[1]) and + exit without talking to the remote. + :: Location of the repository. The shorthand defined in $GIT_DIR/branches/ can be used. Use "." (dot) to list references in diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt index b295bf8330..87842e33f8 100644 --- a/Documentation/git-merge-base.txt +++ b/Documentation/git-merge-base.txt @@ -11,6 +11,7 @@ SYNOPSIS [verse] 'git merge-base' [-a|--all] ... 'git merge-base' [-a|--all] --octopus ... +'git merge-base' --is-ancestor 'git merge-base' --independent ... 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 is an ancestor of the second , + 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 d7207bd9b9..6b563c500f 100644 --- a/Documentation/git-mergetool.txt +++ b/Documentation/git-mergetool.txt @@ -64,6 +64,9 @@ variable `mergetool..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-remote.txt b/Documentation/git-remote.txt index a308f4c79f..e8c396b5f9 100644 --- a/Documentation/git-remote.txt +++ b/Documentation/git-remote.txt @@ -12,7 +12,7 @@ SYNOPSIS 'git remote' [-v | --verbose] 'git remote add' [-t ] [-m ] [-f] [--tags|--no-tags] [--mirror=] 'git remote rename' -'git remote rm' +'git remote remove' 'git remote set-head' (-a | -d | ) 'git remote set-branches' [--add] ... 'git remote set-url' [--push] [] @@ -85,6 +85,7 @@ In case and are the same, and is a file under `$GIT_DIR/remotes` or `$GIT_DIR/branches`, the remote is converted to the configuration file format. +'remove':: 'rm':: Remove the remote named . All remote-tracking branches and diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index fbbbcb282c..2de7bf0900 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -149,6 +149,11 @@ submodule with the `--init` option. + If `--recursive` is specified, this command will recurse into the registered submodules, and update any nested submodules within. ++ +If `--force` is specified, the submodule will be checked out (using +`git checkout --force` if appropriate), even if the commit specified in the +index of the containing repository already matches the commit checked out in +the submodule. summary:: Show commit summary between the given commit (defaults to HEAD) and @@ -210,7 +215,9 @@ OPTIONS This option is only valid for add and update commands. When running add, allow adding an otherwise ignored submodule path. When running update, throw away local changes in submodules when - switching to a different commit. + switching to a different commit; and always run a checkout operation + in the submodule, even if the commit listed in the index of the + containing repository matches the commit checked out in the submodule. --cached:: This option is only valid for status and summary commands. These diff --git a/Documentation/git.txt b/Documentation/git.txt index 27da0eb209..34d8a1bbdf 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -22,18 +22,17 @@ unusually rich command set that provides both high-level operations and full access to internals. See linkgit:gittutorial[7] to get started, then see -link:everyday.html[Everyday Git] for a useful minimum set of commands, and -"man git-commandname" for documentation of each command. CVS users may -also want to read linkgit:gitcvs-migration[7]. See -the link:user-manual.html[Git User's Manual] for a more in-depth -introduction. +link:everyday.html[Everyday Git] for a useful minimum set of +commands. The link:user-manual.html[Git User's Manual] has a more +in-depth introduction. -The '' is either a name of a Git command (see below) or an alias -as defined in the configuration file (see linkgit:git-config[1]). +After you mastered the basic concepts, you can come back to this +page to learn what commands git offers. You can learn more about +individual git commands with "git help command". linkgit:gitcli[7] +manual page gives you an overview of the command line command syntax. -Formatted and hyperlinked version of the latest git -documentation can be viewed at -`http://git-htmldocs.googlecode.com/git/git.html`. +Formatted and hyperlinked version of the latest git documentation +can be viewed at `http://git-htmldocs.googlecode.com/git/git.html`. ifdef::stalenotes[] [NOTE] @@ -49,9 +48,11 @@ Documentation for older releases are available here: * release notes for link:RelNotes/1.7.12.txt[1.7.12]. -* link:v1.7.11.5/git.html[documentation for release 1.7.11.5] +* link:v1.7.11.7/git.html[documentation for release 1.7.11.7] * release notes for + link:RelNotes/1.7.11.7.txt[1.7.11.7], + link:RelNotes/1.7.11.6.txt[1.7.11.6], link:RelNotes/1.7.11.5.txt[1.7.11.5], link:RelNotes/1.7.11.4.txt[1.7.11.4], link:RelNotes/1.7.11.3.txt[1.7.11.3], @@ -411,24 +412,6 @@ help ...`. linkgit:git-replace[1] for more information. -FURTHER DOCUMENTATION ---------------------- - -See the references above to get started using git. The following is -probably more detail than necessary for a first-time user. - -The link:user-manual.html#git-concepts[git concepts chapter of the -user-manual] and linkgit:gitcore-tutorial[7] both provide -introductions to the underlying git architecture. - -See linkgit:gitworkflows[7] for an overview of recommended workflows. - -See also the link:howto-index.html[howto] documents for some useful -examples. - -The internals are documented in the -link:technical/api-index.html[GIT API documentation]. - GIT COMMANDS ------------ @@ -848,6 +831,29 @@ The index is also capable of storing multiple entries (called "stages") for a given pathname. These stages are used to hold the various unmerged version of a file when a merge is in progress. +FURTHER DOCUMENTATION +--------------------- + +See the references in the "description" section to get started +using git. The following is probably more detail than necessary +for a first-time user. + +The link:user-manual.html#git-concepts[git concepts chapter of the +user-manual] and linkgit:gitcore-tutorial[7] both provide +introductions to the underlying git architecture. + +See linkgit:gitworkflows[7] for an overview of recommended workflows. + +See also the link:howto-index.html[howto] documents for some useful +examples. + +The internals are documented in the +link:technical/api-index.html[GIT API documentation]. + +Users migrating from CVS may also want to +read linkgit:gitcvs-migration[7]. + + Authors ------- Git was started by Linus Torvalds, and is currently maintained by Junio diff --git a/Documentation/gitcli.txt b/Documentation/gitcli.txt index 3e72a5d68e..f6ba90c2da 100644 --- a/Documentation/gitcli.txt +++ b/Documentation/gitcli.txt @@ -37,11 +37,28 @@ arguments. Here are the rules: file called HEAD in your work tree, `git diff HEAD` is ambiguous, and you have to say either `git diff HEAD --` or `git diff -- HEAD` to disambiguate. - ++ When writing a script that is expected to handle random user-input, it is a good practice to make it explicit which arguments are which by placing disambiguating `--` at appropriate places. + * Many commands allow wildcards in paths, but you need to protect + them from getting globbed by the shell. These two mean different + things: ++ +-------------------------------- +$ git checkout -- *.c +$ git checkout -- \*.c +-------------------------------- ++ +The former lets your shell expand the fileglob, and you are asking +the dot-C files in your working tree to be overwritten with the version +in the index. The latter passes the `*.c` to Git, and you are asking +the paths in the index that match the pattern to be checked out to your +working tree. After running `git add hello.c; rm hello.c`, you will _not_ +see `hello.c` in your working tree with the former, but with the latter +you will. + Here are the rules regarding the "flags" that you should follow when you are scripting git: diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index def1340ac7..918c1109f2 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -8,7 +8,8 @@ ordering and formatting options, such as '--reverse'. -- --n 'number':: +-:: +-n :: --max-count=:: Limit the number of commits to output. @@ -636,10 +637,14 @@ These options are mostly targeted for packing of git repositories. Only useful with '--objects'; print the object IDs that are not in packs. ---no-walk:: +--no-walk[=(sorted|unsorted)]:: - Only show the given revs, but do not traverse their ancestors. - This has no effect if a range is specified. + Only show the given commits, but do not traverse their ancestors. + This has no effect if a range is specified. If the argument + "unsorted" is given, the commits are show in the order they were + given on the command line. Otherwise (if "sorted" or no argument + was given), the commits are show in reverse chronological order + by commit time. --do-walk:: diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt index dc0070bcb7..991fcd8f3f 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. '@\{\}', e.g. 'master@\{yesterday\}', 'HEAD@\{5 minutes ago\}':: A ref followed by the suffix '@' with a date specification @@ -213,6 +215,13 @@ of 'r1' and 'r2' and is defined as It is the set of commits that are reachable from either one of 'r1' or 'r2' but not from both. +In these two shorthands, you can omit one end and let it default to HEAD. +For example, 'origin..' is a shorthand for 'origin..HEAD' and asks "What +did I do since I forked from the origin branch?" Similarly, '..origin' +is a shorthand for 'HEAD..origin' and asks "What did the origin do since +I forked from them?" Note that '..' would mean 'HEAD..HEAD' which is an +empty range that is both reachable and unreachable from HEAD. + Two other shorthands for naming a set that is formed by a commit and its parent commits exist. The 'r1{caret}@' notation means all parents of 'r1'. 'r1{caret}!' includes commit 'r1' but excludes diff --git a/Documentation/technical/api-argv-array.txt b/Documentation/technical/api-argv-array.txt index 1b7d8f140c..1a797812fb 100644 --- a/Documentation/technical/api-argv-array.txt +++ b/Documentation/technical/api-argv-array.txt @@ -46,6 +46,10 @@ Functions Format a string and push it onto the end of the array. This is a convenience wrapper combining `strbuf_addf` and `argv_array_push`. +`argv_array_pop`:: + Remove the final element from the array. If there are no + elements in the array, do nothing. + `argv_array_clear`:: Free all memory associated with the array and return it to the initial, empty state. diff --git a/Documentation/user-manual.conf b/Documentation/user-manual.conf index 339b30919e..d87294de2f 100644 --- a/Documentation/user-manual.conf +++ b/Documentation/user-manual.conf @@ -14,7 +14,7 @@ ifdef::backend-docbook[] # "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this. [listingblock] {title} - + | {title#} diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index b27a2ff687..d2d2d699e1 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.7.12 +DEF_VER=v1.7.12.GIT LF=' ' diff --git a/Makefile b/Makefile index 6b0c961d3a..56301dc0a8 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. @@ -157,6 +159,11 @@ all:: # 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) # @@ -496,6 +503,7 @@ TEST_PROGRAMS_NEED_X += test-mergesort TEST_PROGRAMS_NEED_X += test-mktemp TEST_PROGRAMS_NEED_X += test-parse-options TEST_PROGRAMS_NEED_X += test-path-utils +TEST_PROGRAMS_NEED_X += test-regex TEST_PROGRAMS_NEED_X += test-revision-walking TEST_PROGRAMS_NEED_X += test-run-command TEST_PROGRAMS_NEED_X += test-scrap-cache-tree @@ -1639,6 +1647,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 @@ -1670,6 +1682,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 @@ -2805,8 +2824,13 @@ endif ### Check documentation # +ALL_COMMANDS = $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) +ALL_COMMANDS += git +ALL_COMMANDS += gitk +ALL_COMMANDS += gitweb +ALL_COMMANDS += git-gui git-citool check-docs:: - @(for v in $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git gitk; \ + @(for v in $(ALL_COMMANDS); \ do \ case "$$v" in \ git-merge-octopus | git-merge-ours | git-merge-recursive | \ @@ -2828,35 +2852,13 @@ check-docs:: sed -e '/^#/d' \ -e 's/[ ].*//' \ -e 's/^/listed /' command-list.txt; \ - ls -1 Documentation/git*txt | \ + $(MAKE) -C Documentation print-man1 | \ + grep '\.txt$$' | \ sed -e 's|Documentation/|documented |' \ -e 's/\.txt//'; \ ) | while read how cmd; \ do \ - case "$$how,$$cmd" in \ - *,git-citool | \ - *,git-gui | \ - *,git-help | \ - documented,gitattributes | \ - documented,gitignore | \ - documented,gitmodules | \ - documented,gitcli | \ - documented,git-tools | \ - documented,gitcore-tutorial | \ - documented,gitcvs-migration | \ - documented,gitdiffcore | \ - documented,gitglossary | \ - documented,githooks | \ - documented,gitrepository-layout | \ - documented,gitrevisions | \ - documented,gittutorial | \ - documented,gittutorial-2 | \ - documented,git-bisect-lk2009 | \ - documented,git-remote-helpers | \ - documented,gitworkflows | \ - sentinel,not,matching,is,ok ) continue ;; \ - esac; \ - case " $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git gitk " in \ + case " $(ALL_COMMANDS) " in \ *" $$cmd "*) ;; \ *) echo "removed but $$how: $$cmd" ;; \ esac; \ diff --git a/RelNotes b/RelNotes index 19bb2ebbe6..2484b38bbb 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/1.7.12.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 f04ac18e33..05f2d79348 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.c b/archive.c index a4844330fb..466640479e 100644 --- a/archive.c +++ b/archive.c @@ -7,10 +7,10 @@ #include "unpack-trees.h" static char const * const archive_usage[] = { - "git archive [options] [...]", - "git archive --list", - "git archive --remote [--exec ] [options] [...]", - "git archive --remote [--exec ] --list", + N_("git archive [options] [...]"), + N_("git archive --list"), + N_("git archive --remote [--exec ] [options] [...]"), + N_("git archive --remote [--exec ] --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 "), - 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 ")), + OPT_STRING(0, "exec", &exec, N_("command"), + N_("path to the remote git-upload-archive command")), OPT_END() }; diff --git a/argv-array.c b/argv-array.c index 0b5f8898a1..256741d226 100644 --- a/argv-array.c +++ b/argv-array.c @@ -49,12 +49,21 @@ void argv_array_pushl(struct argv_array *array, ...) va_end(ap); } +void argv_array_pop(struct argv_array *array) +{ + if (!array->argc) + return; + free((char *)array->argv[array->argc - 1]); + array->argv[array->argc - 1] = NULL; + array->argc--; +} + void argv_array_clear(struct argv_array *array) { if (array->argv != empty_argv) { int i; for (i = 0; i < array->argc; i++) - free((char **)array->argv[i]); + free((char *)array->argv[i]); free(array->argv); } argv_array_init(array); diff --git a/argv-array.h b/argv-array.h index b93a69c36c..f4b98660f8 100644 --- a/argv-array.h +++ b/argv-array.h @@ -16,6 +16,7 @@ void argv_array_push(struct argv_array *, const char *); __attribute__((format (printf,2,3))) void argv_array_pushf(struct argv_array *, const char *fmt, ...); void argv_array_pushl(struct argv_array *, ...); +void argv_array_pop(struct argv_array *); void argv_array_clear(struct argv_array *); #endif /* ARGV_ARRAY_H */ diff --git a/attr.c b/attr.c index b52efb55a0..f12c83f80a 100644 --- a/attr.c +++ b/attr.c @@ -352,8 +352,11 @@ static struct attr_stack *read_attr_from_file(const char *path, int macro_ok) char buf[2048]; int lineno = 0; - if (!fp) + if (!fp) { + if (errno != ENOENT) + warn_on_inaccessible(path); return NULL; + } res = xcalloc(1, sizeof(*res)); while (fgets(buf, sizeof(buf), fp)) handle_attr_line(res, buf, path, ++lineno, macro_ok); diff --git a/bisect.c b/bisect.c index 48acf73391..1aad49b1a6 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 ba6626b035..8e377522fe 100644 --- a/builtin.h +++ b/builtin.h @@ -43,7 +43,7 @@ extern int check_pager_config(const char *cmd); struct diff_options; extern void setup_diff_pager(struct diff_options *); -extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, char **buf, unsigned long *buf_size); +extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, int sha1_valid, char **buf, unsigned long *buf_size); extern int cmd_add(int argc, const char **argv, const char *prefix); extern int cmd_annotate(int argc, const char **argv, const char *prefix); diff --git a/builtin/add.c b/builtin/add.c index 89dce56a24..e664100c71 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] [--] ...", + N_("git add [options] [--] ..."), 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 d453c83378..156b3ce3b7 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -188,7 +188,6 @@ struct patch { int is_new, is_delete; /* -1 = unknown, 0 = false, 1 = true */ int rejected; unsigned ws_rule; - unsigned long deflate_origlen; int lines_added, lines_deleted; int score; unsigned int is_toplevel_relative:1; @@ -1096,15 +1095,23 @@ static int gitdiff_unrecognized(const char *line, struct patch *patch) return -1; } -static const char *stop_at_slash(const char *line, int llen) +/* + * Skip p_value leading components from "line"; as we do not accept + * absolute paths, return NULL in that case. + */ +static const char *skip_tree_prefix(const char *line, int llen) { - int nslash = p_value; + int nslash; int i; + if (!p_value) + return (llen && line[0] == '/') ? NULL : line; + + nslash = p_value; for (i = 0; i < llen; i++) { int ch = line[i]; if (ch == '/' && --nslash <= 0) - return &line[i]; + return (i == 0) ? NULL : &line[i + 1]; } return NULL; } @@ -1134,12 +1141,11 @@ static char *git_header_name(const char *line, int llen) if (unquote_c_style(&first, line, &second)) goto free_and_fail1; - /* advance to the first slash */ - cp = stop_at_slash(first.buf, first.len); - /* we do not accept absolute paths */ - if (!cp || cp == first.buf) + /* strip the a/b prefix including trailing slash */ + cp = skip_tree_prefix(first.buf, first.len); + if (!cp) goto free_and_fail1; - strbuf_remove(&first, 0, cp + 1 - first.buf); + strbuf_remove(&first, 0, cp - first.buf); /* * second points at one past closing dq of name. @@ -1153,22 +1159,21 @@ static char *git_header_name(const char *line, int llen) if (*second == '"') { if (unquote_c_style(&sp, second, NULL)) goto free_and_fail1; - cp = stop_at_slash(sp.buf, sp.len); - if (!cp || cp == sp.buf) + cp = skip_tree_prefix(sp.buf, sp.len); + if (!cp) goto free_and_fail1; /* They must match, otherwise ignore */ - if (strcmp(cp + 1, first.buf)) + if (strcmp(cp, first.buf)) goto free_and_fail1; strbuf_release(&sp); return strbuf_detach(&first, NULL); } /* unquoted second */ - cp = stop_at_slash(second, line + llen - second); - if (!cp || cp == second) + cp = skip_tree_prefix(second, line + llen - second); + if (!cp) goto free_and_fail1; - cp++; - if (line + llen - cp != first.len + 1 || + if (line + llen - cp != first.len || memcmp(first.buf, cp, first.len)) goto free_and_fail1; return strbuf_detach(&first, NULL); @@ -1180,10 +1185,9 @@ static char *git_header_name(const char *line, int llen) } /* unquoted first name */ - name = stop_at_slash(line, llen); - if (!name || name == line) + name = skip_tree_prefix(line, llen); + if (!name) return NULL; - name++; /* * since the first name is unquoted, a dq if exists must be @@ -1197,10 +1201,9 @@ static char *git_header_name(const char *line, int llen) if (unquote_c_style(&sp, second, NULL)) goto free_and_fail2; - np = stop_at_slash(sp.buf, sp.len); - if (!np || np == sp.buf) + np = skip_tree_prefix(sp.buf, sp.len); + if (!np) goto free_and_fail2; - np++; len = sp.buf + sp.len - np; if (len < second - name && @@ -1232,13 +1235,27 @@ static char *git_header_name(const char *line, int llen) case '\n': return NULL; case '\t': case ' ': - second = stop_at_slash(name + len, line_len - len); + /* + * Is this the separator between the preimage + * and the postimage pathname? Again, we are + * only interested in the case where there is + * no rename, as this is only to set def_name + * and a rename patch has the names elsewhere + * in an unambiguous form. + */ + if (!name[len + 1]) + return NULL; /* no postimage name */ + second = skip_tree_prefix(name + len + 1, + line_len - (len + 1)); if (!second) return NULL; - second++; - if (second[len] == '\n' && !strncmp(name, second, len)) { + /* + * Does len bytes starting at "name" and "second" + * (that are separated by one HT or SP we just + * found) exactly match? + */ + if (second[len] == '\n' && !strncmp(name, second, len)) return xmemdupz(name, len); - } } } } @@ -4297,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 931956def9..9a1cfd3dac 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 "), - 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 ")), + 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 8d325a5179..e3884e3bb6 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 0d50273ce9..0e102bf2c2 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 }; @@ -110,6 +110,7 @@ static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b, long ctxlen, int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, + int sha1_valid, char **buf, unsigned long *buf_size) { @@ -117,7 +118,7 @@ int textconv_object(const char *path, struct userdiff_driver *textconv; df = alloc_filespec(path); - fill_filespec(df, sha1, mode); + fill_filespec(df, sha1, sha1_valid, mode); textconv = get_textconv(df); if (!textconv) { free_filespec(df); @@ -142,7 +143,7 @@ static void fill_origin_blob(struct diff_options *opt, num_read_blob++; if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) && - textconv_object(o->path, o->mode, o->blob_sha1, &file->ptr, &file_size)) + textconv_object(o->path, o->mode, o->blob_sha1, 1, &file->ptr, &file_size)) ; else file->ptr = read_sha1_file(o->blob_sha1, &type, &file_size); @@ -406,8 +407,7 @@ static struct origin *find_origin(struct scoreboard *sb, paths[1] = NULL; diff_tree_setup_paths(paths, &diff_opts); - if (diff_setup_done(&diff_opts) < 0) - die("diff-setup"); + diff_setup_done(&diff_opts); if (is_null_sha1(origin->commit->object.sha1)) do_diff_cache(parent->tree->object.sha1, &diff_opts); @@ -493,8 +493,7 @@ static struct origin *find_rename(struct scoreboard *sb, diff_opts.single_follow = origin->path; paths[0] = NULL; diff_tree_setup_paths(paths, &diff_opts); - if (diff_setup_done(&diff_opts) < 0) - die("diff-setup"); + diff_setup_done(&diff_opts); if (is_null_sha1(origin->commit->object.sha1)) do_diff_cache(parent->tree->object.sha1, &diff_opts); @@ -1074,8 +1073,7 @@ static int find_copy_in_parent(struct scoreboard *sb, paths[0] = NULL; diff_tree_setup_paths(paths, &diff_opts); - if (diff_setup_done(&diff_opts) < 0) - die("diff-setup"); + diff_setup_done(&diff_opts); /* Try "find copies harder" on new path if requested; * we do not want to use diffcore_rename() actually to @@ -2123,7 +2121,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt, switch (st.st_mode & S_IFMT) { case S_IFREG: if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) && - textconv_object(read_from, mode, null_sha1, &buf_ptr, &buf_len)) + textconv_object(read_from, mode, null_sha1, 0, &buf_ptr, &buf_len)) strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1); else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size) die_errno("cannot open or read '%s'", read_from); @@ -2315,27 +2313,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 instead of calling git-rev-list"), - OPT_STRING(0, "contents", &contents_from, "file", "Use '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 instead of calling git-rev-list")), + OPT_STRING(0, "contents", &contents_from, N_("file"), N_("Use '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() }; @@ -2516,7 +2514,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) die("no such path %s in %s", path, final_commit_name); if (DIFF_OPT_TST(&sb.revs->diffopt, ALLOW_TEXTCONV) && - textconv_object(path, o->mode, o->blob_sha1, (char **) &sb.final_buf, + textconv_object(path, o->mode, o->blob_sha1, 1, (char **) &sb.final_buf, &sb.final_buf_size)) ; else diff --git a/builtin/branch.c b/builtin/branch.c index 0e060f2e4a..ffd26849c7 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] []", - "git branch [options] [-r] (-d | -D) ...", - "git branch [options] (-m | -M) [] ", + N_("git branch [options] [-r | -a] [--merged | --no-merged]"), + N_("git branch [options] [-l] [-f] []"), + N_("git branch [options] [-r] (-d | -D) ..."), + N_("git branch [options] (-m | -M) [] "), 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 af74e775a1..00528ddc38 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -146,7 +146,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name) die("git cat-file --textconv %s: must be ", obj_name); - if (!textconv_object(obj_context.path, obj_context.mode, sha1, &buf, &size)) + if (!textconv_object(obj_context.path, obj_context.mode, sha1, 1, &buf, &size)) die("git cat-file --textconv: unable to run textconv on %s", obj_name); break; @@ -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||--textconv) ", - "git cat-file (--batch|--batch-check) < ", + N_("git cat-file (-t|-s|-e|-p||--textconv) "), + N_("git cat-file (--batch|--batch-check) < "), 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(" 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_(" 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 44c421eb0f..e1ff575daa 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 [-a | --all | attr...] < ", +N_("git check-attr [-a | --all | attr...] [--] pathname..."), +N_("git check-attr --stdin [-a | --all | attr...] < "), 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 c16d82b7de..b1feda7d5e 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] [--] [...]", + N_("git checkout-index [options] [--] [...]"), 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", ¬_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 ", + N_("write the content to temporary files")), + OPT_CALLBACK(0, "prefix", NULL, N_("string"), + N_("when creating files, prepend "), 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 d812219b30..781295b2c9 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] ", - "git checkout [options] [] -- ...", + N_("git checkout [options] "), + N_("git checkout [options] [] -- ..."), 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,15 +339,15 @@ 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. */ init_revisions(&rev, NULL); rev.diffopt.flags = opts->flags; rev.diffopt.output_format |= DIFF_FORMAT_NAME_STATUS; - if (diff_setup_done(&rev.diffopt) < 0) - die(_("diff_setup_done failed")); + diff_setup_done(&rev.diffopt); add_pending_object(&rev, head, NULL); run_diff_index(&rev, 0); } @@ -332,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; @@ -351,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 @@ -382,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)); @@ -394,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 { @@ -480,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; @@ -488,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; } @@ -515,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) { @@ -702,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); @@ -726,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; @@ -739,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) @@ -756,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; @@ -911,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; @@ -924,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(), }; @@ -963,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); @@ -972,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")); @@ -1005,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. @@ -1035,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 0c7b3d0f4c..69c1cda906 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 ] [-x | -X] [--] ...", + N_("git clean [-d] [-f] [-n] [-q] [-e ] [-x | -X] [--] ..."), 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 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 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 e314b0b6d2..5a9b2bce24 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -33,7 +33,7 @@ * */ static const char * const builtin_clone_usage[] = { - "git clone [options] [--] []", + N_("git clone [options] [--] []"), 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 instead of 'origin' to track upstream"), - OPT_STRING('b', "branch", &option_branch, "branch", - "checkout 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 instead of 'origin' to track upstream")), + OPT_STRING('b', "branch", &option_branch, N_("branch"), + N_("checkout 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))) @@ -700,7 +700,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 5ea798a7ca..e125a55fc9 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 20cef95d60..778cf16fde 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -30,12 +30,12 @@ #include "column.h" static const char * const builtin_commit_usage[] = { - "git commit [options] [--] ...", + N_("git commit [options] [--] ..."), NULL }; static const char * const builtin_status_usage[] = { - "git status [options] [--] ...", + N_("git status [options] [--] ..."), NULL }; @@ -478,6 +478,20 @@ static void export_one(const char *var, const char *s, const char *e, int hack) strbuf_release(&buf); } +static int sane_ident_split(struct ident_split *person) +{ + if (!person->name_begin || !person->name_end || + person->name_begin == person->name_end) + return 0; /* no human readable name */ + if (!person->mail_begin || !person->mail_end || + person->mail_begin == person->mail_end) + return 0; /* no usable mail */ + if (!person->date_begin || !person->date_end || + !person->tz_begin || !person->tz_end) + return 0; + return 1; +} + static void determine_author_info(struct strbuf *author_ident) { char *name, *email, *date; @@ -530,7 +544,8 @@ static void determine_author_info(struct strbuf *author_ident) if (force_date) date = force_date; strbuf_addstr(author_ident, fmt_ident(name, email, date, IDENT_STRICT)); - if (!split_ident_line(&author, author_ident->buf, author_ident->len)) { + if (!split_ident_line(&author, author_ident->buf, author_ident->len) && + sane_ident_split(&author)) { export_one("GIT_AUTHOR_NAME", author.name_begin, author.name_end, 0); export_one("GIT_AUTHOR_EMAIL", author.mail_begin, author.mail_end, 0); export_one("GIT_AUTHOR_DATE", author.date_begin, author.tz_end, '@'); @@ -1169,26 +1184,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(), }; @@ -1369,53 +1384,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 8cd08da991..e1c33e0691 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(), }; @@ -160,7 +160,7 @@ static int show_config(const char *key_, const char *value_, void *cb) static int get_value(const char *key_, const char *regex_) { - int ret = -1; + int ret = CONFIG_GENERIC_ERROR; char *global = NULL, *xdg = NULL, *repo_config = NULL; const char *system_wide = NULL, *local; struct config_include_data inc = CONFIG_INCLUDE_INIT; @@ -196,11 +196,14 @@ static int get_value(const char *key_, const char *regex_) if (regcomp(key_regexp, key, REG_EXTENDED)) { fprintf(stderr, "Invalid key pattern: %s\n", key_); free(key); + ret = CONFIG_INVALID_PATTERN; goto free_strings; } } else { - if (git_config_parse_key(key_, &key, NULL)) + if (git_config_parse_key(key_, &key, NULL)) { + ret = CONFIG_INVALID_KEY; goto free_strings; + } } if (regex_) { @@ -212,6 +215,7 @@ static int get_value(const char *key_, const char *regex_) regexp = (regex_t*)xmalloc(sizeof(regex_t)); if (regcomp(regexp, regex_, REG_EXTENDED)) { fprintf(stderr, "Invalid pattern: %s\n", regex_); + ret = CONFIG_INVALID_PATTERN; goto free_strings; } } @@ -396,8 +400,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) */ die("$HOME not set"); - if (access(user_config, R_OK) && - xdg_config && !access(xdg_config, R_OK)) + if (access_or_warn(user_config, R_OK) && + xdg_config && !access_or_warn(xdg_config, R_OK)) given_config_file = xdg_config; else given_config_file = user_config; diff --git a/builtin/count-objects.c b/builtin/count-objects.c index c37cb98c31..9afaa88f77 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 9f63067f50..9fe11ed9de 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] *", - "git describe [options] --dirty", + N_("git describe [options] *"), + 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 most recent tags (default: 10)"), - OPT_STRING(0, "match", &pattern, "pattern", - "only consider tags matching "), + N_("consider most recent tags (default: 10)")), + OPT_STRING(0, "match", &pattern, N_("pattern"), + N_("only consider tags matching ")), OPT_BOOLEAN(0, "always", &always, - "show abbreviated commit object as fallback"), - {OPTION_STRING, 0, "dirty", &dirty, "mark", - "append on dirty working tree (default: \"-dirty\")", + N_("show abbreviated commit object as fallback")), + {OPTION_STRING, 0, "dirty", &dirty, N_("mark"), + N_("append on dirty working tree (default: \"-dirty\")"), PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"}, OPT_END(), }; diff --git a/builtin/diff.c b/builtin/diff.c index da8f6aac2b..9650be2c50 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -29,6 +29,8 @@ static void stuff_change(struct diff_options *opt, unsigned old_mode, unsigned new_mode, const unsigned char *old_sha1, const unsigned char *new_sha1, + int old_sha1_valid, + int new_sha1_valid, const char *old_name, const char *new_name) { @@ -54,8 +56,8 @@ static void stuff_change(struct diff_options *opt, one = alloc_filespec(old_name); two = alloc_filespec(new_name); - fill_filespec(one, old_sha1, old_mode); - fill_filespec(two, new_sha1, new_mode); + fill_filespec(one, old_sha1, old_sha1_valid, old_mode); + fill_filespec(two, new_sha1, new_sha1_valid, new_mode); diff_queue(&diff_queued_diff, one, two); } @@ -84,6 +86,7 @@ static int builtin_diff_b_f(struct rev_info *revs, stuff_change(&revs->diffopt, blob[0].mode, canon_mode(st.st_mode), blob[0].sha1, null_sha1, + 1, 0, path, path); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); @@ -108,6 +111,7 @@ static int builtin_diff_blobs(struct rev_info *revs, stuff_change(&revs->diffopt, blob[0].mode, blob[1].mode, blob[0].sha1, blob[1].sha1, + 1, 1, blob[0].name, blob[1].name); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); @@ -298,8 +302,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) argc = setup_revisions(argc, argv, &rev, NULL); if (!rev.diffopt.output_format) { rev.diffopt.output_format = DIFF_FORMAT_PATCH; - if (diff_setup_done(&rev.diffopt) < 0) - die(_("diff_setup_done failed")); + diff_setup_done(&rev.diffopt); } DIFF_OPT_SET(&rev.diffopt, RECURSIVE); diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 9ab6db3fb0..12220ad8da 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 objects"), - OPT_CALLBACK(0, "signed-tags", &signed_tag_mode, "mode", - "select handling of signed tags", + N_("show progress after 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 149db88726..fdda36f149 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -10,6 +10,7 @@ #include "remote.h" #include "run-command.h" #include "transport.h" +#include "version.h" static int transfer_unpack_limit = -1; static int fetch_unpack_limit = -1; @@ -18,6 +19,7 @@ static int prefer_ofs_delta = 1; static int no_done; static int fetch_fsck_objects = -1; static int transfer_fsck_objects = -1; +static int agent_supported; static struct fetch_pack_args args = { /* .uploadpack = */ "git-upload-pack", }; @@ -327,6 +329,8 @@ static int find_common(int fd[2], unsigned char *result_sha1, if (args.no_progress) strbuf_addstr(&c, " no-progress"); if (args.include_tag) strbuf_addstr(&c, " include-tag"); if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta"); + if (agent_supported) strbuf_addf(&c, " agent=%s", + git_user_agent_sanitized()); packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf); strbuf_release(&c); } else @@ -783,6 +787,8 @@ static struct ref *do_fetch_pack(int fd[2], { struct ref *ref = copy_ref_list(orig_ref); unsigned char sha1[20]; + const char *agent_feature; + int agent_len; sort_ref_list(&ref, ref_compare_name); @@ -814,11 +820,25 @@ static struct ref *do_fetch_pack(int fd[2], fprintf(stderr, "Server supports side-band\n"); use_sideband = 1; } + if (!server_supports("thin-pack")) + args.use_thin_pack = 0; + if (!server_supports("no-progress")) + args.no_progress = 0; + if (!server_supports("include-tag")) + args.include_tag = 0; if (server_supports("ofs-delta")) { if (args.verbose) fprintf(stderr, "Server supports ofs-delta\n"); } else prefer_ofs_delta = 0; + + if ((agent_feature = server_feature_value("agent", &agent_len))) { + agent_supported = 1; + if (args.verbose && agent_len) + fprintf(stderr, "Server version is %.*s\n", + agent_len, agent_feature); + } + if (everything_local(&ref, nr_match, match)) { packet_flush(fd[1]); goto all_done; diff --git a/builtin/fetch.c b/builtin/fetch.c index bb9a0743ff..d0dcc8888f 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -14,12 +14,13 @@ #include "transport.h" #include "submodule.h" #include "connected.h" +#include "argv-array.h" static const char * const builtin_fetch_usage[] = { - "git fetch [] [ [...]]", - "git fetch [] ", - "git fetch --multiple [] [( | )...]", - "git fetch --all []", + N_("git fetch [] [ [...]]"), + N_("git fetch [] "), + N_("git fetch --multiple [] [( | )...]"), + N_("git fetch --all []"), NULL }; @@ -56,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() }; @@ -323,7 +324,7 @@ static int update_local_ref(struct ref *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)); @@ -841,38 +842,39 @@ static int add_remote_or_group(const char *name, struct string_list *list) return 1; } -static void add_options_to_argv(int *argc, const char **argv) +static void add_options_to_argv(struct argv_array *argv) { if (dry_run) - argv[(*argc)++] = "--dry-run"; + argv_array_push(argv, "--dry-run"); if (prune) - argv[(*argc)++] = "--prune"; + argv_array_push(argv, "--prune"); if (update_head_ok) - argv[(*argc)++] = "--update-head-ok"; + argv_array_push(argv, "--update-head-ok"); if (force) - argv[(*argc)++] = "--force"; + argv_array_push(argv, "--force"); if (keep) - argv[(*argc)++] = "--keep"; + argv_array_push(argv, "--keep"); if (recurse_submodules == RECURSE_SUBMODULES_ON) - argv[(*argc)++] = "--recurse-submodules"; + argv_array_push(argv, "--recurse-submodules"); else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) - argv[(*argc)++] = "--recurse-submodules=on-demand"; + argv_array_push(argv, "--recurse-submodules=on-demand"); + if (tags == TAGS_SET) + argv_array_push(argv, "--tags"); + else if (tags == TAGS_UNSET) + argv_array_push(argv, "--no-tags"); if (verbosity >= 2) - argv[(*argc)++] = "-v"; + argv_array_push(argv, "-v"); if (verbosity >= 1) - argv[(*argc)++] = "-v"; + argv_array_push(argv, "-v"); else if (verbosity < 0) - argv[(*argc)++] = "-q"; + argv_array_push(argv, "-q"); } static int fetch_multiple(struct string_list *list) { int i, result = 0; - const char *argv[12] = { "fetch", "--append" }; - int argc = 2; - - add_options_to_argv(&argc, argv); + struct argv_array argv = ARGV_ARRAY_INIT; if (!append && !dry_run) { int errcode = truncate_fetch_head(); @@ -880,18 +882,22 @@ static int fetch_multiple(struct string_list *list) return errcode; } + argv_array_pushl(&argv, "fetch", "--append", NULL); + add_options_to_argv(&argv); + for (i = 0; i < list->nr; i++) { const char *name = list->items[i].string; - argv[argc] = name; - argv[argc + 1] = NULL; + argv_array_push(&argv, name); if (verbosity >= 0) printf(_("Fetching %s\n"), name); - if (run_command_v_opt(argv, RUN_GIT_CMD)) { + if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) { error(_("Could not fetch %s"), name); result = 1; } + argv_array_pop(&argv); } + argv_array_clear(&argv); return result; } @@ -1007,13 +1013,14 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) } if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) { - const char *options[10]; - int num_options = 0; - add_options_to_argv(&num_options, options); - result = fetch_populated_submodules(num_options, options, + struct argv_array options = ARGV_ARRAY_INIT; + + add_options_to_argv(&options); + result = fetch_populated_submodules(&options, submodule_prefix, recurse_submodules, verbosity < 0); + argv_array_clear(&options); } /* All names were strdup()ed or strndup()ed */ diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index 2c4d435da1..e2e27b2c40 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 ] [--log[=]|--no-log] [--file ]", + N_("git fmt-merge-msg [-m ] [--log[=]|--no-log] [--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 entries from shortlog", + { OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"), + N_("populate log with at most 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 as start of message"), - OPT_FILENAME('F', "file", &inpath, "file to read from"), + OPT_STRING('m', "message", &message, N_("text"), + N_("use 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 b01d76a243..7f059c31df 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -962,7 +962,9 @@ static int opt_parse_sort(const struct option *opt, const char *arg, int unset) if (!arg) /* should --no-sort void the list ? */ return -1; - *sort_tail = s = xcalloc(1, sizeof(*s)); + s = xcalloc(1, sizeof(*s)); + s->next = *sort_tail; + *sort_tail = s; if (*arg == '-') { s->reverse = 1; @@ -974,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] []", + N_("git for-each-ref [options] []"), NULL }; @@ -989,19 +991,19 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) struct option opts[] = { OPT_BIT('s', "shell", "e_style, - "quote placeholders suitably for shells", QUOTE_SHELL), + N_("quote placeholders suitably for shells"), QUOTE_SHELL), OPT_BIT('p', "perl", "e_style, - "quote placeholders suitably for perl", QUOTE_PERL), + N_("quote placeholders suitably for perl"), QUOTE_PERL), OPT_BIT(0 , "python", "e_style, - "quote placeholders suitably for python", QUOTE_PYTHON), + N_("quote placeholders suitably for python"), QUOTE_PYTHON), OPT_BIT(0 , "tcl", "e_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 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 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 a710227a64..bb9a2cd447 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] [...]", + N_("git fsck [options] [...]"), 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 9b4232c8f3..6d46608fc9 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() }; diff --git a/builtin/grep.c b/builtin/grep.c index 29adb0ac93..09ca4c980e 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] [...] [[--] ...]", + N_("git grep [options] [-e] [...] [[--] ...]"), NULL }; @@ -260,6 +260,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; @@ -270,12 +317,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; @@ -669,95 +721,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 levels", PARSE_OPT_NONEG, + { OPTION_INTEGER, 0, "max-depth", &opt.max_depth, N_("depth"), + N_("descend at most 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 context lines before and after matches", + OPT_CALLBACK('C', "context", &opt, N_("n"), + N_("show context lines before and after matches"), context_callback), OPT_INTEGER('B', "before-context", &opt.pre_context, - "show context lines before matches"), + N_("show context lines before matches")), OPT_INTEGER('A', "after-context", &opt.post_context, - "show context lines after matches"), - OPT_NUMBER_CALLBACK(&opt, "shortcut for -C NUM", + N_("show 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 ", 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 "), 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, "", @@ -769,16 +814,16 @@ 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")), 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() }; @@ -799,6 +844,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, ""); @@ -824,28 +871,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 33911fd5e9..8d184f1a99 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 ] [-w] [--path=|--no-filters] [--stdin] [--] ...", - "git hash-object --stdin-paths < ", + N_("git hash-object [-t ] [-w] [--path=|--no-filters] [--stdin] [--] ..."), + N_("git hash-object --stdin-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 efea4f55e1..bd86253d83 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 953dd3004e..43d364b8d5 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 244fb7fc32..78aa3872dd 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=] [--shared[=]] [directory]", + N_("git init [-q | --quiet] [--bare] [--template=] [--shared[=]] [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 ecc2793690..09cf43e6d4 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 [] [..] [[--] ...]\n" - " or: git show [options] ...", + N_("git log [] [..] [[--] ...]\n") + N_(" or: git show [options] ..."), 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() }; @@ -109,9 +109,9 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN | PARSE_OPT_KEEP_DASHDASH); - argc = setup_revisions(argc, argv, rev, opt); if (quiet) rev->diffopt.output_format |= DIFF_FORMAT_NO_OUTPUT; + argc = setup_revisions(argc, argv, rev, opt); /* Any arguments at this point are not recognized */ if (argc > 1) @@ -456,7 +456,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) init_revisions(&rev, prefix); rev.diff = 1; rev.always_show_header = 1; - rev.no_walk = 1; + rev.no_walk = REVISION_WALK_NO_WALK_SORTED; rev.diffopt.stat_width = -1; /* Scale to real terminal size */ memset(&opt, 0, sizeof(opt)); @@ -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] [ | ]", + N_("git format-patch [options] [ | ]"), 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 instead of '.patch'"), + N_("use simple number sequence for output file names")), + OPT_STRING(0, "suffix", &fmt_patch_suffix, N_("sfx"), + N_("use instead of '.patch'")), OPT_INTEGER(0, "start-number", &start_number, - "start numbering patches at instead of 1"), - { OPTION_CALLBACK, 0, "subject-prefix", &rev, "prefix", - "Use [] instead of [PATCH]", + N_("start numbering patches at instead of 1")), + { OPTION_CALLBACK, 0, "subject-prefix", &rev, N_("prefix"), + N_("Use [] instead of [PATCH]"), PARSE_OPT_NONEG, subject_prefix_callback }, { OPTION_CALLBACK, 'o', "output-directory", &output_directory, - "dir", "store resulting files in ", + N_("dir"), N_("store resulting files in "), 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 "), - { 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 ")), + { 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] [ [ []]]", + N_("git cherry [-v] [ [ []]]"), 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 31b3f2d900..b5434af0c8 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] [...]", + N_("git ls-files [options] [...]"), 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 ", + { OPTION_CALLBACK, 'X', "exclude-from", &dir, N_("file"), + N_("exclude patterns are read from "), 0, option_parse_exclude_from }, - OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, "file", - "read additional per-directory exclude patterns in "), + OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, N_("file"), + N_("read additional per-directory exclude patterns in ")), { 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 is not in the index, treat this as an error"), - OPT_STRING(0, "with-tree", &with_tree, "tree-ish", - "pretend that paths removed since are still present"), + N_("if any 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 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-remote.c b/builtin/ls-remote.c index 41c88a98a2..25e83cfe9d 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -5,7 +5,7 @@ static const char ls_remote_usage[] = "git ls-remote [--heads] [--tags] [-u | --upload-pack ]\n" -" [-q|--quiet] [--exit-code] [ [...]]"; +" [-q|--quiet] [--exit-code] [--get-url] [ [...]]"; /* * Is there one among the list of patterns that match the tail part diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 6b666e1e87..235c17cc01 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 [] [...]", + N_("git ls-tree [] [...]"), 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 18895ee4d9..b691b77158 100644 --- a/builtin/mailinfo.c +++ b/builtin/mailinfo.c @@ -483,36 +483,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 4f30f1b0c8..1bc7991048 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] ...", - "git merge-base [-a|--all] --octopus ...", - "git merge-base --independent ...", + N_("git merge-base [-a|--all] ..."), + N_("git merge-base [-a|--all] --octopus ..."), + N_("git merge-base --independent ..."), + N_("git merge-base --is-ancestor "), 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 6f0efef43c..c0570f2407 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 dd50a0c57b..0ec8f0d449 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] [...]", - "git merge [options] HEAD ", - "git merge --abort", + N_("git merge [options] [...]"), + N_("git merge [options] HEAD "), + 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 ) 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 ) 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() }; @@ -404,8 +404,7 @@ static void finish(struct commit *head_commit, opts.output_format |= DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT; opts.detect_rename = DIFF_DETECT_RENAME; - if (diff_setup_done(&opts) < 0) - die(_("diff_setup_done failed")); + diff_setup_done(&opts); diff_tree_sha1(head, new_head, "", &opts); diffcore_std(&opts); diff_flush(&opts); diff --git a/builtin/mktree.c b/builtin/mktree.c index 4ae1c412d4..f92ba404ab 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 2a144b011c..034fec92a1 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] ... ", + N_("git mv [options] ... "), 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 1b374583c2..6238247974 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] ...", - "git name-rev [options] --all", - "git name-rev [options] --stdin", + N_("git name-rev [options] ..."), + 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 "), + 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 ")), 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 3644d140ec..554c80167c 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -20,71 +20,71 @@ #include "notes-merge.h" static const char * const git_notes_usage[] = { - "git notes [--ref ] [list []]", - "git notes [--ref ] add [-f] [-m | -F | (-c | -C) ] []", - "git notes [--ref ] copy [-f] ", - "git notes [--ref ] append [-m | -F | (-c | -C) ] []", - "git notes [--ref ] edit []", - "git notes [--ref ] show []", - "git notes [--ref ] merge [-v | -q] [-s ] ", - "git notes merge --commit [-v | -q]", - "git notes merge --abort [-v | -q]", - "git notes [--ref ] remove [...]", - "git notes [--ref ] prune [-n | -v]", - "git notes [--ref ] get-ref", + N_("git notes [--ref ] [list []]"), + N_("git notes [--ref ] add [-f] [-m | -F | (-c | -C) ] []"), + N_("git notes [--ref ] copy [-f] "), + N_("git notes [--ref ] append [-m | -F | (-c | -C) ] []"), + N_("git notes [--ref ] edit []"), + N_("git notes [--ref ] show []"), + N_("git notes [--ref ] merge [-v | -q] [-s ] "), + N_("git notes merge --commit [-v | -q]"), + N_("git notes merge --abort [-v | -q]"), + N_("git notes [--ref ] remove [...]"), + N_("git notes [--ref ] prune [-n | -v]"), + N_("git notes [--ref ] get-ref"), NULL }; static const char * const git_notes_list_usage[] = { - "git notes [list []]", + N_("git notes [list []]"), NULL }; static const char * const git_notes_add_usage[] = { - "git notes add [] []", + N_("git notes add [] []"), NULL }; static const char * const git_notes_copy_usage[] = { - "git notes copy [] ", - "git notes copy --stdin [ ]...", + N_("git notes copy [] "), + N_("git notes copy --stdin [ ]..."), NULL }; static const char * const git_notes_append_usage[] = { - "git notes append [] []", + N_("git notes append [] []"), NULL }; static const char * const git_notes_edit_usage[] = { - "git notes edit []", + N_("git notes edit []"), NULL }; static const char * const git_notes_show_usage[] = { - "git notes show []", + N_("git notes show []"), NULL }; static const char * const git_notes_merge_usage[] = { - "git notes merge [] ", - "git notes merge --commit []", - "git notes merge --abort []", + N_("git notes merge [] "), + N_("git notes merge --commit []"), + N_("git notes merge --abort []"), NULL }; static const char * const git_notes_remove_usage[] = { - "git notes remove []", + N_("git notes remove []"), NULL }; static const char * const git_notes_prune_usage[] = { - "git notes prune []", + N_("git notes prune []"), NULL }; static const char * const git_notes_get_ref_usage[] = { - "git notes get-ref", + N_("git notes get-ref"), NULL }; @@ -531,19 +531,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 +611,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 (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 (implies " + "--stdin)")), OPT_END() }; @@ -688,17 +688,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 +861,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 +980,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 +1064,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 "), + OPT_STRING(0, "ref", &override_notes_ref, N_("notes_ref"), + N_("use notes from ")), OPT_END() }; diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 782e7d0c38..5e14064094 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