From: Junio C Hamano Date: Mon, 9 Jul 2012 16:02:11 +0000 (-0700) Subject: Merge branch 'pw/git-p4-tests' X-Git-Tag: v1.7.12-rc0~51 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/faae8854bfb18da013e0a41d061dbbe73b3c9c73?hp=a0327c0edc7ada60ae2af5ec8daa5dcfcacd095d Merge branch 'pw/git-p4-tests' More "git p4" tests. * pw/git-p4-tests: git p4 test: fix badp4dir test git p4 test: split up big t9800 test git p4 test: cleanup_git should make a new $git git p4 test: copy source indeterminate git p4 test: check for error message in failed test git p4 test: rename some "git-p4 command" strings git p4 test: never create default test repo git p4 test: simplify quoting involving TRASH_DIRECTORY git p4 test: use real_path to resolve p4 client symlinks git p4 test: wait longer for p4d to start and test its pid --- diff --git a/.gitignore b/.gitignore index bf66648e2c..c188d0b461 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ /git-commit-tree /git-config /git-count-objects +/git-credential /git-credential-cache /git-credential-cache--daemon /git-credential-store @@ -172,7 +173,6 @@ /gitweb/static/gitweb.js /gitweb/static/gitweb.min.* /test-chmtime -/test-credential /test-ctype /test-date /test-delta diff --git a/Documentation/Makefile b/Documentation/Makefile index 5d76a84078..063fa696c9 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -65,12 +65,6 @@ endif -include ../config.mak.autogen -include ../config.mak -# -# For asciidoc ... -# -7.1.2, set ASCIIDOC7 -# 8.0-, no extra settings are needed -# - # # For docbook-xsl ... # -1.68.1, no extra settings are needed? @@ -81,9 +75,6 @@ endif # 1.73.0-, no extra settings are needed # -ifndef ASCIIDOC7 -ASCIIDOC_EXTRA += -a asciidoc7compatible -endif ifdef DOCBOOK_XSL_172 ASCIIDOC_EXTRA += -a git-asciidoc-no-roff MANPAGE_XSL = manpage-1.72.xsl @@ -134,15 +125,6 @@ DEFAULT_EDITOR_SQ = $(subst ','\'',$(DEFAULT_EDITOR)) ASCIIDOC_EXTRA += -a 'git-default-editor=$(DEFAULT_EDITOR_SQ)' endif -# -# Please note that there is a minor bug in asciidoc. -# The version after 6.0.3 _will_ include the patch found here: -# http://marc.theaimsgroup.com/?l=git&m=111558757202243&w=2 -# -# Until that version is released you may have to apply the patch -# yourself - yes, all 6 characters of it! -# - QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir QUIET_SUBDIR1 = diff --git a/Documentation/RelNotes/1.7.12.txt b/Documentation/RelNotes/1.7.12.txt new file mode 100644 index 0000000000..34f301d557 --- /dev/null +++ b/Documentation/RelNotes/1.7.12.txt @@ -0,0 +1,123 @@ +Git v1.7.12 Release Notes +========================= + +Updates since v1.7.11 +--------------------- + +UI, Workflows & Features + + * "git help" used to always default to "man" format even on platforms + where "man" viewer is not widely available. + + * "git clone --local $path" started its life as an experiment to + optionally use link/copy when cloning a repository on the disk, but + we didn't deprecate it after we made the option a no-op to always + use the optimization. The command learned "--no-local" option to + turn this off, as a more explicit alternative over use of file:// + URL. + + * "git fetch" and friends used to say "remote side hung up + unexpectedly" when they failed to get response they expect from the + other side, but one common reason why they don't get expected + response is that the remote repository does not exist or cannot be + read. The error message in this case was updated to give better + hints to the user. + + * git native protocol agents learned to show software version over + the wire, so that the server log can be examined to see the vintage + distribution of clients. + + * "git rebase -i" learned "-x " to insert "exec " after + each commit in the resulting history. + + * "git status" gives finer classification to various states of paths + in conflicted state and offer advice messages in its output. + + * "git submodule" learned to deal with nested submodule structure + where a module is contained within a module whose origin is + specified as a relative URL to its superproject's origin. + + * A rather heavy-ish "git completion" script has been split to create + a separate "git prompting" script, to help lazy-autoloading of the + completion part while making prompting part always available. + + +Foreign Interface + + +Performance, Internal Implementation, etc. (please report possible regressions) + + * Some tests showed false failures caused by a bug in ecryptofs. + + * We no longer use AsciiDoc7 syntax in our documentation and favor a + more modern style. + + * "git index-pack" and "git pack-objects" use streaming API to read + from the object store to avoid having to hold a large blob object + in-core while they are doing their thing. + + * Code to match paths with exclude patterns learned to avoid calling + fnmatch() by comparing fixed leading substring literally when + possible. + + +Also contains minor documentation updates and code clean-ups. + + +Fixes since v1.7.11 +------------------- + +Unless otherwise noted, all the fixes since v1.7.11 in the maintenance +releases are contained in this release (see release notes to them for +details). + + * "git clone --single-branch" to clone a single branch did not limit + the cloning to the specified branch. + (merge 0ec4b16 nd/clone-single-fix later to maint). + + * "git diff --no-index" did not correctly handle relative paths and + did not correctly give exit codes when run under "--quiet" option. + (merge 304970d th/diff-no-index-fixes later to maint). + + * When "git log" gets "--simplify-merges/by-decoration" together with + "--first-parent", the combination of these options makes the + simplification logic to use in-core commit objects that haven't + been examined for relevance, either producing incorrect result or + taking too long to produce any output. Teach the simplification + logic to ignore commits that the first-parent traversal logic + ignored when both are in effect to work around the issue. + (merge 6e513ba jc/rev-list-simplify-merges-first-parent later to maint). + + * "git add" allows adding a regular file to the path where a + submodule used to exist, but "git update-index" does not allow an + equivalent operation to Porcelain writers. + (merge 242f55f hv/submodule-update-nuke-submodules later to maint). + + * "git diff --no-index" did not work with pagers correctly. + (merge af63b54 jk/diff-no-index-pager later to maint). + + * "git diff COPYING HEAD:COPYING" gave a nonsense error message that + claimed that the treeish HEAD did not have COPYING in it. + (merge 023e37c mm/verify-filename-fix later to maint). + + * The documentation for "git cherry-pick A B..C" was misleading. + (merge b98878e cn/cherry-pick-range-docs later to maint). + + * "git archive" incorrectly computed the header checksum; the symptom + was observed only when using pathnames with hi-bit set. + (merge a5a46eb jc/ustar-checksum-is-unsigned later to maint). + + * Running "git bundle verify" on a bundle that records a complete + history said "it requires these 0 commits". + (merge 8c3710f jc/bundle-complete-notice later to maint). + + * "git ls-files --exclude=t -i" did not consider anything under t/ as + excluded, as it did not pay attention to exclusion of leading paths + while walking the index. Other two users of excluded() are also + updated. + (merge 0d316f0 jc/ls-files-i-dir later to maint). + + * "git request-pull $url dev" when the tip of "dev" branch was tagged + with "ext4-for-linus" used the contents from the tag in the output + but still asked the "dev" branch to be pulled, not the tag. + (merge 682853e jc/request-pull-match-tagname later to maint). diff --git a/Documentation/config.txt b/Documentation/config.txt index 915cb5a547..c6ff15e594 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -159,9 +159,10 @@ advice.*:: specified a refspec that isn't your current branch) and it resulted in a non-fast-forward error. statusHints:: - Directions on how to stage/unstage/add shown in the - output of linkgit:git-status[1] and the template shown - when writing commit messages. + Show directions on how to proceed from the current + state in the output of linkgit:git-status[1] and in + the template shown when writing commit messages in + linkgit:git-commit[1]. commitBeforeMerge:: Advice shown when linkgit:git-merge[1] refuses to merge to avoid overwriting local changes. @@ -483,7 +484,9 @@ core.excludesfile:: '.git/info/exclude', git looks into this file for patterns of files which are not meant to be tracked. "`~/`" is expanded to the value of `$HOME` and "`~user/`" to the specified user's - home directory. See linkgit:gitignore[5]. + home directory. Its default value is $XDG_CONFIG_HOME/git/ignore. + If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/ignore + is used instead. See linkgit:gitignore[5]. core.askpass:: Some commands (e.g. svn and http interfaces) that interactively @@ -498,7 +501,9 @@ core.attributesfile:: In addition to '.gitattributes' (per-directory) and '.git/info/attributes', git looks into this file for attributes (see linkgit:gitattributes[5]). Path expansions are made the same - way as for `core.excludesfile`. + way as for `core.excludesfile`. Its default value is + $XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME is either not + set or empty, $HOME/.config/git/attributes is used instead. core.editor:: Commands such as `commit` and `tag` that lets you edit @@ -880,7 +885,7 @@ column.ui:: make equal size columns -- + - This option defaults to 'never'. +This option defaults to 'never'. column.branch:: Specify whether to output branch listing in `git branch` in columns. @@ -1720,6 +1725,7 @@ push.default:: no refspec is implied by any of the options given on the command line. Possible values are: + +-- * `nothing` - do not push anything. * `matching` - push all branches having the same name in both ends. This is for those who prepare all the branches into a publishable @@ -1739,12 +1745,13 @@ push.default:: option and is well-suited for beginners. It will become the default in Git 2.0. * `current` - push the current branch to a branch of the same name. - + - The `simple`, `current` and `upstream` modes are for those who want to - push out a single branch after finishing work, even when the other - branches are not yet ready to be pushed out. If you are working with - other people to push into the same shared repository, you would want - to use one of these. +-- ++ +The `simple`, `current` and `upstream` modes are for those who want to +push out a single branch after finishing work, even when the other +branches are not yet ready to be pushed out. If you are working with +other people to push into the same shared repository, you would want +to use one of these. rebase.stat:: Whether to show a diffstat of what changed upstream since the last diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt index 9f3dae631e..0e170a51ca 100644 --- a/Documentation/git-cherry-pick.txt +++ b/Documentation/git-cherry-pick.txt @@ -47,7 +47,9 @@ OPTIONS linkgit:gitrevisions[7]. Sets of commits can be passed but no traversal is done by default, as if the '--no-walk' option was specified, see - linkgit:git-rev-list[1]. + linkgit:git-rev-list[1]. Note that specifying a range will + feed all ... arguments to a single revision walk + (see a later example that uses 'maint master..next'). -e:: --edit:: @@ -149,6 +151,15 @@ EXAMPLES Apply the changes introduced by all commits that are ancestors of master but not of HEAD to produce new commits. +`git cherry-pick maint next ^master`:: +`git cherry-pick maint master..next`:: + + Apply the changes introduced by all commits that are + ancestors of maint or next, but not master or any of its + ancestors. Note that the latter does not mean `maint` and + everything between `master` and `next`; specifically, + `maint` will not be used if it is included in `master`. + `git cherry-pick master~4 master~2`:: Apply the changes introduced by the fifth and third last diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 6e22522c4f..c1ddd4c2cc 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -46,13 +46,18 @@ OPTIONS mechanism and clones the repository by making a copy of HEAD and everything under objects and refs directories. The files under `.git/objects/` directory are hardlinked - to save space when possible. This is now the default when - the source repository is specified with `/path/to/repo` - syntax, so it essentially is a no-op option. To force - copying instead of hardlinking (which may be desirable - if you are trying to make a back-up of your repository), - but still avoid the usual "git aware" transport - mechanism, `--no-hardlinks` can be used. + to save space when possible. ++ +If the repository is specified as a local path (e.g., `/path/to/repo`), +this is the default, and --local is essentially a no-op. If the +repository is specified as a URL, then this flag is ignored (and we +never use the local optimizations). Specifying `--no-local` will +override the default when `/path/to/repo` is given, using the regular +git transport instead. ++ +To force copying instead of hardlinking (which may be desirable if you +are trying to make a back-up of your repository), but still avoid the +usual "git aware" transport mechanism, `--no-hardlinks` can be used. --no-hardlinks:: Optimize the cloning process from a repository on a diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 2d695f619c..f400835921 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -101,12 +101,16 @@ OPTIONS When doing a dry-run, give the output in the short-format. See linkgit:git-status[1] for details. Implies `--dry-run`. +--branch:: + Show the branch and tracking info even in short-format. + --porcelain:: When doing a dry-run, give the output in a porcelain-ready format. See linkgit:git-status[1] for details. Implies `--dry-run`. -z:: +--null:: When showing `short` or `porcelain` status output, terminate entries in the status output with NUL, instead of LF. If no format is given, implies the `--porcelain` output format. @@ -189,6 +193,10 @@ OPTIONS current tip -- if it was a merge, it will have the parents of the current tip as parents -- so the current top commit is discarded. + +--no-post-rewrite:: + Bypass the post-rewrite hook. + + -- It is a rough equivalent for: diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index d9463cb387..2d6ef32a08 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -97,10 +97,11 @@ OPTIONS --global:: For writing options: write to global ~/.gitconfig file rather than - the repository .git/config. + the repository .git/config, write to $XDG_CONFIG_HOME/git/config file + if this file exists and the ~/.gitconfig file doesn't. + -For reading options: read only from global ~/.gitconfig rather than -from all available files. +For reading options: read only from global ~/.gitconfig and from +$XDG_CONFIG_HOME/git/config rather than from all available files. + See also <>. @@ -194,7 +195,7 @@ See also <>. FILES ----- -If not set explicitly with '--file', there are three files where +If not set explicitly with '--file', there are four files where 'git config' will search for configuration options: $GIT_DIR/config:: @@ -204,6 +205,14 @@ $GIT_DIR/config:: User-specific configuration file. Also called "global" configuration file. +$XDG_CONFIG_HOME/git/config:: + Second user-specific configuration file. If $XDG_CONFIG_HOME is not set + or empty, $HOME/.config/git/config will be used. Any single-valued + variable set in this file will be overwritten by whatever is in + ~/.gitconfig. It is a good idea not to create this file if + you sometimes use older versions of Git, as support for this + file was added fairly recently. + $(prefix)/etc/gitconfig:: System-wide configuration file. diff --git a/Documentation/git-credential.txt b/Documentation/git-credential.txt new file mode 100644 index 0000000000..a81684e15f --- /dev/null +++ b/Documentation/git-credential.txt @@ -0,0 +1,144 @@ +git-credential(1) +================= + +NAME +---- +git-credential - retrieve and store user credentials + +SYNOPSIS +-------- +------------------ +git credential +------------------ + +DESCRIPTION +----------- + +Git has an internal interface for storing and retrieving credentials +from system-specific helpers, as well as prompting the user for +usernames and passwords. The git-credential command exposes this +interface to scripts which may want to retrieve, store, or prompt for +credentials in the same manner as git. The design of this scriptable +interface models the internal C API; see +link:technical/api-credentials.txt[the git credential API] for more +background on the concepts. + +git-credential takes an "action" option on the command-line (one of +`fill`, `approve`, or `reject`) and reads a credential description +on stdin (see <>). + +If the action is `fill`, git-credential will attempt to add "username" +and "password" attributes to the description by reading config files, +by contacting any configured credential helpers, or by prompting the +user. The username and password attributes of the credential +description are then printed to stdout together with the attributes +already provided. + +If the action is `approve`, git-credential will send the description +to any configured credential helpers, which may store the credential +for later use. + +If the action is `reject`, git-credential will send the description to +any configured credential helpers, which may erase any stored +credential matching the description. + +If the action is `approve` or `reject`, no output should be emitted. + +TYPICAL USE OF GIT CREDENTIAL +----------------------------- + +An application using git-credential will typically use `git +credential` following these steps: + + 1. Generate a credential description based on the context. ++ +For example, if we want a password for +`https://example.com/foo.git`, we might generate the following +credential description (don't forget the blank line at the end; it +tells `git credential` that the application finished feeding all the +infomation it has): + + protocol=https + host=example.com + path=foo.git + + 2. Ask git-credential to give us a username and password for this + description. This is done by running `git credential fill`, + feeding the description from step (1) to its standard input. The complete + credential description (including the credential per se, i.e. the + login and password) will be produced on standard output, like: + + protocol=https + host=example.com + username=bob + password=secr3t ++ +In most cases, this means the attributes given in the input will be +repeated in the output, but git may also modify the credential +description, for example by removing the `path` attribute when the +protocol is HTTP(s) and `credential.useHttpPath` is false. ++ +If the `git credential` knew about the password, this step may +not have involved the user actually typing this password (the +user may have typed a password to unlock the keychain instead, +or no user interaction was done if the keychain was already +unlocked) before it returned `password=secr3t`. + + 3. Use the credential (e.g., access the URL with the username and + password from step (2)), and see if it's accepted. + + 4. Report on the success or failure of the password. If the + credential allowed the operation to complete successfully, then + it can be marked with an "approve" action to tell `git + credential` to reuse it in its next invocation. If the credential + was rejected during the operation, use the "reject" action so + that `git credential` will ask for a new password in its next + invocation. In either case, `git credential` should be fed with + the credential description obtained from step (2) (which also + contain the ones provided in step (1)). + +[[IOFMT]] +INPUT/OUTPUT FORMAT +------------------- + +`git credential` reads and/or writes (depending on the action used) +credential information in its standard input/output. These information +can correspond either to keys for which `git credential` will obtain +the login/password information (e.g. host, protocol, path), or to the +actual credential data to be obtained (login/password). + +The credential is split into a set of named attributes. +Attributes are provided to the helper, one per line. Each attribute is +specified by a key-value pair, separated by an `=` (equals) sign, +followed by a newline. The key may contain any bytes except `=`, +newline, or NUL. The value may contain any bytes except newline or NUL. +In both cases, all bytes are treated as-is (i.e., there is no quoting, +and one cannot transmit a value with newline or NUL in it). The list of +attributes is terminated by a blank line or end-of-file. +Git will send the following attributes (but may not send all of +them for a given credential; for example, a `host` attribute makes no +sense when dealing with a non-network protocol): + +`protocol`:: + + The protocol over which the credential will be used (e.g., + `https`). + +`host`:: + + The remote hostname for a network credential. + +`path`:: + + The path with which the credential will be used. E.g., for + accessing a remote https repository, this will be the + repository's path on the server. + +`username`:: + + The credential's username, if we already have one (e.g., from a + URL, from the user, or from a previously run helper). + +`password`:: + + The credential's password, if we are asking it to be stored. diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 147fa1a8e0..2d71e4b975 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -8,9 +8,9 @@ git-rebase - Forward-port local commits to the updated upstream head SYNOPSIS -------- [verse] -'git rebase' [-i | --interactive] [options] [--onto ] +'git rebase' [-i | --interactive] [options] [--exec ] [--onto ] [] [] -'git rebase' [-i | --interactive] [options] --onto +'git rebase' [-i | --interactive] [options] [--exec ] --onto --root [] 'git rebase' --continue | --skip | --abort @@ -210,7 +210,7 @@ rebase.autosquash:: OPTIONS ------- -:: +--onto :: Starting point at which to create the new commits. If the --onto option is not specified, the starting point is . May be any valid commit, and not just an @@ -344,6 +344,27 @@ This uses the `--interactive` machinery internally, but combining it with the `--interactive` option explicitly is generally not a good idea unless you know what you are doing (see BUGS below). +-x :: +--exec :: + Append "exec " after each line creating a commit in the + final history. will be interpreted as one or more shell + commands. ++ +This option can only be used with the `--interactive` option +(see INTERACTIVE MODE below). ++ +You may execute several commands by either using one instance of `--exec` +with several commands: ++ + git rebase -i --exec "cmd1 && cmd2 && ..." ++ +or by giving more than one `--exec`: ++ + git rebase -i --exec "cmd1" --exec "cmd2" --exec ... ++ +If `--autosquash` is used, "exec" lines will not be appended for +the intermediate commits, and will only appear at the end of each +squash/fixup series. --root:: Rebase all commits reachable from , instead of @@ -521,6 +542,24 @@ in `$SHELL`, or the default shell if `$SHELL` is not set), so you can use shell features (like "cd", ">", ";" ...). The command is run from the root of the working tree. +---------------------------------- +$ git rebase -i --exec "make test" +---------------------------------- + +This command lets you check that intermediate commits are compilable. +The todo list becomes like that: + +-------------------- +pick 5928aea one +exec make test +pick 04d0fda two +exec make test +pick ba46169 three +exec make test +pick f4593f9 four +exec make test +-------------------- + SPLITTING COMMITS ----------------- diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 80120ea14f..e16f3e175b 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -75,6 +75,8 @@ repositories (i.e., attributes of interest to all users) should go into `.gitattributes` files. Attributes that should affect all repositories for a single user should be placed in a file specified by the `core.attributesfile` configuration option (see linkgit:git-config[1]). +Its default value is $XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME +is either not set or empty, $HOME/.config/git/attributes is used instead. Attributes for all users on a system should be placed in the `$(prefix)/etc/gitattributes` file. diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt index 2e7328b830..c1f692a71e 100644 --- a/Documentation/gitignore.txt +++ b/Documentation/gitignore.txt @@ -50,7 +50,9 @@ the repository but are specific to one user's workflow) should go into the `$GIT_DIR/info/exclude` file. Patterns which a user wants git to ignore in all situations (e.g., backup or temporary files generated by the user's editor of choice) generally go into a file specified by -`core.excludesfile` in the user's `~/.gitconfig`. +`core.excludesfile` in the user's `~/.gitconfig`. Its default value is +$XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is either not set or empty, +$HOME/.config/git/ignore is used instead. The underlying git plumbing tools, such as 'git ls-files' and 'git read-tree', read diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 1ae3c899ef..84e34b1aba 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -622,6 +622,7 @@ These options are mostly targeted for packing of git repositories. --no-walk:: Only show the given revs, but do not traverse their ancestors. + This has no effect if a range is specified. --do-walk:: diff --git a/Documentation/technical/api-credentials.txt b/Documentation/technical/api-credentials.txt index adb6f0c896..5977b58e57 100644 --- a/Documentation/technical/api-credentials.txt +++ b/Documentation/technical/api-credentials.txt @@ -241,42 +241,9 @@ appended to its command line, which is one of: Remove a matching credential, if any, from the helper's storage. The details of the credential will be provided on the helper's stdin -stream. The credential is split into a set of named attributes. -Attributes are provided to the helper, one per line. Each attribute is -specified by a key-value pair, separated by an `=` (equals) sign, -followed by a newline. The key may contain any bytes except `=`, -newline, or NUL. The value may contain any bytes except newline or NUL. -In both cases, all bytes are treated as-is (i.e., there is no quoting, -and one cannot transmit a value with newline or NUL in it). The list of -attributes is terminated by a blank line or end-of-file. - -Git will send the following attributes (but may not send all of -them for a given credential; for example, a `host` attribute makes no -sense when dealing with a non-network protocol): - -`protocol`:: - - The protocol over which the credential will be used (e.g., - `https`). - -`host`:: - - The remote hostname for a network credential. - -`path`:: - - The path with which the credential will be used. E.g., for - accessing a remote https repository, this will be the - repository's path on the server. - -`username`:: - - The credential's username, if we already have one (e.g., from a - URL, from the user, or from a previously run helper). - -`password`:: - - The credential's password, if we are asking it to be stored. +stream. The exact format is the same as the input/output format of the +`git credential` plumbing command (see the section `INPUT/OUTPUT +FORMAT` in linkgit:git-credential[7] for a detailed specification). For a `get` operation, the helper should produce a list of attributes on stdout in the same format. A helper is free to produce a subset, or diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index a7570decfb..fde74a68d5 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.7.11.1 +DEF_VER=v1.7.11.GIT LF=' ' diff --git a/Makefile b/Makefile index 4592f1f2ee..169dda5453 100644 --- a/Makefile +++ b/Makefile @@ -158,6 +158,9 @@ all:: # Define NO_PREAD if you have a problem with pread() system call (e.g. # cygwin1.dll before v1.5.22). # +# Define NO_THREAD_SAFE_PREAD if your pread() implementation is not +# thread-safe. (e.g. compat/pread.c or cygwin) +# # Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is # generally faster on your platform than accessing the working directory. # @@ -203,8 +206,6 @@ all:: # Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have st_blocks # field that counts the on-disk footprint in 512-byte blocks. # -# Define ASCIIDOC7 if you want to format documentation with AsciiDoc 7 -# # Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72 # (not v1.73 or v1.71). # @@ -296,6 +297,13 @@ all:: # the diff algorithm. It gives a nice speedup if your processor has # fast unaligned word loads. Does NOT work on big-endian systems! # Enabled by default on x86_64. +# +# Define GIT_USER_AGENT if you want to change how git identifies itself during +# network interactions. The default is "git/$(GIT_VERSION)". +# +# Define DEFAULT_HELP_FORMAT to "man", "info" or "html" +# (defaults to "man") if you want to have a different default when +# "git help" is called without a parameter specifying the format. GIT-VERSION-FILE: FORCE @$(SHELL_PATH) ./GIT-VERSION-GEN @@ -480,7 +488,6 @@ X = PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS)) TEST_PROGRAMS_NEED_X += test-chmtime -TEST_PROGRAMS_NEED_X += test-credential TEST_PROGRAMS_NEED_X += test-ctype TEST_PROGRAMS_NEED_X += test-date TEST_PROGRAMS_NEED_X += test-delta @@ -799,6 +806,7 @@ LIB_OBJS += usage.o LIB_OBJS += userdiff.o LIB_OBJS += utf8.o LIB_OBJS += varint.o +LIB_OBJS += version.o LIB_OBJS += walker.o LIB_OBJS += wrapper.o LIB_OBJS += write_or_die.o @@ -827,6 +835,7 @@ BUILTIN_OBJS += builtin/commit-tree.o BUILTIN_OBJS += builtin/commit.o BUILTIN_OBJS += builtin/config.o BUILTIN_OBJS += builtin/count-objects.o +BUILTIN_OBJS += builtin/credential.o BUILTIN_OBJS += builtin/describe.o BUILTIN_OBJS += builtin/diff-files.o BUILTIN_OBJS += builtin/diff-index.o @@ -904,6 +913,8 @@ BUILTIN_OBJS += builtin/write-tree.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) EXTLIBS = +GIT_USER_AGENT = git/$(GIT_VERSION) + # # Platform specific tweaks # @@ -1051,6 +1062,7 @@ ifeq ($(uname_O),Cygwin) NO_IPV6 = YesPlease OLD_ICONV = UnfortunatelyYes endif + NO_THREAD_SAFE_PREAD = YesPlease NEEDS_LIBICONV = YesPlease NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes NO_TRUSTABLE_FILEMODE = UnfortunatelyYes @@ -1236,6 +1248,7 @@ ifeq ($(uname_S),Windows) BLK_SHA1 = YesPlease NO_POSIX_GOODIES = UnfortunatelyYes NATIVE_CRLF = YesPlease + DEFAULT_HELP_FORMAT = html CC = compat/vcbuild/scripts/clink.pl AR = compat/vcbuild/scripts/lib.pl @@ -1659,6 +1672,10 @@ endif ifdef NO_PREAD COMPAT_CFLAGS += -DNO_PREAD COMPAT_OBJS += compat/pread.o + NO_THREAD_SAFE_PREAD = YesPlease +endif +ifdef NO_THREAD_SAFE_PREAD + BASIC_CFLAGS += -DNO_THREAD_SAFE_PREAD endif ifdef NO_FAST_WORKING_DIRECTORY BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY @@ -1834,10 +1851,6 @@ ifndef V endif endif -ifdef ASCIIDOC7 - export ASCIIDOC7 -endif - ifdef NO_INSTALL_HARDLINKS export NO_INSTALL_HARDLINKS endif @@ -1915,6 +1928,15 @@ SHELL_PATH_CQ_SQ = $(subst ','\'',$(SHELL_PATH_CQ)) BASIC_CFLAGS += -DSHELL_PATH='$(SHELL_PATH_CQ_SQ)' endif +GIT_USER_AGENT_SQ = $(subst ','\'',$(GIT_USER_AGENT)) +GIT_USER_AGENT_CQ = "$(subst ",\",$(subst \,\\,$(GIT_USER_AGENT)))" +GIT_USER_AGENT_CQ_SQ = $(subst ','\'',$(GIT_USER_AGENT_CQ)) +BASIC_CFLAGS += -DGIT_USER_AGENT='$(GIT_USER_AGENT_CQ_SQ)' + +ifdef DEFAULT_HELP_FORMAT +BASIC_CFLAGS += -DDEFAULT_HELP_FORMAT='"$(DEFAULT_HELP_FORMAT)"' +endif + ALL_CFLAGS += $(BASIC_CFLAGS) ALL_LDFLAGS += $(BASIC_LDFLAGS) @@ -1962,7 +1984,7 @@ strip: $(PROGRAMS) git$X $(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X git.o: common-cmds.h -git.sp git.s git.o: EXTRA_CPPFLAGS = -DGIT_VERSION='"$(GIT_VERSION)"' \ +git.sp git.s git.o: EXTRA_CPPFLAGS = \ '-DGIT_HTML_PATH="$(htmldir_SQ)"' \ '-DGIT_MAN_PATH="$(mandir_SQ)"' \ '-DGIT_INFO_PATH="$(infodir_SQ)"' @@ -1979,6 +2001,9 @@ builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \ '-DGIT_MAN_PATH="$(mandir_SQ)"' \ '-DGIT_INFO_PATH="$(infodir_SQ)"' +version.sp version.s version.o: EXTRA_CPPFLAGS = \ + '-DGIT_VERSION="$(GIT_VERSION)"' + $(BUILT_INS): git$X $(QUIET_BUILT_IN)$(RM) $@ && \ ln git$X $@ 2>/dev/null || \ @@ -1996,6 +2021,7 @@ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ -e 's|@@DIFF@@|$(DIFF_SQ)|' \ -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ + -e 's|@@GIT_USER_AGENT@@|$(GIT_USER_AGENT_SQ)|g' \ -e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' \ -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ -e 's/@@USE_GETTEXT_SCHEME@@/$(USE_GETTEXT_SCHEME)/g' \ @@ -2089,7 +2115,7 @@ configure: configure.ac $(RM) $<+ # These can record GIT_VERSION -git.o git.spec http.o \ +version.o git.spec \ $(patsubst %.sh,%,$(SCRIPT_SH)) \ $(patsubst %.perl,%,$(SCRIPT_PERL)) \ : GIT-VERSION-FILE @@ -2259,9 +2285,6 @@ attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \ gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \ -DGIT_LOCALE_PATH='"$(localedir_SQ)"' -http.sp http.s http.o: EXTRA_CPPFLAGS = \ - -DGIT_HTTP_USER_AGENT='"git/$(GIT_VERSION)"' - ifdef NO_EXPAT http-walker.sp http-walker.s http-walker.o: EXTRA_CPPFLAGS = -DNO_EXPAT endif diff --git a/RelNotes b/RelNotes index ceedb902ca..19bb2ebbe6 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/1.7.11.1.txt \ No newline at end of file +Documentation/RelNotes/1.7.12.txt \ No newline at end of file diff --git a/archive-tar.c b/archive-tar.c index dc91c6b50d..0ba3f25cf5 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -139,13 +139,13 @@ static void strbuf_append_ext_header(struct strbuf *sb, const char *keyword, static unsigned int ustar_header_chksum(const struct ustar_header *header) { - const char *p = (const char *)header; + const unsigned char *p = (const unsigned char *)header; unsigned int chksum = 0; - while (p < header->chksum) + while (p < (const unsigned char *)header->chksum) chksum += *p++; chksum += sizeof(header->chksum) * ' '; p += sizeof(header->chksum); - while (p < (const char *)header + sizeof(struct ustar_header)) + while (p < (const unsigned char *)header + sizeof(struct ustar_header)) chksum += *p++; return chksum; } diff --git a/attr.c b/attr.c index 303751f6c2..aef93d896f 100644 --- a/attr.c +++ b/attr.c @@ -497,6 +497,7 @@ static int git_attr_system(void) static void bootstrap_attr_stack(void) { struct attr_stack *elem; + char *xdg_attributes_file; if (attr_stack) return; @@ -515,13 +516,15 @@ static void bootstrap_attr_stack(void) } } - if (git_attributes_file) { - elem = read_attr_from_file(git_attributes_file, 1); - if (elem) { - elem->origin = NULL; - elem->prev = attr_stack; - attr_stack = elem; - } + if (!git_attributes_file) { + home_config_paths(NULL, &xdg_attributes_file, "attributes"); + git_attributes_file = xdg_attributes_file; + } + elem = read_attr_from_file(git_attributes_file, 1); + if (elem) { + elem->origin = NULL; + elem->prev = attr_stack; + attr_stack = elem; } if (!is_bare_repository() || direction == GIT_ATTR_INDEX) { diff --git a/branch.c b/branch.c index eccdaf9392..2bef1e7e71 100644 --- a/branch.c +++ b/branch.c @@ -74,25 +74,33 @@ void install_branch_config(int flag, const char *local, const char *origin, cons strbuf_addf(&key, "branch.%s.rebase", local); git_config_set(key.buf, "true"); } + strbuf_release(&key); if (flag & BRANCH_CONFIG_VERBOSE) { - strbuf_reset(&key); - - strbuf_addstr(&key, origin ? "remote" : "local"); - - /* Are we tracking a proper "branch"? */ - if (remote_is_branch) { - strbuf_addf(&key, " branch %s", shortname); - if (origin) - strbuf_addf(&key, " from %s", origin); - } + if (remote_is_branch && origin) + printf(rebasing ? + "Branch %s set up to track remote branch %s from %s by rebasing.\n" : + "Branch %s set up to track remote branch %s from %s.\n", + local, shortname, origin); + else if (remote_is_branch && !origin) + printf(rebasing ? + "Branch %s set up to track local branch %s by rebasing.\n" : + "Branch %s set up to track local branch %s.\n", + local, shortname); + else if (!remote_is_branch && origin) + printf(rebasing ? + "Branch %s set up to track remote ref %s by rebasing.\n" : + "Branch %s set up to track remote ref %s.\n", + local, remote); + else if (!remote_is_branch && !origin) + printf(rebasing ? + "Branch %s set up to track local ref %s by rebasing.\n" : + "Branch %s set up to track local ref %s.\n", + local, remote); else - strbuf_addf(&key, " ref %s", remote); - printf("Branch %s set up to track %s%s.\n", - local, key.buf, - rebasing ? " by rebasing" : ""); + die("BUG: impossible combination of %d and %p", + remote_is_branch, origin); } - strbuf_release(&key); } /* diff --git a/builtin.h b/builtin.h index 338f540e39..ba6626b035 100644 --- a/builtin.h +++ b/builtin.h @@ -9,7 +9,6 @@ #define DEFAULT_MERGE_LOG_LEN 20 -extern const char git_version_string[]; extern const char git_usage_string[]; extern const char git_more_info_string[]; @@ -41,6 +40,8 @@ int copy_note_for_rewrite(struct notes_rewrite_cfg *c, void finish_copy_notes_for_rewrite(struct notes_rewrite_cfg *c); extern int check_pager_config(const char *cmd); +struct diff_options; +extern void setup_diff_pager(struct diff_options *); extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, char **buf, unsigned long *buf_size); @@ -66,6 +67,7 @@ extern int cmd_commit(int argc, const char **argv, const char *prefix); extern int cmd_commit_tree(int argc, const char **argv, const char *prefix); extern int cmd_config(int argc, const char **argv, const char *prefix); extern int cmd_count_objects(int argc, const char **argv, const char *prefix); +extern int cmd_credential(int argc, const char **argv, const char *prefix); extern int cmd_describe(int argc, const char **argv, const char *prefix); extern int cmd_diff_files(int argc, const char **argv, const char *prefix); extern int cmd_diff_index(int argc, const char **argv, const char *prefix); @@ -83,7 +85,6 @@ extern int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix extern int cmd_grep(int argc, const char **argv, const char *prefix); extern int cmd_hash_object(int argc, const char **argv, const char *prefix); extern int cmd_help(int argc, const char **argv, const char *prefix); -extern int cmd_http_fetch(int argc, const char **argv, const char *prefix); extern int cmd_index_pack(int argc, const char **argv, const char *prefix); extern int cmd_init_db(int argc, const char **argv, const char *prefix); extern int cmd_log(int argc, const char **argv, const char *prefix); @@ -108,7 +109,6 @@ extern int cmd_notes(int argc, const char **argv, const char *prefix); extern int cmd_pack_objects(int argc, const char **argv, const char *prefix); extern int cmd_pack_redundant(int argc, const char **argv, const char *prefix); extern int cmd_patch_id(int argc, const char **argv, const char *prefix); -extern int cmd_pickaxe(int argc, const char **argv, const char *prefix); extern int cmd_prune(int argc, const char **argv, const char *prefix); extern int cmd_prune_packed(int argc, const char **argv, const char *prefix); extern int cmd_push(int argc, const char **argv, const char *prefix); @@ -141,7 +141,6 @@ extern int cmd_update_ref(int argc, const char **argv, const char *prefix); extern int cmd_update_server_info(int argc, const char **argv, const char *prefix); extern int cmd_upload_archive(int argc, const char **argv, const char *prefix); extern int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix); -extern int cmd_upload_tar(int argc, const char **argv, const char *prefix); extern int cmd_var(int argc, const char **argv, const char *prefix); extern int cmd_verify_tag(int argc, const char **argv, const char *prefix); extern int cmd_version(int argc, const char **argv, const char *prefix); diff --git a/builtin/add.c b/builtin/add.c index b79336d712..87446cf92a 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -443,6 +443,9 @@ int cmd_add(int argc, const char **argv, const char *prefix) if (pathspec) { int i; + struct path_exclude_check check; + + path_exclude_check_init(&check, &dir); if (!seen) seen = find_used_pathspec(pathspec); for (i = 0; pathspec[i]; i++) { @@ -450,7 +453,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) && !file_exists(pathspec[i])) { if (ignore_missing) { int dtype = DT_UNKNOWN; - if (excluded(&dir, pathspec[i], &dtype)) + if (path_excluded(&check, pathspec[i], -1, &dtype)) dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i])); } else die(_("pathspec '%s' did not match any files"), @@ -458,6 +461,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) } } free(seen); + path_exclude_check_clear(&check); } plug_bulk_checkin(); diff --git a/builtin/blame.c b/builtin/blame.c index 24d3dd5292..960c58d855 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1837,6 +1837,16 @@ static int read_ancestry(const char *graft_file) return 0; } +static int update_auto_abbrev(int auto_abbrev, struct origin *suspect) +{ + const char *uniq = find_unique_abbrev(suspect->commit->object.sha1, + auto_abbrev); + int len = strlen(uniq); + if (auto_abbrev < len) + return len; + return auto_abbrev; +} + /* * How many columns do we need to show line numbers, authors, * and filenames? @@ -1847,12 +1857,16 @@ static void find_alignment(struct scoreboard *sb, int *option) int longest_dst_lines = 0; unsigned largest_score = 0; struct blame_entry *e; + int compute_auto_abbrev = (abbrev < 0); + int auto_abbrev = default_abbrev; for (e = sb->ent; e; e = e->next) { struct origin *suspect = e->suspect; struct commit_info ci; int num; + if (compute_auto_abbrev) + auto_abbrev = update_auto_abbrev(auto_abbrev, suspect); if (strcmp(suspect->path, sb->path)) *option |= OUTPUT_SHOW_NAME; num = strlen(suspect->path); @@ -1880,6 +1894,10 @@ static void find_alignment(struct scoreboard *sb, int *option) max_orig_digits = decimal_width(longest_src_lines); max_digits = decimal_width(longest_dst_lines); max_score_digits = decimal_width(largest_score); + + if (compute_auto_abbrev) + /* one more abbrev length is needed for the boundary commit */ + abbrev = auto_abbrev + 1; } /* @@ -2353,10 +2371,9 @@ int cmd_blame(int argc, const char **argv, const char *prefix) parse_done: argc = parse_options_end(&ctx); - if (abbrev == -1) - abbrev = default_abbrev; - /* one more abbrev length is needed for the boundary commit */ - abbrev++; + if (0 < abbrev) + /* one more abbrev length is needed for the boundary commit */ + abbrev++; if (revs_file && read_ancestry(revs_file)) die_errno("reading graft file '%s' failed", revs_file); diff --git a/builtin/checkout.c b/builtin/checkout.c index e8c1b1f189..3980d5d06e 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -915,6 +915,8 @@ static int switch_unborn_to_new_branch(struct checkout_opts *opts) int status; struct strbuf branch_ref = STRBUF_INIT; + if (!opts->new_branch) + die(_("You are on a branch yet to be born")); strbuf_addf(&branch_ref, "refs/heads/%s", opts->new_branch); status = create_symref("HEAD", branch_ref.buf, "checkout -b"); strbuf_release(&branch_ref); diff --git a/builtin/clone.c b/builtin/clone.c index a4d8d25ee3..d3b7fdccec 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -38,7 +38,7 @@ static const char * const builtin_clone_usage[] = { }; static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1; -static int option_local, option_no_hardlinks, option_shared, option_recursive; +static int option_local = -1, option_no_hardlinks, option_shared, option_recursive; static char *option_template, *option_depth; static char *option_origin = NULL; static char *option_branch = NULL; @@ -70,8 +70,8 @@ static struct option builtin_clone_options[] = { PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, OPT_BOOLEAN(0, "mirror", &option_mirror, "create a mirror repository (implies bare)"), - OPT_BOOLEAN('l', "local", &option_local, - "to clone from a local repository"), + OPT_BOOL('l', "local", &option_local, + "to clone from a local repository"), OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks, "don't use local hardlinks, always copy"), OPT_BOOLEAN('s', "shared", &option_shared, @@ -342,7 +342,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, if (!option_no_hardlinks) { if (!link(src->buf, dest->buf)) continue; - if (option_local) + if (option_local > 0) die_errno(_("failed to create link '%s'"), dest->buf); option_no_hardlinks = 1; } @@ -433,8 +433,11 @@ static struct ref *wanted_peer_refs(const struct ref *refs, if (!option_branch) remote_head = guess_remote_head(head, refs, 0); - else - remote_head = find_remote_branch(refs, option_branch); + else { + local_refs = NULL; + tail = &local_refs; + remote_head = copy_ref(find_remote_branch(refs, option_branch)); + } if (!remote_head && option_branch) warning(_("Could not find remote branch %s to clone."), @@ -668,7 +671,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) die(_("repository '%s' does not exist"), repo_name); else repo = repo_name; - is_local = path && !is_bundle; + is_local = option_local != 0 && path && !is_bundle; if (is_local && option_depth) warning(_("--depth is ignored in local clones; use file:// instead.")); diff --git a/builtin/config.c b/builtin/config.c index 33c8820af6..e8e1c0a456 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -161,7 +161,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; - char *global = NULL, *repo_config = NULL; + char *global = NULL, *xdg = NULL, *repo_config = NULL; const char *system_wide = NULL, *local; struct config_include_data inc = CONFIG_INCLUDE_INIT; config_fn_t fn; @@ -169,12 +169,10 @@ static int get_value(const char *key_, const char *regex_) local = given_config_file; if (!local) { - const char *home = getenv("HOME"); local = repo_config = git_pathdup("config"); - if (home) - global = xstrdup(mkpath("%s/.gitconfig", home)); if (git_config_system()) system_wide = git_etc_gitconfig(); + home_config_paths(&global, &xdg, "config"); } if (use_key_regexp) { @@ -229,6 +227,8 @@ static int get_value(const char *key_, const char *regex_) if (do_all && system_wide) git_config_from_file(fn, system_wide, data); + if (do_all && xdg) + git_config_from_file(fn, xdg, data); if (do_all && global) git_config_from_file(fn, global, data); if (do_all) @@ -238,6 +238,8 @@ static int get_value(const char *key_, const char *regex_) git_config_from_file(fn, local, data); if (!do_all && !seen && global) git_config_from_file(fn, global, data); + if (!do_all && !seen && xdg) + git_config_from_file(fn, xdg, data); if (!do_all && !seen && system_wide) git_config_from_file(fn, system_wide, data); @@ -255,6 +257,7 @@ static int get_value(const char *key_, const char *regex_) free_strings: free(repo_config); free(global); + free(xdg); return ret; } @@ -379,13 +382,17 @@ int cmd_config(int argc, const char **argv, const char *prefix) } if (use_global_config) { - char *home = getenv("HOME"); - if (home) { - char *user_config = xstrdup(mkpath("%s/.gitconfig", home)); + char *user_config = NULL; + char *xdg_config = NULL; + + home_config_paths(&user_config, &xdg_config, "config"); + + if (access(user_config, R_OK) && !access(xdg_config, R_OK)) + given_config_file = xdg_config; + else if (user_config) given_config_file = user_config; - } else { + else die("$HOME not set"); - } } else if (use_system_config) given_config_file = git_etc_gitconfig(); diff --git a/builtin/credential.c b/builtin/credential.c new file mode 100644 index 0000000000..0412fa00f0 --- /dev/null +++ b/builtin/credential.c @@ -0,0 +1,31 @@ +#include "git-compat-util.h" +#include "credential.h" +#include "builtin.h" + +static const char usage_msg[] = + "git credential [fill|approve|reject]"; + +int cmd_credential(int argc, const char **argv, const char *prefix) +{ + const char *op; + struct credential c = CREDENTIAL_INIT; + + op = argv[1]; + if (!op) + usage(usage_msg); + + if (credential_read(&c, stdin) < 0) + die("unable to read credential from stdin"); + + if (!strcmp(op, "fill")) { + credential_fill(&c); + credential_write(&c, stdout); + } else if (!strcmp(op, "approve")) { + credential_approve(&c); + } else if (!strcmp(op, "reject")) { + credential_reject(&c); + } else { + usage(usage_msg); + } + return 0; +} diff --git a/builtin/diff.c b/builtin/diff.c index 9069dc41be..da8f6aac2b 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -304,13 +304,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) DIFF_OPT_SET(&rev.diffopt, RECURSIVE); - /* - * If the user asked for our exit code then don't start a - * pager or we would end up reporting its exit code instead. - */ - if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS) && - check_pager_config("diff") != 0) - setup_pager(); + setup_diff_pager(&rev.diffopt); /* * Do we have --cached and not have a pending object, then @@ -421,3 +415,19 @@ int cmd_diff(int argc, const char **argv, const char *prefix) refresh_index_quietly(); return result; } + +void setup_diff_pager(struct diff_options *opt) +{ + /* + * If the user asked for our exit code, then either they want --quiet + * or --exit-code. We should definitely not bother with a pager in the + * former case, as we will generate no output. Since we still properly + * report our exit code even when a pager is run, we _could_ run a + * pager with --exit-code. But since we have not done so historically, + * and because it is easy to find people oneline advising "git diff + * --exit-code" in hooks and other scripts, we do not do so. + */ + if (!DIFF_OPT_TST(opt, EXIT_WITH_STATUS) && + check_pager_config("diff") != 0) + setup_pager(); +} diff --git a/builtin/fast-export.c b/builtin/fast-export.c index ef7c012094..9ab6db3fb0 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -185,6 +185,8 @@ static void print_path(const char *path) int need_quote = quote_c_style(path, NULL, NULL, 0); if (need_quote) quote_c_style(path, NULL, stdout, 0); + else if (strchr(path, ' ')) + printf("\"%s\"", path); else printf("%s", path); } diff --git a/builtin/grep.c b/builtin/grep.c index fe1726f5ef..29adb0ac93 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -928,7 +928,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) if (!seen_dashdash) { int j; for (j = i; j < argc; j++) - verify_filename(prefix, argv[j]); + verify_filename(prefix, argv[j], j == i); } paths = get_pathspec(prefix, argv + i); diff --git a/builtin/help.c b/builtin/help.c index 43d3c84449..8f9cd60548 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -12,6 +12,10 @@ #include "column.h" #include "help.h" +#ifndef DEFAULT_HELP_FORMAT +#define DEFAULT_HELP_FORMAT "man" +#endif + static struct man_viewer_list { struct man_viewer_list *next; char name[FLEX_ARRAY]; @@ -447,6 +451,8 @@ int cmd_help(int argc, const char **argv, const char *prefix) if (parsed_help_format != HELP_FORMAT_NONE) help_format = parsed_help_format; + if (help_format == HELP_FORMAT_NONE) + help_format = parse_help_format(DEFAULT_HELP_FORMAT); alias = alias_lookup(argv[0]); if (alias && !is_git_command(argv[0])) { diff --git a/builtin/index-pack.c b/builtin/index-pack.c index dc2cfe6e6f..5a0372ab08 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -9,6 +9,7 @@ #include "progress.h" #include "fsck.h" #include "exec_cmd.h" +#include "streaming.h" #include "thread-utils.h" static const char index_pack_usage[] = @@ -39,8 +40,8 @@ struct base_data { int ofs_first, ofs_last; }; -#if !defined(NO_PTHREADS) && defined(NO_PREAD) -/* NO_PREAD uses compat/pread.c, which is not thread-safe. Disable threading. */ +#if !defined(NO_PTHREADS) && defined(NO_THREAD_SAFE_PREAD) +/* pread() emulation is not thread-safe. Disable threading. */ #define NO_PTHREADS #endif @@ -384,30 +385,62 @@ static void unlink_base_data(struct base_data *c) free_base_data(c); } -static void *unpack_entry_data(unsigned long offset, unsigned long size) +static int is_delta_type(enum object_type type) +{ + return (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA); +} + +static void *unpack_entry_data(unsigned long offset, unsigned long size, + enum object_type type, unsigned char *sha1) { + static char fixed_buf[8192]; int status; git_zstream stream; - void *buf = xmalloc(size); + void *buf; + git_SHA_CTX c; + char hdr[32]; + int hdrlen; + + if (!is_delta_type(type)) { + hdrlen = sprintf(hdr, "%s %lu", typename(type), size) + 1; + git_SHA1_Init(&c); + git_SHA1_Update(&c, hdr, hdrlen); + } else + sha1 = NULL; + if (type == OBJ_BLOB && size > big_file_threshold) + buf = fixed_buf; + else + buf = xmalloc(size); memset(&stream, 0, sizeof(stream)); git_inflate_init(&stream); stream.next_out = buf; - stream.avail_out = size; + stream.avail_out = buf == fixed_buf ? sizeof(fixed_buf) : size; do { + unsigned char *last_out = stream.next_out; stream.next_in = fill(1); stream.avail_in = input_len; status = git_inflate(&stream, 0); use(input_len - stream.avail_in); + if (sha1) + git_SHA1_Update(&c, last_out, stream.next_out - last_out); + if (buf == fixed_buf) { + stream.next_out = buf; + stream.avail_out = sizeof(fixed_buf); + } } while (status == Z_OK); if (stream.total_out != size || status != Z_STREAM_END) bad_object(offset, _("inflate returned %d"), status); git_inflate_end(&stream); - return buf; + if (sha1) + git_SHA1_Final(sha1, &c); + return buf == fixed_buf ? NULL : buf; } -static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_base) +static void *unpack_raw_entry(struct object_entry *obj, + union delta_base *delta_base, + unsigned char *sha1) { unsigned char *p; unsigned long size, c; @@ -467,12 +500,14 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_ } obj->hdr_size = consumed_bytes - obj->idx.offset; - data = unpack_entry_data(obj->idx.offset, obj->size); + data = unpack_entry_data(obj->idx.offset, obj->size, obj->type, sha1); obj->idx.crc32 = input_crc32; return data; } -static void *get_data_from_pack(struct object_entry *obj) +static void *unpack_data(struct object_entry *obj, + int (*consume)(const unsigned char *, unsigned long, void *), + void *cb_data) { off_t from = obj[0].idx.offset + obj[0].hdr_size; unsigned long len = obj[1].idx.offset - from; @@ -480,15 +515,16 @@ static void *get_data_from_pack(struct object_entry *obj) git_zstream stream; int status; - data = xmalloc(obj->size); + data = xmalloc(consume ? 64*1024 : obj->size); inbuf = xmalloc((len < 64*1024) ? len : 64*1024); memset(&stream, 0, sizeof(stream)); git_inflate_init(&stream); stream.next_out = data; - stream.avail_out = obj->size; + stream.avail_out = consume ? 64*1024 : obj->size; do { + unsigned char *last_out = stream.next_out; ssize_t n = (len < 64*1024) ? len : 64*1024; n = pread(pack_fd, inbuf, n, from); if (n < 0) @@ -503,6 +539,15 @@ static void *get_data_from_pack(struct object_entry *obj) stream.next_in = inbuf; stream.avail_in = n; status = git_inflate(&stream, 0); + if (consume) { + if (consume(last_out, stream.next_out - last_out, cb_data)) { + free(inbuf); + free(data); + return NULL; + } + stream.next_out = data; + stream.avail_out = 64*1024; + } } while (len && status == Z_OK && !stream.avail_in); /* This has been inflated OK when first encountered, so... */ @@ -511,9 +556,18 @@ static void *get_data_from_pack(struct object_entry *obj) git_inflate_end(&stream); free(inbuf); + if (consume) { + free(data); + data = NULL; + } return data; } +static void *get_data_from_pack(struct object_entry *obj) +{ + return unpack_data(obj, NULL, NULL); +} + static int compare_delta_bases(const union delta_base *base1, const union delta_base *base2, enum object_type type1, @@ -568,25 +622,102 @@ static void find_delta_children(const union delta_base *base, *last_index = last; } -static void sha1_object(const void *data, unsigned long size, - enum object_type type, unsigned char *sha1) +struct compare_data { + struct object_entry *entry; + struct git_istream *st; + unsigned char *buf; + unsigned long buf_size; +}; + +static int compare_objects(const unsigned char *buf, unsigned long size, + void *cb_data) +{ + struct compare_data *data = cb_data; + + if (data->buf_size < size) { + free(data->buf); + data->buf = xmalloc(size); + data->buf_size = size; + } + + while (size) { + ssize_t len = read_istream(data->st, data->buf, size); + if (len == 0) + die(_("SHA1 COLLISION FOUND WITH %s !"), + sha1_to_hex(data->entry->idx.sha1)); + if (len < 0) + die(_("unable to read %s"), + sha1_to_hex(data->entry->idx.sha1)); + if (memcmp(buf, data->buf, len)) + die(_("SHA1 COLLISION FOUND WITH %s !"), + sha1_to_hex(data->entry->idx.sha1)); + size -= len; + buf += len; + } + return 0; +} + +static int check_collison(struct object_entry *entry) +{ + struct compare_data data; + enum object_type type; + unsigned long size; + + if (entry->size <= big_file_threshold || entry->type != OBJ_BLOB) + return -1; + + memset(&data, 0, sizeof(data)); + data.entry = entry; + data.st = open_istream(entry->idx.sha1, &type, &size, NULL); + if (!data.st) + return -1; + if (size != entry->size || type != entry->type) + die(_("SHA1 COLLISION FOUND WITH %s !"), + sha1_to_hex(entry->idx.sha1)); + unpack_data(entry, compare_objects, &data); + close_istream(data.st); + free(data.buf); + return 0; +} + +static void sha1_object(const void *data, struct object_entry *obj_entry, + unsigned long size, enum object_type type, + const unsigned char *sha1) { - hash_sha1_file(data, size, typename(type), sha1); + void *new_data = NULL; + int collision_test_needed; + + assert(data || obj_entry); + read_lock(); - if (has_sha1_file(sha1)) { + collision_test_needed = has_sha1_file(sha1); + read_unlock(); + + if (collision_test_needed && !data) { + read_lock(); + if (!check_collison(obj_entry)) + collision_test_needed = 0; + read_unlock(); + } + if (collision_test_needed) { void *has_data; enum object_type has_type; unsigned long has_size; + read_lock(); + has_type = sha1_object_info(sha1, &has_size); + if (has_type != type || has_size != size) + die(_("SHA1 COLLISION FOUND WITH %s !"), sha1_to_hex(sha1)); has_data = read_sha1_file(sha1, &has_type, &has_size); read_unlock(); + if (!data) + data = new_data = get_data_from_pack(obj_entry); if (!has_data) die(_("cannot read existing object %s"), sha1_to_hex(sha1)); if (size != has_size || type != has_type || memcmp(data, has_data, size) != 0) die(_("SHA1 COLLISION FOUND WITH %s !"), sha1_to_hex(sha1)); free(has_data); - } else - read_unlock(); + } if (strict) { read_lock(); @@ -601,6 +732,9 @@ static void sha1_object(const void *data, unsigned long size, int eaten; void *buf = (void *) data; + if (!buf) + buf = new_data = get_data_from_pack(obj_entry); + /* * we do not need to free the memory here, as the * buf is deleted by the caller. @@ -625,11 +759,8 @@ static void sha1_object(const void *data, unsigned long size, } read_unlock(); } -} -static int is_delta_type(enum object_type type) -{ - return (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA); + free(new_data); } /* @@ -711,7 +842,9 @@ static void resolve_delta(struct object_entry *delta_obj, free(delta_data); if (!result->data) bad_object(delta_obj->idx.offset, _("failed to apply delta")); - sha1_object(result->data, result->size, delta_obj->real_type, + hash_sha1_file(result->data, result->size, + typename(delta_obj->real_type), delta_obj->idx.sha1); + sha1_object(result->data, NULL, result->size, delta_obj->real_type, delta_obj->idx.sha1); counter_lock(); nr_resolved_deltas++; @@ -841,7 +974,7 @@ static void *threaded_second_pass(void *data) */ static void parse_pack_objects(unsigned char *sha1) { - int i; + int i, nr_delays = 0; struct delta_entry *delta = deltas; struct stat st; @@ -851,14 +984,18 @@ static void parse_pack_objects(unsigned char *sha1) nr_objects); for (i = 0; i < nr_objects; i++) { struct object_entry *obj = &objects[i]; - void *data = unpack_raw_entry(obj, &delta->base); + void *data = unpack_raw_entry(obj, &delta->base, obj->idx.sha1); obj->real_type = obj->type; if (is_delta_type(obj->type)) { nr_deltas++; delta->obj_no = i; delta++; + } else if (!data) { + /* large blobs, check later */ + obj->real_type = OBJ_BAD; + nr_delays++; } else - sha1_object(data, obj->size, obj->type, obj->idx.sha1); + sha1_object(data, NULL, obj->size, obj->type, obj->idx.sha1); free(data); display_progress(progress, i+1); } @@ -878,6 +1015,17 @@ static void parse_pack_objects(unsigned char *sha1) if (S_ISREG(st.st_mode) && lseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size) die(_("pack has junk at the end")); + + for (i = 0; i < nr_objects; i++) { + struct object_entry *obj = &objects[i]; + if (obj->real_type != OBJ_BAD) + continue; + obj->real_type = obj->type; + sha1_object(NULL, obj, obj->size, obj->type, obj->idx.sha1); + nr_delays--; + } + if (nr_delays) + die(_("confusion beyond insanity in parse_pack_objects()")); } /* diff --git a/builtin/log.c b/builtin/log.c index 906dca475a..4f1b42a685 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -21,6 +21,7 @@ #include "parse-options.h" #include "branch.h" #include "streaming.h" +#include "version.h" /* Set a default date-time format for git log ("log.date" config variable) */ static const char *default_date_mode = NULL; diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 7cff175745..31b3f2d900 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -200,9 +200,19 @@ static void show_ru_info(void) } } +static int ce_excluded(struct path_exclude_check *check, struct cache_entry *ce) +{ + int dtype = ce_to_dtype(ce); + return path_excluded(check, ce->name, ce_namelen(ce), &dtype); +} + static void show_files(struct dir_struct *dir) { int i; + struct path_exclude_check check; + + if ((dir->flags & DIR_SHOW_IGNORED)) + path_exclude_check_init(&check, dir); /* For cached/deleted files we don't need to even do the readdir */ if (show_others || show_killed) { @@ -215,9 +225,8 @@ static void show_files(struct dir_struct *dir) if (show_cached | show_stage) { for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; - int dtype = ce_to_dtype(ce); - if (dir->flags & DIR_SHOW_IGNORED && - !excluded(dir, ce->name, &dtype)) + if ((dir->flags & DIR_SHOW_IGNORED) && + !ce_excluded(&check, ce)) continue; if (show_unmerged && !ce_stage(ce)) continue; @@ -232,9 +241,8 @@ static void show_files(struct dir_struct *dir) struct cache_entry *ce = active_cache[i]; struct stat st; int err; - int dtype = ce_to_dtype(ce); - if (dir->flags & DIR_SHOW_IGNORED && - !excluded(dir, ce->name, &dtype)) + if ((dir->flags & DIR_SHOW_IGNORED) && + !ce_excluded(&check, ce)) continue; if (ce->ce_flags & CE_UPDATE) continue; @@ -247,6 +255,9 @@ static void show_files(struct dir_struct *dir) show_ce_entry(tag_modified, ce); } } + + if ((dir->flags & DIR_SHOW_IGNORED)) + path_exclude_check_clear(&check); } /* diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index ccfcbad146..f3348208d8 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -16,6 +16,7 @@ #include "list-objects.h" #include "progress.h" #include "refs.h" +#include "streaming.h" #include "thread-utils.h" static const char *pack_usage[] = { @@ -150,6 +151,46 @@ static unsigned long do_compress(void **pptr, unsigned long size) return stream.total_out; } +static unsigned long write_large_blob_data(struct git_istream *st, struct sha1file *f, + const unsigned char *sha1) +{ + git_zstream stream; + unsigned char ibuf[1024 * 16]; + unsigned char obuf[1024 * 16]; + unsigned long olen = 0; + + memset(&stream, 0, sizeof(stream)); + git_deflate_init(&stream, pack_compression_level); + + for (;;) { + ssize_t readlen; + int zret = Z_OK; + readlen = read_istream(st, ibuf, sizeof(ibuf)); + if (readlen == -1) + die(_("unable to read %s"), sha1_to_hex(sha1)); + + stream.next_in = ibuf; + stream.avail_in = readlen; + while ((stream.avail_in || readlen == 0) && + (zret == Z_OK || zret == Z_BUF_ERROR)) { + stream.next_out = obuf; + stream.avail_out = sizeof(obuf); + zret = git_deflate(&stream, readlen ? 0 : Z_FINISH); + sha1write(f, obuf, stream.next_out - obuf); + olen += stream.next_out - obuf; + } + if (stream.avail_in) + die(_("deflate error (%d)"), zret); + if (readlen == 0) { + if (zret != Z_STREAM_END) + die(_("deflate error (%d)"), zret); + break; + } + } + git_deflate_end(&stream); + return olen; +} + /* * we are going to reuse the existing object data as is. make * sure it is not corrupt. @@ -208,11 +249,18 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent unsigned hdrlen; enum object_type type; void *buf; + struct git_istream *st = NULL; if (!usable_delta) { - buf = read_sha1_file(entry->idx.sha1, &type, &size); - if (!buf) - die("unable to read %s", sha1_to_hex(entry->idx.sha1)); + if (entry->type == OBJ_BLOB && + entry->size > big_file_threshold && + (st = open_istream(entry->idx.sha1, &type, &size, NULL)) != NULL) + buf = NULL; + else { + buf = read_sha1_file(entry->idx.sha1, &type, &size); + if (!buf) + die(_("unable to read %s"), sha1_to_hex(entry->idx.sha1)); + } /* * make sure no cached delta data remains from a * previous attempt before a pack split occurred. @@ -233,7 +281,9 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent OBJ_OFS_DELTA : OBJ_REF_DELTA; } - if (entry->z_delta_size) + if (st) /* large blob case, just assume we don't compress well */ + datalen = size; + else if (entry->z_delta_size) datalen = entry->z_delta_size; else datalen = do_compress(&buf, size); @@ -256,6 +306,8 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent while (ofs >>= 7) dheader[--pos] = 128 | (--ofs & 127); if (limit && hdrlen + sizeof(dheader) - pos + datalen + 20 >= limit) { + if (st) + close_istream(st); free(buf); return 0; } @@ -268,6 +320,8 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent * an additional 20 bytes for the base sha1. */ if (limit && hdrlen + 20 + datalen + 20 >= limit) { + if (st) + close_istream(st); free(buf); return 0; } @@ -276,13 +330,20 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent hdrlen += 20; } else { if (limit && hdrlen + datalen + 20 >= limit) { + if (st) + close_istream(st); free(buf); return 0; } sha1write(f, header, hdrlen); } - sha1write(f, buf, datalen); - free(buf); + if (st) { + datalen = write_large_blob_data(st, f, entry->idx.sha1); + close_istream(st); + } else { + sha1write(f, buf, datalen); + free(buf); + } return hdrlen + datalen; } diff --git a/builtin/reflog.c b/builtin/reflog.c index 062d7dad1b..b3c9e27bde 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -330,8 +330,10 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1, printf("keep %s", message); return 0; prune: - if (!cb->newlog || cb->cmd->verbose) - printf("%sprune %s", cb->newlog ? "" : "would ", message); + if (!cb->newlog) + printf("would prune %s", message); + else if (cb->cmd->verbose) + printf("prune %s", message); return 0; } diff --git a/builtin/reset.c b/builtin/reset.c index 8c2c1d52a2..4cc34c9084 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -285,7 +285,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) rev = argv[i++]; } else { /* Otherwise we treat this as a filename */ - verify_filename(prefix, argv[i]); + verify_filename(prefix, argv[i], 1); } } diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 733f626f6c..13495b88f5 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -486,7 +486,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) if (as_is) { if (show_file(arg) && as_is < 2) - verify_filename(prefix, arg); + verify_filename(prefix, arg, 0); continue; } if (!strcmp(arg,"-n")) { @@ -734,7 +734,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) as_is = 1; if (!show_file(arg)) continue; - verify_filename(prefix, arg); + verify_filename(prefix, arg, 1); } if (verify) { if (revs_count == 1) { diff --git a/builtin/update-index.c b/builtin/update-index.c index 5f038d64da..5a4e9ea55a 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -211,12 +211,6 @@ static int process_path(const char *path) if (S_ISDIR(st.st_mode)) return process_directory(path, len, &st); - /* - * Process a regular file - */ - if (ce && S_ISGITLINK(ce->ce_mode)) - return error("%s is already a gitlink, not replacing", path); - return add_one_path(ce, path, len, &st); } diff --git a/bundle.c b/bundle.c index 8d31b98f58..8d12816b9d 100644 --- a/bundle.c +++ b/bundle.c @@ -188,12 +188,16 @@ int verify_bundle(struct bundle_header *header, int verbose) r->nr), r->nr); list_refs(r, 0, NULL); - r = &header->prerequisites; - printf_ln(Q_("The bundle requires this ref", - "The bundle requires these %d refs", - r->nr), - r->nr); - list_refs(r, 0, NULL); + if (!r->nr) { + printf_ln(_("The bundle records a complete history.")); + } else { + r = &header->prerequisites; + printf_ln(Q_("The bundle requires this ref", + "The bundle requires these %d refs", + r->nr), + r->nr); + list_refs(r, 0, NULL); + } } return ret; } diff --git a/cache.h b/cache.h index 06413e1584..c22b928980 100644 --- a/cache.h +++ b/cache.h @@ -409,8 +409,11 @@ extern const char *setup_git_directory(void); extern char *prefix_path(const char *prefix, int len, const char *path); extern const char *prefix_filename(const char *prefix, int len, const char *path); extern int check_filename(const char *prefix, const char *name); -extern void verify_filename(const char *prefix, const char *name); +extern void verify_filename(const char *prefix, + const char *name, + int diagnose_misspelt_rev); extern void verify_non_filename(const char *prefix, const char *name); +extern int path_inside_repo(const char *prefix, const char *path); #define INIT_DB_QUIET 0x0001 @@ -619,6 +622,8 @@ extern char *git_snpath(char *buf, size_t n, const char *fmt, ...) __attribute__((format (printf, 3, 4))); extern char *git_pathdup(const char *fmt, ...) __attribute__((format (printf, 1, 2))); +extern char *mkpathdup(const char *fmt, ...) + __attribute__((format (printf, 1, 2))); /* Return a statically allocated filename matching the sha1 signature */ extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); @@ -708,6 +713,7 @@ int set_shared_perm(const char *path, int mode); int safe_create_leading_directories(char *path); int safe_create_leading_directories_const(const char *path); int mkdir_in_gitdir(const char *path); +extern void home_config_paths(char **global, char **xdg, char *file); extern char *expand_user_path(const char *path); const char *enter_repo(const char *path, int strict); static inline int is_absolute_path(const char *path) diff --git a/config.c b/config.c index 71ef171cab..d28a499b0b 100644 --- a/config.c +++ b/config.c @@ -929,7 +929,10 @@ int git_config_system(void) int git_config_early(config_fn_t fn, void *data, const char *repo_config) { int ret = 0, found = 0; - const char *home = NULL; + char *xdg_config = NULL; + char *user_config = NULL; + + home_config_paths(&user_config, &xdg_config, "config"); if (git_config_system() && !access(git_etc_gitconfig(), R_OK)) { ret += git_config_from_file(fn, git_etc_gitconfig(), @@ -937,14 +940,14 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config) found += 1; } - home = getenv("HOME"); - if (home) { - char buf[PATH_MAX]; - char *user_config = mksnpath(buf, sizeof(buf), "%s/.gitconfig", home); - if (!access(user_config, R_OK)) { - ret += git_config_from_file(fn, user_config, data); - found += 1; - } + if (!access(xdg_config, R_OK)) { + ret += git_config_from_file(fn, xdg_config, data); + found += 1; + } + + if (!access(user_config, R_OK)) { + ret += git_config_from_file(fn, user_config, data); + found += 1; } if (repo_config && !access(repo_config, R_OK)) { @@ -963,6 +966,8 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config) break; } + free(xdg_config); + free(user_config); return ret == 0 ? found : ret; } diff --git a/config.mak.in b/config.mak.in index b2ba7104eb..802d34223a 100644 --- a/config.mak.in +++ b/config.mak.in @@ -28,7 +28,6 @@ VPATH = @srcdir@ export exec_prefix mandir export srcdir VPATH -ASCIIDOC7=@ASCIIDOC7@ NEEDS_SSL_WITH_CRYPTO=@NEEDS_SSL_WITH_CRYPTO@ NO_OPENSSL=@NO_OPENSSL@ NO_CURL=@NO_CURL@ diff --git a/configure.ac b/configure.ac index e1255506a6..4e9012f49b 100644 --- a/configure.ac +++ b/configure.ac @@ -437,21 +437,14 @@ if test -n "$ASCIIDOC"; then AC_MSG_CHECKING([for asciidoc version]) asciidoc_version=`$ASCIIDOC --version 2>/dev/null` case "${asciidoc_version}" in - asciidoc' '7*) - ASCIIDOC7=YesPlease - AC_MSG_RESULT([${asciidoc_version} > 7]) - ;; asciidoc' '8*) - ASCIIDOC7= AC_MSG_RESULT([${asciidoc_version}]) ;; *) - ASCIIDOC7= AC_MSG_RESULT([${asciidoc_version} (unknown)]) ;; esac fi -AC_SUBST(ASCIIDOC7) ## Checks for libraries. diff --git a/connect.c b/connect.c index 912cddeea8..55a85adea9 100644 --- a/connect.c +++ b/connect.c @@ -49,6 +49,16 @@ static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1 extra->nr++; } +static void die_initial_contact(int got_at_least_one_head) +{ + if (got_at_least_one_head) + die("The remote end hung up upon initial contact"); + else + die("Could not read from remote repository.\n\n" + "Please make sure you have the correct access rights\n" + "and the repository exists."); +} + /* * Read all the refs from the other end */ @@ -56,6 +66,8 @@ struct ref **get_remote_heads(int in, struct ref **list, unsigned int flags, struct extra_have_objects *extra_have) { + int got_at_least_one_head = 0; + *list = NULL; for (;;) { struct ref *ref; @@ -64,7 +76,10 @@ struct ref **get_remote_heads(int in, struct ref **list, char *name; int len, name_len; - len = packet_read_line(in, buffer, sizeof(buffer)); + len = packet_read(in, buffer, sizeof(buffer)); + if (len < 0) + die_initial_contact(got_at_least_one_head); + if (!len) break; if (buffer[len-1] == '\n') @@ -95,6 +110,7 @@ struct ref **get_remote_heads(int in, struct ref **list, hashcpy(ref->old_sha1, old_sha1); *list = ref; list = &ref->next; + got_at_least_one_head = 1; } return list; } @@ -536,7 +552,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig, * Add support for ssh port: ssh://host.xy:/... */ if (protocol == PROTO_SSH && host != url) - port = get_port(host); + port = get_port(end); if (protocol == PROTO_GIT) { /* These underlying connection commands die() if they diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash old mode 100755 new mode 100644 index 2e1b5e14b9..ffedce751c --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -20,46 +20,8 @@ # 1) Copy this file to somewhere (e.g. ~/.git-completion.sh). # 2) Add the following line to your .bashrc/.zshrc: # source ~/.git-completion.sh -# -# 3) Consider changing your PS1 to also show the current branch: -# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' -# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ ' -# -# The argument to __git_ps1 will be displayed only if you -# are currently in a git repository. The %s token will be -# the name of the current branch. -# -# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty -# value, unstaged (*) and staged (+) changes will be shown next -# to the branch name. You can configure this per-repository -# with the bash.showDirtyState variable, which defaults to true -# once GIT_PS1_SHOWDIRTYSTATE is enabled. -# -# You can also see if currently something is stashed, by setting -# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed, -# then a '$' will be shown next to the branch name. -# -# If you would like to see if there're untracked files, then you can -# set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're -# untracked files, then a '%' will be shown next to the branch name. -# -# If you would like to see the difference between HEAD and its -# upstream, set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates -# you are behind, ">" indicates you are ahead, and "<>" -# indicates you have diverged. You can further control -# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated -# list of values: -# verbose show number of commits ahead/behind (+/-) upstream -# legacy don't use the '--count' option available in recent -# versions of git-rev-list -# git always compare HEAD to @{upstream} -# svn always compare HEAD to your SVN upstream -# By default, __git_ps1 will compare HEAD to your SVN upstream -# if it can find one, or @{upstream} otherwise. Once you have -# set GIT_PS1_SHOWUPSTREAM, you can override it on a -# per-repository basis by setting the bash.showUpstream config -# variable. -# +# 3) Consider changing your PS1 to also show the current branch, +# see git-prompt.sh for details. if [[ -n ${ZSH_VERSION-} ]]; then autoload -U +X bashcompinit && bashcompinit @@ -74,9 +36,14 @@ esac # returns location of .git repo __gitdir () { + # Note: this function is duplicated in git-prompt.sh + # When updating it, make sure you update the other one to match. if [ -z "${1-}" ]; then if [ -n "${__git_dir-}" ]; then echo "$__git_dir" + elif [ -n "${GIT_DIR-}" ]; then + test -d "${GIT_DIR-}" || return 1 + echo "$GIT_DIR" elif [ -d .git ]; then echo .git else @@ -89,221 +56,6 @@ __gitdir () fi } -# stores the divergence from upstream in $p -# used by GIT_PS1_SHOWUPSTREAM -__git_ps1_show_upstream () -{ - local key value - local svn_remote svn_url_pattern count n - local upstream=git legacy="" verbose="" - - svn_remote=() - # get some config options from git-config - local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')" - while read -r key value; do - case "$key" in - bash.showupstream) - GIT_PS1_SHOWUPSTREAM="$value" - if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then - p="" - return - fi - ;; - svn-remote.*.url) - svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value" - svn_url_pattern+="\\|$value" - upstream=svn+git # default upstream is SVN if available, else git - ;; - esac - done <<< "$output" - - # parse configuration values - for option in ${GIT_PS1_SHOWUPSTREAM}; do - case "$option" in - git|svn) upstream="$option" ;; - verbose) verbose=1 ;; - legacy) legacy=1 ;; - esac - done - - # Find our upstream - case "$upstream" in - git) upstream="@{upstream}" ;; - svn*) - # get the upstream from the "git-svn-id: ..." in a commit message - # (git-svn uses essentially the same procedure internally) - local svn_upstream=($(git log --first-parent -1 \ - --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null)) - if [[ 0 -ne ${#svn_upstream[@]} ]]; then - svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]} - svn_upstream=${svn_upstream%@*} - local n_stop="${#svn_remote[@]}" - for ((n=1; n <= n_stop; n++)); do - svn_upstream=${svn_upstream#${svn_remote[$n]}} - done - - if [[ -z "$svn_upstream" ]]; then - # default branch name for checkouts with no layout: - upstream=${GIT_SVN_ID:-git-svn} - else - upstream=${svn_upstream#/} - fi - elif [[ "svn+git" = "$upstream" ]]; then - upstream="@{upstream}" - fi - ;; - esac - - # Find how many commits we are ahead/behind our upstream - if [[ -z "$legacy" ]]; then - count="$(git rev-list --count --left-right \ - "$upstream"...HEAD 2>/dev/null)" - else - # produce equivalent output to --count for older versions of git - local commits - if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)" - then - local commit behind=0 ahead=0 - for commit in $commits - do - case "$commit" in - "<"*) ((behind++)) ;; - *) ((ahead++)) ;; - esac - done - count="$behind $ahead" - else - count="" - fi - fi - - # calculate the result - if [[ -z "$verbose" ]]; then - case "$count" in - "") # no upstream - p="" ;; - "0 0") # equal to upstream - p="=" ;; - "0 "*) # ahead of upstream - p=">" ;; - *" 0") # behind upstream - p="<" ;; - *) # diverged from upstream - p="<>" ;; - esac - else - case "$count" in - "") # no upstream - p="" ;; - "0 0") # equal to upstream - p=" u=" ;; - "0 "*) # ahead of upstream - p=" u+${count#0 }" ;; - *" 0") # behind upstream - p=" u-${count% 0}" ;; - *) # diverged from upstream - p=" u+${count#* }-${count% *}" ;; - esac - fi - -} - - -# __git_ps1 accepts 0 or 1 arguments (i.e., format string) -# returns text to add to bash PS1 prompt (includes branch name) -__git_ps1 () -{ - local g="$(__gitdir)" - if [ -n "$g" ]; then - local r="" - local b="" - if [ -f "$g/rebase-merge/interactive" ]; then - r="|REBASE-i" - b="$(cat "$g/rebase-merge/head-name")" - elif [ -d "$g/rebase-merge" ]; then - r="|REBASE-m" - b="$(cat "$g/rebase-merge/head-name")" - else - if [ -d "$g/rebase-apply" ]; then - if [ -f "$g/rebase-apply/rebasing" ]; then - r="|REBASE" - elif [ -f "$g/rebase-apply/applying" ]; then - r="|AM" - else - r="|AM/REBASE" - fi - elif [ -f "$g/MERGE_HEAD" ]; then - r="|MERGING" - elif [ -f "$g/CHERRY_PICK_HEAD" ]; then - r="|CHERRY-PICKING" - elif [ -f "$g/BISECT_LOG" ]; then - r="|BISECTING" - fi - - b="$(git symbolic-ref HEAD 2>/dev/null)" || { - - b="$( - case "${GIT_PS1_DESCRIBE_STYLE-}" in - (contains) - git describe --contains HEAD ;; - (branch) - git describe --contains --all HEAD ;; - (describe) - git describe HEAD ;; - (* | default) - git describe --tags --exact-match HEAD ;; - esac 2>/dev/null)" || - - b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." || - b="unknown" - b="($b)" - } - fi - - local w="" - local i="" - local s="" - local u="" - local c="" - local p="" - - if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then - if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then - c="BARE:" - else - b="GIT_DIR!" - fi - elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then - if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then - if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then - git diff --no-ext-diff --quiet --exit-code || w="*" - if git rev-parse --quiet --verify HEAD >/dev/null; then - git diff-index --cached --quiet HEAD -- || i="+" - else - i="#" - fi - fi - fi - if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then - git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$" - fi - - if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then - if [ -n "$(git ls-files --others --exclude-standard)" ]; then - u="%" - fi - fi - - if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then - __git_ps1_show_upstream - fi - fi - - local f="$w$i$s$u" - printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p" - fi -} - __gitcomp_1 () { local c IFS=$' \t\n' diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh new file mode 100644 index 0000000000..29b1ec9eb1 --- /dev/null +++ b/contrib/completion/git-prompt.sh @@ -0,0 +1,289 @@ +# bash/zsh git prompt support +# +# Copyright (C) 2006,2007 Shawn O. Pearce +# Distributed under the GNU General Public License, version 2.0. +# +# This script allows you to see the current branch in your prompt. +# +# To enable: +# +# 1) Copy this file to somewhere (e.g. ~/.git-prompt.sh). +# 2) Add the following line to your .bashrc/.zshrc: +# source ~/.git-prompt.sh +# 3) Change your PS1 to also show the current branch: +# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' +# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ ' +# +# The argument to __git_ps1 will be displayed only if you are currently +# in a git repository. The %s token will be the name of the current +# branch. +# +# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty value, +# unstaged (*) and staged (+) changes will be shown next to the branch +# name. You can configure this per-repository with the +# bash.showDirtyState variable, which defaults to true once +# GIT_PS1_SHOWDIRTYSTATE is enabled. +# +# You can also see if currently something is stashed, by setting +# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed, +# then a '$' will be shown next to the branch name. +# +# If you would like to see if there're untracked files, then you can set +# GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're untracked +# files, then a '%' will be shown next to the branch name. +# +# If you would like to see the difference between HEAD and its upstream, +# set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates you are behind, ">" +# indicates you are ahead, and "<>" indicates you have diverged. You +# can further control behaviour by setting GIT_PS1_SHOWUPSTREAM to a +# space-separated list of values: +# +# verbose show number of commits ahead/behind (+/-) upstream +# legacy don't use the '--count' option available in recent +# versions of git-rev-list +# git always compare HEAD to @{upstream} +# svn always compare HEAD to your SVN upstream +# +# By default, __git_ps1 will compare HEAD to your SVN upstream if it can +# find one, or @{upstream} otherwise. Once you have set +# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by +# setting the bash.showUpstream config variable. + +# __gitdir accepts 0 or 1 arguments (i.e., location) +# returns location of .git repo +__gitdir () +{ + # Note: this function is duplicated in git-completion.bash + # When updating it, make sure you update the other one to match. + if [ -z "${1-}" ]; then + if [ -n "${__git_dir-}" ]; then + echo "$__git_dir" + elif [ -n "${GIT_DIR-}" ]; then + test -d "${GIT_DIR-}" || return 1 + echo "$GIT_DIR" + elif [ -d .git ]; then + echo .git + else + git rev-parse --git-dir 2>/dev/null + fi + elif [ -d "$1/.git" ]; then + echo "$1/.git" + else + echo "$1" + fi +} + +# stores the divergence from upstream in $p +# used by GIT_PS1_SHOWUPSTREAM +__git_ps1_show_upstream () +{ + local key value + local svn_remote svn_url_pattern count n + local upstream=git legacy="" verbose="" + + svn_remote=() + # get some config options from git-config + local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')" + while read -r key value; do + case "$key" in + bash.showupstream) + GIT_PS1_SHOWUPSTREAM="$value" + if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then + p="" + return + fi + ;; + svn-remote.*.url) + svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value" + svn_url_pattern+="\\|$value" + upstream=svn+git # default upstream is SVN if available, else git + ;; + esac + done <<< "$output" + + # parse configuration values + for option in ${GIT_PS1_SHOWUPSTREAM}; do + case "$option" in + git|svn) upstream="$option" ;; + verbose) verbose=1 ;; + legacy) legacy=1 ;; + esac + done + + # Find our upstream + case "$upstream" in + git) upstream="@{upstream}" ;; + svn*) + # get the upstream from the "git-svn-id: ..." in a commit message + # (git-svn uses essentially the same procedure internally) + local svn_upstream=($(git log --first-parent -1 \ + --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null)) + if [[ 0 -ne ${#svn_upstream[@]} ]]; then + svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]} + svn_upstream=${svn_upstream%@*} + local n_stop="${#svn_remote[@]}" + for ((n=1; n <= n_stop; n++)); do + svn_upstream=${svn_upstream#${svn_remote[$n]}} + done + + if [[ -z "$svn_upstream" ]]; then + # default branch name for checkouts with no layout: + upstream=${GIT_SVN_ID:-git-svn} + else + upstream=${svn_upstream#/} + fi + elif [[ "svn+git" = "$upstream" ]]; then + upstream="@{upstream}" + fi + ;; + esac + + # Find how many commits we are ahead/behind our upstream + if [[ -z "$legacy" ]]; then + count="$(git rev-list --count --left-right \ + "$upstream"...HEAD 2>/dev/null)" + else + # produce equivalent output to --count for older versions of git + local commits + if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)" + then + local commit behind=0 ahead=0 + for commit in $commits + do + case "$commit" in + "<"*) ((behind++)) ;; + *) ((ahead++)) ;; + esac + done + count="$behind $ahead" + else + count="" + fi + fi + + # calculate the result + if [[ -z "$verbose" ]]; then + case "$count" in + "") # no upstream + p="" ;; + "0 0") # equal to upstream + p="=" ;; + "0 "*) # ahead of upstream + p=">" ;; + *" 0") # behind upstream + p="<" ;; + *) # diverged from upstream + p="<>" ;; + esac + else + case "$count" in + "") # no upstream + p="" ;; + "0 0") # equal to upstream + p=" u=" ;; + "0 "*) # ahead of upstream + p=" u+${count#0 }" ;; + *" 0") # behind upstream + p=" u-${count% 0}" ;; + *) # diverged from upstream + p=" u+${count#* }-${count% *}" ;; + esac + fi + +} + + +# __git_ps1 accepts 0 or 1 arguments (i.e., format string) +# returns text to add to bash PS1 prompt (includes branch name) +__git_ps1 () +{ + local g="$(__gitdir)" + if [ -n "$g" ]; then + local r="" + local b="" + if [ -f "$g/rebase-merge/interactive" ]; then + r="|REBASE-i" + b="$(cat "$g/rebase-merge/head-name")" + elif [ -d "$g/rebase-merge" ]; then + r="|REBASE-m" + b="$(cat "$g/rebase-merge/head-name")" + else + if [ -d "$g/rebase-apply" ]; then + if [ -f "$g/rebase-apply/rebasing" ]; then + r="|REBASE" + elif [ -f "$g/rebase-apply/applying" ]; then + r="|AM" + else + r="|AM/REBASE" + fi + elif [ -f "$g/MERGE_HEAD" ]; then + r="|MERGING" + elif [ -f "$g/CHERRY_PICK_HEAD" ]; then + r="|CHERRY-PICKING" + elif [ -f "$g/BISECT_LOG" ]; then + r="|BISECTING" + fi + + b="$(git symbolic-ref HEAD 2>/dev/null)" || { + + b="$( + case "${GIT_PS1_DESCRIBE_STYLE-}" in + (contains) + git describe --contains HEAD ;; + (branch) + git describe --contains --all HEAD ;; + (describe) + git describe HEAD ;; + (* | default) + git describe --tags --exact-match HEAD ;; + esac 2>/dev/null)" || + + b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." || + b="unknown" + b="($b)" + } + fi + + local w="" + local i="" + local s="" + local u="" + local c="" + local p="" + + if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then + if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then + c="BARE:" + else + b="GIT_DIR!" + fi + elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then + if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then + if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then + git diff --no-ext-diff --quiet --exit-code || w="*" + if git rev-parse --quiet --verify HEAD >/dev/null; then + git diff-index --cached --quiet HEAD -- || i="+" + else + i="#" + fi + fi + fi + if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then + git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$" + fi + + if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then + if [ -n "$(git ls-files --others --exclude-standard)" ]; then + u="%" + fi + fi + + if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then + __git_ps1_show_upstream + fi + fi + + local f="$w$i$s$u" + printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p" + fi +} diff --git a/contrib/emacs/git-blame.el b/contrib/emacs/git-blame.el index d351cfb6e7..e671f6c1c6 100644 --- a/contrib/emacs/git-blame.el +++ b/contrib/emacs/git-blame.el @@ -304,7 +304,7 @@ See also function `git-blame-mode'." (defun git-blame-cleanup () "Remove all blame properties" - (mapcar 'delete-overlay git-blame-overlays) + (mapc 'delete-overlay git-blame-overlays) (setq git-blame-overlays nil) (remove-git-blame-text-properties (point-min) (point-max))) @@ -337,16 +337,16 @@ See also function `git-blame-mode'." (defvar in-blame-filter nil) (defun git-blame-filter (proc str) - (save-excursion - (set-buffer (process-buffer proc)) - (goto-char (process-mark proc)) - (insert-before-markers str) - (goto-char 0) - (unless in-blame-filter - (let ((more t) - (in-blame-filter t)) - (while more - (setq more (git-blame-parse))))))) + (with-current-buffer (process-buffer proc) + (save-excursion + (goto-char (process-mark proc)) + (insert-before-markers str) + (goto-char (point-min)) + (unless in-blame-filter + (let ((more t) + (in-blame-filter t)) + (while more + (setq more (git-blame-parse)))))))) (defun git-blame-parse () (cond ((looking-at "\\([0-9a-f]\\{40\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)\n") @@ -385,32 +385,33 @@ See also function `git-blame-mode'." info)))) (defun git-blame-create-overlay (info start-line num-lines) - (save-excursion - (set-buffer git-blame-file) - (let ((inhibit-point-motion-hooks t) - (inhibit-modification-hooks t)) - (goto-line start-line) - (let* ((start (point)) - (end (progn (forward-line num-lines) (point))) - (ovl (make-overlay start end)) - (hash (car info)) - (spec `((?h . ,(substring hash 0 6)) - (?H . ,hash) - (?a . ,(git-blame-get-info info 'author)) - (?A . ,(git-blame-get-info info 'author-mail)) - (?c . ,(git-blame-get-info info 'committer)) - (?C . ,(git-blame-get-info info 'committer-mail)) - (?s . ,(git-blame-get-info info 'summary))))) - (push ovl git-blame-overlays) - (overlay-put ovl 'git-blame info) - (overlay-put ovl 'help-echo - (format-spec git-blame-mouseover-format spec)) - (if git-blame-use-colors - (overlay-put ovl 'face (list :background - (cdr (assq 'color (cdr info)))))) - (overlay-put ovl 'line-prefix - (propertize (format-spec git-blame-prefix-format spec) - 'face 'git-blame-prefix-face)))))) + (with-current-buffer git-blame-file + (save-excursion + (let ((inhibit-point-motion-hooks t) + (inhibit-modification-hooks t)) + (goto-char (point-min)) + (forward-line (1- start-line)) + (let* ((start (point)) + (end (progn (forward-line num-lines) (point))) + (ovl (make-overlay start end)) + (hash (car info)) + (spec `((?h . ,(substring hash 0 6)) + (?H . ,hash) + (?a . ,(git-blame-get-info info 'author)) + (?A . ,(git-blame-get-info info 'author-mail)) + (?c . ,(git-blame-get-info info 'committer)) + (?C . ,(git-blame-get-info info 'committer-mail)) + (?s . ,(git-blame-get-info info 'summary))))) + (push ovl git-blame-overlays) + (overlay-put ovl 'git-blame info) + (overlay-put ovl 'help-echo + (format-spec git-blame-mouseover-format spec)) + (if git-blame-use-colors + (overlay-put ovl 'face (list :background + (cdr (assq 'color (cdr info)))))) + (overlay-put ovl 'line-prefix + (propertize (format-spec git-blame-prefix-format spec) + 'face 'git-blame-prefix-face))))))) (defun git-blame-add-info (info key value) (nconc info (list (cons (intern key) value)))) diff --git a/contrib/mw-to-git/git-remote-mediawiki b/contrib/mw-to-git/git-remote-mediawiki index c18bfa1f15..c07b4f0ee6 100755 --- a/contrib/mw-to-git/git-remote-mediawiki +++ b/contrib/mw-to-git/git-remote-mediawiki @@ -26,9 +26,6 @@ # - Git renames could be turned into MediaWiki renames (see TODO # below) # -# - login/password support requires the user to write the password -# cleartext in a file (see TODO below). -# # - No way to import "one page, and all pages included in it" # # - Multiple remote MediaWikis have not been very well tested. @@ -43,6 +40,8 @@ use encoding 'utf8'; binmode STDERR, ":utf8"; use URI::Escape; +use IPC::Open2; + use warnings; # Mediawiki filenames can contain forward slashes. This variable decides by which pattern they should be replaced @@ -72,9 +71,7 @@ my @tracked_categories = split(/[ \n]/, run_git("config --get-all remote.". $rem chomp(@tracked_categories); my $wiki_login = run_git("config --get remote.". $remotename .".mwLogin"); -# TODO: ideally, this should be able to read from keyboard, but we're -# inside a remote helper, so our stdin is connect to git, not to a -# terminal. +# Note: mwPassword is discourraged. Use the credential system instead. my $wiki_passwd = run_git("config --get remote.". $remotename .".mwPassword"); my $wiki_domain = run_git("config --get remote.". $remotename .".mwDomain"); chomp($wiki_login); @@ -151,28 +148,108 @@ while () { ########################## Functions ############################## +## credential API management (generic functions) + +sub credential_from_url { + my $url = shift; + my $parsed = URI->new($url); + my %credential; + + if ($parsed->scheme) { + $credential{protocol} = $parsed->scheme; + } + if ($parsed->host) { + $credential{host} = $parsed->host; + } + if ($parsed->path) { + $credential{path} = $parsed->path; + } + if ($parsed->userinfo) { + if ($parsed->userinfo =~ /([^:]*):(.*)/) { + $credential{username} = $1; + $credential{password} = $2; + } else { + $credential{username} = $parsed->userinfo; + } + } + + return %credential; +} + +sub credential_read { + my %credential; + my $reader = shift; + my $op = shift; + while (<$reader>) { + my ($key, $value) = /([^=]*)=(.*)/; + if (not defined $key) { + die "ERROR receiving response from git credential $op:\n$_\n"; + } + $credential{$key} = $value; + } + return %credential; +} + +sub credential_write { + my $credential = shift; + my $writer = shift; + while (my ($key, $value) = each(%$credential) ) { + if ($value) { + print $writer "$key=$value\n"; + } + } +} + +sub credential_run { + my $op = shift; + my $credential = shift; + my $pid = open2(my $reader, my $writer, "git credential $op"); + credential_write($credential, $writer); + print $writer "\n"; + close($writer); + + if ($op eq "fill") { + %$credential = credential_read($reader, $op); + } else { + if (<$reader>) { + die "ERROR while running git credential $op:\n$_"; + } + } + close($reader); + waitpid($pid, 0); + my $child_exit_status = $? >> 8; + if ($child_exit_status != 0) { + die "'git credential $op' failed with code $child_exit_status."; + } +} + # MediaWiki API instance, created lazily. my $mediawiki; sub mw_connect_maybe { if ($mediawiki) { - return; + return; } $mediawiki = MediaWiki::API->new; $mediawiki->{config}->{api_url} = "$url/api.php"; if ($wiki_login) { - if (!$mediawiki->login({ - lgname => $wiki_login, - lgpassword => $wiki_passwd, - lgdomain => $wiki_domain, - })) { - print STDERR "Failed to log in mediawiki user \"$wiki_login\" on $url\n"; - print STDERR "(error " . - $mediawiki->{error}->{code} . ': ' . - $mediawiki->{error}->{details} . ")\n"; - exit 1; + my %credential = credential_from_url($url); + $credential{username} = $wiki_login; + $credential{password} = $wiki_passwd; + credential_run("fill", \%credential); + my $request = {lgname => $credential{username}, + lgpassword => $credential{password}, + lgdomain => $wiki_domain}; + if ($mediawiki->login($request)) { + credential_run("approve", \%credential); + print STDERR "Logged in mediawiki user \"$credential{username}\".\n"; } else { - print STDERR "Logged in with user \"$wiki_login\".\n"; + print STDERR "Failed to log in mediawiki user \"$credential{username}\" on $url\n"; + print STDERR " (error " . + $mediawiki->{error}->{code} . ': ' . + $mediawiki->{error}->{details} . ")\n"; + credential_run("reject", \%credential); + exit 1; } } } diff --git a/credential.c b/credential.c index 62d1c56819..2c400073fa 100644 --- a/credential.c +++ b/credential.c @@ -191,7 +191,7 @@ static void credential_write_item(FILE *fp, const char *key, const char *value) fprintf(fp, "%s=%s\n", key, value); } -static void credential_write(const struct credential *c, FILE *fp) +void credential_write(const struct credential *c, FILE *fp) { credential_write_item(fp, "protocol", c->protocol); credential_write_item(fp, "host", c->host); diff --git a/credential.h b/credential.h index 96ea41bd1c..0c3e85e8e4 100644 --- a/credential.h +++ b/credential.h @@ -26,6 +26,7 @@ void credential_approve(struct credential *); void credential_reject(struct credential *); int credential_read(struct credential *, FILE *); +void credential_write(const struct credential *, FILE *); void credential_from_url(struct credential *, const char *url); int credential_match(const struct credential *have, const struct credential *want); diff --git a/diff-no-index.c b/diff-no-index.c index f0b0010aed..beec49b5ac 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -151,23 +151,6 @@ static int queue_diff(struct diff_options *o, } } -static int path_outside_repo(const char *path) -{ - const char *work_tree; - size_t len; - - if (!is_absolute_path(path)) - return 0; - work_tree = get_git_work_tree(); - if (!work_tree) - return 1; - len = strlen(work_tree); - if (strncmp(path, work_tree, len) || - (path[len] != '\0' && path[len] != '/')) - return 1; - return 0; -} - void diff_no_index(struct rev_info *revs, int argc, const char **argv, int nongit, const char *prefix) @@ -197,8 +180,8 @@ void diff_no_index(struct rev_info *revs, * a colourful "diff" replacement. */ if ((argc != i + 2) || - (!path_outside_repo(argv[i]) && - !path_outside_repo(argv[i+1]))) + (path_inside_repo(prefix, argv[i]) && + path_inside_repo(prefix, argv[i+1]))) return; } if (argc != i + 2) @@ -224,13 +207,6 @@ void diff_no_index(struct rev_info *revs, } } - /* - * If the user asked for our exit code then don't start a - * pager or we would end up reporting its exit code instead. - */ - if (!DIFF_OPT_TST(&revs->diffopt, EXIT_WITH_STATUS)) - setup_pager(); - if (prefix) { int len = strlen(prefix); const char *paths[3]; @@ -255,13 +231,15 @@ void diff_no_index(struct rev_info *revs, if (!revs->diffopt.output_format) revs->diffopt.output_format = DIFF_FORMAT_PATCH; - DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); DIFF_OPT_SET(&revs->diffopt, NO_INDEX); revs->max_count = -2; if (diff_setup_done(&revs->diffopt) < 0) die("diff_setup_done failed"); + setup_diff_pager(&revs->diffopt); + DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); + if (queue_diff(&revs->diffopt, revs->diffopt.pathspec.raw[0], revs->diffopt.pathspec.raw[1])) exit(1); @@ -273,5 +251,5 @@ void diff_no_index(struct rev_info *revs, * The return code for --no-index imitates diff(1): * 0 = no changes, 1 = changes, else error */ - exit(revs->diffopt.found_changes); + exit(diff_result_code(&revs->diffopt, 0)); } diff --git a/dir.c b/dir.c index ed1510fbc8..a772c6dc6c 100644 --- a/dir.c +++ b/dir.c @@ -288,9 +288,24 @@ int match_pathspec_depth(const struct pathspec *ps, return retval; } +/* + * Return the length of the "simple" part of a path match limiter. + */ +static int simple_length(const char *match) +{ + int len = -1; + + for (;;) { + unsigned char c = *match++; + len++; + if (c == '\0' || is_glob_special(c)) + return len; + } +} + static int no_wildcard(const char *string) { - return string[strcspn(string, "*?[{\\")] == '\0'; + return string[simple_length(string)] == '\0'; } void add_exclude(const char *string, const char *base, @@ -326,8 +341,7 @@ void add_exclude(const char *string, const char *base, x->flags = flags; if (!strchr(string, '/')) x->flags |= EXC_FLAG_NODIR; - if (no_wildcard(string)) - x->flags |= EXC_FLAG_NOWILDCARD; + x->nowildcardlen = simple_length(string); if (*string == '*' && no_wildcard(string+1)) x->flags |= EXC_FLAG_ENDSWITH; ALLOC_GROW(which->excludes, which->nr + 1, which->alloc); @@ -498,62 +512,74 @@ int excluded_from_list(const char *pathname, { int i; - if (el->nr) { - for (i = el->nr - 1; 0 <= i; i--) { - struct exclude *x = el->excludes[i]; - const char *exclude = x->pattern; - int to_exclude = x->to_exclude; - - if (x->flags & EXC_FLAG_MUSTBEDIR) { - if (*dtype == DT_UNKNOWN) - *dtype = get_dtype(NULL, pathname, pathlen); - if (*dtype != DT_DIR) - continue; - } + if (!el->nr) + return -1; /* undefined */ - if (x->flags & EXC_FLAG_NODIR) { - /* match basename */ - if (x->flags & EXC_FLAG_NOWILDCARD) { - if (!strcmp_icase(exclude, basename)) - return to_exclude; - } else if (x->flags & EXC_FLAG_ENDSWITH) { - if (x->patternlen - 1 <= pathlen && - !strcmp_icase(exclude + 1, pathname + pathlen - x->patternlen + 1)) - return to_exclude; - } else { - if (fnmatch_icase(exclude, basename, 0) == 0) - return to_exclude; - } - } - else { - /* match with FNM_PATHNAME: - * exclude has base (baselen long) implicitly - * in front of it. - */ - int baselen = x->baselen; - if (*exclude == '/') - exclude++; - - if (pathlen < baselen || - (baselen && pathname[baselen-1] != '/') || - strncmp_icase(pathname, x->base, baselen)) - continue; - - if (x->flags & EXC_FLAG_NOWILDCARD) { - if (!strcmp_icase(exclude, pathname + baselen)) - return to_exclude; - } else { - if (fnmatch_icase(exclude, pathname+baselen, - FNM_PATHNAME) == 0) - return to_exclude; - } + for (i = el->nr - 1; 0 <= i; i--) { + struct exclude *x = el->excludes[i]; + const char *name, *exclude = x->pattern; + int to_exclude = x->to_exclude; + int namelen, prefix = x->nowildcardlen; + + if (x->flags & EXC_FLAG_MUSTBEDIR) { + if (*dtype == DT_UNKNOWN) + *dtype = get_dtype(NULL, pathname, pathlen); + if (*dtype != DT_DIR) + continue; + } + + if (x->flags & EXC_FLAG_NODIR) { + /* match basename */ + if (prefix == x->patternlen) { + if (!strcmp_icase(exclude, basename)) + return to_exclude; + } else if (x->flags & EXC_FLAG_ENDSWITH) { + if (x->patternlen - 1 <= pathlen && + !strcmp_icase(exclude + 1, pathname + pathlen - x->patternlen + 1)) + return to_exclude; + } else { + if (fnmatch_icase(exclude, basename, 0) == 0) + return to_exclude; } + continue; + } + + /* match with FNM_PATHNAME: + * exclude has base (baselen long) implicitly in front of it. + */ + if (*exclude == '/') { + exclude++; + prefix--; + } + + if (pathlen < x->baselen || + (x->baselen && pathname[x->baselen-1] != '/') || + strncmp_icase(pathname, x->base, x->baselen)) + continue; + + namelen = x->baselen ? pathlen - x->baselen : pathlen; + name = pathname + pathlen - namelen; + + /* if the non-wildcard part is longer than the + remaining pathname, surely it cannot match */ + if (prefix > namelen) + continue; + + if (prefix) { + if (strncmp_icase(exclude, name, prefix)) + continue; + exclude += prefix; + name += prefix; + namelen -= prefix; } + + if (!namelen || !fnmatch_icase(exclude, name, FNM_PATHNAME)) + return to_exclude; } return -1; /* undecided */ } -int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p) +static int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p) { int pathlen = strlen(pathname); int st; @@ -573,6 +599,64 @@ int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p) return 0; } +void path_exclude_check_init(struct path_exclude_check *check, + struct dir_struct *dir) +{ + check->dir = dir; + strbuf_init(&check->path, 256); +} + +void path_exclude_check_clear(struct path_exclude_check *check) +{ + strbuf_release(&check->path); +} + +/* + * Is this name excluded? This is for a caller like show_files() that + * do not honor directory hierarchy and iterate through paths that are + * possibly in an ignored directory. + * + * A path to a directory known to be excluded is left in check->path to + * optimize for repeated checks for files in the same excluded directory. + */ +int path_excluded(struct path_exclude_check *check, + const char *name, int namelen, int *dtype) +{ + int i; + struct strbuf *path = &check->path; + + /* + * we allow the caller to pass namelen as an optimization; it + * must match the length of the name, as we eventually call + * excluded() on the whole name string. + */ + if (namelen < 0) + namelen = strlen(name); + + if (path->len && + path->len <= namelen && + !memcmp(name, path->buf, path->len) && + (!name[path->len] || name[path->len] == '/')) + return 1; + + strbuf_setlen(path, 0); + for (i = 0; name[i]; i++) { + int ch = name[i]; + + if (ch == '/') { + int dt = DT_DIR; + if (excluded(check->dir, path->buf, &dt)) + return 1; + } + strbuf_addch(path, ch); + } + + /* An entry in the index; cannot be a directory with subentries */ + strbuf_setlen(path, 0); + + return excluded(check->dir, name, dtype); +} + static struct dir_entry *dir_entry_new(const char *pathname, int len) { struct dir_entry *ent; @@ -997,21 +1081,6 @@ static int cmp_name(const void *p1, const void *p2) e2->name, e2->len); } -/* - * Return the length of the "simple" part of a path match limiter. - */ -static int simple_length(const char *match) -{ - int len = -1; - - for (;;) { - unsigned char c = *match++; - len++; - if (c == '\0' || is_glob_special(c)) - return len; - } -} - static struct path_simplify *create_simplify(const char **pathspec) { int nr, alloc = 0; @@ -1234,12 +1303,17 @@ int remove_dir_recursively(struct strbuf *path, int flag) void setup_standard_excludes(struct dir_struct *dir) { const char *path; + char *xdg_path; dir->exclude_per_dir = ".gitignore"; path = git_path("info/exclude"); + if (!excludes_file) { + home_config_paths(NULL, &xdg_path, "ignore"); + excludes_file = xdg_path; + } if (!access(path, R_OK)) add_excludes_from_file(dir, path); - if (excludes_file && !access(excludes_file, R_OK)) + if (!access(excludes_file, R_OK)) add_excludes_from_file(dir, excludes_file); } diff --git a/dir.h b/dir.h index 58b6fc7c86..893465a1e8 100644 --- a/dir.h +++ b/dir.h @@ -1,13 +1,14 @@ #ifndef DIR_H #define DIR_H +#include "strbuf.h" + struct dir_entry { unsigned int len; char name[FLEX_ARRAY]; /* more */ }; #define EXC_FLAG_NODIR 1 -#define EXC_FLAG_NOWILDCARD 2 #define EXC_FLAG_ENDSWITH 4 #define EXC_FLAG_MUSTBEDIR 8 @@ -17,6 +18,7 @@ struct exclude_list { struct exclude { const char *pattern; int patternlen; + int nowildcardlen; const char *base; int baselen; int to_exclude; @@ -76,8 +78,22 @@ extern int read_directory(struct dir_struct *, const char *path, int len, const extern int excluded_from_list(const char *pathname, int pathlen, const char *basename, int *dtype, struct exclude_list *el); -extern int excluded(struct dir_struct *, const char *, int *); struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len); + +/* + * The excluded() API is meant for callers that check each level of leading + * directory hierarchies with excluded() to avoid recursing into excluded + * directories. Callers that do not do so should use this API instead. + */ +struct path_exclude_check { + struct dir_struct *dir; + struct strbuf path; +}; +extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *); +extern void path_exclude_check_clear(struct path_exclude_check *); +extern int path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype); + + extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, char **buf_p, struct exclude_list *which, int check_index); extern void add_excludes_from_file(struct dir_struct *, const char *fname); diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 0c19b7c753..5f566726ab 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -684,6 +684,27 @@ rearrange_squash () { rm -f "$1.sq" "$1.rearranged" } +# Add commands after a pick or after a squash/fixup serie +# in the todo list. +add_exec_commands () { + { + first=t + while read -r insn rest + do + case $insn in + pick) + test -n "$first" || + printf "%s" "$cmd" + ;; + esac + printf "%s %s\n" "$insn" "$rest" + first= + done + printf "%s" "$cmd" + } <"$1" >"$1.new" && + mv "$1.new" "$1" +} + case "$action" in continue) # do we have anything to commit? @@ -857,6 +878,8 @@ fi test -s "$todo" || echo noop >> "$todo" test -n "$autosquash" && rearrange_squash "$todo" +test -n "$cmd" && add_exec_commands "$todo" + cat >> "$todo" << EOF # Rebase $shortrevisions onto $shortonto diff --git a/git-rebase.sh b/git-rebase.sh index e616737444..6bd8eae648 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -3,7 +3,8 @@ # Copyright (c) 2005 Junio C Hamano. # -USAGE='[--interactive | -i] [-v] [--force-rebase | -f] [--no-ff] [--onto ] [|--root] [] [--quiet | -q]' +USAGE='[--interactive | -i] [--exec | -x ] [-v] [--force-rebase | -f] + [--no-ff] [--onto ] [|--root] [] [--quiet | -q]' LONG_USAGE='git-rebase replaces with a new branch of the same name. When the --onto option is provided the new branch starts out with a HEAD equal to , otherwise it is equal to @@ -30,8 +31,8 @@ Example: git-rebase master~1 topic SUBDIRECTORY_OK=Yes OPTIONS_KEEPDASHDASH= OPTIONS_SPEC="\ -git rebase [-i] [options] [--onto ] [] [] -git rebase [-i] [options] --onto --root [] +git rebase [-i] [options] [--exec ] [--onto ] [] [] +git rebase [-i] [options] [--exec ] --onto --root [] git-rebase [-i] --continue | --abort | --skip -- Available options are @@ -43,6 +44,7 @@ s,strategy=! use the given merge strategy no-ff! cherry-pick all commits, even if unchanged m,merge! use merging strategies to rebase i,interactive! let the user edit the list of commits to rebase +x,exec=! add exec lines after each commit of the editable list k,keep-empty preserve empty commits during rebase f,force-rebase! force rebase even if branch is up to date X,strategy-option=! pass the argument through to the merge strategy @@ -76,6 +78,7 @@ If you would prefer to skip this patch, instead run \"git rebase --skip\". To check out the original branch and stop rebasing run \"git rebase --abort\". " unset onto +cmd= strategy= strategy_opts= do_merge= @@ -220,6 +223,11 @@ do onto="$2" shift ;; + -x) + test 2 -le "$#" || usage + cmd="${cmd}exec $2${LF}" + shift + ;; -i) interactive_rebase=explicit ;; @@ -305,6 +313,12 @@ do done test $# -gt 2 && usage +if test -n "$cmd" && + test "$interactive_rebase" != explicit +then + die "--exec option must be used with --interactive option" +fi + if test -n "$action" then test -z "$in_progress" && die "No rebase in progress?" diff --git a/git-request-pull.sh b/git-request-pull.sh index e6438e24c7..d566015975 100755 --- a/git-request-pull.sh +++ b/git-request-pull.sh @@ -57,9 +57,13 @@ headrev=$(git rev-parse --verify "$head"^0) || exit merge_base=$(git merge-base $baserev $headrev) || die "fatal: No commits in common between $base and $head" -# $head is the token given from the command line. If a ref with that -# name exists at the remote and their values match, we should use it. -# Otherwise find a ref that matches $headrev. +# $head is the token given from the command line, and $tag_name, if +# exists, is the tag we are going to show the commit information for. +# If that tag exists at the remote and it points at the commit, use it. +# Otherwise, if a branch with the same name as $head exists at the remote +# and their values match, use that instead. +# +# Otherwise find a random ref that matches $headrev. find_matching_ref=' sub abbr { my $ref = shift; @@ -70,24 +74,29 @@ find_matching_ref=' } } - my ($exact, $found); + my ($tagged, $branch, $found); while () { my ($sha1, $ref, $deref) = /^(\S+)\s+(\S+?)(\^\{\})?$/; next unless ($sha1 eq $ARGV[1]); $found = abbr($ref); + if ($deref && $ref eq "tags/$ARGV[2]") { + $tagged = $found; + last; + } if ($ref =~ m|/\Q$ARGV[0]\E$|) { $exact = $found; - last; } } - if ($exact) { + if ($tagged) { + print "$tagged\n"; + } elsif ($exact) { print "$exact\n"; } elsif ($found) { print "$found\n"; } ' -ref=$(git ls-remote "$url" | perl -e "$find_matching_ref" "$head" "$headrev") +ref=$(git ls-remote "$url" | perl -e "$find_matching_ref" "$head" "$headrev" "$tag_name") url=$(git ls-remote --get-url "$url") @@ -114,6 +123,12 @@ fi && if test -n "$tag_name" then + if test -z "$ref" || test "$ref" != "tags/$tag_name" + then + echo >&2 "warn: You locally have $tag_name but it does not (yet)" + echo >&2 "warn: appear to be at $url" + echo >&2 "warn: Do you want to push it there, perhaps?" + fi git cat-file tag "$tag_name" | sed -n -e '1,/^$/d' -e '/^-----BEGIN PGP /q' -e p echo diff --git a/git-submodule.sh b/git-submodule.sh index fbf2fafaaf..5629d875e6 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -30,7 +30,22 @@ nofetch= update= prefix= -# Resolve relative url by appending to parent's url +# The function takes at most 2 arguments. The first argument is the +# URL that navigates to the submodule origin repo. When relative, this URL +# is relative to the superproject origin URL repo. The second up_path +# argument, if specified, is the relative path that navigates +# from the submodule working tree to the superproject working tree. +# +# The output of the function is the origin URL of the submodule. +# +# The output will either be an absolute URL or filesystem path (if the +# superproject origin URL is an absolute URL or filesystem path, +# respectively) or a relative file system path (if the superproject +# origin URL is a relative file system path). +# +# When the output is a relative file system path, the path is either +# relative to the submodule working tree, if up_path is specified, or to +# the superproject working tree otherwise. resolve_relative_url () { remote=$(get_default_remote) @@ -39,6 +54,21 @@ resolve_relative_url () url="$1" remoteurl=${remoteurl%/} sep=/ + up_path="$2" + + case "$remoteurl" in + *:*|/*) + is_relative= + ;; + ./*|../*) + is_relative=t + ;; + *) + is_relative=t + remoteurl="./$remoteurl" + ;; + esac + while test -n "$url" do case "$url" in @@ -53,7 +83,12 @@ resolve_relative_url () sep=: ;; *) - die "$(eval_gettext "cannot strip one component off url '\$remoteurl'")" + if test -z "$is_relative" || test "." = "$remoteurl" + then + die "$(eval_gettext "cannot strip one component off url '\$remoteurl'")" + else + remoteurl=. + fi ;; esac ;; @@ -64,7 +99,8 @@ resolve_relative_url () break;; esac done - echo "$remoteurl$sep${url%/}" + remoteurl="$remoteurl$sep${url%/}" + echo "${is_relative:+${up_path}}${remoteurl#./}" } # @@ -965,14 +1001,26 @@ cmd_sync() # Possibly a url relative to parent case "$url" in ./*|../*) - url=$(resolve_relative_url "$url") || exit + # rewrite foo/bar as ../.. to find path from + # submodule work tree to superproject work tree + up_path="$(echo "$sm_path" | sed "s/[^/][^/]*/../g")" && + # guarantee a trailing / + up_path=${up_path%/}/ && + # path from submodule work tree to submodule origin repo + sub_origin_url=$(resolve_relative_url "$url" "$up_path") && + # path from superproject work tree to submodule origin repo + super_config_url=$(resolve_relative_url "$url") || exit + ;; + *) + sub_origin_url="$url" + super_config_url="$url" ;; esac if git config "submodule.$name.url" >/dev/null 2>/dev/null then say "$(eval_gettext "Synchronizing submodule url for '\$name'")" - git config submodule."$name".url "$url" + git config submodule."$name".url "$super_config_url" if test -e "$sm_path"/.git then @@ -980,7 +1028,7 @@ cmd_sync() clear_local_git_env cd "$sm_path" remote=$(get_default_remote) - git config remote."$remote".url "$url" + git config remote."$remote".url "$sub_origin_url" ) fi fi diff --git a/git.c b/git.c index d232de92e4..8788b32ccd 100644 --- a/git.c +++ b/git.c @@ -256,8 +256,6 @@ static int handle_alias(int *argcp, const char ***argv) return ret; } -const char git_version_string[] = GIT_VERSION; - #define RUN_SETUP (1<<0) #define RUN_SETUP_GENTLY (1<<1) #define USE_PAGER (1<<2) @@ -353,6 +351,7 @@ static void handle_internal_command(int argc, const char **argv) { "commit-tree", cmd_commit_tree, RUN_SETUP }, { "config", cmd_config, RUN_SETUP_GENTLY }, { "count-objects", cmd_count_objects, RUN_SETUP }, + { "credential", cmd_credential, RUN_SETUP_GENTLY }, { "describe", cmd_describe, RUN_SETUP }, { "diff", cmd_diff }, { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE }, diff --git a/help.c b/help.c index 6012c07b73..662349dd56 100644 --- a/help.c +++ b/help.c @@ -6,6 +6,7 @@ #include "common-cmds.h" #include "string-list.h" #include "column.h" +#include "version.h" void add_cmdname(struct cmdnames *cmds, const char *name, int len) { diff --git a/http.c b/http.c index 5cb87f16f2..b61ac85d4b 100644 --- a/http.c +++ b/http.c @@ -4,6 +4,7 @@ #include "run-command.h" #include "url.h" #include "credential.h" +#include "version.h" int active_requests; int http_is_verbose; @@ -299,7 +300,7 @@ static CURL *get_curl_handle(void) curl_easy_setopt(result, CURLOPT_VERBOSE, 1); curl_easy_setopt(result, CURLOPT_USERAGENT, - user_agent ? user_agent : GIT_HTTP_USER_AGENT); + user_agent ? user_agent : git_user_agent()); if (curl_ftp_no_epsv) curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0); diff --git a/notes-merge.c b/notes-merge.c index 74aa77ce4b..29c6411fc6 100644 --- a/notes-merge.c +++ b/notes-merge.c @@ -524,8 +524,10 @@ static int merge_from_diffs(struct notes_merge_options *o, free(changes); if (o->verbosity >= 4) - printf("Merge result: %i unmerged notes and a %s notes tree\n", - conflicts, t->dirty ? "dirty" : "clean"); + printf(t->dirty ? + "Merge result: %i unmerged notes and a dirty notes tree\n" : + "Merge result: %i unmerged notes and a clean notes tree\n", + conflicts); return conflicts ? -1 : 1; } diff --git a/path.c b/path.c index 6f2aa699ad..66acd24fa8 100644 --- a/path.c +++ b/path.c @@ -87,6 +87,21 @@ char *git_pathdup(const char *fmt, ...) return xstrdup(path); } +char *mkpathdup(const char *fmt, ...) +{ + char *path; + struct strbuf sb = STRBUF_INIT; + va_list args; + + va_start(args, fmt); + strbuf_vaddf(&sb, fmt, args); + va_end(args); + path = xstrdup(cleanup_path(sb.buf)); + + strbuf_release(&sb); + return path; +} + char *mkpath(const char *fmt, ...) { va_list args; @@ -122,6 +137,32 @@ char *git_path(const char *fmt, ...) return cleanup_path(pathname); } +void home_config_paths(char **global, char **xdg, char *file) +{ + char *xdg_home = getenv("XDG_CONFIG_HOME"); + char *home = getenv("HOME"); + char *to_free = NULL; + + if (!home) { + if (global) + *global = NULL; + } else { + if (!xdg_home) { + to_free = mkpathdup("%s/.config", home); + xdg_home = to_free; + } + if (global) + *global = mkpathdup("%s/.gitconfig", home); + } + + if (!xdg_home) + *xdg = NULL; + else + *xdg = mkpathdup("%s/git/%s", xdg_home, file); + + free(to_free); +} + char *git_path_submodule(const char *path, const char *fmt, ...) { char *pathname = get_pathname(); diff --git a/perl/Makefile b/perl/Makefile index fe7a486464..6ca7d472eb 100644 --- a/perl/Makefile +++ b/perl/Makefile @@ -34,22 +34,34 @@ modules += Git/SVN/Ra $(makfile): ../GIT-CFLAGS Makefile echo all: private-Error.pm Git.pm Git/I18N.pm > $@ - echo ' mkdir -p blib/lib/Git/SVN/Memoize' >> $@ set -e; \ for i in $(modules); \ do \ + if test $$i = $${i%/*}; \ + then \ + subdir=; \ + else \ + subdir=/$${i%/*}; \ + fi; \ echo ' $(RM) blib/lib/'$$i'.pm' >> $@; \ + echo ' mkdir -p blib/lib'$$subdir >> $@; \ echo ' cp '$$i'.pm blib/lib/'$$i'.pm' >> $@; \ done echo ' $(RM) blib/lib/Error.pm' >> $@ '$(PERL_PATH_SQ)' -MError -e 'exit($$Error::VERSION < 0.15009)' || \ echo ' cp private-Error.pm blib/lib/Error.pm' >> $@ echo install: >> $@ - echo ' mkdir -p "$$(DESTDIR)$(instdir_SQ)/Git/SVN/Memoize"' >> $@ set -e; \ for i in $(modules); \ do \ + if test $$i = $${i%/*}; \ + then \ + subdir=; \ + else \ + subdir=/$${i%/*}; \ + fi; \ echo ' $(RM) "$$(DESTDIR)$(instdir_SQ)/'$$i'.pm"' >> $@; \ + echo ' mkdir -p "$$(DESTDIR)$(instdir_SQ)'$$subdir'"' >> $@; \ echo ' cp '$$i'.pm "$$(DESTDIR)$(instdir_SQ)/'$$i'.pm"' >> $@; \ done echo ' $(RM) "$$(DESTDIR)$(instdir_SQ)/Error.pm"' >> $@ diff --git a/pkt-line.c b/pkt-line.c index 5a04984ea3..eaba15f124 100644 --- a/pkt-line.c +++ b/pkt-line.c @@ -135,13 +135,19 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...) strbuf_add(buf, buffer, n); } -static void safe_read(int fd, void *buffer, unsigned size) +static int safe_read(int fd, void *buffer, unsigned size, int return_line_fail) { ssize_t ret = read_in_full(fd, buffer, size); if (ret < 0) die_errno("read error"); - else if (ret < size) + else if (ret < size) { + if (return_line_fail) + return -1; + die("The remote end hung up unexpectedly"); + } + + return ret; } static int packet_length(const char *linelen) @@ -169,12 +175,14 @@ static int packet_length(const char *linelen) return len; } -int packet_read_line(int fd, char *buffer, unsigned size) +static int packet_read_internal(int fd, char *buffer, unsigned size, int return_line_fail) { - int len; + int len, ret; char linelen[4]; - safe_read(fd, linelen, 4); + ret = safe_read(fd, linelen, 4, return_line_fail); + if (return_line_fail && ret < 0) + return ret; len = packet_length(linelen); if (len < 0) die("protocol error: bad line length character: %.4s", linelen); @@ -185,12 +193,24 @@ int packet_read_line(int fd, char *buffer, unsigned size) len -= 4; if (len >= size) die("protocol error: bad line length %d", len); - safe_read(fd, buffer, len); + ret = safe_read(fd, buffer, len, return_line_fail); + if (return_line_fail && ret < 0) + return ret; buffer[len] = 0; packet_trace(buffer, len, 0); return len; } +int packet_read(int fd, char *buffer, unsigned size) +{ + return packet_read_internal(fd, buffer, size, 1); +} + +int packet_read_line(int fd, char *buffer, unsigned size) +{ + return packet_read_internal(fd, buffer, size, 0); +} + int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len) { diff --git a/pkt-line.h b/pkt-line.h index 1e5dcfe87c..8cfeb0c31c 100644 --- a/pkt-line.h +++ b/pkt-line.h @@ -13,6 +13,7 @@ void packet_buf_flush(struct strbuf *buf); void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3))); int packet_read_line(int fd, char *buffer, unsigned size); +int packet_read(int fd, char *buffer, unsigned size); int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len); ssize_t safe_write(int, const void *, ssize_t); diff --git a/po/sv.po b/po/sv.po index 3a9059258a..b0ff6f99a7 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: git 1.7.10\n" "Report-Msgid-Bugs-To: Git Mailing List \n" -"POT-Creation-Date: 2012-05-15 06:31+0800\n" -"PO-Revision-Date: 2012-05-28 22:35+0100\n" +"POT-Creation-Date: 2012-06-08 10:20+0800\n" +"PO-Revision-Date: 2012-07-01 22:59+0100\n" "Last-Translator: Peter Krefting \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -38,12 +38,86 @@ msgstr "" "lämpligt för att ange lösning och checka in,\n" "eller använd \"git commit -a\"." -#: commit.c:47 +#: bundle.c:36 +#, c-format +msgid "'%s' does not look like a v2 bundle file" +msgstr "'%s' ser inte ut som en v2-bundle-fil" + +#: bundle.c:63 +#, c-format +msgid "unrecognized header: %s%s (%d)" +msgstr "okänt huvud: %s%s (%d)" + +#: bundle.c:89 builtin/commit.c:696 +#, c-format +msgid "could not open '%s'" +msgstr "kunde inte öppna \"%s\"" + +#: bundle.c:140 +msgid "Repository lacks these prerequisite commits:" +msgstr "Arkivet saknar dessa nödvändiga incheckningar:" + +#: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:289 +#: builtin/log.c:720 builtin/log.c:1309 builtin/log.c:1528 builtin/merge.c:347 +#: builtin/shortlog.c:181 +msgid "revision walk setup failed" +msgstr "misslyckades skapa revisionstraversering" + +#: bundle.c:186 +#, c-format +msgid "The bundle contains %d ref" +msgid_plural "The bundle contains %d refs" +msgstr[0] "Paketet (bundlen) innehÃ¥ller %d referens" +msgstr[1] "Paketet (bundlen) innehÃ¥ller %d referenser" + +#: bundle.c:192 +#, c-format +msgid "The bundle requires this ref" +msgid_plural "The bundle requires these %d refs" +msgstr[0] "Paketet (bundlen) kräver denna referens" +msgstr[1] "Paketet (bundlen) kräver dessa %d referenser" + +#: bundle.c:290 +msgid "rev-list died" +msgstr "rev-list dog" + +#: bundle.c:296 builtin/log.c:1205 builtin/shortlog.c:284 +#, c-format +msgid "unrecognized argument: %s" +msgstr "okänt argument: %s" + +#: bundle.c:331 +#, c-format +msgid "ref '%s' is excluded by the rev-list options" +msgstr "referensen \"%s\" exkluderas av argumenten till rev-list" + +#: bundle.c:376 +msgid "Refusing to create empty bundle." +msgstr "Vägrar skapa ett tomt paket (bundle)." + +#: bundle.c:394 +msgid "Could not spawn pack-objects" +msgstr "Kunde inte starta pack-objects" + +#: bundle.c:412 +msgid "pack-objects died" +msgstr "pack-objects misslyckades" + +#: bundle.c:415 +#, c-format +msgid "cannot create '%s'" +msgstr "kan inte skapa \"%s\"" + +#: bundle.c:437 +msgid "index-pack died" +msgstr "index-pack dog" + +#: commit.c:48 #, c-format msgid "could not parse %s" msgstr "kunde inte tolka %s" -#: commit.c:49 +#: commit.c:50 #, c-format msgid "%s %s is not a commit!" msgstr "%s %s är inte en incheckning!" @@ -66,6 +140,73 @@ msgstr "kunde inte skriva till rev-list: %s" msgid "failed to close rev-list's stdin: %s" msgstr "kunde inte stänga rev-list:s standard in: %s" +#: date.c:95 +msgid "in the future" +msgstr "i framtiden" + +#: date.c:101 +#, c-format +msgid "%lu second ago" +msgid_plural "%lu seconds ago" +msgstr[0] "%lu sekund sedan" +msgstr[1] "%lu sekunder sedan" + +#: date.c:108 +#, c-format +msgid "%lu minute ago" +msgid_plural "%lu minutes ago" +msgstr[0] "%lu minut sedan" +msgstr[1] "%lu minuter sedan" + +#: date.c:115 +#, c-format +msgid "%lu hour ago" +msgid_plural "%lu hours ago" +msgstr[0] "%lu timme sedan" +msgstr[1] "%lu timmar sedan" + +#: date.c:122 +#, c-format +msgid "%lu day ago" +msgid_plural "%lu days ago" +msgstr[0] "%lu dag sedan" +msgstr[1] "%lu dagar sedan" + +#: date.c:128 +#, c-format +msgid "%lu week ago" +msgid_plural "%lu weeks ago" +msgstr[0] "%lu vecka sedan" +msgstr[1] "%lu veckor sedan" + +#: date.c:135 +#, c-format +msgid "%lu month ago" +msgid_plural "%lu months ago" +msgstr[0] "%lu mÃ¥nad sedan" +msgstr[1] "%lu mÃ¥nader sedan" + +#: date.c:146 +#, c-format +msgid "%lu year" +msgid_plural "%lu years" +msgstr[0] "%lu Ã¥r" +msgstr[1] "%lu Ã¥r" + +#: date.c:149 +#, c-format +msgid "%s, %lu month ago" +msgid_plural "%s, %lu months ago" +msgstr[0] "%s, %lu mÃ¥nad sedan" +msgstr[1] "%s, %lu mÃ¥nader sedan" + +#: date.c:154 date.c:159 +#, c-format +msgid "%lu year ago" +msgid_plural "%lu years ago" +msgstr[0] "%lu Ã¥r sedan" +msgstr[1] "%lu Ã¥r sedan" + #: diff.c:105 #, c-format msgid " Failed to parse dirstat cut-off percentage '%.*s'\n" @@ -110,7 +251,7 @@ msgid_plural ", %d deletions(-)" msgstr[0] ", %d borttagning(-)" msgstr[1] ", %d borttagningar(-)" -#: diff.c:3439 +#: diff.c:3478 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -131,22 +272,31 @@ msgstr "gpg godtog inte data" msgid "gpg failed to sign the data" msgstr "gpg misslyckades signera data" -#: grep.c:1280 +#: grep.c:1320 #, c-format msgid "'%s': unable to read %s" msgstr "\"%s\" kunde inte läsa %s" -#: grep.c:1297 +#: grep.c:1337 #, c-format msgid "'%s': %s" msgstr "\"%s\": %s" -#: grep.c:1308 +#: grep.c:1348 #, c-format msgid "'%s': short read %s" msgstr "\"%s\": kort läsning %s" -#: help.c:287 +#: help.c:207 +#, c-format +msgid "available git commands in '%s'" +msgstr "git-kommandon tillgängliga i \"%s\"" + +#: help.c:214 +msgid "git commands available from elsewhere on your $PATH" +msgstr "git-kommandon frÃ¥n andra platser i din $PATH" + +#: help.c:270 #, c-format msgid "" "'%s' appears to be a git command, but we were not\n" @@ -155,14 +305,72 @@ msgstr "" "\"%s\" verkar vara ett git-kommando, men vi kan inte\n" "köra det. Kanske git-%s är trasigt?" -#: remote.c:1607 +#: help.c:327 +msgid "Uh oh. Your system reports no Git commands at all." +msgstr "Oj dÃ¥. Ditt system rapporterar inga Git-kommandon alls." + +#: help.c:349 +#, c-format +msgid "" +"WARNING: You called a Git command named '%s', which does not exist.\n" +"Continuing under the assumption that you meant '%s'" +msgstr "" +"VARNING: Du anropade ett Git-kommando vid namn \"%s\", som inte finns.\n" +"Fortsätter under förutsättningen att du menade \"%s\"" + +#: help.c:354 +#, c-format +msgid "in %0.1f seconds automatically..." +msgstr "automatiskt om %0.1f sekunder..." + +#: help.c:361 +#, c-format +msgid "git: '%s' is not a git command. See 'git --help'." +msgstr "git: \"%s\" är inte ett git-kommando. Se \"git --help\"." + +#: help.c:365 +msgid "" +"\n" +"Did you mean this?" +msgid_plural "" +"\n" +"Did you mean one of these?" +msgstr[0] "" +"\n" +"Menade du detta?" +msgstr[1] "" +"\n" +"Menade du ett av dessa?" + +#: parse-options.c:493 +msgid "..." +msgstr "..." + +#: parse-options.c:511 +#, c-format +msgid "usage: %s" +msgstr "användning: %s" + +#. TRANSLATORS: the colon here should align with the +#. one in "usage: %s" translation +#: parse-options.c:515 +#, c-format +msgid " or: %s" +msgstr " eller: %s" + +#: parse-options.c:518 +#, c-format +msgid " %s" +msgstr " %s" + +#: remote.c:1629 #, c-format msgid "Your branch is ahead of '%s' by %d commit.\n" msgid_plural "Your branch is ahead of '%s' by %d commits.\n" msgstr[0] "Din gren ligger före \"%s\" med %d incheckning.\n" msgstr[1] "Din gren ligger före \"%s\" med %d incheckningar.\n" -#: remote.c:1613 +#: remote.c:1635 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -172,7 +380,7 @@ msgstr[0] "" msgstr[1] "" "Din gren ligger efter \"%s\" med %d incheckningar, och kan snabbspolas.\n" -#: remote.c:1621 +#: remote.c:1643 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -187,19 +395,19 @@ msgstr[1] "" "Din gren och \"%s\" har divergerat,\n" "och har %d respektive %d olika incheckningar.\n" -#: sequencer.c:120 builtin/merge.c:865 builtin/merge.c:978 +#: sequencer.c:121 builtin/merge.c:865 builtin/merge.c:978 #: builtin/merge.c:1088 builtin/merge.c:1098 #, c-format msgid "Could not open '%s' for writing" msgstr "Kunde inte öppna \"%s\" för skrivning" -#: sequencer.c:122 builtin/merge.c:333 builtin/merge.c:868 +#: sequencer.c:123 builtin/merge.c:333 builtin/merge.c:868 #: builtin/merge.c:1090 builtin/merge.c:1103 #, c-format msgid "Could not write to '%s'" msgstr "Kunde inte skriva till \"%s\"" -#: sequencer.c:143 +#: sequencer.c:144 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add ' or 'git rm '" @@ -207,7 +415,7 @@ msgstr "" "efter att ha löst konflikterna, markera de rättade sökvägarna\n" "med \"git add \" eller \"git rm \"" -#: sequencer.c:146 +#: sequencer.c:147 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add ' or 'git rm '\n" @@ -217,439 +425,479 @@ msgstr "" "med \"git add \" eller \"git rm \"\n" "och checka in resultatet med \"git commit\"" -#: sequencer.c:159 sequencer.c:685 sequencer.c:768 +#: sequencer.c:160 sequencer.c:758 sequencer.c:841 #, c-format msgid "Could not write to %s" msgstr "Kunde inte skriva till %s" -#: sequencer.c:162 +#: sequencer.c:163 #, c-format msgid "Error wrapping up %s" msgstr "Fel vid ombrytning av %s" -#: sequencer.c:177 +#: sequencer.c:178 msgid "Your local changes would be overwritten by cherry-pick." msgstr "Dina lokala ändringar skulle skrivas över av \"cherry-pick\"." -#: sequencer.c:179 +#: sequencer.c:180 msgid "Your local changes would be overwritten by revert." msgstr "Dina lokala ändringar skulle skrivas över av \"revert\"." -#: sequencer.c:182 +#: sequencer.c:183 msgid "Commit your changes or stash them to proceed." msgstr "Checka in dina ändringar eller använd \"stash\" för att fortsätta." #. TRANSLATORS: %s will be "revert" or "cherry-pick" -#: sequencer.c:232 +#: sequencer.c:233 #, c-format msgid "%s: Unable to write new index file" msgstr "%s: Kunde inte skriva ny indexfil" -#: sequencer.c:298 +#: sequencer.c:261 +msgid "Could not resolve HEAD commit\n" +msgstr "Kunde inte bestämma HEAD:s incheckning\n" + +#: sequencer.c:282 +msgid "Unable to update cache tree\n" +msgstr "Kan inte uppdatera cacheträd\n" + +#: sequencer.c:324 +#, c-format +msgid "Could not parse commit %s\n" +msgstr "Kunde inte tolka incheckningen %s\n" + +#: sequencer.c:329 +#, c-format +msgid "Could not parse parent commit %s\n" +msgstr "Kunde inte tolka föräldraincheckningen %s\n" + +#: sequencer.c:395 msgid "Your index file is unmerged." msgstr "Din indexfil har inte slagits ihop." -#: sequencer.c:301 +#: sequencer.c:398 msgid "You do not have a valid HEAD" msgstr "Du har ingen giltig HEAD" -#: sequencer.c:316 +#: sequencer.c:413 #, c-format msgid "Commit %s is a merge but no -m option was given." msgstr "Incheckning %s är en sammanslagning, men flaggan -m angavs inte." -#: sequencer.c:324 +#: sequencer.c:421 #, c-format msgid "Commit %s does not have parent %d" msgstr "Incheckning %s har inte förälder %d" -#: sequencer.c:328 +#: sequencer.c:425 #, c-format msgid "Mainline was specified but commit %s is not a merge." msgstr "Huvudlinje angavs, men incheckningen %s är inte en sammanslagning" #. TRANSLATORS: The first %s will be "revert" or #. "cherry-pick", the second %s a SHA1 -#: sequencer.c:339 +#: sequencer.c:436 #, c-format msgid "%s: cannot parse parent commit %s" msgstr "%s: kan inte tolka föräldraincheckningen %s" -#: sequencer.c:343 +#: sequencer.c:440 #, c-format msgid "Cannot get commit message for %s" msgstr "Kan inte hämta incheckningsmeddelande för %s" -#: sequencer.c:427 +#: sequencer.c:524 #, c-format msgid "could not revert %s... %s" msgstr "kunde inte Ã¥ngra %s... %s" -#: sequencer.c:428 +#: sequencer.c:525 #, c-format msgid "could not apply %s... %s" -msgstr "kunde inte applicera %s... %s" +msgstr "kunde inte tillämpa %s... %s" -#: sequencer.c:450 sequencer.c:909 builtin/log.c:288 builtin/log.c:713 -#: builtin/log.c:1329 builtin/log.c:1548 builtin/merge.c:347 -#: builtin/shortlog.c:181 -msgid "revision walk setup failed" -msgstr "misslyckades skapa revisionstraversering" - -#: sequencer.c:453 +#: sequencer.c:553 msgid "empty commit set passed" msgstr "den angivna uppsättningen incheckningar är tom" -#: sequencer.c:461 +#: sequencer.c:561 #, c-format msgid "git %s: failed to read the index" msgstr "git %s: misslyckades läsa indexet" -#: sequencer.c:466 +#: sequencer.c:566 #, c-format msgid "git %s: failed to refresh the index" msgstr "git %s: misslyckades uppdatera indexet" -#: sequencer.c:551 +#: sequencer.c:624 #, c-format msgid "Cannot %s during a %s" msgstr "kan inte %s under en %s" -#: sequencer.c:573 +#: sequencer.c:646 #, c-format msgid "Could not parse line %d." msgstr "Kan inte tolka rad %d." -#: sequencer.c:578 +#: sequencer.c:651 msgid "No commits parsed." msgstr "Inga incheckningar lästes." -#: sequencer.c:591 +#: sequencer.c:664 #, c-format msgid "Could not open %s" msgstr "Kunde inte öppna %s" -#: sequencer.c:595 +#: sequencer.c:668 #, c-format msgid "Could not read %s." msgstr "kunde inte läsa %s." -#: sequencer.c:602 +#: sequencer.c:675 #, c-format msgid "Unusable instruction sheet: %s" msgstr "Oanvändbart manus: %s" -#: sequencer.c:630 +#: sequencer.c:703 #, c-format msgid "Invalid key: %s" msgstr "Felaktig nyckel: %s" -#: sequencer.c:633 +#: sequencer.c:706 #, c-format msgid "Invalid value for %s: %s" msgstr "Felaktigt värde för %s: %s" -#: sequencer.c:645 +#: sequencer.c:718 #, c-format msgid "Malformed options sheet: %s" msgstr "Trasigt manus: %s" -#: sequencer.c:666 +#: sequencer.c:739 msgid "a cherry-pick or revert is already in progress" msgstr "en \"cherry-pick\" eller \"revert\" pÃ¥gÃ¥r redan" -#: sequencer.c:667 +#: sequencer.c:740 msgid "try \"git cherry-pick (--continue | --quit | --abort)\"" msgstr "testa \"git cherry-pick (--continue | --quit | --abort)\"" -#: sequencer.c:671 +#: sequencer.c:744 #, c-format msgid "Could not create sequencer directory %s" msgstr "Kunde inte skapa \"sequencer\"-katalogen \"%s\"" -#: sequencer.c:687 sequencer.c:772 +#: sequencer.c:760 sequencer.c:845 #, c-format msgid "Error wrapping up %s." msgstr "Fel vid ombrytning av %s." -#: sequencer.c:706 sequencer.c:840 +#: sequencer.c:779 sequencer.c:913 msgid "no cherry-pick or revert in progress" msgstr "ingen \"cherry-pick\" eller \"revert\" pÃ¥gÃ¥r" -#: sequencer.c:708 +#: sequencer.c:781 msgid "cannot resolve HEAD" msgstr "kan inte bestämma HEAD" -#: sequencer.c:710 +#: sequencer.c:783 msgid "cannot abort from a branch yet to be born" msgstr "kan inte avbryta frÃ¥n en gren som ännu inte är född" -#: sequencer.c:732 +#: sequencer.c:805 builtin/apply.c:3697 #, c-format msgid "cannot open %s: %s" msgstr "kan inte öppna %s: %s" -#: sequencer.c:735 +#: sequencer.c:808 #, c-format msgid "cannot read %s: %s" msgstr "kan inte läsa %s: %s" -#: sequencer.c:736 +#: sequencer.c:809 msgid "unexpected end of file" msgstr "oväntat filslut" -#: sequencer.c:742 +#: sequencer.c:815 #, c-format msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" msgstr "sparad HEAD-fil frÃ¥n före \"cherry-pick\", \"%s\", är trasig" -#: sequencer.c:765 +#: sequencer.c:838 #, c-format msgid "Could not format %s." msgstr "Kunde inte formatera %s." -#: sequencer.c:927 +#: sequencer.c:1000 msgid "Can't revert as initial commit" msgstr "Kan inte Ã¥ngra som första incheckning" -#: sequencer.c:928 +#: sequencer.c:1001 msgid "Can't cherry-pick into empty head" msgstr "Kan inte göra \"cherry-pick\" i ett tomt huvud" -#: wt-status.c:134 +#: sha1_name.c:864 +msgid "HEAD does not point to a branch" +msgstr "HEAD pekar inte pÃ¥ en gren" + +#: sha1_name.c:867 +#, c-format +msgid "No such branch: '%s'" +msgstr "Okänd gren: \"%s\"" + +#: sha1_name.c:869 +#, c-format +msgid "No upstream configured for branch '%s'" +msgstr "Ingen standarduppström angiven för grenen \"%s\"" + +#: sha1_name.c:872 +#, c-format +msgid "Upstream branch '%s' not stored as a remote-tracking branch" +msgstr "Uppströmsgrenen \"%s\" är inte lagrad som en fjärrspÃ¥rande gren" + +#: wrapper.c:413 +#, c-format +msgid "unable to look up current user in the passwd file: %s" +msgstr "kan inte slÃ¥ upp aktuell användare i passwd-filen: %s" + +#: wrapper.c:414 +msgid "no such user" +msgstr "okänd användare" + +#: wt-status.c:135 msgid "Unmerged paths:" msgstr "Ej sammanslagna sökvägar:" -#: wt-status.c:140 wt-status.c:157 +#: wt-status.c:141 wt-status.c:158 #, c-format msgid " (use \"git reset %s ...\" to unstage)" msgstr " (använd \"git reset %s ...\" för att ta bort frÃ¥n kö)" -#: wt-status.c:142 wt-status.c:159 +#: wt-status.c:143 wt-status.c:160 msgid " (use \"git rm --cached ...\" to unstage)" msgstr " (använd \"git rm --cached ...\" för att ta bort frÃ¥n kö)" -#: wt-status.c:143 +#: wt-status.c:144 msgid " (use \"git add/rm ...\" as appropriate to mark resolution)" msgstr " (använd \"git add/rm ...\" som lämpligt för att ange lösning)" -#: wt-status.c:151 +#: wt-status.c:152 msgid "Changes to be committed:" msgstr "Ändringar att checka in:" -#: wt-status.c:169 +#: wt-status.c:170 msgid "Changes not staged for commit:" msgstr "Ändringar ej i incheckningskön:" -#: wt-status.c:173 +#: wt-status.c:174 msgid " (use \"git add ...\" to update what will be committed)" msgstr "" " (använd \"git add ...\" för att uppdatera vad som skall checkas in)" -#: wt-status.c:175 +#: wt-status.c:176 msgid " (use \"git add/rm ...\" to update what will be committed)" msgstr "" " (använd \"git add/rm ...\" för att uppdatera vad som skall checkas in)" -#: wt-status.c:176 +#: wt-status.c:177 msgid "" " (use \"git checkout -- ...\" to discard changes in working directory)" msgstr "" " (använd \"git checkout -- ...\" för att förkasta ändringar i " "arbetskatalogen)" -#: wt-status.c:178 +#: wt-status.c:179 msgid " (commit or discard the untracked or modified content in submodules)" msgstr "" " (checka in eller förkasta ospÃ¥rat eller ändrat innehÃ¥ll i undermoduler)" # %s är ett verb ("Untracked"/"Ignored"); lägg till ett -e. -#: wt-status.c:187 +#: wt-status.c:188 #, c-format msgid "%s files:" msgstr "%se filer:" -#: wt-status.c:190 +#: wt-status.c:191 #, c-format msgid " (use \"git %s ...\" to include in what will be committed)" msgstr "" " (använd \"git %s ...\" för att ta med i vad som skall checkas in)" -#: wt-status.c:207 +#: wt-status.c:208 msgid "bug" msgstr "programfel" -#: wt-status.c:212 +#: wt-status.c:213 msgid "both deleted:" msgstr "borttaget av bägge:" -#: wt-status.c:213 +#: wt-status.c:214 msgid "added by us:" msgstr "tillagt av oss:" -#: wt-status.c:214 +#: wt-status.c:215 msgid "deleted by them:" msgstr "borttaget av dem:" -#: wt-status.c:215 +#: wt-status.c:216 msgid "added by them:" msgstr "tillagt av dem:" -#: wt-status.c:216 +#: wt-status.c:217 msgid "deleted by us:" msgstr "borttaget av oss:" -#: wt-status.c:217 +#: wt-status.c:218 msgid "both added:" msgstr "tillagt av bägge:" -#: wt-status.c:218 +#: wt-status.c:219 msgid "both modified:" msgstr "ändrat av bägge:" -#: wt-status.c:248 +#: wt-status.c:249 msgid "new commits, " msgstr "nya incheckningar, " -#: wt-status.c:250 +#: wt-status.c:251 msgid "modified content, " msgstr "ändrat innehÃ¥ll, " -#: wt-status.c:252 +#: wt-status.c:253 msgid "untracked content, " msgstr "ospÃ¥rat innehÃ¥ll, " -#: wt-status.c:266 +#: wt-status.c:267 #, c-format msgid "new file: %s" msgstr "ny fil: %s" -#: wt-status.c:269 +#: wt-status.c:270 #, c-format msgid "copied: %s -> %s" msgstr "kopierad: %s -> %s" -#: wt-status.c:272 +#: wt-status.c:273 #, c-format msgid "deleted: %s" msgstr "borttagen: %s" -#: wt-status.c:275 +#: wt-status.c:276 #, c-format msgid "modified: %s" msgstr "ändrad: %s" -#: wt-status.c:278 +#: wt-status.c:279 #, c-format msgid "renamed: %s -> %s" msgstr "namnbyte: %s -> %s" -#: wt-status.c:281 +#: wt-status.c:282 #, c-format msgid "typechange: %s" msgstr "typbyte: %s" -#: wt-status.c:284 +#: wt-status.c:285 #, c-format msgid "unknown: %s" msgstr "okänd: %s" -#: wt-status.c:287 +#: wt-status.c:288 #, c-format msgid "unmerged: %s" msgstr "osammansl.: %s" -#: wt-status.c:290 +#: wt-status.c:291 #, c-format msgid "bug: unhandled diff status %c" msgstr "programfel: diff-status %c ej hanterad" -#: wt-status.c:713 +#: wt-status.c:737 msgid "On branch " msgstr "PÃ¥ grenen " -#: wt-status.c:720 +#: wt-status.c:744 msgid "Not currently on any branch." msgstr "Inte pÃ¥ nÃ¥gon gren för närvarande." -#: wt-status.c:731 +#: wt-status.c:755 msgid "Initial commit" msgstr "Första incheckning" -#: wt-status.c:745 +#: wt-status.c:769 msgid "Untracked" msgstr "OspÃ¥rad" -#: wt-status.c:747 +#: wt-status.c:771 msgid "Ignored" msgstr "Ignorerad" # %s är nästa sträng eller tom. -#: wt-status.c:749 +#: wt-status.c:773 #, c-format msgid "Untracked files not listed%s" msgstr "OspÃ¥rade filer visas ej%s" -#: wt-status.c:751 +#: wt-status.c:775 msgid " (use -u option to show untracked files)" msgstr " (använd flaggan -u för att visa ospÃ¥rade filer)" -#: wt-status.c:757 +#: wt-status.c:781 msgid "No changes" msgstr "Inga ändringar" -#: wt-status.c:761 +#: wt-status.c:785 #, c-format msgid "no changes added to commit%s\n" msgstr "inga ändringar att checka in%s\n" -#: wt-status.c:763 +#: wt-status.c:787 msgid " (use \"git add\" and/or \"git commit -a\")" msgstr " (använd \"git add\" och/eller \"git commit -a\")" -#: wt-status.c:765 +#: wt-status.c:789 #, c-format msgid "nothing added to commit but untracked files present%s\n" msgstr "inget köat för incheckning, men ospÃ¥rade filer finns%s\n" -#: wt-status.c:767 +#: wt-status.c:791 msgid " (use \"git add\" to track)" msgstr " (använd \"git add\" för att spÃ¥ra)" -#: wt-status.c:769 wt-status.c:772 wt-status.c:775 +#: wt-status.c:793 wt-status.c:796 wt-status.c:799 #, c-format msgid "nothing to commit%s\n" msgstr "inget att checka in%s\n" -#: wt-status.c:770 +#: wt-status.c:794 msgid " (create/copy files and use \"git add\" to track)" msgstr " (skapa/kopiera filer och använd \"git add\" för att spÃ¥ra)" -#: wt-status.c:773 +#: wt-status.c:797 msgid " (use -u to show untracked files)" msgstr " (använd -u för att visa ospÃ¥rade filer)" -#: wt-status.c:776 +#: wt-status.c:800 msgid " (working directory clean)" msgstr " (arbetskatalogen ren)" -#: wt-status.c:884 +#: wt-status.c:908 msgid "HEAD (no branch)" msgstr "HEAD (ingen gren)" -#: wt-status.c:890 +#: wt-status.c:914 msgid "Initial commit on " msgstr "Första incheckning pÃ¥ " -#: wt-status.c:905 +#: wt-status.c:929 msgid "behind " msgstr "efter " -#: wt-status.c:908 wt-status.c:911 +#: wt-status.c:932 wt-status.c:935 msgid "ahead " msgstr "före " -#: wt-status.c:913 +#: wt-status.c:937 msgid ", behind " msgstr ", efter " @@ -658,7 +906,7 @@ msgstr ", efter " msgid "unexpected diff status %c" msgstr "diff-status %c förväntades inte" -#: builtin/add.c:67 builtin/commit.c:298 +#: builtin/add.c:67 builtin/commit.c:226 msgid "updating files failed" msgstr "misslyckades uppdatera filer" @@ -711,7 +959,7 @@ msgstr "Tom patch. Avbryter." #: builtin/add.c:303 #, c-format msgid "Could not apply '%s'" -msgstr "Kunde inte applicera \"%s\"" +msgstr "Kunde inte tillämpa \"%s\"" #: builtin/add.c:312 msgid "The following paths are ignored by one of your .gitignore files:\n" @@ -748,15 +996,487 @@ msgstr "Inget angivet, inget tillagt.\n" msgid "Maybe you wanted to say 'git add .'?\n" msgstr "Kanske menade du att skriva \"git add .\"?\n" -#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:358 builtin/mv.c:82 +#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:286 builtin/mv.c:82 #: builtin/rm.c:162 msgid "index file corrupt" msgstr "indexfilen trasig" -#: builtin/add.c:476 builtin/mv.c:229 builtin/rm.c:260 +#: builtin/add.c:476 builtin/apply.c:4108 builtin/mv.c:229 builtin/rm.c:260 msgid "Unable to write new index file" msgstr "Kunde inte skriva ny indexfil" +#: builtin/apply.c:53 +msgid "git apply [options] [...]" +msgstr "git apply [flaggor] [...]" + +#: builtin/apply.c:106 +#, c-format +msgid "unrecognized whitespace option '%s'" +msgstr "okänt alternativ för whitespace: \"%s\"" + +#: builtin/apply.c:121 +#, c-format +msgid "unrecognized whitespace ignore option '%s'" +msgstr "okänt alternativ för ignore-whitespace: \"%s\"" + +#: builtin/apply.c:815 +#, c-format +msgid "Cannot prepare timestamp regexp %s" +msgstr "Kan inte förbereda reguljärt uttryck för tidsstämpeln %s" + +#: builtin/apply.c:824 +#, c-format +msgid "regexec returned %d for input: %s" +msgstr "regexec returnerade %d för indata: %s" + +#: builtin/apply.c:905 +#, c-format +msgid "unable to find filename in patch at line %d" +msgstr "kan inte hitta filnamn i patchen pÃ¥ rad %d" + +#: builtin/apply.c:937 +#, c-format +msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d" +msgstr "git apply: dÃ¥lig git-diff - förväntade /dev/null, fick %s pÃ¥ rad %d" + +#: builtin/apply.c:941 +#, c-format +msgid "git apply: bad git-diff - inconsistent new filename on line %d" +msgstr "git apply: dÃ¥lig git-diff - motsägande nytt filnamn pÃ¥ rad %d" + +#: builtin/apply.c:942 +#, c-format +msgid "git apply: bad git-diff - inconsistent old filename on line %d" +msgstr "git apply: dÃ¥lig git-diff - motsägande gammalt filnamn pÃ¥ rad %d" + +#: builtin/apply.c:949 +#, c-format +msgid "git apply: bad git-diff - expected /dev/null on line %d" +msgstr "git apply: dÃ¥lig git-diff - förväntade /dev/null pÃ¥ rad %d" + +#: builtin/apply.c:1394 +#, c-format +msgid "recount: unexpected line: %.*s" +msgstr "recount: förväntade rad: %.*s" + +#: builtin/apply.c:1451 +#, c-format +msgid "patch fragment without header at line %d: %.*s" +msgstr "patch-fragment utan huvud pÃ¥ rad %d: %.*s" + +#: builtin/apply.c:1468 +#, c-format +msgid "" +"git diff header lacks filename information when removing %d leading pathname " +"component (line %d)" +msgid_plural "" +"git diff header lacks filename information when removing %d leading pathname " +"components (line %d)" +msgstr[0] "" +"git-diff-huvudet saknar filnamnsinformation när %d ledande sökvägskomponent\n" +"tas bort (rad %d)" +msgstr[1] "" +"git-diff-huvudet saknar filnamnsinformation när %d ledande " +"sökvägskomponenter\n" +"tas bort (rad %d)" + +#: builtin/apply.c:1628 +msgid "new file depends on old contents" +msgstr "ny fil beror pÃ¥ gammalt innehÃ¥ll" + +#: builtin/apply.c:1630 +msgid "deleted file still has contents" +msgstr "borttagen fil har fortfarande innehÃ¥ll" + +#: builtin/apply.c:1656 +#, c-format +msgid "corrupt patch at line %d" +msgstr "trasig patch pÃ¥ rad %d" + +#: builtin/apply.c:1692 +#, c-format +msgid "new file %s depends on old contents" +msgstr "nya filen %s beror pÃ¥ gammalt innehÃ¥ll" + +#: builtin/apply.c:1694 +#, c-format +msgid "deleted file %s still has contents" +msgstr "borttagna filen %s har fortfarande innehÃ¥ll" + +#: builtin/apply.c:1697 +#, c-format +msgid "** warning: file %s becomes empty but is not deleted" +msgstr "** varning: filen %s blir tom men har inte tagits bort" + +#: builtin/apply.c:1843 +#, c-format +msgid "corrupt binary patch at line %d: %.*s" +msgstr "trasig binärpatch pÃ¥ rad %d: %.*s" + +#. there has to be one hunk (forward hunk) +#: builtin/apply.c:1872 +#, c-format +msgid "unrecognized binary patch at line %d" +msgstr "binärpatchen pÃ¥ rad %d känns inte igen" + +#: builtin/apply.c:1958 +#, c-format +msgid "patch with only garbage at line %d" +msgstr "patch med bara skräp pÃ¥ rad %d" + +#: builtin/apply.c:2048 +#, c-format +msgid "unable to read symlink %s" +msgstr "kunde inte läsa symboliska länken %s" + +#: builtin/apply.c:2052 +#, c-format +msgid "unable to open or read %s" +msgstr "kunde inte öppna eller läsa %s" + +#: builtin/apply.c:2123 +msgid "oops" +msgstr "hoppsan" + +#: builtin/apply.c:2645 +#, c-format +msgid "invalid start of line: '%c'" +msgstr "felaktig inledning pÃ¥ rad: \"%c\"" + +#: builtin/apply.c:2763 +#, c-format +msgid "Hunk #%d succeeded at %d (offset %d line)." +msgid_plural "Hunk #%d succeeded at %d (offset %d lines)." +msgstr[0] "Stycke %d lyckades pÃ¥ %d (offset %d rad)." +msgstr[1] "Stycke %d lyckades pÃ¥ %d (offset %d rader)." + +#: builtin/apply.c:2775 +#, c-format +msgid "Context reduced to (%ld/%ld) to apply fragment at %d" +msgstr "Sammanhang reducerat till (%ld/%ld) för att tillämpa fragment vid %d" + +#: builtin/apply.c:2781 +#, c-format +msgid "" +"while searching for:\n" +"%.*s" +msgstr "" +"vid sökning efter:\n" +"%.*s" + +#: builtin/apply.c:2800 +#, c-format +msgid "missing binary patch data for '%s'" +msgstr "saknar binära patchdata för \"%s\"" + +#: builtin/apply.c:2903 +#, c-format +msgid "binary patch does not apply to '%s'" +msgstr "binärpatchen kan inte tillämpas pÃ¥ \"%s\"" + +#: builtin/apply.c:2909 +#, c-format +msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" +msgstr "binärpatchen pÃ¥ \"%s\" ger felaktigt resultat (förväntade %s, fick %s)" + +#: builtin/apply.c:2930 +#, c-format +msgid "patch failed: %s:%ld" +msgstr "patch misslyckades: %s:%ld" + +#: builtin/apply.c:3045 +#, c-format +msgid "patch %s has been renamed/deleted" +msgstr "patchen %s har ändrat namn/tagits bort" + +#: builtin/apply.c:3052 builtin/apply.c:3069 +#, c-format +msgid "read of %s failed" +msgstr "misslyckades läsa %s" + +#: builtin/apply.c:3084 +msgid "removal patch leaves file contents" +msgstr "patch för borttagning lämnar kvar filinnehÃ¥ll" + +#: builtin/apply.c:3105 +#, c-format +msgid "%s: already exists in working directory" +msgstr "%s: finns redan i arbetskatalogen" + +#: builtin/apply.c:3143 +#, c-format +msgid "%s: has been deleted/renamed" +msgstr "%s: har tagits bort/ändrat namn" + +#: builtin/apply.c:3148 builtin/apply.c:3179 +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: builtin/apply.c:3159 +#, c-format +msgid "%s: does not exist in index" +msgstr "%s: finns inte i indexet" + +#: builtin/apply.c:3173 +#, c-format +msgid "%s: does not match index" +msgstr "%s: motsvarar inte indexet" + +#: builtin/apply.c:3190 +#, c-format +msgid "%s: wrong type" +msgstr "%s: fel typ" + +#: builtin/apply.c:3192 +#, c-format +msgid "%s has type %o, expected %o" +msgstr "%s har typen %o, förväntade %o" + +#: builtin/apply.c:3247 +#, c-format +msgid "%s: already exists in index" +msgstr "%s: finns redan i indexet" + +#: builtin/apply.c:3267 +#, c-format +msgid "new mode (%o) of %s does not match old mode (%o)" +msgstr "nytt läge (%o) för %s motsvarar inte gammalt läge (%o)" + +#: builtin/apply.c:3272 +#, c-format +msgid "new mode (%o) of %s does not match old mode (%o) of %s" +msgstr "nytt läge (%o) för %s motsvarar inte gammalt läge (%o) för %s" + +#: builtin/apply.c:3280 +#, c-format +msgid "%s: patch does not apply" +msgstr "%s: patchen kan inte tillämpas" + +#: builtin/apply.c:3293 +#, c-format +msgid "Checking patch %s..." +msgstr "Kontrollerar patchen %s..." + +#: builtin/apply.c:3348 builtin/checkout.c:212 builtin/reset.c:158 +#, c-format +msgid "make_cache_entry failed for path '%s'" +msgstr "make_cache_entry misslyckades för sökvägen \"%s\"" + +#: builtin/apply.c:3491 +#, c-format +msgid "unable to remove %s from index" +msgstr "kan inte ta bort %s frÃ¥n indexet" + +#: builtin/apply.c:3518 +#, c-format +msgid "corrupt patch for subproject %s" +msgstr "trasig patch för underprojektet %s" + +#: builtin/apply.c:3522 +#, c-format +msgid "unable to stat newly created file '%s'" +msgstr "kan inte ta status pÃ¥ nyligen skapade filen \"%s\"" + +#: builtin/apply.c:3527 +#, c-format +msgid "unable to create backing store for newly created file %s" +msgstr "kan inte skapa säkerhetsminne för nyligen skapade filen %s" + +#: builtin/apply.c:3530 +#, c-format +msgid "unable to add cache entry for %s" +msgstr "kan inte lägga till cachepost för %s" + +#: builtin/apply.c:3563 +#, c-format +msgid "closing file '%s'" +msgstr "stänger filen \"%s\"" + +#: builtin/apply.c:3612 +#, c-format +msgid "unable to write file '%s' mode %o" +msgstr "kan inte skriva filen \"%s\" läge %o" + +#: builtin/apply.c:3668 +#, c-format +msgid "Applied patch %s cleanly." +msgstr "Tillämpade patchen %s rent." + +#: builtin/apply.c:3676 +msgid "internal error" +msgstr "internt fel" + +#. Say this even without --verbose +#: builtin/apply.c:3679 +#, c-format +msgid "Applying patch %%s with %d reject..." +msgid_plural "Applying patch %%s with %d rejects..." +msgstr[0] "Tillämpade patchen %%s med %d refuserad..." +msgstr[1] "Tillämpade patchen %%s med %d refuserade..." + +#: builtin/apply.c:3689 +#, c-format +msgid "truncating .rej filename to %.*s.rej" +msgstr "trunkerar .rej-filnamnet till %.*s.rej" + +#: builtin/apply.c:3710 +#, c-format +msgid "Hunk #%d applied cleanly." +msgstr "Stycke %d tillämpades rent." + +#: builtin/apply.c:3713 +#, c-format +msgid "Rejected hunk #%d." +msgstr "Refuserar stycke %d." + +#: builtin/apply.c:3844 +msgid "unrecognized input" +msgstr "indata känns inte igen" + +#: builtin/apply.c:3855 +msgid "unable to read index file" +msgstr "kan inte läsa indexfilen" + +#: builtin/apply.c:3970 builtin/apply.c:3973 +msgid "path" +msgstr "sökväg" + +#: builtin/apply.c:3971 +msgid "don't apply changes matching the given path" +msgstr "tillämpa inte ändringar som motsvarar given sökväg" + +#: builtin/apply.c:3974 +msgid "apply changes matching the given path" +msgstr "tillämpa ändringar som motsvarar given sökväg" + +#: builtin/apply.c:3976 +msgid "num" +msgstr "antal" + +#: builtin/apply.c:3977 +msgid "remove leading slashes from traditional diff paths" +msgstr "ta bort inledande snedstreck frÃ¥n traditionella diff-sökvägar" + +#: builtin/apply.c:3980 +msgid "ignore additions made by the patch" +msgstr "ignorera tillägg gjorda av patchen" + +#: builtin/apply.c:3982 +msgid "instead of applying the patch, output diffstat for the input" +msgstr "istället för att tillämpa patchen, skriv ut diffstat för indata" + +#: builtin/apply.c:3986 +msgid "shows number of added and deleted lines in decimal notation" +msgstr "visar antal tillagda och borttagna rader decimalt" + +#: builtin/apply.c:3988 +msgid "instead of applying the patch, output a summary for the input" +msgstr "istället för att tillämpa patchen, skriv ut en summering av indata" + +#: builtin/apply.c:3990 +msgid "instead of applying the patch, see if the patch is applicable" +msgstr "istället för att tillämpa patchen, se om patchen kan tillämpas" + +#: builtin/apply.c:3992 +msgid "make sure the patch is applicable to the current index" +msgstr "se till att patchen kan tillämpas pÃ¥ aktuellt index" + +#: builtin/apply.c:3994 +msgid "apply a patch without touching the working tree" +msgstr "tillämpa en patch utan att röra arbetskatalogen" + +#: builtin/apply.c:3996 +msgid "also apply the patch (use with --stat/--summary/--check)" +msgstr "tillämpa ocksÃ¥ patchen (använd med --stat/--summary/--check)" + +#: builtin/apply.c:3998 +msgid "build a temporary index based on embedded index information" +msgstr "bygg ett temporärt index baserat pÃ¥ inbyggd indexinformation" + +#: builtin/apply.c:4000 +msgid "paths are separated with NUL character" +msgstr "sökvägar avdelas med NUL-tecken" + +#: builtin/apply.c:4003 +msgid "ensure at least lines of context match" +msgstr "se till att Ã¥tminstone rader sammanhang är lika" + +#: builtin/apply.c:4004 +msgid "action" +msgstr "Ã¥tgärd" + +#: builtin/apply.c:4005 +msgid "detect new or modified lines that have whitespace errors" +msgstr "detektera nya eller ändrade rader som har fel i blanktecken" + +#: builtin/apply.c:4008 builtin/apply.c:4011 +msgid "ignore changes in whitespace when finding context" +msgstr "ignorera ändringar i blanktecken för sammanhang" + +#: builtin/apply.c:4014 +msgid "apply the patch in reverse" +msgstr "tillämpa patchen baklänges" + +#: builtin/apply.c:4016 +msgid "don't expect at least one line of context" +msgstr "förvänta inte minst en rad sammanhang" + +#: builtin/apply.c:4018 +msgid "leave the rejected hunks in corresponding *.rej files" +msgstr "lämna refuserade stycken i motsvarande *.rej-filer" + +#: builtin/apply.c:4020 +msgid "allow overlapping hunks" +msgstr "tillÃ¥t överlappande stycken" + +#: builtin/apply.c:4021 +msgid "be verbose" +msgstr "var pratsam" + +#: builtin/apply.c:4023 +msgid "tolerate incorrectly detected missing new-line at the end of file" +msgstr "tolerera felaktigt detekterade saknade nyradstecken vid filslut" + +#: builtin/apply.c:4026 +msgid "do not trust the line counts in the hunk headers" +msgstr "lite inte pÃ¥ antalet linjer i styckehuvuden" + +#: builtin/apply.c:4028 +msgid "root" +msgstr "rot" + +#: builtin/apply.c:4029 +msgid "prepend to all filenames" +msgstr "lägg till i alla filnamn" + +#: builtin/apply.c:4050 +msgid "--index outside a repository" +msgstr "--index utanför arkiv" + +#: builtin/apply.c:4053 +msgid "--cached outside a repository" +msgstr "--cached utanför arkiv" + +#: builtin/apply.c:4069 +#, c-format +msgid "can't open patch '%s'" +msgstr "kan inte öppna patchen \"%s\"" + +#: builtin/apply.c:4083 +#, c-format +msgid "squelched %d whitespace error" +msgid_plural "squelched %d whitespace errors" +msgstr[0] "undertryckte %d fel i blanksteg" +msgstr[1] "undertryckte %d fel i blanksteg" + +#: builtin/apply.c:4089 builtin/apply.c:4099 +#, c-format +msgid "%d line adds whitespace errors." +msgid_plural "%d lines add whitespace errors." +msgstr[0] "%d rad lägger till fel i blanksteg." +msgstr[1] "%d rader lägger till fel i blanksteg." + #: builtin/archive.c:17 #, c-format msgid "could not create archive file '%s'" @@ -792,7 +1512,7 @@ msgstr "git archive: protokollfel" msgid "git archive: expected a flush" msgstr "git archive: förväntade en tömning (flush)" -#: builtin/branch.c:137 +#: builtin/branch.c:144 #, c-format msgid "" "deleting branch '%s' that has been merged to\n" @@ -801,7 +1521,7 @@ msgstr "" "tar bort grenen \"%s\" som har slagits ihop med\n" " \"%s\", men ännu inte slagits ihop med HEAD." -#: builtin/branch.c:141 +#: builtin/branch.c:148 #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" @@ -810,35 +1530,35 @@ msgstr "" "tar inte bort grenen \"%s\" som inte har slagits ihop med\n" " \"%s\", trots att den har slagits ihop med HEAD." -#. TRANSLATORS: This is "remote " in "remote branch '%s' not found" -#: builtin/branch.c:163 -msgid "remote " -msgstr "fjärr" - -#: builtin/branch.c:171 +#: builtin/branch.c:180 msgid "cannot use -a with -d" msgstr "kan inte ange -a med -d" -#: builtin/branch.c:177 +#: builtin/branch.c:186 msgid "Couldn't look up commit object for HEAD" msgstr "Kunde inte slÃ¥ upp incheckningsobjekt för HEAD" -#: builtin/branch.c:182 +#: builtin/branch.c:191 #, c-format msgid "Cannot delete the branch '%s' which you are currently on." msgstr "Kan inte ta bort grenen \"%s\" som du befinner dig pÃ¥ för närvarande." -#: builtin/branch.c:192 +#: builtin/branch.c:202 #, c-format -msgid "%sbranch '%s' not found." -msgstr "%sgrenen \"%s\" hittades inte." +msgid "remote branch '%s' not found." +msgstr "fjärrgrenen \"%s\" hittades inte." -#: builtin/branch.c:200 +#: builtin/branch.c:203 +#, c-format +msgid "branch '%s' not found." +msgstr "grenen \"%s\" hittades inte." + +#: builtin/branch.c:210 #, c-format msgid "Couldn't look up commit object for '%s'" msgstr "Kunde inte slÃ¥ upp incheckningsobjekt för \"%s\"" -#: builtin/branch.c:206 +#: builtin/branch.c:216 #, c-format msgid "" "The branch '%s' is not fully merged.\n" @@ -847,95 +1567,124 @@ msgstr "" "Grenen \"%s\" har inte slagits samman i sin helhet.\n" "Om du är säker pÃ¥ att du vill ta bort den, kör \"git branch -D %s\"." -#: builtin/branch.c:214 +#: builtin/branch.c:225 +#, c-format +msgid "Error deleting remote branch '%s'" +msgstr "Fel vid borttagning av fjärrgrenen \"%s\"" + +#: builtin/branch.c:226 #, c-format -msgid "Error deleting %sbranch '%s'" -msgstr "Fel vid borttagning av %sgrenen \"%s\"" +msgid "Error deleting branch '%s'" +msgstr "Fel vid borttagning av grenen \"%s\"" -#: builtin/branch.c:219 +#: builtin/branch.c:233 #, c-format -msgid "Deleted %sbranch %s (was %s).\n" -msgstr "Tog bort %sgrenen %s (var %s).\n" +msgid "Deleted remote branch %s (was %s).\n" +msgstr "Tog bort fjärrgrenen %s (var %s).\n" -#: builtin/branch.c:224 +#: builtin/branch.c:234 +#, c-format +msgid "Deleted branch %s (was %s).\n" +msgstr "Tog bort grenen %s (var %s).\n" + +#: builtin/branch.c:239 msgid "Update of config-file failed" msgstr "Misslyckades uppdatera konfigurationsfil" -#: builtin/branch.c:322 +#: builtin/branch.c:337 #, c-format msgid "branch '%s' does not point at a commit" msgstr "grenen \"%s\" pekar inte pÃ¥ en incheckning" -#: builtin/branch.c:394 +#: builtin/branch.c:409 +#, c-format +msgid "[%s: behind %d]" +msgstr "[%s: bakom %d] " + +#: builtin/branch.c:411 +#, c-format +msgid "[behind %d]" +msgstr "[bakom %d] " + +#: builtin/branch.c:415 #, c-format -msgid "behind %d] " -msgstr "bakom %d] " +msgid "[%s: ahead %d]" +msgstr "[%s: före %d] " -#: builtin/branch.c:396 +#: builtin/branch.c:417 #, c-format -msgid "ahead %d] " -msgstr "före %d] " +msgid "[ahead %d]" +msgstr "[före %d] " -#: builtin/branch.c:398 +#: builtin/branch.c:420 #, c-format -msgid "ahead %d, behind %d] " -msgstr "före %d, bakom %d] " +msgid "[%s: ahead %d, behind %d]" +msgstr "[%s: före %d, bakom %d] " -#: builtin/branch.c:501 +#: builtin/branch.c:423 +#, c-format +msgid "[ahead %d, behind %d]" +msgstr "[före %d, bakom %d] " + +#: builtin/branch.c:535 msgid "(no branch)" msgstr "(ingen gren)" -#: builtin/branch.c:566 +#: builtin/branch.c:600 msgid "some refs could not be read" msgstr "vissa referenser kunde inte läsas" -#: builtin/branch.c:579 +#: builtin/branch.c:613 msgid "cannot rename the current branch while not on any." msgstr "" "kunde inte byta namn pÃ¥ aktuell gren när du inte befinner dig pÃ¥ nÃ¥gon." -#: builtin/branch.c:589 +#: builtin/branch.c:623 #, c-format msgid "Invalid branch name: '%s'" msgstr "Felaktigt namn pÃ¥ gren: \"%s\"" -#: builtin/branch.c:604 +#: builtin/branch.c:638 msgid "Branch rename failed" msgstr "Misslyckades byta namn pÃ¥ gren" -#: builtin/branch.c:608 +#: builtin/branch.c:642 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "Bytte bort namn pÃ¥ en felaktigt namngiven gren \"%s\"" -#: builtin/branch.c:612 +#: builtin/branch.c:646 #, c-format msgid "Branch renamed to %s, but HEAD is not updated!" msgstr "Grenen namnbytt till %s, men HEAD har inte uppdaterats!" -#: builtin/branch.c:619 +#: builtin/branch.c:653 msgid "Branch is renamed, but update of config-file failed" msgstr "Grenen namnbytt, men misslyckades uppdatera konfigurationsfilen" -#: builtin/branch.c:634 +#: builtin/branch.c:668 #, c-format msgid "malformed object name %s" msgstr "felformat objektnamn %s" -#: builtin/branch.c:658 +#: builtin/branch.c:692 #, c-format -msgid "could not write branch description template: %s\n" -msgstr "kunde inte skriva grenbeskrivningsmall: %s\n" +msgid "could not write branch description template: %s" +msgstr "kunde inte skriva grenbeskrivningsmall: %s" -#: builtin/branch.c:746 +#: builtin/branch.c:783 msgid "Failed to resolve HEAD as a valid ref." msgstr "Misslyckades slÃ¥ upp HEAD som giltig referens" -#: builtin/branch.c:751 builtin/clone.c:558 +#: builtin/branch.c:788 builtin/clone.c:558 msgid "HEAD not found below refs/heads!" msgstr "HEAD hittades inte under refs/heads!" -#: builtin/branch.c:809 +#: builtin/branch.c:808 +msgid "--column and --verbose are incompatible" +msgstr "--column och --verbose är inkompatibla" + +#: builtin/branch.c:857 msgid "-a and -r options to 'git branch' do not make sense with a branch name" msgstr "" "flaggorna -a och -r pÃ¥ \"git branch\" kan inte anges tillsammans med ett " @@ -984,11 +1733,6 @@ msgstr "sökväg \"%s\": kan inte slÃ¥ ihop" msgid "Unable to add merge result for '%s'" msgstr "Kunde inte lägga till sammanslagningsresultat för \"%s\"" -#: builtin/checkout.c:212 builtin/reset.c:158 -#, c-format -msgid "make_cache_entry failed for path '%s'" -msgstr "make_cache_entry misslyckades för sökvägen \"%s\"" - #: builtin/checkout.c:234 builtin/checkout.c:392 msgid "corrupt index file" msgstr "indexfilen är trasig" @@ -1016,42 +1760,42 @@ msgstr "du mÃ¥ste lösa ditt befintliga index först" msgid "Can not do reflog for '%s'\n" msgstr "Kan inte skapa referenslog för \"%s\"\n" -#: builtin/checkout.c:565 +#: builtin/checkout.c:566 msgid "HEAD is now at" msgstr "HEAD är nu pÃ¥" -#: builtin/checkout.c:572 +#: builtin/checkout.c:573 #, c-format msgid "Reset branch '%s'\n" msgstr "Återställ gren \"%s\"\n" -#: builtin/checkout.c:575 +#: builtin/checkout.c:576 #, c-format msgid "Already on '%s'\n" msgstr "Redan pÃ¥ \"%s\"\n" -#: builtin/checkout.c:579 +#: builtin/checkout.c:580 #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "Växlade till och nollställde grenen \"%s\"\n" -#: builtin/checkout.c:581 +#: builtin/checkout.c:582 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "Växlade till en ny gren \"%s\"\n" -#: builtin/checkout.c:583 +#: builtin/checkout.c:584 #, c-format msgid "Switched to branch '%s'\n" msgstr "Växlade till grenen \"%s\"\n" -#: builtin/checkout.c:639 +#: builtin/checkout.c:640 #, c-format msgid " ... and %d more.\n" msgstr " ... och %d till.\n" #. The singular version -#: builtin/checkout.c:645 +#: builtin/checkout.c:646 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -1074,7 +1818,7 @@ msgstr[1] "" "\n" "%s\n" -#: builtin/checkout.c:663 +#: builtin/checkout.c:664 #, c-format msgid "" "If you want to keep them by creating a new branch, this may be a good time\n" @@ -1089,71 +1833,71 @@ msgstr "" " git branch nytt_grennamn %s\n" "\n" -#: builtin/checkout.c:693 +#: builtin/checkout.c:694 msgid "internal error in revision walk" msgstr "internt fel vid genomgÃ¥ng av revisioner (revision walk)" -#: builtin/checkout.c:697 +#: builtin/checkout.c:698 msgid "Previous HEAD position was" msgstr "Tidigare position för HEAD var" -#: builtin/checkout.c:723 +#: builtin/checkout.c:724 msgid "You are on a branch yet to be born" msgstr "Du är pÃ¥ en gren som ännu inte är född" #. case (1) -#: builtin/checkout.c:854 +#: builtin/checkout.c:855 #, c-format msgid "invalid reference: %s" msgstr "felaktig referens: %s" #. case (1): want a tree -#: builtin/checkout.c:893 +#: builtin/checkout.c:894 #, c-format msgid "reference is not a tree: %s" msgstr "referensen är inte ett träd: %s" -#: builtin/checkout.c:973 +#: builtin/checkout.c:974 msgid "-B cannot be used with -b" msgstr "-B kan inte användas med -b" -#: builtin/checkout.c:982 +#: builtin/checkout.c:983 msgid "--patch is incompatible with all other options" msgstr "--patch är inkompatibel med alla andra flaggor" -#: builtin/checkout.c:985 +#: builtin/checkout.c:986 msgid "--detach cannot be used with -b/-B/--orphan" msgstr "--detcah kan inte användas med -b/-B/--orphan" -#: builtin/checkout.c:987 +#: builtin/checkout.c:988 msgid "--detach cannot be used with -t" msgstr "--detach kan inte användas med -t" -#: builtin/checkout.c:993 +#: builtin/checkout.c:994 msgid "--track needs a branch name" msgstr "--track behöver ett namn pÃ¥ en gren" -#: builtin/checkout.c:1000 +#: builtin/checkout.c:1001 msgid "Missing branch name; try -b" msgstr "Grennamn saknas; försök med -b" -#: builtin/checkout.c:1006 +#: builtin/checkout.c:1007 msgid "--orphan and -b|-B are mutually exclusive" msgstr "--orphan och -b|-B kan inte användas samtidigt" -#: builtin/checkout.c:1008 +#: builtin/checkout.c:1009 msgid "--orphan cannot be used with -t" msgstr "--orphan kan inte användas med -t" -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1019 msgid "git checkout: -f and -m are incompatible" msgstr "git checkout: -f och -m är inkompatibla" -#: builtin/checkout.c:1052 +#: builtin/checkout.c:1053 msgid "invalid path specification" msgstr "felaktig sökvägsangivelse" -#: builtin/checkout.c:1060 +#: builtin/checkout.c:1061 #, c-format msgid "" "git checkout: updating paths is incompatible with switching branches.\n" @@ -1162,15 +1906,15 @@ msgstr "" "git checkout: uppdatera sökvägar är inkompatibelt med att växla gren.\n" "Ville du checka ut \"%s\" som inte kan lösas som en sammanslaning?" -#: builtin/checkout.c:1062 +#: builtin/checkout.c:1063 msgid "git checkout: updating paths is incompatible with switching branches." msgstr "git checkout: uppdatera sökvägar är inkompatibelt med att växla gren." -#: builtin/checkout.c:1067 +#: builtin/checkout.c:1068 msgid "git checkout: --detach does not take a path argument" msgstr "git checkout: --detach tar inte en sökväg som argument" -#: builtin/checkout.c:1070 +#: builtin/checkout.c:1071 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -1178,11 +1922,11 @@ msgstr "" "git checkout: --ours/--theirs, --force och --merge är inkompatibla när\n" "du checkar ut frÃ¥n indexet." -#: builtin/checkout.c:1089 +#: builtin/checkout.c:1090 msgid "Cannot switch branch to a non-commit." msgstr "Kan inte växla gren pÃ¥ en icke-incheckning." -#: builtin/checkout.c:1092 +#: builtin/checkout.c:1093 msgid "--ours/--theirs is incompatible with switching branches." msgstr "--ours/--theirs är inkompatibla med att byta gren." @@ -1356,7 +2100,11 @@ msgstr "Fjärrgrenen %s hittades inte i uppströmsarkivet %s" msgid "You appear to have cloned an empty repository." msgstr "Du verkar ha klonat ett tomt arkiv." -#: builtin/commit.c:42 +#: builtin/column.c:51 +msgid "--command must be the first argument" +msgstr "--command mÃ¥ste vara första argument" + +#: builtin/commit.c:43 msgid "" "Your name and email address were configured automatically based\n" "on your username and hostname. Please check that they are accurate.\n" @@ -1381,7 +2129,7 @@ msgstr "" "\n" " git commit --amend --reset-author\n" -#: builtin/commit.c:54 +#: builtin/commit.c:55 msgid "" "You asked to amend the most recent commit, but doing so would make\n" "it empty. You can repeat your command with --allow-empty, or you can\n" @@ -1391,7 +2139,7 @@ msgstr "" "blir den tom. Du kan köra kommandot pÃ¥ nytt med --allow-empty, eller\n" "sÃ¥ kan du ta bort incheckningen helt med \"git reset HEAD^\".\n" -#: builtin/commit.c:59 +#: builtin/commit.c:60 msgid "" "The previous cherry-pick is now empty, possibly due to conflict resolution.\n" "If you wish to commit it anyway, use:\n" @@ -1407,291 +2155,293 @@ msgstr "" "\n" "Annars använder du \"git reset\"\n" -#: builtin/commit.c:205 builtin/reset.c:33 -msgid "merge" -msgstr "sammanslagning" - -#: builtin/commit.c:208 -msgid "cherry-pick" -msgstr "cherry-pick" - -#: builtin/commit.c:325 +#: builtin/commit.c:253 msgid "failed to unpack HEAD tree object" msgstr "misslyckades packa upp HEAD:s trädobjekt" -#: builtin/commit.c:367 +#: builtin/commit.c:295 msgid "unable to create temporary index" msgstr "kunde inte skapa temporär indexfil" -#: builtin/commit.c:373 +#: builtin/commit.c:301 msgid "interactive add failed" msgstr "interaktiv tilläggning misslyckades" -#: builtin/commit.c:406 builtin/commit.c:427 builtin/commit.c:473 +#: builtin/commit.c:334 builtin/commit.c:355 builtin/commit.c:405 msgid "unable to write new_index file" msgstr "kunde inte skriva filen new_index" -# %s är antingen "merge" eller "cherry-pick". -#: builtin/commit.c:457 -#, c-format -msgid "cannot do a partial commit during a %s." -msgstr "kan inte utföra en delvis incheckning under en %s" +#: builtin/commit.c:386 +msgid "cannot do a partial commit during a merge." +msgstr "kan inte utföra en delvis incheckning under en sammanslagning." -#: builtin/commit.c:466 +#: builtin/commit.c:388 +msgid "cannot do a partial commit during a cherry-pick." +msgstr "kan inte utföra en delvis incheckning under en cherry-pick." + +#: builtin/commit.c:398 msgid "cannot read the index" msgstr "kan inte läsa indexet" -#: builtin/commit.c:486 +#: builtin/commit.c:418 msgid "unable to write temporary index file" msgstr "kunde inte skriva temporär indexfil" -#: builtin/commit.c:561 builtin/commit.c:567 +#: builtin/commit.c:493 builtin/commit.c:499 #, c-format msgid "invalid commit: %s" msgstr "felaktig incheckning: %s" -#: builtin/commit.c:590 +#: builtin/commit.c:522 msgid "malformed --author parameter" msgstr "felformad \"--author\"-flagga" -#: builtin/commit.c:651 +#: builtin/commit.c:582 #, c-format msgid "Malformed ident string: '%s'" msgstr "Felaktig indragningssträng: \"%s\"" -#: builtin/commit.c:689 builtin/commit.c:722 builtin/commit.c:1033 +#: builtin/commit.c:620 builtin/commit.c:653 builtin/commit.c:967 #, c-format msgid "could not lookup commit %s" msgstr "kunde inte slÃ¥ upp incheckningen %s" -#: builtin/commit.c:701 builtin/shortlog.c:296 +#: builtin/commit.c:632 builtin/shortlog.c:296 #, c-format msgid "(reading log message from standard input)\n" msgstr "(läser loggmeddelande frÃ¥n standard in)\n" -#: builtin/commit.c:703 +#: builtin/commit.c:634 msgid "could not read log from standard input" msgstr "kunde inte läsa logg frÃ¥n standard in" -#: builtin/commit.c:707 +#: builtin/commit.c:638 #, c-format msgid "could not read log file '%s'" msgstr "kunde inte läsa loggfilen \"%s\"" -#: builtin/commit.c:713 +#: builtin/commit.c:644 msgid "commit has empty message" msgstr "incheckningen har ett tomt meddelande" -#: builtin/commit.c:729 +#: builtin/commit.c:660 msgid "could not read MERGE_MSG" msgstr "kunde inte läsa MERGE_MSG" -#: builtin/commit.c:733 +#: builtin/commit.c:664 msgid "could not read SQUASH_MSG" msgstr "kunde inte läsa SQUASH_MSG" -#: builtin/commit.c:737 +#: builtin/commit.c:668 #, c-format msgid "could not read '%s'" msgstr "kunde inte läsa \"%s\"" -#: builtin/commit.c:765 -#, c-format -msgid "could not open '%s'" -msgstr "kunde inte öppna \"%s\"" - -#: builtin/commit.c:789 +#: builtin/commit.c:720 msgid "could not write commit template" msgstr "kunde inte skriva incheckningsmall" -# %s är "merge" eller "cherry-pick" -#: builtin/commit.c:799 +#: builtin/commit.c:731 #, c-format msgid "" "\n" -"It looks like you may be committing a %s.\n" +"It looks like you may be committing a merge.\n" "If this is not correct, please remove the file\n" "\t%s\n" "and try again.\n" msgstr "" "\n" -"Det verkar som du checkar in en %s.\n" +"Det verkar som du checkar in en sammanslagning.\n" "Om det inte stämmer tar du bort filen\n" "\t%s\n" "och försöker igen.\n" -#: builtin/commit.c:812 -msgid "Please enter the commit message for your changes." -msgstr "Ange ett incheckningsmeddelande för dina ändringar." +#: builtin/commit.c:736 +#, c-format +msgid "" +"\n" +"It looks like you may be committing a cherry-pick.\n" +"If this is not correct, please remove the file\n" +"\t%s\n" +"and try again.\n" +msgstr "" +"\n" +"Det verkar som du checkar in en cherry-pick.\n" +"Om det inte stämmer tar du bort filen\n" +"\t%s\n" +"och försöker igen.\n" -#: builtin/commit.c:815 +#: builtin/commit.c:748 msgid "" -" Lines starting\n" +"Please enter the commit message for your changes. Lines starting\n" "with '#' will be ignored, and an empty message aborts the commit.\n" msgstr "" -" Rader som inleds\n" +"Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n" "med \"#\" kommer ignoreras, och ett tomt meddelande avbryter incheckningen.\n" -#: builtin/commit.c:820 +#: builtin/commit.c:753 msgid "" -" Lines starting\n" +"Please enter the commit message for your changes. Lines starting\n" "with '#' will be kept; you may remove them yourself if you want to.\n" "An empty message aborts the commit.\n" msgstr "" -" Rader som inleds\n" +"Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n" "med \"#\" kommer behÃ¥llas; du kan själv ta bort dem om du vill.\n" "Ett tomt meddelande avbryter incheckningen.\n" -#: builtin/commit.c:832 +#: builtin/commit.c:766 #, c-format msgid "%sAuthor: %s" msgstr "%sFörfattare: %s" -#: builtin/commit.c:839 +#: builtin/commit.c:773 #, c-format msgid "%sCommitter: %s" msgstr "%sIncheckare: %s" -#: builtin/commit.c:859 +#: builtin/commit.c:793 msgid "Cannot read index" msgstr "Kan inte läsa indexet" -#: builtin/commit.c:896 +#: builtin/commit.c:830 msgid "Error building trees" msgstr "Fel vid byggande av träd" -#: builtin/commit.c:911 builtin/tag.c:357 +#: builtin/commit.c:845 builtin/tag.c:361 #, c-format msgid "Please supply the message using either -m or -F option.\n" msgstr "Ange meddelandet en av flaggorna -m eller -F.\n" -#: builtin/commit.c:1008 +#: builtin/commit.c:942 #, c-format msgid "No existing author found with '%s'" msgstr "Hittade ingen befintlig författare med \"%s\"" -#: builtin/commit.c:1023 builtin/commit.c:1217 +#: builtin/commit.c:957 builtin/commit.c:1157 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "Ogiltigt läge för ospÃ¥rade filer: \"%s\"" -#: builtin/commit.c:1063 +#: builtin/commit.c:997 msgid "Using both --reset-author and --author does not make sense" msgstr "Kan inte använda bÃ¥de --reset-author och --author" -#: builtin/commit.c:1074 +#: builtin/commit.c:1008 msgid "You have nothing to amend." msgstr "Du har inget att utöka." -#: builtin/commit.c:1076 -#, c-format -msgid "You are in the middle of a %s -- cannot amend." -msgstr "Du är i mitten av en %s -- kan inte utöka." +#: builtin/commit.c:1011 +msgid "You are in the middle of a merge -- cannot amend." +msgstr "Du är i mitten av en sammanslagning -- kan inte utöka." + +#: builtin/commit.c:1013 +msgid "You are in the middle of a cherry-pick -- cannot amend." +msgstr "Du är i mitten av en cherry-pick -- kan inte utöka." -#: builtin/commit.c:1078 +#: builtin/commit.c:1016 msgid "Options --squash and --fixup cannot be used together" msgstr "Flaggorna --squash och --fixup kan inte användas samtidigt" -#: builtin/commit.c:1088 +#: builtin/commit.c:1026 msgid "Only one of -c/-C/-F/--fixup can be used." msgstr "Endast en av -c/-C/-F/--fixup kan användas." -#: builtin/commit.c:1090 +#: builtin/commit.c:1028 msgid "Option -m cannot be combined with -c/-C/-F/--fixup." msgstr "Flaggan -m kan inte kombineras med -c/-C/-F/--fixup." -#: builtin/commit.c:1098 +#: builtin/commit.c:1036 msgid "--reset-author can be used only with -C, -c or --amend." msgstr "--reset-author kan endast användas med -C, -c eller --amend." -#: builtin/commit.c:1115 +#: builtin/commit.c:1053 msgid "Only one of --include/--only/--all/--interactive/--patch can be used." msgstr "" "Endast en av --include/--only/--all/--interactive/--patch kan användas." -#: builtin/commit.c:1117 +#: builtin/commit.c:1055 msgid "No paths with --include/--only does not make sense." msgstr "Du mÃ¥ste ange sökvägar tillsammans med --include/--only." -#: builtin/commit.c:1119 +#: builtin/commit.c:1057 msgid "Clever... amending the last one with dirty index." msgstr "Smart... utöka den senaste med smutsigt index." -#: builtin/commit.c:1121 +#: builtin/commit.c:1059 msgid "Explicit paths specified without -i nor -o; assuming --only paths..." msgstr "Explicita sökvägar angavs utan -i eller -o; antar --only sökvägar..." -#: builtin/commit.c:1131 builtin/tag.c:556 +#: builtin/commit.c:1069 builtin/tag.c:577 #, c-format msgid "Invalid cleanup mode %s" msgstr "Felaktigt städningsläge %s" -#: builtin/commit.c:1136 +#: builtin/commit.c:1074 msgid "Paths with -a does not make sense." msgstr "Kan inte ange sökvägar med -a." -#: builtin/commit.c:1315 +#: builtin/commit.c:1257 msgid "couldn't look up newly created commit" msgstr "kunde inte slÃ¥ upp en precis skapad incheckning" -#: builtin/commit.c:1317 +#: builtin/commit.c:1259 msgid "could not parse newly created commit" msgstr "kunde inte tolka en precis skapad incheckning" -#: builtin/commit.c:1358 +#: builtin/commit.c:1300 msgid "detached HEAD" msgstr "frÃ¥nkopplad HEAD" -#: builtin/commit.c:1360 +#: builtin/commit.c:1302 msgid " (root-commit)" msgstr " (rotincheckning)" -#: builtin/commit.c:1450 +#: builtin/commit.c:1446 msgid "could not parse HEAD commit" msgstr "kunde inte tolka HEAD:s incheckning" -#: builtin/commit.c:1487 builtin/merge.c:509 +#: builtin/commit.c:1484 builtin/merge.c:509 #, c-format msgid "could not open '%s' for reading" msgstr "kunde inte öppna \"%s\" för läsning" -#: builtin/commit.c:1494 +#: builtin/commit.c:1491 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "Trasig MERGE_HEAD-fil (%s)" -#: builtin/commit.c:1501 +#: builtin/commit.c:1498 msgid "could not read MERGE_MODE" msgstr "kunde inte läsa MERGE_MODE" -#: builtin/commit.c:1520 +#: builtin/commit.c:1517 #, c-format msgid "could not read commit message: %s" msgstr "kunde inte läsa incheckningsmeddelande: %s" -#: builtin/commit.c:1534 +#: builtin/commit.c:1531 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "Avbryter incheckning; meddelandet inte redigerat.\n" -#: builtin/commit.c:1539 +#: builtin/commit.c:1536 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "Avbryter pÃ¥ grund av tomt incheckningsmeddelande.\n" -#: builtin/commit.c:1554 builtin/merge.c:936 builtin/merge.c:961 +#: builtin/commit.c:1551 builtin/merge.c:936 builtin/merge.c:961 msgid "failed to write commit object" msgstr "kunde inte skriva incheckningsobjekt" -#: builtin/commit.c:1575 +#: builtin/commit.c:1572 msgid "cannot lock HEAD ref" msgstr "kunde inte lÃ¥sa HEAD-referens" -#: builtin/commit.c:1579 +#: builtin/commit.c:1576 msgid "cannot update HEAD ref" msgstr "kunde inte uppdatera HEAD-referens" -#: builtin/commit.c:1590 +#: builtin/commit.c:1587 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full or quota is\n" @@ -1900,19 +2650,19 @@ msgstr "" #: builtin/fetch.c:549 #, c-format -msgid " (%s will become dangling)\n" -msgstr " (%s kommer bli dinglande)\n" +msgid " (%s will become dangling)" +msgstr " (%s kommer bli dinglande)" #: builtin/fetch.c:550 #, c-format -msgid " (%s has become dangling)\n" -msgstr " (%s har blivit dinglande)\n" +msgid " (%s has become dangling)" +msgstr " (%s har blivit dinglande)" #: builtin/fetch.c:557 msgid "[deleted]" msgstr "[borttagen]" -#: builtin/fetch.c:558 +#: builtin/fetch.c:558 builtin/remote.c:1055 msgid "(none)" msgstr "(ingen)" @@ -1941,7 +2691,7 @@ msgstr "Flaggan \"%s\" ignoreras för %s\n" msgid "Fetching %s\n" msgstr "Hämtar %s\n" -#: builtin/fetch.c:890 +#: builtin/fetch.c:890 builtin/remote.c:100 #, c-format msgid "Could not fetch %s" msgstr "Kunde inte hämta %s" @@ -2011,59 +2761,363 @@ msgstr "" msgid "grep: failed to create thread: %s" msgstr "grep: misslyckades skapa trÃ¥d. %s" -#: builtin/grep.c:402 +#: builtin/grep.c:402 +#, c-format +msgid "Failed to chdir: %s" +msgstr "Kunde inte byta katalog (chdir): %s" + +#: builtin/grep.c:478 builtin/grep.c:512 +#, c-format +msgid "unable to read tree (%s)" +msgstr "kunde inte läsa träd (%s)" + +#: builtin/grep.c:526 +#, c-format +msgid "unable to grep from object of type %s" +msgstr "Kunde inte \"grep\" frÃ¥n objekt av typen %s" + +#: builtin/grep.c:584 +#, c-format +msgid "switch `%c' expects a numerical value" +msgstr "flaggan \"%c\" antar ett numeriskt värde" + +#: builtin/grep.c:601 +#, c-format +msgid "cannot open '%s'" +msgstr "kan inte öppna \"%s\"" + +#: builtin/grep.c:885 +msgid "no pattern given." +msgstr "inget mönster angavs." + +#: builtin/grep.c:899 +#, c-format +msgid "bad object %s" +msgstr "felaktigt objekt %s" + +#: builtin/grep.c:940 +msgid "--open-files-in-pager only works on the worktree" +msgstr "--open-files-in-pager fungerar endast i arbetskatalogen" + +#: builtin/grep.c:963 +msgid "--cached or --untracked cannot be used with --no-index." +msgstr "--cached och --untracked kan inte användas med --no-index." + +#: builtin/grep.c:968 +msgid "--no-index or --untracked cannot be used with revs." +msgstr "--no-index och --untracked kan inte användas med revisioner." + +#: builtin/grep.c:971 +msgid "--[no-]exclude-standard cannot be used for tracked contents." +msgstr "--[no-]exclude-standard kan inte användas för spÃ¥rat innehÃ¥ll." + +#: builtin/grep.c:979 +msgid "both --cached and trees are given." +msgstr "bÃ¥de --cached och träd angavs." + +#: builtin/help.c:59 +#, c-format +msgid "unrecognized help format '%s'" +msgstr "okänt hjälpformat: %s" + +#: builtin/help.c:87 +msgid "Failed to start emacsclient." +msgstr "Misslyckades starta emacsclient." + +#: builtin/help.c:100 +msgid "Failed to parse emacsclient version." +msgstr "Kunde inte tolka emacsclient-version." + +#: builtin/help.c:108 +#, c-format +msgid "emacsclient version '%d' too old (< 22)." +msgstr "emacsclient version \"%d\" för gammal (< 22)." + +#: builtin/help.c:126 builtin/help.c:154 builtin/help.c:163 builtin/help.c:171 +#, c-format +msgid "failed to exec '%s': %s" +msgstr "exec misslyckades för \"%s\": %s" + +#: builtin/help.c:211 +#, c-format +msgid "" +"'%s': path for unsupported man viewer.\n" +"Please consider using 'man..cmd' instead." +msgstr "" +"\"%s\": sökväg för man-visare som ej stöds.\n" +"Använd \"man..cmd\" istället." + +#: builtin/help.c:223 +#, c-format +msgid "" +"'%s': cmd for supported man viewer.\n" +"Please consider using 'man..path' instead." +msgstr "" +"\"%s\": kommando för man-visare som stöds.\n" +"Använd \"man..path\" istället." + +#: builtin/help.c:287 +msgid "The most commonly used git commands are:" +msgstr "De mest använda git-kommandona är:" + +#: builtin/help.c:355 +#, c-format +msgid "'%s': unknown man viewer." +msgstr "\"%s\": okänd man-visare." + +#: builtin/help.c:372 +msgid "no man viewer handled the request" +msgstr "ingen man-visare hanterade förfrÃ¥gan" + +#: builtin/help.c:380 +msgid "no info viewer handled the request" +msgstr "ingen info-visare hanterade förfrÃ¥gan" + +#: builtin/help.c:391 +#, c-format +msgid "'%s': not a documentation directory." +msgstr "\"%s\": inte en dokumentationskatalog." + +#: builtin/help.c:432 builtin/help.c:439 +#, c-format +msgid "usage: %s%s" +msgstr "användning: %s%s" + +#: builtin/help.c:453 +#, c-format +msgid "`git %s' is aliased to `%s'" +msgstr "\"git %s\" är ett alias för \"%s\"" + +#: builtin/index-pack.c:169 +#, c-format +msgid "object type mismatch at %s" +msgstr "objekttyp stämmer inte överens vid %s" + +#: builtin/index-pack.c:189 +msgid "object of unexpected type" +msgstr "objekt av oväntad typ" + +#: builtin/index-pack.c:226 +#, c-format +msgid "cannot fill %d byte" +msgid_plural "cannot fill %d bytes" +msgstr[0] "kan inte fylla %d byte" +msgstr[1] "kan inte fylla %d byte" + +#: builtin/index-pack.c:236 +msgid "early EOF" +msgstr "tidigt filslut" + +#: builtin/index-pack.c:237 +msgid "read error on input" +msgstr "indataläsfel" + +#: builtin/index-pack.c:249 +msgid "used more bytes than were available" +msgstr "använde fler byte än tillgängligt" + +#: builtin/index-pack.c:256 +msgid "pack too large for current definition of off_t" +msgstr "paket för stort för nuvarande definition av off_t" + +#: builtin/index-pack.c:272 +#, c-format +msgid "unable to create '%s'" +msgstr "kunde inte skapa \"%s\"" + +#: builtin/index-pack.c:277 +#, c-format +msgid "cannot open packfile '%s'" +msgstr "kan inte öppna paketfilen \"%s\"" + +#: builtin/index-pack.c:291 +msgid "pack signature mismatch" +msgstr "paketsignatur stämmer inte överens" + +#: builtin/index-pack.c:311 +#, c-format +msgid "pack has bad object at offset %lu: %s" +msgstr "paketet har felaktigt objekt vid index %lu: %s" + +#: builtin/index-pack.c:405 +#, c-format +msgid "inflate returned %d" +msgstr "inflate returnerade %d" + +#: builtin/index-pack.c:450 +msgid "offset value overflow for delta base object" +msgstr "indexvärdespill för deltabasobjekt" + +#: builtin/index-pack.c:458 +msgid "delta base offset is out of bound" +msgstr "deltabasindex utanför gränsen" + +#: builtin/index-pack.c:466 +#, c-format +msgid "unknown object type %d" +msgstr "okänd objekttyp %d" + +#: builtin/index-pack.c:495 +msgid "cannot pread pack file" +msgstr "kan inte utföra \"pread\" pÃ¥ paketfil" + +#: builtin/index-pack.c:497 +#, c-format +msgid "premature end of pack file, %lu byte missing" +msgid_plural "premature end of pack file, %lu bytes missing" +msgstr[0] "för tidigt slut pÃ¥ paketfilen, %lu byte saknas" +msgstr[1] "för tidigt slut pÃ¥ paketfilen, %lu byte saknas" + +#: builtin/index-pack.c:510 +msgid "serious inflate inconsistency" +msgstr "allvarlig inflate-inkonsekvens" + +#: builtin/index-pack.c:583 +#, c-format +msgid "cannot read existing object %s" +msgstr "kan inte läsa befintligt objekt %s" + +#: builtin/index-pack.c:586 +#, c-format +msgid "SHA1 COLLISION FOUND WITH %s !" +msgstr "SHA1-KOLLISION UPPTÄCKT VID %s !" + +#: builtin/index-pack.c:598 +#, c-format +msgid "invalid blob object %s" +msgstr "ogiltigt blob-objekt %s" + +#: builtin/index-pack.c:610 +#, c-format +msgid "invalid %s" +msgstr "ogiltigt %s" + +#: builtin/index-pack.c:612 +msgid "Error in object" +msgstr "Fel i objekt" + +#: builtin/index-pack.c:614 +#, c-format +msgid "Not all child objects of %s are reachable" +msgstr "Inte alla barnobjekt för %s kan nÃ¥s" + +#: builtin/index-pack.c:687 builtin/index-pack.c:713 +msgid "failed to apply delta" +msgstr "misslyckades tillämpa delta" + +#: builtin/index-pack.c:850 +msgid "Receiving objects" +msgstr "Tar bort objeckt" + +#: builtin/index-pack.c:850 +msgid "Indexing objects" +msgstr "Skapar index för objekt" + +#: builtin/index-pack.c:872 +msgid "pack is corrupted (SHA1 mismatch)" +msgstr "paketet är trasigt (SHA1 stämmer inte)" + +#: builtin/index-pack.c:877 +msgid "cannot fstat packfile" +msgstr "kan inte utföra \"fstat\" pÃ¥ paketfil" + +#: builtin/index-pack.c:880 +msgid "pack has junk at the end" +msgstr "paket har skräp i slutet" + +#: builtin/index-pack.c:903 +msgid "Resolving deltas" +msgstr "Analyserar delta" + +#: builtin/index-pack.c:954 +msgid "confusion beyond insanity" +msgstr "förvirrad bortom vanvett" + +#: builtin/index-pack.c:973 +#, c-format +msgid "pack has %d unresolved delta" +msgid_plural "pack has %d unresolved deltas" +msgstr[0] "paketet har %d oanalyserat delta" +msgstr[1] "paketet har %d oanalyserade delta" + +#: builtin/index-pack.c:998 +#, c-format +msgid "unable to deflate appended object (%d)" +msgstr "kunde inte utföra \"deflate\" pÃ¥ tillagt objekt (%d)" + +#: builtin/index-pack.c:1077 #, c-format -msgid "Failed to chdir: %s" -msgstr "Kunde inte byta katalog (chdir): %s" +msgid "local object %s is corrupt" +msgstr "lokalt objekt %s är trasigt" -#: builtin/grep.c:478 builtin/grep.c:512 +#: builtin/index-pack.c:1101 +msgid "error while closing pack file" +msgstr "fel vid stängning av paketfil" + +#: builtin/index-pack.c:1114 #, c-format -msgid "unable to read tree (%s)" -msgstr "kunde inte läsa träd (%s)" +msgid "cannot write keep file '%s'" +msgstr "kan inte ta skriva \"keep\"-fil \"%s\"" -#: builtin/grep.c:526 +#: builtin/index-pack.c:1122 #, c-format -msgid "unable to grep from object of type %s" -msgstr "Kunde inte \"grep\" frÃ¥n objekt av typen %s" +msgid "cannot close written keep file '%s'" +msgstr "akn inte stänga skriven \"keep\"-fil \"%s\"" -#: builtin/grep.c:584 +#: builtin/index-pack.c:1135 +msgid "cannot store pack file" +msgstr "kan inte spara paketfil" + +#: builtin/index-pack.c:1146 +msgid "cannot store index file" +msgstr "kan inte spara indexfil" + +#: builtin/index-pack.c:1247 #, c-format -msgid "switch `%c' expects a numerical value" -msgstr "flaggan \"%c\" antar ett numeriskt värde" +msgid "Cannot open existing pack file '%s'" +msgstr "Kan inte öppna befintlig paketfil \"%s\"" -#: builtin/grep.c:601 +#: builtin/index-pack.c:1249 #, c-format -msgid "cannot open '%s'" -msgstr "kan inte öppna \"%s\"" +msgid "Cannot open existing pack idx file for '%s'" +msgstr "Kan inte öppna befintligt paket-idx-fil för \"%s\"" -#: builtin/grep.c:888 -msgid "no pattern given." -msgstr "inget mönster angavs." +#: builtin/index-pack.c:1296 +#, c-format +msgid "non delta: %d object" +msgid_plural "non delta: %d objects" +msgstr[0] "icke-delta: %d objekt" +msgstr[1] "icke-delta: %d objekt" -#: builtin/grep.c:902 +#: builtin/index-pack.c:1303 #, c-format -msgid "bad object %s" -msgstr "felaktigt objekt %s" +msgid "chain length = %d: %lu object" +msgid_plural "chain length = %d: %lu objects" +msgstr[0] "kedjelängd = %d: %lu objekt" +msgstr[1] "kedjelängd = %d: %lu objekt" -#: builtin/grep.c:943 -msgid "--open-files-in-pager only works on the worktree" -msgstr "--open-files-in-pager fungerar endast i arbetskatalogen" +#: builtin/index-pack.c:1330 +msgid "Cannot come back to cwd" +msgstr "Kan inte gÃ¥ tillbaka till arbetskatalogen (cwd)" -#: builtin/grep.c:966 -msgid "--cached or --untracked cannot be used with --no-index." -msgstr "--cached och --untracked kan inte användas med --no-index." +#: builtin/index-pack.c:1374 builtin/index-pack.c:1377 +#: builtin/index-pack.c:1389 builtin/index-pack.c:1393 +#, c-format +msgid "bad %s" +msgstr "felaktig %s" -#: builtin/grep.c:971 -msgid "--no-index or --untracked cannot be used with revs." -msgstr "--no-index och --untracked kan inte användas med revisioner." +#: builtin/index-pack.c:1407 +msgid "--fix-thin cannot be used without --stdin" +msgstr "--fix-thin kan inte användas med --stdin" -#: builtin/grep.c:974 -msgid "--[no-]exclude-standard cannot be used for tracked contents." -msgstr "--[no-]exclude-standard kan inte användas för spÃ¥rat innehÃ¥ll." +#: builtin/index-pack.c:1411 builtin/index-pack.c:1421 +#, c-format +msgid "packfile name '%s' does not end with '.pack'" +msgstr "paketfilnamnet \"%s\" slutar inte med \".pack\"" -#: builtin/grep.c:982 -msgid "both --cached and trees are given." -msgstr "bÃ¥de --cached och träd angavs." +#: builtin/index-pack.c:1430 +msgid "--verify with no packfile name given" +msgstr "--verify angavs utan paketfilnamn" #: builtin/init-db.c:35 #, c-format @@ -2209,109 +3263,100 @@ msgstr "Kan inte komma Ã¥t aktuell arbetskatalog" msgid "Cannot access work tree '%s'" msgstr "Kan inte komma Ã¥t arbetskatalogen \"%s\"" -#: builtin/log.c:187 +#: builtin/log.c:188 #, c-format msgid "Final output: %d %s\n" msgstr "Slututdata: %d %s\n" -#: builtin/log.c:395 builtin/log.c:483 +#: builtin/log.c:401 builtin/log.c:489 #, c-format msgid "Could not read object %s" msgstr "Kunde inte läsa objektet %s" -#: builtin/log.c:507 +#: builtin/log.c:513 #, c-format msgid "Unknown type: %d" msgstr "Okänd typ: %d" -#: builtin/log.c:596 +#: builtin/log.c:602 msgid "format.headers without value" msgstr "format.headers utan värde" -#: builtin/log.c:669 +#: builtin/log.c:676 msgid "name of output directory is too long" msgstr "namnet pÃ¥ utdatakatalogen är för lÃ¥ngt" -#: builtin/log.c:680 +#: builtin/log.c:687 #, c-format msgid "Cannot open patch file %s" msgstr "Kan inte öppna patchfilen %s" -#: builtin/log.c:694 +#: builtin/log.c:701 msgid "Need exactly one range." msgstr "Behöver precis ett intervall." -#: builtin/log.c:702 +#: builtin/log.c:709 msgid "Not a range." msgstr "Inte ett intervall." -#: builtin/log.c:739 -msgid "Could not extract email from committer identity." -msgstr "Kunde inte extrahera e-postadress frÃ¥n incheckarens identitet." - -#: builtin/log.c:785 +#: builtin/log.c:786 msgid "Cover letter needs email format" msgstr "Omslagsbrevet behöver e-postformat" -#: builtin/log.c:879 +#: builtin/log.c:859 #, c-format msgid "insane in-reply-to: %s" msgstr "tokigt in-reply-to: %s" -#: builtin/log.c:952 +#: builtin/log.c:932 msgid "Two output directories?" msgstr "TvÃ¥ utdatakataloger?" -#: builtin/log.c:1173 +#: builtin/log.c:1153 #, c-format msgid "bogus committer info %s" msgstr "felaktig incheckarinformation %s" -#: builtin/log.c:1218 +#: builtin/log.c:1198 msgid "-n and -k are mutually exclusive." msgstr "-n och -k kan inte användas samtidigt." -#: builtin/log.c:1220 +#: builtin/log.c:1200 msgid "--subject-prefix and -k are mutually exclusive." msgstr "--subject-prefix och -k kan inte användas samtidigt." -#: builtin/log.c:1225 builtin/shortlog.c:284 -#, c-format -msgid "unrecognized argument: %s" -msgstr "okänt argument: %s" - -#: builtin/log.c:1228 +#: builtin/log.c:1208 msgid "--name-only does not make sense" msgstr "kan inte använda --name-only" -#: builtin/log.c:1230 +#: builtin/log.c:1210 msgid "--name-status does not make sense" msgstr "kan inte använda --name-status" -#: builtin/log.c:1232 +#: builtin/log.c:1212 msgid "--check does not make sense" msgstr "kan inte använda --check" -#: builtin/log.c:1255 +#: builtin/log.c:1235 msgid "standard output, or directory, which one?" msgstr "standard ut, eller katalog, vilken skall det vara?" -#: builtin/log.c:1257 +#: builtin/log.c:1237 #, c-format msgid "Could not create directory '%s'" msgstr "Kunde inte skapa katalogen \"%s\"" -#: builtin/log.c:1410 +#: builtin/log.c:1390 msgid "Failed to create output files" msgstr "Misslyckades skapa utdatafiler" -#: builtin/log.c:1514 +#: builtin/log.c:1494 #, c-format msgid "" "Could not find a tracked remote branch, please specify manually.\n" msgstr "Kunde inte hitta en spÃ¥rad fjärrgren, ange manuellt.\n" -#: builtin/log.c:1530 builtin/log.c:1532 builtin/log.c:1544 +#: builtin/log.c:1510 builtin/log.c:1512 builtin/log.c:1524 #, c-format msgid "Unknown commit %s" msgstr "Okänd incheckning %s" @@ -2638,7 +3683,7 @@ msgstr "%s, källa=%s, mÃ¥l=%s" msgid "Renaming %s to %s\n" msgstr "Byter namn pÃ¥ %s till %s\n" -#: builtin/mv.c:215 +#: builtin/mv.c:215 builtin/remote.c:731 #, c-format msgid "renaming '%s' failed" msgstr "misslyckades byta namn pÃ¥ \"%s\"" @@ -2662,7 +3707,7 @@ msgstr "kunde inte stänga röret till \"show\" för objektet \"%s\"" msgid "failed to finish 'show' for object '%s'" msgstr "kunde inte avsluta \"show\" för objektet \"%s\"" -#: builtin/notes.c:175 builtin/tag.c:343 +#: builtin/notes.c:175 builtin/tag.c:347 #, c-format msgid "could not create file '%s'" msgstr "kunde inte skapa filen \"%s\"" @@ -2685,12 +3730,12 @@ msgstr "kunde inte skriva anteckningsobjekt" msgid "The note contents has been left in %s" msgstr "Anteckningens innehÃ¥ll har lämnats kvar i %s" -#: builtin/notes.c:251 builtin/tag.c:521 +#: builtin/notes.c:251 builtin/tag.c:542 #, c-format msgid "cannot read '%s'" msgstr "kunde inte läsa \"%s\"" -#: builtin/notes.c:253 builtin/tag.c:524 +#: builtin/notes.c:253 builtin/tag.c:545 #, c-format msgid "could not open or read '%s'" msgstr "kunde inte öppna eller läsa \"%s\"" @@ -2698,7 +3743,7 @@ msgstr "kunde inte öppna eller läsa \"%s\"" #: builtin/notes.c:272 builtin/notes.c:445 builtin/notes.c:447 #: builtin/notes.c:507 builtin/notes.c:561 builtin/notes.c:644 #: builtin/notes.c:649 builtin/notes.c:724 builtin/notes.c:766 -#: builtin/notes.c:968 builtin/reset.c:293 builtin/tag.c:537 +#: builtin/notes.c:968 builtin/reset.c:293 builtin/tag.c:558 #, c-format msgid "Failed to resolve '%s' as a valid ref." msgstr "Kunde inte slÃ¥ upp \"%s\" som en giltig referens." @@ -2796,27 +3841,27 @@ msgstr "" msgid "Object %s has no note\n" msgstr "Objektet %s har ingen anteckning\n" -#: builtin/notes.c:1103 +#: builtin/notes.c:1103 builtin/remote.c:1598 #, c-format msgid "Unknown subcommand: %s" msgstr "Okänt underkommando: %s" -#: builtin/pack-objects.c:2315 +#: builtin/pack-objects.c:2337 #, c-format msgid "unsupported index version %s" msgstr "indexversionen %s stöds ej" -#: builtin/pack-objects.c:2319 +#: builtin/pack-objects.c:2341 #, c-format msgid "bad index version '%s'" msgstr "felaktig indexversion \"%s\"" -#: builtin/pack-objects.c:2342 +#: builtin/pack-objects.c:2364 #, c-format msgid "option %s does not accept negative form" msgstr "flaggan %s godtar inte negativ form" -#: builtin/pack-objects.c:2346 +#: builtin/pack-objects.c:2368 #, c-format msgid "unable to parse value '%s' for option %s" msgstr "kunde inte tolka värdet \"%s\" för flaggan %s" @@ -2829,7 +3874,41 @@ msgstr "taggförkortning utan " msgid "--delete only accepts plain target ref names" msgstr "--delete godtar endast enkla mÃ¥lreferensnamn" -#: builtin/push.c:84 +#: builtin/push.c:99 +msgid "" +"\n" +"To choose either option permanently, see push.default in 'git help config'." +msgstr "" +"\n" +"För att välja ett av alternativen permanent, se push.default i \"git help " +"config\"." + +#: builtin/push.c:102 +#, c-format +msgid "" +"The upstream branch of your current branch does not match\n" +"the name of your current branch. To push to the upstream branch\n" +"on the remote, use\n" +"\n" +" git push %s HEAD:%s\n" +"\n" +"To push to the branch of the same name on the remote, use\n" +"\n" +" git push %s %s\n" +"%s" +msgstr "" +"Uppströmsgrenen för din nuvarande gren stämmer inte överens\n" +"med namnet pÃ¥ din aktuella gren. För att sända till uppströmsgrenen\n" +"i fjärrarkivet använder du\n" +"\n" +" git push %s HEAD:%s\n" +"\n" +"För att sända till grenen med samma namn i fjärrarkivet använder du\n" +"\n" +" git push %s %s\n" +"%s" + +#: builtin/push.c:121 #, c-format msgid "" "You are not currently on a branch.\n" @@ -2844,142 +3923,494 @@ msgstr "" "\n" " git push %s HEAD:\n" -#: builtin/push.c:91 +#: builtin/push.c:128 +#, c-format +msgid "" +"The current branch %s has no upstream branch.\n" +"To push the current branch and set the remote as upstream, use\n" +"\n" +" git push --set-upstream %s %s\n" +msgstr "" +"Den aktuella grenen %s har ingen uppströmsgren.\n" +"För att sända aktuell gren och ange fjärrarkiv som uppström använder du\n" +"\n" +" git push --set-upstream %s %s\n" + +#: builtin/push.c:136 +#, c-format +msgid "The current branch %s has multiple upstream branches, refusing to push." +msgstr "Den aktuella grenen %s har flera uppströmsgrenar, vägrar sända." + +#: builtin/push.c:139 +#, c-format +msgid "" +"You are pushing to remote '%s', which is not the upstream of\n" +"your current branch '%s', without telling me what to push\n" +"to update which remote branch." +msgstr "" +"Du sänder till fjärren \"%s\", som inte är uppströms för den\n" +"aktuella grenen \"%s\", utan att tala om för mig vad som\n" +"skall sändas för att uppdatera fjärrgrenen." + +#: builtin/push.c:174 +msgid "" +"You didn't specify any refspecs to push, and push.default is \"nothing\"." +msgstr "" +"Du angav inga referensspecifikationer att sända, och push.default är " +"\"nothing\"." + +#: builtin/push.c:181 +msgid "" +"Updates were rejected because the tip of your current branch is behind\n" +"its remote counterpart. Merge the remote changes (e.g. 'git pull')\n" +"before pushing again.\n" +"See the 'Note about fast-forwards' in 'git push --help' for details." +msgstr "" +"Uppdateringar avvisades dÃ¥ änden pÃ¥ din befintliga gren är bakom\n" +"dess fjärrmotsvarighet. SlÃ¥ ihop fjärrändringarna (t.ex. \"git pull\")\n" +"innan du sänder igen.\n" +"Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer." + +#: builtin/push.c:187 +msgid "" +"Updates were rejected because a pushed branch tip is behind its remote\n" +"counterpart. If you did not intend to push that branch, you may want to\n" +"specify branches to push or set the 'push.default' configuration\n" +"variable to 'current' or 'upstream' to push only the current branch." +msgstr "" +"Uppdateringar avvisades dÃ¥ änden pÃ¥ en insänd gren är bakom dess\n" +"fjärrmotsvarighet. Om det inte var meningen att sända in grenen, bör\n" +"du specificera grenar att sända, eller ändra inställningsvariabeln\n" +"\"push-default\" till \"current\" eller \"upstream\" för att endast sända\n" +"aktuell gren." + +#: builtin/push.c:193 +msgid "" +"Updates were rejected because a pushed branch tip is behind its remote\n" +"counterpart. Check out this branch and merge the remote changes\n" +"(e.g. 'git pull') before pushing again.\n" +"See the 'Note about fast-forwards' in 'git push --help' for details." +msgstr "" +"Uppdateringar avvisades dÃ¥ änden pÃ¥ en gren som sänds in är bakom dess\n" +"fjärrmotsvarighet. Checka ut grenen och slÃ¥ ihop fjärrändringarna (t.ex.\n" +"\"git pull\") innan du sänder igen.\n" +"Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer." + +#: builtin/push.c:233 +#, c-format +msgid "Pushing to %s\n" +msgstr "Sänder till %s\n" + +#: builtin/push.c:237 +#, c-format +msgid "failed to push some refs to '%s'" +msgstr "misslyckades sända vissa referenser till \"%s\"" + +#: builtin/push.c:269 +#, c-format +msgid "bad repository '%s'" +msgstr "felaktigt arkiv \"%s\"" + +#: builtin/push.c:270 +msgid "" +"No configured push destination.\n" +"Either specify the URL from the command-line or configure a remote " +"repository using\n" +"\n" +" git remote add \n" +"\n" +"and then push using the remote name\n" +"\n" +" git push \n" +msgstr "" +"Ingen destination har angivits.\n" +"Ange antingen URL:en pÃ¥ kommandoraden eller ställ in ett uppströmsarkiv med\n" +"\n" +" git remote add \n" +"\n" +"och sänd sedan med hjälp av fjärrnamnet\n" +"\n" +" git push \n" + +#: builtin/push.c:285 +msgid "--all and --tags are incompatible" +msgstr "--all och --tags är inkompatibla" + +#: builtin/push.c:286 +msgid "--all can't be combined with refspecs" +msgstr "--all kan inte kombineras med referensspecifikationer" + +#: builtin/push.c:291 +msgid "--mirror and --tags are incompatible" +msgstr "--mirror och --tags är inkompatibla" + +#: builtin/push.c:292 +msgid "--mirror can't be combined with refspecs" +msgstr "--mirror kan inte kombineras med referensspecifikationer" + +#: builtin/push.c:297 +msgid "--all and --mirror are incompatible" +msgstr "--all och --mirror är inkompatibla" + +#: builtin/push.c:385 +msgid "--delete is incompatible with --all, --mirror and --tags" +msgstr "--delete är imkompatibel med --all, --mirror och --tags" + +#: builtin/push.c:387 +msgid "--delete doesn't make sense without any refs" +msgstr "--delete kan inte användas utan referenser" + +#: builtin/remote.c:98 +#, c-format +msgid "Updating %s" +msgstr "Uppdaterar %s" + +#: builtin/remote.c:130 +msgid "" +"--mirror is dangerous and deprecated; please\n" +"\t use --mirror=fetch or --mirror=push instead" +msgstr "" +"--mirror är farlig och förÃ¥ldrad; använd\n" +"\t --mirror=fetch eller --mirror=push istället" + +#: builtin/remote.c:147 +#, c-format +msgid "unknown mirror argument: %s" +msgstr "okänt argument till mirror: %s" + +#: builtin/remote.c:185 +msgid "specifying a master branch makes no sense with --mirror" +msgstr "att ange en master-gren ger ingen mening med --mirror" + +#: builtin/remote.c:187 +msgid "specifying branches to track makes sense only with fetch mirrors" +msgstr "att ange grenar att spÃ¥ra ger mening bara med hämtningsspeglar" + +#: builtin/remote.c:195 builtin/remote.c:646 +#, c-format +msgid "remote %s already exists." +msgstr "fjärrarkivet %s finns redan." + +#: builtin/remote.c:199 builtin/remote.c:650 +#, c-format +msgid "'%s' is not a valid remote name" +msgstr "\"%s\" är inte ett giltigt namn pÃ¥ fjärrarkiv" + +#: builtin/remote.c:243 +#, c-format +msgid "Could not setup master '%s'" +msgstr "Kunde inte skapa master \"%s\"" + +#: builtin/remote.c:299 +#, c-format +msgid "more than one %s" +msgstr "mer än en %s" + +#: builtin/remote.c:339 +#, c-format +msgid "Could not get fetch map for refspec %s" +msgstr "Kunde inte hämta mappning för referensspecifikation %s" + +#: builtin/remote.c:440 builtin/remote.c:448 +msgid "(matching)" +msgstr "(matchande)" + +#: builtin/remote.c:452 +msgid "(delete)" +msgstr "(ta bort)" + +#: builtin/remote.c:595 builtin/remote.c:601 builtin/remote.c:607 +#, c-format +msgid "Could not append '%s' to '%s'" +msgstr "Kunde inte tillämpa \"%s\" pÃ¥ \"%s\"" + +#: builtin/remote.c:639 builtin/remote.c:792 builtin/remote.c:890 +#, c-format +msgid "No such remote: %s" +msgstr "Inget sÃ¥dant fjärrarkiv: %s" + +#: builtin/remote.c:656 +#, c-format +msgid "Could not rename config section '%s' to '%s'" +msgstr "Kunde inte byta namn pÃ¥ konfigurationssektionen \"%s\" till \"%s\"" + +#: builtin/remote.c:662 builtin/remote.c:799 +#, c-format +msgid "Could not remove config section '%s'" +msgstr "Kunde inte ta bort konfigurationssektionen \"%s\"" + +#: builtin/remote.c:677 +#, c-format +msgid "" +"Not updating non-default fetch refspec\n" +"\t%s\n" +"\tPlease update the configuration manually if necessary." +msgstr "" +"Uppdaterar inte icke-standard hämtningsreferensspecifikation\n" +"\t%s\n" +"\tUppdatera konfigurationen manuellt om nödvändigt." + +#: builtin/remote.c:683 +#, c-format +msgid "Could not append '%s'" +msgstr "Kunde inte lägga till pÃ¥ \"%s\"" + +#: builtin/remote.c:694 +#, c-format +msgid "Could not set '%s'" +msgstr "Kunde inte sätta \"%s\"" + +#: builtin/remote.c:716 +#, c-format +msgid "deleting '%s' failed" +msgstr "misslyckades ta bort \"%s\"" + +#: builtin/remote.c:750 +#, c-format +msgid "creating '%s' failed" +msgstr "misslyckades skapa \"%s\"" + +#: builtin/remote.c:764 +#, c-format +msgid "Could not remove branch %s" +msgstr "Kunde inte ta bort grenen %s" + +#: builtin/remote.c:834 +msgid "" +"Note: A branch outside the refs/remotes/ hierarchy was not removed;\n" +"to delete it, use:" +msgid_plural "" +"Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n" +"to delete them, use:" +msgstr[0] "" +"Observera: En gren utanför hierarkin refs/remotes/ togs inte bort;\n" +"för att ta bort den, använd:" +msgstr[1] "" +"Observera: NÃ¥gra grenar utanför hierarkin refs/remotes/ togs inte bort;\n" +"för att ta bort dem, använd:" + +#: builtin/remote.c:943 +#, c-format +msgid " new (next fetch will store in remotes/%s)" +msgstr " ny (nästa hämtning sparar i remotes/%s)" + +#: builtin/remote.c:946 +msgid " tracked" +msgstr " spÃ¥rad" + +#: builtin/remote.c:948 +msgid " stale (use 'git remote prune' to remove)" +msgstr " förlegad (använd \"git remote prune\" för att ta bort)" + +#: builtin/remote.c:950 +msgid " ???" +msgstr " ???" + +#: builtin/remote.c:991 +#, c-format +msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch" +msgstr "ogiltig branch.%s.merge; kan inte ombasera över > 1 gren" + +#: builtin/remote.c:998 +#, c-format +msgid "rebases onto remote %s" +msgstr "ombaseras pÃ¥ fjärren %s" + +#: builtin/remote.c:1001 +#, c-format +msgid " merges with remote %s" +msgstr " sammanslÃ¥s med fjärren %s" + +#: builtin/remote.c:1002 +msgid " and with remote" +msgstr " och med fjärren" + +#: builtin/remote.c:1004 +#, c-format +msgid "merges with remote %s" +msgstr "sammanslÃ¥s med fjärren %s" + +#: builtin/remote.c:1005 +msgid " and with remote" +msgstr " och med fjärren" + +#: builtin/remote.c:1051 +msgid "create" +msgstr "skapa" + +#: builtin/remote.c:1054 +msgid "delete" +msgstr "ta bort" + +#: builtin/remote.c:1058 +msgid "up to date" +msgstr "àjour" + +#: builtin/remote.c:1061 +msgid "fast-forwardable" +msgstr "kan snabbspolas" + +#: builtin/remote.c:1064 +msgid "local out of date" +msgstr "lokal förÃ¥ldrad" + +#: builtin/remote.c:1071 +#, c-format +msgid " %-*s forces to %-*s (%s)" +msgstr " %-*s tvingar till %-*s (%s)" + +#: builtin/remote.c:1074 +#, c-format +msgid " %-*s pushes to %-*s (%s)" +msgstr " %-*s sänder till %-*s (%s)" + +#: builtin/remote.c:1078 +#, c-format +msgid " %-*s forces to %s" +msgstr " %-*s tvingar till %s" + +#: builtin/remote.c:1081 #, c-format -msgid "" -"The current branch %s has no upstream branch.\n" -"To push the current branch and set the remote as upstream, use\n" -"\n" -" git push --set-upstream %s %s\n" -msgstr "" -"Den aktuella grenen %s har ingen uppströmsgren.\n" -"För att sända aktuell gren och ange fjärrarkiv som uppström använder du\n" -"\n" -" git push --set-upstream %s %s\n" +msgid " %-*s pushes to %s" +msgstr " %-*s sänder till %s" -#: builtin/push.c:99 +#: builtin/remote.c:1118 #, c-format -msgid "The current branch %s has multiple upstream branches, refusing to push." -msgstr "Den aktuella grenen %s har flera uppströmsgrenar, vägrar sända." +msgid "* remote %s" +msgstr "* fjärr %s" -#: builtin/push.c:102 +#: builtin/remote.c:1119 #, c-format -msgid "" -"You are pushing to remote '%s', which is not the upstream of\n" -"your current branch '%s', without telling me what to push\n" -"to update which remote branch." -msgstr "" -"Du sänder till fjärren \"%s\", som inte är uppströms för den\n" -"aktuella grenen \"%s\", utan att tala om för mig vad som\n" -"skall sändas för att uppdatera fjärrgrenen." +msgid " Fetch URL: %s" +msgstr " Hämt-URL: %s" -#: builtin/push.c:131 -msgid "" -"You didn't specify any refspecs to push, and push.default is \"nothing\"." -msgstr "" -"Du angav inga referensspecifikationer att sända, och push.default är " -"\"nothing\"." +#: builtin/remote.c:1120 builtin/remote.c:1285 +msgid "(no URL)" +msgstr "(ingen URL)" -#: builtin/push.c:138 -msgid "" -"Updates were rejected because the tip of your current branch is behind\n" -"its remote counterpart. Merge the remote changes (e.g. 'git pull')\n" -"before pushing again.\n" -"See the 'Note about fast-forwards' in 'git push --help' for details." -msgstr "" -"Uppdateringar avvisades dÃ¥ änden pÃ¥ din befintliga gren är bakom\n" -"dess fjärrmotsvarighet. SlÃ¥ ihop fjärrändringarna (t.ex. \"git pull\")\n" -"innan du sänder igen.\n" -"Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer." +#: builtin/remote.c:1129 builtin/remote.c:1131 +#, c-format +msgid " Push URL: %s" +msgstr " Sänd-URL: %s" -#: builtin/push.c:144 -msgid "" -"Updates were rejected because a pushed branch tip is behind its remote\n" -"counterpart. If you did not intend to push that branch, you may want to\n" -"specify branches to push or set the 'push.default' configuration\n" -"variable to 'current' or 'upstream' to push only the current branch." -msgstr "" -"Uppdateringar avvisades dÃ¥ änden pÃ¥ en insänd gren är bakom dess\n" -"fjärrmotsvarighet. Om det inte var meningen att sända in grenen, bör\n" -"du specificera grenar att sända, eller ändra inställningsvariabeln\n" -"\"push-default\" till \"current\" eller \"upstream\" för att endast sända\n" -"aktuell gren." +#: builtin/remote.c:1133 builtin/remote.c:1135 builtin/remote.c:1137 +#, c-format +msgid " HEAD branch: %s" +msgstr " HEAD-gren: %s" -#: builtin/push.c:150 +#: builtin/remote.c:1139 +#, c-format msgid "" -"Updates were rejected because a pushed branch tip is behind its remote\n" -"counterpart. Check out this branch and merge the remote changes\n" -"(e.g. 'git pull') before pushing again.\n" -"See the 'Note about fast-forwards' in 'git push --help' for details." -msgstr "" -"Uppdateringar avvisades dÃ¥ änden pÃ¥ en gren som sänds in är bakom dess\n" -"fjärrmotsvarighet. Checka ut grenen och slÃ¥ ihop fjärrändringarna (t.ex.\n" -"\"git pull\") innan du sänder igen.\n" -"Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer." +" HEAD branch (remote HEAD is ambiguous, may be one of the following):\n" +msgstr " HEAD-gren (HEAD pÃ¥ fjärr är tvetydig, kan vara en av följande):\n" -#: builtin/push.c:190 +#: builtin/remote.c:1151 #, c-format -msgid "Pushing to %s\n" -msgstr "Sänder till %s\n" +msgid " Remote branch:%s" +msgid_plural " Remote branches:%s" +msgstr[0] " Fjärrgren:%s" +msgstr[1] " Fjärrgrenar:%s" + +#: builtin/remote.c:1154 builtin/remote.c:1181 +msgid " (status not queried)" +msgstr " (status inte förfrÃ¥gad)" + +#: builtin/remote.c:1163 +msgid " Local branch configured for 'git pull':" +msgid_plural " Local branches configured for 'git pull':" +msgstr[0] " Lokal gren konfigurerad för \"git pull\":" +msgstr[1] " Lokala grenar konfigurerade för \"git pull\":" -#: builtin/push.c:194 +#: builtin/remote.c:1171 +msgid " Local refs will be mirrored by 'git push'" +msgstr " Lokala referenser speglas av \"git push\"" + +#: builtin/remote.c:1178 #, c-format -msgid "failed to push some refs to '%s'" -msgstr "misslyckades sända vissa referenser till \"%s\"" +msgid " Local ref configured for 'git push'%s:" +msgid_plural " Local refs configured for 'git push'%s:" +msgstr[0] " Lokal referens konfigurerad för \"git push\"%s:" +msgstr[1] " Lokala referenser konfigurerade för \"git push\"%s:" + +#: builtin/remote.c:1216 +msgid "Cannot determine remote HEAD" +msgstr "Kan inte bestämma HEAD pÃ¥ fjärren" -#: builtin/push.c:226 +#: builtin/remote.c:1218 +msgid "Multiple remote HEAD branches. Please choose one explicitly with:" +msgstr "Flera HEAD-grenar pÃ¥ fjärren. Välj en explicit med:" + +#: builtin/remote.c:1228 #, c-format -msgid "bad repository '%s'" -msgstr "felaktigt arkiv \"%s\"" +msgid "Could not delete %s" +msgstr "Kunde inte ta bort %s" -#: builtin/push.c:227 -msgid "" -"No configured push destination.\n" -"Either specify the URL from the command-line or configure a remote " -"repository using\n" -"\n" -" git remote add \n" -"\n" -"and then push using the remote name\n" -"\n" -" git push \n" -msgstr "" -"Ingen destination har angivits.\n" -"Ange antingen URL:en pÃ¥ kommandoraden eller ställ in ett uppströmsarkiv med\n" -"\n" -" git remote add \n" -"\n" -"och sänd sedan med hjälp av fjärrnamnet\n" -"\n" -" git push \n" +#: builtin/remote.c:1236 +#, c-format +msgid "Not a valid ref: %s" +msgstr "Inte en giltig referens: %s" -#: builtin/push.c:242 -msgid "--all and --tags are incompatible" -msgstr "--all och --tags är inkompatibla" +#: builtin/remote.c:1238 +#, c-format +msgid "Could not setup %s" +msgstr "Kunde inte ställa in %s" -#: builtin/push.c:243 -msgid "--all can't be combined with refspecs" -msgstr "--all kan inte kombineras med referensspecifikationer" +#: builtin/remote.c:1274 +#, c-format +msgid " %s will become dangling!" +msgstr " %s kommer bli dinglande!" -#: builtin/push.c:248 -msgid "--mirror and --tags are incompatible" -msgstr "--mirror och --tags är inkompatibla" +#: builtin/remote.c:1275 +#, c-format +msgid " %s has become dangling!" +msgstr " %s har blivit dinglande!" -#: builtin/push.c:249 -msgid "--mirror can't be combined with refspecs" -msgstr "--mirror kan inte kombineras med referensspecifikationer" +#: builtin/remote.c:1281 +#, c-format +msgid "Pruning %s" +msgstr "Rensar %s" -#: builtin/push.c:254 -msgid "--all and --mirror are incompatible" -msgstr "--all och --mirror är inkompatibla" +#: builtin/remote.c:1282 +#, c-format +msgid "URL: %s" +msgstr "URL: %s" -#: builtin/push.c:334 -msgid "--delete is incompatible with --all, --mirror and --tags" -msgstr "--delete är imkompatibel med --all, --mirror och --tags" +#: builtin/remote.c:1295 +#, c-format +msgid " * [would prune] %s" +msgstr " * [skulle rensa] %s" -#: builtin/push.c:336 -msgid "--delete doesn't make sense without any refs" -msgstr "--delete kan inte användas utan referenser" +#: builtin/remote.c:1298 +#, c-format +msgid " * [pruned] %s" +msgstr " * [rensad] %s" + +#: builtin/remote.c:1387 builtin/remote.c:1461 +#, c-format +msgid "No such remote '%s'" +msgstr "Ingen sÃ¥dan fjärr \"%s\"" + +#: builtin/remote.c:1414 +msgid "no remote specified" +msgstr "ingen fjärr angavs" + +#: builtin/remote.c:1447 +msgid "--add --delete doesn't make sense" +msgstr "--add --delete ger ingen mening" + +#: builtin/remote.c:1487 +#, c-format +msgid "Invalid old URL pattern: %s" +msgstr "Felaktig gammalt URL-mönster: %s" + +#: builtin/remote.c:1495 +#, c-format +msgid "No such URL found: %s" +msgstr "Ingen sÃ¥dan URL hittades: %s" + +#: builtin/remote.c:1497 +msgid "Will not delete all non-push URLs" +msgstr "Kommer inte ta bort alla icke-sänd-URL:er" #: builtin/reset.c:33 msgid "mixed" @@ -2993,6 +4424,10 @@ msgstr "mjuk" msgid "hard" msgstr "hÃ¥rd" +#: builtin/reset.c:33 +msgid "merge" +msgstr "sammanslagning" + #: builtin/reset.c:33 msgid "keep" msgstr "behÃ¥ll" @@ -3066,15 +4501,15 @@ msgstr "Kunde inte Ã¥terställa indexfilen till versionen \"%s\"." msgid "%s: %s cannot be used with %s" msgstr "%s: %s kan inte användas med %s" -#: builtin/revert.c:127 +#: builtin/revert.c:131 msgid "program error" msgstr "programfel" -#: builtin/revert.c:213 +#: builtin/revert.c:221 msgid "revert failed" msgstr "\"revert\" misslyckades" -#: builtin/revert.c:228 +#: builtin/revert.c:236 msgid "cherry-pick failed" msgstr "\"cherry-pick\" misslyckades" @@ -3120,32 +4555,32 @@ msgstr "git rm: kan inte ta bort %s" msgid "Missing author: %s" msgstr "Författare saknas: %s" -#: builtin/tag.c:58 +#: builtin/tag.c:60 #, c-format msgid "malformed object at '%s'" msgstr "felformat objekt vid \"%s\"" -#: builtin/tag.c:205 +#: builtin/tag.c:207 #, c-format msgid "tag name too long: %.*s..." msgstr "taggnamnet för lÃ¥ngt: %.*s..." -#: builtin/tag.c:210 +#: builtin/tag.c:212 #, c-format msgid "tag '%s' not found." msgstr "taggen \"%s\" hittades inte." -#: builtin/tag.c:225 +#: builtin/tag.c:227 #, c-format msgid "Deleted tag '%s' (was %s)\n" msgstr "Tog bort tagg \"%s\" (var %s)\n" -#: builtin/tag.c:237 +#: builtin/tag.c:239 #, c-format msgid "could not verify the tag '%s'" msgstr "kunde inte bekräfta taggen \"%s\"" -#: builtin/tag.c:247 +#: builtin/tag.c:249 msgid "" "\n" "#\n" @@ -3159,7 +4594,7 @@ msgstr "" "# Rader som inleds med \"#\" ignoreras.\n" "#\n" -#: builtin/tag.c:254 +#: builtin/tag.c:256 msgid "" "\n" "#\n" @@ -3175,167 +4610,362 @@ msgstr "" "# du vill.\n" "#\n" -#: builtin/tag.c:294 +#: builtin/tag.c:298 msgid "unable to sign the tag" msgstr "kunde inte signera taggen" -#: builtin/tag.c:296 +#: builtin/tag.c:300 msgid "unable to write tag file" msgstr "kunde inte skriva tagg-filen" -#: builtin/tag.c:321 +#: builtin/tag.c:325 msgid "bad object type." msgstr "felaktig objekttyp" -#: builtin/tag.c:334 +#: builtin/tag.c:338 msgid "tag header too big." msgstr "tagghuvud för stort." -#: builtin/tag.c:366 +#: builtin/tag.c:370 msgid "no tag message?" msgstr "inget taggmeddelande?" -#: builtin/tag.c:372 +#: builtin/tag.c:376 #, c-format msgid "The tag message has been left in %s\n" msgstr "Taggmeddelandet har lämnats i %s\n" -#: builtin/tag.c:421 +#: builtin/tag.c:425 msgid "switch 'points-at' requires an object" msgstr "flaggan \"points-at\" behöver ett object" -#: builtin/tag.c:423 +#: builtin/tag.c:427 #, c-format msgid "malformed object name '%s'" msgstr "felformat objektnamn \"%s\"" -#: builtin/tag.c:502 +#: builtin/tag.c:506 +msgid "--column and -n are incompatible" +msgstr "--column och -n är inkompatibla" + +#: builtin/tag.c:523 msgid "-n option is only allowed with -l." msgstr "Flaggan -n är endast tillÃ¥ten tillsammans med -l." -#: builtin/tag.c:504 +#: builtin/tag.c:525 msgid "--contains option is only allowed with -l." msgstr "Flaggan --contains är endast tillÃ¥ten tillsammans med -l" -#: builtin/tag.c:506 +#: builtin/tag.c:527 msgid "--points-at option is only allowed with -l." msgstr "Flaggan --points-at är endast tillÃ¥ten tillsammans med -l." -#: builtin/tag.c:514 +#: builtin/tag.c:535 msgid "only one -F or -m option is allowed." msgstr "endast en av flaggorna -F eller -m tillÃ¥ts." -#: builtin/tag.c:534 +#: builtin/tag.c:555 msgid "too many params" msgstr "för mÃ¥nga parametrar" -#: builtin/tag.c:540 +#: builtin/tag.c:561 #, c-format msgid "'%s' is not a valid tag name." msgstr "\"%s\" är inte ett giltigt taggnamn." -#: builtin/tag.c:545 +#: builtin/tag.c:566 #, c-format msgid "tag '%s' already exists" msgstr "taggen \"%s\" finns redan" -#: builtin/tag.c:563 +#: builtin/tag.c:584 #, c-format msgid "%s: cannot lock the ref" msgstr "%s: kan inte lÃ¥sa referensen" -#: builtin/tag.c:565 +#: builtin/tag.c:586 #, c-format msgid "%s: cannot update the ref" msgstr "%s: kan inte uppdatera referensen" -#: builtin/tag.c:567 +#: builtin/tag.c:588 #, c-format msgid "Updated tag '%s' (was %s)\n" msgstr "Uppdaterad tagg \"%s\" (var %s)\n" -#: git-am.sh:49 +#: git.c:16 +msgid "See 'git help ' for more information on a specific command." +msgstr "" +"Se \"git help \" för mer information om ett specifikt kommando." + +#: parse-options.h:133 parse-options.h:235 +msgid "n" +msgstr "n" + +#: parse-options.h:141 +msgid "time" +msgstr "tid" + +# %s är ett verb ("Untracked"/"Ignored"); lägg till ett -e. +#: parse-options.h:149 +msgid "file" +msgstr "fil" + +#: parse-options.h:151 +msgid "when" +msgstr "när" + +#: parse-options.h:156 +msgid "no-op (backward compatibility)" +msgstr "ingen funktion (bakÃ¥tkompatibilitet)" + +#: parse-options.h:228 +msgid "be more verbose" +msgstr "var mer pratsam" + +#: parse-options.h:230 +msgid "be more quiet" +msgstr "var mer tyst" + +#: parse-options.h:236 +msgid "use digits to display SHA-1s" +msgstr "använd siffror för att visa SHA-1:or" + +#: common-cmds.h:8 +msgid "Add file contents to the index" +msgstr "Lägg filinnehÃ¥ll till indexet" + +#: common-cmds.h:9 +msgid "Find by binary search the change that introduced a bug" +msgstr "Binärsök för att hitta ändringen som introducerade ett fel" + +#: common-cmds.h:10 +msgid "List, create, or delete branches" +msgstr "Visa, skapa eller ta bort grenar" + +#: common-cmds.h:11 +msgid "Checkout a branch or paths to the working tree" +msgstr "Checka ut en gren eller filer i arbetskatalogen" + +#: common-cmds.h:12 +msgid "Clone a repository into a new directory" +msgstr "Klona ett arkiv till en ny katalog" + +#: common-cmds.h:13 +msgid "Record changes to the repository" +msgstr "Protokollför ändringar i arkivet" + +#: common-cmds.h:14 +msgid "Show changes between commits, commit and working tree, etc" +msgstr "Visa ändringar mellan incheckningar, med arbetskatalogen, osv" + +#: common-cmds.h:15 +msgid "Download objects and refs from another repository" +msgstr "Hämta objekt och referenser frÃ¥n annat arkiv" + +#: common-cmds.h:16 +msgid "Print lines matching a pattern" +msgstr "Visa rader som motsvarar mönster" + +#: common-cmds.h:17 +msgid "Create an empty git repository or reinitialize an existing one" +msgstr "Skapa tomt git-arkiv eller ominitiera ett befintligt" + +#: common-cmds.h:18 +msgid "Show commit logs" +msgstr "Visa incheckningsloggar" + +#: common-cmds.h:19 +msgid "Join two or more development histories together" +msgstr "SlÃ¥ ihop tvÃ¥ eller flera utvecklingshistorier" + +#: common-cmds.h:20 +msgid "Move or rename a file, a directory, or a symlink" +msgstr "Flytta eller byt namn pÃ¥ en fil, katalog eller symbolisk länk" + +#: common-cmds.h:21 +msgid "Fetch from and merge with another repository or a local branch" +msgstr "Hämta frÃ¥n och slÃ¥ ihop med annat arkiv eller en lokal gren" + +#: common-cmds.h:22 +msgid "Update remote refs along with associated objects" +msgstr "Uppdatera fjärr-referenser och tillhörande objekt" + +#: common-cmds.h:23 +msgid "Forward-port local commits to the updated upstream head" +msgstr "FramÃ¥tanpassa lokala kommandon pÃ¥ uppdaterat uppströmshuvud" + +#: common-cmds.h:24 +msgid "Reset current HEAD to the specified state" +msgstr "Återställ aktuell HEAD till angivet tillstÃ¥nd" + +#: common-cmds.h:25 +msgid "Remove files from the working tree and from the index" +msgstr "Ta bort filer frÃ¥n arbetskatalogen och frÃ¥n indexet" + +#: common-cmds.h:26 +msgid "Show various types of objects" +msgstr "Visa olika sorters objekt" + +#: common-cmds.h:27 +msgid "Show the working tree status" +msgstr "Visa status för arbetskatalogen" + +#: common-cmds.h:28 +msgid "Create, list, delete or verify a tag object signed with GPG" +msgstr "Skapa, visa, ta bort eller verifiera ett taggobjekt signerat med GPG" + +#: git-am.sh:50 msgid "You need to set your committer info first" msgstr "Du mÃ¥ste ställa in din incheckarinformation först" -#: git-am.sh:136 +#: git-am.sh:95 +msgid "" +"You seem to have moved HEAD since the last 'am' failure.\n" +"Not rewinding to ORIG_HEAD" +msgstr "" +"Du verkar ha flyttat HEAD sedan \"am\" sist misslyckades.\n" +"Återställer inte till ORIG_HEAD" + +#: git-am.sh:105 +#, sh-format +msgid "" +"When you have resolved this problem run \"$cmdline --resolved\".\n" +"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n" +"To restore the original branch and stop patching run \"$cmdline --abort\"." +msgstr "" +"När du har löst problemet kör du \"$cmdline --resolved\".\n" +"Om du vill hoppa över patchen kör du istället \"$cmdline --skip\".\n" +"För att Ã¥terställa originalgrenen och avbryta kör du \"$cmdline --abort\"." + +#: git-am.sh:121 +msgid "Cannot fall back to three-way merge." +msgstr "Kan inte falla tillbaka pÃ¥ trevägssammanslagning." + +#: git-am.sh:137 msgid "Repository lacks necessary blobs to fall back on 3-way merge." msgstr "" "Arkivet saknar objekt som behövs för att falla tillbaka pÃ¥ 3-" "vägssammanslagning." -#: git-am.sh:147 +#: git-am.sh:154 msgid "" "Did you hand edit your patch?\n" "It does not apply to blobs recorded in its index." msgstr "" "Har du handredigerat din patch?\n" -"Den kan inte appliceras pÃ¥ blobbar som antecknats i dess index." +"Den kan inte tillämpas pÃ¥ blobbar som antecknats i dess index." -#: git-am.sh:156 +#: git-am.sh:163 msgid "Falling back to patching base and 3-way merge..." msgstr "" "Faller tillbaka pÃ¥ att pacha grundversionen och trevägssammanslagning..." -#: git-am.sh:268 +#: git-am.sh:275 msgid "Only one StGIT patch series can be applied at once" -msgstr "Endast en StGIT-patchserie kan appliceras Ã¥t gÃ¥ngen" +msgstr "Endast en StGIT-patchserie kan tillämpas Ã¥t gÃ¥ngen" -#: git-am.sh:355 +#: git-am.sh:362 #, sh-format msgid "Patch format $patch_format is not supported." msgstr "Patchformatet $patch_format stöds inte." -#: git-am.sh:357 +#: git-am.sh:364 msgid "Patch format detection failed." msgstr "Misslyckades detektera patchformat." -#: git-am.sh:411 +#: git-am.sh:418 msgid "-d option is no longer supported. Do not use." msgstr "Flaggan -d stöds inte lägre. Använd inte." -#: git-am.sh:474 +#: git-am.sh:481 #, sh-format msgid "previous rebase directory $dotest still exists but mbox given." msgstr "tidigare rebase-katalog $dotest finns fortfarande, men mbox angavs." -#: git-am.sh:479 +#: git-am.sh:486 msgid "Please make up your mind. --skip or --abort?" msgstr "Bestäm dig. --skip eller --abort?" -#: git-am.sh:506 +#: git-am.sh:513 msgid "Resolve operation not in progress, we are not resuming." msgstr "Lösningsoperation pÃ¥gÃ¥r inte, vi Ã¥terupptar inte." -#: git-am.sh:572 +#: git-am.sh:579 #, sh-format msgid "Dirty index: cannot apply patches (dirty: $files)" -msgstr "Smutsigt index: kan inte applicera patchar (smutsiga: $files)" +msgstr "Smutsigt index: kan inte tillämpa patchar (smutsiga: $files)" -#: git-am.sh:748 +#: git-am.sh:671 +#, sh-format +msgid "" +"Patch is empty. Was it split wrong?\n" +"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n" +"To restore the original branch and stop patching run \"$cmdline --abort\"." +msgstr "" +"Patchen är tom. Delades den upp felaktigt?\n" +"Om du vill hoppa över patchen kör du istället \"$cmdline --skip\".\n" +"För att Ã¥terställa originalgrenen och avbryta kör du \"$cmdline --abort\"." + +#: git-am.sh:708 +msgid "Patch does not have a valid e-mail address." +msgstr "Patchen har inte nÃ¥gon giltig e-postadress." + +#: git-am.sh:755 msgid "cannot be interactive without stdin connected to a terminal." msgstr "" "kan inte vara interaktiv om standard in inte är ansluten till en terminal." +#: git-am.sh:759 +msgid "Commit Body is:" +msgstr "Incheckningskroppen är:" + #. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a] #. in your translation. The program will only accept English #. input at this point. -#: git-am.sh:759 +#: git-am.sh:766 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all " -msgstr "Applicera? Y=ja/N=nej/E=redigera/V=visa patch/A=godta alla " +msgstr "Tillämpa? Y=ja/N=nej/E=redigera/V=visa patch/A=godta alla " -#: git-am.sh:795 +#: git-am.sh:802 #, sh-format msgid "Applying: $FIRSTLINE" -msgstr "Applicerar: $FIRSTLINE" +msgstr "Tillämpar: $FIRSTLINE" -#: git-am.sh:840 +#: git-am.sh:823 +msgid "" +"No changes - did you forget to use 'git add'?\n" +"If there is nothing left to stage, chances are that something else\n" +"already introduced the same changes; you might want to skip this patch." +msgstr "" +"Inga ändringar - glömde du använda \"git add\"?\n" +"Om det inte är nÃ¥got kvar att köa kan det hända att nÃ¥got annat redan\n" +"introducerat samma ändringar; kanske du bör hoppa över patchen." + +#: git-am.sh:831 +msgid "" +"You still have unmerged paths in your index\n" +"did you forget to use 'git add'?" +msgstr "" +"Du har fortfarande sökvägar som inte slagits samman i ditt index\n" +"glömde du använda \"git add\"?" + +#: git-am.sh:847 msgid "No changes -- Patch already applied." -msgstr "Inga ändringar -- Patchen har redan applicerats." +msgstr "Inga ändringar -- Patchen har redan tillämpats." + +#: git-am.sh:857 +#, sh-format +msgid "Patch failed at $msgnum $FIRSTLINE" +msgstr "Patchen misslyckades vid $msgnum $FIRSTLINE" -#: git-am.sh:866 +#: git-am.sh:873 msgid "applying to an empty history" -msgstr "applicerar pÃ¥ en tom historik" +msgstr "tillämpar pÃ¥ en tom historik" + +#: git-bisect.sh:48 +msgid "You need to start by \"git bisect start\"" +msgstr "Du mÃ¥ste starta med \"git bisect start\"" #. TRANSLATORS: Make sure to include [Y] and [n] in your #. translation. The program will only accept English input @@ -3398,6 +5028,12 @@ msgstr "Felaktig rev-indata: $rev" msgid "'git bisect bad' can take only one argument." msgstr "\"git bisect bad\" kan bara ta ett argument." +#. have bad but not good. we could bisect although +#. this is less optimum. +#: git-bisect.sh:273 +msgid "Warning: bisecting only with a bad commit." +msgstr "Varning: utför \"bisect\" med endast en dÃ¥lig incheckning" + #. TRANSLATORS: Make sure to include [Y] and [n] in your #. translation. The program will only accept English input #. at this point. @@ -3405,6 +5041,28 @@ msgstr "\"git bisect bad\" kan bara ta ett argument." msgid "Are you sure [Y/n]? " msgstr "Är du säker [Y=ja/N=nej]? " +#: git-bisect.sh:289 +msgid "" +"You need to give me at least one good and one bad revisions.\n" +"(You can use \"git bisect bad\" and \"git bisect good\" for that.)" +msgstr "" +"Du mÃ¥ste ange Ã¥tminstone en bra och en dÃ¥lig version.\n" +"(Du kan använda \"git bisect bad\" och \"git bisect good\" för detta.)" + +#: git-bisect.sh:292 +msgid "" +"You need to start by \"git bisect start\".\n" +"You then need to give me at least one good and one bad revisions.\n" +"(You can use \"git bisect bad\" and \"git bisect good\" for that.)" +msgstr "" +"Du mÃ¥ste starta med \"git bisect start\".\n" +"Du mÃ¥ste sedan ange Ã¥tminstone en bra och en dÃ¥lig version.\n" +"(Du kan använda \"git bisect bad\" och \"git bisect good\" för detta.)" + +#: git-bisect.sh:347 git-bisect.sh:474 +msgid "We are not bisecting." +msgstr "Vi utför ingen bisect för tillfället." + #: git-bisect.sh:354 #, sh-format msgid "'$invalid' is not a valid commit" @@ -3432,9 +5090,36 @@ msgstr "kan inte läsa $file för uppspelning" msgid "?? what are you talking about?" msgstr "?? vad menar du?" -#: git-bisect.sh:474 -msgid "We are not bisecting." -msgstr "Vi utför ingen bisect för tillfället." +#: git-bisect.sh:420 +#, sh-format +msgid "running $command" +msgstr "kör $command" + +#: git-bisect.sh:427 +#, sh-format +msgid "" +"bisect run failed:\n" +"exit code $res from '$command' is < 0 or >= 128" +msgstr "" +"\"bisect\"-körningen misslyckades:\n" +"felkod $res frÃ¥n \"$command\" är < 0 eller >= 128" + +#: git-bisect.sh:453 +msgid "bisect run cannot continue any more" +msgstr "\"bisect\"-körningen kan inte fortsätta längre" + +#: git-bisect.sh:459 +#, sh-format +msgid "" +"bisect run failed:\n" +"'bisect_state $state' exited with error code $res" +msgstr "" +"\"bisect\"-körningen misslyckades:\n" +"\"bisect_state $state\" avslutades med felkoden $res" + +#: git-bisect.sh:466 +msgid "bisect run success" +msgstr "\"bisect\"-körningen lyckades" #: git-pull.sh:21 msgid "" @@ -3454,6 +5139,21 @@ msgstr "Du kan inte göra en \"pull\" dÃ¥ du har ändringar som inte checkats in msgid "updating an unborn branch with changes added to the index" msgstr "uppdaterar en ofödd gren med ändringar som lagts till i indexet" +#. The fetch involved updating the current branch. +#. The working tree and the index file is still based on the +#. $orig_head commit, but we are merging into $curr_head. +#. First update the working tree to match $curr_head. +#: git-pull.sh:228 +#, sh-format +msgid "" +"Warning: fetch updated the current branch head.\n" +"Warning: fast-forwarding your working tree from\n" +"Warning: commit $orig_head." +msgstr "" +"Varning: fetch uppdaterade huvudet för aktuell gren.\n" +"Varning: snabbspolar din arbetskatalog frÃ¥n\n" +"Varning: incheckningen $orig_head." + #: git-pull.sh:253 msgid "Cannot merge multiple branches into empty head" msgstr "Kan inte slÃ¥ ihop flera grenar i ett tomt huvud." @@ -3490,6 +5190,25 @@ msgstr "Kan inte ta bort temporärt index (kan inte inträffa)" msgid "Cannot record working tree state" msgstr "Kan inte registrera tillstÃ¥nd för arbetskatalog" +#. TRANSLATORS: $option is an invalid option, like +#. `--blah-blah'. The 7 spaces at the beginning of the +#. second line correspond to "error: ". So you should line +#. up the second line with however many characters the +#. translation of "error: " takes in your language. E.g. in +#. English this is: +#. +#. $ git stash save --blah-blah 2>&1 | head -n 2 +#. error: unknown option for 'stash save': --blah-blah +#. To provide a message, use git stash save -- '--blah-blah' +#: git-stash.sh:202 +#, sh-format +msgid "" +"error: unknown option for 'stash save': $option\n" +" To provide a message, use git stash save -- '$option'" +msgstr "" +"fel: felaktig flagga för \"stash save\": $option\n" +" För att ange ett meddelande, använd git stash save -- \"$option\"" + #: git-stash.sh:223 msgid "No local changes to save" msgstr "Inga lokala ändringar att spara" @@ -3536,7 +5255,7 @@ msgstr "kan inte uppdatera indexet" #: git-stash.sh:416 msgid "Cannot apply a stash in the middle of a merge" -msgstr "Kan inte applicera en \"stash\" mitt i en sammanslagning" +msgstr "Kan inte tillämpa en \"stash\" mitt i en sammanslagning" #: git-stash.sh:424 msgid "Conflicts in index. Try without --index." @@ -3550,6 +5269,10 @@ msgstr "Kunde inte spara indexträd" msgid "Cannot unstage modified files" msgstr "Kan inte ta bort ändrade filer ur kön" +#: git-stash.sh:474 +msgid "Index was not unstashed." +msgstr "Indexet har inte tagits ur kön." + #: git-stash.sh:491 #, sh-format msgid "Dropped ${REV} ($s)" @@ -3573,168 +5296,212 @@ msgstr "(För att Ã¥terställa dem, skriv \"git stash apply\")" msgid "cannot strip one component off url '$remoteurl'" msgstr "kan inte ta bort en komponent frÃ¥n url:en \"$remoteurl\"" -#: git-submodule.sh:108 +#: git-submodule.sh:109 #, sh-format -msgid "No submodule mapping found in .gitmodules for path '$path'" -msgstr "Hittade ingen undermodulmappning i .gitmodules för sökvägen \"$path\"" +msgid "No submodule mapping found in .gitmodules for path '$sm_path'" +msgstr "" +"Hittade ingen undermodulmappning i .gitmodules för sökvägen \"$sm_path\"" -#: git-submodule.sh:149 +#: git-submodule.sh:150 #, sh-format -msgid "Clone of '$url' into submodule path '$path' failed" -msgstr "Misslyckades klona \"$url\" till undermodulsökvägen \"$path\"" +msgid "Clone of '$url' into submodule path '$sm_path' failed" +msgstr "Misslyckades klona \"$url\" till undermodulsökvägen \"$sm_path\"" -#: git-submodule.sh:159 +#: git-submodule.sh:160 #, sh-format msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa" msgstr "Gitkatalog \"$a\" ingÃ¥r i underkatalogsökvägen \"$b\" eller omvänt" -#: git-submodule.sh:248 +#: git-submodule.sh:249 #, sh-format msgid "repo URL: '$repo' must be absolute or begin with ./|../" msgstr "arkiv-URL: \"$repo\" mÃ¥ste vara absolut eller börja med ./|../" -#: git-submodule.sh:265 +#: git-submodule.sh:266 #, sh-format -msgid "'$path' already exists in the index" -msgstr "\"$path\" finns redan i indexet" +msgid "'$sm_path' already exists in the index" +msgstr "\"$sm_path\" finns redan i indexet" -#: git-submodule.sh:282 +#: git-submodule.sh:270 #, sh-format -msgid "'$path' already exists and is not a valid git repo" -msgstr "\"$path\" finns redan och är inte ett giltigt git-arkiv" +msgid "" +"The following path is ignored by one of your .gitignore files:\n" +"$sm_path\n" +"Use -f if you really want to add it." +msgstr "" +"Följande sökvägar ignoreras av en av dina .gitignore-filer:\n" +"$sm_path\n" +"Använd -f om du verkligen vill lägga till den" -#: git-submodule.sh:296 +#: git-submodule.sh:281 #, sh-format -msgid "Unable to checkout submodule '$path'" -msgstr "Kan inte checka ut undermodul \"$path\"" +msgid "Adding existing repo at '$sm_path' to the index" +msgstr "Lägger till befintligt arkiv i \"$sm_path\" i indexet" -#: git-submodule.sh:301 +#: git-submodule.sh:283 #, sh-format -msgid "Failed to add submodule '$path'" -msgstr "Misslyckades lägga till underkatalog \"$path\"" +msgid "'$sm_path' already exists and is not a valid git repo" +msgstr "\"$sm_path\" finns redan och är inte ett giltigt git-arkiv" -#: git-submodule.sh:306 +#: git-submodule.sh:297 #, sh-format -msgid "Failed to register submodule '$path'" -msgstr "Misslyckades registrera undermodul \"$path\"" +msgid "Unable to checkout submodule '$sm_path'" +msgstr "Kan inte checka ut undermodulen \"$sm_path\"" -#: git-submodule.sh:348 +#: git-submodule.sh:302 #, sh-format -msgid "Entering '$prefix$path'" -msgstr "GÃ¥r in i \"$prefix$path\"" +msgid "Failed to add submodule '$sm_path'" +msgstr "Misslyckades lägga till undermodulen \"$sm_path\"" -#: git-submodule.sh:360 +#: git-submodule.sh:307 #, sh-format -msgid "Stopping at '$path'; script returned non-zero status." -msgstr "Stoppar pÃ¥ \"$path\"; skriptet returnerade en status skild frÃ¥n noll." +msgid "Failed to register submodule '$sm_path'" +msgstr "Misslyckades registrera undermodulen \"$sm_path\"" -#: git-submodule.sh:402 +#: git-submodule.sh:349 #, sh-format -msgid "No url found for submodule path '$path' in .gitmodules" -msgstr "Hittade ingen url för undermodulsökvägen \"$path\" i .gitmodules" +msgid "Entering '$prefix$sm_path'" +msgstr "GÃ¥r in i \"$prefix$sm_path\"" -#: git-submodule.sh:411 +#: git-submodule.sh:363 #, sh-format -msgid "Failed to register url for submodule path '$path'" -msgstr "Misslyckades registrera url för underkatalogsökväg \"$path\"" +msgid "Stopping at '$sm_path'; script returned non-zero status." +msgstr "" +"Stoppar pÃ¥ \"$sm_path\"; skriptet returnerade en status skild frÃ¥n noll." -#: git-submodule.sh:419 +#: git-submodule.sh:406 #, sh-format -msgid "Failed to register update mode for submodule path '$path'" -msgstr "" -"Misslyckades registrera uppdateringsläge för undermodulsökväg \"$path\"" +msgid "No url found for submodule path '$sm_path' in .gitmodules" +msgstr "Hittade ingen url för undermodulsökvägen \"$sm_path\" i .gitmodules" + +#: git-submodule.sh:415 +#, sh-format +msgid "Failed to register url for submodule path '$sm_path'" +msgstr "Misslyckades registrera url för underkatalogsökväg \"$sm_path\"" + +#: git-submodule.sh:417 +#, sh-format +msgid "Submodule '$name' ($url) registered for path '$sm_path'" +msgstr "Undermodulen \"$name\" ($url) registrerad för sökvägen \"$sm_path\"" -#: git-submodule.sh:421 +#: git-submodule.sh:425 #, sh-format -msgid "Submodule '$name' ($url) registered for path '$path'" -msgstr "Undermodulen \"$name\" ($url) registrerad för sökvägen \"$path\"" +msgid "Failed to register update mode for submodule path '$sm_path'" +msgstr "" +"Misslyckades registrera uppdateringsläge för undermodulsökväg \"$sm_path\"" -#: git-submodule.sh:520 +#: git-submodule.sh:524 #, sh-format msgid "" -"Submodule path '$path' not initialized\n" +"Submodule path '$sm_path' not initialized\n" "Maybe you want to use 'update --init'?" msgstr "" -"Undermodulen \"$path\" har inte initierats\n" +"Undermodulen \"$sm_path\" har inte initierats\n" "Kanske du vill köra \"update --init\"?" -#: git-submodule.sh:533 +#: git-submodule.sh:537 #, sh-format -msgid "Unable to find current revision in submodule path '$path'" -msgstr "Kan inte hitta aktuell revision i undermodulsökväg \"$path\"" +msgid "Unable to find current revision in submodule path '$sm_path'" +msgstr "Kan inte hitta aktuell revision i undermodulsökväg \"$sm_path\"" -#: git-submodule.sh:552 +#: git-submodule.sh:556 #, sh-format -msgid "Unable to fetch in submodule path '$path'" -msgstr "Kan inte hämta i undermodulsökväg \"$path\"" +msgid "Unable to fetch in submodule path '$sm_path'" +msgstr "Kan inte hämta i undermodulsökväg \"$sm_path\"" -#: git-submodule.sh:566 +#: git-submodule.sh:570 #, sh-format -msgid "Unable to rebase '$sha1' in submodule path '$path'" -msgstr "Kan inte göra \"rebase\" av \"$sha1\" i undermodulsökväg \"$path\"" +msgid "Unable to rebase '$sha1' in submodule path '$sm_path'" +msgstr "Kan inte ombasera \"$sha1\" i undermodulsökväg \"$sm_path\"" -#: git-submodule.sh:567 +#: git-submodule.sh:571 #, sh-format -msgid "Submodule path '$path': rebased into '$sha1'" -msgstr "Undermodulsökvägen \"$path\": \"rebase\":ad in i \"$sha1\"" +msgid "Submodule path '$sm_path': rebased into '$sha1'" +msgstr "Undermodulsökvägen \"$sm_path\": ombaserade in i \"$sha1\"" -#: git-submodule.sh:572 +#: git-submodule.sh:576 #, sh-format -msgid "Unable to merge '$sha1' in submodule path '$path'" -msgstr "Kan inte slÃ¥ ihop \"$sha1\" i undermodulsökvägen \"$path\"" +msgid "Unable to merge '$sha1' in submodule path '$sm_path'" +msgstr "Kan inte slÃ¥ ihop \"$sha1\" i undermodulsökvägen \"$sm_path\"" -#: git-submodule.sh:573 +#: git-submodule.sh:577 #, sh-format -msgid "Submodule path '$path': merged in '$sha1'" -msgstr "Undermodulsökvägen \"$path\": sammanslagen i \"$sha1\"" +msgid "Submodule path '$sm_path': merged in '$sha1'" +msgstr "Undermodulsökvägen \"$sm_path\": sammanslagen i \"$sha1\"" -#: git-submodule.sh:578 +#: git-submodule.sh:582 #, sh-format -msgid "Unable to checkout '$sha1' in submodule path '$path'" -msgstr "Kan inte checka ut \"$sha1\" i undermodulsökvägen \"$path\"" +msgid "Unable to checkout '$sha1' in submodule path '$sm_path'" +msgstr "Kan inte checka ut \"$sha1\" i undermodulsökvägen \"$sm_path\"" -#: git-submodule.sh:579 +#: git-submodule.sh:583 #, sh-format -msgid "Submodule path '$path': checked out '$sha1'" -msgstr "Undermodulsökvägen \"$path\": checkade ut \"$sha1\"" +msgid "Submodule path '$sm_path': checked out '$sha1'" +msgstr "Undermodulsökvägen \"$sm_path\": checkade ut \"$sha1\"" -#: git-submodule.sh:601 git-submodule.sh:924 +#: git-submodule.sh:605 git-submodule.sh:928 #, sh-format -msgid "Failed to recurse into submodule path '$path'" -msgstr "Misslyckades rekursera in i undermodulsökvägen \"$path\"" +msgid "Failed to recurse into submodule path '$sm_path'" +msgstr "Misslyckades rekursera in i undermodulsökvägen \"$sm_path\"" -#: git-submodule.sh:709 -msgid "--" -msgstr "--" +#: git-submodule.sh:713 +msgid "--cached cannot be used with --files" +msgstr "--cached kan inte användas med --files" -#: git-submodule.sh:767 +#. unexpected type +#: git-submodule.sh:753 +#, sh-format +msgid "unexpected mode $mod_dst" +msgstr "oväntat läge $mod_dst" + +#: git-submodule.sh:771 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_src" msgstr " Varning: $name innehÃ¥ller inte incheckning $sha1_src" -#: git-submodule.sh:770 +#: git-submodule.sh:774 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_dst" msgstr " Varning: $name innehÃ¥ller inte incheckning $sha1_dst" -#: git-submodule.sh:773 +#: git-submodule.sh:777 #, sh-format msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst" msgstr " Varning: $name innehÃ¥ller inte incheckningar $sha1_src och $sha1_dst" -#: git-submodule.sh:798 +#: git-submodule.sh:802 msgid "blob" msgstr "blob" -#: git-submodule.sh:799 +#: git-submodule.sh:803 msgid "submodule" msgstr "undermodul" -#: git-submodule.sh:970 +#: git-submodule.sh:840 +msgid "# Submodules changed but not updated:" +msgstr "# Undermoduler ändrade men inte uppdaterade:" + +#: git-submodule.sh:842 +msgid "# Submodule changes to be committed:" +msgstr "# Undermodulers ändringar att checka in:" + +#: git-submodule.sh:974 #, sh-format msgid "Synchronizing submodule url for '$name'" msgstr "Synkroniserar undermodul-url för \"$name\"" +#~ msgid "cherry-pick" +#~ msgstr "cherry-pick" + +#~ msgid "Please enter the commit message for your changes." +#~ msgstr "Ange ett incheckningsmeddelande för dina ändringar." + +#~ msgid "Could not extract email from committer identity." +#~ msgstr "Kunde inte extrahera e-postadress frÃ¥n incheckarens identitet." + +#~ msgid "--" +#~ msgstr "--" + #~ msgid "Too many options specified" #~ msgstr "För mÃ¥nga flaggor angavs" @@ -3846,62 +5613,3 @@ msgstr "Synkroniserar undermodul-url för \"$name\"" #~ msgid "signing key value too long (%.10s...)" #~ msgstr "signeringsnyckelvärdet för lÃ¥ngt (%.10s...)" - -#~ msgid "" -#~ "When you have resolved this problem run \"$cmdline --resolved\".\n" -#~ "If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n" -#~ "To restore the original branch and stop patching run \"$cmdline --abort\"." -#~ msgstr "" -#~ "När du har löst problemet kör du \"$cmdline --resolved\".\n" -#~ "Om du vill hoppa över patchen kör du istället \"$cmdline --skip\".\n" -#~ "För att Ã¥terställa originalgrenen och avbryta kör du \"$cmdline --abort\"." - -#~ msgid "" -#~ "Patch is empty. Was it split wrong?\n" -#~ "If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n" -#~ "To restore the original branch and stop patching run \"$cmdline --abort\"." -#~ msgstr "" -#~ "Patchen är tom. Delades den upp felaktigt?\n" -#~ "Om du vill hoppa över patchen kör du istället \"$cmdline --skip\".\n" -#~ "För att Ã¥terställa originalgrenen och avbryta kör du \"$cmdline --abort\"." - -#~ msgid "Patch does not have a valid e-mail address." -#~ msgstr "Patchen har inte nÃ¥gon giltig e-postadress." - -#~ msgid "Commit Body is:" -#~ msgstr "Incheckningskroppen är:" - -#~ msgid "" -#~ "No changes - did you forget to use 'git add'?\n" -#~ "If there is nothing left to stage, chances are that something else\n" -#~ "already introduced the same changes; you might want to skip this patch." -#~ msgstr "" -#~ "Inga ändringar - glömde du använda \"git add\"?\n" -#~ "Om det inte är nÃ¥got kvar att köa kan det hända att nÃ¥got annat redan\n" -#~ "introducerat samma ändringar; kanske du bör hoppa över patchen." - -#~ msgid "" -#~ "You still have unmerged paths in your index\n" -#~ "did you forget to use 'git add'?" -#~ msgstr "" -#~ "Du har fortfarande sökvägar som inte slagits samman i ditt index\n" -#~ "glömde du använda \"git add\"?" - -#~ msgid "Patch failed at $msgnum $FIRSTLINE" -#~ msgstr "Patchen misslyckades vid $msgnum $FIRSTLINE" - -#, fuzzy -#~ msgid "You need to start by \"git bisect start\"" -#~ msgstr "Du mÃ¥ste ställa in din incheckarinformation först" - -#, fuzzy -#~ msgid "Index was not unstashed." -#~ msgstr "kunde köra stash." - -#, fuzzy -#~ msgid "# Submodules changed but not updated:" -#~ msgstr "# Ändrade men inte uppdaterade:" - -#, fuzzy -#~ msgid "# Submodule changes to be committed:" -#~ msgstr "# Ändringar att checka in:" diff --git a/rerere.c b/rerere.c index dcb525a4d0..da18fc37df 100644 --- a/rerere.c +++ b/rerere.c @@ -544,13 +544,13 @@ static int do_plain_rerere(struct string_list *rr, int fd) if (has_rerere_resolution(name)) { if (!merge(name, path)) { - if (rerere_autoupdate) + const char *msg; + if (rerere_autoupdate) { string_list_insert(&update, path); - fprintf(stderr, - "%s '%s' using previous resolution.\n", - rerere_autoupdate - ? "Staged" : "Resolved", - path); + msg = "Staged '%s' using previous resolution.\n"; + } else + msg = "Resolved '%s' using previous resolution.\n"; + fprintf(stderr, msg, path); goto mark_resolved; } } diff --git a/revision.c b/revision.c index 935e7a7ba4..5b81a92e3a 100644 --- a/revision.c +++ b/revision.c @@ -1358,11 +1358,13 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->topo_order = 1; } else if (!strcmp(arg, "--simplify-merges")) { revs->simplify_merges = 1; + revs->topo_order = 1; revs->rewrite_parents = 1; revs->simplify_history = 0; revs->limited = 1; } else if (!strcmp(arg, "--simplify-by-decoration")) { revs->simplify_merges = 1; + revs->topo_order = 1; revs->rewrite_parents = 1; revs->simplify_history = 0; revs->simplify_by_decoration = 1; @@ -1781,7 +1783,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s * but the latter we have checked in the main loop. */ for (j = i; j < argc; j++) - verify_filename(revs->prefix, argv[j]); + verify_filename(revs->prefix, argv[j], j == i); append_prune_data(&prune_data, argv + i); break; @@ -1947,8 +1949,9 @@ static struct commit_list **simplify_one(struct rev_info *revs, struct commit *c } /* - * Do we know what commit all of our parents should be rewritten to? - * Otherwise we are not ready to rewrite this one yet. + * Do we know what commit all of our parents that matter + * should be rewritten to? Otherwise we are not ready to + * rewrite this one yet. */ for (cnt = 0, p = commit->parents; p; p = p->next) { pst = locate_simplify_state(revs, p->item); @@ -1956,6 +1959,8 @@ static struct commit_list **simplify_one(struct rev_info *revs, struct commit *c tail = &commit_list_insert(p->item, tail)->next; cnt++; } + if (revs->first_parent_only) + break; } if (cnt) { tail = &commit_list_insert(commit, tail)->next; @@ -1968,8 +1973,13 @@ static struct commit_list **simplify_one(struct rev_info *revs, struct commit *c for (p = commit->parents; p; p = p->next) { pst = locate_simplify_state(revs, p->item); p->item = pst->simplified; + if (revs->first_parent_only) + break; } - cnt = remove_duplicate_parents(commit); + if (!revs->first_parent_only) + cnt = remove_duplicate_parents(commit); + else + cnt = 1; /* * It is possible that we are a merge and one side branch @@ -2013,25 +2023,31 @@ static struct commit_list **simplify_one(struct rev_info *revs, struct commit *c static void simplify_merges(struct rev_info *revs) { - struct commit_list *list; + struct commit_list *list, *next; struct commit_list *yet_to_do, **tail; + struct commit *commit; - if (!revs->topo_order) - sort_in_topological_order(&revs->commits, revs->lifo); if (!revs->prune) return; /* feed the list reversed */ yet_to_do = NULL; - for (list = revs->commits; list; list = list->next) - commit_list_insert(list->item, &yet_to_do); + for (list = revs->commits; list; list = next) { + commit = list->item; + next = list->next; + /* + * Do not free(list) here yet; the original list + * is used later in this function. + */ + commit_list_insert(commit, &yet_to_do); + } while (yet_to_do) { list = yet_to_do; yet_to_do = NULL; tail = &yet_to_do; while (list) { - struct commit *commit = list->item; - struct commit_list *next = list->next; + commit = list->item; + next = list->next; free(list); list = next; tail = simplify_one(revs, commit, tail); @@ -2043,9 +2059,10 @@ static void simplify_merges(struct rev_info *revs) revs->commits = NULL; tail = &revs->commits; while (list) { - struct commit *commit = list->item; - struct commit_list *next = list->next; struct merge_simplify_state *st; + + commit = list->item; + next = list->next; free(list); list = next; st = locate_simplify_state(revs, commit); diff --git a/setup.c b/setup.c index 731851a4a8..e11497720e 100644 --- a/setup.c +++ b/setup.c @@ -4,7 +4,7 @@ static int inside_git_dir = -1; static int inside_work_tree = -1; -char *prefix_path(const char *prefix, int len, const char *path) +static char *prefix_path_gently(const char *prefix, int len, const char *path) { const char *orig = path; char *sanitized; @@ -31,7 +31,8 @@ char *prefix_path(const char *prefix, int len, const char *path) if (strncmp(sanitized, work_tree, len) || (len > root_len && sanitized[len] != '\0' && sanitized[len] != '/')) { error_out: - die("'%s' is outside repository", orig); + free(sanitized); + return NULL; } if (sanitized[len] == '/') len++; @@ -40,6 +41,25 @@ char *prefix_path(const char *prefix, int len, const char *path) return sanitized; } +char *prefix_path(const char *prefix, int len, const char *path) +{ + char *r = prefix_path_gently(prefix, len, path); + if (!r) + die("'%s' is outside repository", path); + return r; +} + +int path_inside_repo(const char *prefix, const char *path) +{ + int len = prefix ? strlen(prefix) : 0; + char *r = prefix_path_gently(prefix, len, path); + if (r) { + free(r); + return 1; + } + return 0; +} + int check_filename(const char *prefix, const char *arg) { const char *name; @@ -53,11 +73,17 @@ int check_filename(const char *prefix, const char *arg) die_errno("failed to stat '%s'", arg); } -static void NORETURN die_verify_filename(const char *prefix, const char *arg) +static void NORETURN die_verify_filename(const char *prefix, + const char *arg, + int diagnose_misspelt_rev) { unsigned char sha1[20]; unsigned mode; + if (!diagnose_misspelt_rev) + die("%s: no such path in the working tree.\n" + "Use '-- ...' to specify paths that do not exist locally.", + arg); /* * Saying "'(icase)foo' does not exist in the index" when the * user gave us ":(icase)foo" is just stupid. A magic pathspec @@ -80,14 +106,29 @@ static void NORETURN die_verify_filename(const char *prefix, const char *arg) * as true, because even if such a filename were to exist, we want * it to be preceded by the "--" marker (or we want the user to * use a format like "./-filename") + * + * The "diagnose_misspelt_rev" is used to provide a user-friendly + * diagnosis when dying upon finding that "name" is not a pathname. + * If set to 1, the diagnosis will try to diagnose "name" as an + * invalid object name (e.g. HEAD:foo). If set to 0, the diagnosis + * will only complain about an inexisting file. + * + * This function is typically called to check that a "file or rev" + * argument is unambiguous. In this case, the caller will want + * diagnose_misspelt_rev == 1 when verifying the first non-rev + * argument (which could have been a revision), and + * diagnose_misspelt_rev == 0 for the next ones (because we already + * saw a filename, there's not ambiguity anymore). */ -void verify_filename(const char *prefix, const char *arg) +void verify_filename(const char *prefix, + const char *arg, + int diagnose_misspelt_rev) { if (*arg == '-') die("bad flag '%s' used after filename", arg); if (check_filename(prefix, arg)) return; - die_verify_filename(prefix, arg); + die_verify_filename(prefix, arg, diagnose_misspelt_rev); } /* diff --git a/sha1_name.c b/sha1_name.c index c6331136d1..5d81ea0564 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -1127,7 +1127,7 @@ int get_sha1_with_context_1(const char *name, unsigned char *sha1, if (new_filename) filename = new_filename; ret = get_tree_entry(tree_sha1, filename, sha1, &oc->mode); - if (only_to_die) { + if (ret && only_to_die) { diagnose_invalid_sha1_path(prefix, filename, tree_sha1, object_name); free(object_name); diff --git a/t/README b/t/README index 3534f43d01..4c3ea25e66 100644 --- a/t/README +++ b/t/README @@ -307,6 +307,25 @@ Don't: Use test_done instead if you need to stop the tests early (see "Skipping tests" below). + - use '! git cmd' when you want to make sure the git command exits + with failure in a controlled way by calling "die()". Instead, + use 'test_must_fail git cmd'. This will signal a failure if git + dies in an unexpected way (e.g. segfault). + + - use perl without spelling it as "$PERL_PATH". This is to help our + friends on Windows where the platform Perl often adds CR before + the end of line, and they bundle Git with a version of Perl that + does not do so, whose path is specified with $PERL_PATH. + + - use sh without spelling it as "$SHELL_PATH", when the script can + be misinterpreted by broken platform shell (e.g. Solaris). + + - chdir around in tests. It is not sufficient to chdir to + somewhere and then chdir back to the original location later in + the test, as any intermediate step can fail and abort the test, + causing the next test to start in an unexpected directory. Do so + inside a subshell if necessary. + - Break the TAP output The raw output from your test may be interpreted by a TAP harness. TAP @@ -342,9 +361,9 @@ If you need to skip tests you should do so by using the three-arg form of the test_* functions (see the "Test harness library" section below), e.g.: - test_expect_success PERL 'I need Perl' " - '$PERL_PATH' -e 'hlagh() if unf_unf()' - " + test_expect_success PERL 'I need Perl' ' + "$PERL_PATH" -e "hlagh() if unf_unf()" + ' The advantage of skipping tests like this is that platforms that don't have the PERL and other optional dependencies get an indication of how diff --git a/t/lib-bash.sh b/t/lib-bash.sh new file mode 100644 index 0000000000..11397f747b --- /dev/null +++ b/t/lib-bash.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# +# Ensures that tests are run under Bash; primarily intended for running tests +# of the completion script. + +if test -n "$BASH" && test -z "$POSIXLY_CORRECT"; then + # we are in full-on bash mode + true +elif type bash >/dev/null 2>&1; then + # execute in full-on bash mode + unset POSIXLY_CORRECT + exec bash "$0" "$@" +else + echo '1..0 #SKIP skipping bash completion tests; bash not available' + exit 0 +fi + +. ./test-lib.sh diff --git a/t/lib-credential.sh b/t/lib-credential.sh index 4a37cd79e5..957ae936e8 100755 --- a/t/lib-credential.sh +++ b/t/lib-credential.sh @@ -4,10 +4,20 @@ # stdout and stderr should be provided on stdin, # separated by "--". check() { + credential_opts= + credential_cmd=$1 + shift + for arg in "$@"; do + credential_opts="$credential_opts -c credential.helper='$arg'" + done read_chunk >stdin && read_chunk >expect-stdout && read_chunk >expect-stderr && - test-credential "$@" stdout 2>stderr && + if ! eval "git $credential_opts credential $credential_cmd stdout 2>stderr"; then + echo "git credential failed with code $?" && + cat stderr && + false + fi && test_cmp expect-stdout stdout && test_cmp expect-stderr stderr } @@ -41,7 +51,7 @@ reject() { echo protocol=$2 echo host=$3 echo username=$4 - ) | test-credential reject $1 + ) | git -c credential.helper=$1 credential reject } helper_test() { @@ -52,6 +62,8 @@ helper_test() { protocol=https host=example.com -- + protocol=https + host=example.com username=askpass-username password=askpass-password -- @@ -74,6 +86,8 @@ helper_test() { protocol=https host=example.com -- + protocol=https + host=example.com username=store-user password=store-pass -- @@ -85,6 +99,8 @@ helper_test() { protocol=http host=example.com -- + protocol=http + host=example.com username=askpass-username password=askpass-password -- @@ -98,6 +114,8 @@ helper_test() { protocol=https host=other.tld -- + protocol=https + host=other.tld username=askpass-username password=askpass-password -- @@ -112,6 +130,8 @@ helper_test() { host=example.com username=other -- + protocol=https + host=example.com username=other password=askpass-password -- @@ -133,6 +153,9 @@ helper_test() { host=path.tld path=bar.git -- + protocol=http + host=path.tld + path=bar.git username=askpass-username password=askpass-password -- @@ -150,6 +173,8 @@ helper_test() { protocol=https host=example.com -- + protocol=https + host=example.com username=askpass-username password=askpass-password -- @@ -176,6 +201,8 @@ helper_test() { host=example.com username=user1 -- + protocol=https + host=example.com username=user1 password=pass1 EOF @@ -184,6 +211,8 @@ helper_test() { host=example.com username=user2 -- + protocol=https + host=example.com username=user2 password=pass2 EOF @@ -200,6 +229,8 @@ helper_test() { host=example.com username=user1 -- + protocol=https + host=example.com username=user1 password=askpass-password -- @@ -213,6 +244,8 @@ helper_test() { host=example.com username=user2 -- + protocol=https + host=example.com username=user2 password=pass2 EOF @@ -234,6 +267,8 @@ helper_test_timeout() { protocol=https host=timeout.tld -- + protocol=https + host=timeout.tld username=askpass-username password=askpass-password -- diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh index 20e28e34e7..538ea5fb1c 100755 --- a/t/t0300-credentials.sh +++ b/t/t0300-credentials.sh @@ -82,6 +82,9 @@ test_expect_success 'credential_fill passes along metadata' ' host=example.com path=foo.git -- + protocol=ftp + host=example.com + path=foo.git username=one password=two -- @@ -213,6 +216,8 @@ test_expect_success 'match configured credential' ' host=example.com path=repo.git -- + protocol=https + host=example.com username=foo password=bar -- @@ -225,6 +230,8 @@ test_expect_success 'do not match configured credential' ' protocol=https host=bar -- + protocol=https + host=bar username=askpass-username password=askpass-password -- @@ -239,6 +246,8 @@ test_expect_success 'pull username from config' ' protocol=https host=example.com -- + protocol=https + host=example.com username=foo password=askpass-password -- @@ -252,6 +261,8 @@ test_expect_success 'http paths can be part of context' ' host=example.com path=foo.git -- + protocol=https + host=example.com username=foo password=bar -- @@ -265,6 +276,9 @@ test_expect_success 'http paths can be part of context' ' host=example.com path=foo.git -- + protocol=https + host=example.com + path=foo.git username=foo password=bar -- diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh index b946f87686..df573c4978 100755 --- a/t/t1010-mktree.sh +++ b/t/t1010-mktree.sh @@ -42,13 +42,13 @@ test_expect_success 'ls-tree piped to mktree (2)' ' ' test_expect_success 'ls-tree output in wrong order given to mktree (1)' ' - perl -e "print reverse <>" " actual && test_cmp tree actual ' test_expect_success 'ls-tree output in wrong order given to mktree (2)' ' - perl -e "print reverse <>" " actual && test_cmp tree.withsub actual ' diff --git a/t/t1050-large.sh b/t/t1050-large.sh index 55ed955cef..fd10528009 100755 --- a/t/t1050-large.sh +++ b/t/t1050-large.sh @@ -130,10 +130,27 @@ test_expect_success 'git-show a large file' ' ' +test_expect_success 'index-pack' ' + git clone file://"`pwd`"/.git foo && + GIT_DIR=non-existent git index-pack --strict --verify foo/.git/objects/pack/*.pack +' + test_expect_success 'repack' ' git repack -ad ' +test_expect_success 'pack-objects with large loose object' ' + SHA1=`git hash-object huge` && + test_create_repo loose && + echo $SHA1 | git pack-objects --stdout | + GIT_ALLOC_LIMIT=0 GIT_DIR=loose/.git git unpack-objects && + echo $SHA1 | GIT_DIR=loose/.git git pack-objects pack && + test_create_repo packed && + mv pack-* packed/.git/objects/pack && + GIT_DIR=packed/.git git cat-file blob $SHA1 >actual && + cmp huge actual +' + test_expect_success 'tar achiving' ' git archive --format=tar HEAD >/dev/null ' diff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh index 2b962cfda7..79045abb51 100755 --- a/t/t1304-default-acl.sh +++ b/t/t1304-default-acl.sh @@ -14,16 +14,15 @@ umask 077 # We need an arbitrary other user give permission to using ACLs. root # is a good candidate: exists on all unices, and it has permission # anyway, so we don't create a security hole running the testsuite. - -setfacl_out="$(setfacl -m u:root:rwx . 2>&1)" -setfacl_ret=$? - -if test $setfacl_ret != 0 -then - say "Unable to use setfacl (output: '$setfacl_out'; return code: '$setfacl_ret')" -else - test_set_prereq SETFACL -fi +test_expect_success 'checking for a working acl setup' ' + if setfacl -m d:m:rwx -m u:root:rwx . && + getfacl . | grep user:root:rwx && + touch should-have-readable-acl && + getfacl should-have-readable-acl | egrep "mask::?rw-" + then + test_set_prereq SETFACL + fi +' if test -z "$LOGNAME" then diff --git a/t/t1306-xdg-files.sh b/t/t1306-xdg-files.sh new file mode 100755 index 0000000000..3c75c3f2e7 --- /dev/null +++ b/t/t1306-xdg-files.sh @@ -0,0 +1,158 @@ +#!/bin/sh +# +# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas, +# Thomas Nguy, Khoi Nguyen +# Grenoble INP Ensimag +# + +test_description='Compatibility with $XDG_CONFIG_HOME/git/ files' + +. ./test-lib.sh + +test_expect_success 'read config: xdg file exists and ~/.gitconfig doesn'\''t' ' + mkdir -p .config/git && + echo "[alias]" >.config/git/config && + echo " myalias = !echo in_config" >>.config/git/config && + echo in_config >expected && + git myalias >actual && + test_cmp expected actual +' + + +test_expect_success 'read config: xdg file exists and ~/.gitconfig exists' ' + >.gitconfig && + echo "[alias]" >.gitconfig && + echo " myalias = !echo in_gitconfig" >>.gitconfig && + echo in_gitconfig >expected && + git myalias >actual && + test_cmp expected actual +' + + +test_expect_success 'read with --get: xdg file exists and ~/.gitconfig doesn'\''t' ' + rm .gitconfig && + echo "[user]" >.config/git/config && + echo " name = read_config" >>.config/git/config && + echo read_config >expected && + git config --get user.name >actual && + test_cmp expected actual +' + + +test_expect_success 'read with --get: xdg file exists and ~/.gitconfig exists' ' + >.gitconfig && + echo "[user]" >.gitconfig && + echo " name = read_gitconfig" >>.gitconfig && + echo read_gitconfig >expected && + git config --get user.name >actual && + test_cmp expected actual +' + + +test_expect_success 'read with --list: xdg file exists and ~/.gitconfig doesn'\''t' ' + rm .gitconfig && + echo user.name=read_config >expected && + git config --global --list >actual && + test_cmp expected actual +' + + +test_expect_success 'read with --list: xdg file exists and ~/.gitconfig exists' ' + >.gitconfig && + echo "[user]" >.gitconfig && + echo " name = read_gitconfig" >>.gitconfig && + echo user.name=read_gitconfig >expected && + git config --global --list >actual && + test_cmp expected actual +' + + +test_expect_success 'Setup' ' + git init git && + cd git && + echo foo >to_be_excluded +' + + +test_expect_success 'Exclusion of a file in the XDG ignore file' ' + mkdir -p "$HOME"/.config/git/ && + echo to_be_excluded >"$HOME"/.config/git/ignore && + test_must_fail git add to_be_excluded +' + + +test_expect_success 'Exclusion in both XDG and local ignore files' ' + echo to_be_excluded >.gitignore && + test_must_fail git add to_be_excluded +' + + +test_expect_success 'Exclusion in a non-XDG global ignore file' ' + rm .gitignore && + echo >"$HOME"/.config/git/ignore && + echo to_be_excluded >"$HOME"/my_gitignore && + git config core.excludesfile "$HOME"/my_gitignore && + test_must_fail git add to_be_excluded +' + + +test_expect_success 'Checking attributes in the XDG attributes file' ' + echo foo >f && + git check-attr -a f >actual && + test_line_count -eq 0 actual && + echo "f attr_f" >"$HOME"/.config/git/attributes && + echo "f: attr_f: set" >expected && + git check-attr -a f >actual && + test_cmp expected actual +' + + +test_expect_success 'Checking attributes in both XDG and local attributes files' ' + echo "f -attr_f" >.gitattributes && + echo "f: attr_f: unset" >expected && + git check-attr -a f >actual && + test_cmp expected actual +' + + +test_expect_success 'Checking attributes in a non-XDG global attributes file' ' + test_might_fail rm .gitattributes && + echo "f attr_f=test" >"$HOME"/my_gitattributes && + git config core.attributesfile "$HOME"/my_gitattributes && + echo "f: attr_f: test" >expected && + git check-attr -a f >actual && + test_cmp expected actual +' + + +test_expect_success 'write: xdg file exists and ~/.gitconfig doesn'\''t' ' + mkdir -p "$HOME"/.config/git && + >"$HOME"/.config/git/config && + test_might_fail rm "$HOME"/.gitconfig && + git config --global user.name "write_config" && + echo "[user]" >expected && + echo " name = write_config" >>expected && + test_cmp expected "$HOME"/.config/git/config +' + + +test_expect_success 'write: xdg file exists and ~/.gitconfig exists' ' + >"$HOME"/.gitconfig && + git config --global user.name "write_gitconfig" && + echo "[user]" >expected && + echo " name = write_gitconfig" >>expected && + test_cmp expected "$HOME"/.gitconfig +' + + +test_expect_success 'write: ~/.config/git/ exists and config file doesn'\''t' ' + test_might_fail rm "$HOME"/.gitconfig && + test_might_fail rm "$HOME"/.config/git/config && + git config --global user.name "write_gitconfig" && + echo "[user]" >expected && + echo " name = write_gitconfig" >>expected && + test_cmp expected "$HOME"/.gitconfig +' + + +test_done diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh index 0843a1c13b..c5cb77a0e1 100755 --- a/t/t1506-rev-parse-diagnosis.sh +++ b/t/t1506-rev-parse-diagnosis.sh @@ -171,4 +171,15 @@ test_expect_success 'relative path when startup_info is NULL' ' grep "BUG: startup_info struct is not initialized." error ' +test_expect_success ':file correctly diagnosed after a pathname' ' + test_must_fail git rev-parse file.txt HEAD:file.txt 1>actual 2>error && + test_i18ngrep ! "exists on disk" error && + test_i18ngrep "no such path in the working tree" error && + cat >expect <<-\EOF && + file.txt + HEAD:file.txt + EOF + test_cmp expect actual +' + test_done diff --git a/t/t2017-checkout-orphan.sh b/t/t2017-checkout-orphan.sh index 0e3b8582f2..655f278c5f 100755 --- a/t/t2017-checkout-orphan.sh +++ b/t/t2017-checkout-orphan.sh @@ -116,4 +116,10 @@ test_expect_success '--orphan refuses to switch if a merge is needed' ' git reset --hard ' +test_expect_success 'cannot --detach on an unborn branch' ' + git checkout master && + git checkout --orphan new && + test_must_fail git checkout --detach +' + test_done diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh index c53c9f65eb..1f35e55ee3 100755 --- a/t/t3300-funny-names.sh +++ b/t/t3300-funny-names.sh @@ -71,7 +71,7 @@ test_expect_success 'ls-files -z does not quote funny filename' ' tabs ," (dq) and spaces EOF git ls-files -z >ls-files.z && - perl -pe "y/\000/\012/" current && + "$PERL_PATH" -pe "y/\000/\012/" current && test_cmp expected current ' @@ -108,7 +108,7 @@ test_expect_success 'diff-index -z does not quote funny filename' ' tabs ," (dq) and spaces EOF git diff-index -z --name-status $t0 >diff-index.z && - perl -pe "y/\000/\012/" current && + "$PERL_PATH" -pe "y/\000/\012/" current && test_cmp expected current ' @@ -118,7 +118,7 @@ test_expect_success 'diff-tree -z does not quote funny filename' ' tabs ," (dq) and spaces EOF git diff-tree -z --name-status $t0 $t1 >diff-tree.z && - perl -pe y/\\000/\\012/ current && + "$PERL_PATH" -pe y/\\000/\\012/ current && test_cmp expected current ' diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 025c1c610e..68d61480fb 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -755,4 +755,121 @@ test_expect_success 'rebase-i history with funny messages' ' test_cmp expect actual ' + +test_expect_success 'prepare for rebase -i --exec' ' + git checkout master && + git checkout -b execute && + test_commit one_exec main.txt one_exec && + test_commit two_exec main.txt two_exec && + test_commit three_exec main.txt three_exec +' + + +test_expect_success 'running "git rebase -i --exec git show HEAD"' ' + git rebase -i --exec "git show HEAD" HEAD~2 >actual && + ( + FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" && + export FAKE_LINES && + git rebase -i HEAD~2 >expect + ) && + sed -e "1,9d" expect >expected && + test_cmp expected actual +' + + +test_expect_success 'running "git rebase --exec git show HEAD -i"' ' + git reset --hard execute && + git rebase --exec "git show HEAD" -i HEAD~2 >actual && + ( + FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" && + export FAKE_LINES && + git rebase -i HEAD~2 >expect + ) && + sed -e "1,9d" expect >expected && + test_cmp expected actual +' + + +test_expect_success 'running "git rebase -ix git show HEAD"' ' + git reset --hard execute && + git rebase -ix "git show HEAD" HEAD~2 >actual && + ( + FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" && + export FAKE_LINES && + git rebase -i HEAD~2 >expect + ) && + sed -e "1,9d" expect >expected && + test_cmp expected actual +' + + +test_expect_success 'rebase -ix with several ' ' + git reset --hard execute && + git rebase -ix "git show HEAD; pwd" HEAD~2 >actual && + ( + FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" && + export FAKE_LINES && + git rebase -i HEAD~2 >expect + ) && + sed -e "1,9d" expect >expected && + test_cmp expected actual +' + + +test_expect_success 'rebase -ix with several instances of --exec' ' + git reset --hard execute && + git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual && + ( + FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2 + exec_git_show_HEAD exec_pwd" && + export FAKE_LINES && + git rebase -i HEAD~2 >expect + ) && + sed -e "1,11d" expect >expected && + test_cmp expected actual +' + + +test_expect_success 'rebase -ix with --autosquash' ' + git reset --hard execute && + git checkout -b autosquash && + echo second >second.txt && + git add second.txt && + git commit -m "fixup! two_exec" && + echo bis >bis.txt && + git add bis.txt && + git commit -m "fixup! two_exec" && + ( + git checkout -b autosquash_actual && + git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual + ) && + git checkout autosquash && + ( + git checkout -b autosquash_expected && + FAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" && + export FAKE_LINES && + git rebase -i HEAD~4 >expect + ) && + sed -e "1,13d" expect >expected && + test_cmp expected actual +' + + +test_expect_success 'rebase --exec without -i shows error message' ' + git reset --hard execute && + test_must_fail git rebase --exec "git show HEAD" HEAD~2 2>actual && + echo "--exec option must be used with --interactive option" >expected && + test_i18ncmp expected actual +' + + +test_expect_success 'rebase -i --exec without ' ' + git reset --hard execute && + test_must_fail git rebase -i --exec 2>tmp && + sed -e "1d" tmp >actual && + test_must_fail git rebase -h >expected && + test_cmp expected actual && + git checkout master +' + test_done diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index b473b6d6eb..959aa26ef5 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -243,7 +243,7 @@ check_threading () { (git format-patch --stdout "$@"; echo $? > status.out) | # Prints everything between the Message-ID and In-Reply-To, # and replaces all Message-ID-lookalikes by a sequence number - perl -ne ' + "$PERL_PATH" -ne ' if (/^(message-id|references|in-reply-to)/i) { $printing = 1; } elsif (/^\S/) { diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh index 083f62d1d6..533afc1185 100755 --- a/t/t4020-diff-external.sh +++ b/t/t4020-diff-external.sh @@ -118,7 +118,7 @@ test_expect_success 'no diff with -diff' ' git diff | grep Binary ' -echo NULZbetweenZwords | perl -pe 'y/Z/\000/' > file +echo NULZbetweenZwords | "$PERL_PATH" -pe 'y/Z/\000/' > file test_expect_success 'force diff with "diff"' ' echo >.gitattributes "file diff" && diff --git a/t/t4029-diff-trailing-space.sh b/t/t4029-diff-trailing-space.sh index 3ccc237a8d..36e2f075c9 100755 --- a/t/t4029-diff-trailing-space.sh +++ b/t/t4029-diff-trailing-space.sh @@ -27,7 +27,7 @@ test_expect_success \ git config --bool diff.suppressBlankEmpty true && git diff f > actual && test_cmp exp actual && - perl -i.bak -p -e "s/^\$/ /" exp && + "$PERL_PATH" -i.bak -p -e "s/^\$/ /" exp && git config --bool diff.suppressBlankEmpty false && git diff f > actual && test_cmp exp actual && diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh index d4ab4f2ccf..eebb1eed8b 100755 --- a/t/t4030-diff-textconv.sh +++ b/t/t4030-diff-textconv.sh @@ -21,7 +21,7 @@ EOF cat >hexdump <<'EOF' #!/bin/sh -perl -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1" +"$PERL_PATH" -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1" EOF chmod +x hexdump diff --git a/t/t4031-diff-rewrite-binary.sh b/t/t4031-diff-rewrite-binary.sh index c8296fa4fc..eacc6694f7 100755 --- a/t/t4031-diff-rewrite-binary.sh +++ b/t/t4031-diff-rewrite-binary.sh @@ -60,7 +60,7 @@ test_expect_success 'diff --stat counts binary rewrite as 0 lines' ' { echo "#!$SHELL_PATH" cat <<'EOF' -perl -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1" +"$PERL_PATH" -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1" EOF } >dump chmod +x dump diff --git a/t/t4035-diff-quiet.sh b/t/t4035-diff-quiet.sh index cdb9202f57..231412d100 100755 --- a/t/t4035-diff-quiet.sh +++ b/t/t4035-diff-quiet.sh @@ -10,7 +10,22 @@ test_expect_success 'setup' ' git commit -m first && echo 2 >b && git add . && - git commit -a -m second + git commit -a -m second && + mkdir -p test-outside/repo && ( + cd test-outside/repo && + git init && + echo "1 1" >a && + git add . && + git commit -m 1 + ) && + mkdir -p test-outside/non/git && ( + cd test-outside/non/git && + echo "1 1" >a && + echo "1 1" >matching-file && + echo "1 1 " >trailing-space && + echo "1 1" >extra-space && + echo "2" >never-match + ) ' test_expect_success 'git diff-tree HEAD^ HEAD' ' @@ -77,4 +92,60 @@ test_expect_success 'git diff-index --cached HEAD' ' } ' +test_expect_success 'git diff, one file outside repo' ' + ( + cd test-outside/repo && + test_expect_code 0 git diff --quiet a ../non/git/matching-file && + test_expect_code 1 git diff --quiet a ../non/git/extra-space + ) +' + +test_expect_success 'git diff, both files outside repo' ' + ( + GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/test-outside" && + export GIT_CEILING_DIRECTORIES && + cd test-outside/non/git && + test_expect_code 0 git diff --quiet a matching-file && + test_expect_code 1 git diff --quiet a extra-space + ) +' + +test_expect_success 'git diff --ignore-space-at-eol, one file outside repo' ' + ( + cd test-outside/repo && + test_expect_code 0 git diff --quiet --ignore-space-at-eol a ../non/git/trailing-space && + test_expect_code 1 git diff --quiet --ignore-space-at-eol a ../non/git/extra-space + ) +' + +test_expect_success 'git diff --ignore-space-at-eol, both files outside repo' ' + ( + GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/test-outside" && + export GIT_CEILING_DIRECTORIES && + cd test-outside/non/git && + test_expect_code 0 git diff --quiet --ignore-space-at-eol a trailing-space && + test_expect_code 1 git diff --quiet --ignore-space-at-eol a extra-space + ) +' + +test_expect_success 'git diff --ignore-all-space, one file outside repo' ' + ( + cd test-outside/repo && + test_expect_code 0 git diff --quiet --ignore-all-space a ../non/git/trailing-space && + test_expect_code 0 git diff --quiet --ignore-all-space a ../non/git/extra-space && + test_expect_code 1 git diff --quiet --ignore-all-space a ../non/git/never-match + ) +' + +test_expect_success 'git diff --ignore-all-space, both files outside repo' ' + ( + GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/test-outside" && + export GIT_CEILING_DIRECTORIES && + cd test-outside/non/git && + test_expect_code 0 git diff --quiet --ignore-all-space a trailing-space && + test_expect_code 0 git diff --quiet --ignore-all-space a extra-space && + test_expect_code 1 git diff --quiet --ignore-all-space a never-match + ) +' + test_done diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh index 4dc8c67edc..979e98398b 100755 --- a/t/t4053-diff-no-index.sh +++ b/t/t4053-diff-no-index.sh @@ -8,7 +8,12 @@ test_expect_success 'setup' ' mkdir a && mkdir b && echo 1 >a/1 && - echo 2 >a/2 + echo 2 >a/2 && + git init repo && + echo 1 >repo/a && + mkdir -p non/git && + echo 1 >non/git/a && + echo 1 >non/git/b ' test_expect_success 'git diff --no-index directories' ' @@ -16,4 +21,12 @@ test_expect_success 'git diff --no-index directories' ' test $? = 1 && test_line_count = 14 cnt ' +test_expect_success 'git diff --no-index relative path outside repo' ' + ( + cd repo && + test_expect_code 0 git diff --no-index a ../non/git/a && + test_expect_code 0 git diff --no-index ../non/git/a ../non/git/b + ) +' + test_done diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh index dbbf56cba9..99627bc6d6 100755 --- a/t/t4103-apply-binary.sh +++ b/t/t4103-apply-binary.sh @@ -25,10 +25,10 @@ test_expect_success 'setup' " git commit -m 'Initial Version' 2>/dev/null && git checkout -b binary && - perl -pe 'y/x/\000/' file3 && + "$PERL_PATH" -pe 'y/x/\000/' file3 && cat file3 >file4 && git add file2 && - perl -pe 'y/\000/v/' file1 && + "$PERL_PATH" -pe 'y/\000/v/' file1 && rm -f file2 && git update-index --add --remove file1 file2 file3 file4 && git commit -m 'Second Version' && diff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh index 2298ece801..fca815392e 100755 --- a/t/t4116-apply-reverse.sh +++ b/t/t4116-apply-reverse.sh @@ -12,14 +12,14 @@ test_description='git apply in reverse test_expect_success setup ' for i in a b c d e f g h i j k l m n; do echo $i; done >file1 && - perl -pe "y/ijk/\\000\\001\\002/" file2 && + "$PERL_PATH" -pe "y/ijk/\\000\\001\\002/" file2 && git add file1 file2 && git commit -m initial && git tag initial && for i in a b c g h i J K L m o n p q; do echo $i; done >file1 && - perl -pe "y/mon/\\000\\001\\002/" file2 && + "$PERL_PATH" -pe "y/mon/\\000\\001\\002/" file2 && git commit -a -m second && git tag second && diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 36255d608a..3ab670d36a 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -78,7 +78,7 @@ test_expect_success 'activate rerere, old style (conflicting merge)' ' test_might_fail git config --unset rerere.enabled && test_must_fail git merge first && - sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) && + sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) && rr=.git/rr-cache/$sha1 && grep "^=======\$" $rr/preimage && ! test -f $rr/postimage && @@ -91,7 +91,7 @@ test_expect_success 'rerere.enabled works, too' ' git reset --hard && test_must_fail git merge first && - sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) && + sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) && rr=.git/rr-cache/$sha1 && grep ^=======$ $rr/preimage ' @@ -101,7 +101,7 @@ test_expect_success 'set up rr-cache' ' git config rerere.enabled true && git reset --hard && test_must_fail git merge first && - sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) && + sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) && rr=.git/rr-cache/$sha1 ' @@ -185,7 +185,7 @@ test_expect_success 'rerere updates postimage timestamp' ' test_expect_success 'rerere clear' ' rm $rr/postimage && - echo "$sha1 a1" | perl -pe "y/\012/\000/" >.git/MERGE_RR && + echo "$sha1 a1" | "$PERL_PATH" -pe "y/\012/\000/" >.git/MERGE_RR && git rerere clear && ! test -d $rr ' diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index d9d856b87b..2e52f8b838 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -13,9 +13,9 @@ TRASH=`pwd` test_expect_success \ 'setup' \ 'rm -f .git/index* && - perl -e "print \"a\" x 4096;" > a && - perl -e "print \"b\" x 4096;" > b && - perl -e "print \"c\" x 4096;" > c && + "$PERL_PATH" -e "print \"a\" x 4096;" > a && + "$PERL_PATH" -e "print \"b\" x 4096;" > b && + "$PERL_PATH" -e "print \"c\" x 4096;" > c && test-genrandom "seed a" 2097152 > a_big && test-genrandom "seed b" 2097152 > b_big && git update-index --add a a_big b b_big c && @@ -129,7 +129,7 @@ test_expect_success \ cd "$TRASH" test_expect_success 'compare delta flavors' ' - perl -e '\'' + "$PERL_PATH" -e '\'' defined($_ = -s $_) or die for @ARGV; exit 1 if $ARGV[0] <= $ARGV[1]; '\'' test-2-$packname_2.pack test-3-$packname_3.pack @@ -418,4 +418,9 @@ test_expect_success \ 'test_must_fail git index-pack -o bad.idx test-3.pack 2>msg && grep "SHA1 COLLISION FOUND" msg' +test_expect_success \ + 'make sure index-pack detects the SHA1 collision (large blobs)' \ + 'test_must_fail git -c core.bigfilethreshold=1 index-pack -o bad.idx test-3.pack 2>msg && + grep "SHA1 COLLISION FOUND" msg' + test_done diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh index 5f6cd4f333..5b1250f0d2 100755 --- a/t/t5303-pack-corruption-resilience.sh +++ b/t/t5303-pack-corruption-resilience.sh @@ -98,7 +98,7 @@ test_expect_success \ 'create_new_pack && git prune-packed && chmod +w ${pack}.pack && - perl -i.bak -pe "s/ base /abcdef/" ${pack}.pack && + "$PERL_PATH" -i.bak -pe "s/ base /abcdef/" ${pack}.pack && test_must_fail git cat-file blob $blob_1 > /dev/null && test_must_fail git cat-file blob $blob_2 > /dev/null && test_must_fail git cat-file blob $blob_3 > /dev/null' @@ -155,7 +155,7 @@ test_expect_success \ 'create_new_pack && git prune-packed && chmod +w ${pack}.pack && - perl -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack && + "$PERL_PATH" -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack && git cat-file blob $blob_1 > /dev/null && test_must_fail git cat-file blob $blob_2 > /dev/null && test_must_fail git cat-file blob $blob_3 > /dev/null' diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 1d1ca98588..e80a2af348 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -125,6 +125,11 @@ test_expect_success 'single branch object count' ' test_cmp expected count.singlebranch ' +test_expect_success 'single given branch clone' ' + git clone --single-branch --branch A "file://$(pwd)/." branch-a && + test_must_fail git --git-dir=branch-a/.git rev-parse origin/B +' + test_expect_success 'clone shallow' ' git clone --no-single-branch --depth 2 "file://$(pwd)/." shallow ' @@ -276,7 +281,7 @@ test_expect_success 'clone shallow with --branch' ' ' test_expect_success 'clone shallow object count' ' - echo "in-pack: 12" > count3.expected && + echo "in-pack: 6" > count3.expected && GIT_DIR=shallow3/.git git count-objects -v | grep "^in-pack" > count3.actual && test_cmp count3.expected count3.actual diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh index 6764d511ce..d16e5d384a 100755 --- a/t/t5512-ls-remote.sh +++ b/t/t5512-ls-remote.sh @@ -87,17 +87,15 @@ test_expect_success 'use branch..remote if possible' ' test_expect_success 'confuses pattern as remote when no remote specified' ' cat >exp <<-\EOF && fatal: '\''refs*master'\'' does not appear to be a git repository - fatal: The remote end hung up unexpectedly + fatal: Could not read from remote repository. + + Please make sure you have the correct access rights + and the repository exists. EOF # - # Do not expect "git ls-remote " to work; ls-remote, correctly, - # confuses for . Although ugly, this behaviour is akin - # to the confusion of refspecs for remotes by git-fetch and git-push, - # eg: - # - # $ git fetch branch - # - + # Do not expect "git ls-remote " to work; ls-remote needs + # if you want to feed , just like you cannot say + # fetch . # We could just as easily have used "master"; the "*" emphasizes its # role as a pattern. test_must_fail git ls-remote refs*master >actual 2>&1 && diff --git a/t/t5532-fetch-proxy.sh b/t/t5532-fetch-proxy.sh index 62f2460047..5531bd1af4 100755 --- a/t/t5532-fetch-proxy.sh +++ b/t/t5532-fetch-proxy.sh @@ -15,7 +15,7 @@ test_expect_success 'setup remote repo' ' cat >proxy <<'EOF' #!/bin/sh echo >&2 "proxying for $*" -cmd=`perl -e ' +cmd=`"$PERL_PATH" -e ' read(STDIN, $buf, 4); my $n = hex($buf) - 4; read(STDIN, $buf, $n); diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh index be6094be77..fadf2f258e 100755 --- a/t/t5551-http-fetch.sh +++ b/t/t5551-http-fetch.sh @@ -130,7 +130,7 @@ test_expect_success EXPENSIVE 'create 50,000 tags in the repo' ' done | git fast-import --export-marks=marks && # now assign tags to all the dangling commits we created above - tag=$(perl -e "print \"bla\" x 30") && + tag=$("$PERL_PATH" -e "print \"bla\" x 30") && sed -e "s/^:\(.\+\) \(.\+\)$/\2 refs\/tags\/$tag-\1/" >packed-refs ) ' diff --git a/t/t5701-clone-local.sh b/t/t5701-clone-local.sh index c6feca44e3..7ff6e0e16c 100755 --- a/t/t5701-clone-local.sh +++ b/t/t5701-clone-local.sh @@ -124,4 +124,14 @@ test_expect_success 'cloning non-git directory fails' ' test_must_fail git clone not-a-git-repo not-a-git-repo-clone ' +test_expect_success 'cloning file:// does not hardlink' ' + git clone --bare file://"$(pwd)"/a non-local && + ! repo_is_hardlinked non-local +' + +test_expect_success 'cloning a local path with --no-local does not hardlink' ' + git clone --bare --no-local a force-nonlocal && + ! repo_is_hardlinked force-nonlocal +' + test_done diff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh index e51eb41f4b..bbb0581f88 100755 --- a/t/t6011-rev-list-with-bad-commit.sh +++ b/t/t6011-rev-list-with-bad-commit.sh @@ -37,7 +37,7 @@ test_expect_success 'verify number of revisions' \ test_expect_success 'corrupt second commit object' \ ' - perl -i.bak -pe "s/second commit/socond commit/" .git/objects/pack/*.pack && + "$PERL_PATH" -i.bak -pe "s/second commit/socond commit/" .git/objects/pack/*.pack && test_must_fail git fsck --full ' diff --git a/t/t6013-rev-list-reverse-parents.sh b/t/t6013-rev-list-reverse-parents.sh index 59fc2f06e0..892a537989 100755 --- a/t/t6013-rev-list-reverse-parents.sh +++ b/t/t6013-rev-list-reverse-parents.sh @@ -25,7 +25,7 @@ test_expect_success 'set up --reverse example' ' test_expect_success '--reverse --parents --full-history combines correctly' ' git rev-list --parents --full-history master -- foo | - perl -e "print reverse <>" > expected && + "$PERL_PATH" -e "print reverse <>" > expected && git rev-list --reverse --parents --full-history master -- foo \ > actual && test_cmp actual expected @@ -33,7 +33,7 @@ test_expect_success '--reverse --parents --full-history combines correctly' ' test_expect_success '--boundary does too' ' git rev-list --boundary --parents --full-history master ^root -- foo | - perl -e "print reverse <>" > expected && + "$PERL_PATH" -e "print reverse <>" > expected && git rev-list --boundary --reverse --parents --full-history \ master ^root -- foo > actual && test_cmp actual expected diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh index b8cb4906aa..f4f38a5e73 100755 --- a/t/t7060-wtstatus.sh +++ b/t/t7060-wtstatus.sh @@ -30,6 +30,9 @@ test_expect_success 'Report new path with conflict' ' cat >expect <..." as appropriate to mark resolution) # @@ -118,4 +121,97 @@ test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' ' test_cmp expected actual ' + +test_expect_success 'status when conflicts with add and rm advice (deleted by them)' ' + git reset --hard && + git checkout master && + test_commit init main.txt init && + git checkout -b second_branch && + git rm main.txt && + git commit -m "main.txt deleted on second_branch" && + test_commit second conflict.txt second && + git checkout master && + test_commit on_second main.txt on_second && + test_commit master conflict.txt master && + test_must_fail git merge second_branch && + cat >expected <<-\EOF && + # On branch master + # You have unmerged paths. + # (fix conflicts and run "git commit") + # + # Unmerged paths: + # (use "git add/rm ..." as appropriate to mark resolution) + # + # both added: conflict.txt + # deleted by them: main.txt + # + no changes added to commit (use "git add" and/or "git commit -a") + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'prepare for conflicts' ' + git reset --hard && + git checkout -b conflict && + test_commit one main.txt one && + git branch conflict_second && + git mv main.txt sub_master.txt && + git commit -m "main.txt renamed in sub_master.txt" && + git checkout conflict_second && + git mv main.txt sub_second.txt && + git commit -m "main.txt renamed in sub_second.txt" +' + + +test_expect_success 'status when conflicts with add and rm advice (both deleted)' ' + test_must_fail git merge conflict && + cat >expected <<-\EOF && + # On branch conflict_second + # You have unmerged paths. + # (fix conflicts and run "git commit") + # + # Unmerged paths: + # (use "git add/rm ..." as appropriate to mark resolution) + # + # both deleted: main.txt + # added by them: sub_master.txt + # added by us: sub_second.txt + # + no changes added to commit (use "git add" and/or "git commit -a") + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status when conflicts with only rm advice (both deleted)' ' + git reset --hard conflict_second && + test_must_fail git merge conflict && + git add sub_master.txt && + git add sub_second.txt && + cat >expected <<-\EOF && + # On branch conflict_second + # You have unmerged paths. + # (fix conflicts and run "git commit") + # + # Changes to be committed: + # + # new file: sub_master.txt + # + # Unmerged paths: + # (use "git rm ..." to mark resolution) + # + # both deleted: main.txt + # + # Untracked files not listed (use -u option to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual && + git reset --hard && + git checkout master +' + + test_done diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 81827e696f..c73bec9551 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -483,21 +483,72 @@ test_expect_success 'set up for relative path tests' ' git add sub && git config -f .gitmodules submodule.sub.path sub && git config -f .gitmodules submodule.sub.url ../subrepo && - cp .git/config pristine-.git-config + cp .git/config pristine-.git-config && + cp .gitmodules pristine-.gitmodules ) ' -test_expect_success 'relative path works with URL' ' +test_expect_success '../subrepo works with URL - ssh://hostname/repo' ' ( cd reltest && cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && git config remote.origin.url ssh://hostname/repo && git submodule init && test "$(git config submodule.sub.url)" = ssh://hostname/subrepo ) ' -test_expect_success 'relative path works with user@host:path' ' +test_expect_success '../subrepo works with port-qualified URL - ssh://hostname:22/repo' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + git config remote.origin.url ssh://hostname:22/repo && + git submodule init && + test "$(git config submodule.sub.url)" = ssh://hostname:22/subrepo + ) +' + +# About the choice of the path in the next test: +# - double-slash side-steps path mangling issues on Windows +# - it is still an absolute local path +# - there cannot be a server with a blank in its name just in case the +# path is used erroneously to access a //server/share style path +test_expect_success '../subrepo path works with local path - //somewhere else/repo' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + git config remote.origin.url "//somewhere else/repo" && + git submodule init && + test "$(git config submodule.sub.url)" = "//somewhere else/subrepo" + ) +' + +test_expect_success '../subrepo works with file URL - file:///tmp/repo' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + git config remote.origin.url file:///tmp/repo && + git submodule init && + test "$(git config submodule.sub.url)" = file:///tmp/subrepo + ) +' + +test_expect_success '../subrepo works with helper URL- helper:://hostname/repo' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + git config remote.origin.url helper:://hostname/repo && + git submodule init && + test "$(git config submodule.sub.url)" = helper:://hostname/subrepo + ) +' + +test_expect_success '../subrepo works with scp-style URL - user@host:repo' ' ( cd reltest && cp pristine-.git-config .git/config && @@ -507,6 +558,98 @@ test_expect_success 'relative path works with user@host:path' ' ) ' +test_expect_success '../subrepo works with scp-style URL - user@host:path/to/repo' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + git config remote.origin.url user@host:path/to/repo && + git submodule init && + test "$(git config submodule.sub.url)" = user@host:path/to/subrepo + ) +' + +test_expect_success '../subrepo works with relative local path - foo' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + git config remote.origin.url foo && + # actual: fails with an error + git submodule init && + test "$(git config submodule.sub.url)" = subrepo + ) +' + +test_expect_success '../subrepo works with relative local path - foo/bar' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + git config remote.origin.url foo/bar && + git submodule init && + test "$(git config submodule.sub.url)" = foo/subrepo + ) +' + +test_expect_success '../subrepo works with relative local path - ./foo' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + git config remote.origin.url ./foo && + git submodule init && + test "$(git config submodule.sub.url)" = subrepo + ) +' + +test_expect_success '../subrepo works with relative local path - ./foo/bar' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + git config remote.origin.url ./foo/bar && + git submodule init && + test "$(git config submodule.sub.url)" = foo/subrepo + ) +' + +test_expect_success '../subrepo works with relative local path - ../foo' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + git config remote.origin.url ../foo && + git submodule init && + test "$(git config submodule.sub.url)" = ../subrepo + ) +' + +test_expect_success '../subrepo works with relative local path - ../foo/bar' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + git config remote.origin.url ../foo/bar && + git submodule init && + test "$(git config submodule.sub.url)" = ../foo/subrepo + ) +' + +test_expect_success '../bar/a/b/c works with relative local path - ../foo/bar.git' ' + ( + cd reltest && + cp pristine-.git-config .git/config && + cp pristine-.gitmodules .gitmodules && + mkdir -p a/b/c && + (cd a/b/c; git init) && + git config remote.origin.url ../foo/bar.git && + git submodule add ../bar/a/b/c ./a/b/c && + git submodule init && + test "$(git config submodule.a/b/c.url)" = ../foo/bar/a/b/c + ) +' + test_expect_success 'moving the superproject does not break submodules' ' ( cd addtest && diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh index 3620215c1f..524d5c1b21 100755 --- a/t/t7403-submodule-sync.sh +++ b/t/t7403-submodule-sync.sh @@ -26,7 +26,9 @@ test_expect_success setup ' (cd super-clone && git submodule update --init) && git clone super empty-clone && (cd empty-clone && git submodule init) && - git clone super top-only-clone + git clone super top-only-clone && + git clone super relative-clone && + (cd relative-clone && git submodule update --init) ' test_expect_success 'change submodule' ' @@ -86,4 +88,90 @@ test_expect_success '"git submodule sync" should not vivify uninteresting submod ) ' +test_expect_success '"git submodule sync" handles origin URL of the form foo' ' + (cd relative-clone && + git remote set-url origin foo && + git submodule sync && + (cd submodule && + #actual fails with: "cannot strip off url foo + test "$(git config remote.origin.url)" = "../submodule" + ) + ) +' + +test_expect_success '"git submodule sync" handles origin URL of the form foo/bar' ' + (cd relative-clone && + git remote set-url origin foo/bar && + git submodule sync && + (cd submodule && + #actual foo/submodule + test "$(git config remote.origin.url)" = "../foo/submodule" + ) + ) +' + +test_expect_success '"git submodule sync" handles origin URL of the form ./foo' ' + (cd relative-clone && + git remote set-url origin ./foo && + git submodule sync && + (cd submodule && + #actual ./submodule + test "$(git config remote.origin.url)" = "../submodule" + ) + ) +' + +test_expect_success '"git submodule sync" handles origin URL of the form ./foo/bar' ' + (cd relative-clone && + git remote set-url origin ./foo/bar && + git submodule sync && + (cd submodule && + #actual ./foo/submodule + test "$(git config remote.origin.url)" = "../foo/submodule" + ) + ) +' + +test_expect_success '"git submodule sync" handles origin URL of the form ../foo' ' + (cd relative-clone && + git remote set-url origin ../foo && + git submodule sync && + (cd submodule && + #actual ../submodule + test "$(git config remote.origin.url)" = "../../submodule" + ) + ) +' + +test_expect_success '"git submodule sync" handles origin URL of the form ../foo/bar' ' + (cd relative-clone && + git remote set-url origin ../foo/bar && + git submodule sync && + (cd submodule && + #actual ../foo/submodule + test "$(git config remote.origin.url)" = "../../foo/submodule" + ) + ) +' + +test_expect_success '"git submodule sync" handles origin URL of the form ../foo/bar with deeply nested submodule' ' + (cd relative-clone && + git remote set-url origin ../foo/bar && + mkdir -p a/b/c && + ( cd a/b/c && + git init && + :> .gitignore && + git add .gitignore && + test_tick && + git commit -m "initial commit" ) && + git submodule add ../bar/a/b/c ./a/b/c && + git submodule sync && + (cd a/b/c && + #actual ../foo/bar/a/b/c + test "$(git config remote.origin.url)" = "../../../../foo/bar/a/b/c" + ) + ) +' + + test_done diff --git a/t/t7508-status.sh b/t/t7508-status.sh index 28e184829c..c206f4777a 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -941,7 +941,7 @@ test_expect_success 'status -s submodule summary (clean submodule)' ' test_expect_success 'status -z implies porcelain' ' git status --porcelain | - perl -pe "s/\012/\000/g" >expect && + "$PERL_PATH" -pe "s/\012/\000/g" >expect && git status -z >output && test_cmp expect output ' diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh new file mode 100755 index 0000000000..b3f6eb9c68 --- /dev/null +++ b/t/t7512-status-help.sh @@ -0,0 +1,649 @@ +#!/bin/sh +# +# Copyright (c) 2012 Valentin Duperray, Lucien Kong, Franck Jonas, +# Thomas Nguy, Khoi Nguyen +# Grenoble INP Ensimag +# + +test_description='git status advices' + +. ./test-lib.sh + +. "$TEST_DIRECTORY"/lib-rebase.sh + +set_fake_editor + +test_expect_success 'prepare for conflicts' ' + test_commit init main.txt init && + git branch conflicts && + test_commit on_master main.txt on_master && + git checkout conflicts && + test_commit on_conflicts main.txt on_conflicts +' + + +test_expect_success 'status when conflicts unresolved' ' + test_must_fail git merge master && + cat >expected <<-\EOF && + # On branch conflicts + # You have unmerged paths. + # (fix conflicts and run "git commit") + # + # Unmerged paths: + # (use "git add ..." to mark resolution) + # + # both modified: main.txt + # + no changes added to commit (use "git add" and/or "git commit -a") + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status when conflicts resolved before commit' ' + git reset --hard conflicts && + test_must_fail git merge master && + echo one >main.txt && + git add main.txt && + cat >expected <<-\EOF && + # On branch conflicts + # All conflicts fixed but you are still merging. + # (use "git commit" to conclude merge) + # + # Changes to be committed: + # + # modified: main.txt + # + # Untracked files not listed (use -u option to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'prepare for rebase conflicts' ' + git reset --hard master && + git checkout -b rebase_conflicts && + test_commit one_rebase main.txt one && + test_commit two_rebase main.txt two && + test_commit three_rebase main.txt three +' + + +test_expect_success 'status when rebase in progress before resolving conflicts' ' + test_when_finished "git rebase --abort" && + test_must_fail git rebase HEAD^ --onto HEAD^^ && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently rebasing. + # (fix conflicts and then run "git rebase --continue") + # (use "git rebase --skip" to skip this patch) + # (use "git rebase --abort" to check out the original branch) + # + # Unmerged paths: + # (use "git reset HEAD ..." to unstage) + # (use "git add ..." to mark resolution) + # + # both modified: main.txt + # + no changes added to commit (use "git add" and/or "git commit -a") + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status when rebase in progress before rebase --continue' ' + git reset --hard rebase_conflicts && + test_when_finished "git rebase --abort" && + test_must_fail git rebase HEAD^ --onto HEAD^^ && + echo three >main.txt && + git add main.txt && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently rebasing. + # (all conflicts fixed: run "git rebase --continue") + # + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # modified: main.txt + # + # Untracked files not listed (use -u option to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'prepare for rebase_i_conflicts' ' + git reset --hard master && + git checkout -b rebase_i_conflicts && + test_commit one_unmerge main.txt one_unmerge && + git branch rebase_i_conflicts_second && + test_commit one_master main.txt one_master && + git checkout rebase_i_conflicts_second && + test_commit one_second main.txt one_second +' + + +test_expect_success 'status during rebase -i when conflicts unresolved' ' + test_when_finished "git rebase --abort" && + test_must_fail git rebase -i rebase_i_conflicts && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently rebasing. + # (fix conflicts and then run "git rebase --continue") + # (use "git rebase --skip" to skip this patch) + # (use "git rebase --abort" to check out the original branch) + # + # Unmerged paths: + # (use "git reset HEAD ..." to unstage) + # (use "git add ..." to mark resolution) + # + # both modified: main.txt + # + no changes added to commit (use "git add" and/or "git commit -a") + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status during rebase -i after resolving conflicts' ' + git reset --hard rebase_i_conflicts_second && + test_when_finished "git rebase --abort" && + test_must_fail git rebase -i rebase_i_conflicts && + git add main.txt && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently rebasing. + # (all conflicts fixed: run "git rebase --continue") + # + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # modified: main.txt + # + # Untracked files not listed (use -u option to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status when rebasing -i in edit mode' ' + git reset --hard master && + git checkout -b rebase_i_edit && + test_commit one_rebase_i main.txt one && + test_commit two_rebase_i main.txt two && + test_commit three_rebase_i main.txt three && + FAKE_LINES="1 edit 2" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~2 && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently editing a commit during a rebase. + # (use "git commit --amend" to amend the current commit) + # (use "git rebase --continue" once you are satisfied with your changes) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status when splitting a commit' ' + git reset --hard master && + git checkout -b split_commit && + test_commit one_split main.txt one && + test_commit two_split main.txt two && + test_commit three_split main.txt three && + test_commit four_split main.txt four && + FAKE_LINES="1 edit 2 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~3 && + git reset HEAD^ && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently splitting a commit during a rebase. + # (Once your working directory is clean, run "git rebase --continue") + # + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # (use "git checkout -- ..." to discard changes in working directory) + # + # modified: main.txt + # + no changes added to commit (use "git add" and/or "git commit -a") + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status after editing the last commit with --amend during a rebase -i' ' + git reset --hard master && + git checkout -b amend_last && + test_commit one_amend main.txt one && + test_commit two_amend main.txt two && + test_commit three_amend main.txt three && + test_commit four_amend main.txt four && + FAKE_LINES="1 2 edit 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~3 && + git commit --amend -m "foo" && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently editing a commit during a rebase. + # (use "git commit --amend" to amend the current commit) + # (use "git rebase --continue" once you are satisfied with your changes) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'prepare for several edits' ' + git reset --hard master && + git checkout -b several_edits && + test_commit one_edits main.txt one && + test_commit two_edits main.txt two && + test_commit three_edits main.txt three && + test_commit four_edits main.txt four +' + + +test_expect_success 'status: (continue first edit) second edit' ' + FAKE_LINES="edit 1 edit 2 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~3 && + git rebase --continue && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently editing a commit during a rebase. + # (use "git commit --amend" to amend the current commit) + # (use "git rebase --continue" once you are satisfied with your changes) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status: (continue first edit) second edit and split' ' + git reset --hard several_edits && + FAKE_LINES="edit 1 edit 2 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~3 && + git rebase --continue && + git reset HEAD^ && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently splitting a commit during a rebase. + # (Once your working directory is clean, run "git rebase --continue") + # + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # (use "git checkout -- ..." to discard changes in working directory) + # + # modified: main.txt + # + no changes added to commit (use "git add" and/or "git commit -a") + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status: (continue first edit) second edit and amend' ' + git reset --hard several_edits && + FAKE_LINES="edit 1 edit 2 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~3 && + git rebase --continue && + git commit --amend -m "foo" && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently editing a commit during a rebase. + # (use "git commit --amend" to amend the current commit) + # (use "git rebase --continue" once you are satisfied with your changes) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status: (amend first edit) second edit' ' + git reset --hard several_edits && + FAKE_LINES="edit 1 edit 2 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~3 && + git commit --amend -m "a" && + git rebase --continue && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently editing a commit during a rebase. + # (use "git commit --amend" to amend the current commit) + # (use "git rebase --continue" once you are satisfied with your changes) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status: (amend first edit) second edit and split' ' + git reset --hard several_edits && + FAKE_LINES="edit 1 edit 2 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~3 && + git commit --amend -m "b" && + git rebase --continue && + git reset HEAD^ && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently splitting a commit during a rebase. + # (Once your working directory is clean, run "git rebase --continue") + # + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # (use "git checkout -- ..." to discard changes in working directory) + # + # modified: main.txt + # + no changes added to commit (use "git add" and/or "git commit -a") + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status: (amend first edit) second edit and amend' ' + git reset --hard several_edits && + FAKE_LINES="edit 1 edit 2 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~3 && + git commit --amend -m "c" && + git rebase --continue && + git commit --amend -m "d" && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently editing a commit during a rebase. + # (use "git commit --amend" to amend the current commit) + # (use "git rebase --continue" once you are satisfied with your changes) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status: (split first edit) second edit' ' + git reset --hard several_edits && + FAKE_LINES="edit 1 edit 2 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~3 && + git reset HEAD^ && + git add main.txt && + git commit -m "e" && + git rebase --continue && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently editing a commit during a rebase. + # (use "git commit --amend" to amend the current commit) + # (use "git rebase --continue" once you are satisfied with your changes) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status: (split first edit) second edit and split' ' + git reset --hard several_edits && + FAKE_LINES="edit 1 edit 2 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~3 && + git reset HEAD^ && + git add main.txt && + git commit --amend -m "f" && + git rebase --continue && + git reset HEAD^ && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently splitting a commit during a rebase. + # (Once your working directory is clean, run "git rebase --continue") + # + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # (use "git checkout -- ..." to discard changes in working directory) + # + # modified: main.txt + # + no changes added to commit (use "git add" and/or "git commit -a") + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status: (split first edit) second edit and amend' ' + git reset --hard several_edits && + FAKE_LINES="edit 1 edit 2 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + git rebase -i HEAD~3 && + git reset HEAD^ && + git add main.txt && + git commit --amend -m "g" && + git rebase --continue && + git commit --amend -m "h" && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently editing a commit during a rebase. + # (use "git commit --amend" to amend the current commit) + # (use "git rebase --continue" once you are satisfied with your changes) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'prepare am_session' ' + git reset --hard master && + git checkout -b am_session && + test_commit one_am one.txt "one" && + test_commit two_am two.txt "two" && + test_commit three_am three.txt "three" +' + + +test_expect_success 'status in an am session: file already exists' ' + git checkout -b am_already_exists && + test_when_finished "rm Maildir/* && git am --abort" && + git format-patch -1 -oMaildir && + test_must_fail git am Maildir/*.patch && + cat >expected <<-\EOF && + # On branch am_already_exists + # You are in the middle of an am session. + # (fix conflicts and then run "git am --resolved") + # (use "git am --skip" to skip this patch) + # (use "git am --abort" to restore the original branch) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status in an am session: file does not exist' ' + git reset --hard am_session && + git checkout -b am_not_exists && + git rm three.txt && + git commit -m "delete three.txt" && + test_when_finished "rm Maildir/* && git am --abort" && + git format-patch -1 -oMaildir && + test_must_fail git am Maildir/*.patch && + cat >expected <<-\EOF && + # On branch am_not_exists + # You are in the middle of an am session. + # (fix conflicts and then run "git am --resolved") + # (use "git am --skip" to skip this patch) + # (use "git am --abort" to restore the original branch) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status in an am session: empty patch' ' + git reset --hard am_session && + git checkout -b am_empty && + test_when_finished "rm Maildir/* && git am --abort" && + git format-patch -3 -oMaildir && + git rm one.txt two.txt three.txt && + git commit -m "delete all am_empty" && + echo error >Maildir/0002-two_am.patch && + test_must_fail git am Maildir/*.patch && + cat >expected <<-\EOF && + # On branch am_empty + # You are in the middle of an am session. + # The current patch is empty. + # (use "git am --skip" to skip this patch) + # (use "git am --abort" to restore the original branch) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status when bisecting' ' + git reset --hard master && + git checkout -b bisect && + test_commit one_bisect main.txt one && + test_commit two_bisect main.txt two && + test_commit three_bisect main.txt three && + test_when_finished "git bisect reset" && + git bisect start && + git bisect bad && + git bisect good one_bisect && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently bisecting. + # (use "git bisect reset" to get back to the original branch) + # + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status when rebase conflicts with statushints disabled' ' + git reset --hard master && + git checkout -b statushints_disabled && + test_when_finished "git config --local advice.statushints true" && + git config --local advice.statushints false && + test_commit one_statushints main.txt one && + test_commit two_statushints main.txt two && + test_commit three_statushints main.txt three && + test_when_finished "git rebase --abort" && + test_must_fail git rebase HEAD^ --onto HEAD^^ && + cat >expected <<-\EOF && + # Not currently on any branch. + # You are currently rebasing. + # + # Unmerged paths: + # both modified: main.txt + # + no changes added to commit + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'prepare for cherry-pick conflicts' ' + git reset --hard master && + git checkout -b cherry_branch && + test_commit one_cherry main.txt one && + test_commit two_cherries main.txt two && + git checkout -b cherry_branch_second && + test_commit second_cherry main.txt second && + git checkout cherry_branch && + test_commit three_cherries main.txt three +' + + +test_expect_success 'status when cherry-picking before resolving conflicts' ' + test_when_finished "git cherry-pick --abort" && + test_must_fail git cherry-pick cherry_branch_second && + cat >expected <<-\EOF && + # On branch cherry_branch + # You are currently cherry-picking. + # (fix conflicts and run "git commit") + # + # Unmerged paths: + # (use "git add ..." to mark resolution) + # + # both modified: main.txt + # + no changes added to commit (use "git add" and/or "git commit -a") + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_expect_success 'status when cherry-picking after resolving conflicts' ' + git reset --hard cherry_branch && + test_when_finished "git cherry-pick --abort" && + test_must_fail git cherry-pick cherry_branch_second && + echo end >main.txt && + git add main.txt && + cat >expected <<-\EOF && + # On branch cherry_branch + # You are currently cherry-picking. + # (all conflicts fixed: run "git commit") + # + # Changes to be committed: + # + # modified: main.txt + # + # Untracked files not listed (use -u option to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + + +test_done diff --git a/t/t8006-blame-textconv.sh b/t/t8006-blame-textconv.sh index c3c22f7764..bf6caa4dc3 100755 --- a/t/t8006-blame-textconv.sh +++ b/t/t8006-blame-textconv.sh @@ -10,7 +10,7 @@ find_blame() { cat >helper <<'EOF' #!/bin/sh grep -q '^bin: ' "$1" || { echo "E: $1 is not \"binary\" file" 1>&2; exit 1; } -perl -p -e 's/^bin: /converted: /' "$1" +"$PERL_PATH" -p -e 's/^bin: /converted: /' "$1" EOF chmod +x helper diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh index 8cfdfe790f..9a40f1e199 100755 --- a/t/t9129-git-svn-i18n-commitencoding.sh +++ b/t/t9129-git-svn-i18n-commitencoding.sh @@ -29,7 +29,7 @@ fi compare_svn_head_with () { # extract just the log message and strip out committer info. # don't use --limit here since svn 1.1.x doesn't have it, - LC_ALL="$a_utf8_locale" svn log `git svn info --url` | perl -w -e ' + LC_ALL="$a_utf8_locale" svn log `git svn info --url` | "$PERL_PATH" -w -e ' use bytes; $/ = ("-"x72) . "\n"; my @x = ; diff --git a/t/t9137-git-svn-dcommit-clobber-series.sh b/t/t9137-git-svn-dcommit-clobber-series.sh index d60da63f7a..c17aa3186f 100755 --- a/t/t9137-git-svn-dcommit-clobber-series.sh +++ b/t/t9137-git-svn-dcommit-clobber-series.sh @@ -20,8 +20,8 @@ test_expect_success '(supposedly) non-conflicting change from SVN' ' test x"`sed -n -e 61p < file`" = x61 && svn_cmd co "$svnrepo" tmp && (cd tmp && - perl -i.bak -p -e "s/^58$/5588/" file && - perl -i.bak -p -e "s/^61$/6611/" file && + "$PERL_PATH" -i.bak -p -e "s/^58$/5588/" file && + "$PERL_PATH" -i.bak -p -e "s/^61$/6611/" file && poke file && test x"`sed -n -e 58p < file`" = x5588 && test x"`sed -n -e 61p < file`" = x6611 && @@ -40,8 +40,8 @@ test_expect_success 'some unrelated changes to git' " test_expect_success 'change file but in unrelated area' " test x\"\`sed -n -e 4p < file\`\" = x4 && test x\"\`sed -n -e 7p < file\`\" = x7 && - perl -i.bak -p -e 's/^4\$/4444/' file && - perl -i.bak -p -e 's/^7\$/7777/' file && + "$PERL_PATH" -i.bak -p -e 's/^4\$/4444/' file && + "$PERL_PATH" -i.bak -p -e 's/^7\$/7777/' file && test x\"\`sed -n -e 4p < file\`\" = x4444 && test x\"\`sed -n -e 7p < file\`\" = x7777 && git commit -m '4 => 4444, 7 => 7777' file && diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index c17f52e586..2fcf269469 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -12,7 +12,7 @@ test_description='test git fast-import utility' # This could be written as "head -c $1", but IRIX "head" does not # support the -c option. head_c () { - perl -e ' + "$PERL_PATH" -e ' my $len = $ARGV[1]; while ($len > 0) { my $s; diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index b00196bd23..3e821f958b 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -424,13 +424,13 @@ test_expect_success 'fast-export quotes pathnames' ' --cacheinfo 100644 $blob "path with \\backslash" \ --cacheinfo 100644 $blob "path with space" && git commit -m addition && - git ls-files -z -s | perl -0pe "s{\\t}{$&subdir/}" >index && + git ls-files -z -s | "$PERL_PATH" -0pe "s{\\t}{$&subdir/}" >index && git read-tree --empty && git update-index -z --index-info export.out && + git fast-export -M HEAD >export.out && git rev-list HEAD >expect && git init result && cd result && diff --git a/t/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh index d8bb3d06de..e9daa9c4f6 100755 --- a/t/t9810-git-p4-rcs.sh +++ b/t/t9810-git-p4-rcs.sh @@ -246,7 +246,7 @@ test_expect_success 'cope with rcs keyword expansion damage' ' git config git-p4.attemptRCSCleanup true && (cd "$cli" && p4_append_to_file kwfile1.c) && old_lines=$(wc -l /dev/null 2>&1; then - # execute in full-on bash mode - unset POSIXLY_CORRECT - exec bash "$0" "$@" -else - echo '1..0 #SKIP skipping bash completion tests; bash not available' - exit 0 -fi - test_description='test bash completion' -. ./test-lib.sh +. ./lib-bash.sh complete () { diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh new file mode 100755 index 0000000000..f17c1f8b85 --- /dev/null +++ b/t/t9903-bash-prompt.sh @@ -0,0 +1,456 @@ +#!/bin/sh +# +# Copyright (c) 2012 SZEDER Gábor +# + +test_description='test git-specific bash prompt functions' + +. ./lib-bash.sh + +. "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh" + +actual="$TRASH_DIRECTORY/actual" + +test_expect_success 'setup for prompt tests' ' + mkdir -p subdir/subsubdir && + git init otherrepo && + echo 1 > file && + git add file && + test_tick && + git commit -m initial && + git tag -a -m msg1 t1 && + git checkout -b b1 && + echo 2 > file && + git commit -m "second b1" file && + echo 3 > file && + git commit -m "third b1" file && + git tag -a -m msg2 t2 && + git checkout -b b2 master && + echo 0 > file && + git commit -m "second b2" file && + git checkout master +' + +test_expect_success 'gitdir - from command line (through $__git_dir)' ' + echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && + ( + __git_dir="$TRASH_DIRECTORY/otherrepo/.git" && + __gitdir > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'gitdir - repo as argument' ' + echo "otherrepo/.git" > expected && + __gitdir "otherrepo" > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'gitdir - remote as argument' ' + echo "remote" > expected && + __gitdir "remote" > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'gitdir - .git directory in cwd' ' + echo ".git" > expected && + __gitdir > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'gitdir - .git directory in parent' ' + echo "$TRASH_DIRECTORY/.git" > expected && + ( + cd subdir/subsubdir && + __gitdir > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'gitdir - cwd is a .git directory' ' + echo "." > expected && + ( + cd .git && + __gitdir > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'gitdir - parent is a .git directory' ' + echo "$TRASH_DIRECTORY/.git" > expected && + ( + cd .git/refs/heads && + __gitdir > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'gitdir - $GIT_DIR set while .git directory in cwd' ' + echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && + ( + GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" && + export GIT_DIR && + __gitdir > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'gitdir - $GIT_DIR set while .git directory in parent' ' + echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && + ( + GIT_DIR="$TRASH_DIRECTORY/otherrepo/.git" && + export GIT_DIR && + cd subdir && + __gitdir > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'gitdir - non-existing $GIT_DIR' ' + ( + GIT_DIR="$TRASH_DIRECTORY/non-existing" && + export GIT_DIR && + test_must_fail __gitdir + ) +' + +test_expect_success 'gitdir - gitfile in cwd' ' + echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && + echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git && + test_when_finished "rm -f subdir/.git" && + ( + cd subdir && + __gitdir > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'gitdir - gitfile in parent' ' + echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && + echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git && + test_when_finished "rm -f subdir/.git" && + ( + cd subdir/subsubdir && + __gitdir > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success SYMLINKS 'gitdir - resulting path avoids symlinks' ' + echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && + mkdir otherrepo/dir && + test_when_finished "rm -rf otherrepo/dir" && + ln -s otherrepo/dir link && + test_when_finished "rm -f link" && + ( + cd link && + __gitdir > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'gitdir - not a git repository' ' + ( + cd subdir/subsubdir && + GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY" && + export GIT_CEILING_DIRECTORIES && + test_must_fail __gitdir + ) +' + +test_expect_success 'prompt - branch name' ' + printf " (master)" > expected && + __git_ps1 > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - detached head' ' + printf " ((%s...))" $(git log -1 --format="%h" b1^) > expected && + git checkout b1^ && + test_when_finished "git checkout master" && + __git_ps1 > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - describe detached head - contains' ' + printf " ((t2~1))" > expected && + git checkout b1^ && + test_when_finished "git checkout master" && + ( + GIT_PS1_DESCRIBE_STYLE=contains && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - describe detached head - branch' ' + printf " ((b1~1))" > expected && + git checkout b1^ && + test_when_finished "git checkout master" && + ( + GIT_PS1_DESCRIBE_STYLE=branch && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - describe detached head - describe' ' + printf " ((t1-1-g%s))" $(git log -1 --format="%h" b1^) > expected && + git checkout b1^ && + test_when_finished "git checkout master" && + ( + GIT_PS1_DESCRIBE_STYLE=describe && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - describe detached head - default' ' + printf " ((t2))" > expected && + git checkout --detach b1 && + test_when_finished "git checkout master" && + __git_ps1 > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - inside .git directory' ' + printf " (GIT_DIR!)" > expected && + ( + cd .git && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - deep inside .git directory' ' + printf " (GIT_DIR!)" > expected && + ( + cd .git/refs/heads && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - inside bare repository' ' + printf " (BARE:master)" > expected && + git init --bare bare.git && + test_when_finished "rm -rf bare.git" && + ( + cd bare.git && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - interactive rebase' ' + printf " (b1|REBASE-i)" > expected + echo "#!$SHELL_PATH" >fake_editor.sh && + cat >>fake_editor.sh <<\EOF && +echo "edit $(git log -1 --format="%h")" > "$1" +EOF + test_when_finished "rm -f fake_editor.sh" && + chmod a+x fake_editor.sh && + test_set_editor "$TRASH_DIRECTORY/fake_editor.sh" && + git checkout b1 && + test_when_finished "git checkout master" && + git rebase -i HEAD^ && + test_when_finished "git rebase --abort" + __git_ps1 > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - rebase merge' ' + printf " (b2|REBASE-m)" > expected && + git checkout b2 && + test_when_finished "git checkout master" && + test_must_fail git rebase --merge b1 b2 && + test_when_finished "git rebase --abort" && + __git_ps1 > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - rebase' ' + printf " ((t2)|REBASE)" > expected && + git checkout b2 && + test_when_finished "git checkout master" && + test_must_fail git rebase b1 b2 && + test_when_finished "git rebase --abort" && + __git_ps1 > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - merge' ' + printf " (b1|MERGING)" > expected && + git checkout b1 && + test_when_finished "git checkout master" && + test_must_fail git merge b2 && + test_when_finished "git reset --hard" && + __git_ps1 > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - cherry-pick' ' + printf " (master|CHERRY-PICKING)" > expected && + test_must_fail git cherry-pick b1 && + test_when_finished "git reset --hard" && + __git_ps1 > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - bisect' ' + printf " (master|BISECTING)" > expected && + git bisect start && + test_when_finished "git bisect reset" && + __git_ps1 > "$actual" && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - dirty status indicator - clean' ' + printf " (master)" > expected && + ( + GIT_PS1_SHOWDIRTYSTATE=y && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - dirty status indicator - dirty worktree' ' + printf " (master *)" > expected && + echo "dirty" > file && + test_when_finished "git reset --hard" && + ( + GIT_PS1_SHOWDIRTYSTATE=y && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - dirty status indicator - dirty index' ' + printf " (master +)" > expected && + echo "dirty" > file && + test_when_finished "git reset --hard" && + git add -u && + ( + GIT_PS1_SHOWDIRTYSTATE=y && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - dirty status indicator - dirty index and worktree' ' + printf " (master *+)" > expected && + echo "dirty index" > file && + test_when_finished "git reset --hard" && + git add -u && + echo "dirty worktree" > file && + ( + GIT_PS1_SHOWDIRTYSTATE=y && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - dirty status indicator - before root commit' ' + printf " (master #)" > expected && + ( + GIT_PS1_SHOWDIRTYSTATE=y && + cd otherrepo && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - dirty status indicator - disabled by config' ' + printf " (master)" > expected && + echo "dirty" > file && + test_when_finished "git reset --hard" && + test_config bash.showDirtyState false && + ( + GIT_PS1_SHOWDIRTYSTATE=y && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - dirty status indicator - not shown inside .git directory' ' + printf " (GIT_DIR!)" > expected && + echo "dirty" > file && + test_when_finished "git reset --hard" && + ( + GIT_PS1_SHOWDIRTYSTATE=y && + cd .git && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - stash status indicator - no stash' ' + printf " (master)" > expected && + ( + GIT_PS1_SHOWSTASHSTATE=y && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - stash status indicator - stash' ' + printf " (master $)" > expected && + echo 2 >file && + git stash && + test_when_finished "git stash drop" && + ( + GIT_PS1_SHOWSTASHSTATE=y && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - stash status indicator - not shown inside .git directory' ' + printf " (GIT_DIR!)" > expected && + echo 2 >file && + git stash && + test_when_finished "git stash drop" && + ( + GIT_PS1_SHOWSTASHSTATE=y && + cd .git && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - untracked files status indicator - no untracked files' ' + printf " (master)" > expected && + ( + GIT_PS1_SHOWUNTRACKEDFILES=y && + cd otherrepo && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - untracked files status indicator - untracked files' ' + printf " (master %%)" > expected && + ( + GIT_PS1_SHOWUNTRACKEDFILES=y && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - untracked files status indicator - not shown inside .git directory' ' + printf " (GIT_DIR!)" > expected && + ( + GIT_PS1_SHOWUNTRACKEDFILES=y && + cd .git && + __git_ps1 > "$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - format string starting with dash' ' + printf -- "-master" > expected && + __git_ps1 "-%s" > "$actual" && + test_cmp expected "$actual" +' + +test_done diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 7b3b4bef30..16397691d9 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -76,11 +76,11 @@ test_decode_color () { } nul_to_q () { - perl -pe 'y/\000/Q/' + "$PERL_PATH" -pe 'y/\000/Q/' } q_to_nul () { - perl -pe 'y/Q/\000/' + "$PERL_PATH" -pe 'y/Q/\000/' } q_to_cr () { diff --git a/t/test-lib.sh b/t/test-lib.sh index 9e2b71132a..acda33d177 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -494,6 +494,8 @@ export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM . "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS +export PERL_PATH + if test -z "$GIT_TEST_CMP" then if test -n "$GIT_TEST_CMP_USE_COPIED_CONTEXT" diff --git a/test-credential.c b/test-credential.c deleted file mode 100644 index dee200e7f2..0000000000 --- a/test-credential.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "cache.h" -#include "credential.h" -#include "string-list.h" - -static const char usage_msg[] = -"test-credential [helper...]"; - -int main(int argc, const char **argv) -{ - const char *op; - struct credential c = CREDENTIAL_INIT; - int i; - - op = argv[1]; - if (!op) - usage(usage_msg); - for (i = 2; i < argc; i++) - string_list_append(&c.helpers, argv[i]); - - if (credential_read(&c, stdin) < 0) - die("unable to read credential from stdin"); - - if (!strcmp(op, "fill")) { - credential_fill(&c); - if (c.username) - printf("username=%s\n", c.username); - if (c.password) - printf("password=%s\n", c.password); - } - else if (!strcmp(op, "approve")) - credential_approve(&c); - else if (!strcmp(op, "reject")) - credential_reject(&c); - else - usage(usage_msg); - - return 0; -} diff --git a/unpack-trees.c b/unpack-trees.c index ad40109432..33a581924e 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1023,6 +1023,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options o->el = ⪙ } + if (o->dir) { + o->path_exclude_check = xmalloc(sizeof(struct path_exclude_check)); + path_exclude_check_init(o->path_exclude_check, o->dir); + } memset(&o->result, 0, sizeof(o->result)); o->result.initialized = 1; o->result.timestamp.sec = o->src_index->timestamp.sec; @@ -1148,6 +1152,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options done: free_excludes(&el); + if (o->path_exclude_check) { + path_exclude_check_clear(o->path_exclude_check); + free(o->path_exclude_check); + } return ret; return_failed: @@ -1363,7 +1371,8 @@ static int check_ok_to_remove(const char *name, int len, int dtype, if (ignore_case && icase_exists(o, name, len, st)) return 0; - if (o->dir && excluded(o->dir, name, &dtype)) + if (o->dir && + path_excluded(o->path_exclude_check, name, -1, &dtype)) /* * ce->name is explicitly excluded, so it is Ok to * overwrite it. diff --git a/unpack-trees.h b/unpack-trees.h index 5e432f576e..ec74a9f19a 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -52,6 +52,7 @@ struct unpack_trees_options { const char *prefix; int cache_bottom; struct dir_struct *dir; + struct path_exclude_check *path_exclude_check; struct pathspec *pathspec; merge_fn_t fn; const char *msgs[NB_UNPACK_TREES_ERROR_TYPES]; diff --git a/version.c b/version.c new file mode 100644 index 0000000000..f98d5a654d --- /dev/null +++ b/version.c @@ -0,0 +1,17 @@ +#include "git-compat-util.h" +#include "version.h" + +const char git_version_string[] = GIT_VERSION; + +const char *git_user_agent(void) +{ + static const char *agent = NULL; + + if (!agent) { + agent = getenv("GIT_USER_AGENT"); + if (!agent) + agent = GIT_USER_AGENT; + } + + return agent; +} diff --git a/version.h b/version.h new file mode 100644 index 0000000000..fd9cdd6316 --- /dev/null +++ b/version.h @@ -0,0 +1,8 @@ +#ifndef VERSION_H +#define VERSION_H + +extern const char git_version_string[]; + +const char *git_user_agent(void); + +#endif /* VERSION_H */ diff --git a/wt-status.c b/wt-status.c index dd6d8c4106..c749267c95 100644 --- a/wt-status.c +++ b/wt-status.c @@ -12,6 +12,7 @@ #include "refs.h" #include "submodule.h" #include "column.h" +#include "strbuf.h" static char default_wt_status_colors[][COLOR_MAXLEN] = { GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */ @@ -23,6 +24,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = { GIT_COLOR_GREEN, /* WT_STATUS_LOCAL_BRANCH */ GIT_COLOR_RED, /* WT_STATUS_REMOTE_BRANCH */ GIT_COLOR_NIL, /* WT_STATUS_ONBRANCH */ + GIT_COLOR_NORMAL, /* WT_STATUS_IN_PROGRESS */ }; static const char *color(int slot, struct wt_status *s) @@ -130,9 +132,34 @@ void wt_status_prepare(struct wt_status *s) static void wt_status_print_unmerged_header(struct wt_status *s) { + int i; + int del_mod_conflict = 0; + int both_deleted = 0; + int not_deleted = 0; const char *c = color(WT_STATUS_HEADER, s); status_printf_ln(s, c, _("Unmerged paths:")); + + for (i = 0; i < s->change.nr; i++) { + struct string_list_item *it = &(s->change.items[i]); + struct wt_status_change_data *d = it->util; + + switch (d->stagemask) { + case 0: + break; + case 1: + both_deleted = 1; + break; + case 3: + case 5: + del_mod_conflict = 1; + break; + default: + not_deleted = 1; + break; + } + } + if (!advice_status_hints) return; if (s->whence != FROM_COMMIT) @@ -141,7 +168,17 @@ static void wt_status_print_unmerged_header(struct wt_status *s) status_printf_ln(s, c, _(" (use \"git reset %s ...\" to unstage)"), s->reference); else status_printf_ln(s, c, _(" (use \"git rm --cached ...\" to unstage)")); - status_printf_ln(s, c, _(" (use \"git add/rm ...\" as appropriate to mark resolution)")); + + if (!both_deleted) { + if (!del_mod_conflict) + status_printf_ln(s, c, _(" (use \"git add ...\" to mark resolution)")); + else + status_printf_ln(s, c, _(" (use \"git add/rm ...\" as appropriate to mark resolution)")); + } else if (!del_mod_conflict && !not_deleted) { + status_printf_ln(s, c, _(" (use \"git rm ...\" to mark resolution)")); + } else { + status_printf_ln(s, c, _(" (use \"git add/rm ...\" as appropriate to mark resolution)")); + } status_printf_ln(s, c, ""); } @@ -728,6 +765,211 @@ static void wt_status_print_tracking(struct wt_status *s) color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "#"); } +static int has_unmerged(struct wt_status *s) +{ + int i; + + for (i = 0; i < s->change.nr; i++) { + struct wt_status_change_data *d; + d = s->change.items[i].util; + if (d->stagemask) + return 1; + } + return 0; +} + +static void show_merge_in_progress(struct wt_status *s, + struct wt_status_state *state, + const char *color) +{ + if (has_unmerged(s)) { + status_printf_ln(s, color, _("You have unmerged paths.")); + if (advice_status_hints) + status_printf_ln(s, color, + _(" (fix conflicts and run \"git commit\")")); + } else { + status_printf_ln(s, color, + _("All conflicts fixed but you are still merging.")); + if (advice_status_hints) + status_printf_ln(s, color, + _(" (use \"git commit\" to conclude merge)")); + } + wt_status_print_trailer(s); +} + +static void show_am_in_progress(struct wt_status *s, + struct wt_status_state *state, + const char *color) +{ + status_printf_ln(s, color, + _("You are in the middle of an am session.")); + if (state->am_empty_patch) + status_printf_ln(s, color, + _("The current patch is empty.")); + if (advice_status_hints) { + if (!state->am_empty_patch) + status_printf_ln(s, color, + _(" (fix conflicts and then run \"git am --resolved\")")); + status_printf_ln(s, color, + _(" (use \"git am --skip\" to skip this patch)")); + status_printf_ln(s, color, + _(" (use \"git am --abort\" to restore the original branch)")); + } + wt_status_print_trailer(s); +} + +static char *read_line_from_git_path(const char *filename) +{ + struct strbuf buf = STRBUF_INIT; + FILE *fp = fopen(git_path("%s", filename), "r"); + if (!fp) { + strbuf_release(&buf); + return NULL; + } + strbuf_getline(&buf, fp, '\n'); + if (!fclose(fp)) { + return strbuf_detach(&buf, NULL); + } else { + strbuf_release(&buf); + return NULL; + } +} + +static int split_commit_in_progress(struct wt_status *s) +{ + int split_in_progress = 0; + char *head = read_line_from_git_path("HEAD"); + char *orig_head = read_line_from_git_path("ORIG_HEAD"); + char *rebase_amend = read_line_from_git_path("rebase-merge/amend"); + char *rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head"); + + if (!head || !orig_head || !rebase_amend || !rebase_orig_head || + !s->branch || strcmp(s->branch, "HEAD")) + return split_in_progress; + + if (!strcmp(rebase_amend, rebase_orig_head)) { + if (strcmp(head, rebase_amend)) + split_in_progress = 1; + } else if (strcmp(orig_head, rebase_orig_head)) { + split_in_progress = 1; + } + + if (!s->amend && !s->nowarn && !s->workdir_dirty) + split_in_progress = 0; + + free(head); + free(orig_head); + free(rebase_amend); + free(rebase_orig_head); + return split_in_progress; +} + +static void show_rebase_in_progress(struct wt_status *s, + struct wt_status_state *state, + const char *color) +{ + struct stat st; + + if (has_unmerged(s)) { + status_printf_ln(s, color, _("You are currently rebasing.")); + if (advice_status_hints) { + status_printf_ln(s, color, + _(" (fix conflicts and then run \"git rebase --continue\")")); + status_printf_ln(s, color, + _(" (use \"git rebase --skip\" to skip this patch)")); + status_printf_ln(s, color, + _(" (use \"git rebase --abort\" to check out the original branch)")); + } + } else if (state->rebase_in_progress || !stat(git_path("MERGE_MSG"), &st)) { + status_printf_ln(s, color, _("You are currently rebasing.")); + if (advice_status_hints) + status_printf_ln(s, color, + _(" (all conflicts fixed: run \"git rebase --continue\")")); + } else if (split_commit_in_progress(s)) { + status_printf_ln(s, color, _("You are currently splitting a commit during a rebase.")); + if (advice_status_hints) + status_printf_ln(s, color, + _(" (Once your working directory is clean, run \"git rebase --continue\")")); + } else { + status_printf_ln(s, color, _("You are currently editing a commit during a rebase.")); + if (advice_status_hints && !s->amend) { + status_printf_ln(s, color, + _(" (use \"git commit --amend\" to amend the current commit)")); + status_printf_ln(s, color, + _(" (use \"git rebase --continue\" once you are satisfied with your changes)")); + } + } + wt_status_print_trailer(s); +} + +static void show_cherry_pick_in_progress(struct wt_status *s, + struct wt_status_state *state, + const char *color) +{ + status_printf_ln(s, color, _("You are currently cherry-picking.")); + if (advice_status_hints) { + if (has_unmerged(s)) + status_printf_ln(s, color, + _(" (fix conflicts and run \"git commit\")")); + else + status_printf_ln(s, color, + _(" (all conflicts fixed: run \"git commit\")")); + } + wt_status_print_trailer(s); +} + +static void show_bisect_in_progress(struct wt_status *s, + struct wt_status_state *state, + const char *color) +{ + status_printf_ln(s, color, _("You are currently bisecting.")); + if (advice_status_hints) + status_printf_ln(s, color, + _(" (use \"git bisect reset\" to get back to the original branch)")); + wt_status_print_trailer(s); +} + +static void wt_status_print_state(struct wt_status *s) +{ + const char *state_color = color(WT_STATUS_IN_PROGRESS, s); + struct wt_status_state state; + struct stat st; + + memset(&state, 0, sizeof(state)); + + if (!stat(git_path("MERGE_HEAD"), &st)) { + state.merge_in_progress = 1; + } else if (!stat(git_path("rebase-apply"), &st)) { + if (!stat(git_path("rebase-apply/applying"), &st)) { + state.am_in_progress = 1; + if (!stat(git_path("rebase-apply/patch"), &st) && !st.st_size) + state.am_empty_patch = 1; + } else { + state.rebase_in_progress = 1; + } + } else if (!stat(git_path("rebase-merge"), &st)) { + if (!stat(git_path("rebase-merge/interactive"), &st)) + state.rebase_interactive_in_progress = 1; + else + state.rebase_in_progress = 1; + } else if (!stat(git_path("CHERRY_PICK_HEAD"), &st)) { + state.cherry_pick_in_progress = 1; + } + if (!stat(git_path("BISECT_LOG"), &st)) + state.bisect_in_progress = 1; + + if (state.merge_in_progress) + show_merge_in_progress(s, &state, state_color); + else if (state.am_in_progress) + show_am_in_progress(s, &state, state_color); + else if (state.rebase_in_progress || state.rebase_interactive_in_progress) + show_rebase_in_progress(s, &state, state_color); + else if (state.cherry_pick_in_progress) + show_cherry_pick_in_progress(s, &state, state_color); + if (state.bisect_in_progress) + show_bisect_in_progress(s, &state, state_color); +} + void wt_status_print(struct wt_status *s) { const char *branch_color = color(WT_STATUS_ONBRANCH, s); @@ -750,6 +992,7 @@ void wt_status_print(struct wt_status *s) wt_status_print_tracking(s); } + wt_status_print_state(s); if (s->is_initial) { status_printf_ln(s, color(WT_STATUS_HEADER, s), ""); status_printf_ln(s, color(WT_STATUS_HEADER, s), _("Initial commit")); diff --git a/wt-status.h b/wt-status.h index 14aa9f7e13..c1066a0ec6 100644 --- a/wt-status.h +++ b/wt-status.h @@ -15,6 +15,7 @@ enum color_wt_status { WT_STATUS_LOCAL_BRANCH, WT_STATUS_REMOTE_BRANCH, WT_STATUS_ONBRANCH, + WT_STATUS_IN_PROGRESS, WT_STATUS_MAXSLOT }; @@ -71,6 +72,16 @@ struct wt_status { struct string_list ignored; }; +struct wt_status_state { + int merge_in_progress; + int am_in_progress; + int am_empty_patch; + int rebase_in_progress; + int rebase_interactive_in_progress; + int cherry_pick_in_progress; + int bisect_in_progress; +}; + void wt_status_prepare(struct wt_status *s); void wt_status_print(struct wt_status *s); void wt_status_collect(struct wt_status *s);