From: Junio C Hamano Date: Sun, 30 Jul 2017 21:46:43 +0000 (-0700) Subject: Merge tag 'v2.7.6' into maint-2.8 X-Git-Tag: v2.8.6~1 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/7720c33f632c2d67b53169030a7ed2e0e6ae8fde?hp=5e0649dc65fe33e8cf38823350e9d7951f6a6346 Merge tag 'v2.7.6' into maint-2.8 Git 2.7.6 --- diff --git a/.gitignore b/.gitignore index 1c2f832138..5087ce1eb7 100644 --- a/.gitignore +++ b/.gitignore @@ -187,6 +187,7 @@ /test-dump-cache-tree /test-dump-split-index /test-dump-untracked-cache +/test-fake-ssh /test-scrap-cache-tree /test-genrandom /test-hashmap diff --git a/.mailmap b/.mailmap index e5b4126bec..a9162c0095 100644 --- a/.mailmap +++ b/.mailmap @@ -51,6 +51,7 @@ Dirk Süsserott Eric Blake Eric Hanchrow Eric S. Raymond +Eric Wong Erik Faye-Lund Eyvind Bernhardsen Florian Achleitner diff --git a/.travis.yml b/.travis.yml index c3bf9c6d4d..adab5b89bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,11 @@ language: c +sudo: false + +cache: + directories: + - $HOME/travis-cache + os: - linux - osx @@ -15,34 +21,52 @@ addons: env: global: - - P4_VERSION="15.2" - - GIT_LFS_VERSION="1.1.0" + - DEVELOPER=1 + # The Linux build installs the defined dependency versions below. + # The OS X build installs the latest available versions. Keep that + # in mind when you encounter a broken OS X build! + - LINUX_P4_VERSION="16.1" + - LINUX_GIT_LFS_VERSION="1.2.0" - DEFAULT_TEST_TARGET=prove - - GIT_PROVE_OPTS="--timer --jobs 3" + - GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" - GIT_TEST_OPTS="--verbose --tee" - - CFLAGS="-g -O2 -Wall -Werror" - GIT_TEST_CLONE_2GB=YesPlease # t9810 occasionally fails on Travis CI OS X # t9816 occasionally fails with "TAP out of sequence errors" on Travis CI OS X - GIT_SKIP_TESTS="t9810 t9816" +matrix: + include: + - env: Documentation + os: linux + compiler: clang + addons: + apt: + packages: + - asciidoc + - xmlto + before_install: + before_script: + script: ci/test-documentation.sh + after_failure: + before_install: - > case "${TRAVIS_OS_NAME:-linux}" in linux) mkdir --parents custom/p4 pushd custom/p4 - wget --quiet http://filehost.perforce.com/perforce/r$P4_VERSION/bin.linux26x86_64/p4d - wget --quiet http://filehost.perforce.com/perforce/r$P4_VERSION/bin.linux26x86_64/p4 + wget --quiet http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION/bin.linux26x86_64/p4d + wget --quiet http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION/bin.linux26x86_64/p4 chmod u+x p4d chmod u+x p4 export PATH="$(pwd):$PATH" popd mkdir --parents custom/git-lfs pushd custom/git-lfs - wget --quiet https://github.com/github/git-lfs/releases/download/v$GIT_LFS_VERSION/git-lfs-linux-amd64-$GIT_LFS_VERSION.tar.gz - tar --extract --gunzip --file "git-lfs-linux-amd64-$GIT_LFS_VERSION.tar.gz" - cp git-lfs-$GIT_LFS_VERSION/git-lfs . + wget --quiet https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION/git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz + tar --extract --gunzip --file "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" + cp git-lfs-$LINUX_GIT_LFS_VERSION/git-lfs . export PATH="$(pwd):$PATH" popd ;; @@ -67,6 +91,8 @@ before_install: p4 -V | grep Rev.; echo "$(tput setaf 6)Git-LFS Version$(tput sgr0)"; git-lfs version; + mkdir -p $HOME/travis-cache; + ln -s $HOME/travis-cache/.prove t/.prove; before_script: make --jobs=2 diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index c6e536f180..0ddd36879a 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -171,6 +171,11 @@ For C programs: - We try to keep to at most 80 characters per line. + - As a Git developer we assume you have a reasonably modern compiler + and we recommend you to enable the DEVELOPER makefile knob to + ensure your patch is clear of all compiler warnings we care about, + by e.g. "echo DEVELOPER=1 >>config.mak". + - We try to support a wide range of C compilers to compile Git with, including old ones. That means that you should not use C99 initializers, even if a lot of compilers grok it. diff --git a/Documentation/RelNotes/2.8.0.txt b/Documentation/RelNotes/2.8.0.txt new file mode 100644 index 0000000000..25079710fa --- /dev/null +++ b/Documentation/RelNotes/2.8.0.txt @@ -0,0 +1,439 @@ +Git 2.8 Release Notes +===================== + +Backward compatibility note +--------------------------- + +The rsync:// transport has been removed. + + +Updates since v2.7 +------------------ + +UI, Workflows & Features + + * It turns out "git clone" over rsync transport has been broken when + the source repository has packed references for a long time, and + nobody noticed nor complained about it. + + * "push" learned that its "--delete" option can be shortened to + "-d", just like "branch --delete" and "branch -d" are the same + thing. + + * "git blame" learned to produce the progress eye-candy when it takes + too much time before emitting the first line of the result. + + * "git grep" can now be configured (or told from the command line) + how many threads to use when searching in the working tree files. + + * Some "git notes" operations, e.g. "git log --notes=", should + be able to read notes from any tree-ish that is shaped like a notes + tree, but the notes infrastructure required that the argument must + be a ref under refs/notes/. Loosen it to require a valid ref only + when the operation would update the notes (in which case we must + have a place to store the updated notes tree, iow, a ref). + + * "git grep" by default does not fall back to its "--no-index" + behavior outside a directory under Git's control (otherwise the + user may by mistake end up running a huge recursive search); with a + new configuration (set in $HOME/.gitconfig--by definition this + cannot be set in the config file per project), this safety can be + disabled. + + * "git pull --rebase" has been extended to allow invoking + "rebase -i". + + * "git p4" learned to cope with the type of a file getting changed. + + * "git format-patch" learned to notice format.outputDirectory + configuration variable. This allows "-o " option to be + omitted on the command line if you always use the same directory in + your workflow. + + * "interpret-trailers" has been taught to optionally update a file in + place, instead of always writing the result to the standard output. + + * Many commands that read files that are expected to contain text + that is generated (or can be edited) by the end user to control + their behavior (e.g. "git grep -f ") have been updated + to be more tolerant to lines that are terminated with CRLF (they + used to treat such a line to contain payload that ends with CR, + which is usually not what the users expect). + + * "git notes merge" used to limit the source of the merged notes tree + to somewhere under refs/notes/ hierarchy, which was too limiting + when inventing a workflow to exchange notes with remote + repositories using remote-tracking notes trees (located in e.g. + refs/remote-notes/ or somesuch). + + * "git ls-files" learned a new "--eol" option to help diagnose + end-of-line problems. + + * "ls-remote" learned an option to show which branch the remote + repository advertises as its primary by pointing its HEAD at. + + * New http.proxyAuthMethod configuration variable can be used to + specify what authentication method to use, as a way to work around + proxies that do not give error response expected by libcurl when + CURLAUTH_ANY is used. Also, the codepath for proxy authentication + has been taught to use credential API to store the authentication + material in user's keyrings. + + * Update the untracked cache subsystem and change its primary UI from + "git update-index" to "git config". + + * There were a few "now I am doing this thing" progress messages in + the TCP connection code that can be triggered by setting a verbose + option internally in the code, but "git fetch -v" and friends never + passed the verbose option down to that codepath. + + * Clean/smudge filters defined in a configuration file of lower + precedence can now be overridden to be a pass-through no-op by + setting the variable to an empty string. + + * A new "^{/!-}" notation can be used to name a + commit that is reachable from that does not match the + given . + + * The "user.useConfigOnly" configuration variable can be used to + force the user to always set user.email & user.name configuration + variables, serving as a reminder for those who work on multiple + projects and do not want to put these in their $HOME/.gitconfig. + + * "git fetch" and friends that make network connections can now be + told to only use ipv4 (or ipv6). + + * Some authentication methods do not need username or password, but + libcurl needs some hint that it needs to perform authentication. + Supplying an empty username and password string is a valid way to + do so, but you can set the http.[.]emptyAuth configuration + variable to achieve the same, if you find it cleaner. + + * You can now set http.[.]pinnedpubkey to specify the pinned + public key when building with recent enough versions of libcURL. + + * The configuration system has been taught to phrase where it found a + bad configuration variable in a better way in its error messages. + "git config" learnt a new "--show-origin" option to indicate where + the values come from. + + * The "credential-cache" daemon process used to run in whatever + directory it happened to start in, but this made umount(2)ing the + filesystem that houses the repository harder; now the process + chdir()s to the directory that house its own socket on startup. + + * When "git submodule update" did not result in fetching the commit + object in the submodule that is referenced by the superproject, the + command learned to retry another fetch, specifically asking for + that commit that may not be connected to the refs it usually + fetches. + + * "git merge-recursive" learned "--no-renames" option to disable its + rename detection logic. + + * Across the transition at around Git version 2.0, the user used to + get a pretty loud warning when running "git push" without setting + push.default configuration variable. We no longer warn because the + transition was completed a long time ago. + + * README has been renamed to README.md and its contents got tweaked + slightly to make it easier on the eyes. + + +Performance, Internal Implementation, Development Support etc. + + * Add a framework to spawn a group of processes in parallel, and use + it to run "git fetch --recurse-submodules" in parallel. + + * A slight update to the Makefile to mark ".PHONY" targets as such + correctly. + + * In-core storage of the reverse index for .pack files (which lets + you go from a pack offset to an object name) has been streamlined. + + * d95138e6 (setup: set env $GIT_WORK_TREE when work tree is set, like + $GIT_DIR, 2015-06-26) attempted to work around a glitch in alias + handling by overwriting GIT_WORK_TREE environment variable to + affect subprocesses when set_git_work_tree() gets called, which + resulted in a rather unpleasant regression to "clone" and "init". + Try to address the same issue by always restoring the environment + and respawning the real underlying command when handling alias. + + * The low-level code that is used to create symbolic references has + been updated to share more code with the code that deals with + normal references. + + * strbuf_getline() and friends have been redefined to make it easier + to identify which callsite of (new) strbuf_getline_lf() should + allow and silently ignore carriage-return at the end of the line to + help users on DOSsy systems. + + * "git shortlog" used to accumulate various pieces of information + regardless of what was asked to be shown in the final output. It + has been optimized by noticing what need not to be collected + (e.g. there is no need to collect the log messages when showing + only the number of changes). + + * "git checkout $branch" (and other operations that share the same + underlying machinery) has been optimized. + + * Automated tests in Travis CI environment has been optimized by + persisting runtime statistics of previous "prove" run, executing + tests that take longer before other ones; this reduces the total + wallclock time. + + * Test scripts have been updated to remove assumptions that are not + portable between Git for POSIX and Git for Windows, or to skip ones + with expectations that are not satisfiable on Git for Windows. + + * Some calls to strcpy(3) triggers a false warning from static + analyzers that are less intelligent than humans, and reducing the + number of these false hits helps us notice real issues. A few + calls to strcpy(3) in a couple of protrams that are already safe + has been rewritten to avoid false warnings. + + * The "name_path" API was an attempt to reduce the need to construct + the full path out of a series of path components while walking a + tree hierarchy, but over time made less efficient because the path + needs to be flattened, e.g. to be compared with another path that + is already flat. The API has been removed and its users have been + rewritten to simplify the overall code complexity. + + * Help those who debug http(s) part of the system. + (merge 0054045 sp/remote-curl-ssl-strerror later to maint). + + * The internal API to interact with "remote.*" configuration + variables has been streamlined. + + * The ref-filter's format-parsing code has been refactored, in + preparation for "branch --format" and friends. + + * Traditionally, the tests that try commands that work on the + contents in the working tree were named with "worktree" in their + filenames, but with the recent addition of "git worktree" + subcommand, whose tests are also named similarly, it has become + harder to tell them apart. The traditional tests have been renamed + to use "work-tree" instead in an attempt to differentiate them. + (merge 5549029 mg/work-tree-tests later to maint). + + * Many codepaths forget to check return value from git_config_set(); + the function is made to die() to make sure we do not proceed when + setting a configuration variable failed. + (merge 3d18064 ps/config-error later to maint). + + * Handling of errors while writing into our internal asynchronous + process has been made more robust, which reduces flakiness in our + tests. + (merge 43f3afc jk/epipe-in-async later to maint). + + * There is a new DEVELOPER knob that enables many compiler warning + options in the Makefile. + + * The way the test scripts configure the Apache web server has been + updated to work also for Apache 2.4 running on RedHat derived + distros. + + * Out of maintenance gcc on OSX 10.6 fails to compile the code in + 'master'; work it around by using clang by default on the platform. + + * The "name_path" API was an attempt to reduce the need to construct + the full path out of a series of path components while walking a + tree hierarchy, but over time made less efficient because the path + needs to be flattened, e.g. to be compared with another path that + is already flat, in many cases. The API has been removed and its + users have been rewritten to simplify the overall code complexity. + This incidentally also closes some heap-corruption holes. + + * Recent versions of GNU grep is pickier than before to decide if a + file is "binary" and refuse to give line-oriented hits when we + expect it to, unless explicitly told with "-a" option. As our + scripted Porcelains use sane_grep wrapper for line-oriented data, + even when the line may contain non-ASCII payload we took from + end-user data, use "grep -a" to implement sane_grep wrapper when + using an implementation of "grep" that takes the "-a" option. + + + +Also contains various documentation updates and code clean-ups. + + +Fixes since v2.7 +---------------- + +Unless otherwise noted, all the fixes since v2.7 in the maintenance +track are contained in this release (see the maintenance releases' +notes for details). + + * An earlier change in 2.5.x-era broke users' hooks and aliases by + exporting GIT_WORK_TREE to point at the root of the working tree, + interfering when they tried to use a different working tree without + setting GIT_WORK_TREE environment themselves. + + * The "exclude_list" structure has the usual "alloc, nr" pair of + fields to be used by ALLOC_GROW(), but clear_exclude_list() forgot + to reset 'alloc' to 0 when it cleared 'nr' to discard the managed + array. + + * Paths that have been told the index about with "add -N" are not + quite yet in the index, but a few commands behaved as if they + already are in a harmful way. + + * "git send-email" was confused by escaped quotes stored in the alias + files saved by "mutt", which has been corrected. + + * A few non-portable C construct have been spotted by clang compiler + and have been fixed. + + * The documentation has been updated to hint the connection between + the '--signoff' option and DCO. + + * "git reflog" incorrectly assumed that all objects that used to be + at the tip of a ref must be commits, which caused it to segfault. + + * The ignore mechanism saw a few regressions around untracked file + listing and sparse checkout selection areas in 2.7.0; the change + that is responsible for the regression has been reverted. + + * Some codepaths used fopen(3) when opening a fixed path in $GIT_DIR + (e.g. COMMIT_EDITMSG) that is meant to be left after the command is + done. This however did not work well if the repository is set to + be shared with core.sharedRepository and the umask of the previous + user is tighter. They have been made to work better by calling + unlink(2) and retrying after fopen(3) fails with EPERM. + + * Asking gitweb for a nonexistent commit left a warning in the server + log. + + Somebody may want to follow this up with an additional test, perhaps? + IIRC, we do test that no Perl warnings are given to the server log, + so this should have been caught if our test coverage were good. + + * "git rebase", unlike all other callers of "gc --auto", did not + ignore the exit code from "gc --auto". + + * Many codepaths that run "gc --auto" before exiting kept packfiles + mapped and left the file descriptors to them open, which was not + friendly to systems that cannot remove files that are open. They + now close the packs before doing so. + + * A recent optimization to filter-branch in v2.7.0 introduced a + regression when --prune-empty filter is used, which has been + corrected. + + * The description for SANITY prerequisite the test suite uses has + been clarified both in the comment and in the implementation. + + * "git tag" started listing a tag "foo" as "tags/foo" when a branch + named "foo" exists in the same repository; remove this unnecessary + disambiguation, which is a regression introduced in v2.7.0. + + * The way "git svn" uses auth parameter was broken by Subversion + 1.9.0 and later. + + * The "split" subcommand of "git subtree" (in contrib/) incorrectly + skipped merges when it shouldn't, which was corrected. + + * A few options of "git diff" did not work well when the command was + run from a subdirectory. + + * The command line completion learned a handful of additional options + and command specific syntax. + + * dirname() emulation has been added, as Msys2 lacks it. + + * The underlying machinery used by "ls-files -o" and other commands + has been taught not to create empty submodule ref cache for a + directory that is not a submodule. This removes a ton of wasted + CPU cycles. + + * "git worktree" had a broken code that attempted to auto-fix + possible inconsistency that results from end-users moving a + worktree to different places without telling Git (the original + repository needs to maintain back-pointers to its worktrees, + but "mv" run by end-users who are not familiar with that fact + will obviously not adjust them), which actually made things + worse when triggered. + + * The low-level merge machinery has been taught to use CRLF line + termination when inserting conflict markers to merged contents that + are themselves CRLF line-terminated. + + * "git push --force-with-lease" has been taught to report if the push + needed to force (or fast-forwarded). + + * The emulated "yes" command used in our test scripts has been + tweaked not to spend too much time generating unnecessary output + that is not used, to help those who test on Windows where it would + not stop until it fills the pipe buffer due to lack of SIGPIPE. + + * The documentation for "git clean" has been corrected; it mentioned + that .git/modules/* are removed by giving two "-f", which has never + been the case. + + * The vimdiff backend for "git mergetool" has been tweaked to arrange + and number buffers in the order that would match the expectation of + majority of people who read left to right, then top down and assign + buffers 1 2 3 4 "mentally" to local base remote merge windows based + on that order. + + * "git show 'HEAD:Foo[BAR]Baz'" did not interpret the argument as a + rev, i.e. the object named by the the pathname with wildcard + characters in a tree object. + (merge aac4fac nd/dwim-wildcards-as-pathspecs later to maint). + + * "git rev-parse --git-common-dir" used in the worktree feature + misbehaved when run from a subdirectory. + (merge 17f1365 nd/git-common-dir-fix later to maint). + + * "git worktree add -B " did not work. + + * The "v(iew)" subcommand of the interactive "git am -i" command was + broken in 2.6.0 timeframe when the command was rewritten in C. + (merge 708b8cc jc/am-i-v-fix later to maint). + + * "git merge-tree" used to mishandle "both sides added" conflict with + its own "create a fake ancestor file that has the common parts of + what both sides have added and do a 3-way merge" logic; this has + been updated to use the usual "3-way merge with an empty blob as + the fake common ancestor file" approach used in the rest of the + system. + (merge 907681e jk/no-diff-emit-common later to maint). + + * The memory ownership rule of fill_textconv() API, which was a bit + tricky, has been documented a bit better. + (merge a64e6a4 jk/more-comments-on-textconv later to maint). + + * Update various codepaths to avoid manually-counted malloc(). + (merge 08c95df jk/tighten-alloc later to maint). + + * The documentation did not clearly state that the 'simple' mode is + now the default for "git push" when push.default configuration is + not set. + (merge f6b1fb3 mm/push-simple-doc later to maint). + + * Recent versions of GNU grep are pickier when their input contains + arbitrary binary data, which some of our tests uses. Rewrite the + tests to sidestep the problem. + (merge 3b1442d jk/grep-binary-workaround-in-test later to maint). + + * A helper function "git submodule" uses since v2.7.0 to list the + modules that match the pathspec argument given to its subcommands + (e.g. "submodule add ") has been fixed. + (merge 2b56bb7 sb/submodule-module-list-fix later to maint). + + * "git config section.var value" to set a value in per-repository + configuration file failed when it was run outside any repository, + but didn't say the reason correctly. + (merge 638fa62 js/config-set-in-non-repository later to maint). + + * The code to read the pack data using the offsets stored in the pack + idx file has been made more carefully check the validity of the + data in the idx. + (merge 7465feb jk/pack-idx-corruption-safety later to maint). + + * Other minor clean-ups and documentation updates + (merge f459823 ak/extract-argv0-last-dir-sep later to maint). + (merge 63ca1c0 ak/git-strip-extension-from-dashed-command later to maint). + (merge 4867f11 ps/plug-xdl-merge-leak later to maint). + (merge 4938686 dt/initial-ref-xn-commit-doc later to maint). + (merge 9537f21 ma/update-hooks-sample-typofix later to maint). diff --git a/Documentation/RelNotes/2.8.1.txt b/Documentation/RelNotes/2.8.1.txt new file mode 100644 index 0000000000..ef6d80b008 --- /dev/null +++ b/Documentation/RelNotes/2.8.1.txt @@ -0,0 +1,9 @@ +Git v2.8.1 Release Notes +======================== + +Fixes since v2.8 +---------------- + + * "make rpmbuild" target was broken as its input, git.spec.in, was + not updated to match a file it describes that has been renamed + recently. This has been fixed. diff --git a/Documentation/RelNotes/2.8.2.txt b/Documentation/RelNotes/2.8.2.txt new file mode 100644 index 0000000000..447b1933a8 --- /dev/null +++ b/Documentation/RelNotes/2.8.2.txt @@ -0,0 +1,70 @@ +Git v2.8.2 Release Notes +======================== + +Fixes since v2.8.1 +------------------ + + * The embedded args argv-array in the child process is used to build + the command line to run pack-objects instead of using a separate + array of strings. + + * Bunch of tests on "git clone" has been renumbered for better + organization. + + * The tests that involve running httpd leaked the system-wide + configuration in /etc/gitconfig to the tested environment. + + * "index-pack --keep=" was broken since v2.1.0 timeframe. + + * "git config --get-urlmatch", unlike other variants of the "git + config --get" family, did not signal error with its exit status + when there was no matching configuration. + + * The "--local-env-vars" and "--resolve-git-dir" options of "git + rev-parse" failed to work outside a repository when the command's + option parsing was rewritten in 1.8.5 era. + + * Fetching of history by naming a commit object name directly didn't + work across remote-curl transport. + + * A small memory leak in an error codepath has been plugged in xdiff + code. + + * strbuf_getwholeline() did not NUL-terminate the buffer on certain + corner cases in its error codepath. + + * The startup_info data, which records if we are working inside a + repository (among other things), are now uniformly available to Git + subcommand implementations, and Git avoids attempting to touch + references when we are not in a repository. + + * "git mergetool" did not work well with conflicts that both sides + deleted. + + * "git send-email" had trouble parsing alias file in mailrc format + when lines in it had trailing whitespaces on them. + + * When "git merge --squash" stopped due to conflict, the concluding + "git commit" failed to read in the SQUASH_MSG that shows the log + messages from all the squashed commits. + + * "git merge FETCH_HEAD" dereferenced NULL pointer when merging + nothing into an unborn history (which is arguably unusual usage, + which perhaps was the reason why nobody noticed it). + + * Build updates for MSVC. + + * "git diff -M" used to work better when two originally identical + files A and B got renamed to X/A and X/B by pairing A to X/A and B + to X/B, but this was broken in the 2.0 timeframe. + + * "git send-pack --all " was broken when its command line + option parsing was written in the 2.6 timeframe. + + * When running "git blame $path" with unnormalized data in the index + for the path, the data in the working tree was blamed, even though + "git add" would not have changed what is already in the index, due + to "safe crlf" that disables the line-end conversion. It has been + corrected. + +Also contains minor documentation updates and code clean-ups. diff --git a/Documentation/RelNotes/2.8.3.txt b/Documentation/RelNotes/2.8.3.txt new file mode 100644 index 0000000000..fedd9968e5 --- /dev/null +++ b/Documentation/RelNotes/2.8.3.txt @@ -0,0 +1,101 @@ +Git v2.8.3 Release Notes +======================== + +Fixes since v2.8.2 +------------------ + + * "git send-email" now uses a more readable timestamps when + formulating a message ID. + + * The repository set-up sequence has been streamlined (the biggest + change is that there is no longer git_config_early()), so that we + do not attempt to look into refs/* when we know we do not have a + Git repository. + + * When "git worktree" feature is in use, "git branch -d" allowed + deletion of a branch that is checked out in another worktree + + * When "git worktree" feature is in use, "git branch -m" renamed a + branch that is checked out in another worktree without adjusting + the HEAD symbolic ref for the worktree. + + * "git format-patch --help" showed `-s` and `--no-patch` as if these + are valid options to the command. We already hide `--patch` option + from the documentation, because format-patch is about showing the + diff, and the documentation now hides these options as well. + + * A change back in version 2.7 to "git branch" broke display of a + symbolic ref in a non-standard place in the refs/ hierarchy (we + expect symbolic refs to appear in refs/remotes/*/HEAD to point at + the primary branch the remote has, and as .git/HEAD to point at the + branch we locally checked out). + + * A partial rewrite of "git submodule" in the 2.7 timeframe changed + the way the gitdir: pointer in the submodules point at the real + repository location to use absolute paths by accident. This has + been corrected. + + * "git commit" misbehaved in a few minor ways when an empty message + is given via -m '', all of which has been corrected. + + * Support for CRAM-MD5 authentication method in "git imap-send" did + not work well. + + * The socks5:// proxy support added back in 2.6.4 days was not aware + that socks5h:// proxies behave differently. + + * "git config" had a codepath that tried to pass a NULL to + printf("%s"), which nobody seems to have noticed. + + * On Cygwin, object creation uses the "create a temporary and then + rename it to the final name" pattern, not "create a temporary, + hardlink it to the final name and then unlink the temporary" + pattern. + + This is necessary to use Git on Windows shared directories, and is + already enabled for the MinGW and plain Windows builds. It also + has been used in Cygwin packaged versions of Git for quite a while. + See http://thread.gmane.org/gmane.comp.version-control.git/291853 + and http://thread.gmane.org/gmane.comp.version-control.git/275680. + + * "git replace -e" did not honour "core.editor" configuration. + + * Upcoming OpenSSL 1.1.0 will break compilation b updating a few APIs + we use in imap-send, which has been adjusted for the change. + + * "git submodule" reports the paths of submodules the command + recurses into, but this was incorrect when the command was not run + from the root level of the superproject. + + * The test scripts for "git p4" (but not "git p4" implementation + itself) has been updated so that they would work even on a system + where the installed version of Python is python 3. + + * The "user.useConfigOnly" configuration variable makes it an error + if users do not explicitly set user.name and user.email. However, + its check was not done early enough and allowed another error to + trigger, reporting that the default value we guessed from the + system setting was unusable. This was a suboptimal end-user + experience as we want the users to set user.name/user.email without + relying on the auto-detection at all. + + * "git mv old new" did not adjust the path for a submodule that lives + as a subdirectory inside old/ directory correctly. + + * "git push" from a corrupt repository that attempts to push a large + number of refs deadlocked; the thread to relay rejection notices + for these ref updates blocked on writing them to the main thread, + after the main thread at the receiving end notices that the push + failed and decides not to read these notices and return a failure. + + * A question by "git send-email" to ask the identity of the sender + has been updated. + + * Recent update to Git LFS broke "git p4" by changing the output from + its "lfs pointer" subcommand. + + * Some multi-byte encoding can have a backslash byte as a later part + of one letter, which would confuse "highlight" filter used in + gitweb. + +Also contains minor documentation updates and code clean-ups. diff --git a/Documentation/RelNotes/2.8.4.txt b/Documentation/RelNotes/2.8.4.txt new file mode 100644 index 0000000000..f4e2552836 --- /dev/null +++ b/Documentation/RelNotes/2.8.4.txt @@ -0,0 +1,69 @@ +Git v2.8.4 Release Notes +======================== + +Fixes since v2.8.3 +------------------ + + * Documentation for "git merge --verify-signatures" has been updated + to clarify that the signature of only the commit at the tip is + verified. Also the phrasing used for signature and key validity is + adjusted to align with that used by OpenPGP. + + * On Windows, .git and optionally any files whose name starts with a + dot are now marked as hidden, with a core.hideDotFiles knob to + customize this behaviour. + + * Portability enhancement for "rebase -i" to help platforms whose + shell does not like "for i in " (which is not POSIX-kosher). + + * "git fsck" learned to catch NUL byte in a commit object as + potential error and warn. + + * CI test was taught to build documentation pages. + + * Many 'linkgit:' references were broken, + which are all fixed with this. + + * "git describe --contains" often made a hard-to-justify choice of + tag to give name to a given commit, because it tried to come up + with a name with smallest number of hops from a tag, causing an old + commit whose close descendant that is recently tagged were not + described with respect to an old tag but with a newer tag. It did + not help that its computation of "hop" count was further tweaked to + penalize being on a side branch of a merge. The logic has been + updated to favor using the tag with the oldest tagger date, which + is a lot easier to explain to the end users: "We describe a commit + in terms of the (chronologically) oldest tag that contains the + commit." + + * Running tests with '-x' option to trace the individual command + executions is a useful way to debug test scripts, but some tests + that capture the standard error stream and check what the command + said can be broken with the trace output mixed in. When running + our tests under "bash", however, we can redirect the trace output + to another file descriptor to keep the standard error of programs + being tested intact. + + * "http.cookieFile" configuration variable clearly wants a pathname, + but we forgot to treat it as such by e.g. applying tilde expansion. + + * When de-initialising all submodules, "git submodule deinit" gave a + faulty recommendation to use "git submodule deinit .", which would + result in a strange error message in a pathological corner case. + This has been corrected to suggest "submodule deinit --all" instead. + + * Many commands normalize command line arguments from NFD to NFC + variant of UTF-8 on OSX, but commands in the "diff" family did + not, causing "git diff $path" to complain that no such path is + known to Git. They have been taught to do the normalization. + + * A couple of bugs around core.autocrlf have been fixed. + + * "git difftool" learned to handle unmerged paths correctly in + dir-diff mode. + + * The "are we talking with TTY, doing an interactive session?" + detection has been updated to work better for "Git for Windows". + + +Also contains other minor documentation updates and code clean-ups. diff --git a/Documentation/RelNotes/2.8.5.txt b/Documentation/RelNotes/2.8.5.txt new file mode 100644 index 0000000000..7bd179fa12 --- /dev/null +++ b/Documentation/RelNotes/2.8.5.txt @@ -0,0 +1,12 @@ +Git v2.8.5 Release Notes +======================== + +Fixes since v2.8.4 +------------------ + + * "git-shell" rejects a request to serve a repository whose name + begins with a dash, which makes it no longer possible to get it + confused into spawning service programs like "git-upload-pack" with + an option like "--help", which in turn would spawn an interactive + pager, instead of working with the repository user asked to access + (i.e. the one whose name is "--help"). diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 98fc4cc1d0..e8ad978824 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -61,23 +61,28 @@ Make sure that you have tests for the bug you are fixing. See t/README for guidance. When adding a new feature, make sure that you have new tests to show -the feature triggers the new behaviour when it should, and to show the -feature does not trigger when it shouldn't. Also make sure that the -test suite passes after your commit. Do not forget to update the -documentation to describe the updated behaviour. - -Speaking of the documentation, it is currently a liberal mixture of US -and UK English norms for spelling and grammar, which is somewhat -unfortunate. A huge patch that touches the files all over the place -only to correct the inconsistency is not welcome, though. Potential -clashes with other changes that can result from such a patch are not -worth it. We prefer to gradually reconcile the inconsistencies in -favor of US English, with small and easily digestible patches, as a -side effect of doing some other real work in the vicinity (e.g. -rewriting a paragraph for clarity, while turning en_UK spelling to -en_US). Obvious typographical fixes are much more welcomed ("teh -> -"the"), preferably submitted as independent patches separate from -other documentation changes. +the feature triggers the new behavior when it should, and to show the +feature does not trigger when it shouldn't. After any code change, make +sure that the entire test suite passes. + +If you have an account at GitHub (and you can get one for free to work +on open source projects), you can use their Travis CI integration to +test your changes on Linux, Mac (and hopefully soon Windows). See +GitHub-Travis CI hints section for details. + +Do not forget to update the documentation to describe the updated +behavior and make sure that the resulting documentation set formats +well. It is currently a liberal mixture of US and UK English norms for +spelling and grammar, which is somewhat unfortunate. A huge patch that +touches the files all over the place only to correct the inconsistency +is not welcome, though. Potential clashes with other changes that can +result from such a patch are not worth it. We prefer to gradually +reconcile the inconsistencies in favor of US English, with small and +easily digestible patches, as a side effect of doing some other real +work in the vicinity (e.g. rewriting a paragraph for clarity, while +turning en_UK spelling to en_US). Obvious typographical fixes are much +more welcomed ("teh -> "the"), preferably submitted as independent +patches separate from other documentation changes. Oh, another thing. We are picky about whitespaces. Make sure your changes do not trigger errors with the sample pre-commit hook shipped @@ -370,6 +375,47 @@ Know the status of your patch after submission entitled "What's cooking in git.git" and "What's in git.git" giving the status of various proposed changes. +-------------------------------------------------- +GitHub-Travis CI hints + +With an account at GitHub (you can get one for free to work on open +source projects), you can use Travis CI to test your changes on Linux, +Mac (and hopefully soon Windows). You can find a successful example +test build here: https://travis-ci.org/git/git/builds/120473209 + +Follow these steps for the initial setup: + + (1) Fork https://github.com/git/git to your GitHub account. + You can find detailed instructions how to fork here: + https://help.github.com/articles/fork-a-repo/ + + (2) Open the Travis CI website: https://travis-ci.org + + (3) Press the "Sign in with GitHub" button. + + (4) Grant Travis CI permissions to access your GitHub account. + You can find more information about the required permissions here: + https://docs.travis-ci.com/user/github-oauth-scopes + + (5) Open your Travis CI profile page: https://travis-ci.org/profile + + (6) Enable Travis CI builds for your Git fork. + +After the initial setup, Travis CI will run whenever you push new changes +to your fork of Git on GitHub. You can monitor the test state of all your +branches here: https://travis-ci.org//git/branches + +If a branch did not pass all test cases then it is marked with a red +cross. In that case you can click on the failing Travis CI job and +scroll all the way down in the log. Find the line "<-- Click here to see +detailed test output!" and click on the triangle next to the log line +number to expand the detailed test output. Here is such a failing +example: https://travis-ci.org/git/git/jobs/122676187 + +Fix the problem and push your fix to your Git fork. This will trigger +a new Travis CI build to ensure all tests pass. + + ------------------------------------------------ MUA specific hints diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt index 760eab7428..02cb6845cd 100644 --- a/Documentation/blame-options.txt +++ b/Documentation/blame-options.txt @@ -69,6 +69,13 @@ include::line-range-format.txt[] iso format is used. For supported values, see the discussion of the --date option at linkgit:git-log[1]. +--[no-]progress:: + Progress status is reported on the standard error stream + by default when it is attached to a terminal. This flag + enables progress reporting even if not attached to a + terminal. Can't use `--progress` together with `--porcelain` + or `--incremental`. + -M||:: Detect moved or copied lines within a file. When a commit moves or copies a block of lines (e.g. the original file diff --git a/Documentation/config.txt b/Documentation/config.txt index f61788668e..02696208c9 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -81,13 +81,16 @@ Includes You can include one config file from another by setting the special `include.path` variable to the name of the file to be included. The +variable takes a pathname as its value, and is subject to tilde +expansion. + +The included file is expanded immediately, as if its contents had been found at the location of the include directive. If the value of the `include.path` variable is a relative path, the path is considered to be relative to the configuration file in which the include directive was -found. The value of `include.path` is subject to tilde expansion: `~/` -is expanded to the value of `$HOME`, and `~user/` to the specified -user's home directory. See below for examples. +found. See below for examples. + Example ~~~~~~~ @@ -114,7 +117,7 @@ Example [include] path = /path/to/foo.inc ; include by absolute path path = foo ; expand "foo" relative to the current file - path = ~/foo ; expand "foo" in your $HOME directory + path = ~/foo ; expand "foo" in your `$HOME` directory Values @@ -169,6 +172,13 @@ thing on the same output line (e.g. opening parenthesis before the list of branch names in `log --decorate` output) is set to be painted with `bold` or some other attribute. +pathname:: + A variable that takes a pathname value can be given a + string that begins with "`~/`" or "`~user/`", and the usual + tilde expansion happens to such a string: `~/` + is expanded to the value of `$HOME`, and `~user/` to the + specified user's home directory. + Variables ~~~~~~~~~ @@ -269,6 +279,12 @@ See linkgit:git-update-index[1]. + The default is true (when core.filemode is not specified in the config file). +core.hideDotFiles:: + (Windows-only) If true, mark newly-created directories and files whose + name starts with a dot as hidden. If 'dotGitOnly', only the `.git/` + directory is hidden, but no other files starting with a dot. The + default mode is 'dotGitOnly'. + core.ignoreCase:: If true, this option enables various workarounds to enable Git to work better on filesystems that are not case sensitive, @@ -308,6 +324,15 @@ core.trustctime:: crawlers and some backup systems). See linkgit:git-update-index[1]. True by default. +core.untrackedCache:: + Determines what to do about the untracked cache feature of the + index. It will be kept, if this variable is unset or set to + `keep`. It will automatically be added if set to `true`. And + it will automatically be removed, if set to `false`. Before + setting it to `true`, you should check that mtime is working + properly on your system. + See linkgit:git-update-index[1]. `keep` by default. + core.checkStat:: Determines which stat fields to match between the index and work tree. The user can set this to 'default' or @@ -328,9 +353,9 @@ core.quotePath:: core.eol:: Sets the line ending type to use in the working directory for - files that have the `text` property set. Alternatives are - 'lf', 'crlf' and 'native', which uses the platform's native - line ending. The default value is `native`. See + files that have the `text` property set when core.autocrlf is false. + Alternatives are 'lf', 'crlf' and 'native', which uses the platform's + native line ending. The default value is `native`. See linkgit:gitattributes[5] for more information on end-of-line conversion. @@ -477,10 +502,10 @@ repository's usual working tree). core.logAllRefUpdates:: Enable the reflog. Updates to a ref is logged to the file - "$GIT_DIR/logs/", by appending the new and old + "`$GIT_DIR/logs/`", by appending the new and old SHA-1, the date/time and the reason of the update, but only when the file exists. If this configuration - variable is set to true, missing "$GIT_DIR/logs/" + variable is set to true, missing "`$GIT_DIR/logs/`" file is automatically created for branch heads (i.e. under refs/heads/), remote refs (i.e. under refs/remotes/), note refs (i.e. under refs/notes/), and the symbolic ref HEAD. @@ -584,12 +609,11 @@ be delta compressed, but larger binary media files won't be. Common unit suffixes of 'k', 'm', or 'g' are supported. core.excludesFile:: - In addition to '.gitignore' (per-directory) and - '.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. Its default value is $XDG_CONFIG_HOME/git/ignore. - If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/ignore + Specifies the pathname to the file that contains patterns to + describe paths that are not meant to be tracked, in addition + to '.gitignore' (per-directory) and '.git/info/exclude'. + Defaults to `$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:: @@ -606,8 +630,8 @@ core.attributesFile:: '.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`. 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. + `$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 @@ -870,6 +894,8 @@ When preserve, also pass `--preserve-merges` along to 'git rebase' so that locally committed merge commits will not be flattened by running 'git pull'. + +When the value is `interactive`, the rebase is run in interactive mode. ++ *NOTE*: this is a possibly dangerous operation; do *not* use it unless you understand the implications (see linkgit:git-rebase[1] for details). @@ -1095,9 +1121,8 @@ commit.status:: message. Defaults to true. commit.template:: - Specify a file to use as the template for new commit messages. - "`~/`" is expanded to the value of `$HOME` and "`~user/`" to the - specified user's home directory. + Specify the pathname of a file to use as the template for + new commit messages. credential.helper:: Specify an external helper to be called when a username or @@ -1243,6 +1268,10 @@ format.coverLetter:: format-patch is invoked, but in addition can be set to "auto", to generate a cover-letter only when there's more than one patch. +format.outputDirectory:: + Set a custom directory to store the resulting files instead of the + current working directory. + filter..clean:: The command which is used to convert the content of a worktree file to a blob upon checkin. See linkgit:gitattributes[5] for @@ -1319,7 +1348,7 @@ gc.worktreePruneExpire:: 'git worktree prune --expire 3.months.ago'. This config variable can be used to set a different grace period. The value "now" may be used to disable the grace - period and prune $GIT_DIR/worktrees immediately, or "never" + period and prune `$GIT_DIR/worktrees` immediately, or "never" may be used to suppress pruning. gc.reflogExpire:: @@ -1450,14 +1479,22 @@ grep.extendedRegexp:: option is ignored when the 'grep.patternType' option is set to a value other than 'default'. +grep.threads:: + Number of grep worker threads to use. + See `grep.threads` in linkgit:git-grep[1] for more information. + +grep.fallbackToNoIndex:: + If set to true, fall back to git grep --no-index if git grep + is executed outside of a git repository. Defaults to false. + gpg.program:: - Use this custom program instead of "gpg" found on $PATH when + Use this custom program instead of "`gpg`" found on `$PATH` when making or verifying a PGP signature. The program must support the same command-line interface as GPG, namely, to verify a detached - signature, "gpg --verify $file - <$signature" is run, and the + signature, "`gpg --verify $file - <$signature`" is run, and the program is expected to signal a good signature by exiting with code 0, and to generate an ASCII-armored detached signature, the - standard input of "gpg -bsau $key" is fed with the contents to be + standard input of "`gpg -bsau $key`" is fed with the contents to be signed, and the program is expected to send the result to its standard output. @@ -1470,7 +1507,7 @@ gui.diffContext:: made by the linkgit:git-gui[1]. The default is "5". gui.displayUntracked:: - Determines if linkgit::git-gui[1] shows untracked files + Determines if linkgit:git-gui[1] shows untracked files in the file list. The default is "true". gui.encoding:: @@ -1596,16 +1633,48 @@ help.htmlPath:: http.proxy:: Override the HTTP proxy, normally configured using the 'http_proxy', - 'https_proxy', and 'all_proxy' environment variables (see - `curl(1)`). This can be overridden on a per-remote basis; see - remote..proxy + 'https_proxy', and 'all_proxy' environment variables (see `curl(1)`). In + addition to the syntax understood by curl, it is possible to specify a + proxy string with a user name but no password, in which case git will + attempt to acquire one in the same way it does for other credentials. See + linkgit:gitcredentials[7] for more information. The syntax thus is + '[protocol://][user[:password]@]proxyhost[:port]'. This can be overridden + on a per-remote basis; see remote..proxy + +http.proxyAuthMethod:: + Set the method with which to authenticate against the HTTP proxy. This + only takes effect if the configured proxy string contains a user name part + (i.e. is of the form 'user@host' or 'user@host:port'). This can be + overridden on a per-remote basis; see `remote..proxyAuthMethod`. + Both can be overridden by the 'GIT_HTTP_PROXY_AUTHMETHOD' environment + variable. Possible values are: ++ +-- +* `anyauth` - Automatically pick a suitable authentication method. It is + assumed that the proxy answers an unauthenticated request with a 407 + status code and one or more Proxy-authenticate headers with supported + authentication methods. This is the default. +* `basic` - HTTP Basic authentication +* `digest` - HTTP Digest authentication; this prevents the password from being + transmitted to the proxy in clear text +* `negotiate` - GSS-Negotiate authentication (compare the --negotiate option + of `curl(1)`) +* `ntlm` - NTLM authentication (compare the --ntlm option of `curl(1)`) +-- + +http.emptyAuth:: + Attempt authentication without seeking a username or password. This + can be used to attempt GSS-Negotiate authentication without specifying + a username in the URL, as libcurl normally requires a username for + authentication. http.cookieFile:: - File containing previously stored cookie lines which should be used + The pathname of a file containing previously stored cookie lines, + which should be used in the Git http session, if they match the server. The file format of the file to read cookies from should be plain HTTP headers or - the Netscape/Mozilla cookie file format (see linkgit:curl[1]). - NOTE that the file specified with http.cookieFile is only used as + the Netscape/Mozilla cookie file format (see `curl(1)`). + NOTE that the file specified with http.cookieFile is used only as input unless http.saveCookies is set. http.saveCookies:: @@ -1679,6 +1748,14 @@ http.sslCAPath:: with when fetching or pushing over HTTPS. Can be overridden by the 'GIT_SSL_CAPATH' environment variable. +http.pinnedpubkey:: + Public key of the https service. It may either be the filename of + a PEM or DER encoded public key file or a string starting with + 'sha256//' followed by the base64 encoded sha256 hash of the + public key. See also libcurl 'CURLOPT_PINNEDPUBLICKEY'. git will + exit with an error if this option is set but not supported by + cURL. + http.sslTry:: Attempt to use AUTH SSL/TLS and encrypted data transfers when connecting via regular FTP protocol. This might be needed @@ -2074,7 +2151,7 @@ pack.indexVersion:: larger than 2 GB. + If you have an old Git that does not understand the version 2 `*.idx` file, -cloning or fetching over a non native protocol (e.g. "http" and "rsync") +cloning or fetching over a non native protocol (e.g. "http") that will copy both `*.pack` file and corresponding `*.idx` file from the other side may give you a repository that cannot be accessed with your older version of Git. If the `*.pack` file is smaller than 2 GB, however, @@ -2085,8 +2162,11 @@ pack.packSizeLimit:: The maximum size of a pack. This setting only affects packing to a file when repacking, i.e. the git:// protocol is unaffected. It can be overridden by the `--max-pack-size` - option of linkgit:git-repack[1]. The minimum size allowed is - limited to 1 MiB. The default is unlimited. + option of linkgit:git-repack[1]. Reaching this limit results + in the creation of multiple packfiles; which in turn prevents + bitmaps from being created. + The minimum size allowed is limited to 1 MiB. + The default is unlimited. Common unit suffixes of 'k', 'm', or 'g' are supported. @@ -2149,6 +2229,8 @@ When preserve, also pass `--preserve-merges` along to 'git rebase' so that locally committed merge commits will not be flattened by running 'git pull'. + +When the value is `interactive`, the rebase is run in interactive mode. ++ *NOTE*: this is a possibly dangerous operation; do *not* use it unless you understand the implications (see linkgit:git-rebase[1] for details). @@ -2407,6 +2489,11 @@ remote..proxy:: the proxy to use for that remote. Set to the empty string to disable proxying for that remote. +remote..proxyAuthMethod:: + For remotes that require curl (http, https and ftp), the method to use for + authenticating against the proxy in use (probably set in + `remote..proxy`). See `http.proxyAuthMethod`. + remote..fetch:: The default set of "refspec" for linkgit:git-fetch[1]. See linkgit:git-fetch[1]. @@ -2479,8 +2566,9 @@ repack.writeBitmaps:: objects to disk (e.g., when `git repack -a` is run). This index can speed up the "counting objects" phase of subsequent packs created for clones and fetches, at the cost of some disk - space and extra time spent on the initial repack. Defaults to - false. + space and extra time spent on the initial repack. This has + no effect if multiple packfiles are created. + Defaults to false. rerere.autoUpdate:: When set to true, `git-rerere` updates the index with the @@ -2775,6 +2863,16 @@ user.name:: Can be overridden by the 'GIT_AUTHOR_NAME' and 'GIT_COMMITTER_NAME' environment variables. See linkgit:git-commit-tree[1]. +user.useConfigOnly:: + Instruct Git to avoid trying to guess defaults for 'user.email' + and 'user.name', and instead retrieve the values only from the + configuration. For example, if you have multiple email addresses + and would like to use a different one for each repository, then + with this configuration option set to `true` in the global config + along with a name, Git will prompt you to set up an email before + making new commits in a newly cloned repository. + Defaults to `false`. + user.signingKey:: If linkgit:git-tag[1] or linkgit:git-commit[1] is not selecting the key you want it to automatically when creating a signed tag or diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 306b7e3604..3cb301556e 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -26,12 +26,12 @@ ifndef::git-format-patch[] ifdef::git-diff[] This is the default. endif::git-diff[] -endif::git-format-patch[] -s:: --no-patch:: Suppress diff output. Useful for commands like `git show` that show the patch by default, or to cancel the effect of `--patch`. +endif::git-format-patch[] -U:: --unified=:: @@ -271,7 +271,7 @@ For example, `--word-diff-regex=.` will treat each character as a word and, correspondingly, show differences character by character. + The regex can also be set via a diff driver or configuration option, see -linkgit:gitattributes[1] or linkgit:git-config[1]. Giving it explicitly +linkgit:gitattributes[5] or linkgit:git-config[1]. Giving it explicitly overrides any diff driver or configuration setting. Diff drivers override configuration settings. @@ -286,8 +286,8 @@ endif::git-format-patch[] ifndef::git-format-patch[] --check:: - Warn if changes introduce whitespace errors. What are - considered whitespace errors is controlled by `core.whitespace` + Warn if changes introduce conflict markers or whitespace errors. + What are considered whitespace errors is controlled by `core.whitespace` configuration. By default, trailing whitespaces (including lines that solely consist of whitespaces) and a space character that is immediately followed by a tab character inside the diff --git a/Documentation/everyday.txto b/Documentation/everyday.txto index c5047d8f9b..ae555bd47e 100644 --- a/Documentation/everyday.txto +++ b/Documentation/everyday.txto @@ -1,7 +1,7 @@ Everyday Git With 20 Commands Or So =================================== -This document has been moved to linkgit:giteveryday[1]. +This document has been moved to linkgit:giteveryday[7]. Please let the owners of the referring site know so that they can update the link you clicked to get here. diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt index 78cd2653cd..036edfb099 100644 --- a/Documentation/fetch-options.txt +++ b/Documentation/fetch-options.txt @@ -101,6 +101,13 @@ ifndef::git-pull[] reference to a commit that isn't already in the local submodule clone. +-j:: +--jobs=:: + Number of parallel children to be used for fetching submodules. + Each will fetch from different submodules, such that fetching many + submodules will be faster. By default submodules will be fetched + one at a time. + --no-recurse-submodules:: Disable recursive fetching of submodules (this has the same effect as using the '--recurse-submodules=no' option). @@ -151,3 +158,11 @@ endif::git-pull[] by default when it is attached to a terminal, unless -q is specified. This flag forces progress status even if the standard error stream is not directed to a terminal. + +-4:: +--ipv4:: + Use IPv4 addresses only, ignoring IPv6 addresses. + +-6:: +--ipv6:: + Use IPv6 addresses only, ignoring IPv4 addresses. diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index d9ed6a1a4e..8ddb207409 100644 --- a/Documentation/git-apply.txt +++ b/Documentation/git-apply.txt @@ -13,7 +13,7 @@ SYNOPSIS [--apply] [--no-add] [--build-fake-ancestor=] [-R | --reverse] [--allow-binary-replacement | --binary] [--reject] [-z] [-p] [-C] [--inaccurate-eof] [--recount] [--cached] - [--ignore-space-change | --ignore-whitespace ] + [--ignore-space-change | --ignore-whitespace] [--whitespace=(nowarn|warn|fix|error|error-all)] [--exclude=] [--include=] [--directory=] [--verbose] [--unsafe-paths] [...] @@ -21,6 +21,8 @@ SYNOPSIS DESCRIPTION ----------- Reads the supplied diff output (i.e. "a patch") and applies it to files. +When running from a subdirectory in a repository, patched paths +outside the directory are ignored. With the `--index` option the patch is also applied to the index, and with the `--cached` option the patch is only applied to the index. Without these options, the command applies the patch only to files, diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt index e6e947c808..ba5417567c 100644 --- a/Documentation/git-blame.txt +++ b/Documentation/git-blame.txt @@ -10,7 +10,8 @@ SYNOPSIS [verse] 'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental] [-L ] [-S ] [-M] [-C] [-C] [-C] [--since=] - [--abbrev=] [ | --contents | --reverse ] [--] + [--progress] [--abbrev=] [ | --contents | --reverse ] + [--] DESCRIPTION ----------- diff --git a/Documentation/git-bundle.txt b/Documentation/git-bundle.txt index 0417562eb7..3a8120c3b3 100644 --- a/Documentation/git-bundle.txt +++ b/Documentation/git-bundle.txt @@ -20,7 +20,7 @@ DESCRIPTION Some workflows require that one or more branches of development on one machine be replicated on another machine, but the two machines cannot be directly connected, and therefore the interactive Git protocols (git, -ssh, rsync, http) cannot be used. This command provides support for +ssh, http) cannot be used. This command provides support for 'git fetch' and 'git pull' to operate by packaging objects and references in an archive at the originating machine, then importing those into another repository using 'git fetch' and 'git pull' diff --git a/Documentation/git-check-ignore.txt b/Documentation/git-check-ignore.txt index e94367a5ed..611754f10b 100644 --- a/Documentation/git-check-ignore.txt +++ b/Documentation/git-check-ignore.txt @@ -112,7 +112,7 @@ EXIT STATUS SEE ALSO -------- linkgit:gitignore[5] -linkgit:gitconfig[5] +linkgit:git-config[1] linkgit:git-ls-files[1] GIT diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 789b668f77..b7c467a001 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -115,8 +115,7 @@ objects from the source repository into a pack in the cloned repository. --quiet:: -q:: Operate quietly. Progress is not reported to the standard - error stream. This flag is also passed to the `rsync' - command when given. + error stream. --verbose:: -v:: diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 2608ca74ac..6843114fc0 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -9,18 +9,18 @@ git-config - Get and set repository or global options SYNOPSIS -------- [verse] -'git config' [] [type] [-z|--null] name [value [value_regex]] +'git config' [] [type] [--show-origin] [-z|--null] name [value [value_regex]] 'git config' [] [type] --add name value 'git config' [] [type] --replace-all name value [value_regex] -'git config' [] [type] [-z|--null] --get name [value_regex] -'git config' [] [type] [-z|--null] --get-all name [value_regex] -'git config' [] [type] [-z|--null] [--name-only] --get-regexp name_regex [value_regex] +'git config' [] [type] [--show-origin] [-z|--null] --get name [value_regex] +'git config' [] [type] [--show-origin] [-z|--null] --get-all name [value_regex] +'git config' [] [type] [--show-origin] [-z|--null] [--name-only] --get-regexp name_regex [value_regex] 'git config' [] [type] [-z|--null] --get-urlmatch name URL 'git config' [] --unset name [value_regex] 'git config' [] --unset-all name [value_regex] 'git config' [] --rename-section old_name new_name 'git config' [] --remove-section name -'git config' [] [-z|--null] [--name-only] -l | --list +'git config' [] [--show-origin] [-z|--null] [--name-only] -l | --list 'git config' [] --get-color name [default] 'git config' [] --get-colorbool name [stdout-is-tty] 'git config' [] -e | --edit @@ -58,13 +58,13 @@ that location (you can say '--local' but that is the default). This command will fail with non-zero status upon error. Some exit codes are: -. The config file is invalid (ret=3), -. can not write to the config file (ret=4), -. no section or name was provided (ret=2), -. the section or key is invalid (ret=1), -. you try to unset an option which does not exist (ret=5), -. you try to unset/set an option for which multiple lines match (ret=5), or -. you try to use an invalid regexp (ret=6). +- The section or key is invalid (ret=1), +- no section or name was provided (ret=2), +- the config file is invalid (ret=3), +- the config file cannot be written (ret=4), +- you try to unset an option which does not exist (ret=5), +- you try to unset/set an option for which multiple lines match (ret=5), or +- you try to use an invalid regexp (ret=6). On success, the command returns the exit code 0. @@ -86,8 +86,7 @@ OPTIONS found and the last value if multiple key values were found. --get-all:: - Like get, but does not fail if the number of values for the key - is not exactly one. + Like get, but returns all values for a multi-valued key. --get-regexp:: Like --get-all, but interprets the name as a regular expression and @@ -102,7 +101,7 @@ OPTIONS given URL is returned (if no such key exists, the value for section.key is used as a fallback). When given just the section as name, do so for all the keys in the section and - list them. + list them. Returns error code 1 if no value is found. --global:: For writing options: write to global `~/.gitconfig` file @@ -194,6 +193,12 @@ See also <>. Output only the names of config variables for `--list` or `--get-regexp`. +--show-origin:: + Augment the output of all queried config options with the + origin type (file, standard input, blob, command line) and + the actual origin (config file path, ref, or blob id if + applicable). + --get-colorbool name [stdout-is-tty]:: Find the color setting for `name` (e.g. `color.diff`) and output @@ -219,7 +224,9 @@ See also <>. --[no-]includes:: Respect `include.*` directives in config files when looking up - values. Defaults to on. + values. Defaults to `off` when a specific file is given (e.g., + using `--file`, `--global`, etc) and `on` when searching all + config files. [[FILES]] FILES diff --git a/Documentation/git-credential-cache.txt b/Documentation/git-credential-cache.txt index 89b730632d..96208f822e 100644 --- a/Documentation/git-credential-cache.txt +++ b/Documentation/git-credential-cache.txt @@ -36,7 +36,7 @@ OPTIONS cache daemon if one is not started). Defaults to `~/.git-credential-cache/socket`. If your home directory is on a network-mounted filesystem, you may need to change this to a - local filesystem. + local filesystem. You must specify an absolute path. CONTROLLING THE DAEMON ---------------------- diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt index 8680f45f8d..239623cc24 100644 --- a/Documentation/git-fetch-pack.txt +++ b/Documentation/git-fetch-pack.txt @@ -104,6 +104,10 @@ be in a separate packet, and the list must end with a flush packet. The remote heads to update from. This is relative to $GIT_DIR (e.g. "HEAD", "refs/heads/master"). When unspecified, update from all heads the remote side has. ++ +If the remote has enabled the options `uploadpack.allowTipSHA1InWant` or +`uploadpack.allowReachableSHA1InWant`, they may alternatively be 40-hex +sha1s present on the remote. SEE ALSO -------- diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index 73fd9e8230..003731f6a9 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -205,7 +205,7 @@ to other tags will be rewritten to point to the underlying commit. Remap to ancestor ~~~~~~~~~~~~~~~~~ -By using linkgit:rev-list[1] arguments, e.g., path limiters, you can limit the +By using linkgit:git-rev-list[1] arguments, e.g., path limiters, you can limit the set of revisions which get rewritten. However, positive refs on the command line are distinguished: we don't let them be excluded by such limiters. For this purpose, they are instead rewritten to point at the nearest ancestor that diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index 2e3e96f663..d9d406dcfb 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -76,7 +76,7 @@ OPTIONS specified commit (HEAD if not specified). --contains []:: - Only list tags which contain the specified commit (HEAD if not + Only list refs which contain the specified commit (HEAD if not specified). FIELD NAMES @@ -133,14 +133,18 @@ color:: align:: Left-, middle-, or right-align the content between - %(align:...) and %(end). The "align:" is followed by `` - and `` in any order separated by a comma, where the - `` is either left, right or middle, default being - left and `` is the total length of the content with - alignment. If the contents length is more than the width then - no alignment is performed. If used with '--quote' everything - in between %(align:...) and %(end) is quoted, but if nested - then only the topmost level performs quoting. + %(align:...) and %(end). The "align:" is followed by + `width=` and `position=` in any order + separated by a comma, where the `` is either left, + right or middle, default being left and `` is the total + length of the content with alignment. For brevity, the + "width=" and/or "position=" prefixes may be omitted, and bare + and used instead. For instance, + `%(align:,)`. If the contents length is more + than the width then no alignment is performed. If used with + '--quote' everything in between %(align:...) and %(end) is + quoted, but if nested then only the topmost level performs + quoting. In addition to the above, for commit and tag objects, the header field names (`tree`, `parent`, `object`, `type`, and `tag`) can @@ -175,7 +179,7 @@ returns an empty string instead. As a special case for the date-type fields, you may specify a format for the date by adding `:` followed by date format name (see the -values the `--date` option to linkgit::git-rev-list[1] takes). +values the `--date` option to linkgit:git-rev-list[1] takes). EXAMPLES diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index b149e09065..6821441d7d 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -57,7 +57,11 @@ The names of the output files are printed to standard output, unless the `--stdout` option is specified. If `-o` is specified, output files are created in . Otherwise -they are created in the current working directory. +they are created in the current working directory. The default path +can be set with the 'format.outputDirectory' configuration option. +The `-o` option takes precedence over `format.outputDirectory`. +To store patches in the current working directory even when +`format.outputDirectory` points elsewhere, use `-o .`. By default, the subject of a single patch is "[PATCH] " followed by the concatenation of lines from the commit message up to the first blank diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index 4a44d6da13..cb0f6cf678 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -23,6 +23,7 @@ SYNOPSIS [--break] [--heading] [-p | --show-function] [-A ] [-B ] [-C ] [-W | --function-context] + [--threads ] [-f ] [-e] [--and|--or|--not|(|)|-e ...] [ [--[no-]exclude-standard] [--cached | --no-index | --untracked] | ...] @@ -53,9 +54,17 @@ grep.extendedRegexp:: option is ignored when the 'grep.patternType' option is set to a value other than 'default'. +grep.threads:: + Number of grep worker threads to use. If unset (or set to 0), + 8 threads are used by default (for now). + grep.fullName:: If set to true, enable '--full-name' option by default. +grep.fallbackToNoIndex:: + If set to true, fall back to git grep --no-index if git grep + is executed outside of a git repository. Defaults to false. + OPTIONS ------- @@ -227,6 +236,10 @@ OPTIONS effectively showing the whole function in which the match was found. +--threads :: + Number of grep worker threads to use. + See `grep.threads` in 'CONFIGURATION' for more information. + -f :: Read patterns from , one per line. diff --git a/Documentation/git-interpret-trailers.txt b/Documentation/git-interpret-trailers.txt index 0ecd497c4d..a77b901f1d 100644 --- a/Documentation/git-interpret-trailers.txt +++ b/Documentation/git-interpret-trailers.txt @@ -8,7 +8,7 @@ git-interpret-trailers - help add structured information into commit messages SYNOPSIS -------- [verse] -'git interpret-trailers' [--trim-empty] [(--trailer [(=|:)])...] [...] +'git interpret-trailers' [--in-place] [--trim-empty] [(--trailer [(=|:)])...] [...] DESCRIPTION ----------- @@ -64,6 +64,9 @@ folding rules, the encoding rules and probably many other rules. OPTIONS ------- +--in-place:: + Edit the files in place. + --trim-empty:: If the part of any trailer contains only whitespace, the whole trailer will be removed from the resulting message. @@ -216,6 +219,25 @@ Signed-off-by: Alice Signed-off-by: Bob ------------ +* Use the '--in-place' option to edit a message file in place: ++ +------------ +$ cat msg.txt +subject + +message + +Signed-off-by: Bob +$ git interpret-trailers --trailer 'Acked-by: Alice ' --in-place msg.txt +$ cat msg.txt +subject + +message + +Signed-off-by: Bob +Acked-by: Alice +------------ + * Extract the last commit as a patch, and add a 'Cc' and a 'Reviewed-by' trailer to it: + diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt index e26f01fb1d..75c3f4157d 100644 --- a/Documentation/git-ls-files.txt +++ b/Documentation/git-ls-files.txt @@ -12,6 +12,7 @@ SYNOPSIS 'git ls-files' [-z] [-t] [-v] (--[cached|deleted|others|ignored|stage|unmerged|killed|modified])* (-[c|d|o|i|s|u|k|m])* + [--eol] [-x |--exclude=] [-X |--exclude-from=] [--exclude-per-directory=] @@ -147,6 +148,24 @@ a space) at the start of each line: possible for manual inspection; the exact format may change at any time. +--eol:: + Show and of files. + is the file content identification used by Git when + the "text" attribute is "auto" (or not set and core.autocrlf is not false). + is either "-text", "none", "lf", "crlf", "mixed" or "". ++ +"" means the file is not a regular file, it is not in the index or +not accessible in the working tree. ++ + is the attribute that is used when checking out or committing, +it is either "", "-text", "text", "text=auto", "text eol=lf", "text eol=crlf". +Note: Currently Git does not support "text=auto eol=lf" or "text=auto eol=crlf", +that may change in the future. ++ +Both the in the index ("i/") +and in the working tree ("w/") are shown for regular files, +followed by the ("attr/"). + \--:: Do not interpret any more arguments as options. @@ -161,6 +180,9 @@ which case it outputs: [ ] +'git ls-files --eol' will show + i/w/attr/ + 'git ls-files --unmerged' and 'git ls-files --stage' can be used to examine detailed information on unmerged paths. diff --git a/Documentation/git-ls-remote.txt b/Documentation/git-ls-remote.txt index d510c05e11..5f2628c8f8 100644 --- a/Documentation/git-ls-remote.txt +++ b/Documentation/git-ls-remote.txt @@ -9,8 +9,9 @@ git-ls-remote - List references in a remote repository SYNOPSIS -------- [verse] -'git ls-remote' [--heads] [--tags] [--upload-pack=] - [--exit-code] [...] +'git ls-remote' [--heads] [--tags] [--refs] [--upload-pack=] + [-q | --quiet] [--exit-code] [--get-url] + [--symref] [ [...]] DESCRIPTION ----------- @@ -29,6 +30,13 @@ OPTIONS both, references stored in refs/heads and refs/tags are displayed. +--refs:: + Do not show peeled tags or pseudorefs like HEAD in the output. + +-q:: +--quiet:: + Do not print remote URL to stderr. + --upload-pack=:: Specify the full path of 'git-upload-pack' on the remote host. This allows listing references from repositories accessed via @@ -46,6 +54,12 @@ OPTIONS "url..insteadOf" config setting (See linkgit:git-config[1]) and exit without talking to the remote. +--symref:: + In addition to the object pointed by it, show the underlying + ref pointed by it when showing a symbolic ref. Currently, + upload-pack only shows the symref HEAD, so it will be the only + one shown by ls-remote. + :: The "remote" repository to query. This parameter can be either a URL or the name of a remote (see the GIT URLS and diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt index 0947084140..3bbc731f67 100644 --- a/Documentation/git-mailinfo.txt +++ b/Documentation/git-mailinfo.txt @@ -85,7 +85,7 @@ with comments and suggestions on the message you are responding to, and to conclude it with a patch submission, separating the discussion and the beginning of the proposed commit log message with a scissors line. + -This can enabled by default with the configuration option mailinfo.scissors. +This can be enabled by default with the configuration option mailinfo.scissors. --no-scissors:: Ignore scissors lines. Useful for overriding mailinfo.scissors settings. diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index 8de349968a..9c4fd6812c 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.txt @@ -402,4 +402,4 @@ on the `notes.rewrite.` and `notes.rewriteRef` settings. GIT --- -Part of the linkgit:git[7] suite +Part of the linkgit:git[1] suite diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt index 738cfde10c..35e3170918 100644 --- a/Documentation/git-p4.txt +++ b/Documentation/git-p4.txt @@ -515,20 +515,18 @@ git-p4.pathEncoding:: Git expects paths encoded as UTF-8. Use this config to tell git-p4 what encoding Perforce had used for the paths. This encoding is used to transcode the paths to UTF-8. As an example, Perforce on Windows - often uses “cp1252” to encode path names. + often uses "cp1252" to encode path names. git-p4.largeFileSystem:: Specify the system that is used for large (binary) files. Please note that large file systems do not support the 'git p4 submit' command. - Only Git LFS [1] is implemented right now. Download - and install the Git LFS command line extension to use this option - and configure it like this: + Only Git LFS is implemented right now (see https://git-lfs.github.com/ + for more information). Download and install the Git LFS command line + extension to use this option and configure it like this: + ------------- git config git-p4.largeFileSystem GitLFS ------------- -+ - [1] https://git-lfs.github.com/ git-p4.largeFileExtensions:: All files matching a file extension in the list will be processed diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt index bbea5294ca..19cdcd0341 100644 --- a/Documentation/git-pack-objects.txt +++ b/Documentation/git-pack-objects.txt @@ -110,7 +110,8 @@ base-name:: --max-pack-size=:: Maximum size of each output pack file. The size can be suffixed with "k", "m", or "g". The minimum size allowed is limited to 1 MiB. - If specified, multiple packfiles may be created. + If specified, multiple packfiles may be created, which also + prevents the creation of a bitmap index. The default is unlimited, unless the config variable `pack.packSizeLimit` is set. diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index 93c72a29ce..a62a2a615d 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt @@ -101,7 +101,7 @@ Options related to merging include::merge-options.txt[] -r:: ---rebase[=false|true|preserve]:: +--rebase[=false|true|preserve|interactive]:: When true, rebase the current branch on top of the upstream branch after fetching. If there is a remote-tracking branch corresponding to the upstream branch and the upstream branch @@ -113,6 +113,8 @@ to `git rebase` so that locally created merge commits will not be flattened. + When false, merge the current branch into the upstream branch. + +When `interactive`, enable the interactive mode of rebase. ++ See `pull.rebase`, `branch..rebase` and `branch.autoSetupRebase` in linkgit:git-config[1] if you want to make `git pull` always use `--rebase` instead of merging. diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index af521f8990..cf6ee4a4df 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git push' [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=] - [--repo=] [-f | --force] [--prune] [-v | --verbose] + [--repo=] [-f | --force] [-d | --delete] [--prune] [-v | --verbose] [-u | --set-upstream] [--[no-]signed|--sign=(true|false|if-asked)] [--force-with-lease[=[:]]] @@ -284,6 +284,13 @@ origin +master` to force a push to the `master` branch). See the default is --verify, giving the hook a chance to prevent the push. With --no-verify, the hook is bypassed completely. +-4:: +--ipv4:: + Use IPv4 addresses only, ignoring IPv6 addresses. + +-6:: +--ipv6:: + Use IPv6 addresses only, ignoring IPv4 addresses. include::urls-remotes.txt[] diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 6cca8bb51d..6ed610a031 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -3,7 +3,7 @@ git-rebase(1) NAME ---- -git-rebase - Forward-port local commits to the updated upstream head +git-rebase - Reapply commits on top of another base tip SYNOPSIS -------- diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt index 0e0bd363d6..b9c02ce481 100644 --- a/Documentation/git-repack.txt +++ b/Documentation/git-repack.txt @@ -106,7 +106,8 @@ other objects in that pack they already have locally. --max-pack-size=:: Maximum size of each output pack file. The size can be suffixed with "k", "m", or "g". The minimum size allowed is limited to 1 MiB. - If specified, multiple packfiles may be created. + If specified, multiple packfiles may be created, which also + prevents the creation of a bitmap index. The default is unlimited, unless the config variable `pack.packSizeLimit` is set. @@ -115,7 +116,8 @@ other objects in that pack they already have locally. Write a reachability bitmap index as part of the repack. This only makes sense when used with `-a` or `-A`, as the bitmaps must be able to refer to all reachable objects. This option - overrides the setting of `pack.writeBitmaps`. + overrides the setting of `repack.writeBitmaps`. This option + has no effect if multiple packfiles are created. --pack-kept-objects:: Include objects in `.keep` files when repacking. Note that we @@ -123,7 +125,7 @@ other objects in that pack they already have locally. This means that we may duplicate objects, but this makes the option safe to use when there are concurrent pushes or fetches. This option is generally only useful if you are writing bitmaps - with `-b` or `pack.writeBitmaps`, as it ensures that the + with `-b` or `repack.writeBitmaps`, as it ensures that the bitmapped packfile has the necessary objects. Configuration @@ -133,7 +135,7 @@ By default, the command passes `--delta-base-offset` option to 'git pack-objects'; this typically results in slightly smaller packs, but the generated packs are incompatible with versions of Git older than version 1.4.4. If you need to share your repository with such ancient Git -versions, either directly or via the dumb http or rsync protocol, then you +versions, either directly or via the dumb http protocol, then you need to set the configuration variable `repack.UseDeltaBaseOffset` to "false" and repack. Access from old Git versions over the native protocol is unaffected by this option as the conversion is performed on the fly diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 1572f058f5..ad851838cc 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -13,7 +13,7 @@ SYNOPSIS [--reference ] [--depth ] [--] [] 'git submodule' [--quiet] status [--cached] [--recursive] [--] [...] 'git submodule' [--quiet] init [--] [...] -'git submodule' [--quiet] deinit [-f|--force] [--] ... +'git submodule' [--quiet] deinit [-f|--force] (--all|[--] ...) 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase|--merge] [--reference ] [--depth ] [--recursive] [--] [...] @@ -140,12 +140,15 @@ deinit:: tree. Further calls to `git submodule update`, `git submodule foreach` and `git submodule sync` will skip any unregistered submodules until they are initialized again, so use this command if you don't want to - have a local checkout of the submodule in your work tree anymore. If + have a local checkout of the submodule in your working tree anymore. If you really want to remove a submodule from the repository and commit that use linkgit:git-rm[1] instead. + -If `--force` is specified, the submodule's work tree will be removed even if -it contains local modifications. +When the command is run without pathspec, it errors out, +instead of deinit-ing everything, to prevent mistakes. ++ +If `--force` is specified, the submodule's working tree will +be removed even if it contains local modifications. update:: + @@ -247,6 +250,10 @@ OPTIONS --quiet:: Only print error messages. +--all:: + This option is only valid for the deinit command. Unregister all + submodules in the working tree. + -b:: --branch:: Branch of repository to add as submodule. @@ -257,8 +264,8 @@ OPTIONS --force:: This option is only valid for add, deinit and update commands. When running add, allow adding an otherwise ignored submodule path. - When running deinit the submodule work trees will be removed even if - they contain local changes. + When running deinit the submodule working trees will be removed even + if they contain local changes. When running update (only effective with the checkout procedure), throw away local changes in submodules when switching to a different commit; and always run a checkout operation in the diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 0c0f60b20e..fb23a98a17 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -1034,6 +1034,8 @@ listed below are allowed: url = http://server.org/svn fetch = trunk/project-a:refs/remotes/project-a/trunk branches = branches/*/project-a:refs/remotes/project-a/branches/* + branches = branches/release_*:refs/remotes/project-a/branches/release_* + branches = branches/re*se:refs/remotes/project-a/branches/* tags = tags/*/project-a:refs/remotes/project-a/tags/* ------------------------------------------------------------------------ @@ -1044,6 +1046,16 @@ independent path component (surrounded by '/' or EOL). This type of configuration is not automatically created by 'init' and should be manually entered with a text-editor or using 'git config'. +Also note that only one asterisk is allowed per word. For example: + + branches = branches/re*se:refs/remotes/project-a/branches/* + +will match branches 'release', 'rese', 're123se', however + + branches = branches/re*s*e:refs/remotes/project-a/branches/* + +will produce an error. + It is also possible to fetch a subset of branches or tags by using a comma-separated list of names within braces. For example: diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt index f4e5a85351..c6cbed189c 100644 --- a/Documentation/git-update-index.txt +++ b/Documentation/git-update-index.txt @@ -18,7 +18,7 @@ SYNOPSIS [--[no-]skip-worktree] [--ignore-submodules] [--[no-]split-index] - [--[no-|force-]untracked-cache] + [--[no-|test-|force-]untracked-cache] [--really-refresh] [--unresolve] [--again | -g] [--info-only] [--index-info] [-z] [--stdin] [--index-version ] @@ -174,17 +174,30 @@ may not support it yet. --untracked-cache:: --no-untracked-cache:: - Enable or disable untracked cache extension. This could speed - up for commands that involve determining untracked files such - as `git status`. The underlying operating system and file - system must change `st_mtime` field of a directory if files - are added or deleted in that directory. + Enable or disable untracked cache feature. Please use + `--test-untracked-cache` before enabling it. ++ +These options take effect whatever the value of the `core.untrackedCache` +configuration variable (see linkgit:git-config[1]). But a warning is +emitted when the change goes against the configured value, as the +configured value will take effect next time the index is read and this +will remove the intended effect of the option. + +--test-untracked-cache:: + Only perform tests on the working directory to make sure + untracked cache can be used. You have to manually enable + untracked cache using `--untracked-cache` or + `--force-untracked-cache` or the `core.untrackedCache` + configuration variable afterwards if you really want to use + it. If a test fails the exit code is 1 and a message + explains what is not working as needed, otherwise the exit + code is 0 and OK is printed. --force-untracked-cache:: - For safety, `--untracked-cache` performs tests on the working - directory to make sure untracked cache can be used. These - tests can take a few seconds. `--force-untracked-cache` can be - used to skip the tests. + Same as `--untracked-cache`. Provided for backwards + compatibility with older versions of Git where + `--untracked-cache` used to imply `--test-untracked-cache` but + this option would enable the extension unconditionally. \--:: Do not interpret any more arguments as options. @@ -375,6 +388,37 @@ Although this bit looks similar to assume-unchanged bit, its goal is different from assume-unchanged bit's. Skip-worktree also takes precedence over assume-unchanged bit when both are set. +Untracked cache +--------------- + +This cache is meant to speed up commands that involve determining +untracked files such as `git status`. + +This feature works by recording the mtime of the working tree +directories and then omitting reading directories and stat calls +against files in those directories whose mtime hasn't changed. For +this to work the underlying operating system and file system must +change the `st_mtime` field of directories if files in the directory +are added, modified or deleted. + +You can test whether the filesystem supports that with the +`--test-untracked-cache` option. The `--untracked-cache` option used +to implicitly perform that test in older versions of Git, but that's +no longer the case. + +If you want to enable (or disable) this feature, it is easier to use +the `core.untrackedCache` configuration variable (see +linkgit:git-config[1]) than using the `--untracked-cache` option to +`git update-index` in each repository, especially if you want to do so +across all repositories you use, because you can set the configuration +variable to `true` (or `false`) in your `$HOME/.gitconfig` just once +and have it affect all repositories you touch. + +When the `core.untrackedCache` configuration variable is changed, the +untracked cache is added to or removed from the index the next time a +command reads the index; while when `--[no-|force-]untracked-cache` +are used, the untracked cache is immediately added to or removed from +the index. Configuration ------------- @@ -400,6 +444,9 @@ It can be useful when the inode change time is regularly modified by something outside Git (file system crawlers and backup systems use ctime for marking files processed) (see linkgit:git-config[1]). +The untracked cache extension can be enabled by the +`core.untrackedCache` configuration variable (see +linkgit:git-config[1]). SEE ALSO -------- diff --git a/Documentation/git.txt b/Documentation/git.txt index bf9b6c8c87..8fdb0c8c23 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,6 +43,16 @@ unreleased) version of Git, that is available from the 'master' branch of the `git.git` repository. Documentation for older releases are available here: +* link:v2.8.5/git.html[documentation for release 2.8.5] + +* release notes for + link:RelNotes/2.8.5.txt[2.8.5], + link:RelNotes/2.8.4.txt[2.8.4], + link:RelNotes/2.8.3.txt[2.8.3], + link:RelNotes/2.8.2.txt[2.8.2], + link:RelNotes/2.8.1.txt[2.8.1], + link:RelNotes/2.8.0.txt[2.8]. + * link:v2.7.5/git.html[documentation for release 2.7.5] * release notes for @@ -1132,9 +1142,7 @@ of clones and fetches. connection (or proxy, if configured) - `ssh`: git over ssh (including `host:path` syntax, - `git+ssh://`, etc). - - - `rsync`: git over rsync + `ssh://`, etc). - `http`: git over http, both "smart http" and "dumb http". Note that this does _not_ include `https`; if you want both, diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt index 36e9ab3e16..15b3bfa8db 100644 --- a/Documentation/gitcore-tutorial.txt +++ b/Documentation/gitcore-tutorial.txt @@ -710,7 +710,7 @@ files). Again, this can all be simplified with ---------------- -$ git clone rsync://rsync.kernel.org/pub/scm/git/git.git/ my-git +$ git clone git://git.kernel.org/pub/scm/git/git.git/ my-git $ cd my-git $ git checkout ---------------- @@ -1011,20 +1011,6 @@ $ git fetch One of the following transports can be used to name the repository to download from: -Rsync:: - `rsync://remote.machine/path/to/repo.git/` -+ -Rsync transport is usable for both uploading and downloading, -but is completely unaware of what git does, and can produce -unexpected results when you download from the public repository -while the repository owner is uploading into it via `rsync` -transport. Most notably, it could update the files under -`refs/` which holds the object name of the topmost commits -before uploading the files in `objects/` -- the downloader would -obtain head commit object name while that object itself is still -not available in the repository. For this reason, it is -considered deprecated. - SSH:: `remote.machine:/path/to/repo.git/` or + @@ -1430,7 +1416,7 @@ while, depending on how active your project is. When a repository is synchronized via `git push` and `git pull` objects packed in the source repository are usually stored -unpacked in the destination, unless rsync transport is used. +unpacked in the destination. While this allows you to use different packing strategies on both ends, it also means you may need to repack both repositories every once in a while. diff --git a/Documentation/gittutorial.txt b/Documentation/gittutorial.txt index b00c67df46..b3b58d324e 100644 --- a/Documentation/gittutorial.txt +++ b/Documentation/gittutorial.txt @@ -451,7 +451,7 @@ perform clones and pulls using the ssh protocol: bob$ git clone alice.org:/home/alice/project myrepo ------------------------------------- -Alternatively, Git has a native protocol, or can use rsync or http; +Alternatively, Git has a native protocol, or can use http; see linkgit:git-pull[1] for details. Git can also be used in a CVS-like mode, with a central repository diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt index cafc284359..8ad29e61a9 100644 --- a/Documentation/glossary-content.txt +++ b/Documentation/glossary-content.txt @@ -145,7 +145,7 @@ current branch integrates with) obviously do not work, as there is no A fast-forward is a special type of <> where you have a <> and you are "merging" another <>'s changes that happen to be a descendant of what - you have. In such these cases, you do not make a new <> + you have. In such a case, you do not make a new <> <> but instead just update to his revision. This will happen frequently on a <> of a remote diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index f08e9b80c5..30808a01e7 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -89,8 +89,11 @@ option can be used to override --squash. --verify-signatures:: --no-verify-signatures:: - Verify that the commits being merged have good and trusted GPG signatures - and abort the merge in case they do not. + Verify that the tip commit of the side branch being merged is + signed with a valid key, i.e. a key that has a valid uid: in the + default trust model, this means the signing key has been signed by + a trusted key. If the tip commit of the side branch is not signed + with a valid key, the merge is aborted. --summary:: --no-summary:: diff --git a/Documentation/merge-strategies.txt b/Documentation/merge-strategies.txt index 7bbd19b300..2eb92b9327 100644 --- a/Documentation/merge-strategies.txt +++ b/Documentation/merge-strategies.txt @@ -81,9 +81,17 @@ no-renormalize;; Disables the `renormalize` option. This overrides the `merge.renormalize` configuration variable. +no-renames;; + Turn off rename detection. + See also linkgit:git-diff[1] `--no-renames`. + +find-renames[=];; + Turn on rename detection, optionally setting the similarity + threshold. This is the default. + See also linkgit:git-diff[1] `--find-renames`. + rename-threshold=;; - Controls the similarity threshold used for rename detection. - See also linkgit:git-diff[1] `-M`. + Deprecated synonym for `find-renames=`. subtree[=];; This option is a more advanced form of 'subtree' strategy, where diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index 671cebd95c..29b19b992f 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -143,8 +143,8 @@ ifndef::git-rev-list[] - '%N': commit notes endif::git-rev-list[] - '%GG': raw verification message from GPG for a signed commit -- '%G?': show "G" for a Good signature, "B" for a Bad signature, "U" for a good, - untrusted signature and "N" for no signature +- '%G?': show "G" for a good (valid) signature, "B" for a bad signature, + "U" for a good signature with unknown validity and "N" for no signature - '%GS': show the name of the signer for a signed commit - '%GK': show the key used to sign a signed commit - '%gD': reflog selector, e.g., `refs/stash@{1}` diff --git a/Documentation/pretty-options.txt b/Documentation/pretty-options.txt index 4b659ac1a6..54b88b6dca 100644 --- a/Documentation/pretty-options.txt +++ b/Documentation/pretty-options.txt @@ -43,7 +43,7 @@ people using 80-column terminals. commit may be copied to the output. ifndef::git-rev-list[] ---notes[=]:: +--notes[=]:: Show the notes (see linkgit:git-notes[1]) that annotate the commit, when showing the commit log message. This is the default for `git log`, `git show` and `git whatchanged` commands when @@ -54,8 +54,8 @@ By default, the notes shown are from the notes refs listed in the 'core.notesRef' and 'notes.displayRef' variables (or corresponding environment overrides). See linkgit:git-config[1] for more details. + -With an optional '' argument, show this notes ref instead of the -default notes ref(s). The ref specifies the full refname when it begins +With an optional '' argument, use the treeish to find the notes +to display. The treeish can specify the full refname when it begins with `refs/notes/`; when it begins with `notes/`, `refs/` and otherwise `refs/notes/` is prefixed to form a full name of the ref. + @@ -71,7 +71,7 @@ being displayed. Examples: "--notes=foo" will show only notes from "--notes --notes=foo --no-notes --notes=bar" will only show notes from "refs/notes/bar". ---show-notes[=]:: +--show-notes[=]:: --[no-]standard-notes:: These options are deprecated. Use the above --notes/--no-notes options instead. diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt index d85e303364..19314e3b7f 100644 --- a/Documentation/revisions.txt +++ b/Documentation/revisions.txt @@ -61,11 +61,11 @@ some output processing may assume ref names in UTF-8. '@':: '@' alone is a shortcut for 'HEAD'. -'@\{\}', e.g. 'master@\{yesterday\}', 'HEAD@\{5 minutes ago\}':: +'@{}', e.g. 'master@\{yesterday\}', 'HEAD@{5 minutes ago}':: A ref followed by the suffix '@' with a date specification enclosed in a brace - pair (e.g. '\{yesterday\}', '\{1 month 2 weeks 3 days 1 hour 1 - second ago\}' or '\{1979-02-26 18:30:00\}') specifies the value + pair (e.g. '\{yesterday\}', '{1 month 2 weeks 3 days 1 hour 1 + second ago}' or '{1979-02-26 18:30:00}') specifies the value of the ref at a prior point in time. This suffix may only be used immediately following a ref name and the ref must have an existing log ('$GIT_DIR/logs/'). Note that this looks up the state @@ -73,7 +73,7 @@ some output processing may assume ref names in UTF-8. 'master' branch last week. If you want to look at commits made during certain times, see '--since' and '--until'. -'@\{\}', e.g. 'master@\{1\}':: +'@{}', e.g. 'master@\{1\}':: A ref followed by the suffix '@' with an ordinal specification enclosed in a brace pair (e.g. '\{1\}', '\{15\}') specifies the n-th prior value of that ref. For example 'master@\{1\}' @@ -82,13 +82,13 @@ some output processing may assume ref names in UTF-8. immediately following a ref name and the ref must have an existing log ('$GIT_DIR/logs/'). -'@\{\}', e.g. '@\{1\}':: +'@{}', e.g. '@\{1\}':: You can use the '@' construct with an empty ref part to get at a reflog entry of the current branch. For example, if you are on branch 'blabla' then '@\{1\}' means the same as 'blabla@\{1\}'. -'@\{-\}', e.g. '@\{-1\}':: - The construct '@\{-\}' means the th branch/commit checked out +'@{-}', e.g. '@{-1}':: + The construct '@{-}' means the th branch/commit checked out before the current one. '@\{upstream\}', e.g. 'master@\{upstream\}', '@\{u\}':: @@ -139,7 +139,7 @@ from one location and push to another. In a non-triangular workflow, '{caret}1{caret}1{caret}1'. See below for an illustration of the usage of this form. -'{caret}\{\}', e.g. 'v0.99.8{caret}\{commit\}':: +'{caret}{}', e.g. 'v0.99.8{caret}\{commit\}':: A suffix '{caret}' followed by an object type name enclosed in brace pair means dereference the object at '' recursively until an object of type '' is found or the object cannot be @@ -159,13 +159,13 @@ it does not have to be dereferenced even once to get to an object. 'rev{caret}\{tag\}' can be used to ensure that 'rev' identifies an existing tag object. -'{caret}\{\}', e.g. 'v0.99.8{caret}\{\}':: +'{caret}{}', e.g. 'v0.99.8{caret}{}':: A suffix '{caret}' followed by an empty brace pair means the object could be a tag, and dereference the tag recursively until a non-tag object is found. -'{caret}\{/\}', e.g. 'HEAD^{/fix nasty bug}':: +'{caret}{/}', e.g. 'HEAD^{/fix nasty bug}':: A suffix '{caret}' to a revision parameter, followed by a brace pair that contains a text led by a slash, is the same as the ':/fix nasty bug' syntax below except that @@ -176,11 +176,12 @@ existing tag object. A colon, followed by a slash, followed by a text, names a commit whose commit message matches the specified regular expression. This name returns the youngest matching commit which is - reachable from any ref. If the commit message starts with a - '!' you have to repeat that; the special sequence ':/!', - followed by something else than '!', is reserved for now. - The regular expression can match any part of the commit message. To - match messages starting with a string, one can use e.g. ':/^foo'. + reachable from any ref. The regular expression can match any part of the + commit message. To match messages starting with a string, one can use + e.g. ':/^foo'. The special sequence ':/!' is reserved for modifiers to what + is matched. ':/!-foo' performs a negative match, while ':/!!foo' matches a + literal '!' character, followed by 'foo'. Any other sequence beginning with + ':/!' is reserved for now. ':', e.g. 'HEAD:README', ':README', 'master:./README':: A suffix ':' followed by a path names the blob or tree diff --git a/Documentation/technical/api-config.txt b/Documentation/technical/api-config.txt index 0d8b99b368..20741f345e 100644 --- a/Documentation/technical/api-config.txt +++ b/Documentation/technical/api-config.txt @@ -63,13 +63,6 @@ parse for configuration, rather than looking in the usual files. Regular Specify whether include directives should be followed in parsed files. Regular `git_config` defaults to `1`. -There is a special version of `git_config` called `git_config_early`. -This version takes an additional parameter to specify the repository -config, instead of having it looked up via `git_path`. This is useful -early in a Git program before the repository has been found. Unless -you're working with early setup code, you probably don't want to use -this. - Reading Specific Files ---------------------- diff --git a/Documentation/technical/api-credentials.txt b/Documentation/technical/api-credentials.txt index e44426dd04..75368f26ca 100644 --- a/Documentation/technical/api-credentials.txt +++ b/Documentation/technical/api-credentials.txt @@ -243,7 +243,7 @@ appended to its command line, which is one of: The details of the credential will be provided on the helper's stdin 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). +FORMAT` in linkgit:git-credential[1] 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 @@ -268,4 +268,4 @@ See also linkgit:gitcredentials[7] -linkgit:git-config[5] (See configuration variables `credential.*`) +linkgit:git-config[1] (See configuration variables `credential.*`) diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt index 5f0757dcc9..695bd4bf43 100644 --- a/Documentation/technical/api-parse-options.txt +++ b/Documentation/technical/api-parse-options.txt @@ -231,6 +231,13 @@ There are some macros to easily define options: pass the command-line option, which can be specified multiple times, to another command. +`OPT_CMDMODE(short, long, &int_var, description, enum_val)`:: + Define an "operation mode" option, only one of which in the same + group of "operating mode" options that share the same `int_var` + can be given by the user. `enum_val` is set to `int_var` when the + option is used, but an error is reported if other "operating mode" + option has already set its value to the same `int_var`. + The last element of the array must be `OPT_END()`. diff --git a/Documentation/technical/api-remote.txt b/Documentation/technical/api-remote.txt index 2cfdd224a8..f10941b2e8 100644 --- a/Documentation/technical/api-remote.txt +++ b/Documentation/technical/api-remote.txt @@ -51,6 +51,10 @@ struct remote The proxy to use for curl (http, https, ftp, etc.) URLs. +`http_proxy_authmethod`:: + + The method used for authenticating against `http_proxy`. + struct remotes can be found by name with remote_get(), and iterated through with for_each_remote(). remote_get(NULL) will return the default remote, given the current branch and configuration. diff --git a/Documentation/technical/api-trace.txt b/Documentation/technical/api-trace.txt index 097a651d96..fadb5979c4 100644 --- a/Documentation/technical/api-trace.txt +++ b/Documentation/technical/api-trace.txt @@ -28,7 +28,7 @@ static struct trace_key trace_foo = TRACE_KEY_INIT(FOO); static void trace_print_foo(const char *message) { - trace_print_key(&trace_foo, message); + trace_printf_key(&trace_foo, "%s", message); } ------------ + @@ -95,3 +95,46 @@ for (;;) { } trace_performance(t, "frotz"); ------------ + +Bugs & Caveats +-------------- + +GIT_TRACE_* environment variables can be used to tell Git to show +trace output to its standard error stream. Git can often spawn a pager +internally to run its subcommand and send its standard output and +standard error to it. + +Because GIT_TRACE_PERFORMANCE trace is generated only at the very end +of the program with atexit(), which happens after the pager exits, it +would not work well if you send its log to the standard error output +and let Git spawn the pager at the same time. + +As a work around, you can for example use '--no-pager', or set +GIT_TRACE_PERFORMANCE to another file descriptor which is redirected +to stderr, or set GIT_TRACE_PERFORMANCE to a file specified by its +absolute path. + +For example instead of the following command which by default may not +print any performance information: + +------------ +GIT_TRACE_PERFORMANCE=2 git log -1 +------------ + +you may want to use: + +------------ +GIT_TRACE_PERFORMANCE=2 git --no-pager log -1 +------------ + +or: + +------------ +GIT_TRACE_PERFORMANCE=3 3>&2 git log -1 +------------ + +or: + +------------ +GIT_TRACE_PERFORMANCE=/path/to/log/file git log -1 +------------ diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt index c6977bbc5a..8b36343802 100644 --- a/Documentation/technical/pack-protocol.txt +++ b/Documentation/technical/pack-protocol.txt @@ -526,7 +526,7 @@ Push Certificate A push certificate begins with a set of header lines. After the header and an empty line, the protocol commands follow, one per -line. Note that the the trailing LF in push-cert PKT-LINEs is _not_ +line. Note that the trailing LF in push-cert PKT-LINEs is _not_ optional; it must be present. Currently, the following header fields are defined: diff --git a/Documentation/urls.txt b/Documentation/urls.txt index 9ccb24677e..b05da95788 100644 --- a/Documentation/urls.txt +++ b/Documentation/urls.txt @@ -7,9 +7,8 @@ Depending on the transport protocol, some of this information may be absent. Git supports ssh, git, http, and https protocols (in addition, ftp, -and ftps can be used for fetching and rsync can be used for fetching -and pushing, but these are inefficient and deprecated; do not use -them). +and ftps can be used for fetching, but this is inefficient and +deprecated; do not use it). The native transport (i.e. git:// URL) does no authentication and should be used with caution on unsecured networks. @@ -20,7 +19,6 @@ The following syntaxes may be used with them: - git://host.xz{startsb}:port{endsb}/path/to/repo.git/ - http{startsb}s{endsb}://host.xz{startsb}:port{endsb}/path/to/repo.git/ - ftp{startsb}s{endsb}://host.xz{startsb}:port{endsb}/path/to/repo.git/ -- rsync://host.xz/path/to/repo.git/ An alternative scp-like syntax may also be used with the ssh protocol: diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index ec6bacfcdf..5e07454572 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -2134,7 +2134,7 @@ browsing the repository using gitweb. The default server when using instaweb is lighttpd. See the file gitweb/INSTALL in the Git source tree and -linkgit:gitweb[1] for instructions on details setting up a permament +linkgit:gitweb[1] for instructions on details setting up a permanent installation with a CGI or Perl capable server. [[how-to-get-a-git-repository-with-minimal-history]] diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 2c156bce82..253c63277b 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.7.6 +DEF_VER=v2.8.5 LF=' ' diff --git a/Makefile b/Makefile index fd19b544c2..e11e626d05 100644 --- a/Makefile +++ b/Makefile @@ -264,6 +264,9 @@ all:: # # Define NO_TCLTK if you do not want Tcl/Tk GUI. # +# Define SANE_TEXT_GREP to "-a" if you use recent versions of GNU grep +# and egrep that are pickier when their input contains non-ASCII data. +# # The TCL_PATH variable governs the location of the Tcl interpreter # used to optimize git-gui for your system. Only used if NO_TCLTK # is not set. Defaults to the bare 'tclsh'. @@ -352,9 +355,6 @@ all:: # # Define HAVE_CLOCK_MONOTONIC if your platform has CLOCK_MONOTONIC in librt. # -# Define NO_HMAC_CTX_CLEANUP if your OpenSSL is version 0.9.6b or earlier to -# cleanup the HMAC context with the older HMAC_cleanup function. -# # Define USE_PARENS_AROUND_GETTEXT_N to "yes" if your compiler happily # compiles the following initialization: # @@ -380,6 +380,18 @@ ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS) ALL_LDFLAGS = $(LDFLAGS) STRIP ?= strip +ifdef DEVELOPER +CFLAGS += -Werror \ + -Wdeclaration-after-statement \ + -Wno-format-zero-length \ + -Wold-style-definition \ + -Woverflow \ + -Wpointer-arith \ + -Wstrict-prototypes \ + -Wunused \ + -Wvla +endif + # Create as necessary, replace existing, make ranlib unneeded. ARFLAGS = rcs @@ -583,6 +595,7 @@ TEST_PROGRAMS_NEED_X += test-delta TEST_PROGRAMS_NEED_X += test-dump-cache-tree TEST_PROGRAMS_NEED_X += test-dump-split-index TEST_PROGRAMS_NEED_X += test-dump-untracked-cache +TEST_PROGRAMS_NEED_X += test-fake-ssh TEST_PROGRAMS_NEED_X += test-genrandom TEST_PROGRAMS_NEED_X += test-hashmap TEST_PROGRAMS_NEED_X += test-index-version @@ -1122,9 +1135,6 @@ ifndef NO_OPENSSL ifdef NEEDS_CRYPTO_WITH_SSL OPENSSL_LIBSSL += -lcrypto endif - ifdef NO_HMAC_CTX_CLEANUP - BASIC_CFLAGS += -DNO_HMAC_CTX_CLEANUP - endif else BASIC_CFLAGS += -DNO_OPENSSL BLK_SHA1 = 1 @@ -1727,7 +1737,7 @@ common-cmds.h: $(wildcard Documentation/git-*.txt) SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\ $(localedir_SQ):$(NO_CURL):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\ - $(gitwebdir_SQ):$(PERL_PATH_SQ) + $(gitwebdir_SQ):$(PERL_PATH_SQ):$(SANE_TEXT_GREP) define cmd_munge_script $(RM) $@ $@+ && \ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ @@ -1739,6 +1749,7 @@ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e $(BROKEN_PATH_FIX) \ -e 's|@@GITWEBDIR@@|$(gitwebdir_SQ)|g' \ -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \ + -e 's|@@SANE_TEXT_GREP@@|$(SANE_TEXT_GREP)|g' \ $@.sh >$@+ endef @@ -2025,6 +2036,7 @@ $(VCSSVN_LIB): $(VCSSVN_OBJS) export DEFAULT_EDITOR DEFAULT_PAGER +.PHONY: doc man html info pdf doc: $(MAKE) -C Documentation all @@ -2051,7 +2063,7 @@ XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \ --keyword=gettextln --keyword=eval_gettextln XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H) -LOCALIZED_SH = $(SCRIPT_SH) +LOCALIZED_SH = $(SCRIPT_SH) git-parse-remote.sh LOCALIZED_PERL = $(SCRIPT_PERL) ifdef XGETTEXT_INCLUDE_TESTS @@ -2068,6 +2080,7 @@ po/git.pot: $(GENERATED_H) FORCE $(LOCALIZED_PERL) mv $@+ $@ +.PHONY: pot pot: po/git.pot POFILES := $(wildcard po/*.po) @@ -2244,10 +2257,10 @@ sparse: $(SP_OBJ) check: common-cmds.h @if sparse; \ then \ - echo 2>&1 "Use 'make sparse' instead"; \ + echo >&2 "Use 'make sparse' instead"; \ $(MAKE) --no-print-directory sparse; \ else \ - echo 2>&1 "Did you mean 'make test'?"; \ + echo >&2 "Did you mean 'make test'?"; \ exit 1; \ fi @@ -2277,6 +2290,7 @@ mergetools_instdir_SQ = $(subst ','\'',$(mergetools_instdir)) install_bindir_programs := $(patsubst %,%$X,$(BINDIR_PROGRAMS_NEED_X)) $(BINDIR_PROGRAMS_NO_X) +.PHONY: profile-install profile-fast-install profile-install: profile $(MAKE) install @@ -2343,6 +2357,8 @@ endif done && \ ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X" +.PHONY: install-gitweb install-doc install-man install-html install-info install-pdf +.PHONY: quick-install-doc quick-install-man quick-install-html install-gitweb: $(MAKE) -C gitweb install @@ -2402,6 +2418,7 @@ rpm: dist htmldocs = git-htmldocs-$(GIT_VERSION) manpages = git-manpages-$(GIT_VERSION) +.PHONY: dist-doc distclean dist-doc: $(RM) -r .doc-tmp-dir mkdir .doc-tmp-dir @@ -2470,6 +2487,8 @@ ALL_COMMANDS += git ALL_COMMANDS += gitk ALL_COMMANDS += gitweb ALL_COMMANDS += git-gui git-citool + +.PHONY: check-docs check-docs:: @(for v in $(ALL_COMMANDS); \ do \ @@ -2514,6 +2533,7 @@ check-builtins:: ### Test suite coverage testing # .PHONY: coverage coverage-clean coverage-compile coverage-test coverage-report +.PHONY: coverage-untested-functions cover_db cover_db_html .PHONY: coverage-clean-results coverage: diff --git a/README b/README deleted file mode 100644 index 1083735d1c..0000000000 --- a/README +++ /dev/null @@ -1,56 +0,0 @@ -//////////////////////////////////////////////////////////////// - - Git - the stupid content tracker - -//////////////////////////////////////////////////////////////// - -"git" can mean anything, depending on your mood. - - - random three-letter combination that is pronounceable, and not - actually used by any common UNIX command. The fact that it is a - mispronunciation of "get" may or may not be relevant. - - stupid. contemptible and despicable. simple. Take your pick from the - dictionary of slang. - - "global information tracker": you're in a good mood, and it actually - works for you. Angels sing, and a light suddenly fills the room. - - "goddamn idiotic truckload of sh*t": when it breaks - -Git is a fast, scalable, distributed revision control system with an -unusually rich command set that provides both high-level operations -and full access to internals. - -Git is an Open Source project covered by the GNU General Public -License version 2 (some parts of it are under different licenses, -compatible with the GPLv2). It was originally written by Linus -Torvalds with help of a group of hackers around the net. - -Please read the file INSTALL for installation instructions. - -See Documentation/gittutorial.txt to get started, then see -Documentation/giteveryday.txt for a useful minimum set of commands, and -Documentation/git-commandname.txt for documentation of each command. -If git has been correctly installed, then the tutorial can also be -read with "man gittutorial" or "git help tutorial", and the -documentation of each command with "man git-commandname" or "git help -commandname". - -CVS users may also want to read Documentation/gitcvs-migration.txt -("man gitcvs-migration" or "git help cvs-migration" if git is -installed). - -Many Git online resources are accessible from http://git-scm.com/ -including full documentation and Git related tools. - -The user discussion and development of Git take place on the Git -mailing list -- everyone is welcome to post bug reports, feature -requests, comments and patches to git@vger.kernel.org (read -Documentation/SubmittingPatches for instructions on patch submission). -To subscribe to the list, send an email with just "subscribe git" in -the body to majordomo@vger.kernel.org. The mailing list archives are -available at http://news.gmane.org/gmane.comp.version-control.git/, -http://marc.info/?l=git and other archival sites. - -The maintainer frequently sends the "What's cooking" reports that -list the current status of various development topics to the mailing -list. The discussion following them give a good reference for -project status, development direction and remaining tasks. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..d1ffbb6170 --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +Git - fast, scalable, distributed revision control system +========================================================= + +Git is a fast, scalable, distributed revision control system with an +unusually rich command set that provides both high-level operations +and full access to internals. + +Git is an Open Source project covered by the GNU General Public +License version 2 (some parts of it are under different licenses, +compatible with the GPLv2). It was originally written by Linus +Torvalds with help of a group of hackers around the net. + +Please read the file [INSTALL][] for installation instructions. + +Many Git online resources are accessible from http://git-scm.com/ +including full documentation and Git related tools. + +See [Documentation/gittutorial.txt][] to get started, then see +[Documentation/giteveryday.txt][] for a useful minimum set of commands, and +[Documentation/git-commandname.txt][] for documentation of each command. +If git has been correctly installed, then the tutorial can also be +read with "man gittutorial" or "git help tutorial", and the +documentation of each command with "man git-commandname" or "git help +commandname". + +CVS users may also want to read [Documentation/gitcvs-migration.txt][] +("man gitcvs-migration" or "git help cvs-migration" if git is +installed). + +The user discussion and development of Git take place on the Git +mailing list -- everyone is welcome to post bug reports, feature +requests, comments and patches to git@vger.kernel.org (read +[Documentation/SubmittingPatches][] for instructions on patch submission). +To subscribe to the list, send an email with just "subscribe git" in +the body to majordomo@vger.kernel.org. The mailing list archives are +available at http://news.gmane.org/gmane.comp.version-control.git/, +http://marc.info/?l=git and other archival sites. + +The maintainer frequently sends the "What's cooking" reports that +list the current status of various development topics to the mailing +list. The discussion following them give a good reference for +project status, development direction and remaining tasks. + +The name "git" was given by Linus Torvalds when he wrote the very +first version. He described the tool as "the stupid content tracker" +and the name as (depending on your mood): + + - random three-letter combination that is pronounceable, and not + actually used by any common UNIX command. The fact that it is a + mispronunciation of "get" may or may not be relevant. + - stupid. contemptible and despicable. simple. Take your pick from the + dictionary of slang. + - "global information tracker": you're in a good mood, and it actually + works for you. Angels sing, and a light suddenly fills the room. + - "goddamn idiotic truckload of sh*t": when it breaks + +[INSTALL]: INSTALL +[Documentation/gittutorial.txt]: Documentation/gittutorial.txt +[Documentation/giteveryday.txt]: Documentation/giteveryday.txt +[Documentation/git-commandname.txt]: Documentation/git-commandname.txt +[Documentation/gitcvs-migration.txt]: Documentation/gitcvs-migration.txt +[Documentation/SubmittingPatches]: Documentation/SubmittingPatches diff --git a/RelNotes b/RelNotes index a256349b9d..c395dd85d1 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/2.7.6.txt \ No newline at end of file +Documentation/RelNotes/2.8.5.txt \ No newline at end of file diff --git a/abspath.c b/abspath.c index 5edb4e7816..2825de8591 100644 --- a/abspath.c +++ b/abspath.c @@ -167,7 +167,6 @@ const char *prefix_filename(const char *pfx, int pfx_len, const char *arg) strbuf_add(&path, pfx, pfx_len); strbuf_addstr(&path, arg); #else - char *p; /* don't add prefix to absolute paths, but still replace '\' by '/' */ strbuf_reset(&path); if (is_absolute_path(arg)) @@ -175,9 +174,7 @@ const char *prefix_filename(const char *pfx, int pfx_len, const char *arg) else if (pfx_len) strbuf_add(&path, pfx, pfx_len); strbuf_addstr(&path, arg); - for (p = path.buf + pfx_len; *p; p++) - if (*p == '\\') - *p = '/'; + convert_slashes(path.buf + pfx_len); #endif return path.buf; } diff --git a/attr.c b/attr.c index 6537a433da..eec5d7d15a 100644 --- a/attr.c +++ b/attr.c @@ -122,7 +122,7 @@ struct pattern { const char *pattern; int patternlen; int nowildcardlen; - int flags; /* EXC_FLAG_* */ + unsigned flags; /* EXC_FLAG_* */ }; /* diff --git a/bisect.c b/bisect.c index 6d0793b9fc..7996c2907b 100644 --- a/bisect.c +++ b/bisect.c @@ -440,7 +440,7 @@ static void read_bisect_paths(struct argv_array *array) if (!fp) die_errno("Could not open file '%s'", filename); - while (strbuf_getline(&str, fp, '\n') != EOF) { + while (strbuf_getline_lf(&str, fp) != EOF) { strbuf_trim(&str); if (sq_dequote_to_argv_array(str.buf, array)) die("Badly quoted content in file '%s': %s", @@ -668,7 +668,7 @@ static int is_expected_rev(const struct object_id *oid) if (!fp) return 0; - if (strbuf_getline(&str, fp, '\n') != EOF) + if (strbuf_getline_lf(&str, fp) != EOF) res = !strcmp(str.buf, oid_to_hex(oid)); strbuf_release(&str); @@ -914,9 +914,9 @@ void read_bisect_terms(const char **read_bad, const char **read_good) strerror(errno)); } } else { - strbuf_getline(&str, fp, '\n'); + strbuf_getline_lf(&str, fp); *read_bad = strbuf_detach(&str, NULL); - strbuf_getline(&str, fp, '\n'); + strbuf_getline_lf(&str, fp); *read_good = strbuf_detach(&str, NULL); } strbuf_release(&str); diff --git a/branch.c b/branch.c index c50ea42172..4162443707 100644 --- a/branch.c +++ b/branch.c @@ -344,3 +344,26 @@ void die_if_checked_out(const char *branch) die(_("'%s' is already checked out at '%s'"), branch, existing); } } + +int replace_each_worktree_head_symref(const char *oldref, const char *newref) +{ + int ret = 0; + struct worktree **worktrees = get_worktrees(); + int i; + + for (i = 0; worktrees[i]; i++) { + if (worktrees[i]->is_detached) + continue; + if (strcmp(oldref, worktrees[i]->head_ref)) + continue; + + if (set_worktree_head_symref(worktrees[i]->git_dir, newref)) { + ret = -1; + error(_("HEAD of working tree %s is not updated"), + worktrees[i]->path); + } + } + + free_worktrees(worktrees); + return ret; +} diff --git a/branch.h b/branch.h index 78ad4387cd..d69163daf7 100644 --- a/branch.h +++ b/branch.h @@ -60,4 +60,11 @@ extern int read_branch_desc(struct strbuf *, const char *branch_name); */ extern void die_if_checked_out(const char *branch); +/* + * Update all per-worktree HEADs pointing at the old ref to point the new ref. + * This will be used when renaming a branch. Returns 0 if successful, non-zero + * otherwise. + */ +extern int replace_each_worktree_head_symref(const char *oldref, const char *newref); + #endif diff --git a/builtin/am.c b/builtin/am.c index 5668e0c3a5..d003939bc5 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -45,21 +45,6 @@ static int is_empty_file(const char *filename) return !st.st_size; } -/** - * Like strbuf_getline(), but treats both '\n' and "\r\n" as line terminators. - */ -static int strbuf_getline_crlf(struct strbuf *sb, FILE *fp) -{ - if (strbuf_getwholeline(sb, fp, '\n')) - return EOF; - if (sb->buf[sb->len - 1] == '\n') { - strbuf_setlen(sb, sb->len - 1); - if (sb->len > 0 && sb->buf[sb->len - 1] == '\r') - strbuf_setlen(sb, sb->len - 1); - } - return 0; -} - /** * Returns the length of the first line of msg. */ @@ -284,7 +269,7 @@ static char *read_shell_var(FILE *fp, const char *key) struct strbuf sb = STRBUF_INIT; const char *str; - if (strbuf_getline(&sb, fp, '\n')) + if (strbuf_getline_lf(&sb, fp)) goto fail; if (!skip_prefix(sb.buf, key, &str)) @@ -573,7 +558,7 @@ static int copy_notes_for_rebase(const struct am_state *state) fp = xfopen(am_path(state, "rewritten"), "r"); - while (!strbuf_getline(&sb, fp, '\n')) { + while (!strbuf_getline_lf(&sb, fp)) { unsigned char from_obj[GIT_SHA1_RAWSZ], to_obj[GIT_SHA1_RAWSZ]; if (sb.len != GIT_SHA1_HEXSZ * 2 + 1) { @@ -628,7 +613,7 @@ static int is_mail(FILE *fp) if (regcomp(®ex, header_regex, REG_NOSUB | REG_EXTENDED)) die("invalid pattern: %s", header_regex); - while (!strbuf_getline_crlf(&sb, fp)) { + while (!strbuf_getline(&sb, fp)) { if (!sb.len) break; /* End of header */ @@ -675,7 +660,7 @@ static int detect_patch_format(const char **paths) fp = xfopen(*paths, "r"); - while (!strbuf_getline_crlf(&l1, fp)) { + while (!strbuf_getline(&l1, fp)) { if (l1.len) break; } @@ -696,9 +681,9 @@ static int detect_patch_format(const char **paths) } strbuf_reset(&l2); - strbuf_getline_crlf(&l2, fp); + strbuf_getline(&l2, fp); strbuf_reset(&l3); - strbuf_getline_crlf(&l3, fp); + strbuf_getline(&l3, fp); /* * If the second line is empty and the third is a From, Author or Date @@ -817,7 +802,7 @@ static int stgit_patch_to_mail(FILE *out, FILE *in, int keep_cr) struct strbuf sb = STRBUF_INIT; int subject_printed = 0; - while (!strbuf_getline(&sb, in, '\n')) { + while (!strbuf_getline_lf(&sb, in)) { const char *str; if (str_isspace(sb.buf)) @@ -875,7 +860,7 @@ static int split_mail_stgit_series(struct am_state *state, const char **paths, return error(_("could not open '%s' for reading: %s"), *paths, strerror(errno)); - while (!strbuf_getline(&sb, fp, '\n')) { + while (!strbuf_getline_lf(&sb, fp)) { if (*sb.buf == '#') continue; /* skip comment lines */ @@ -900,7 +885,7 @@ static int hg_patch_to_mail(FILE *out, FILE *in, int keep_cr) { struct strbuf sb = STRBUF_INIT; - while (!strbuf_getline(&sb, in, '\n')) { + while (!strbuf_getline_lf(&sb, in)) { const char *str; if (skip_prefix(sb.buf, "# User ", &str)) @@ -1317,7 +1302,7 @@ static int parse_mail(struct am_state *state, const char *mail) /* Extract message and author information */ fp = xfopen(am_path(state, "info"), "r"); - while (!strbuf_getline(&sb, fp, '\n')) { + while (!strbuf_getline_lf(&sb, fp)) { const char *x; if (skip_prefix(sb.buf, "Subject: ", &x)) { @@ -1383,7 +1368,7 @@ static int get_mail_commit_sha1(unsigned char *commit_id, const char *mail) FILE *fp = xfopen(mail, "r"); const char *x; - if (strbuf_getline(&sb, fp, '\n')) + if (strbuf_getline_lf(&sb, fp)) return -1; if (!skip_prefix(sb.buf, "From ", &x)) diff --git a/builtin/apply.c b/builtin/apply.c index 0db6d14cc2..ce3b77853c 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -931,22 +931,19 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, return find_name(line, NULL, p_value, TERM_TAB); if (orig_name) { - int len; - const char *name; + int len = strlen(orig_name); char *another; - name = orig_name; - len = strlen(name); if (isnull) - die(_("git apply: bad git-diff - expected /dev/null, got %s on line %d"), name, linenr); + die(_("git apply: bad git-diff - expected /dev/null, got %s on line %d"), + orig_name, linenr); another = find_name(line, NULL, p_value, TERM_TAB); - if (!another || memcmp(another, name, len + 1)) + if (!another || memcmp(another, orig_name, len + 1)) die((side == DIFF_NEW_NAME) ? _("git apply: bad git-diff - inconsistent new filename on line %d") : _("git apply: bad git-diff - inconsistent old filename on line %d"), linenr); free(another); return orig_name; - } - else { + } else { /* expect "/dev/null" */ if (memcmp("/dev/null", line, 9) || line[9] != '\n') die(_("git apply: bad git-diff - expected /dev/null on line %d"), linenr); @@ -956,21 +953,15 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, static int gitdiff_oldname(const char *line, struct patch *patch) { - char *orig = patch->old_name; patch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name, DIFF_OLD_NAME); - if (orig != patch->old_name) - free(orig); return 0; } static int gitdiff_newname(const char *line, struct patch *patch) { - char *orig = patch->new_name; patch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name, DIFF_NEW_NAME); - if (orig != patch->new_name) - free(orig); return 0; } @@ -1872,6 +1863,11 @@ static struct fragment *parse_binary_hunk(char **buf_p, return NULL; } +/* + * Returns: + * -1 in case of error, + * the length of the parsed binary patch otherwise + */ static int parse_binary(char *buffer, unsigned long size, struct patch *patch) { /* @@ -2017,6 +2013,8 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch) linenr++; used = parse_binary(buffer + hd + llen, size - hd - llen, patch); + if (used < 0) + return -1; if (used) patchsize = used + llen; else @@ -4373,8 +4371,10 @@ static int apply_patch(int fd, const char *filename, int options) patch->inaccurate_eof = !!(options & INACCURATE_EOF); patch->recount = !!(options & RECOUNT); nr = parse_chunk(buf.buf + offset, buf.len - offset, patch); - if (nr < 0) + if (nr < 0) { + free_patch(patch); break; + } if (apply_in_reverse) reverse_patches(patch); if (use_patch(patch)) { @@ -4464,16 +4464,6 @@ static int option_parse_p(const struct option *opt, return 0; } -static int option_parse_z(const struct option *opt, - const char *arg, int unset) -{ - if (unset) - line_termination = '\n'; - else - line_termination = 0; - return 0; -} - static int option_parse_space_change(const struct option *opt, const char *arg, int unset) { @@ -4546,9 +4536,9 @@ int cmd_apply(int argc, const char **argv, const char *prefix_) N_( "attempt three-way merge if a patch does not apply")), OPT_FILENAME(0, "build-fake-ancestor", &fake_ancestor, N_("build a temporary index based on embedded index information")), - { OPTION_CALLBACK, 'z', NULL, NULL, NULL, - N_("paths are separated with NUL character"), - PARSE_OPT_NOARG, option_parse_z }, + /* Think twice before adding "--nul" synonym to this */ + OPT_SET_INT('z', NULL, &line_termination, + N_("paths are separated with NUL character"), '\0'), OPT_INTEGER('C', NULL, &p_context, N_("ensure at least lines of context match")), { OPTION_CALLBACK, 0, "whitespace", &whitespace_option, N_("action"), diff --git a/builtin/blame.c b/builtin/blame.c index 0b4f0bbb53..21f42b0b62 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -28,6 +28,7 @@ #include "line-range.h" #include "line-log.h" #include "dir.h" +#include "progress.h" static char blame_usage[] = N_("git blame [] [] [] [--] "); @@ -50,6 +51,7 @@ static int incremental; static int xdl_opts; static int abbrev = -1; static int no_whole_file_rename; +static int show_progress; static struct date_mode blame_date_mode = { DATE_ISO8601 }; static size_t blame_date_width; @@ -127,6 +129,11 @@ struct origin { char path[FLEX_ARRAY]; }; +struct progress_info { + struct progress *progress; + int blamed_lines; +}; + static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b, long ctxlen, xdl_emit_hunk_consume_func_t hunk_func, void *cb_data) { @@ -1744,7 +1751,8 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat) * The blame_entry is found to be guilty for the range. * Show it in incremental output. */ -static void found_guilty_entry(struct blame_entry *ent) +static void found_guilty_entry(struct blame_entry *ent, + struct progress_info *pi) { if (incremental) { struct origin *suspect = ent->suspect; @@ -1756,6 +1764,8 @@ static void found_guilty_entry(struct blame_entry *ent) write_filename_info(suspect->path); maybe_flush_or_die(stdout, "stdout"); } + pi->blamed_lines += ent->num_lines; + display_progress(pi->progress, pi->blamed_lines); } /* @@ -1766,6 +1776,11 @@ static void assign_blame(struct scoreboard *sb, int opt) { struct rev_info *revs = sb->revs; struct commit *commit = prio_queue_get(&sb->commits); + struct progress_info pi = { NULL, 0 }; + + if (show_progress) + pi.progress = start_progress_delay(_("Blaming lines"), + sb->num_lines, 50, 1); while (commit) { struct blame_entry *ent; @@ -1807,7 +1822,7 @@ static void assign_blame(struct scoreboard *sb, int opt) suspect->guilty = 1; for (;;) { struct blame_entry *next = ent->next; - found_guilty_entry(ent); + found_guilty_entry(ent, &pi); if (next) { ent = next; continue; @@ -1823,6 +1838,8 @@ static void assign_blame(struct scoreboard *sb, int opt) if (DEBUG) /* sanity */ sanity_check_refcnt(sb); } + + stop_progress(&pi.progress); } static const char *format_time(unsigned long time, const char *tz_str, @@ -2290,6 +2307,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt, unsigned mode; struct strbuf msg = STRBUF_INIT; + read_cache(); time(&now); commit = alloc_commit_node(); commit->object.parsed = 1; @@ -2514,6 +2532,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) OPT_BOOL('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: off)")), OPT_BOOL(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")), OPT_BOOL(0, "show-stats", &show_stats, N_("Show work cost statistics")), + OPT_BOOL(0, "progress", &show_progress, N_("Force progress reporting")), OPT_BIT(0, "score-debug", &output_option, N_("Show output score for blame entries"), OUTPUT_SHOW_SCORE), OPT_BIT('f', "show-name", &output_option, N_("Show original filename (Default: auto)"), OUTPUT_SHOW_NAME), OPT_BIT('n', "show-number", &output_option, N_("Show original linenumber (Default: off)"), OUTPUT_SHOW_NUMBER), @@ -2549,6 +2568,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) save_commit_buffer = 0; dashdash_pos = 0; + show_progress = -1; parse_options_start(&ctx, argc, argv, prefix, options, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0); @@ -2573,6 +2593,13 @@ int cmd_blame(int argc, const char **argv, const char *prefix) DIFF_OPT_CLR(&revs.diffopt, FOLLOW_RENAMES); argc = parse_options_end(&ctx); + if (incremental || (output_option & OUTPUT_PORCELAIN)) { + if (show_progress > 0) + die("--progress can't be used with --incremental or porcelain formats"); + show_progress = 0; + } else if (show_progress < 0) + show_progress = isatty(2); + if (0 < abbrev) /* one more abbrev length is needed for the boundary commit */ abbrev++; @@ -2822,11 +2849,11 @@ int cmd_blame(int argc, const char **argv, const char *prefix) read_mailmap(&mailmap, NULL); + assign_blame(&sb, opt); + if (!incremental) setup_pager(); - assign_blame(&sb, opt); - free(final_commit_name); if (incremental) diff --git a/builtin/branch.c b/builtin/branch.c index 7b45b6bd6b..37af77161e 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -20,6 +20,7 @@ #include "utf8.h" #include "wt-status.h" #include "ref-filter.h" +#include "worktree.h" static const char * const builtin_branch_usage[] = { N_("git branch [] [-r | -a] [--merged | --no-merged]"), @@ -215,16 +216,21 @@ static int delete_branches(int argc, const char **argv, int force, int kinds, int flags = 0; strbuf_branchname(&bname, argv[i]); - if (kinds == FILTER_REFS_BRANCHES && !strcmp(head, bname.buf)) { - error(_("Cannot delete the branch '%s' " - "which you are currently on."), bname.buf); - ret = 1; - continue; - } - free(name); - name = mkpathdup(fmt, bname.buf); + + if (kinds == FILTER_REFS_BRANCHES) { + char *worktree = find_shared_symref("HEAD", name); + if (worktree) { + error(_("Cannot delete branch '%s' " + "checked out at '%s'"), + bname.buf, worktree); + free(worktree); + ret = 1; + continue; + } + } + target = resolve_ref_unsafe(name, RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE @@ -369,12 +375,14 @@ static char *get_head_description(void) strbuf_addf(&desc, _("(no branch, bisect started on %s)"), state.branch); else if (state.detached_from) { - /* TRANSLATORS: make sure these match _("HEAD detached at ") - and _("HEAD detached from ") in wt-status.c */ if (state.detached_at) + /* TRANSLATORS: make sure this matches + "HEAD detached at " in wt-status.c */ strbuf_addf(&desc, _("(HEAD detached at %s)"), state.detached_from); else + /* TRANSLATORS: make sure this matches + "HEAD detached from " in wt-status.c */ strbuf_addf(&desc, _("(HEAD detached from %s)"), state.detached_from); } @@ -393,22 +401,25 @@ static void format_and_print_ref_item(struct ref_array_item *item, int maxwidth, int current = 0; int color; struct strbuf out = STRBUF_INIT, name = STRBUF_INIT; - const char *prefix = ""; + const char *prefix_to_show = ""; + const char *prefix_to_skip = NULL; const char *desc = item->refname; char *to_free = NULL; switch (item->kind) { case FILTER_REFS_BRANCHES: - skip_prefix(desc, "refs/heads/", &desc); + prefix_to_skip = "refs/heads/"; + skip_prefix(desc, prefix_to_skip, &desc); if (!filter->detached && !strcmp(desc, head)) current = 1; else color = BRANCH_COLOR_LOCAL; break; case FILTER_REFS_REMOTES: - skip_prefix(desc, "refs/remotes/", &desc); + prefix_to_skip = "refs/remotes/"; + skip_prefix(desc, prefix_to_skip, &desc); color = BRANCH_COLOR_REMOTE; - prefix = remote_prefix; + prefix_to_show = remote_prefix; break; case FILTER_REFS_DETACHED_HEAD: desc = to_free = get_head_description(); @@ -425,7 +436,7 @@ static void format_and_print_ref_item(struct ref_array_item *item, int maxwidth, color = BRANCH_COLOR_CURRENT; } - strbuf_addf(&name, "%s%s", prefix, desc); + strbuf_addf(&name, "%s%s", prefix_to_show, desc); if (filter->verbose) { int utf8_compensation = strlen(name.buf) - utf8_strwidth(name.buf); strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color), @@ -436,8 +447,10 @@ static void format_and_print_ref_item(struct ref_array_item *item, int maxwidth, name.buf, branch_get_color(BRANCH_COLOR_RESET)); if (item->symref) { - skip_prefix(item->symref, "refs/remotes/", &desc); - strbuf_addf(&out, " -> %s", desc); + const char *symref = item->symref; + if (prefix_to_skip) + skip_prefix(symref, prefix_to_skip, &symref); + strbuf_addf(&out, " -> %s", symref); } else if (filter->verbose) /* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */ @@ -552,8 +565,7 @@ static void rename_branch(const char *oldname, const char *newname, int force) if (recovery) warning(_("Renamed a misnamed branch '%s' away"), oldref.buf + 11); - /* no need to pass logmsg here as HEAD didn't really move */ - if (!strcmp(oldname, head) && create_symref("HEAD", newref.buf, NULL)) + if (replace_each_worktree_head_symref(oldref.buf, newref.buf)) die(_("Branch renamed to %s, but HEAD is not updated!"), newname); strbuf_addf(&oldsection, "branch.%s", oldref.buf + 11); @@ -620,7 +632,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) BRANCH_TRACK_EXPLICIT), OPT_SET_INT( 0, "set-upstream", &track, N_("change upstream info"), BRANCH_TRACK_OVERRIDE), - OPT_STRING('u', "set-upstream-to", &new_upstream, "upstream", "change the upstream info"), + OPT_STRING('u', "set-upstream-to", &new_upstream, N_("upstream"), N_("change the upstream info")), OPT_BOOL(0, "unset-upstream", &unset_upstream, "Unset the upstream info"), OPT__COLOR(&branch_use_color, N_("use colored output")), OPT_SET_INT('r', "remotes", &filter.kind, N_("act on remote-tracking branches"), @@ -828,8 +840,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix) if (argc == 1 && track == BRANCH_TRACK_OVERRIDE && !branch_existed && remote_tracking) { fprintf(stderr, _("\nIf you wanted to make '%s' track '%s', do this:\n\n"), head, branch->name); - fprintf(stderr, _(" git branch -d %s\n"), branch->name); - fprintf(stderr, _(" git branch --set-upstream-to %s\n"), branch->name); + fprintf(stderr, " git branch -d %s\n", branch->name); + fprintf(stderr, " git branch --set-upstream-to %s\n", branch->name); } } else diff --git a/builtin/cat-file.c b/builtin/cat-file.c index c0fd8dbb1c..54db1184a0 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -401,7 +401,7 @@ static int batch_objects(struct batch_options *opt) save_warning = warn_on_object_refname_ambiguity; warn_on_object_refname_ambiguity = 0; - while (strbuf_getline(&buf, stdin, '\n') != EOF) { + while (strbuf_getline(&buf, stdin) != EOF) { if (data.split_on_whitespace) { /* * Split at first whitespace, tying off the beginning diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 265c9ba022..53a5a18c16 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -72,23 +72,23 @@ static void check_attr(const char *prefix, int cnt, static void check_attr_stdin_paths(const char *prefix, int cnt, struct git_attr_check *check) { - struct strbuf buf, nbuf; - int line_termination = nul_term_line ? 0 : '\n'; - - strbuf_init(&buf, 0); - strbuf_init(&nbuf, 0); - while (strbuf_getline(&buf, stdin, line_termination) != EOF) { - if (line_termination && buf.buf[0] == '"') { - strbuf_reset(&nbuf); - if (unquote_c_style(&nbuf, buf.buf, NULL)) + struct strbuf buf = STRBUF_INIT; + struct strbuf unquoted = STRBUF_INIT; + strbuf_getline_fn getline_fn; + + getline_fn = nul_term_line ? strbuf_getline_nul : strbuf_getline_lf; + while (getline_fn(&buf, stdin) != EOF) { + if (!nul_term_line && buf.buf[0] == '"') { + strbuf_reset(&unquoted); + if (unquote_c_style(&unquoted, buf.buf, NULL)) die("line is badly quoted"); - strbuf_swap(&buf, &nbuf); + strbuf_swap(&buf, &unquoted); } check_attr(prefix, cnt, check, buf.buf); maybe_flush_or_die(stdout, "attribute to stdout"); } strbuf_release(&buf); - strbuf_release(&nbuf); + strbuf_release(&unquoted); } static NORETURN void error_with_usage(const char *msg) diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c index 43f361797a..1d73d3ca3d 100644 --- a/builtin/check-ignore.c +++ b/builtin/check-ignore.c @@ -115,19 +115,19 @@ static int check_ignore(struct dir_struct *dir, static int check_ignore_stdin_paths(struct dir_struct *dir, const char *prefix) { - struct strbuf buf, nbuf; + struct strbuf buf = STRBUF_INIT; + struct strbuf unquoted = STRBUF_INIT; char *pathspec[2] = { NULL, NULL }; - int line_termination = nul_term_line ? 0 : '\n'; + strbuf_getline_fn getline_fn; int num_ignored = 0; - strbuf_init(&buf, 0); - strbuf_init(&nbuf, 0); - while (strbuf_getline(&buf, stdin, line_termination) != EOF) { - if (line_termination && buf.buf[0] == '"') { - strbuf_reset(&nbuf); - if (unquote_c_style(&nbuf, buf.buf, NULL)) + getline_fn = nul_term_line ? strbuf_getline_nul : strbuf_getline_lf; + while (getline_fn(&buf, stdin) != EOF) { + if (!nul_term_line && buf.buf[0] == '"') { + strbuf_reset(&unquoted); + if (unquote_c_style(&unquoted, buf.buf, NULL)) die("line is badly quoted"); - strbuf_swap(&buf, &nbuf); + strbuf_swap(&buf, &unquoted); } pathspec[0] = buf.buf; num_ignored += check_ignore(dir, prefix, @@ -135,7 +135,7 @@ static int check_ignore_stdin_paths(struct dir_struct *dir, const char *prefix) maybe_flush_or_die(stdout, "check-ignore to stdout"); } strbuf_release(&buf); - strbuf_release(&nbuf); + strbuf_release(&unquoted); return num_ignored; } diff --git a/builtin/check-mailmap.c b/builtin/check-mailmap.c index eaaea546d3..cf0f54f6b9 100644 --- a/builtin/check-mailmap.c +++ b/builtin/check-mailmap.c @@ -54,7 +54,7 @@ int cmd_check_mailmap(int argc, const char **argv, const char *prefix) if (use_stdin) { struct strbuf buf = STRBUF_INIT; - while (strbuf_getline(&buf, stdin, '\n') != EOF) { + while (strbuf_getline_lf(&buf, stdin) != EOF) { check_mailmap(&mailmap, buf.buf); maybe_flush_or_die(stdout, "stdout"); } diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c index 8028c3768f..92c69672e9 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -11,7 +11,7 @@ #include "parse-options.h" #define CHECKOUT_ALL 4 -static int line_termination = '\n'; +static int nul_term_line; static int checkout_stage; /* default to checkout stage0 */ static int to_tempfile; static char topath[4][TEMPORARY_FILENAME_LENGTH + 1]; @@ -35,7 +35,8 @@ static void write_tempfile_record(const char *name, const char *prefix) fputs(topath[checkout_stage], stdout); putchar('\t'); - write_name_quoted_relative(name, prefix, stdout, line_termination); + write_name_quoted_relative(name, prefix, stdout, + nul_term_line ? '\0' : '\n'); for (i = 0; i < 4; i++) { topath[i][0] = 0; @@ -129,36 +130,6 @@ static const char * const builtin_checkout_index_usage[] = { static struct lock_file lock_file; -static int option_parse_u(const struct option *opt, - const char *arg, int unset) -{ - int *newfd = opt->value; - - state.refresh_cache = 1; - state.istate = &the_index; - if (*newfd < 0) - *newfd = hold_locked_index(&lock_file, 1); - return 0; -} - -static int option_parse_z(const struct option *opt, - const char *arg, int unset) -{ - if (unset) - line_termination = '\n'; - else - line_termination = 0; - return 0; -} - -static int option_parse_prefix(const struct option *opt, - const char *arg, int unset) -{ - state.base_dir = arg; - state.base_dir_len = strlen(arg); - return 0; -} - static int option_parse_stage(const struct option *opt, const char *arg, int unset) { @@ -170,7 +141,7 @@ static int option_parse_stage(const struct option *opt, if ('1' <= ch && ch <= '3') checkout_stage = arg[0] - '0'; else - die("stage should be between 1 and 3 or all"); + die(_("stage should be between 1 and 3 or all")); } return 0; } @@ -183,6 +154,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) int read_from_stdin = 0; int prefix_length; int force = 0, quiet = 0, not_new = 0; + int index_opt = 0; struct option builtin_checkout_index_options[] = { OPT_BOOL('a', "all", &all, N_("check out all files in the index")), @@ -191,22 +163,19 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) N_("no warning for existing files and files not in index")), OPT_BOOL('n', "no-create", ¬_new, N_("don't checkout new files")), - { OPTION_CALLBACK, 'u', "index", &newfd, NULL, - N_("update stat information in the index file"), - PARSE_OPT_NOARG, option_parse_u }, - { OPTION_CALLBACK, 'z', NULL, NULL, NULL, - N_("paths are separated with NUL character"), - PARSE_OPT_NOARG, option_parse_z }, + OPT_BOOL('u', "index", &index_opt, + N_("update stat information in the index file")), + OPT_BOOL('z', NULL, &nul_term_line, + N_("paths are separated with NUL character")), OPT_BOOL(0, "stdin", &read_from_stdin, N_("read list of paths from the standard input")), OPT_BOOL(0, "temp", &to_tempfile, N_("write the content to temporary files")), - OPT_CALLBACK(0, "prefix", NULL, N_("string"), - N_("when creating files, prepend "), - option_parse_prefix), - OPT_CALLBACK(0, "stage", NULL, NULL, + OPT_STRING(0, "prefix", &state.base_dir, N_("string"), + N_("when creating files, prepend ")), + { OPTION_CALLBACK, 0, "stage", NULL, "1-3|all", N_("copy out the files from named stage"), - option_parse_stage), + PARSE_OPT_NONEG, option_parse_stage }, OPT_END() }; @@ -214,7 +183,6 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) usage_with_options(builtin_checkout_index_usage, builtin_checkout_index_options); git_config(git_default_config, NULL); - state.base_dir = ""; prefix_length = prefix ? strlen(prefix) : 0; if (read_cache() < 0) { @@ -227,15 +195,17 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) state.quiet = quiet; state.not_new = not_new; - if (state.base_dir_len || to_tempfile) { - /* when --prefix is specified we do not - * want to update cache. - */ - if (state.refresh_cache) { - rollback_lock_file(&lock_file); - newfd = -1; - } - state.refresh_cache = 0; + if (!state.base_dir) + state.base_dir = ""; + state.base_dir_len = strlen(state.base_dir); + + /* + * when --prefix is specified we do not want to update cache. + */ + if (index_opt && !state.base_dir_len && !to_tempfile) { + state.refresh_cache = 1; + state.istate = &the_index; + newfd = hold_locked_index(&lock_file, 1); } /* Check out named files first */ @@ -253,24 +223,27 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) } if (read_from_stdin) { - struct strbuf buf = STRBUF_INIT, nbuf = STRBUF_INIT; + struct strbuf buf = STRBUF_INIT; + struct strbuf unquoted = STRBUF_INIT; + strbuf_getline_fn getline_fn; if (all) die("git checkout-index: don't mix '--all' and '--stdin'"); - while (strbuf_getline(&buf, stdin, line_termination) != EOF) { + getline_fn = nul_term_line ? strbuf_getline_nul : strbuf_getline_lf; + while (getline_fn(&buf, stdin) != EOF) { char *p; - if (line_termination && buf.buf[0] == '"') { - strbuf_reset(&nbuf); - if (unquote_c_style(&nbuf, buf.buf, NULL)) + if (!nul_term_line && buf.buf[0] == '"') { + strbuf_reset(&unquoted); + if (unquote_c_style(&unquoted, buf.buf, NULL)) die("line is badly quoted"); - strbuf_swap(&buf, &nbuf); + strbuf_swap(&buf, &unquoted); } p = prefix_path(prefix, prefix_length, buf.buf); checkout_file(p, prefix); free(p); } - strbuf_release(&nbuf); + strbuf_release(&unquoted); strbuf_release(&buf); } diff --git a/builtin/checkout.c b/builtin/checkout.c index d53ab75ac9..efcbd8f6b5 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -661,7 +661,8 @@ static void update_refs_for_switch(const struct checkout_opts *opts, describe_detached_head(_("HEAD is now at"), new->commit); } } else if (new->path) { /* Switch branches. */ - create_symref("HEAD", new->path, msg.buf); + if (create_symref("HEAD", new->path, msg.buf) < 0) + die(_("unable to update HEAD")); if (!opts->quiet) { if (old->path && !strcmp(new->path, old->path)) { if (opts->new_branch_force) diff --git a/builtin/clean.c b/builtin/clean.c index fb1824ce95..0371010afb 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -570,7 +570,7 @@ static int *list_and_choose(struct menu_opts *opts, struct menu_stuff *stuff) clean_get_color(CLEAN_COLOR_RESET)); } - if (strbuf_getline(&choice, stdin, '\n') != EOF) { + if (strbuf_getline_lf(&choice, stdin) != EOF) { strbuf_trim(&choice); } else { eof = 1; @@ -652,7 +652,7 @@ static int filter_by_patterns_cmd(void) clean_print_color(CLEAN_COLOR_PROMPT); printf(_("Input ignore patterns>> ")); clean_print_color(CLEAN_COLOR_RESET); - if (strbuf_getline(&confirm, stdin, '\n') != EOF) + if (strbuf_getline_lf(&confirm, stdin) != EOF) strbuf_trim(&confirm); else putchar('\n'); @@ -750,7 +750,7 @@ static int ask_each_cmd(void) qname = quote_path_relative(item->string, NULL, &buf); /* TRANSLATORS: Make sure to keep [y/N] as is */ printf(_("Remove %s [y/N]? "), qname); - if (strbuf_getline(&confirm, stdin, '\n') != EOF) { + if (strbuf_getline_lf(&confirm, stdin) != EOF) { strbuf_trim(&confirm); } else { putchar('\n'); diff --git a/builtin/clone.c b/builtin/clone.c index 8a90cad5b5..661639255c 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -47,6 +47,7 @@ static const char *real_git_dir; static char *option_upload_pack = "git-upload-pack"; static int option_verbosity; static int option_progress = -1; +static enum transport_family family; static struct string_list option_config; static struct string_list option_reference; static int option_dissociate; @@ -92,6 +93,10 @@ static struct option builtin_clone_options[] = { N_("separate git dir from working tree")), OPT_STRING_LIST('c', "config", &option_config, N_("key=value"), N_("set config inside the new repository")), + OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"), + TRANSPORT_FAMILY_IPV4), + OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"), + TRANSPORT_FAMILY_IPV6), OPT_END() }; @@ -231,8 +236,8 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) strip_suffix_mem(start, &len, is_bundle ? ".bundle" : ".git"); if (!len || (len == 1 && *start == '/')) - die("No directory name could be guessed.\n" - "Please specify a directory on the command line"); + die(_("No directory name could be guessed.\n" + "Please specify a directory on the command line")); if (is_bare) dir = xstrfmt("%.*s.git", (int)len, start); @@ -339,7 +344,7 @@ static void copy_alternates(struct strbuf *src, struct strbuf *dst, FILE *in = fopen(src->buf, "r"); struct strbuf line = STRBUF_INIT; - while (strbuf_getline(&line, in, '\n') != EOF) { + while (strbuf_getline(&line, in) != EOF) { char *abs_path; if (!line.len || line.buf[0] == '#') continue; @@ -636,9 +641,11 @@ static void update_remote_refs(const struct ref *refs, struct strbuf head_ref = STRBUF_INIT; strbuf_addstr(&head_ref, branch_top); strbuf_addstr(&head_ref, "HEAD"); - create_symref(head_ref.buf, - remote_head_points_at->peer_ref->name, - msg); + if (create_symref(head_ref.buf, + remote_head_points_at->peer_ref->name, + msg) < 0) + die(_("unable to update %s"), head_ref.buf); + strbuf_release(&head_ref); } } @@ -648,7 +655,8 @@ static void update_head(const struct ref *our, const struct ref *remote, const char *head; if (our && skip_prefix(our->name, "refs/heads/", &head)) { /* Local default branch link */ - create_symref("HEAD", our->name, NULL); + if (create_symref("HEAD", our->name, NULL) < 0) + die(_("unable to update HEAD")); if (!option_bare) { update_ref(msg, "HEAD", our->old_oid.hash, NULL, 0, UPDATE_REFS_DIE_ON_ERR); @@ -742,7 +750,7 @@ static void write_config(struct string_list *config) for (i = 0; i < config->nr; i++) { if (git_config_parse_parameter(config->items[i].string, write_one_config, NULL) < 0) - die("unable to write parameters to config file"); + die(_("unable to write parameters to config file")); } } @@ -967,6 +975,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) remote = remote_get(option_origin); transport = transport_get(remote, remote->url[0]); transport_set_verbosity(transport, option_verbosity, option_progress); + transport->family = family; path = get_repo_path(remote->url[0], &is_bundle); is_local = option_local != 0 && path && !is_bundle; diff --git a/builtin/column.c b/builtin/column.c index 449413c8a8..33314b4d71 100644 --- a/builtin/column.c +++ b/builtin/column.c @@ -51,7 +51,7 @@ int cmd_column(int argc, const char **argv, const char *prefix) die(_("--command must be the first argument")); } finalize_colopts(&colopts, -1); - while (!strbuf_getline(&sb, stdin, '\n')) + while (!strbuf_getline(&sb, stdin)) string_list_append(&list, sb.buf); print_columns(&list, colopts, &copts); diff --git a/builtin/commit.c b/builtin/commit.c index 89bf6ad38a..e13303787a 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -694,7 +694,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, } } - if (message.len) { + if (have_option_m) { strbuf_addbuf(&sb, &message); hook_arg1 = "message"; } else if (logfile && !strcmp(logfile, "-")) { @@ -726,9 +726,18 @@ static int prepare_to_commit(const char *index_file, const char *prefix, &sb, &ctx); hook_arg1 = "message"; } else if (!stat(git_path_merge_msg(), &statbuf)) { + /* + * prepend SQUASH_MSG here if it exists and a + * "merge --squash" was originally performed + */ + if (!stat(git_path_squash_msg(), &statbuf)) { + if (strbuf_read_file(&sb, git_path_squash_msg(), 0) < 0) + die_errno(_("could not read SQUASH_MSG")); + hook_arg1 = "squash"; + } else + hook_arg1 = "merge"; if (strbuf_read_file(&sb, git_path_merge_msg(), 0) < 0) die_errno(_("could not read MERGE_MSG")); - hook_arg1 = "merge"; } else if (!stat(git_path_squash_msg(), &statbuf)) { if (strbuf_read_file(&sb, git_path_squash_msg(), 0) < 0) die_errno(_("could not read SQUASH_MSG")); @@ -1162,9 +1171,9 @@ static int parse_and_validate_options(int argc, const char *argv[], f++; if (f > 1) die(_("Only one of -c/-C/-F/--fixup can be used.")); - if (message.len && f > 0) + if (have_option_m && f > 0) die((_("Option -m cannot be combined with -c/-C/-F/--fixup."))); - if (f || message.len) + if (f || have_option_m) template_file = NULL; if (edit_message) use_message = edit_message; @@ -1690,7 +1699,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) if (fp == NULL) die_errno(_("could not open '%s' for reading"), git_path_merge_head()); - while (strbuf_getline(&m, fp, '\n') != EOF) { + while (strbuf_getline_lf(&m, fp) != EOF) { struct commit *parent; parent = get_merge_parent(m.buf); diff --git a/builtin/config.c b/builtin/config.c index 746233e4bb..1d7c6ef558 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -3,6 +3,7 @@ #include "color.h" #include "parse-options.h" #include "urlmatch.h" +#include "quote.h" static const char *const builtin_config_usage[] = { N_("git config []"), @@ -27,6 +28,7 @@ static int actions, types; static const char *get_color_slot, *get_colorbool_slot; static int end_null; static int respect_includes = -1; +static int show_origin; #define ACTION_GET (1<<0) #define ACTION_GET_ALL (1<<1) @@ -81,6 +83,7 @@ static struct option builtin_config_options[] = { OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")), OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")), OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")), + OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")), OPT_END(), }; @@ -91,8 +94,28 @@ static void check_argc(int argc, int min, int max) { usage_with_options(builtin_config_usage, builtin_config_options); } +static void show_config_origin(struct strbuf *buf) +{ + const char term = end_null ? '\0' : '\t'; + + strbuf_addstr(buf, current_config_origin_type()); + strbuf_addch(buf, ':'); + if (end_null) + strbuf_addstr(buf, current_config_name()); + else + quote_c_style(current_config_name(), buf, NULL, 0); + strbuf_addch(buf, term); +} + static int show_all_config(const char *key_, const char *value_, void *cb) { + if (show_origin) { + struct strbuf buf = STRBUF_INIT; + show_config_origin(&buf); + /* Use fwrite as "buf" can contain \0's if "end_null" is set. */ + fwrite(buf.buf, 1, buf.len, stdout); + strbuf_release(&buf); + } if (!omit_values && value_) printf("%s%c%s%c", key_, delim, value_, term); else @@ -108,6 +131,8 @@ struct strbuf_list { static int format_config(struct strbuf *buf, const char *key_, const char *value_) { + if (show_origin) + show_config_origin(buf); if (show_keys) strbuf_addstr(buf, key_); if (!omit_values) { @@ -392,6 +417,7 @@ static int urlmatch_collect_fn(const char *var, const char *value, void *cb) static int get_urlmatch(const char *var, const char *url) { + int ret; char *section_tail; struct string_list_item *item; struct urlmatch_config config = { STRING_LIST_INIT_DUP }; @@ -418,6 +444,8 @@ static int get_urlmatch(const char *var, const char *url) git_config_with_options(urlmatch_config_entry, &config, &given_config_source, respect_includes); + ret = !values.nr; + for_each_string_list_item(item, &values) { struct urlmatch_current_candidate_value *matched = item->util; struct strbuf buf = STRBUF_INIT; @@ -434,7 +462,7 @@ static int get_urlmatch(const char *var, const char *url) free(config.url.url); free((void *)config.section); - return 0; + return ret; } static char *default_user_config(void) @@ -541,6 +569,14 @@ int cmd_config(int argc, const char **argv, const char *prefix) error("--name-only is only applicable to --list or --get-regexp"); usage_with_options(builtin_config_usage, builtin_config_options); } + + if (show_origin && !(actions & + (ACTION_GET|ACTION_GET_ALL|ACTION_GET_REGEXP|ACTION_LIST))) { + error("--show-origin is only applicable to --get, --get-all, " + "--get-regexp, and --list."); + usage_with_options(builtin_config_usage, builtin_config_options); + } + if (actions == ACTION_LIST) { check_argc(argc, 0, 0); if (git_config_with_options(show_all_config, NULL, diff --git a/builtin/diff-files.c b/builtin/diff-files.c index 8ed2eb8813..15c61fd8d1 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -24,6 +24,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) gitmodules_config(); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ rev.abbrev = 0; + precompose_argv(argc, argv); argc = setup_revisions(argc, argv, &rev, NULL); while (1 < argc && argv[1][0] == '-') { diff --git a/builtin/diff-index.c b/builtin/diff-index.c index d979824f93..1af373d002 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -21,6 +21,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) gitmodules_config(); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ rev.abbrev = 0; + precompose_argv(argc, argv); argc = setup_revisions(argc, argv, &rev, NULL); for (i = 1; i < argc; i++) { diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index 2a12b81e06..806dd7a885 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -114,6 +114,8 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) opt->disable_stdin = 1; memset(&s_r_opt, 0, sizeof(s_r_opt)); s_r_opt.tweak = diff_tree_tweak_rev; + + precompose_argv(argc, argv); argc = setup_revisions(argc, argv, opt, &s_r_opt); while (--argc > 0) { diff --git a/builtin/diff.c b/builtin/diff.c index 52c98a9217..d6b8f9834d 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -319,6 +319,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) if (!no_index) gitmodules_config(); git_config(git_diff_ui_config, NULL); + precompose_argv(argc, argv); init_revisions(&rev, prefix); diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index 7d5914f921..bfd0be44a9 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -16,10 +16,20 @@ static void add_sought_entry(struct ref ***sought, int *nr, int *alloc, struct ref *ref; struct object_id oid; - if (!get_oid_hex(name, &oid) && name[GIT_SHA1_HEXSZ] == ' ') - name += GIT_SHA1_HEXSZ + 1; - else + if (!get_oid_hex(name, &oid)) { + if (name[GIT_SHA1_HEXSZ] == ' ') { + /* , find refname */ + name += GIT_SHA1_HEXSZ + 1; + } else if (name[GIT_SHA1_HEXSZ] == '\0') { + ; /* , leave sha1 as name */ + } else { + /* , clear cruft from oid */ + oidclr(&oid); + } + } else { + /* , clear cruft from get_oid_hex */ oidclr(&oid); + } ref = alloc_ref(name); oidcpy(&ref->old_oid, &oid); @@ -149,7 +159,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) else { /* read from stdin one ref per line, until EOF */ struct strbuf line = STRBUF_INIT; - while (strbuf_getline(&line, stdin, '\n') != EOF) + while (strbuf_getline_lf(&line, stdin) != EOF) add_sought_entry(&sought, &nr_sought, &alloc_sought, line.buf); strbuf_release(&line); } diff --git a/builtin/fetch.c b/builtin/fetch.c index 683f08ec91..e4639d8eb1 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -37,6 +37,8 @@ static int prune = -1; /* unspecified */ static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity; static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT; static int tags = TAGS_DEFAULT, unshallow, update_shallow; +static int max_children = 1; +static enum transport_family family; static const char *depth; static const char *upload_pack; static struct strbuf default_rla = STRBUF_INIT; @@ -99,6 +101,8 @@ static struct option builtin_fetch_options[] = { N_("fetch all tags and associated objects"), TAGS_SET), OPT_SET_INT('n', NULL, &tags, N_("do not fetch all tags (--no-tags)"), TAGS_UNSET), + OPT_INTEGER('j', "jobs", &max_children, + N_("number of submodules fetched in parallel")), OPT_BOOL('p', "prune", &prune, N_("prune remote-tracking branches no longer on remote")), { OPTION_CALLBACK, 0, "recurse-submodules", NULL, N_("on-demand"), @@ -124,6 +128,10 @@ static struct option builtin_fetch_options[] = { N_("accept refs that update .git/shallow")), { OPTION_CALLBACK, 0, "refmap", NULL, N_("refmap"), N_("specify fetch refmap"), PARSE_OPT_NONEG, parse_refmap_arg }, + OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"), + TRANSPORT_FAMILY_IPV4), + OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"), + TRANSPORT_FAMILY_IPV6), OPT_END() }; @@ -861,6 +869,7 @@ static struct transport *prepare_transport(struct remote *remote) struct transport *transport; transport = transport_get(remote, NULL); transport_set_verbosity(transport, verbosity, progress); + transport->family = family; if (upload_pack) set_option(transport, TRANS_OPT_UPLOADPACK, upload_pack); if (keep) @@ -1013,10 +1022,9 @@ static int add_remote_or_group(const char *name, struct string_list *list) git_config(get_remote_group, &g); if (list->nr == prev_nr) { - struct remote *remote; - if (!remote_is_configured(name)) + struct remote *remote = remote_get(name); + if (!remote_is_configured(remote)) return 0; - remote = remote_get(name); string_list_append(list, remote->name); } return 1; @@ -1213,7 +1221,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) result = fetch_populated_submodules(&options, submodule_prefix, recurse_submodules, - verbosity < 0); + verbosity < 0, + max_children); argv_array_clear(&options); } diff --git a/builtin/grep.c b/builtin/grep.c index 65c02010c7..111b6f6cf1 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -24,11 +24,11 @@ static char const * const grep_usage[] = { NULL }; -static int use_threads = 1; +#define GREP_NUM_THREADS_DEFAULT 8 +static int num_threads; #ifndef NO_PTHREADS -#define THREADS 8 -static pthread_t threads[THREADS]; +static pthread_t *threads; /* We use one producer thread and THREADS consumer * threads. The producer adds struct work_items to 'todo' and the @@ -63,13 +63,13 @@ static pthread_mutex_t grep_mutex; static inline void grep_lock(void) { - if (use_threads) + if (num_threads) pthread_mutex_lock(&grep_mutex); } static inline void grep_unlock(void) { - if (use_threads) + if (num_threads) pthread_mutex_unlock(&grep_mutex); } @@ -206,7 +206,8 @@ static void start_threads(struct grep_opt *opt) strbuf_init(&todo[i].out, 0); } - for (i = 0; i < ARRAY_SIZE(threads); i++) { + threads = xcalloc(num_threads, sizeof(*threads)); + for (i = 0; i < num_threads; i++) { int err; struct grep_opt *o = grep_opt_dup(opt); o->output = strbuf_out; @@ -238,12 +239,14 @@ static int wait_all(void) pthread_cond_broadcast(&cond_add); grep_unlock(); - for (i = 0; i < ARRAY_SIZE(threads); i++) { + for (i = 0; i < num_threads; i++) { void *h; pthread_join(threads[i], &h); hit |= (int) (intptr_t) h; } + free(threads); + pthread_mutex_destroy(&grep_mutex); pthread_mutex_destroy(&grep_read_mutex); pthread_mutex_destroy(&grep_attr_mutex); @@ -267,6 +270,14 @@ static int grep_cmd_config(const char *var, const char *value, void *cb) int st = grep_config(var, value, cb); if (git_color_default_config(var, value, cb) < 0) st = -1; + + if (!strcmp(var, "grep.threads")) { + num_threads = git_config_int(var, value); + if (num_threads < 0) + die(_("invalid number of threads specified (%d) for %s"), + num_threads, var); + } + return st; } @@ -294,7 +305,7 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1, } #ifndef NO_PTHREADS - if (use_threads) { + if (num_threads) { add_work(opt, GREP_SOURCE_SHA1, pathbuf.buf, path, sha1); strbuf_release(&pathbuf); return 0; @@ -323,7 +334,7 @@ static int grep_file(struct grep_opt *opt, const char *filename) strbuf_addstr(&buf, filename); #ifndef NO_PTHREADS - if (use_threads) { + if (num_threads) { add_work(opt, GREP_SOURCE_FILE, buf.buf, filename, filename); strbuf_release(&buf); return 0; @@ -511,12 +522,14 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec, } static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec, - int exc_std) + int exc_std, int use_index) { struct dir_struct dir; int i, hit = 0; memset(&dir, 0, sizeof(dir)); + if (!use_index) + dir.flags |= DIR_NO_GITLINKS; if (exc_std) setup_standard_excludes(&dir); @@ -562,7 +575,7 @@ static int file_callback(const struct option *opt, const char *arg, int unset) patterns = from_stdin ? stdin : fopen(arg, "r"); if (!patterns) die_errno(_("cannot open '%s'"), arg); - while (strbuf_getline(&sb, patterns, '\n') == 0) { + while (strbuf_getline(&sb, patterns) == 0) { /* ignore empty line like grep does */ if (sb.len == 0) continue; @@ -697,6 +710,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix) N_("show context lines before matches")), OPT_INTEGER('A', "after-context", &opt.post_context, N_("show context lines after matches")), + OPT_INTEGER(0, "threads", &num_threads, + N_("use worker threads")), OPT_NUMBER_CALLBACK(&opt, N_("shortcut for -C NUM"), context_callback), OPT_BOOL('p', "show-function", &opt.funcname, @@ -755,9 +770,15 @@ int cmd_grep(int argc, const char **argv, const char *prefix) PARSE_OPT_STOP_AT_NON_OPTION); grep_commit_pattern_type(pattern_type_arg, &opt); - if (use_index && !startup_info->have_repository) - /* die the same way as if we did it at the beginning */ - setup_git_directory(); + if (use_index && !startup_info->have_repository) { + int fallback = 0; + git_config_get_bool("grep.fallbacktonoindex", &fallback); + if (fallback) + use_index = 0; + else + /* die the same way as if we did it at the beginning */ + setup_git_directory(); + } /* * skip a -- separator; we know it cannot be @@ -786,7 +807,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix) opt.output_priv = &path_list; opt.output = append_path; string_list_append(&path_list, show_in_pager); - use_threads = 0; } if (!opt.pattern_list) @@ -817,14 +837,18 @@ int cmd_grep(int argc, const char **argv, const char *prefix) } #ifndef NO_PTHREADS - if (list.nr || cached || online_cpus() == 1) - use_threads = 0; + if (list.nr || cached || show_in_pager) + num_threads = 0; + else if (num_threads == 0) + num_threads = GREP_NUM_THREADS_DEFAULT; + else if (num_threads < 0) + die(_("invalid number of threads specified (%d)"), num_threads); #else - use_threads = 0; + num_threads = 0; #endif #ifndef NO_PTHREADS - if (use_threads) { + if (num_threads) { if (!(opt.name_only || opt.unmatch_name_only || opt.count) && (opt.pre_context || opt.post_context || opt.file_break || opt.funcbody)) @@ -880,7 +904,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) int use_exclude = (opt_exclude < 0) ? use_index : !!opt_exclude; if (list.nr) die(_("--no-index or --untracked cannot be used with revs.")); - hit = grep_directory(&opt, &pathspec, use_exclude); + hit = grep_directory(&opt, &pathspec, use_exclude, use_index); } else if (0 <= opt_exclude) { die(_("--[no-]exclude-standard cannot be used for tracked contents.")); } else if (!list.nr) { @@ -894,7 +918,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) hit = grep_objects(&opt, &pathspec, &list); } - if (use_threads) + if (num_threads) hit |= wait_all(); if (hit && show_in_pager) run_pager(&opt, prefix); diff --git a/builtin/hash-object.c b/builtin/hash-object.c index 43b098b76c..f7d3567dd0 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -58,20 +58,21 @@ static void hash_object(const char *path, const char *type, const char *vpath, static void hash_stdin_paths(const char *type, int no_filters, unsigned flags, int literally) { - struct strbuf buf = STRBUF_INIT, nbuf = STRBUF_INIT; + struct strbuf buf = STRBUF_INIT; + struct strbuf unquoted = STRBUF_INIT; - while (strbuf_getline(&buf, stdin, '\n') != EOF) { + while (strbuf_getline(&buf, stdin) != EOF) { if (buf.buf[0] == '"') { - strbuf_reset(&nbuf); - if (unquote_c_style(&nbuf, buf.buf, NULL)) + strbuf_reset(&unquoted); + if (unquote_c_style(&unquoted, buf.buf, NULL)) die("line is badly quoted"); - strbuf_swap(&buf, &nbuf); + strbuf_swap(&buf, &unquoted); } hash_object(buf.buf, type, no_filters ? NULL : buf.buf, flags, literally); } strbuf_release(&buf); - strbuf_release(&nbuf); + strbuf_release(&unquoted); } int cmd_hash_object(int argc, const char **argv, const char *prefix) diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 45245199ae..e8c71fc1d2 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1250,7 +1250,9 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha nr_unresolved * sizeof(*objects)); f = sha1fd(output_fd, curr_pack); fix_unresolved_deltas(f); - strbuf_addf(&msg, _("completed with %d local objects"), + strbuf_addf(&msg, Q_("completed with %d local object", + "completed with %d local objects", + nr_objects - nr_objects_initial), nr_objects - nr_objects_initial); stop_progress_msg(&progress, msg.buf); strbuf_release(&msg); @@ -1599,6 +1601,18 @@ static void show_pack_info(int stat_only) } } +static const char *derive_filename(const char *pack_name, const char *suffix, + struct strbuf *buf) +{ + size_t len; + if (!strip_suffix(pack_name, ".pack", &len)) + die(_("packfile name '%s' does not end with '.pack'"), + pack_name); + strbuf_add(buf, pack_name, len); + strbuf_addstr(buf, suffix); + return buf->buf; +} + int cmd_index_pack(int argc, const char **argv, const char *prefix) { int i, fix_thin_pack = 0, verify = 0, stat_only = 0; @@ -1707,24 +1721,11 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) usage(index_pack_usage); if (fix_thin_pack && !from_stdin) die(_("--fix-thin cannot be used without --stdin")); - if (!index_name && pack_name) { - size_t len; - if (!strip_suffix(pack_name, ".pack", &len)) - die(_("packfile name '%s' does not end with '.pack'"), - pack_name); - strbuf_add(&index_name_buf, pack_name, len); - strbuf_addstr(&index_name_buf, ".idx"); - index_name = index_name_buf.buf; - } - if (keep_msg && !keep_name && pack_name) { - size_t len; - if (!strip_suffix(pack_name, ".pack", &len)) - die(_("packfile name '%s' does not end with '.pack'"), - pack_name); - strbuf_add(&keep_name_buf, pack_name, len); - strbuf_addstr(&keep_name_buf, ".idx"); - keep_name = keep_name_buf.buf; - } + if (!index_name && pack_name) + index_name = derive_filename(pack_name, ".idx", &index_name_buf); + if (keep_msg && !keep_name && pack_name) + keep_name = derive_filename(pack_name, ".keep", &keep_name_buf); + if (verify) { if (!index_name) die(_("--verify with no packfile name given")); diff --git a/builtin/init-db.c b/builtin/init-db.c index 6223b7d46a..b2d8d40a67 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -95,6 +95,8 @@ static void copy_templates(const char *template_dir) struct strbuf path = STRBUF_INIT; struct strbuf template_path = STRBUF_INIT; size_t template_len; + struct repository_format template_format; + struct strbuf err = STRBUF_INIT; DIR *dir; char *to_free = NULL; @@ -121,17 +123,18 @@ static void copy_templates(const char *template_dir) /* Make sure that template is from the correct vintage */ strbuf_addstr(&template_path, "config"); - repository_format_version = 0; - git_config_from_file(check_repository_format_version, - template_path.buf, NULL); + read_repository_format(&template_format, template_path.buf); strbuf_setlen(&template_path, template_len); - if (repository_format_version && - repository_format_version != GIT_REPO_VERSION) { - warning(_("not copying templates of " - "a wrong format version %d from '%s'"), - repository_format_version, - template_dir); + /* + * No mention of version at all is OK, but anything else should be + * verified. + */ + if (template_format.version >= 0 && + verify_repository_format(&template_format, &err) < 0) { + warning(_("not copying templates from '%s': %s"), + template_dir, err.buf); + strbuf_release(&err); goto close_free_return; } @@ -199,13 +202,13 @@ static int create_default_files(const char *template_path) /* reading existing config may have overwrote it */ if (init_shared_repository != -1) - shared_repository = init_shared_repository; + set_shared_repository(init_shared_repository); /* * We would have created the above under user's umask -- under * shared-repository settings, we would need to fix them up. */ - if (shared_repository) { + if (get_shared_repository()) { adjust_shared_perm(get_git_dir()); adjust_shared_perm(git_path_buf(&buf, "refs")); adjust_shared_perm(git_path_buf(&buf, "refs/heads")); @@ -322,6 +325,7 @@ int set_git_dir_init(const char *git_dir, const char *real_git_dir, set_git_dir(real_path(git_dir)); git_link = NULL; } + startup_info->have_repository = 1; return 0; } @@ -369,7 +373,7 @@ int init_db(const char *template_dir, unsigned int flags) create_object_directory(); - if (shared_repository) { + if (get_shared_repository()) { char buf[10]; /* We do not spell "group" and such, so that * the configuration can be read by older version @@ -377,12 +381,12 @@ int init_db(const char *template_dir, unsigned int flags) * and compatibility values for PERM_GROUP and * PERM_EVERYBODY. */ - if (shared_repository < 0) + if (get_shared_repository() < 0) /* force to the mode value */ - xsnprintf(buf, sizeof(buf), "0%o", -shared_repository); - else if (shared_repository == PERM_GROUP) + xsnprintf(buf, sizeof(buf), "0%o", -get_shared_repository()); + else if (get_shared_repository() == PERM_GROUP) xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_GROUP); - else if (shared_repository == PERM_EVERYBODY) + else if (get_shared_repository() == PERM_EVERYBODY) xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_EVERYBODY); else die("BUG: invalid value for shared_repository"); @@ -398,7 +402,7 @@ int init_db(const char *template_dir, unsigned int flags) "", and the last '%s%s' is the verbatim directory name. */ printf(_("%s%s Git repository in %s%s\n"), reinit ? _("Reinitialized existing") : _("Initialized empty"), - shared_repository ? _(" shared") : "", + get_shared_repository() ? _(" shared") : "", git_dir, len && git_dir[len-1] != '/' ? "/" : ""); } @@ -493,8 +497,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) * and we know shared_repository should always be 0; * but just in case we play safe. */ - saved = shared_repository; - shared_repository = 0; + saved = get_shared_repository(); + set_shared_repository(0); switch (safe_create_leading_directories_const(argv[0])) { case SCLD_OK: case SCLD_PERMS: @@ -506,7 +510,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) die_errno(_("cannot mkdir %s"), argv[0]); break; } - shared_repository = saved; + set_shared_repository(saved); if (mkdir(argv[0], 0777) < 0) die_errno(_("cannot mkdir %s"), argv[0]); mkdir_tried = 1; @@ -524,7 +528,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) } if (init_shared_repository != -1) - shared_repository = init_shared_repository; + set_shared_repository(init_shared_repository); /* * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c index 46838d24a9..b99ae4be88 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -12,16 +12,18 @@ #include "trailer.h" static const char * const git_interpret_trailers_usage[] = { - N_("git interpret-trailers [--trim-empty] [(--trailer [(=|:)])...] [...]"), + N_("git interpret-trailers [--in-place] [--trim-empty] [(--trailer [(=|:)])...] [...]"), NULL }; int cmd_interpret_trailers(int argc, const char **argv, const char *prefix) { + int in_place = 0; int trim_empty = 0; struct string_list trailers = STRING_LIST_INIT_DUP; struct option options[] = { + OPT_BOOL(0, "in-place", &in_place, N_("edit files in place")), OPT_BOOL(0, "trim-empty", &trim_empty, N_("trim empty trailers")), OPT_STRING_LIST(0, "trailer", &trailers, N_("trailer"), N_("trailer(s) to add")), @@ -34,9 +36,12 @@ int cmd_interpret_trailers(int argc, const char **argv, const char *prefix) if (argc) { int i; for (i = 0; i < argc; i++) - process_trailers(argv[i], trim_empty, &trailers); - } else - process_trailers(NULL, trim_empty, &trailers); + process_trailers(argv[i], in_place, trim_empty, &trailers); + } else { + if (in_place) + die(_("no input file given for in-place editing")); + process_trailers(NULL, in_place, trim_empty, &trailers); + } string_list_clear(&trailers, 0); diff --git a/builtin/log.c b/builtin/log.c index e00cea75cc..0d738d6ddc 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -699,6 +699,7 @@ static int do_signoff; static const char *signature = git_version_string; static const char *signature_file; static int config_cover_letter; +static const char *config_output_directory; enum { COVER_UNSET, @@ -777,6 +778,8 @@ static int git_format_config(const char *var, const char *value, void *cb) config_cover_letter = git_config_bool(var, value) ? COVER_ON : COVER_OFF; return 0; } + if (!strcmp(var, "format.outputdirectory")) + return git_config_string(&config_output_directory, var, value); return git_log_config(var, value, cb); } @@ -1391,6 +1394,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) if (rev.show_notes) init_display_notes(&rev.notes_opt); + if (!output_directory && !use_stdout) + output_directory = config_output_directory; + if (!use_stdout) output_directory = set_outdir(prefix, output_directory); else diff --git a/builtin/ls-files.c b/builtin/ls-files.c index b6a7cb0c7c..f02e3d23bb 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -27,6 +27,7 @@ static int show_killed; static int show_valid_bit; static int line_terminator = '\n'; static int debug_mode; +static int show_eol; static const char *prefix; static int max_prefix_len; @@ -47,6 +48,23 @@ static const char *tag_modified = ""; static const char *tag_skip_worktree = ""; static const char *tag_resolve_undo = ""; +static void write_eolinfo(const struct cache_entry *ce, const char *path) +{ + if (!show_eol) + return; + else { + struct stat st; + const char *i_txt = ""; + const char *w_txt = ""; + const char *a_txt = get_convert_attr_ascii(path); + if (ce && S_ISREG(ce->ce_mode)) + i_txt = get_cached_convert_stats_ascii(ce->name); + if (!lstat(path, &st) && S_ISREG(st.st_mode)) + w_txt = get_wt_convert_stats_ascii(path); + printf("i/%-5s w/%-5s attr/%-17s\t", i_txt, w_txt, a_txt); + } +} + static void write_name(const char *name) { /* @@ -68,6 +86,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent) return; fputs(tag, stdout); + write_eolinfo(NULL, ent->name); write_name(ent->name); } @@ -170,6 +189,7 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce) find_unique_abbrev(ce->sha1,abbrev), ce_stage(ce)); } + write_eolinfo(ce, ce->name); write_name(ce->name); if (debug_mode) { const struct stat_data *sd = &ce->ce_stat_data; @@ -359,14 +379,6 @@ static const char * const ls_files_usage[] = { NULL }; -static int option_parse_z(const struct option *opt, - const char *arg, int unset) -{ - line_terminator = unset ? '\n' : '\0'; - - return 0; -} - static int option_parse_exclude(const struct option *opt, const char *arg, int unset) { @@ -408,9 +420,9 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) struct exclude_list *el; struct string_list exclude_list = STRING_LIST_INIT_NODUP; struct option builtin_ls_files_options[] = { - { OPTION_CALLBACK, 'z', NULL, NULL, NULL, - N_("paths are separated with NUL character"), - PARSE_OPT_NOARG, option_parse_z }, + /* Think twice before adding "--nul" synonym to this */ + OPT_SET_INT('z', NULL, &line_terminator, + N_("paths are separated with NUL character"), '\0'), OPT_BOOL('t', NULL, &show_tag, N_("identify the file status with tags")), OPT_BOOL('v', NULL, &show_valid_bit, @@ -433,6 +445,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) OPT_BIT(0, "directory", &dir.flags, N_("show 'other' directories' names only"), DIR_SHOW_OTHER_DIRECTORIES), + OPT_BOOL(0, "eol", &show_eol, N_("show line endings of files")), OPT_NEGBIT(0, "empty-directory", &dir.flags, N_("don't show empty directories"), DIR_HIDE_EMPTY_DIRECTORIES), diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index fa65a8448a..66cdd45cc1 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -3,9 +3,12 @@ #include "transport.h" #include "remote.h" -static const char ls_remote_usage[] = -"git ls-remote [--heads] [--tags] [--upload-pack=]\n" -" [-q | --quiet] [--exit-code] [--get-url] [ [...]]"; +static const char * const ls_remote_usage[] = { + N_("git ls-remote [--heads] [--tags] [--refs] [--upload-pack=]\n" + " [-q | --quiet] [--exit-code] [--get-url]\n" + " [--symref] [ [...]]"), + NULL +}; /* * Is there one among the list of patterns that match the tail part @@ -30,12 +33,12 @@ static int tail_match(const char **pattern, const char *path) int cmd_ls_remote(int argc, const char **argv, const char *prefix) { - int i; const char *dest = NULL; unsigned flags = 0; int get_url = 0; int quiet = 0; int status = 0; + int show_symref_target = 0; const char *uploadpack = NULL; const char **pattern = NULL; @@ -43,59 +46,36 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) struct transport *transport; const struct ref *ref; - if (argc == 2 && !strcmp("-h", argv[1])) - usage(ls_remote_usage); + struct option options[] = { + OPT__QUIET(&quiet, N_("do not print remote URL")), + OPT_STRING(0, "upload-pack", &uploadpack, N_("exec"), + N_("path of git-upload-pack on the remote host")), + { OPTION_STRING, 0, "exec", &uploadpack, N_("exec"), + N_("path of git-upload-pack on the remote host"), + PARSE_OPT_HIDDEN }, + OPT_BIT('t', "tags", &flags, N_("limit to tags"), REF_TAGS), + OPT_BIT('h', "heads", &flags, N_("limit to heads"), REF_HEADS), + OPT_BIT(0, "refs", &flags, N_("do not show peeled tags"), REF_NORMAL), + OPT_BOOL(0, "get-url", &get_url, + N_("take url..insteadOf into account")), + OPT_SET_INT(0, "exit-code", &status, + N_("exit with exit code 2 if no matching refs are found"), 2), + OPT_BOOL(0, "symref", &show_symref_target, + N_("show underlying ref in addition to the object pointed by it")), + OPT_END() + }; - for (i = 1; i < argc; i++) { - const char *arg = argv[i]; + argc = parse_options(argc, argv, prefix, options, ls_remote_usage, + PARSE_OPT_STOP_AT_NON_OPTION); + dest = argv[0]; - if (*arg == '-') { - if (starts_with(arg, "--upload-pack=")) { - uploadpack = arg + 14; - continue; - } - if (starts_with(arg, "--exec=")) { - uploadpack = arg + 7; - continue; - } - if (!strcmp("--tags", arg) || !strcmp("-t", arg)) { - flags |= REF_TAGS; - continue; - } - if (!strcmp("--heads", arg) || !strcmp("-h", arg)) { - flags |= REF_HEADS; - continue; - } - if (!strcmp("--refs", arg)) { - flags |= REF_NORMAL; - continue; - } - if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) { - quiet = 1; - continue; - } - if (!strcmp("--get-url", arg)) { - get_url = 1; - continue; - } - if (!strcmp("--exit-code", arg)) { - /* return this code if no refs are reported */ - status = 2; - continue; - } - usage(ls_remote_usage); - } - dest = arg; - i++; - break; + if (argc > 1) { + int i; + pattern = xcalloc(argc, sizeof(const char *)); + for (i = 1; i < argc; i++) + pattern[i - 1] = xstrfmt("*/%s", argv[i]); } - if (argv[i]) { - int j; - pattern = xcalloc(argc - i + 1, sizeof(const char *)); - for (j = i; j < argc; j++) - pattern[j - i] = xstrfmt("*/%s", argv[j]); - } remote = remote_get(dest); if (!remote) { if (dest) @@ -125,7 +105,9 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) continue; if (!tail_match(pattern, ref->name)) continue; - printf("%s %s\n", oid_to_hex(&ref->old_oid), ref->name); + if (show_symref_target && ref->symref) + printf("ref: %s\t%s\n", ref->symref, ref->name); + printf("%s\t%s\n", oid_to_hex(&ref->old_oid), ref->name); status = 0; /* we found something */ } return status; diff --git a/builtin/merge.c b/builtin/merge.c index 101ffeff4c..bf2f2614fb 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -1257,12 +1257,12 @@ int cmd_merge(int argc, const char **argv, const char *prefix) builtin_merge_options); if (!head_commit) { - struct commit *remote_head; /* * If the merged head is a valid one there is no reason * to forbid "git merge" into a branch yet to be born. * We do the same for "git pull". */ + unsigned char *remote_head_sha1; if (squash) die(_("Squash commit into empty head not supported yet")); if (fast_forward == FF_NO) @@ -1270,13 +1270,13 @@ int cmd_merge(int argc, const char **argv, const char *prefix) "an empty head")); remoteheads = collect_parents(head_commit, &head_subsumed, argc, argv, NULL); - remote_head = remoteheads->item; - if (!remote_head) + if (!remoteheads) die(_("%s - not something we can merge"), argv[0]); if (remoteheads->next) die(_("Can merge only exactly one commit into empty head")); - read_empty(remote_head->object.oid.hash, 0); - update_ref("initial pull", "HEAD", remote_head->object.oid.hash, + remote_head_sha1 = remoteheads->item->object.oid.hash; + read_empty(remote_head_sha1, 0); + update_ref("initial pull", "HEAD", remote_head_sha1, NULL, 0, UPDATE_REFS_DIE_ON_ERR); goto done; } diff --git a/builtin/mktree.c b/builtin/mktree.c index b0aab65353..4282b62c59 100644 --- a/builtin/mktree.c +++ b/builtin/mktree.c @@ -66,7 +66,7 @@ static const char *mktree_usage[] = { NULL }; -static void mktree_line(char *buf, size_t len, int line_termination, int allow_missing) +static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_missing) { char *ptr, *ntr; unsigned mode; @@ -98,7 +98,7 @@ static void mktree_line(char *buf, size_t len, int line_termination, int allow_m *ntr++ = 0; /* now at the beginning of SHA1 */ path = ntr + 41; /* at the beginning of name */ - if (line_termination && path[0] == '"') { + if (!nul_term_line && path[0] == '"') { struct strbuf p_uq = STRBUF_INIT; if (unquote_c_style(&p_uq, path, NULL)) die("invalid quoting"); @@ -142,23 +142,25 @@ int cmd_mktree(int ac, const char **av, const char *prefix) { struct strbuf sb = STRBUF_INIT; unsigned char sha1[20]; - int line_termination = '\n'; + int nul_term_line = 0; int allow_missing = 0; int is_batch_mode = 0; int got_eof = 0; + strbuf_getline_fn getline_fn; const struct option option[] = { - OPT_SET_INT('z', NULL, &line_termination, N_("input is NUL terminated"), '\0'), + OPT_BOOL('z', NULL, &nul_term_line, N_("input is NUL terminated")), OPT_SET_INT( 0 , "missing", &allow_missing, N_("allow missing objects"), 1), OPT_SET_INT( 0 , "batch", &is_batch_mode, N_("allow creation of more than one tree"), 1), OPT_END() }; ac = parse_options(ac, av, prefix, option, mktree_usage, 0); + getline_fn = nul_term_line ? strbuf_getline_nul : strbuf_getline_lf; while (!got_eof) { while (1) { - if (strbuf_getline(&sb, stdin, line_termination) == EOF) { + if (getline_fn(&sb, stdin) == EOF) { got_eof = 1; break; } @@ -168,7 +170,7 @@ int cmd_mktree(int ac, const char **av, const char *prefix) break; die("input format error: (blank line only valid in batch mode)"); } - mktree_line(sb.buf, sb.len, line_termination, allow_missing); + mktree_line(sb.buf, sb.len, nul_term_line, allow_missing); } if (is_batch_mode && got_eof && used < 1) { /* diff --git a/builtin/mv.c b/builtin/mv.c index aeae855e2b..a2014266b6 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -252,15 +252,18 @@ int cmd_mv(int argc, const char **argv, const char *prefix) int pos; if (show_only || verbose) printf(_("Renaming %s to %s\n"), src, dst); - if (!show_only && mode != INDEX) { - if (rename(src, dst) < 0 && !ignore_errors) - die_errno(_("renaming '%s' failed"), src); - if (submodule_gitfile[i]) { - if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR) - connect_work_tree_and_git_dir(dst, submodule_gitfile[i]); - if (!update_path_in_gitmodules(src, dst)) - gitmodules_modified = 1; - } + if (show_only) + continue; + if (mode != INDEX && rename(src, dst) < 0) { + if (ignore_errors) + continue; + die_errno(_("renaming '%s' failed"), src); + } + if (submodule_gitfile[i]) { + if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR) + connect_work_tree_and_git_dir(dst, submodule_gitfile[i]); + if (!update_path_in_gitmodules(src, dst)) + gitmodules_modified = 1; } if (mode == WORKING_DIRECTORY) diff --git a/builtin/name-rev.c b/builtin/name-rev.c index 092e03c3cc..57be35faf5 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -10,6 +10,7 @@ typedef struct rev_name { const char *tip_name; + unsigned long taggerdate; int generation; int distance; } rev_name; @@ -20,7 +21,8 @@ static long cutoff = LONG_MAX; #define MERGE_TRAVERSAL_WEIGHT 65535 static void name_rev(struct commit *commit, - const char *tip_name, int generation, int distance, + const char *tip_name, unsigned long taggerdate, + int generation, int distance, int deref) { struct rev_name *name = (struct rev_name *)commit->util; @@ -43,9 +45,12 @@ static void name_rev(struct commit *commit, name = xmalloc(sizeof(rev_name)); commit->util = name; goto copy_data; - } else if (name->distance > distance) { + } else if (name->taggerdate > taggerdate || + (name->taggerdate == taggerdate && + name->distance > distance)) { copy_data: name->tip_name = tip_name; + name->taggerdate = taggerdate; name->generation = generation; name->distance = distance; } else @@ -66,11 +71,11 @@ static void name_rev(struct commit *commit, new_name = xstrfmt("%.*s^%d", (int)len, tip_name, parent_number); - name_rev(parents->item, new_name, 0, + name_rev(parents->item, new_name, taggerdate, 0, distance + MERGE_TRAVERSAL_WEIGHT, 0); } else { - name_rev(parents->item, tip_name, generation + 1, - distance + 1, 0); + name_rev(parents->item, tip_name, taggerdate, + generation + 1, distance + 1, 0); } } } @@ -140,6 +145,7 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo struct name_ref_data *data = cb_data; int can_abbreviate_output = data->tags_only && data->name_only; int deref = 0; + unsigned long taggerdate = ULONG_MAX; if (data->tags_only && !starts_with(path, "refs/tags/")) return 0; @@ -164,12 +170,13 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo break; /* broken repository */ o = parse_object(t->tagged->oid.hash); deref = 1; + taggerdate = t->date; } if (o && o->type == OBJ_COMMIT) { struct commit *commit = (struct commit *)o; path = name_ref_abbrev(path, can_abbreviate_output); - name_rev(commit, xstrdup(path), 0, 0, deref); + name_rev(commit, xstrdup(path), taggerdate, 0, 0, deref); } return 0; } diff --git a/builtin/notes.c b/builtin/notes.c index 52aa9af74b..6fd058de92 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -286,11 +286,11 @@ static int notes_copy_from_stdin(int force, const char *rewrite_cmd) if (!c) return 0; } else { - init_notes(NULL, NULL, NULL, 0); + init_notes(NULL, NULL, NULL, NOTES_INIT_WRITABLE); t = &default_notes_tree; } - while (strbuf_getline(&buf, stdin, '\n') != EOF) { + while (strbuf_getline_lf(&buf, stdin) != EOF) { unsigned char from_obj[20], to_obj[20]; struct strbuf **split; int err; @@ -329,15 +329,18 @@ static int notes_copy_from_stdin(int force, const char *rewrite_cmd) return ret; } -static struct notes_tree *init_notes_check(const char *subcommand) +static struct notes_tree *init_notes_check(const char *subcommand, + int flags) { struct notes_tree *t; - init_notes(NULL, NULL, NULL, 0); + const char *ref; + init_notes(NULL, NULL, NULL, flags); t = &default_notes_tree; - if (!starts_with(t->ref, "refs/notes/")) + ref = (flags & NOTES_INIT_WRITABLE) ? t->update_ref : t->ref; + if (!starts_with(ref, "refs/notes/")) die("Refusing to %s notes in %s (outside of refs/notes/)", - subcommand, t->ref); + subcommand, ref); return t; } @@ -360,7 +363,7 @@ static int list(int argc, const char **argv, const char *prefix) usage_with_options(git_notes_list_usage, options); } - t = init_notes_check("list"); + t = init_notes_check("list", 0); if (argc) { if (get_sha1(argv[0], object)) die(_("Failed to resolve '%s' as a valid ref."), argv[0]); @@ -420,7 +423,7 @@ static int add(int argc, const char **argv, const char *prefix) if (get_sha1(object_ref, object)) die(_("Failed to resolve '%s' as a valid ref."), object_ref); - t = init_notes_check("add"); + t = init_notes_check("add", NOTES_INIT_WRITABLE); note = get_note(t, object); if (note) { @@ -511,7 +514,7 @@ static int copy(int argc, const char **argv, const char *prefix) if (get_sha1(object_ref, object)) die(_("Failed to resolve '%s' as a valid ref."), object_ref); - t = init_notes_check("copy"); + t = init_notes_check("copy", NOTES_INIT_WRITABLE); note = get_note(t, object); if (note) { @@ -589,7 +592,7 @@ static int append_edit(int argc, const char **argv, const char *prefix) if (get_sha1(object_ref, object)) die(_("Failed to resolve '%s' as a valid ref."), object_ref); - t = init_notes_check(argv[0]); + t = init_notes_check(argv[0], NOTES_INIT_WRITABLE); note = get_note(t, object); prepare_note_data(object, &d, edit ? note : NULL); @@ -652,7 +655,7 @@ static int show(int argc, const char **argv, const char *prefix) if (get_sha1(object_ref, object)) die(_("Failed to resolve '%s' as a valid ref."), object_ref); - t = init_notes_check("show"); + t = init_notes_check("show", 0); note = get_note(t, object); if (!note) @@ -741,13 +744,14 @@ static int merge_commit(struct notes_merge_options *o) static int git_config_get_notes_strategy(const char *key, enum notes_merge_strategy *strategy) { - const char *value; + char *value; - if (git_config_get_string_const(key, &value)) + if (git_config_get_string(key, &value)) return 1; if (parse_notes_merge_strategy(value, strategy)) git_die_config(key, "unknown notes merge strategy %s", value); + free(value); return 0; } @@ -806,10 +810,10 @@ static int merge(int argc, const char **argv, const char *prefix) o.local_ref = default_notes_ref(); strbuf_addstr(&remote_ref, argv[0]); - expand_notes_ref(&remote_ref); + expand_loose_notes_ref(&remote_ref); o.remote_ref = remote_ref.buf; - t = init_notes_check("merge"); + t = init_notes_check("merge", NOTES_INIT_WRITABLE); if (strategy) { if (parse_notes_merge_strategy(strategy, &o.strategy)) { @@ -901,7 +905,7 @@ static int remove_cmd(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, git_notes_remove_usage, 0); - t = init_notes_check("remove"); + t = init_notes_check("remove", NOTES_INIT_WRITABLE); if (!argc && !from_stdin) { retval = remove_one_note(t, "HEAD", flag); @@ -943,7 +947,7 @@ static int prune(int argc, const char **argv, const char *prefix) usage_with_options(git_notes_prune_usage, options); } - t = init_notes_check("prune"); + t = init_notes_check("prune", NOTES_INIT_WRITABLE); prune_notes(t, (verbose ? NOTES_PRUNE_VERBOSE : 0) | (show_only ? NOTES_PRUNE_VERBOSE|NOTES_PRUNE_DRYRUN : 0) ); diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index a27de5b323..b6664ce4d8 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -759,6 +759,10 @@ static off_t write_reused_pack(struct sha1file *f) return reuse_packfile_offset - sizeof(struct pack_header); } +static const char no_split_warning[] = N_( +"disabling bitmap writing, packs are split due to pack.packSizeLimit" +); + static void write_pack_file(void) { uint32_t i = 0, j; @@ -813,7 +817,10 @@ static void write_pack_file(void) fixup_pack_header_footer(fd, sha1, pack_tmp_name, nr_written, sha1, offset); close(fd); - write_bitmap_index = 0; + if (write_bitmap_index) { + warning(_(no_split_warning)); + write_bitmap_index = 0; + } } if (!pack_to_stdout) { diff --git a/builtin/pull.c b/builtin/pull.c index 5145fc60a0..6214af9b10 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -22,7 +22,8 @@ enum rebase_type { REBASE_INVALID = -1, REBASE_FALSE = 0, REBASE_TRUE, - REBASE_PRESERVE + REBASE_PRESERVE, + REBASE_INTERACTIVE }; /** @@ -42,6 +43,8 @@ static enum rebase_type parse_config_rebase(const char *key, const char *value, return REBASE_TRUE; else if (!strcmp(value, "preserve")) return REBASE_PRESERVE; + else if (!strcmp(value, "interactive")) + return REBASE_INTERACTIVE; if (fatal) die(_("Invalid value for %s: %s"), key, value); @@ -95,6 +98,7 @@ static int opt_force; static char *opt_tags; static char *opt_prune; static char *opt_recurse_submodules; +static char *max_children; static int opt_dry_run; static char *opt_keep; static char *opt_depth; @@ -112,7 +116,7 @@ static struct option pull_options[] = { /* Options passed to git-merge or git-rebase */ OPT_GROUP(N_("Options related to merging")), { OPTION_CALLBACK, 'r', "rebase", &opt_rebase, - "false|true|preserve", + "false|true|preserve|interactive", N_("incorporate changes by rebasing rather than merging"), PARSE_OPT_OPTARG, parse_opt_rebase }, OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL, @@ -178,6 +182,9 @@ static struct option pull_options[] = { N_("on-demand"), N_("control recursive fetching of submodules"), PARSE_OPT_OPTARG), + OPT_PASSTHRU('j', "jobs", &max_children, N_("n"), + N_("number of submodules pulled in parallel"), + PARSE_OPT_OPTARG), OPT_BOOL(0, "dry-run", &opt_dry_run, N_("dry run")), OPT_PASSTHRU('k', "keep", &opt_keep, NULL, @@ -378,7 +385,7 @@ static void get_merge_heads(struct sha1_array *merge_heads) if (!(fp = fopen(filename, "r"))) die_errno(_("could not open '%s' for reading"), filename); - while (strbuf_getline(&sb, fp, '\n') != EOF) { + while (strbuf_getline_lf(&sb, fp) != EOF) { if (get_sha1_hex(sb.buf, sha1)) continue; /* invalid line: does not start with SHA1 */ if (starts_with(sb.buf + GIT_SHA1_HEXSZ, "\tnot-for-merge\t")) @@ -451,13 +458,13 @@ static void NORETURN die_no_merge_candidates(const char *repo, const char **refs fprintf_ln(stderr, _("Please specify which branch you want to merge with.")); fprintf_ln(stderr, _("See git-pull(1) for details.")); fprintf(stderr, "\n"); - fprintf_ln(stderr, " git pull "); + fprintf_ln(stderr, " git pull %s %s", _(""), _("")); fprintf(stderr, "\n"); } else if (!curr_branch->merge_nr) { const char *remote_name = NULL; if (for_each_remote(get_only_remote, &remote_name) || !remote_name) - remote_name = ""; + remote_name = _(""); fprintf_ln(stderr, _("There is no tracking information for the current branch.")); if (opt_rebase) @@ -466,12 +473,12 @@ static void NORETURN die_no_merge_candidates(const char *repo, const char **refs fprintf_ln(stderr, _("Please specify which branch you want to merge with.")); fprintf_ln(stderr, _("See git-pull(1) for details.")); fprintf(stderr, "\n"); - fprintf_ln(stderr, " git pull "); + fprintf_ln(stderr, " git pull %s %s", _(""), _("")); + fprintf(stderr, "\n"); + fprintf_ln(stderr, _("If you wish to set tracking information for this branch you can do so with:")); fprintf(stderr, "\n"); - fprintf_ln(stderr, _("If you wish to set tracking information for this branch you can do so with:\n" - "\n" - " git branch --set-upstream-to=%s/ %s\n"), - remote_name, curr_branch->name); + fprintf_ln(stderr, " git branch --set-upstream-to=%s/%s %s\n", + remote_name, _(""), curr_branch->name); } else fprintf_ln(stderr, _("Your configuration specifies to merge with the ref '%s'\n" "from the remote, but no such ref was fetched."), @@ -525,6 +532,8 @@ static int run_fetch(const char *repo, const char **refspecs) argv_array_push(&args, opt_prune); if (opt_recurse_submodules) argv_array_push(&args, opt_recurse_submodules); + if (max_children) + argv_array_push(&args, max_children); if (opt_dry_run) argv_array_push(&args, "--dry-run"); if (opt_keep) @@ -772,6 +781,8 @@ static int run_rebase(const unsigned char *curr_head, /* Options passed to git-rebase */ if (opt_rebase == REBASE_PRESERVE) argv_array_push(&args, "--preserve-merges"); + else if (opt_rebase == REBASE_INTERACTIVE) + argv_array_push(&args, "--interactive"); if (opt_diffstat) argv_array_push(&args, opt_diffstat); argv_array_pushv(&args, opt_strategies.argv); diff --git a/builtin/push.c b/builtin/push.c index 8963dbdf3d..4e9e4dbab2 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -23,6 +23,7 @@ static const char *receivepack; static int verbosity; static int progress = -1; static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT; +static enum transport_family family; static struct push_cas_option cas; @@ -204,37 +205,6 @@ static void setup_push_current(struct remote *remote, struct branch *branch) add_refspec(branch->name); } -static char warn_unspecified_push_default_msg[] = -N_("push.default is unset; its implicit value has changed in\n" - "Git 2.0 from 'matching' to 'simple'. To squelch this message\n" - "and maintain the traditional behavior, use:\n" - "\n" - " git config --global push.default matching\n" - "\n" - "To squelch this message and adopt the new behavior now, use:\n" - "\n" - " git config --global push.default simple\n" - "\n" - "When push.default is set to 'matching', git will push local branches\n" - "to the remote branches that already exist with the same name.\n" - "\n" - "Since Git 2.0, Git defaults to the more conservative 'simple'\n" - "behavior, which only pushes the current branch to the corresponding\n" - "remote branch that 'git pull' uses to update the current branch.\n" - "\n" - "See 'git help config' and search for 'push.default' for further information.\n" - "(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode\n" - "'current' instead of 'simple' if you sometimes use older versions of Git)"); - -static void warn_unspecified_push_default_configuration(void) -{ - static int warn_once; - - if (warn_once++) - return; - warning("%s\n", _(warn_unspecified_push_default_msg)); -} - static int is_workflow_triangular(struct remote *remote) { struct remote *fetch_remote = remote_get(NULL); @@ -253,9 +223,6 @@ static void setup_default_push_refspecs(struct remote *remote) break; case PUSH_DEFAULT_UNSPECIFIED: - warn_unspecified_push_default_configuration(); - /* fallthru */ - case PUSH_DEFAULT_SIMPLE: if (triangular) setup_push_current(remote, branch); @@ -346,6 +313,7 @@ static int push_with_options(struct transport *transport, int flags) unsigned int reject_reasons; transport_set_verbosity(transport, verbosity, progress); + transport->family = family; if (receivepack) transport_set_option(transport, @@ -538,7 +506,7 @@ int cmd_push(int argc, const char **argv, const char *prefix) OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL), OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"), (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)), - OPT_BOOL( 0, "delete", &deleterefs, N_("delete refs")), + OPT_BOOL('d', "delete", &deleterefs, N_("delete refs")), OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")), OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN), OPT_BIT( 0, "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN), @@ -565,6 +533,10 @@ int cmd_push(int argc, const char **argv, const char *prefix) 0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"), PARSE_OPT_OPTARG, option_parse_push_signed }, OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC), + OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"), + TRANSPORT_FAMILY_IPV4), + OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"), + TRANSPORT_FAMILY_IPV6), OPT_END() }; diff --git a/builtin/remote-ext.c b/builtin/remote-ext.c index 7457c743e8..88eb8f9013 100644 --- a/builtin/remote-ext.c +++ b/builtin/remote-ext.c @@ -168,7 +168,7 @@ static int command_loop(const char *child) size_t i; if (!fgets(buffer, MAXCOMMAND - 1, stdin)) { if (ferror(stdin)) - die("Comammand input error"); + die("Command input error"); exit(0); } /* Strip end of line characters. */ diff --git a/builtin/remote.c b/builtin/remote.c index 43136951b5..d33766be39 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -186,10 +186,7 @@ static int add(int argc, const char **argv) url = argv[1]; remote = remote_get(name); - if (remote && (remote->url_nr > 1 || - (strcmp(name, remote->url[0]) && - strcmp(url, remote->url[0])) || - remote->fetch_refspec_nr)) + if (remote_is_configured(remote)) die(_("remote %s already exists."), name); strbuf_addf(&buf2, "refs/heads/test:refs/remotes/%s/test", name); @@ -247,7 +244,7 @@ static int add(int argc, const char **argv) struct branch_info { char *remote_name; struct string_list merge; - int rebase; + enum { NO_REBASE, NORMAL_REBASE, INTERACTIVE_REBASE } rebase; }; static struct string_list branch_list; @@ -307,7 +304,9 @@ static int config_read_branches(const char *key, const char *value, void *cb) if (v >= 0) info->rebase = v; else if (!strcmp(value, "preserve")) - info->rebase = 1; + info->rebase = NORMAL_REBASE; + else if (!strcmp(value, "interactive")) + info->rebase = INTERACTIVE_REBASE; } } return 0; @@ -623,14 +622,14 @@ static int mv(int argc, const char **argv) rename.remote_branches = &remote_branches; oldremote = remote_get(rename.old); - if (!oldremote) + if (!remote_is_configured(oldremote)) die(_("No such remote: %s"), rename.old); if (!strcmp(rename.old, rename.new) && oldremote->origin != REMOTE_CONFIG) return migrate_file(oldremote); newremote = remote_get(rename.new); - if (newremote && (newremote->url_nr > 1 || newremote->fetch_refspec_nr)) + if (remote_is_configured(newremote)) die(_("remote %s already exists."), rename.new); strbuf_addf(&buf, "refs/heads/test:refs/remotes/%s/test", rename.new); @@ -758,7 +757,7 @@ static int rm(int argc, const char **argv) usage_with_options(builtin_remote_rm_usage, options); remote = remote_get(argv[1]); - if (!remote) + if (!remote_is_configured(remote)) die(_("No such remote: %s"), argv[1]); known_remotes.to_delete = remote; @@ -964,7 +963,9 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data) printf(" %-*s ", show_info->width, item->string); if (branch_info->rebase) { - printf_ln(_("rebases onto remote %s"), merge->items[0].string); + printf_ln(_(branch_info->rebase == INTERACTIVE_REBASE ? + "rebases interactively onto remote %s" : + "rebases onto remote %s"), merge->items[0].string); return 0; } else if (show_info->any_rebase) { printf_ln(_(" merges with remote %s"), merge->items[0].string); @@ -1153,6 +1154,8 @@ static int show(int argc, const char **argv) url_nr = states.remote->url_nr; } for (i = 0; i < url_nr; i++) + /* TRANSLATORS: the colon ':' should align with + the one in " Fetch URL: %s" translation */ printf_ln(_(" Push URL: %s"), url[i]); if (!i) printf_ln(_(" Push URL: %s"), "(no URL)"); @@ -1417,9 +1420,9 @@ static int set_remote_branches(const char *remotename, const char **branches, strbuf_addf(&key, "remote.%s.fetch", remotename); - if (!remote_is_configured(remotename)) - die(_("No such remote '%s'"), remotename); remote = remote_get(remotename); + if (!remote_is_configured(remote)) + die(_("No such remote '%s'"), remotename); if (!add_mode && remove_all_fetch_refspecs(remotename, key.buf)) { strbuf_release(&key); @@ -1471,9 +1474,9 @@ static int get_url(int argc, const char **argv) remotename = argv[0]; - if (!remote_is_configured(remotename)) - die(_("No such remote '%s'"), remotename); remote = remote_get(remotename); + if (!remote_is_configured(remote)) + die(_("No such remote '%s'"), remotename); url_nr = 0; if (push_mode) { @@ -1539,9 +1542,9 @@ static int set_url(int argc, const char **argv) if (delete_mode) oldurl = newurl; - if (!remote_is_configured(remotename)) - die(_("No such remote '%s'"), remotename); remote = remote_get(remotename); + if (!remote_is_configured(remote)) + die(_("No such remote '%s'"), remotename); if (push_mode) { strbuf_addf(&name_buf, "remote.%s.pushurl", remotename); diff --git a/builtin/repack.c b/builtin/repack.c index 945611006a..858db38f52 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -266,7 +266,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) return ret; out = xfdopen(cmd.out, "r"); - while (strbuf_getline(&line, out, '\n') != EOF) { + while (strbuf_getline_lf(&line, out) != EOF) { if (line.len != 40) die("repack: Expecting 40 character sha1 lines only from pack-objects."); string_list_append(&names, line.buf); diff --git a/builtin/replace.c b/builtin/replace.c index 748c6ca954..b58c714cb8 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -440,6 +440,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix) }; check_replace_refs = 0; + git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_replace_usage, 0); diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 7a4f2c0b0c..c961b74c5a 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -383,7 +383,7 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) /* get the usage up to the first line with a -- on it */ for (;;) { - if (strbuf_getline(&sb, stdin, '\n') == EOF) + if (strbuf_getline(&sb, stdin) == EOF) die("premature end of input"); ALLOC_GROW(usage, unb + 1, usz); if (!strcmp("--", sb.buf)) { @@ -396,7 +396,7 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) } /* parse: (|,|)[*=?!]*? SP+ */ - while (strbuf_getline(&sb, stdin, '\n') != EOF) { + while (strbuf_getline(&sb, stdin) != EOF) { const char *s; const char *help; struct option *o; @@ -505,6 +505,7 @@ N_("git rev-parse --parseopt [] -- [...]\n" int cmd_rev_parse(int argc, const char **argv, const char *prefix) { int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0; + int did_repo_setup = 0; int has_dashdash = 0; int output_prefix = 0; unsigned char sha1[20]; @@ -528,11 +529,40 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) } } - prefix = setup_git_directory(); - git_config(git_default_config, NULL); + /* No options; just report on whether we're in a git repo or not. */ + if (argc == 1) { + setup_git_directory(); + git_config(git_default_config, NULL); + return 0; + } + for (i = 1; i < argc; i++) { const char *arg = argv[i]; + if (!strcmp(arg, "--local-env-vars")) { + int i; + for (i = 0; local_repo_env[i]; i++) + printf("%s\n", local_repo_env[i]); + continue; + } + if (!strcmp(arg, "--resolve-git-dir")) { + const char *gitdir = argv[++i]; + if (!gitdir) + die("--resolve-git-dir requires an argument"); + gitdir = resolve_gitdir(gitdir); + if (!gitdir) + die("not a gitdir '%s'", argv[i]); + puts(gitdir); + continue; + } + + /* The rest of the options require a git repository. */ + if (!did_repo_setup) { + prefix = setup_git_directory(); + git_config(git_default_config, NULL); + did_repo_setup = 1; + } + if (!strcmp(arg, "--git-path")) { if (!argv[i + 1]) die("--git-path requires an argument"); @@ -706,12 +736,6 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) add_ref_exclusion(&ref_excludes, arg + 10); continue; } - if (!strcmp(arg, "--local-env-vars")) { - int i; - for (i = 0; local_repo_env[i]; i++) - printf("%s\n", local_repo_env[i]); - continue; - } if (!strcmp(arg, "--show-toplevel")) { const char *work_tree = get_git_work_tree(); if (work_tree) @@ -767,16 +791,6 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) puts(prefix_filename(pfx, strlen(pfx), get_git_common_dir())); continue; } - if (!strcmp(arg, "--resolve-git-dir")) { - const char *gitdir = argv[++i]; - if (!gitdir) - die("--resolve-git-dir requires an argument"); - gitdir = resolve_gitdir(gitdir); - if (!gitdir) - die("not a gitdir '%s'", argv[i]); - puts(gitdir); - continue; - } if (!strcmp(arg, "--is-inside-git-dir")) { printf("%s\n", is_inside_git_dir() ? "true" : "false"); diff --git a/builtin/rm.c b/builtin/rm.c index 8829b09d0b..be83c4347a 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -314,7 +314,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) list.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode); if (list.entry[list.nr++].is_submodule && !is_staging_gitmodules_ok()) - die (_("Please, stage your changes to .gitmodules or stash them to proceed")); + die (_("Please stage your changes to .gitmodules or stash them to proceed")); } if (pathspec.nr) { diff --git a/builtin/send-pack.c b/builtin/send-pack.c index f6e5d643c1..1ff5a67538 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -212,7 +212,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) argv_array_push(&all_refspecs, buf); } else { struct strbuf line = STRBUF_INIT; - while (strbuf_getline(&line, stdin, '\n') != EOF) + while (strbuf_getline(&line, stdin) != EOF) argv_array_push(&all_refspecs, line.buf); strbuf_release(&line); } @@ -225,7 +225,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) * --all and --mirror are incompatible; neither makes sense * with any refspecs. */ - if ((refspecs && (send_all || args.send_mirror)) || + if ((nr_refspecs > 0 && (send_all || args.send_mirror)) || (send_all && args.send_mirror)) usage_with_options(send_pack_usage, options); diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 35ebd17f80..bfc082e584 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -14,7 +14,26 @@ static char const * const shortlog_usage[] = { NULL }; -static int compare_by_number(const void *a1, const void *a2) +/* + * The util field of our string_list_items will contain one of two things: + * + * - if --summary is not in use, it will point to a string list of the + * oneline subjects assigned to this author + * + * - if --summary is in use, we don't need that list; we only need to know + * its size. So we abuse the pointer slot to store our integer counter. + * + * This macro accesses the latter. + */ +#define UTIL_TO_INT(x) ((intptr_t)(x)->util) + +static int compare_by_counter(const void *a1, const void *a2) +{ + const struct string_list_item *i1 = a1, *i2 = a2; + return UTIL_TO_INT(i2) - UTIL_TO_INT(i1); +} + +static int compare_by_list(const void *a1, const void *a2) { const struct string_list_item *i1 = a1, *i2 = a2; const struct string_list *l1 = i1->util, *l2 = i2->util; @@ -31,13 +50,9 @@ static void insert_one_record(struct shortlog *log, const char *author, const char *oneline) { - const char *dot3 = log->common_repo_prefix; - char *buffer, *p; struct string_list_item *item; const char *mailbuf, *namebuf; size_t namelen, maillen; - const char *eol; - struct strbuf subject = STRBUF_INIT; struct strbuf namemailbuf = STRBUF_INIT; struct ident_split ident; @@ -56,98 +71,95 @@ static void insert_one_record(struct shortlog *log, strbuf_addf(&namemailbuf, " <%.*s>", (int)maillen, mailbuf); item = string_list_insert(&log->list, namemailbuf.buf); - if (item->util == NULL) - item->util = xcalloc(1, sizeof(struct string_list)); - - /* Skip any leading whitespace, including any blank lines. */ - while (*oneline && isspace(*oneline)) - oneline++; - eol = strchr(oneline, '\n'); - if (!eol) - eol = oneline + strlen(oneline); - if (starts_with(oneline, "[PATCH")) { - char *eob = strchr(oneline, ']'); - if (eob && (!eol || eob < eol)) - oneline = eob + 1; - } - while (*oneline && isspace(*oneline) && *oneline != '\n') - oneline++; - format_subject(&subject, oneline, " "); - buffer = strbuf_detach(&subject, NULL); - - if (dot3) { - int dot3len = strlen(dot3); - if (dot3len > 5) { - while ((p = strstr(buffer, dot3)) != NULL) { - int taillen = strlen(p) - dot3len; - memcpy(p, "/.../", 5); - memmove(p + 5, p + dot3len, taillen + 1); + + if (log->summary) + item->util = (void *)(UTIL_TO_INT(item) + 1); + else { + const char *dot3 = log->common_repo_prefix; + char *buffer, *p; + struct strbuf subject = STRBUF_INIT; + const char *eol; + + /* Skip any leading whitespace, including any blank lines. */ + while (*oneline && isspace(*oneline)) + oneline++; + eol = strchr(oneline, '\n'); + if (!eol) + eol = oneline + strlen(oneline); + if (starts_with(oneline, "[PATCH")) { + char *eob = strchr(oneline, ']'); + if (eob && (!eol || eob < eol)) + oneline = eob + 1; + } + while (*oneline && isspace(*oneline) && *oneline != '\n') + oneline++; + format_subject(&subject, oneline, " "); + buffer = strbuf_detach(&subject, NULL); + + if (dot3) { + int dot3len = strlen(dot3); + if (dot3len > 5) { + while ((p = strstr(buffer, dot3)) != NULL) { + int taillen = strlen(p) - dot3len; + memcpy(p, "/.../", 5); + memmove(p + 5, p + dot3len, taillen + 1); + } } } - } - string_list_append(item->util, buffer); + if (item->util == NULL) + item->util = xcalloc(1, sizeof(struct string_list)); + string_list_append(item->util, buffer); + } } static void read_from_stdin(struct shortlog *log) { - char author[1024], oneline[1024]; + struct strbuf author = STRBUF_INIT; + struct strbuf oneline = STRBUF_INIT; - while (fgets(author, sizeof(author), stdin) != NULL) { - if (!(author[0] == 'A' || author[0] == 'a') || - !starts_with(author + 1, "uthor: ")) + while (strbuf_getline_lf(&author, stdin) != EOF) { + const char *v; + if (!skip_prefix(author.buf, "Author: ", &v) && + !skip_prefix(author.buf, "author ", &v)) continue; - while (fgets(oneline, sizeof(oneline), stdin) && - oneline[0] != '\n') + while (strbuf_getline_lf(&oneline, stdin) != EOF && + oneline.len) ; /* discard headers */ - while (fgets(oneline, sizeof(oneline), stdin) && - oneline[0] == '\n') + while (strbuf_getline_lf(&oneline, stdin) != EOF && + !oneline.len) ; /* discard blanks */ - insert_one_record(log, author + 8, oneline); + insert_one_record(log, v, oneline.buf); } + strbuf_release(&author); + strbuf_release(&oneline); } void shortlog_add_commit(struct shortlog *log, struct commit *commit) { - const char *author = NULL, *buffer; - struct strbuf buf = STRBUF_INIT; - struct strbuf ufbuf = STRBUF_INIT; - - pp_commit_easy(CMIT_FMT_RAW, commit, &buf); - buffer = buf.buf; - while (*buffer && *buffer != '\n') { - const char *eol = strchr(buffer, '\n'); - - if (eol == NULL) - eol = buffer + strlen(buffer); + struct strbuf author = STRBUF_INIT; + struct strbuf oneline = STRBUF_INIT; + struct pretty_print_context ctx = {0}; + + ctx.fmt = CMIT_FMT_USERFORMAT; + ctx.abbrev = log->abbrev; + ctx.subject = ""; + ctx.after_subject = ""; + ctx.date_mode.type = DATE_NORMAL; + ctx.output_encoding = get_log_output_encoding(); + + format_commit_message(commit, "%an <%ae>", &author, &ctx); + if (!log->summary) { + if (log->user_format) + pretty_print_commit(&ctx, commit, &oneline); else - eol++; - - if (starts_with(buffer, "author ")) - author = buffer + 7; - buffer = eol; - } - if (!author) { - warning(_("Missing author: %s"), - oid_to_hex(&commit->object.oid)); - return; + format_commit_message(commit, "%s", &oneline, &ctx); } - if (log->user_format) { - struct pretty_print_context ctx = {0}; - ctx.fmt = CMIT_FMT_USERFORMAT; - ctx.abbrev = log->abbrev; - ctx.subject = ""; - ctx.after_subject = ""; - ctx.date_mode.type = DATE_NORMAL; - ctx.output_encoding = get_log_output_encoding(); - pretty_print_commit(&ctx, commit, &ufbuf); - buffer = ufbuf.buf; - } else if (*buffer) { - buffer++; - } - insert_one_record(log, author, !*buffer ? "" : buffer); - strbuf_release(&ufbuf); - strbuf_release(&buf); + + insert_one_record(log, author.buf, oneline.len ? oneline.buf : ""); + + strbuf_release(&author); + strbuf_release(&oneline); } static void get_from_rev(struct rev_info *rev, struct shortlog *log) @@ -294,14 +306,14 @@ void shortlog_output(struct shortlog *log) if (log->sort_by_number) qsort(log->list.items, log->list.nr, sizeof(struct string_list_item), - compare_by_number); + log->summary ? compare_by_counter : compare_by_list); for (i = 0; i < log->list.nr; i++) { - struct string_list *onelines = log->list.items[i].util; - + const struct string_list_item *item = &log->list.items[i]; if (log->summary) { - printf("%6d\t%s\n", onelines->nr, log->list.items[i].string); + printf("%6d\t%s\n", (int)UTIL_TO_INT(item), item->string); } else { - printf("%s (%d):\n", log->list.items[i].string, onelines->nr); + struct string_list *onelines = item->util; + printf("%s (%d):\n", item->string, onelines->nr); for (j = onelines->nr - 1; j >= 0; j--) { const char *msg = onelines->items[j].string; @@ -314,11 +326,11 @@ void shortlog_output(struct shortlog *log) printf(" %s\n", msg); } putchar('\n'); + onelines->strdup_strings = 1; + string_list_clear(onelines, 0); + free(onelines); } - onelines->strdup_strings = 1; - string_list_clear(onelines, 0); - free(onelines); log->list.items[i].util = NULL; } diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index ed764c9f0e..3bea3aaa50 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -37,9 +37,9 @@ static int module_list_compute(int argc, const char **argv, for (i = 0; i < active_nr; i++) { const struct cache_entry *ce = active_cache[i]; - if (!S_ISGITLINK(ce->ce_mode) || - !match_pathspec(pathspec, ce->name, ce_namelen(ce), - 0, ps_matched, 1)) + if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), + 0, ps_matched, 1) || + !S_ISGITLINK(ce->ce_mode)) continue; ALLOC_GROW(list->entries, list->nr + 1, list->alloc); @@ -147,11 +147,11 @@ static int clone_submodule(const char *path, const char *gitdir, const char *url static int module_clone(int argc, const char **argv, const char *prefix) { - const char *path = NULL, *name = NULL, *url = NULL; + const char *name = NULL, *url = NULL; const char *reference = NULL, *depth = NULL; int quiet = 0; FILE *submodule_dot_git; - char *sm_gitdir, *cwd, *p; + char *p, *path = NULL, *sm_gitdir; struct strbuf rel_path = STRBUF_INIT; struct strbuf sb = STRBUF_INIT; @@ -188,8 +188,18 @@ static int module_clone(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, module_clone_options, git_submodule_helper_usage, 0); + if (!path || !*path) + die(_("submodule--helper: unspecified or empty --path")); + strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name); - sm_gitdir = strbuf_detach(&sb, NULL); + sm_gitdir = xstrdup(absolute_path(sb.buf)); + strbuf_reset(&sb); + + if (!is_absolute_path(path)) { + strbuf_addf(&sb, "%s/%s", get_git_work_tree(), path); + path = strbuf_detach(&sb, NULL); + } else + path = xstrdup(path); if (!file_exists(sm_gitdir)) { if (safe_create_leading_directories_const(sm_gitdir) < 0) @@ -206,45 +216,30 @@ static int module_clone(int argc, const char **argv, const char *prefix) } /* Write a .git file in the submodule to redirect to the superproject. */ - if (safe_create_leading_directories_const(path) < 0) - die(_("could not create directory '%s'"), path); - - if (path && *path) - strbuf_addf(&sb, "%s/.git", path); - else - strbuf_addstr(&sb, ".git"); - + strbuf_addf(&sb, "%s/.git", path); if (safe_create_leading_directories_const(sb.buf) < 0) die(_("could not create leading directories of '%s'"), sb.buf); submodule_dot_git = fopen(sb.buf, "w"); if (!submodule_dot_git) die_errno(_("cannot open file '%s'"), sb.buf); - fprintf(submodule_dot_git, "gitdir: %s\n", - relative_path(sm_gitdir, path, &rel_path)); + fprintf_or_die(submodule_dot_git, "gitdir: %s\n", + relative_path(sm_gitdir, path, &rel_path)); if (fclose(submodule_dot_git)) die(_("could not close file %s"), sb.buf); strbuf_reset(&sb); strbuf_reset(&rel_path); - cwd = xgetcwd(); /* Redirect the worktree of the submodule in the superproject's config */ - if (!is_absolute_path(sm_gitdir)) { - strbuf_addf(&sb, "%s/%s", cwd, sm_gitdir); - free(sm_gitdir); - sm_gitdir = strbuf_detach(&sb, NULL); - } - - strbuf_addf(&sb, "%s/%s", cwd, path); p = git_pathdup_submodule(path, "config"); if (!p) die(_("could not get submodule directory for '%s'"), path); git_config_set_in_file(p, "core.worktree", - relative_path(sb.buf, sm_gitdir, &rel_path)); + relative_path(path, sm_gitdir, &rel_path)); strbuf_release(&sb); strbuf_release(&rel_path); free(sm_gitdir); - free(cwd); + free(path); free(p); return 0; } diff --git a/builtin/update-index.c b/builtin/update-index.c index 7431938fa6..1c94ca59bf 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -35,6 +35,15 @@ static int mark_skip_worktree_only; #define UNMARK_FLAG 2 static struct strbuf mtime_dir = STRBUF_INIT; +/* Untracked cache mode */ +enum uc_mode { + UC_UNSPECIFIED = -1, + UC_DISABLE = 0, + UC_ENABLE, + UC_TEST, + UC_FORCE +}; + __attribute__((format (printf, 1, 2))) static void report(const char *fmt, ...) { @@ -121,7 +130,7 @@ static int test_if_untracked_cache_is_supported(void) if (!mkdtemp(mtime_dir.buf)) die_errno("Could not make temporary directory"); - fprintf(stderr, _("Testing ")); + fprintf(stderr, _("Testing mtime in '%s' "), xgetcwd()); atexit(remove_test_directory); xstat_mtime_dir(&st); fill_stat_data(&base, &st); @@ -468,12 +477,14 @@ static void update_one(const char *path) report("add '%s'", path); } -static void read_index_info(int line_termination) +static void read_index_info(int nul_term_line) { struct strbuf buf = STRBUF_INIT; struct strbuf uq = STRBUF_INIT; + strbuf_getline_fn getline_fn; - while (strbuf_getline(&buf, stdin, line_termination) != EOF) { + getline_fn = nul_term_line ? strbuf_getline_nul : strbuf_getline_lf; + while (getline_fn(&buf, stdin) != EOF) { char *ptr, *tab; char *path_name; unsigned char sha1[20]; @@ -522,7 +533,7 @@ static void read_index_info(int line_termination) goto bad_line; path_name = ptr; - if (line_termination && path_name[0] == '"') { + if (!nul_term_line && path_name[0] == '"') { strbuf_reset(&uq); if (unquote_c_style(&uq, path_name, NULL)) { die("git update-index: bad quoting of path name"); @@ -844,12 +855,12 @@ static int cacheinfo_callback(struct parse_opt_ctx_t *ctx, static int stdin_cacheinfo_callback(struct parse_opt_ctx_t *ctx, const struct option *opt, int unset) { - int *line_termination = opt->value; + int *nul_term_line = opt->value; if (ctx->argc != 1) return error("option '%s' must be the last argument", opt->long_name); allow_add = allow_replace = allow_remove = 1; - read_index_info(*line_termination); + read_index_info(*nul_term_line); return 0; } @@ -901,8 +912,8 @@ static int reupdate_callback(struct parse_opt_ctx_t *ctx, int cmd_update_index(int argc, const char **argv, const char *prefix) { - int newfd, entries, has_errors = 0, line_termination = '\n'; - int untracked_cache = -1; + int newfd, entries, has_errors = 0, nul_term_line = 0; + enum uc_mode untracked_cache = UC_UNSPECIFIED; int read_from_stdin = 0; int prefix_length = prefix ? strlen(prefix) : 0; int preferred_index_format = 0; @@ -912,6 +923,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) int split_index = -1; struct lock_file *lock_file; struct parse_opt_ctx_t ctx; + strbuf_getline_fn getline_fn; int parseopt_state = PARSE_OPT_UNKNOWN; struct option options[] = { OPT_BIT('q', NULL, &refresh_args.flags, @@ -963,13 +975,13 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) N_("add to index only; do not add content to object database"), 1), OPT_SET_INT(0, "force-remove", &force_remove, N_("remove named paths even if present in worktree"), 1), - OPT_SET_INT('z', NULL, &line_termination, - N_("with --stdin: input lines are terminated by null bytes"), '\0'), + OPT_BOOL('z', NULL, &nul_term_line, + N_("with --stdin: input lines are terminated by null bytes")), {OPTION_LOWLEVEL_CALLBACK, 0, "stdin", &read_from_stdin, NULL, N_("read list of paths to be updated from standard input"), PARSE_OPT_NONEG | PARSE_OPT_NOARG, (parse_opt_cb *) stdin_callback}, - {OPTION_LOWLEVEL_CALLBACK, 0, "index-info", &line_termination, NULL, + {OPTION_LOWLEVEL_CALLBACK, 0, "index-info", &nul_term_line, NULL, N_("add entries from standard input to the index"), PARSE_OPT_NONEG | PARSE_OPT_NOARG, (parse_opt_cb *) stdin_cacheinfo_callback}, @@ -996,8 +1008,10 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) N_("enable or disable split index")), OPT_BOOL(0, "untracked-cache", &untracked_cache, N_("enable/disable untracked cache")), + OPT_SET_INT(0, "test-untracked-cache", &untracked_cache, + N_("test if the filesystem supports untracked cache"), UC_TEST), OPT_SET_INT(0, "force-untracked-cache", &untracked_cache, - N_("enable untracked cache without testing the filesystem"), 2), + N_("enable untracked cache without testing the filesystem"), UC_FORCE), OPT_END() }; @@ -1057,6 +1071,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) } } argc = parse_options_end(&ctx); + + getline_fn = nul_term_line ? strbuf_getline_nul : strbuf_getline_lf; if (preferred_index_format) { if (preferred_index_format < INDEX_FORMAT_LB || INDEX_FORMAT_UB < preferred_index_format) @@ -1070,16 +1086,17 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) } if (read_from_stdin) { - struct strbuf buf = STRBUF_INIT, nbuf = STRBUF_INIT; + struct strbuf buf = STRBUF_INIT; + struct strbuf unquoted = STRBUF_INIT; setup_work_tree(); - while (strbuf_getline(&buf, stdin, line_termination) != EOF) { + while (getline_fn(&buf, stdin) != EOF) { char *p; - if (line_termination && buf.buf[0] == '"') { - strbuf_reset(&nbuf); - if (unquote_c_style(&nbuf, buf.buf, NULL)) + if (!nul_term_line && buf.buf[0] == '"') { + strbuf_reset(&unquoted); + if (unquote_c_style(&unquoted, buf.buf, NULL)) die("line is badly quoted"); - strbuf_swap(&buf, &nbuf); + strbuf_swap(&buf, &unquoted); } p = prefix_path(prefix, prefix_length, buf.buf); update_one(p); @@ -1087,7 +1104,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) chmod_path(set_executable_bit, p); free(p); } - strbuf_release(&nbuf); + strbuf_release(&unquoted); strbuf_release(&buf); } @@ -1104,27 +1121,32 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) the_index.split_index = NULL; the_index.cache_changed |= SOMETHING_CHANGED; } - if (untracked_cache > 0) { - struct untracked_cache *uc; - if (untracked_cache < 2) { - setup_work_tree(); - if (!test_if_untracked_cache_is_supported()) - return 1; - } - if (!the_index.untracked) { - uc = xcalloc(1, sizeof(*uc)); - strbuf_init(&uc->ident, 100); - uc->exclude_per_dir = ".gitignore"; - /* should be the same flags used by git-status */ - uc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES; - the_index.untracked = uc; - } - add_untracked_ident(the_index.untracked); - the_index.cache_changed |= UNTRACKED_CHANGED; - } else if (!untracked_cache && the_index.untracked) { - the_index.untracked = NULL; - the_index.cache_changed |= UNTRACKED_CHANGED; + switch (untracked_cache) { + case UC_UNSPECIFIED: + break; + case UC_DISABLE: + if (git_config_get_untracked_cache() == 1) + warning("core.untrackedCache is set to true; " + "remove or change it, if you really want to " + "disable the untracked cache"); + remove_untracked_cache(&the_index); + report(_("Untracked cache disabled")); + break; + case UC_TEST: + setup_work_tree(); + return !test_if_untracked_cache_is_supported(); + case UC_ENABLE: + case UC_FORCE: + if (git_config_get_untracked_cache() == 0) + warning("core.untrackedCache is set to false; " + "remove or change it, if you really want to " + "enable the untracked cache"); + add_untracked_cache(&the_index); + report(_("Untracked cache enabled for '%s'"), get_git_work_tree()); + break; + default: + die("Bug: bad untracked_cache value: %d", untracked_cache); } if (active_cache_changed) { diff --git a/builtin/worktree.c b/builtin/worktree.c index 0a45710be8..38b56096bd 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -201,9 +201,7 @@ static int add_worktree(const char *path, const char *refname, die(_("'%s' already exists"), path); /* is 'refname' a branch or commit? */ - if (opts->force_new_branch) /* definitely a branch */ - ; - else if (!opts->detach && !strbuf_check_branch_ref(&symref, refname) && + if (!opts->detach && !strbuf_check_branch_ref(&symref, refname) && ref_exists(symref.buf)) { /* it's a branch */ if (!opts->force) die_if_checked_out(symref.buf); @@ -336,9 +334,18 @@ static int add(int ac, const char **av, const char *prefix) branch = ac < 2 ? "HEAD" : av[1]; opts.force_new_branch = !!new_branch_force; - if (opts.force_new_branch) + if (opts.force_new_branch) { + struct strbuf symref = STRBUF_INIT; + opts.new_branch = new_branch_force; + if (!opts.force && + !strbuf_check_branch_ref(&symref, opts.new_branch) && + ref_exists(symref.buf)) + die_if_checked_out(symref.buf); + strbuf_release(&symref); + } + if (ac < 2 && !opts.new_branch && !opts.detach) { int n; const char *s = worktree_basename(path, &n); diff --git a/bundle.c b/bundle.c index 506ac49691..bbf4efa0a0 100644 --- a/bundle.c +++ b/bundle.c @@ -435,12 +435,14 @@ int create_bundle(struct bundle_header *header, const char *path, /* write prerequisites */ if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv)) - return -1; + goto err; argc = setup_revisions(argc, argv, &revs, NULL); - if (argc > 1) - return error(_("unrecognized argument: %s"), argv[1]); + if (argc > 1) { + error(_("unrecognized argument: %s"), argv[1]); + goto err; + } object_array_remove_duplicates(&revs.pending); @@ -448,17 +450,26 @@ int create_bundle(struct bundle_header *header, const char *path, if (!ref_count) die(_("Refusing to create empty bundle.")); else if (ref_count < 0) - return -1; + goto err; /* write pack */ - if (write_pack_data(bundle_fd, &revs)) - return -1; + if (write_pack_data(bundle_fd, &revs)) { + bundle_fd = -1; /* already closed by the above call */ + goto err; + } if (!bundle_to_stdout) { if (commit_lock_file(&lock)) die_errno(_("cannot create '%s'"), path); } return 0; +err: + if (!bundle_to_stdout) { + if (0 <= bundle_fd) + close(bundle_fd); + rollback_lock_file(&lock); + } + return -1; } int unbundle(struct bundle_header *header, int bundle_fd, int flags) diff --git a/cache.h b/cache.h index b9fc3a8e33..924354f664 100644 --- a/cache.h +++ b/cache.h @@ -9,6 +9,7 @@ #include "convert.h" #include "trace.h" #include "string-list.h" +#include "pack-revindex.h" #include SHA1_HEADER #ifndef platform_SHA_CTX @@ -650,7 +651,6 @@ extern int prefer_symlink_refs; extern int log_all_ref_updates; extern int warn_ambiguous_refs; extern int warn_on_object_refname_ambiguity; -extern int shared_repository; extern const char *apply_default_whitespace; extern const char *apply_default_ignorewhitespace; extern const char *git_attributes_file; @@ -663,6 +663,9 @@ extern size_t delta_base_cache_limit; extern unsigned long big_file_threshold; extern unsigned long pack_size_limit_cfg; +void set_shared_repository(int value); +int get_shared_repository(void); + /* * Do replace refs need to be checked this run? This variable is * initialized to true unless --no-replace-object is used or @@ -697,6 +700,14 @@ extern int ref_paranoia; extern char comment_line_char; extern int auto_comment_line_char; +/* Windows only */ +enum hide_dotfiles_type { + HIDE_DOTFILES_FALSE = 0, + HIDE_DOTFILES_TRUE, + HIDE_DOTFILES_DOTGITONLY +}; +extern enum hide_dotfiles_type hide_dotfiles; + enum branch_track { BRANCH_TRACK_UNSPECIFIED = -1, BRANCH_TRACK_NEVER = 0, @@ -744,9 +755,39 @@ extern int grafts_replace_parents; */ #define GIT_REPO_VERSION 0 #define GIT_REPO_VERSION_READ 1 -extern int repository_format_version; extern int repository_format_precious_objects; -extern int check_repository_format(void); + +struct repository_format { + int version; + int precious_objects; + int is_bare; + char *work_tree; + struct string_list unknown_extensions; +}; + +/* + * Read the repository format characteristics from the config file "path" into + * "format" struct. Returns the numeric version. On error, -1 is returned, + * format->version is set to -1, and all other fields in the struct are + * undefined. + */ +int read_repository_format(struct repository_format *format, const char *path); + +/* + * Verify that the repository described by repository_format is something we + * can read. If it is, return 0. Otherwise, return -1, and "err" will describe + * any errors encountered. + */ +int verify_repository_format(const struct repository_format *format, + struct strbuf *err); + +/* + * Check the repository format version in the path found in get_git_dir(), + * and die if it is a version we don't understand. Generally one would + * set_git_dir() before calling this, and use it only for "are we in a valid + * repo?". + */ +extern void check_repository_format(void); #define MTIME_CHANGED 0x0001 #define CTIME_CHANGED 0x0002 @@ -925,8 +966,6 @@ static inline int is_empty_blob_sha1(const unsigned char *sha1) int git_mkstemp(char *path, size_t n, const char *template); -int git_mkstemps(char *path, size_t n, const char *template, int suffix_len); - /* set default permissions by passing mode arguments to open(2) */ int git_mkstemps_mode(char *pattern, int suffix_len, int mode); int git_mkstemp_mode(char *pattern, int mode); @@ -1328,6 +1367,7 @@ extern struct packed_git { freshened:1, do_not_close:1; unsigned char sha1[20]; + struct revindex_entry *revindex; /* something like ".git/objects/pack/xxxxx.pack" */ char pack_name[FLEX_ARRAY]; /* more */ } *packed_git; @@ -1524,15 +1564,14 @@ struct git_config_source { typedef int (*config_fn_t)(const char *, const char *, void *); extern int git_default_config(const char *, const char *, void *); extern int git_config_from_file(config_fn_t fn, const char *, void *); -extern int git_config_from_buf(config_fn_t fn, const char *name, - const char *buf, size_t len, void *data); +extern int git_config_from_mem(config_fn_t fn, const char *origin_type, + const char *name, const char *buf, size_t len, void *data); extern void git_config_push_parameter(const char *text); extern int git_config_from_parameters(config_fn_t fn, void *data); extern void git_config(config_fn_t fn, void *); extern int git_config_with_options(config_fn_t fn, void *, struct git_config_source *config_source, int respect_includes); -extern int git_config_early(config_fn_t fn, void *, const char *repo_config); extern int git_parse_ulong(const char *, unsigned long *); extern int git_parse_maybe_bool(const char *); extern int git_config_int(const char *, const char *); @@ -1556,7 +1595,6 @@ extern void git_config_set_multivar_in_file(const char *, const char *, const ch extern int git_config_rename_section(const char *, const char *); extern int git_config_rename_section_in_file(const char *, const char *, const char *); extern const char *git_etc_gitconfig(void); -extern int check_repository_format_version(const char *var, const char *value, void *cb); extern int git_env_bool(const char *, int); extern unsigned long git_env_ulong(const char *, unsigned long); extern int git_config_system(void); @@ -1568,6 +1606,8 @@ extern const char *get_log_output_encoding(void); extern const char *get_commit_output_encoding(void); extern int git_config_parse_parameter(const char *, config_fn_t fn, void *data); +extern const char *current_config_origin_type(void); +extern const char *current_config_name(void); struct config_include_data { int depth; @@ -1646,6 +1686,14 @@ extern int git_config_get_bool(const char *key, int *dest); extern int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest); extern int git_config_get_maybe_bool(const char *key, int *dest); extern int git_config_get_pathname(const char *key, const char **dest); +extern int git_config_get_untracked_cache(void); + +/* + * This is a hack for test programs like test-dump-untracked-cache to + * ensure that they do not modify the untracked cache when reading it. + * Do not use it otherwise! + */ +extern int ignore_untracked_cache_config; struct key_value_info { const char *filename; @@ -1767,7 +1815,7 @@ int split_cmdline(char *cmdline, const char ***argv); /* Takes a negative value returned by split_cmdline */ const char *split_cmdline_strerror(int cmdline_errno); -/* git.c */ +/* setup.c */ struct startup_info { int have_repository; const char *prefix; diff --git a/ci/test-documentation.sh b/ci/test-documentation.sh new file mode 100755 index 0000000000..579d540d32 --- /dev/null +++ b/ci/test-documentation.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# +# Perform sanity checks on documentation and build it. +# + +set -e + +make check-builtins +make check-docs +make doc + +test -s Documentation/git.html +test -s Documentation/git.xml +test -s Documentation/git.1 diff --git a/compat/apple-common-crypto.h b/compat/apple-common-crypto.h index d3fb264181..11727f3e1e 100644 --- a/compat/apple-common-crypto.h +++ b/compat/apple-common-crypto.h @@ -3,12 +3,18 @@ #define HEADER_HMAC_H #define HEADER_SHA_H #include -#define HMAC_CTX CCHmacContext -#define HMAC_Init(hmac, key, len, algo) CCHmacInit(hmac, algo, key, len) -#define HMAC_Update CCHmacUpdate -#define HMAC_Final(hmac, hash, ptr) CCHmacFinal(hmac, hash) -#define HMAC_CTX_cleanup(ignore) #define EVP_md5(...) kCCHmacAlgMD5 +/* CCHmac doesn't take md_len and the return type is void */ +#define HMAC git_CC_HMAC +static inline unsigned char *git_CC_HMAC(CCHmacAlgorithm alg, + const void *key, int key_len, + const unsigned char *data, size_t data_len, + unsigned char *md, unsigned int *md_len) +{ + CCHmac(alg, key, key_len, data, data_len, md); + return md; +} + #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 #define APPLE_LION_OR_NEWER #include diff --git a/compat/mingw.c b/compat/mingw.c index af56c1fe61..a8218e6f0f 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -6,6 +6,8 @@ #include "../run-command.h" #include "../cache.h" +#define HCAST(type, handle) ((type)(intptr_t)handle) + static const int delay[] = { 0, 1, 10, 20, 40 }; int err_win_to_posix(DWORD winerr) @@ -284,6 +286,49 @@ int mingw_rmdir(const char *pathname) return ret; } +static inline int needs_hiding(const char *path) +{ + const char *basename; + + if (hide_dotfiles == HIDE_DOTFILES_FALSE) + return 0; + + /* We cannot use basename(), as it would remove trailing slashes */ + mingw_skip_dos_drive_prefix((char **)&path); + if (!*path) + return 0; + + for (basename = path; *path; path++) + if (is_dir_sep(*path)) { + do { + path++; + } while (is_dir_sep(*path)); + /* ignore trailing slashes */ + if (*path) + basename = path; + } + + if (hide_dotfiles == HIDE_DOTFILES_TRUE) + return *basename == '.'; + + assert(hide_dotfiles == HIDE_DOTFILES_DOTGITONLY); + return !strncasecmp(".git", basename, 4) && + (!basename[4] || is_dir_sep(basename[4])); +} + +static int set_hidden_flag(const wchar_t *path, int set) +{ + DWORD original = GetFileAttributesW(path), modified; + if (set) + modified = original | FILE_ATTRIBUTE_HIDDEN; + else + modified = original & ~FILE_ATTRIBUTE_HIDDEN; + if (original == modified || SetFileAttributesW(path, modified)) + return 0; + errno = err_win_to_posix(GetLastError()); + return -1; +} + int mingw_mkdir(const char *path, int mode) { int ret; @@ -291,6 +336,8 @@ int mingw_mkdir(const char *path, int mode) if (xutftowcs_path(wpath, path) < 0) return -1; ret = _wmkdir(wpath); + if (!ret && needs_hiding(path)) + return set_hidden_flag(wpath, 1); return ret; } @@ -317,6 +364,21 @@ int mingw_open (const char *filename, int oflags, ...) if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) errno = EISDIR; } + if ((oflags & O_CREAT) && needs_hiding(filename)) { + /* + * Internally, _wopen() uses the CreateFile() API which errors + * out with an ERROR_ACCESS_DENIED if CREATE_ALWAYS was + * specified and an already existing file's attributes do not + * match *exactly*. As there is no mode or flag we can set that + * would correspond to FILE_ATTRIBUTE_HIDDEN, let's just try + * again *without* the O_CREAT flag (that corresponds to the + * CREATE_ALWAYS flag of CreateFile()). + */ + if (fd < 0 && errno == EACCES) + fd = _wopen(wfilename, oflags & ~O_CREAT, mode); + if (fd >= 0 && set_hidden_flag(wfilename, 1)) + warning("could not mark '%s' as hidden.", filename); + } return fd; } @@ -348,6 +410,7 @@ int mingw_fgetc(FILE *stream) #undef fopen FILE *mingw_fopen (const char *filename, const char *otype) { + int hide = needs_hiding(filename); FILE *file; wchar_t wfilename[MAX_PATH], wotype[4]; if (filename && !strcmp(filename, "/dev/null")) @@ -355,12 +418,19 @@ FILE *mingw_fopen (const char *filename, const char *otype) if (xutftowcs_path(wfilename, filename) < 0 || xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0) return NULL; + if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) { + error("could not unhide %s", filename); + return NULL; + } file = _wfopen(wfilename, wotype); + if (file && hide && set_hidden_flag(wfilename, 1)) + warning("could not mark '%s' as hidden.", filename); return file; } FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream) { + int hide = needs_hiding(filename); FILE *file; wchar_t wfilename[MAX_PATH], wotype[4]; if (filename && !strcmp(filename, "/dev/null")) @@ -368,7 +438,13 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream) if (xutftowcs_path(wfilename, filename) < 0 || xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0) return NULL; + if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) { + error("could not unhide %s", filename); + return NULL; + } file = _wfreopen(wfilename, wotype, stream); + if (file && hide && set_hidden_flag(wfilename, 1)) + warning("could not mark '%s' as hidden.", filename); return file; } @@ -452,6 +528,39 @@ static inline time_t filetime_to_time_t(const FILETIME *ft) return (time_t)(filetime_to_hnsec(ft) / 10000000); } +/** + * Verifies that safe_create_leading_directories() would succeed. + */ +static int has_valid_directory_prefix(wchar_t *wfilename) +{ + int n = wcslen(wfilename); + + while (n > 0) { + wchar_t c = wfilename[--n]; + DWORD attributes; + + if (!is_dir_sep(c)) + continue; + + wfilename[n] = L'\0'; + attributes = GetFileAttributesW(wfilename); + wfilename[n] = c; + if (attributes == FILE_ATTRIBUTE_DIRECTORY || + attributes == FILE_ATTRIBUTE_DEVICE) + return 1; + if (attributes == INVALID_FILE_ATTRIBUTES) + switch (GetLastError()) { + case ERROR_PATH_NOT_FOUND: + continue; + case ERROR_FILE_NOT_FOUND: + /* This implies parent directory exists. */ + return 1; + } + return 0; + } + return 1; +} + /* We keep the do_lstat code in a separate function to avoid recursion. * When a path ends with a slash, the stat will fail with ENOENT. In * this case, we strip the trailing slashes and stat again. @@ -512,6 +621,12 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf) case ERROR_NOT_ENOUGH_MEMORY: errno = ENOMEM; break; + case ERROR_PATH_NOT_FOUND: + if (!has_valid_directory_prefix(wfilename)) { + errno = ENOTDIR; + break; + } + /* fallthru */ default: errno = ENOENT; break; @@ -691,13 +806,13 @@ int pipe(int filedes[2]) errno = err_win_to_posix(GetLastError()); return -1; } - filedes[0] = _open_osfhandle((int)h[0], O_NOINHERIT); + filedes[0] = _open_osfhandle(HCAST(int, h[0]), O_NOINHERIT); if (filedes[0] < 0) { CloseHandle(h[0]); CloseHandle(h[1]); return -1; } - filedes[1] = _open_osfhandle((int)h[1], O_NOINHERIT); + filedes[1] = _open_osfhandle(HCAST(int, h[1]), O_NOINHERIT); if (filedes[1] < 0) { close(filedes[0]); CloseHandle(h[1]); @@ -722,15 +837,12 @@ struct tm *localtime_r(const time_t *timep, struct tm *result) char *mingw_getcwd(char *pointer, int len) { - int i; wchar_t wpointer[MAX_PATH]; if (!_wgetcwd(wpointer, ARRAY_SIZE(wpointer))) return NULL; if (xwcstoutf(pointer, wpointer, len) < 0) return NULL; - for (i = 0; pointer[i]; i++) - if (pointer[i] == '\\') - pointer[i] = '/'; + convert_slashes(pointer); return pointer; } @@ -1601,7 +1713,12 @@ int mingw_rename(const char *pold, const char *pnew) if (gle == ERROR_ACCESS_DENIED && (attrs = GetFileAttributesW(wpnew)) != INVALID_FILE_ATTRIBUTES) { if (attrs & FILE_ATTRIBUTE_DIRECTORY) { - errno = EISDIR; + DWORD attrsold = GetFileAttributesW(wpold); + if (attrsold == INVALID_FILE_ATTRIBUTES || + !(attrsold & FILE_ATTRIBUTE_DIRECTORY)) + errno = EISDIR; + else if (!_wrmdir(wpnew)) + goto repeat; return -1; } if ((attrs & FILE_ATTRIBUTE_READONLY) && @@ -1846,7 +1963,8 @@ void mingw_open_html(const char *unixpath) die("cannot run browser"); printf("Launching default browser to display HTML ...\n"); - r = (int)ShellExecute(NULL, "open", htmlpath, NULL, "\\", SW_SHOWNORMAL); + r = HCAST(int, ShellExecute(NULL, "open", htmlpath, + NULL, "\\", SW_SHOWNORMAL)); FreeLibrary(shell32); /* see the MSDN documentation referring to the result codes here */ if (r <= 32) { @@ -2044,6 +2162,35 @@ int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen) return -1; } +static void setup_windows_environment() +{ + char *tmp = getenv("TMPDIR"); + + /* on Windows it is TMP and TEMP */ + if (!tmp) { + if (!(tmp = getenv("TMP"))) + tmp = getenv("TEMP"); + if (tmp) { + setenv("TMPDIR", tmp, 1); + tmp = getenv("TMPDIR"); + } + } + + if (tmp) { + /* + * Convert all dir separators to forward slashes, + * to help shell commands called from the Git + * executable (by not mistaking the dir separators + * for escape characters). + */ + convert_slashes(tmp); + } + + /* simulate TERM to enable auto-color (see color.c) */ + if (!getenv("TERM")) + setenv("TERM", "cygwin", 1); +} + /* * Disable MSVCRT command line wildcard expansion (__getmainargs called from * mingw startup code, see init.c in mingw runtime). @@ -2122,19 +2269,7 @@ void mingw_startup() qsort(environ, i, sizeof(char*), compareenv); /* fix Windows specific environment settings */ - - /* on Windows it is TMP and TEMP */ - if (!mingw_getenv("TMPDIR")) { - const char *tmp = mingw_getenv("TMP"); - if (!tmp) - tmp = mingw_getenv("TEMP"); - if (tmp) - setenv("TMPDIR", tmp, 1); - } - - /* simulate TERM to enable auto-color (see color.c) */ - if (!getenv("TERM")) - setenv("TERM", "cygwin", 1); + setup_windows_environment(); /* initialize critical section for waitpid pinfo_t list */ InitializeCriticalSection(&pinfo_cs); diff --git a/compat/mingw.h b/compat/mingw.h index a5fb52f977..69bb43dc35 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -1,27 +1,43 @@ +#ifdef __MINGW64_VERSION_MAJOR +#include +#include +typedef _sigset_t sigset_t; +#endif #include #include +/* MinGW-w64 reports to have flockfile, but it does not actually have it. */ +#ifdef __MINGW64_VERSION_MAJOR +#undef _POSIX_THREAD_SAFE_FUNCTIONS +#endif + /* * things that are not available in header files */ -typedef int pid_t; typedef int uid_t; typedef int socklen_t; +#ifndef __MINGW64_VERSION_MAJOR +typedef int pid_t; #define hstrerror strerror +#endif #define S_IFLNK 0120000 /* Symbolic link */ #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK) #define S_ISSOCK(x) 0 +#ifndef S_IRWXG #define S_IRGRP 0 #define S_IWGRP 0 #define S_IXGRP 0 #define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +#endif +#ifndef S_IRWXO #define S_IROTH 0 #define S_IWOTH 0 #define S_IXOTH 0 #define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +#endif #define S_ISUID 0004000 #define S_ISGID 0002000 @@ -100,8 +116,10 @@ static inline int symlink(const char *oldpath, const char *newpath) { errno = ENOSYS; return -1; } static inline int fchmod(int fildes, mode_t mode) { errno = ENOSYS; return -1; } +#ifndef __MINGW64_VERSION_MAJOR static inline pid_t fork(void) { errno = ENOSYS; return -1; } +#endif static inline unsigned int alarm(unsigned int seconds) { return 0; } static inline int fsync(int fd) @@ -124,6 +142,7 @@ static inline int fcntl(int fd, int cmd, ...) #define sigemptyset(x) (void)0 static inline int sigaddset(sigset_t *set, int signum) { return 0; } +#define SIG_BLOCK 0 #define SIG_UNBLOCK 0 static inline int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) { return 0; } @@ -176,8 +195,10 @@ int pipe(int filedes[2]); unsigned int sleep (unsigned int seconds); int mkstemp(char *template); int gettimeofday(struct timeval *tv, void *tz); +#ifndef __MINGW64_VERSION_MAJOR struct tm *gmtime_r(const time_t *timep, struct tm *result); struct tm *localtime_r(const time_t *timep, struct tm *result); +#endif int getpagesize(void); /* defined in MinGW's libgcc.a */ struct passwd *getpwuid(uid_t uid); int setitimer(int type, struct itimerval *in, struct itimerval *out); @@ -301,8 +322,10 @@ static inline int getrlimit(int resource, struct rlimit *rlp) /* * Use mingw specific stat()/lstat()/fstat() implementations on Windows. */ +#ifndef __MINGW64_VERSION_MAJOR #define off_t off64_t #define lseek _lseeki64 +#endif /* use struct stat with 64 bit st_size */ #ifdef stat @@ -374,19 +397,26 @@ static inline char *mingw_find_last_dir_sep(const char *path) ret = (char *)path; return ret; } +static inline void convert_slashes(char *path) +{ + for (; *path; path++) + if (*path == '\\') + *path = '/'; +} #define find_last_dir_sep mingw_find_last_dir_sep int mingw_offset_1st_component(const char *path); #define offset_1st_component mingw_offset_1st_component #define PATH_SEP ';' +#if !defined(__MINGW64_VERSION_MAJOR) && (!defined(_MSC_VER) || _MSC_VER < 1800) #define PRIuMAX "I64u" #define PRId64 "I64d" +#else +#include +#endif void mingw_open_html(const char *path); #define open_html mingw_open_html -void mingw_mark_as_git_dir(const char *dir); -#define mark_as_git_dir mingw_mark_as_git_dir - /** * Converts UTF-8 encoded string to UTF-16LE. * diff --git a/compat/nedmalloc/malloc.c.h b/compat/nedmalloc/malloc.c.h index f216a2a7d3..b833ff9225 100644 --- a/compat/nedmalloc/malloc.c.h +++ b/compat/nedmalloc/malloc.c.h @@ -720,6 +720,9 @@ struct mallinfo { inlining are defined as macros, so these aren't used for them. */ +#ifdef __MINGW64_VERSION_MAJOR +#undef FORCEINLINE +#endif #ifndef FORCEINLINE #if defined(__GNUC__) #define FORCEINLINE __inline __attribute__ ((always_inline)) @@ -1382,6 +1385,7 @@ LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value); /*** Atomic operations ***/ #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 + #undef _ReadWriteBarrier #define _ReadWriteBarrier() __sync_synchronize() #else static __inline__ __attribute__((always_inline)) long __sync_lock_test_and_set(volatile long * const Target, const long Value) @@ -1798,9 +1802,10 @@ struct win32_mlock_t volatile long threadid; }; +static inline int return_0(int i) { return 0; } #define MLOCK_T struct win32_mlock_t #define CURRENT_THREAD win32_getcurrentthreadid() -#define INITIAL_LOCK(sl) (memset(sl, 0, sizeof(MLOCK_T)), 0) +#define INITIAL_LOCK(sl) (memset(sl, 0, sizeof(MLOCK_T)), return_0(0)) #define ACQUIRE_LOCK(sl) win32_acquire_lock(sl) #define RELEASE_LOCK(sl) win32_release_lock(sl) #define TRY_LOCK(sl) win32_try_lock(sl) diff --git a/compat/poll/poll.c b/compat/poll/poll.c index db4e03ed79..b10adc780f 100644 --- a/compat/poll/poll.c +++ b/compat/poll/poll.c @@ -76,7 +76,7 @@ #ifdef WIN32_NATIVE -#define IsConsoleHandle(h) (((long) (h) & 3) == 3) +#define IsConsoleHandle(h) (((long) (intptr_t) (h) & 3) == 3) static BOOL IsSocketHandle (HANDLE h) diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index dfbe6d8408..4293b53b17 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -147,7 +147,7 @@ struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *prec_dir) if (errno || inleft) { /* * iconv() failed and errno could be E2BIG, EILSEQ, EINVAL, EBADF - * MacOS X avoids illegal byte sequemces. + * MacOS X avoids illegal byte sequences. * If they occur on a mounted drive (e.g. NFS) it is not worth to * die() for that, but rather let the user see the original name */ diff --git a/compat/snprintf.c b/compat/snprintf.c index 42ea1ac110..0b11688537 100644 --- a/compat/snprintf.c +++ b/compat/snprintf.c @@ -9,7 +9,7 @@ * always have room for a trailing NUL byte. */ #ifndef SNPRINTF_SIZE_CORR -#if defined(WIN32) && (!defined(__GNUC__) || __GNUC__ < 4) +#if defined(WIN32) && (!defined(__GNUC__) || __GNUC__ < 4) && (!defined(_MSC_VER) || _MSC_VER < 1900) #define SNPRINTF_SIZE_CORR 1 #else #define SNPRINTF_SIZE_CORR 0 diff --git a/compat/terminal.c b/compat/terminal.c index 313897d581..fa13ee672d 100644 --- a/compat/terminal.c +++ b/compat/terminal.c @@ -122,7 +122,7 @@ char *git_terminal_prompt(const char *prompt, int echo) fputs(prompt, output_fh); fflush(output_fh); - r = strbuf_getline(&buf, input_fh, '\n'); + r = strbuf_getline_lf(&buf, input_fh); if (!echo) { putc('\n', output_fh); fflush(output_fh); diff --git a/compat/vcbuild/include/unistd.h b/compat/vcbuild/include/unistd.h index c65c2cd566..3a959d124c 100644 --- a/compat/vcbuild/include/unistd.h +++ b/compat/vcbuild/include/unistd.h @@ -45,11 +45,15 @@ typedef unsigned long long uintmax_t; typedef int64_t off64_t; +#if !defined(_MSC_VER) || _MSC_VER < 1600 #define INTMAX_MIN _I64_MIN #define INTMAX_MAX _I64_MAX #define UINTMAX_MAX _UI64_MAX #define UINT32_MAX 0xffffffff /* 4294967295U */ +#else +#include +#endif #define STDIN_FILENO 0 #define STDOUT_FILENO 1 diff --git a/compat/win32/pthread.h b/compat/win32/pthread.h index 8ad187344f..1c164088fb 100644 --- a/compat/win32/pthread.h +++ b/compat/win32/pthread.h @@ -18,7 +18,10 @@ */ #define pthread_mutex_t CRITICAL_SECTION -#define pthread_mutex_init(a,b) (InitializeCriticalSection((a)), 0) +static inline int return_0(int i) { + return 0; +} +#define pthread_mutex_init(a,b) return_0((InitializeCriticalSection((a)), 0)) #define pthread_mutex_destroy(a) DeleteCriticalSection((a)) #define pthread_mutex_lock EnterCriticalSection #define pthread_mutex_unlock LeaveCriticalSection @@ -75,9 +78,9 @@ extern int win32_pthread_join(pthread_t *thread, void **value_ptr); #define pthread_equal(t1, t2) ((t1).tid == (t2).tid) extern pthread_t pthread_self(void); -static inline int pthread_exit(void *ret) +static inline void NORETURN pthread_exit(void *ret) { - ExitThread((DWORD)ret); + ExitThread((DWORD)(intptr_t)ret); } typedef DWORD pthread_key_t; @@ -101,4 +104,11 @@ static inline void *pthread_getspecific(pthread_key_t key) return TlsGetValue(key); } +#ifndef __MINGW64_VERSION_MAJOR +static inline int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) +{ + return 0; +} +#endif + #endif /* PTHREAD_H */ diff --git a/compat/win32mmap.c b/compat/win32mmap.c index 80a8c9af4f..519d51f2b6 100644 --- a/compat/win32mmap.c +++ b/compat/win32mmap.c @@ -2,37 +2,42 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) { - HANDLE hmap; + HANDLE osfhandle, hmap; void *temp; - off_t len; - struct stat st; + LARGE_INTEGER len; uint64_t o = offset; uint32_t l = o & 0xFFFFFFFF; uint32_t h = (o >> 32) & 0xFFFFFFFF; - if (!fstat(fd, &st)) - len = st.st_size; - else + osfhandle = (HANDLE)_get_osfhandle(fd); + if (!GetFileSizeEx(osfhandle, &len)) die("mmap: could not determine filesize"); - if ((length + offset) > len) - length = xsize_t(len - offset); + if ((length + offset) > len.QuadPart) + length = xsize_t(len.QuadPart - offset); if (!(flags & MAP_PRIVATE)) die("Invalid usage of mmap when built with USE_WIN32_MMAP"); - hmap = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL, - PAGE_WRITECOPY, 0, 0, NULL); + hmap = CreateFileMapping(osfhandle, NULL, + prot == PROT_READ ? PAGE_READONLY : PAGE_WRITECOPY, 0, 0, NULL); - if (!hmap) + if (!hmap) { + errno = EINVAL; return MAP_FAILED; + } - temp = MapViewOfFileEx(hmap, FILE_MAP_COPY, h, l, length, start); + temp = MapViewOfFileEx(hmap, prot == PROT_READ ? + FILE_MAP_READ : FILE_MAP_COPY, h, l, length, start); if (!CloseHandle(hmap)) warning("unable to close file mapping handle"); - return temp ? temp : MAP_FAILED; + if (temp) + return temp; + + errno = GetLastError() == ERROR_COMMITMENT_LIMIT ? EFBIG : EINVAL; + return MAP_FAILED; } int git_munmap(void *start, size_t length) diff --git a/compat/winansi.c b/compat/winansi.c index ceff55bd67..3be60ce1c6 100644 --- a/compat/winansi.c +++ b/compat/winansi.c @@ -23,6 +23,7 @@ static HANDLE hthread, hread, hwrite; static HANDLE hconsole1, hconsole2; #ifdef __MINGW32__ +#if !defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 5 typedef struct _CONSOLE_FONT_INFOEX { ULONG cbSize; DWORD nFont; @@ -32,6 +33,7 @@ typedef struct _CONSOLE_FONT_INFOEX { WCHAR FaceName[LF_FACESIZE]; } CONSOLE_FONT_INFOEX, *PCONSOLE_FONT_INFOEX; #endif +#endif typedef BOOL (WINAPI *PGETCURRENTCONSOLEFONTEX)(HANDLE, BOOL, PCONSOLE_FONT_INFOEX); @@ -452,7 +454,8 @@ static HANDLE duplicate_handle(HANDLE hnd) HANDLE hresult, hproc = GetCurrentProcess(); if (!DuplicateHandle(hproc, hnd, hproc, &hresult, 0, TRUE, DUPLICATE_SAME_ACCESS)) - die_lasterr("DuplicateHandle(%li) failed", (long) hnd); + die_lasterr("DuplicateHandle(%li) failed", + (long) (intptr_t) hnd); return hresult; } @@ -480,6 +483,7 @@ static size_t sizeof_ioinfo = 0; #define IOINFO_L2E 5 #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) +#define FPIPE 0x08 #define FDEV 0x40 static inline ioinfo* _pioinfo(int fd) @@ -527,6 +531,45 @@ static HANDLE swap_osfhnd(int fd, HANDLE new_handle) return old_handle; } +#ifdef DETECT_MSYS_TTY + +#include +#include + +static void detect_msys_tty(int fd) +{ + ULONG result; + BYTE buffer[1024]; + POBJECT_NAME_INFORMATION nameinfo = (POBJECT_NAME_INFORMATION) buffer; + PWSTR name; + + /* check if fd is a pipe */ + HANDLE h = (HANDLE) _get_osfhandle(fd); + if (GetFileType(h) != FILE_TYPE_PIPE) + return; + + /* get pipe name */ + if (!NT_SUCCESS(NtQueryObject(h, ObjectNameInformation, + buffer, sizeof(buffer) - 2, &result))) + return; + name = nameinfo->Name.Buffer; + name[nameinfo->Name.Length] = 0; + + /* check if this could be a MSYS2 pty pipe ('msys-XXXX-ptyN-XX') */ + if (!wcsstr(name, L"msys-") || !wcsstr(name, L"-pty")) + return; + + /* init ioinfo size if we haven't done so */ + if (init_sizeof_ioinfo()) + return; + + /* set FDEV flag, reset FPIPE flag */ + _pioinfo(fd)->osflags &= ~FPIPE; + _pioinfo(fd)->osflags |= FDEV; +} + +#endif + void winansi_init(void) { int con1, con2; @@ -535,8 +578,15 @@ void winansi_init(void) /* check if either stdout or stderr is a console output screen buffer */ con1 = is_console(1); con2 = is_console(2); - if (!con1 && !con2) + if (!con1 && !con2) { +#ifdef DETECT_MSYS_TTY + /* check if stdin / stdout / stderr are MSYS2 pty pipes */ + detect_msys_tty(0); + detect_msys_tty(1); + detect_msys_tty(2); +#endif return; + } /* create a named pipe to communicate with the console thread */ xsnprintf(name, sizeof(name), "\\\\.\\pipe\\winansi%lu", GetCurrentProcessId()); @@ -572,8 +622,11 @@ void winansi_init(void) HANDLE winansi_get_osfhandle(int fd) { HANDLE hnd = (HANDLE) _get_osfhandle(fd); - if ((fd == 1 || fd == 2) && isatty(fd) - && GetFileType(hnd) == FILE_TYPE_PIPE) - return (fd == 1) ? hconsole1 : hconsole2; + if (isatty(fd) && GetFileType(hnd) == FILE_TYPE_PIPE) { + if (fd == 1 && hconsole1) + return hconsole1; + else if (fd == 2 && hconsole2) + return hconsole2; + } return hnd; } diff --git a/config.c b/config.c index 03544e7a3f..6dbc8a409e 100644 --- a/config.c +++ b/config.c @@ -24,6 +24,7 @@ struct config_source { size_t pos; } buf; } u; + const char *origin_type; const char *name; const char *path; int die_on_error; @@ -107,7 +108,7 @@ static int handle_path_include(const char *path, struct config_include_data *inc expanded = expand_user_path(path); if (!expanded) - return error("Could not expand include path '%s'", path); + return error("could not expand include path '%s'", path); path = expanded; /* @@ -471,9 +472,9 @@ static int git_parse_source(config_fn_t fn, void *data) break; } if (cf->die_on_error) - die(_("bad config file line %d in %s"), cf->linenr, cf->name); + die(_("bad config line %d in %s %s"), cf->linenr, cf->origin_type, cf->name); else - return error(_("bad config file line %d in %s"), cf->linenr, cf->name); + return error(_("bad config line %d in %s %s"), cf->linenr, cf->origin_type, cf->name); } static int parse_unit_factor(const char *end, uintmax_t *val) @@ -588,9 +589,9 @@ static void die_bad_number(const char *name, const char *value) if (!value) value = ""; - if (cf && cf->name) - die(_("bad numeric config value '%s' for '%s' in %s: %s"), - value, name, cf->name, reason); + if (cf && cf->origin_type && cf->name) + die(_("bad numeric config value '%s' for '%s' in %s %s: %s"), + value, name, cf->origin_type, cf->name, reason); die(_("bad numeric config value '%s' for '%s': %s"), value, name, reason); } @@ -802,8 +803,6 @@ static int git_default_core_config(const char *var, const char *value) if (!strcmp(var, "core.autocrlf")) { if (value && !strcasecmp(value, "input")) { - if (core_eol == EOL_CRLF) - return error("core.autocrlf=input conflicts with core.eol=crlf"); auto_crlf = AUTO_CRLF_INPUT; return 0; } @@ -829,8 +828,6 @@ static int git_default_core_config(const char *var, const char *value) core_eol = EOL_NATIVE; else core_eol = EOL_UNSET; - if (core_eol == EOL_CRLF && auto_crlf == AUTO_CRLF_INPUT) - return error("core.autocrlf=input conflicts with core.eol=crlf"); return 0; } @@ -911,6 +908,14 @@ static int git_default_core_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.hidedotfiles")) { + if (value && !strcasecmp(value, "dotgitonly")) + hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; + else + hide_dotfiles = git_config_bool(var, value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return 0; } @@ -949,7 +954,7 @@ static int git_default_branch_config(const char *var, const char *value) else if (!strcmp(value, "always")) autorebase = AUTOREBASE_ALWAYS; else - return error("Malformed value for %s", var); + return error("malformed value for %s", var); return 0; } @@ -975,7 +980,7 @@ static int git_default_push_config(const char *var, const char *value) else if (!strcmp(value, "current")) push_default = PUSH_DEFAULT_CURRENT; else { - error("Malformed value for %s: %s", var, value); + error("malformed value for %s: %s", var, value); return error("Must be one of nothing, matching, simple, " "upstream or current."); } @@ -1061,11 +1066,13 @@ static int do_config_from(struct config_source *top, config_fn_t fn, void *data) } static int do_config_from_file(config_fn_t fn, - const char *name, const char *path, FILE *f, void *data) + const char *origin_type, const char *name, const char *path, FILE *f, + void *data) { struct config_source top; top.u.file = f; + top.origin_type = origin_type; top.name = name; top.path = path; top.die_on_error = 1; @@ -1078,7 +1085,7 @@ static int do_config_from_file(config_fn_t fn, static int git_config_from_stdin(config_fn_t fn, void *data) { - return do_config_from_file(fn, "", NULL, stdin, data); + return do_config_from_file(fn, "standard input", "", NULL, stdin, data); } int git_config_from_file(config_fn_t fn, const char *filename, void *data) @@ -1089,21 +1096,22 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data) f = fopen(filename, "r"); if (f) { flockfile(f); - ret = do_config_from_file(fn, filename, filename, f, data); + ret = do_config_from_file(fn, "file", filename, filename, f, data); funlockfile(f); fclose(f); } return ret; } -int git_config_from_buf(config_fn_t fn, const char *name, const char *buf, - size_t len, void *data) +int git_config_from_mem(config_fn_t fn, const char *origin_type, + const char *name, const char *buf, size_t len, void *data) { struct config_source top; top.u.buf.buf = buf; top.u.buf.len = len; top.u.buf.pos = 0; + top.origin_type = origin_type; top.name = name; top.path = NULL; top.die_on_error = 0; @@ -1132,7 +1140,7 @@ static int git_config_from_blob_sha1(config_fn_t fn, return error("reference '%s' does not point to a blob", name); } - ret = git_config_from_buf(fn, name, buf, size, data); + ret = git_config_from_mem(fn, "blob", name, buf, size, data); free(buf); return ret; @@ -1184,11 +1192,12 @@ int git_config_system(void) return !git_env_bool("GIT_CONFIG_NOSYSTEM", 0); } -int git_config_early(config_fn_t fn, void *data, const char *repo_config) +static int do_git_config_sequence(config_fn_t fn, void *data) { int ret = 0, found = 0; char *xdg_config = xdg_config_home("config"); char *user_config = expand_user_path("~/.gitconfig"); + char *repo_config = git_pathdup("config"); if (git_config_system() && !access_or_die(git_etc_gitconfig(), R_OK, 0)) { ret += git_config_from_file(fn, git_etc_gitconfig(), @@ -1224,6 +1233,7 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config) free(xdg_config); free(user_config); + free(repo_config); return ret == 0 ? found : ret; } @@ -1231,8 +1241,6 @@ int git_config_with_options(config_fn_t fn, void *data, struct git_config_source *config_source, int respect_includes) { - char *repo_config = NULL; - int ret; struct config_include_data inc = CONFIG_INCLUDE_INIT; if (respect_includes) { @@ -1253,11 +1261,7 @@ int git_config_with_options(config_fn_t fn, void *data, else if (config_source && config_source->blob) return git_config_from_blob_ref(fn, config_source->blob, data); - repo_config = git_pathdup("config"); - ret = git_config_early(fn, data, repo_config); - if (repo_config) - free(repo_config); - return ret; + return do_git_config_sequence(fn, data); } static void git_config_raw(config_fn_t fn, void *data) @@ -1309,14 +1313,11 @@ static struct config_set_element *configset_find_element(struct config_set *cs, struct config_set_element k; struct config_set_element *found_entry; char *normalized_key; - int ret; /* * `key` may come from the user, so normalize it before using it * for querying entries from the hashmap. */ - ret = git_config_parse_key(key, &normalized_key, NULL); - - if (ret) + if (git_config_parse_key(key, &normalized_key, NULL)) return NULL; hashmap_entry_init(&k, strhash(normalized_key)); @@ -1594,6 +1595,30 @@ int git_config_get_pathname(const char *key, const char **dest) return ret; } +int git_config_get_untracked_cache(void) +{ + int val = -1; + const char *v; + + /* Hack for test programs like test-dump-untracked-cache */ + if (ignore_untracked_cache_config) + return -1; + + if (!git_config_get_maybe_bool("core.untrackedcache", &val)) + return val; + + if (!git_config_get_value("core.untrackedcache", &v)) { + if (!strcasecmp(v, "keep")) + return -1; + + error("unknown core.untrackedCache value '%s'; " + "using 'keep' default value", v); + return -1; + } + + return -1; /* default value */ +} + NORETURN void git_die_config_linenr(const char *key, const char *filename, int linenr) { @@ -2193,9 +2218,13 @@ void git_config_set_multivar_in_file(const char *config_filename, const char *key, const char *value, const char *value_regex, int multi_replace) { - if (git_config_set_multivar_in_file_gently(config_filename, key, value, - value_regex, multi_replace) < 0) - die(_("Could not set '%s' to '%s'"), key, value); + if (!git_config_set_multivar_in_file_gently(config_filename, key, value, + value_regex, multi_replace)) + return; + if (value) + die(_("could not set '%s' to '%s'"), key, value); + else + die(_("could not unset '%s'"), key); } int git_config_set_multivar_gently(const char *key, const char *value, @@ -2376,7 +2405,7 @@ int git_config_rename_section(const char *old_name, const char *new_name) #undef config_error_nonbool int config_error_nonbool(const char *var) { - return error("Missing value for '%s'", var); + return error("missing value for '%s'", var); } int parse_config_key(const char *var, @@ -2411,3 +2440,13 @@ int parse_config_key(const char *var, return 0; } + +const char *current_config_origin_type(void) +{ + return cf && cf->origin_type ? cf->origin_type : "command line"; +} + +const char *current_config_name(void) +{ + return cf && cf->name ? cf->name : ""; +} diff --git a/config.mak.uname b/config.mak.uname index f34dcaad20..a88f13989a 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -37,6 +37,7 @@ ifeq ($(uname_S),Linux) HAVE_CLOCK_GETTIME = YesPlease HAVE_CLOCK_MONOTONIC = YesPlease HAVE_GETDELIM = YesPlease + SANE_TEXT_GREP=-a endif ifeq ($(uname_S),GNU/kFreeBSD) HAVE_ALLOCA_H = YesPlease @@ -186,6 +187,7 @@ ifeq ($(uname_O),Cygwin) X = .exe UNRELIABLE_FSTAT = UnfortunatelyYes SPARSE_FLAGS = -isystem /usr/include/w32api -Wno-one-bit-signed-bitfield + OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo endif ifeq ($(uname_S),FreeBSD) NEEDS_LIBICONV = YesPlease @@ -518,13 +520,12 @@ ifneq (,$(findstring MINGW,$(uname_S))) NO_INET_NTOP = YesPlease NO_POSIX_GOODIES = UnfortunatelyYes DEFAULT_HELP_FORMAT = html - COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -D_USE_32BIT_TIME_T -DNOGDI -Icompat -Icompat/win32 + COMPAT_CFLAGS += -DNOGDI -Icompat -Icompat/win32 COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" COMPAT_OBJS += compat/mingw.o compat/winansi.o \ compat/win32/pthread.o compat/win32/syslog.o \ compat/win32/dirent.o BASIC_CFLAGS += -DPROTECT_NTFS_DEFAULT=1 - BASIC_LDFLAGS += -Wl,--large-address-aware EXTLIBS += -lws2_32 GITLIBS += git.res PTHREAD_LIBS = @@ -541,8 +542,36 @@ ifneq (,$(wildcard ../THIS_IS_MSYSGIT)) INTERNAL_QSORT = YesPlease HAVE_LIBCHARSET_H = YesPlease NO_GETTEXT = YesPlease + COMPAT_CLFAGS += -D__USE_MINGW_ACCESS else - NO_CURL = YesPlease + ifeq ($(shell expr "$(uname_R)" : '2\.'),2) + # MSys2 + prefix = /usr/ + ifeq (MINGW32,$(MSYSTEM)) + prefix = /mingw32 + endif + ifeq (MINGW64,$(MSYSTEM)) + prefix = /mingw64 + else + COMPAT_CFLAGS += -D_USE_32BIT_TIME_T + BASIC_LDFLAGS += -Wl,--large-address-aware + endif + CC = gcc + COMPAT_CFLAGS += -D__USE_MINGW_ANSI_STDIO=0 -DDETECT_MSYS_TTY + EXTLIBS += -lntdll + INSTALL = /bin/install + NO_R_TO_GCC_LINKER = YesPlease + INTERNAL_QSORT = YesPlease + HAVE_LIBCHARSET_H = YesPlease + NO_GETTEXT = + USE_GETTEXT_SCHEME = fallthrough + USE_LIBPCRE= YesPlease + NO_CURL = + USE_NED_ALLOCATOR = YesPlease + else + COMPAT_CFLAGS += -D__USE_MINGW_ANSI_STDIO + NO_CURL = YesPlease + endif endif endif ifeq ($(uname_S),QNX) diff --git a/configure.ac b/configure.ac index 89e2590bd6..c279025747 100644 --- a/configure.ac +++ b/configure.ac @@ -471,6 +471,13 @@ if test -n "$ASCIIDOC"; then esac fi +if grep -a ascii configure.ac >/dev/null; then + AC_MSG_RESULT([Using 'grep -a' for sane_grep]) + SANE_TEXT_GREP=-a +else + SANE_TEXT_GREP= +fi +GIT_CONF_SUBST([SANE_TEXT_GREP]) ## Checks for libraries. AC_MSG_NOTICE([CHECKS for libraries]) @@ -963,10 +970,6 @@ AC_CHECK_LIB([iconv], [locale_charset], [CHARSET_LIB=-lcharset])]) GIT_CONF_SUBST([CHARSET_LIB]) # -# Define NO_HMAC_CTX_CLEANUP=YesPlease if HMAC_CTX_cleanup is missing. -AC_CHECK_LIB([crypto], [HMAC_CTX_cleanup], - [], [GIT_CONF_SUBST([NO_HMAC_CTX_CLEANUP], [YesPlease])]) -# # Define HAVE_CLOCK_GETTIME=YesPlease if clock_gettime is available. GIT_CHECK_FUNC(clock_gettime, [HAVE_CLOCK_GETTIME=YesPlease], diff --git a/connect.c b/connect.c index d77d39771b..c75bf52ee2 100644 --- a/connect.c +++ b/connect.c @@ -267,9 +267,9 @@ static enum protocol get_protocol(const char *name) return PROTO_SSH; if (!strcmp(name, "git")) return PROTO_GIT; - if (!strcmp(name, "git+ssh")) + if (!strcmp(name, "git+ssh")) /* deprecated - do not use */ return PROTO_SSH; - if (!strcmp(name, "ssh+git")) + if (!strcmp(name, "ssh+git")) /* deprecated - do not use */ return PROTO_SSH; if (!strcmp(name, "file")) return PROTO_FILE; @@ -357,6 +357,10 @@ static int git_tcp_connect_sock(char *host, int flags) port = ""; memset(&hints, 0, sizeof(hints)); + if (flags & CONNECT_IPV4) + hints.ai_family = AF_INET; + else if (flags & CONNECT_IPV6) + hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; @@ -794,6 +798,10 @@ struct child_process *git_connect(int fd[2], const char *url, } argv_array_push(&conn->args, ssh); + if (flags & CONNECT_IPV4) + argv_array_push(&conn->args, "-4"); + else if (flags & CONNECT_IPV6) + argv_array_push(&conn->args, "-6"); if (tortoiseplink) argv_array_push(&conn->args, "-batch"); if (port) { diff --git a/connect.h b/connect.h index c41a6850f1..01f14cdf3f 100644 --- a/connect.h +++ b/connect.h @@ -3,6 +3,8 @@ #define CONNECT_VERBOSE (1u << 0) #define CONNECT_DIAG_URL (1u << 1) +#define CONNECT_IPV4 (1u << 2) +#define CONNECT_IPV6 (1u << 3) extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags); extern int finish_connect(struct child_process *conn); extern int git_connection_is_socket(struct child_process *conn); diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 00d729996f..e3918c87e3 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1312,6 +1312,7 @@ _git_grep () --full-name --line-number --extended-regexp --basic-regexp --fixed-strings --perl-regexp + --threads --files-with-matches --name-only --files-without-match --max-depth @@ -1812,7 +1813,7 @@ _git_config () return ;; branch.*.rebase) - __gitcomp "false true" + __gitcomp "false true preserve interactive" return ;; remote.pushdefault) @@ -2059,6 +2060,7 @@ _git_config () core.sparseCheckout core.symlinks core.trustctime + core.untrackedCache core.warnAmbiguousRefs core.whitespace core.worktree diff --git a/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh index 934505bab9..86c9cfa0c7 100755 --- a/contrib/examples/git-commit.sh +++ b/contrib/examples/git-commit.sh @@ -574,10 +574,10 @@ then if test "$templatefile" != "" then # Test whether this is just the unaltered template. - if cnt=`sed -e '/^#/d' < "$templatefile" | + if cnt=$(sed -e '/^#/d' < "$templatefile" | git stripspace | diff "$GIT_DIR"/COMMIT_BAREMSG - | - wc -l` && + wc -l) && test 0 -lt $cnt then have_commitmsg=t @@ -630,8 +630,8 @@ then fi if test -z "$quiet" then - commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\ - --abbrev --summary --root HEAD --` + commit=$(git diff-tree --always --shortstat --pretty="format:%h: %s"\ + --abbrev --summary --root HEAD --) echo "Created${initial_commit:+ initial} commit $commit" fi fi diff --git a/contrib/examples/git-fetch.sh b/contrib/examples/git-fetch.sh index 554070909c..57d2e5616f 100755 --- a/contrib/examples/git-fetch.sh +++ b/contrib/examples/git-fetch.sh @@ -146,13 +146,13 @@ esac reflist=$(get_remote_refs_for_fetch "$@") if test "$tags" then - taglist=`IFS=' ' && + taglist=$(IFS=' ' && echo "$ls_remote_result" | git show-ref --exclude-existing=refs/tags/ | while read sha1 name do echo ".${name}:${name}" - done` || exit + done) || exit if test "$#" -gt 1 then # remote URL plus explicit refspecs; we need to merge them. diff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh index 52f2aafb9d..ee99f1a4ee 100755 --- a/contrib/examples/git-merge.sh +++ b/contrib/examples/git-merge.sh @@ -523,10 +523,10 @@ do if test "$exit" -eq 1 then - cnt=`{ + cnt=$({ git diff-files --name-only git ls-files --unmerged - } | wc -l` + } | wc -l) if test $best_cnt -le 0 || test $cnt -le $best_cnt then best_strategy=$strategy diff --git a/contrib/examples/git-repack.sh b/contrib/examples/git-repack.sh index 96e3fed326..672af93443 100755 --- a/contrib/examples/git-repack.sh +++ b/contrib/examples/git-repack.sh @@ -67,8 +67,8 @@ case ",$all_into_one," in ,t,) args= existing= if [ -d "$PACKDIR" ]; then - for e in `cd "$PACKDIR" && find . -type f -name '*.pack' \ - | sed -e 's/^\.\///' -e 's/\.pack$//'` + for e in $(cd "$PACKDIR" && find . -type f -name '*.pack' \ + | sed -e 's/^\.\///' -e 's/\.pack$//') do if [ -e "$PACKDIR/$e.keep" ]; then : keep diff --git a/contrib/examples/git-revert.sh b/contrib/examples/git-revert.sh index 7e2aad5491..197838d10b 100755 --- a/contrib/examples/git-revert.sh +++ b/contrib/examples/git-revert.sh @@ -138,8 +138,8 @@ cherry-pick) }' logmsg=$(git show -s --pretty=raw --encoding="$encoding" "$commit") - set_author_env=`echo "$logmsg" | - LANG=C LC_ALL=C sed -ne "$pick_author_script"` + set_author_env=$(echo "$logmsg" | + LANG=C LC_ALL=C sed -ne "$pick_author_script") eval "$set_author_env" export GIT_AUTHOR_NAME export GIT_AUTHOR_EMAIL @@ -160,9 +160,9 @@ cherry-pick) esac >.msg eval GITHEAD_$head=HEAD -eval GITHEAD_$next='`git show -s \ +eval GITHEAD_$next='$(git show -s \ --pretty=oneline --encoding="$encoding" "$commit" | - sed -e "s/^[^ ]* //"`' + sed -e "s/^[^ ]* //")' export GITHEAD_$head GITHEAD_$next # This three way merge is an interesting one. We are at diff --git a/contrib/hooks/multimail/CHANGES b/contrib/hooks/multimail/CHANGES index bc77e66b85..53c71b422a 100644 --- a/contrib/hooks/multimail/CHANGES +++ b/contrib/hooks/multimail/CHANGES @@ -1,3 +1,38 @@ +Release 1.3.0 +============= + +* New options multimailhook.htmlInIntro and multimailhook.htmlInFooter + now allow using HTML in the introduction and footer of emails (e.g. + for a more pleasant formatting or to insert a link to the commit on + a web interface). + +* A new option multimailhook.commitBrowseURL gives a simpler (and less + flexible) way to add a link to a web interface for commit emails + than multimailhook.htmlInIntro and multimailhook.htmlInFooter. + +* A new public function config.add_config_parameters was added to + allow custom hooks to set specific Git configuration variables + without modifying the configuration files. See an example in + post-receive.example. + +* Error handling for SMTP has been improved (we used to print Python + backtraces for legitimate errors). + +* The SMTP mailer can now check TLS certificates when the newly added + configuration variable multimailhook.smtpCACerts. + +* Python 3 portability has been improved. + +* The documentation's formatting has been improved. + +* The testsuite has been improved (we now use pyflakes to check for + errors in the code). + +This version has been tested with Python 2.4 and 2.6 to 3.5, and Git +v1.7.10-406-gdc801e7, 2.1.4 and 2.8.1.339.g3ad15fd. + +No change since 1.3 RC1. + Release 1.2.0 ============= diff --git a/contrib/hooks/multimail/CONTRIBUTING.rst b/contrib/hooks/multimail/CONTRIBUTING.rst index 09efdb059c..530ecbfcf1 100644 --- a/contrib/hooks/multimail/CONTRIBUTING.rst +++ b/contrib/hooks/multimail/CONTRIBUTING.rst @@ -1,3 +1,6 @@ +Contributing +============ + git-multimail is an open-source project, built by volunteers. We would welcome your help! @@ -6,9 +9,7 @@ and Matthieu Moy . Please note that although a copy of git-multimail is distributed in the "contrib" section of the main Git project, development takes place -in a separate git-multimail repository on GitHub: - - https://github.com/git-multimail/git-multimail +in a separate `git-multimail repository on GitHub`_. Whenever enough changes to git-multimail have accumulated, a new code-drop of git-multimail will be submitted for inclusion in the Git @@ -21,10 +22,12 @@ to the maintainers). Please sign off your patches as per the `Git project practice `__. -General discussion of git-multimail can take place on the main Git -mailing list, - - git@vger.kernel.org +General discussion of git-multimail can take place on the main `Git +mailing list`_. Please CC emails regarding git-multimail to the maintainers so that we don't overlook them. + + +.. _`git-multimail repository on GitHub`: https://github.com/git-multimail/git-multimail +.. _`Git mailing list`: git@vger.kernel.org diff --git a/contrib/hooks/multimail/README b/contrib/hooks/multimail/README index 55120685f0..1e04801978 100644 --- a/contrib/hooks/multimail/README +++ b/contrib/hooks/multimail/README @@ -1,5 +1,5 @@ -git-multimail (version 1.2.0) -============================= +git-multimail 1.3.0 +=================== .. image:: https://travis-ci.org/git-multimail/git-multimail.svg?branch=master :target: https://travis-ci.org/git-multimail/git-multimail @@ -127,6 +127,13 @@ changes of this type, please consider sharing them with the community.) +Troubleshooting/FAQ +------------------- + +Please read ``__ for frequently asked +questions and common issues with git-multimail. + + Configuration ------------- @@ -134,19 +141,16 @@ By default, git-multimail mostly takes its configuration from the following ``git config`` settings: multimailhook.environment - This describes the general environment of the repository. In most cases, you do not need to specify a value for this variable: `git-multimail` will autodetect which environment to use. Currently supported values: - * generic - + generic the username of the pusher is read from $USER or $USERNAME and the repository name is derived from the repository's path. - * gitolite - + gitolite the username of the pusher is read from $GL_USER, the repository name is read from $GL_REPO, and the From: header value is optionally read from gitolite.conf (see multimailhook.from). @@ -154,8 +158,7 @@ multimailhook.environment For more information about gitolite and git-multimail, read ``__ - * stash - + stash Environment to use when ``git-multimail`` is ran as an Atlassian BitBucket Server (formerly known as Atlassian Stash) hook. @@ -169,8 +172,7 @@ multimailhook.environment and repo come from these two command line flags, which must be specified. - * gerrit - + gerrit Environment to use when ``git-multimail`` is ran as a ``ref-updated`` Gerrit hook. @@ -205,14 +207,12 @@ multimailhook.environment * If none of the above apply, then ``generic`` is used. multimailhook.repoName - A short name of this Git repository, to be used in various places in the notification email text. The default is to use $GL_REPO for gitolite repositories, or otherwise to derive this value from the repository path name. multimailhook.mailingList - The list of email addresses to which notification emails should be sent, as RFC 2822 email addresses separated by commas. This configuration option can be multivalued. Leave it unset or set it @@ -221,7 +221,6 @@ multimailhook.mailingList specific types of notification email. multimailhook.refchangeList - The list of email addresses to which summary emails about reference changes should be sent, as RFC 2822 email addresses separated by commas. This configuration option can be @@ -231,7 +230,6 @@ multimailhook.refchangeList multimailhook.mailingList is set. multimailhook.announceList - The list of email addresses to which emails about new annotated tags should be sent, as RFC 2822 email addresses separated by commas. This configuration option can be multivalued. The @@ -241,7 +239,6 @@ multimailhook.announceList even if one of the other values is set. multimailhook.commitList - The list of email addresses to which emails about individual new commits should be sent, as RFC 2822 email addresses separated by commas. This configuration option can be multivalued. The @@ -251,7 +248,6 @@ multimailhook.commitList multimailhook.mailingList is set. multimailhook.announceShortlog - If this option is set to true, then emails about changes to annotated tags include a shortlog of changes since the previous tag. This can be useful if the annotated tags represent releases; @@ -261,7 +257,6 @@ multimailhook.announceShortlog rather than useful. Default is false. multimailhook.commitEmailFormat - The format of email messages for the individual commits, can be "text" or "html". In the latter case, the emails will include diffs using colorized HTML instead of plain text used by default. Note that this currently the @@ -274,8 +269,43 @@ multimailhook.commitEmailFormat the message starting with ``+++`` or ``---`` colored in red or green). -multimailhook.refchangeShowGraph + By default, all the message is HTML-escaped. See + ``multimailhook.htmlInIntro`` to change this behavior. + +multimailhook.commitBrowseURL + Used to generate a link to an online repository browser in commit + emails. This variable must be a string. Format directives like + ``%()s`` will be expanded the same way as template + strings. In particular, ``%(id)s`` will be replaced by the full + Git commit identifier (40-chars hexadecimal). + + If the string does not contain any format directive, then + ``%(id)s`` will be automatically added to the string. If you don't + want ``%(id)s`` to be automatically added, use the empty format + directive ``%()s`` anywhere in the string. + + For example, a suitable value for the git-multimail project itself + would be + ``https://github.com/git-multimail/git-multimail/commit/%(id)s``. + +multimailhook.htmlInIntro, multimailhook.htmlInFooter + When generating an HTML message, git-multimail escapes any HTML + sequence by default. This means that if a template contains HTML + like ``link``, the reader will see the HTML + source code and not a proper link. + + Set ``multimailhook.htmlInIntro`` to true to allow writting HTML + formatting in introduction templates. Similarly, set + ``multimailhook.htmlInFooter`` for HTML in the footer. + Variables expanded in the template are still escaped. For example, + if a repository's path contains a ``<``, it will be rendered as + such in the message. + + Read ``__ for more details and + examples. + +multimailhook.refchangeShowGraph If this option is set to true, then summary emails about reference changes will additionally include: @@ -287,7 +317,6 @@ multimailhook.refchangeShowGraph specified in graphOpts. The default is false. multimailhook.refchangeShowLog - If this option is set to true, then summary emails about reference changes will include a detailed log of the added commits in addition to the one line summary. The log is generated by running @@ -295,71 +324,80 @@ multimailhook.refchangeShowLog Default is false. multimailhook.mailer - This option changes the way emails are sent. Accepted values are: - - sendmail (the default): use the command ``/usr/sbin/sendmail`` or + * **sendmail (the default)**: use the command ``/usr/sbin/sendmail`` or ``/usr/lib/sendmail`` (or sendmailCommand, if configured). This mode can be further customized via the following options: - * multimailhook.sendmailCommand - - The command used by mailer ``sendmail`` to send emails. Shell - quoting is allowed in the value of this setting, but remember that - Git requires double-quotes to be escaped; e.g.:: + multimailhook.sendmailCommand + The command used by mailer ``sendmail`` to send emails. Shell + quoting is allowed in the value of this setting, but remember that + Git requires double-quotes to be escaped; e.g.:: - git config multimailhook.sendmailcommand '/usr/sbin/sendmail -oi -t -F \"Git Repo\"' + git config multimailhook.sendmailcommand '/usr/sbin/sendmail -oi -t -F \"Git Repo\"' - Default is '/usr/sbin/sendmail -oi -t' or - '/usr/lib/sendmail -oi -t' (depending on which file is - present and executable). + Default is '/usr/sbin/sendmail -oi -t' or + '/usr/lib/sendmail -oi -t' (depending on which file is + present and executable). - * multimailhook.envelopeSender + multimailhook.envelopeSender + If set then pass this value to sendmail via the -f option to set + the envelope sender address. - If set then pass this value to sendmail via the -f option to set - the envelope sender address. - - - smtp: use Python's smtplib. This is useful when the sendmail + * **smtp**: use Python's smtplib. This is useful when the sendmail command is not available on the system. This mode can be further customized via the following options: - * multimailhook.smtpServer - - The name of the SMTP server to connect to. The value can - also include a colon and a port number; e.g., - ``mail.example.com:25``. Default is 'localhost' using port 25. - - * multimailhook.smtpUser - * multimailhook.smtpPass - - Server username and password. Required if smtpEncryption is 'ssl'. - Note that the username and password currently need to be - set cleartext in the configuration file, which is not - recommended. If you need to use this option, be sure your - configuration file is read-only. + multimailhook.smtpServer + The name of the SMTP server to connect to. The value can + also include a colon and a port number; e.g., + ``mail.example.com:25``. Default is 'localhost' using port 25. - * multimailhook.envelopeSender + multimailhook.smtpUser, multimailhook.smtpPass + Server username and password. Required if smtpEncryption is 'ssl'. + Note that the username and password currently need to be + set cleartext in the configuration file, which is not + recommended. If you need to use this option, be sure your + configuration file is read-only. + multimailhook.envelopeSender The sender address to be passed to the SMTP server. If unset, then the value of multimailhook.from is used. - * multimailhook.smtpServerTimeout - + multimailhook.smtpServerTimeout Timeout in seconds. - * multimailhook.smtpEncryption - - Set the security type. Allowed values: none, ssl, tls. - Default=none. - - * multimailhook.smtpServerDebugLevel - + multimailhook.smtpEncryption + Set the security type. Allowed values: ``none``, ``ssl``, ``tls`` (starttls). + Default is ``none``. + + multimailhook.smtpCACerts + Set the path to a list of trusted CA certificate to verify the + server certificate, only supported when ``smtpEncryption`` is + ``tls``. If unset or empty, the server certificate is not + verified. If it targets a file containing a list of trusted CA + certificates (PEM format) these CAs will be used to verify the + server certificate. For debian, you can set + ``/etc/ssl/certs/ca-certificates.crt`` for using the system + trusted CAs. For self-signed server, you can add your server + certificate to the system store:: + + cd /usr/local/share/ca-certificates/ + openssl s_client -starttls smtp \ + -connect mail.example.net:587 -showcerts \ + /dev/null \ + | openssl x509 -outform PEM >mail.example.net.crt + update-ca-certificates + + and used the updated ``/etc/ssl/certs/ca-certificates.crt``. Or + directly use your ``/path/to/mail.example.net.crt``. Default is + unset. + + multimailhook.smtpServerDebugLevel Integer number. Set to greater than 0 to activate debugging. -multimailhook.from -multimailhook.fromCommit -multimailhook.fromRefchange - +multimailhook.from, multimailhook.fromCommit, multimailhook.fromRefchange If set, use this value in the From: field of generated emails. ``fromCommit`` is used for commit emails, ``fromRefchange`` is used for refchange emails, and ``from`` is used as fall-back in @@ -372,7 +410,7 @@ multimailhook.fromRefchange - The value ``pusher``, in which case the pusher's address (if available) will be used. - - The value ``author`` (meaningful only for replyToCommit), in which + - The value ``author`` (meaningful only for ``fromCommit``), in which case the commit author's address will be used. If config values are unset, the value of the From: header is @@ -396,14 +434,12 @@ multimailhook.fromRefchange 3. Use the value of multimailhook.envelopeSender. multimailhook.administrator - The name and/or email address of the administrator of the Git repository; used in FOOTER_TEMPLATE. Default is multimailhook.envelopesender if it is set; otherwise a generic string is used. multimailhook.emailPrefix - All emails have this string prepended to their subjects, to aid email filtering (though filtering based on the X-Git-* email headers is probably more robust). Default is the short name of @@ -411,16 +447,14 @@ multimailhook.emailPrefix value to the empty string to suppress the email prefix. multimailhook.emailMaxLines - The maximum number of lines that should be included in the body of a generated email. If not specified, there is no limit. Lines beyond the limit are suppressed and counted, and a final line is added indicating the number of suppressed lines. multimailhook.emailMaxLineLength - The maximum length of a line in the email body. Lines longer than - this limit are truncated to this length with a trailing `` [...]`` + this limit are truncated to this length with a trailing ``[...]`` added to indicate the missing text. The default is 500, because (a) diffs with longer lines are probably from binary files, for which a diff is useless, and (b) even if a text file has such long @@ -428,7 +462,6 @@ multimailhook.emailMaxLineLength truncation, set this option to 0. multimailhook.maxCommitEmails - The maximum number of commit emails to send for a given change. When the number of patches is larger that this value, only the summary refchange email is sent. This can avoid accidental @@ -436,14 +469,12 @@ multimailhook.maxCommitEmails emails limit, set this option to 0. The default is 500. multimailhook.emailStrictUTF8 - If this boolean option is set to `true`, then the main part of the email body is forced to be valid UTF-8. Any characters that are not valid UTF-8 are converted to the Unicode replacement character, U+FFFD. The default is `true`. multimailhook.diffOpts - Options passed to ``git diff-tree`` when generating the summary information for ReferenceChange emails. Default is ``--stat --summary --find-copies-harder``. Add -p to those options to @@ -452,7 +483,6 @@ multimailhook.diffOpts details. multimailhook.graphOpts - Options passed to ``git log --graph`` when generating graphs for the reference change summary emails (used only if refchangeShowGraph is true). The default is '--oneline --decorate'. @@ -460,7 +490,6 @@ multimailhook.graphOpts Shell quoting is allowed; see logOpts for details. multimailhook.logOpts - Options passed to ``git log`` to generate additional info for reference change emails (used only if refchangeShowLog is set). For example, adding -p will show each commit's complete diff. The @@ -479,7 +508,6 @@ multimailhook.logOpts logopts = --pretty=format:\"%h %aN <%aE>%n%s%n%n%b%n\" multimailhook.commitLogOpts - Options passed to ``git log`` to generate additional info for revision change emails. For example, adding --ignore-all-spaces will suppress whitespace changes. The default options are ``-C @@ -487,26 +515,21 @@ multimailhook.commitLogOpts multimailhook.logOpts for details. multimailhook.dateSubstitute - String to use as a substitute for ``Date:`` in the output of ``git log`` while formatting commit messages. This is usefull to avoid emitting a line that can be interpreted by mailers as the start of a cited message (Zimbra webmail in particular). Defaults to - ``CommitDate: ``. Set to an empty string or ``none`` to deactivate + ``CommitDate:``. Set to an empty string or ``none`` to deactivate the behavior. multimailhook.emailDomain - Domain name appended to the username of the person doing the push to convert it into an email address (via ``"%s@%s" % (username, emaildomain)``). More complicated schemes can be implemented by overriding Environment and overriding its get_pusher_email() method. -multimailhook.replyTo -multimailhook.replyToCommit -multimailhook.replyToRefchange - +multimailhook.replyTo, multimailhook.replyToCommit, multimailhook.replyToRefchange Addresses to use in the Reply-To: field for commit emails (replyToCommit) and refchange emails (replyToRefchange). multimailhook.replyTo is used as default when replyToCommit or @@ -519,32 +542,24 @@ multimailhook.replyToRefchange commit emails. multimailhook.quiet - Do not output the list of email recipients from the hook multimailhook.stdout - For debugging, send emails to stdout rather than to the mailer. Equivalent to the --stdout command line option multimailhook.scanCommitForCc - If this option is set to true, than recipients from lines in commit body that starts with ``CC:`` will be added to CC list. Default: false multimailhook.combineWhenSingleCommit - If this option is set to true and a single new commit is pushed to a branch, combine the summary and commit email messages into a single email. Default: true -multimailhook.refFilterInclusionRegex -multimailhook.refFilterExclusionRegex -multimailhook.refFilterDoSendRegex -multimailhook.refFilterDontSendRegex - +multimailhook.refFilterInclusionRegex, multimailhook.refFilterExclusionRegex, multimailhook.refFilterDoSendRegex, multimailhook.refFilterDontSendRegex **Warning:** these options are experimental. They should work, but the user-interface is not stable yet (in particular, the option names may change). If you want to participate in stabilizing the @@ -626,14 +641,16 @@ git-multimail is mostly customized via an "environment" that describes the local environment in which Git is running. Two types of environment are built in: -* GenericEnvironment: a stand-alone Git repository. +GenericEnvironment + a stand-alone Git repository. -* GitoliteEnvironment: a Git repository that is managed by gitolite - [3]_. For such repositories, the identity of the pusher is read from - environment variable $GL_USER, the name of the repository is read - from $GL_REPO (if it is not overridden by multimailhook.reponame), - and the From: header value is optionally read from gitolite.conf - (see multimailhook.from). +GitoliteEnvironment + a Git repository that is managed by gitolite + [3]_. For such repositories, the identity of the pusher is read from + environment variable $GL_USER, the name of the repository is read + from $GL_REPO (if it is not overridden by multimailhook.reponame), + and the From: header value is optionally read from gitolite.conf + (see multimailhook.from). By default, git-multimail assumes GitoliteEnvironment if $GL_USER and $GL_REPO are set, and otherwise assumes GenericEnvironment. diff --git a/contrib/hooks/multimail/README.Git b/contrib/hooks/multimail/README.Git index 300a2a4d2d..ee1fa75f99 100644 --- a/contrib/hooks/multimail/README.Git +++ b/contrib/hooks/multimail/README.Git @@ -6,10 +6,10 @@ website: https://github.com/git-multimail/git-multimail The version in this directory was obtained from the upstream project -on October 11 2015 and consists of the "git-multimail" subdirectory from +on May 03 2016 and consists of the "git-multimail" subdirectory from revision - c0791b9ef5821a746fc3475c25765e640452eaae refs/tags/1.2.0 + 26f3ae9f86aa7f8a054ba89235c4d3879f98b03d refs/tags/1.3.0 Please see the README file in this directory for information about how to report bugs or contribute to git-multimail. diff --git a/contrib/hooks/multimail/doc/customizing-emails.rst b/contrib/hooks/multimail/doc/customizing-emails.rst new file mode 100644 index 0000000000..3f5b67f768 --- /dev/null +++ b/contrib/hooks/multimail/doc/customizing-emails.rst @@ -0,0 +1,56 @@ +Customizing the content and formatting of emails +================================================ + +Overloading template strings +---------------------------- + +The content of emails is generated based on template strings defined +in ``git_multimail.py``. You can customize these template strings +without changing the script itself, by defining a Python wrapper +around it. The python wrapper should ``import git_multimail`` and then +override the ``git_multimail.*`` strings like this:: + + import sys # needed for sys.argv + + # Import and customize git_multimail: + import git_multimail + git_multimail.REVISION_INTRO_TEMPLATE = """...""" + git_multimail.COMBINED_INTRO_TEMPLATE = git_multimail.REVISION_INTRO_TEMPLATE + + # start git_multimail itself: + git_multimail.main(sys.argv[1:]) + +The template strings can use any value already used in the existing +templates (read the source code). + +Using HTML in template strings +------------------------------ + +If ``multimailhook.commitEmailFormat`` is set to HTML, then +git-multimail will generate HTML emails for commit notifications. The +log and diff will be formatted automatically by git-multimail. By +default, any HTML special character in the templates will be escaped. + +To use HTML formatting in the introduction of the email, set +``multimailhook.htmlInIntro`` to ``true``. Then, the template can +contain any HTML tags, that will be sent as-is in the email. For +example, to add some formatting and a link to the online commit, use +a format like:: + + git_multimail.REVISION_INTRO_TEMPLATE = """\ + This is an automated email from the git hooks/post-receive script.

+ + %(pusher)s pushed a commit to %(refname_type)s %(short_refname)s + in repository %(repo_shortname)s.
+ + View on GitHub. + """ + +Note that the values expanded from ``%(variable)s`` in the format +strings will still be escaped. + +For a less flexible but easier to set up way to add a link to commit +emails, see ``multimailhook.commitBrowseURL``. + +Similarly, one can set ``multimailhook.htmlInFooter`` and override any +of the ``*_FOOTER*`` template strings. diff --git a/contrib/hooks/multimail/doc/troubleshooting.rst b/contrib/hooks/multimail/doc/troubleshooting.rst new file mode 100644 index 0000000000..d3f346f076 --- /dev/null +++ b/contrib/hooks/multimail/doc/troubleshooting.rst @@ -0,0 +1,44 @@ +Troubleshooting issues with git-multimail: a FAQ +================================================ + +Git is not using the right address in the From/To/Reply-To field +---------------------------------------------------------------- + +First, make sure that git-multimail actually uses what you think it is +using. A lot happens to your email (especially when posting to a +mailing-list) between the time `git_multimail.py` sends it and the +time it reaches your inbox. + +A simple test (to do on a test repository, do not use in production as +it would disable email sending): change your post-receive hook to call +`git_multimail.py` with the `--stdout` option, and try to push to the +repository. You should see something like:: + + Counting objects: 3, done. + Writing objects: 100% (3/3), 263 bytes | 0 bytes/s, done. + Total 3 (delta 0), reused 0 (delta 0) + remote: Sending notification emails to: foo.bar@example.com + remote: =========================================================================== + remote: Date: Mon, 25 Apr 2016 18:39:59 +0200 + remote: To: foo.bar@example.com + remote: Subject: [git] branch master updated: foo + remote: MIME-Version: 1.0 + remote: Content-Type: text/plain; charset=utf-8 + remote: Content-Transfer-Encoding: 8bit + remote: Message-ID: <20160425163959.2311.20498@anie> + remote: From: Auth Or + remote: Reply-To: Auth Or + remote: X-Git-Host: example + ... + remote: -- + remote: To stop receiving notification emails like this one, please contact + remote: the administrator of this repository. + remote: =========================================================================== + To /path/to/repo + 6278f04..e173f20 master -> master + +Note: this does not include the sender (Return-Path: header), as it is +not part of the message content but passed to the mailer. Some mailer +show the ``Sender:`` field instead of the ``From:`` field (for +example, Zimbra Webmail shows ``From: on behalf of +``). diff --git a/contrib/hooks/multimail/git_multimail.py b/contrib/hooks/multimail/git_multimail.py index 0180dba431..f2c92aeed8 100755 --- a/contrib/hooks/multimail/git_multimail.py +++ b/contrib/hooks/multimail/git_multimail.py @@ -1,6 +1,6 @@ #! /usr/bin/env python -__version__ = '1.2.0' +__version__ = '1.3.0' # Copyright (c) 2015 Matthieu Moy and others # Copyright (c) 2012-2014 Michael Haggerty and others @@ -57,6 +57,11 @@ import shlex import optparse import smtplib +try: + import ssl +except ImportError: + # Python < 2.6 do not have ssl, but that's OK if we don't use it. + pass import time import cgi @@ -75,6 +80,9 @@ def is_ascii(s): if PYTHON3: + def is_string(s): + return isinstance(s, str) + def str_to_bytes(s): return s.encode(ENCODING) @@ -91,6 +99,12 @@ def write_str(f, msg): except UnicodeEncodeError: f.buffer.write(msg.encode(ENCODING)) else: + def is_string(s): + try: + return isinstance(s, basestring) + except NameError: # Silence Pyflakes warning + raise + def str_to_bytes(s): return s @@ -313,6 +327,16 @@ def next(it): """ +LINK_TEXT_TEMPLATE = """\ +View the commit online: +%(browse_url)s + +""" + +LINK_HTML_TEMPLATE = """\ +

View the commit online.

+""" + REVISION_FOOTER_TEMPLATE = FOOTER_TEMPLATE @@ -532,6 +556,28 @@ def _split(s): assert words[-1] == '' return words[:-1] + @staticmethod + def add_config_parameters(c): + """Add configuration parameters to Git. + + c is either an str or a list of str, each element being of the + form 'var=val' or 'var', with the same syntax and meaning as + the argument of 'git -c var=val'. + """ + if isinstance(c, str): + c = (c,) + parameters = os.environ.get('GIT_CONFIG_PARAMETERS', '') + if parameters: + parameters += ' ' + # git expects GIT_CONFIG_PARAMETERS to be of the form + # "'name1=value1' 'name2=value2' 'name3=value3'" + # including everything inside the double quotes (but not the double + # quotes themselves). Spacing is critical. Also, if a value contains + # a literal single quote that quote must be represented using the + # four character sequence: '\'' + parameters += ' '.join("'" + x.replace("'", "'\\''") + "'" for x in c) + os.environ['GIT_CONFIG_PARAMETERS'] = parameters + def get(self, name, default=None): try: values = self._split(read_git_output( @@ -745,6 +791,12 @@ def _compute_values(self): values['multimail_version'] = get_version() return values + # Aliases usable in template strings. Tuple of pairs (destination, + # source). + VALUES_ALIAS = ( + ("id", "newrev"), + ) + def get_values(self, **extra_values): """Return a dictionary {keyword: expansion} for this Change. @@ -760,6 +812,9 @@ def get_values(self, **extra_values): values = self._values.copy() if extra_values: values.update(extra_values) + + for alias, val in self.VALUES_ALIAS: + values[alias] = values[val] return values def expand(self, template, **extra_values): @@ -772,10 +827,14 @@ def expand(self, template, **extra_values): return template % self.get_values(**extra_values) - def expand_lines(self, template, **extra_values): + def expand_lines(self, template, html_escape_val=False, **extra_values): """Break template into lines and expand each line.""" values = self.get_values(**extra_values) + if html_escape_val: + for k in values: + if is_string(values[k]): + values[k] = cgi.escape(values[k], True) for line in template.splitlines(True): yield line % values @@ -787,9 +846,10 @@ def expand_header_lines(self, template, **extra_values): values = self.get_values(**extra_values) if self._contains_html_diff: - values['contenttype'] = 'html' + self._content_type = 'html' else: - values['contenttype'] = 'plain' + self._content_type = 'plain' + values['contenttype'] = self._content_type for line in template.splitlines(): (name, value) = line.split(': ', 1) @@ -819,7 +879,11 @@ def generate_email_header(self): raise NotImplementedError() - def generate_email_intro(self): + def generate_browse_link(self, base_url): + """Generate a link to an online repository browser.""" + return iter(()) + + def generate_email_intro(self, html_escape_val=False): """Generate the email intro for this Change, a line at a time. The output will be used as the standard boilerplate at the top @@ -835,7 +899,7 @@ def generate_email_body(self): raise NotImplementedError() - def generate_email_footer(self): + def generate_email_footer(self, html_escape_val): """Generate the footer of the email, a line at a time. The footer is always included, irrespective of @@ -876,9 +940,18 @@ def generate_email(self, push, body_filter=None, extra_header_values={}): for line in self.generate_email_header(**extra_header_values): yield line yield '\n' - for line in self._wrap_for_html(self.generate_email_intro()): + html_escape_val = (self.environment.html_in_intro and + self._contains_html_diff) + intro = self.generate_email_intro(html_escape_val) + if not self.environment.html_in_intro: + intro = self._wrap_for_html(intro) + for line in intro: yield line + if self.environment.commitBrowseURL: + for line in self.generate_browse_link(self.environment.commitBrowseURL): + yield line + body = self.generate_email_body(push) if body_filter is not None: body = body_filter(body) @@ -939,8 +1012,12 @@ def generate_email(self, push, body_filter=None, extra_header_values={}): yield line if self._contains_html_diff: yield '' - - for line in self._wrap_for_html(self.generate_email_footer()): + html_escape_val = (self.environment.html_in_footer and + self._contains_html_diff) + footer = self.generate_email_footer(html_escape_val) + if not self.environment.html_in_footer: + footer = self._wrap_for_html(footer) + for line in footer: yield line def get_alt_fromaddr(self): @@ -992,6 +1069,7 @@ def _compute_values(self): values['rev_short'] = self.rev.short values['change_type'] = self.change_type values['refname'] = self.refname + values['newrev'] = self.rev.sha1 values['short_refname'] = self.reference_change.short_refname values['refname_type'] = self.reference_change.refname_type values['reply_to_msgid'] = self.reference_change.msgid @@ -1015,8 +1093,26 @@ def generate_email_header(self, **extra_values): ): yield line - def generate_email_intro(self): - for line in self.expand_lines(REVISION_INTRO_TEMPLATE): + def generate_browse_link(self, base_url): + if '%(' not in base_url: + base_url += '%(id)s' + url = "".join(self.expand_lines(base_url)) + if self._content_type == 'html': + for line in self.expand_lines(LINK_HTML_TEMPLATE, + html_escape_val=True, + browse_url=url): + yield line + elif self._content_type == 'plain': + for line in self.expand_lines(LINK_TEXT_TEMPLATE, + html_escape_val=False, + browse_url=url): + yield line + else: + raise NotImplementedError("Content-type %s unsupported. Please report it as a bug.") + + def generate_email_intro(self, html_escape_val=False): + for line in self.expand_lines(REVISION_INTRO_TEMPLATE, + html_escape_val=html_escape_val): yield line def generate_email_body(self, push): @@ -1031,8 +1127,9 @@ def generate_email_body(self, push): else: yield line - def generate_email_footer(self): - return self.expand_lines(REVISION_FOOTER_TEMPLATE) + def generate_email_footer(self, html_escape_val): + return self.expand_lines(REVISION_FOOTER_TEMPLATE, + html_escape_val=html_escape_val) def generate_email(self, push, body_filter=None, extra_header_values={}): self._contains_diff() @@ -1217,8 +1314,9 @@ def generate_email_header(self, **extra_values): ): yield line - def generate_email_intro(self): - for line in self.expand_lines(self.intro_template): + def generate_email_intro(self, html_escape_val=False): + for line in self.expand_lines(self.intro_template, + html_escape_val=html_escape_val): yield line def generate_email_body(self, push): @@ -1238,8 +1336,9 @@ def generate_email_body(self, push): for line in self.generate_revision_change_summary(push): yield line - def generate_email_footer(self): - return self.expand_lines(self.footer_template) + def generate_email_footer(self, html_escape_val): + return self.expand_lines(self.footer_template, + html_escape_val=html_escape_val) def generate_revision_change_graph(self, push): if self.showgraph: @@ -1896,6 +1995,7 @@ def __init__(self, envelopesender, smtpserver, smtpservertimeout=10.0, smtpserverdebuglevel=0, smtpencryption='none', smtpuser='', smtppass='', + smtpcacerts='' ): if not envelopesender: sys.stderr.write( @@ -1915,6 +2015,7 @@ def __init__(self, envelopesender, smtpserver, self.security = smtpencryption self.username = smtpuser self.password = smtppass + self.smtpcacerts = smtpcacerts try: def call(klass, server, timeout): try: @@ -1925,13 +2026,56 @@ def call(klass, server, timeout): if self.security == 'none': self.smtp = call(smtplib.SMTP, self.smtpserver, timeout=self.smtpservertimeout) elif self.security == 'ssl': + if self.smtpcacerts: + raise smtplib.SMTPException( + "Checking certificate is not supported for ssl, prefer starttls" + ) self.smtp = call(smtplib.SMTP_SSL, self.smtpserver, timeout=self.smtpservertimeout) elif self.security == 'tls': + if 'ssl' not in sys.modules: + sys.stderr.write( + '*** Your Python version does not have the ssl library installed\n' + '*** smtpEncryption=tls is not available.\n' + '*** Either upgrade Python to 2.6 or later\n' + ' or use git_multimail.py version 1.2.\n') if ':' not in self.smtpserver: self.smtpserver += ':587' # default port for TLS self.smtp = call(smtplib.SMTP, self.smtpserver, timeout=self.smtpservertimeout) + # start: ehlo + starttls + # equivalent to + # self.smtp.ehlo() + # self.smtp.starttls() + # with acces to the ssl layer self.smtp.ehlo() - self.smtp.starttls() + if not self.smtp.has_extn("starttls"): + raise smtplib.SMTPException("STARTTLS extension not supported by server") + resp, reply = self.smtp.docmd("STARTTLS") + if resp != 220: + raise smtplib.SMTPException("Wrong answer to the STARTTLS command") + if self.smtpcacerts: + self.smtp.sock = ssl.wrap_socket( + self.smtp.sock, + ca_certs=self.smtpcacerts, + cert_reqs=ssl.CERT_REQUIRED + ) + else: + self.smtp.sock = ssl.wrap_socket( + self.smtp.sock, + cert_reqs=ssl.CERT_NONE + ) + sys.stderr.write( + '*** Warning, the server certificat is not verified (smtp) ***\n' + '*** set the option smtpCACerts ***\n' + ) + if not hasattr(self.smtp.sock, "read"): + # using httplib.FakeSocket with Python 2.5.x or earlier + self.smtp.sock.read = self.smtp.sock.recv + self.smtp.file = smtplib.SSLFakeFile(self.smtp.sock) + self.smtp.helo_resp = None + self.smtp.ehlo_resp = None + self.smtp.esmtp_features = {} + self.smtp.does_esmtp = 0 + # end: ehlo + starttls self.smtp.ehlo() else: sys.stdout.write('*** Error: Control reached an invalid option. ***') @@ -1951,6 +2095,7 @@ def call(klass, server, timeout): def __del__(self): if hasattr(self, 'smtp'): self.smtp.quit() + del self.smtp def send(self, lines, to_addrs): try: @@ -1958,13 +2103,24 @@ def send(self, lines, to_addrs): self.smtp.login(self.username, self.password) msg = ''.join(lines) # turn comma-separated list into Python list if needed. - if isinstance(to_addrs, basestring): + if is_string(to_addrs): to_addrs = [email for (name, email) in getaddresses([to_addrs])] self.smtp.sendmail(self.envelopesender, to_addrs, msg) - except Exception: + except smtplib.SMTPResponseException: sys.stderr.write('*** Error sending email ***\n') - sys.stderr.write('*** %s\n' % sys.exc_info()[1]) - self.smtp.quit() + err = sys.exc_info()[1] + sys.stderr.write('*** Error %d: %s\n' % (err.smtp_code, + bytes_to_str(err.smtp_error))) + try: + smtp = self.smtp + # delete the field before quit() so that in case of + # error, self.smtp is deleted anyway. + del self.smtp + smtp.quit() + except: + sys.stderr.write('*** Error closing the SMTP connection ***\n') + sys.stderr.write('*** Exiting anyway ... ***\n') + sys.stderr.write('*** %s\n' % sys.exc_info()[1]) sys.exit(1) @@ -2097,6 +2253,14 @@ class Environment(object): If "html", generate commit emails in HTML instead of plain text used by default. + html_in_intro (bool) + html_in_footer (bool) + + When generating HTML emails, the introduction (respectively, + the footer) will be HTML-escaped iff html_in_intro (respectively, + the footer) is true. When false, only the values used to expand + the template are escaped. + refchange_showgraph (bool) True iff refchanges emails should include a detailed graph. @@ -2160,6 +2324,9 @@ def __init__(self, osenv=None): self.osenv = osenv or os.environ self.announce_show_shortlog = False self.commit_email_format = "text" + self.html_in_intro = False + self.html_in_footer = False + self.commitBrowseURL = None self.maxcommitemails = 500 self.diffopts = ['--stat', '--summary', '--find-copies-harder'] self.graphopts = ['--oneline', '--decorate'] @@ -2236,7 +2403,7 @@ def get_values(self): The return value is always a new dictionary.""" if self._values is None: - values = {} + values = {'': ''} # %()s expands to the empty string. for key in self.COMPUTED_KEYS: value = getattr(self, 'get_%s' % (key,))() @@ -2375,6 +2542,16 @@ def __init__(self, config, **kw): else: self.commit_email_format = commit_email_format + html_in_intro = config.get_bool('htmlInIntro') + if html_in_intro is not None: + self.html_in_intro = html_in_intro + + html_in_footer = config.get_bool('htmlInFooter') + if html_in_footer is not None: + self.html_in_footer = html_in_footer + + self.commitBrowseURL = config.get('commitBrowseURL') + maxcommitemails = config.get('maxcommitemails') if maxcommitemails is not None: try: @@ -2415,7 +2592,6 @@ def __init__(self, config, **kw): ['author']) self.__reply_to_commit = config.get('replyToCommit', default=reply_to) - from_addr = self.config.get('from') self.from_refchange = config.get('fromRefchange') self.forbid_field_values('fromRefchange', self.from_refchange, @@ -3390,6 +3566,8 @@ def run_as_post_receive_hook(environment, mailer): if changes: push = Push(environment, changes) push.send_emails(mailer, body_filter=environment.filter_body) + if hasattr(mailer, '__del__'): + mailer.__del__() def run_as_update_hook(environment, mailer, refname, oldrev, newrev, force_send=False): @@ -3406,6 +3584,8 @@ def run_as_update_hook(environment, mailer, refname, oldrev, newrev, force_send= ] push = Push(environment, changes, force_send) push.send_emails(mailer, body_filter=environment.filter_body) + if hasattr(mailer, '__del__'): + mailer.__del__() def choose_mailer(config, environment): @@ -3418,6 +3598,7 @@ def choose_mailer(config, environment): smtpencryption = config.get('smtpencryption', default='none') smtpuser = config.get('smtpuser', default='') smtppass = config.get('smtppass', default='') + smtpcacerts = config.get('smtpcacerts', default='') mailer = SMTPMailer( envelopesender=(environment.get_sender() or environment.get_fromaddr()), smtpserver=smtpserver, smtpservertimeout=smtpservertimeout, @@ -3425,6 +3606,7 @@ def choose_mailer(config, environment): smtpencryption=smtpencryption, smtpuser=smtpuser, smtppass=smtppass, + smtpcacerts=smtpcacerts ) elif mailer == 'sendmail': command = config.get('sendmailcommand') @@ -3691,17 +3873,7 @@ def main(args): return if options.c: - parameters = os.environ.get('GIT_CONFIG_PARAMETERS', '') - if parameters: - parameters += ' ' - # git expects GIT_CONFIG_PARAMETERS to be of the form - # "'name1=value1' 'name2=value2' 'name3=value3'" - # including everything inside the double quotes (but not the double - # quotes themselves). Spacing is critical. Also, if a value contains - # a literal single quote that quote must be represented using the - # four character sequence: '\'' - parameters += ' '.join("'" + x.replace("'", "'\\''") + "'" for x in options.c) - os.environ['GIT_CONFIG_PARAMETERS'] = parameters + Config.add_config_parameters(options.c) config = Config('multimailhook') diff --git a/contrib/hooks/multimail/post-receive.example b/contrib/hooks/multimail/post-receive.example index 9975df7107..1ea113d274 100755 --- a/contrib/hooks/multimail/post-receive.example +++ b/contrib/hooks/multimail/post-receive.example @@ -55,6 +55,12 @@ import git_multimail # git-multimail: config = git_multimail.Config('multimailhook') +# Set some Git configuration variables. Equivalent to passing var=val +# to "git -c var=val" each time git is called, or to adding the +# configuration in .git/config (must come before instanciating the +# environment) : +#git_multimail.Config.add_config_parameters('multimailhook.commitEmailFormat=html') +#git_multimail.Config.add_config_parameters(('user.name=foo', 'user.email=foo@example.com')) # Select the type of environment: try: diff --git a/contrib/subtree/Makefile b/contrib/subtree/Makefile index 3071baf493..6afa9aafdf 100644 --- a/contrib/subtree/Makefile +++ b/contrib/subtree/Makefile @@ -37,6 +37,7 @@ GIT_SUBTREE_DOC := git-subtree.1 GIT_SUBTREE_XML := git-subtree.xml GIT_SUBTREE_TXT := git-subtree.txt GIT_SUBTREE_HTML := git-subtree.html +GIT_SUBTREE_TEST := ../../git-subtree all:: $(GIT_SUBTREE) @@ -71,7 +72,10 @@ $(GIT_SUBTREE_HTML): $(GIT_SUBTREE_TXT) $(ASCIIDOC) -b xhtml11 -d manpage -f $(ASCIIDOC_CONF) \ -agit_version=$(GIT_VERSION) $^ -test: +$(GIT_SUBTREE_TEST): $(GIT_SUBTREE) + cp $< $@ + +test: $(GIT_SUBTREE_TEST) $(MAKE) -C t/ test clean: diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index 5c8372709b..7a39b30ad0 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -245,7 +245,10 @@ find_latest_squash() case "$a" in START) sq="$b" ;; git-subtree-mainline:) main="$b" ;; - git-subtree-split:) sub="$b" ;; + git-subtree-split:) + sub="$(git rev-parse "$b^0")" || + die "could not rev-parse split hash $b from commit $sq" + ;; END) if [ -n "$sub" ]; then if [ -n "$main" ]; then @@ -278,7 +281,10 @@ find_existing_splits() case "$a" in START) sq="$b" ;; git-subtree-mainline:) main="$b" ;; - git-subtree-split:) sub="$b" ;; + git-subtree-split:) + sub="$(git rev-parse "$b^0")" || + die "could not rev-parse split hash $b from commit $sq" + ;; END) debug " Main is: '$main'" if [ -z "$main" -a -n "$sub" ]; then diff --git a/contrib/thunderbird-patch-inline/appp.sh b/contrib/thunderbird-patch-inline/appp.sh index 8dc73ece15..1053872eea 100755 --- a/contrib/thunderbird-patch-inline/appp.sh +++ b/contrib/thunderbird-patch-inline/appp.sh @@ -31,8 +31,8 @@ BODY=$(sed -e "1,/${SEP}/d" $1) CMT_MSG=$(sed -e '1,/^$/d' -e '/^---$/,$d' "${PATCH}") DIFF=$(sed -e '1,/^---$/d' "${PATCH}") -CCS=`echo -e "$CMT_MSG\n$HEADERS" | sed -n -e 's/^Cc: \(.*\)$/\1,/gp' \ - -e 's/^Signed-off-by: \(.*\)/\1,/gp'` +CCS=$(echo -e "$CMT_MSG\n$HEADERS" | sed -n -e 's/^Cc: \(.*\)$/\1,/gp' \ + -e 's/^Signed-off-by: \(.*\)/\1,/gp') echo "$SUBJECT" > $1 echo "Cc: $CCS" >> $1 diff --git a/convert.c b/convert.c index 814e814438..b1614bf7ff 100644 --- a/convert.c +++ b/convert.c @@ -13,18 +13,25 @@ * translation when the "text" attribute or "auto_crlf" option is set. */ +/* Stat bits: When BIN is set, the txt bits are unset */ +#define CONVERT_STAT_BITS_TXT_LF 0x1 +#define CONVERT_STAT_BITS_TXT_CRLF 0x2 +#define CONVERT_STAT_BITS_BIN 0x4 + enum crlf_action { - CRLF_GUESS = -1, - CRLF_BINARY = 0, + CRLF_UNDEFINED, + CRLF_BINARY, CRLF_TEXT, - CRLF_INPUT, - CRLF_CRLF, - CRLF_AUTO + CRLF_TEXT_INPUT, + CRLF_TEXT_CRLF, + CRLF_AUTO, + CRLF_AUTO_INPUT, + CRLF_AUTO_CRLF }; struct text_stat { /* NUL, CR, LF and CRLF counts */ - unsigned nul, cr, lf, crlf; + unsigned nul, lonecr, lonelf, crlf; /* These are just approximations! */ unsigned printable, nonprintable; @@ -39,13 +46,15 @@ static void gather_stats(const char *buf, unsigned long size, struct text_stat * for (i = 0; i < size; i++) { unsigned char c = buf[i]; if (c == '\r') { - stats->cr++; - if (i+1 < size && buf[i+1] == '\n') + if (i+1 < size && buf[i+1] == '\n') { stats->crlf++; + i++; + } else + stats->lonecr++; continue; } if (c == '\n') { - stats->lf++; + stats->lonelf++; continue; } if (c == 127) @@ -75,23 +84,84 @@ static void gather_stats(const char *buf, unsigned long size, struct text_stat * /* * The same heuristics as diff.c::mmfile_is_binary() + * We treat files with bare CR as binary */ -static int is_binary(unsigned long size, struct text_stat *stats) +static int convert_is_binary(unsigned long size, const struct text_stat *stats) { - + if (stats->lonecr) + return 1; if (stats->nul) return 1; if ((stats->printable >> 7) < stats->nonprintable) return 1; - /* - * Other heuristics? Average line length might be relevant, - * as might LF vs CR vs CRLF counts.. - * - * NOTE! It might be normal to have a low ratio of CRLF to LF - * (somebody starts with a LF-only file and edits it with an editor - * that adds CRLF only to lines that are added..). But do we - * want to support CR-only? Probably not. - */ + return 0; +} + +static unsigned int gather_convert_stats(const char *data, unsigned long size) +{ + struct text_stat stats; + int ret = 0; + if (!data || !size) + return 0; + gather_stats(data, size, &stats); + if (convert_is_binary(size, &stats)) + ret |= CONVERT_STAT_BITS_BIN; + if (stats.crlf) + ret |= CONVERT_STAT_BITS_TXT_CRLF; + if (stats.lonelf) + ret |= CONVERT_STAT_BITS_TXT_LF; + + return ret; +} + +static const char *gather_convert_stats_ascii(const char *data, unsigned long size) +{ + unsigned int convert_stats = gather_convert_stats(data, size); + + if (convert_stats & CONVERT_STAT_BITS_BIN) + return "-text"; + switch (convert_stats) { + case CONVERT_STAT_BITS_TXT_LF: + return "lf"; + case CONVERT_STAT_BITS_TXT_CRLF: + return "crlf"; + case CONVERT_STAT_BITS_TXT_LF | CONVERT_STAT_BITS_TXT_CRLF: + return "mixed"; + default: + return "none"; + } +} + +const char *get_cached_convert_stats_ascii(const char *path) +{ + const char *ret; + unsigned long sz; + void *data = read_blob_data_from_cache(path, &sz); + ret = gather_convert_stats_ascii(data, sz); + free(data); + return ret; +} + +const char *get_wt_convert_stats_ascii(const char *path) +{ + const char *ret = ""; + struct strbuf sb = STRBUF_INIT; + if (strbuf_read_file(&sb, path, 0) >= 0) + ret = gather_convert_stats_ascii(sb.buf, sb.len); + strbuf_release(&sb); + return ret; +} + +static int text_eol_is_crlf(void) +{ + if (auto_crlf == AUTO_CRLF_TRUE) + return 1; + else if (auto_crlf == AUTO_CRLF_INPUT) + return 0; + if (core_eol == EOL_CRLF) + return 1; + if (core_eol == EOL_UNSET && EOL_NATIVE == EOL_CRLF) + return 1; return 0; } @@ -100,23 +170,19 @@ static enum eol output_eol(enum crlf_action crlf_action) switch (crlf_action) { case CRLF_BINARY: return EOL_UNSET; - case CRLF_CRLF: + case CRLF_TEXT_CRLF: return EOL_CRLF; - case CRLF_INPUT: + case CRLF_TEXT_INPUT: return EOL_LF; - case CRLF_GUESS: - if (!auto_crlf) - return EOL_UNSET; - /* fall through */ + case CRLF_UNDEFINED: + case CRLF_AUTO_CRLF: + case CRLF_AUTO_INPUT: case CRLF_TEXT: case CRLF_AUTO: - if (auto_crlf == AUTO_CRLF_TRUE) - return EOL_CRLF; - else if (auto_crlf == AUTO_CRLF_INPUT) - return EOL_LF; - else if (core_eol == EOL_UNSET) - return EOL_NATIVE; + /* fall through */ + return text_eol_is_crlf() ? EOL_CRLF : EOL_LF; } + warning("Illegal crlf_action %d\n", (int)crlf_action); return core_eol; } @@ -142,7 +208,7 @@ static void check_safe_crlf(const char *path, enum crlf_action crlf_action, * CRLFs would be added by checkout: * check if we have "naked" LFs */ - if (stats->lf != stats->crlf) { + if (stats->lonelf) { if (checksafe == SAFE_CRLF_WARN) warning("LF will be replaced by CRLF in %s.\nThe file will have its original line endings in your working directory.", path); else /* i.e. SAFE_CRLF_FAIL */ @@ -173,7 +239,6 @@ static int crlf_to_git(const char *path, const char *src, size_t len, char *dst; if (crlf_action == CRLF_BINARY || - (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE) || (src && !len)) return 0; @@ -186,22 +251,11 @@ static int crlf_to_git(const char *path, const char *src, size_t len, gather_stats(src, len, &stats); - if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) { - /* - * We're currently not going to even try to convert stuff - * that has bare CR characters. Does anybody do that crazy - * stuff? - */ - if (stats.cr != stats.crlf) + if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) { + if (convert_is_binary(len, &stats)) return 0; - /* - * And add some heuristics for binary vs text, of course... - */ - if (is_binary(len, &stats)) - return 0; - - if (crlf_action == CRLF_GUESS) { + if (crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) { /* * If the file in the index has any CR in it, do not convert. * This is the new safer autocrlf handling. @@ -213,8 +267,8 @@ static int crlf_to_git(const char *path, const char *src, size_t len, check_safe_crlf(path, crlf_action, &stats, checksafe); - /* Optimization: No CR? Nothing to convert, regardless. */ - if (!stats.cr) + /* Optimization: No CRLF? Nothing to convert, regardless. */ + if (!stats.crlf) return 0; /* @@ -228,7 +282,7 @@ static int crlf_to_git(const char *path, const char *src, size_t len, if (strbuf_avail(buf) + buf->len < len) strbuf_grow(buf, len - buf->len); dst = buf->buf; - if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) { + if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) { /* * If we guessed, we already know we rejected a file with * lone CR, and we can strip a CR without looking at what @@ -261,27 +315,19 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len, gather_stats(src, len, &stats); - /* No LF? Nothing to convert, regardless. */ - if (!stats.lf) - return 0; - - /* Was it already in CRLF format? */ - if (stats.lf == stats.crlf) + /* No "naked" LF? Nothing to convert, regardless. */ + if (!stats.lonelf) return 0; - if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) { - if (crlf_action == CRLF_GUESS) { + if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) { + if (crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) { /* If we have any CR or CRLF line endings, we do not touch it */ /* This is the new safer autocrlf-handling */ - if (stats.cr > 0 || stats.crlf > 0) + if (stats.lonecr || stats.crlf ) return 0; } - /* If we have any bare CR characters, we're not going to touch it */ - if (stats.cr != stats.crlf) - return 0; - - if (is_binary(len, &stats)) + if (convert_is_binary(len, &stats)) return 0; } @@ -289,7 +335,7 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len, if (src == buf->buf) to_free = strbuf_detach(buf, NULL); - strbuf_grow(buf, len + stats.lf - stats.crlf); + strbuf_grow(buf, len + stats.lonelf); for (;;) { const char *nl = memchr(src, '\n', len); if (!nl) @@ -395,7 +441,7 @@ static int apply_filter(const char *path, const char *src, size_t len, int fd, struct async async; struct filter_params params; - if (!cmd) + if (!cmd || !*cmd) return 0; if (!dst) @@ -657,7 +703,7 @@ static int ident_to_worktree(const char *path, const char *src, size_t len, return 1; } -static enum crlf_action git_path_check_crlf(const char *path, struct git_attr_check *check) +static enum crlf_action git_path_check_crlf(struct git_attr_check *check) { const char *value = check->value; @@ -668,13 +714,13 @@ static enum crlf_action git_path_check_crlf(const char *path, struct git_attr_ch else if (ATTR_UNSET(value)) ; else if (!strcmp(value, "input")) - return CRLF_INPUT; + return CRLF_TEXT_INPUT; else if (!strcmp(value, "auto")) return CRLF_AUTO; - return CRLF_GUESS; + return CRLF_UNDEFINED; } -static enum eol git_path_check_eol(const char *path, struct git_attr_check *check) +static enum eol git_path_check_eol(struct git_attr_check *check) { const char *value = check->value; @@ -687,8 +733,7 @@ static enum eol git_path_check_eol(const char *path, struct git_attr_check *chec return EOL_UNSET; } -static struct convert_driver *git_path_check_convert(const char *path, - struct git_attr_check *check) +static struct convert_driver *git_path_check_convert(struct git_attr_check *check) { const char *value = check->value; struct convert_driver *drv; @@ -701,28 +746,17 @@ static struct convert_driver *git_path_check_convert(const char *path, return NULL; } -static int git_path_check_ident(const char *path, struct git_attr_check *check) +static int git_path_check_ident(struct git_attr_check *check) { const char *value = check->value; return !!ATTR_TRUE(value); } -static enum crlf_action input_crlf_action(enum crlf_action text_attr, enum eol eol_attr) -{ - if (text_attr == CRLF_BINARY) - return CRLF_BINARY; - if (eol_attr == EOL_LF) - return CRLF_INPUT; - if (eol_attr == EOL_CRLF) - return CRLF_CRLF; - return text_attr; -} - struct conv_attrs { struct convert_driver *drv; - enum crlf_action crlf_action; - enum eol eol_attr; + enum crlf_action attr_action; /* What attr says */ + enum crlf_action crlf_action; /* When no attr is set, use core.autocrlf */ int ident; }; @@ -744,18 +778,33 @@ static void convert_attrs(struct conv_attrs *ca, const char *path) } if (!git_check_attr(path, NUM_CONV_ATTRS, ccheck)) { - ca->crlf_action = git_path_check_crlf(path, ccheck + 4); - if (ca->crlf_action == CRLF_GUESS) - ca->crlf_action = git_path_check_crlf(path, ccheck + 0); - ca->ident = git_path_check_ident(path, ccheck + 1); - ca->drv = git_path_check_convert(path, ccheck + 2); - ca->eol_attr = git_path_check_eol(path, ccheck + 3); + ca->crlf_action = git_path_check_crlf(ccheck + 4); + if (ca->crlf_action == CRLF_UNDEFINED) + ca->crlf_action = git_path_check_crlf(ccheck + 0); + ca->attr_action = ca->crlf_action; + ca->ident = git_path_check_ident(ccheck + 1); + ca->drv = git_path_check_convert(ccheck + 2); + if (ca->crlf_action != CRLF_BINARY) { + enum eol eol_attr = git_path_check_eol(ccheck + 3); + if (eol_attr == EOL_LF) + ca->crlf_action = CRLF_TEXT_INPUT; + else if (eol_attr == EOL_CRLF) + ca->crlf_action = CRLF_TEXT_CRLF; + } + ca->attr_action = ca->crlf_action; } else { ca->drv = NULL; - ca->crlf_action = CRLF_GUESS; - ca->eol_attr = EOL_UNSET; + ca->crlf_action = CRLF_UNDEFINED; ca->ident = 0; } + if (ca->crlf_action == CRLF_TEXT) + ca->crlf_action = text_eol_is_crlf() ? CRLF_TEXT_CRLF : CRLF_TEXT_INPUT; + if (ca->crlf_action == CRLF_UNDEFINED && auto_crlf == AUTO_CRLF_FALSE) + ca->crlf_action = CRLF_BINARY; + if (ca->crlf_action == CRLF_UNDEFINED && auto_crlf == AUTO_CRLF_TRUE) + ca->crlf_action = CRLF_AUTO_CRLF; + if (ca->crlf_action == CRLF_UNDEFINED && auto_crlf == AUTO_CRLF_INPUT) + ca->crlf_action = CRLF_AUTO_INPUT; } int would_convert_to_git_filter_fd(const char *path) @@ -777,6 +826,32 @@ int would_convert_to_git_filter_fd(const char *path) return apply_filter(path, NULL, 0, -1, NULL, ca.drv->clean); } +const char *get_convert_attr_ascii(const char *path) +{ + struct conv_attrs ca; + + convert_attrs(&ca, path); + switch (ca.attr_action) { + case CRLF_UNDEFINED: + return ""; + case CRLF_BINARY: + return "-text"; + case CRLF_TEXT: + return "text"; + case CRLF_TEXT_INPUT: + return "text eol=lf"; + case CRLF_TEXT_CRLF: + return "text eol=crlf"; + case CRLF_AUTO: + return "text=auto"; + case CRLF_AUTO_CRLF: + return "text=auto eol=crlf"; /* This is not supported yet */ + case CRLF_AUTO_INPUT: + return "text=auto eol=lf"; /* This is not supported yet */ + } + return ""; +} + int convert_to_git(const char *path, const char *src, size_t len, struct strbuf *dst, enum safe_crlf checksafe) { @@ -799,7 +874,6 @@ int convert_to_git(const char *path, const char *src, size_t len, src = dst->buf; len = dst->len; } - ca.crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr); ret |= crlf_to_git(path, src, len, dst, ca.crlf_action, checksafe); if (ret && dst) { src = dst->buf; @@ -820,7 +894,6 @@ void convert_to_git_filter_fd(const char *path, int fd, struct strbuf *dst, if (!apply_filter(path, NULL, 0, fd, dst, ca.drv->clean)) die("%s: clean filter '%s' failed", path, ca.drv->name); - ca.crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr); crlf_to_git(path, dst->buf, dst->len, dst, ca.crlf_action, checksafe); ident_to_git(path, dst->buf, dst->len, dst, ca.ident); } @@ -850,7 +923,6 @@ static int convert_to_working_tree_internal(const char *path, const char *src, * is a smudge filter. The filter might expect CRLFs. */ if (filter || !normalizing) { - ca.crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr); ret |= crlf_to_worktree(path, src, len, dst, ca.crlf_action); if (ret) { src = dst->buf; @@ -1308,26 +1380,22 @@ static struct stream_filter *ident_filter(const unsigned char *sha1) struct stream_filter *get_stream_filter(const char *path, const unsigned char *sha1) { struct conv_attrs ca; - enum crlf_action crlf_action; struct stream_filter *filter = NULL; convert_attrs(&ca, path); - if (ca.drv && (ca.drv->smudge || ca.drv->clean)) - return filter; + return NULL; + + if (ca.crlf_action == CRLF_AUTO || ca.crlf_action == CRLF_AUTO_CRLF) + return NULL; if (ca.ident) filter = ident_filter(sha1); - crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr); - - if ((crlf_action == CRLF_BINARY) || (crlf_action == CRLF_INPUT) || - (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE)) - filter = cascade_filter(filter, &null_filter_singleton); - - else if (output_eol(crlf_action) == EOL_CRLF && - !(crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS)) + if (output_eol(ca.crlf_action) == EOL_CRLF) filter = cascade_filter(filter, lf_to_crlf_filter()); + else + filter = cascade_filter(filter, &null_filter_singleton); return filter; } diff --git a/convert.h b/convert.h index d9d853cd3d..ccf436bfbf 100644 --- a/convert.h +++ b/convert.h @@ -32,6 +32,9 @@ enum eol { }; extern enum eol core_eol; +extern const char *get_cached_convert_stats_ascii(const char *path); +extern const char *get_wt_convert_stats_ascii(const char *path); +extern const char *get_convert_attr_ascii(const char *path); /* returns 1 if *dst was used */ extern int convert_to_git(const char *path, const char *src, size_t len, diff --git a/credential-cache--daemon.c b/credential-cache--daemon.c index 9365f2ce5c..291c0fd5e9 100644 --- a/credential-cache--daemon.c +++ b/credential-cache--daemon.c @@ -96,12 +96,12 @@ static int read_request(FILE *fh, struct credential *c, static struct strbuf item = STRBUF_INIT; const char *p; - strbuf_getline(&item, fh, '\n'); + strbuf_getline_lf(&item, fh); if (!skip_prefix(item.buf, "action=", &p)) return error("client sent bogus action line: %s", item.buf); strbuf_addstr(action, p); - strbuf_getline(&item, fh, '\n'); + strbuf_getline_lf(&item, fh); if (!skip_prefix(item.buf, "timeout=", &p)) return error("client sent bogus timeout line: %s", item.buf); *timeout = atoi(p); @@ -126,8 +126,17 @@ static void serve_one_client(FILE *in, FILE *out) fprintf(out, "password=%s\n", e->item.password); } } - else if (!strcmp(action.buf, "exit")) + else if (!strcmp(action.buf, "exit")) { + /* + * It's important that we clean up our socket first, and then + * signal the client only once we have finished the cleanup. + * Calling exit() directly does this, because we clean up in + * our atexit() handler, and then signal the client when our + * process actually ends, which closes the socket and gives + * them EOF. + */ exit(0); + } else if (!strcmp(action.buf, "erase")) remove_credential(&c); else if (!strcmp(action.buf, "store")) { @@ -215,7 +224,7 @@ static const char permissions_advice[] = "users may be able to read your cached credentials. Consider running:\n" "\n" " chmod 0700 %s"; -static void check_socket_directory(const char *path) +static void init_socket_directory(const char *path) { struct stat st; char *path_copy = xstrdup(path); @@ -224,20 +233,27 @@ static void check_socket_directory(const char *path) if (!stat(dir, &st)) { if (st.st_mode & 077) die(permissions_advice, dir); - free(path_copy); - return; + } else { + /* + * We must be sure to create the directory with the correct mode, + * not just chmod it after the fact; otherwise, there is a race + * condition in which somebody can chdir to it, sleep, then try to open + * our protected socket. + */ + if (safe_create_leading_directories_const(dir) < 0) + die_errno("unable to create directories for '%s'", dir); + if (mkdir(dir, 0700) < 0) + die_errno("unable to mkdir '%s'", dir); } - /* - * We must be sure to create the directory with the correct mode, - * not just chmod it after the fact; otherwise, there is a race - * condition in which somebody can chdir to it, sleep, then try to open - * our protected socket. - */ - if (safe_create_leading_directories_const(dir) < 0) - die_errno("unable to create directories for '%s'", dir); - if (mkdir(dir, 0700) < 0) - die_errno("unable to mkdir '%s'", dir); + if (chdir(dir)) + /* + * We don't actually care what our cwd is; we chdir here just to + * be a friendly daemon and avoid tying up our original cwd. + * If this fails, it's OK to just continue without that benefit. + */ + ; + free(path_copy); } @@ -264,7 +280,10 @@ int main(int argc, const char **argv) if (!socket_path) usage_with_options(usage, options); - check_socket_directory(socket_path); + if (!is_absolute_path(socket_path)) + die("socket directory must be an absolute path"); + + init_socket_directory(socket_path); register_tempfile(&socket_file, socket_path); if (ignore_sighup) diff --git a/credential-cache.c b/credential-cache.c index f4afdc6988..86e21de49b 100644 --- a/credential-cache.c +++ b/credential-cache.c @@ -32,6 +32,7 @@ static int send_request(const char *socket, const struct strbuf *out) write_or_die(1, in, r); got_data = 1; } + close(fd); return got_data; } diff --git a/credential-store.c b/credential-store.c index 54c4e04737..57141679ab 100644 --- a/credential-store.c +++ b/credential-store.c @@ -23,7 +23,7 @@ static int parse_credential_file(const char *fn, return found_credential; } - while (strbuf_getline(&line, fh, '\n') != EOF) { + while (strbuf_getline_lf(&line, fh) != EOF) { credential_from_url(&entry, line.buf); if (entry.username && entry.password && credential_match(c, &entry)) { diff --git a/credential.c b/credential.c index b146ad8481..7d6501d190 100644 --- a/credential.c +++ b/credential.c @@ -142,7 +142,7 @@ int credential_read(struct credential *c, FILE *fp) { struct strbuf line = STRBUF_INIT; - while (strbuf_getline(&line, fp, '\n') != EOF) { + while (strbuf_getline_lf(&line, fp) != EOF) { char *key = line.buf; char *value = strchr(key, '='); diff --git a/daemon.c b/daemon.c index 1e258ac8f9..8d45c336f5 100644 --- a/daemon.c +++ b/daemon.c @@ -424,7 +424,7 @@ static void copy_to_log(int fd) return; } - while (strbuf_getline(&line, fp, '\n') != EOF) { + while (strbuf_getline_lf(&line, fp) != EOF) { logerror("%s", line.buf); strbuf_setlen(&line, 0); } diff --git a/diffcore-rename.c b/diffcore-rename.c index 3b3c1ed535..7f03eb5a04 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -340,9 +340,11 @@ static int find_exact_renames(struct diff_options *options) int i, renames = 0; struct hashmap file_table; - /* Add all sources to the hash table */ + /* Add all sources to the hash table in reverse order, because + * later on they will be retrieved in LIFO order. + */ hashmap_init(&file_table, NULL, rename_src_nr); - for (i = 0; i < rename_src_nr; i++) + for (i = rename_src_nr-1; i >= 0; i--) insert_file_table(&file_table, i, rename_src[i].p->one); /* Walk the destinations and find best source match */ diff --git a/dir.c b/dir.c index 3087b7eb2e..656f272adc 100644 --- a/dir.c +++ b/dir.c @@ -64,13 +64,6 @@ int strncmp_icase(const char *a, const char *b, size_t count) return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count); } -int fnmatch_icase(const char *pattern, const char *string, int flags) -{ - return wildmatch(pattern, string, - flags | (ignore_case ? WM_CASEFOLD : 0), - NULL); -} - int git_fnmatch(const struct pathspec_item *item, const char *pattern, const char *string, int prefix) @@ -457,7 +450,7 @@ int no_wildcard(const char *string) void parse_exclude_pattern(const char **pattern, int *patternlen, - int *flags, + unsigned *flags, int *nowildcardlen) { const char *p = *pattern; @@ -498,7 +491,7 @@ void add_exclude(const char *string, const char *base, { struct exclude *x; int patternlen; - int flags; + unsigned flags; int nowildcardlen; parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen); @@ -798,7 +791,7 @@ void add_excludes_from_file(struct dir_struct *dir, const char *fname) int match_basename(const char *basename, int basenamelen, const char *pattern, int prefix, int patternlen, - int flags) + unsigned flags) { if (prefix == patternlen) { if (patternlen == basenamelen && @@ -823,7 +816,7 @@ int match_basename(const char *basename, int basenamelen, int match_pathname(const char *pathname, int pathlen, const char *base, int baselen, const char *pattern, int prefix, int patternlen, - int flags) + unsigned flags) { const char *name; int namelen; @@ -1829,31 +1822,67 @@ static const char *get_ident_string(void) return sb.buf; if (uname(&uts) < 0) die_errno(_("failed to get kernel name and information")); - strbuf_addf(&sb, "Location %s, system %s %s %s", get_git_work_tree(), - uts.sysname, uts.release, uts.version); + strbuf_addf(&sb, "Location %s, system %s", get_git_work_tree(), + uts.sysname); return sb.buf; } static int ident_in_untracked(const struct untracked_cache *uc) { - const char *end = uc->ident.buf + uc->ident.len; - const char *p = uc->ident.buf; + /* + * Previous git versions may have saved many NUL separated + * strings in the "ident" field, but it is insane to manage + * many locations, so just take care of the first one. + */ - for (p = uc->ident.buf; p < end; p += strlen(p) + 1) - if (!strcmp(p, get_ident_string())) - return 1; - return 0; + return !strcmp(uc->ident.buf, get_ident_string()); } -void add_untracked_ident(struct untracked_cache *uc) +static void set_untracked_ident(struct untracked_cache *uc) { - if (ident_in_untracked(uc)) - return; + strbuf_reset(&uc->ident); strbuf_addstr(&uc->ident, get_ident_string()); - /* this strbuf contains a list of strings, save NUL too */ + + /* + * This strbuf used to contain a list of NUL separated + * strings, so save NUL too for backward compatibility. + */ strbuf_addch(&uc->ident, 0); } +static void new_untracked_cache(struct index_state *istate) +{ + struct untracked_cache *uc = xcalloc(1, sizeof(*uc)); + strbuf_init(&uc->ident, 100); + uc->exclude_per_dir = ".gitignore"; + /* should be the same flags used by git-status */ + uc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES; + set_untracked_ident(uc); + istate->untracked = uc; + istate->cache_changed |= UNTRACKED_CHANGED; +} + +void add_untracked_cache(struct index_state *istate) +{ + if (!istate->untracked) { + new_untracked_cache(istate); + } else { + if (!ident_in_untracked(istate->untracked)) { + free_untracked_cache(istate->untracked); + new_untracked_cache(istate); + } + } +} + +void remove_untracked_cache(struct index_state *istate) +{ + if (istate->untracked) { + free_untracked_cache(istate->untracked); + istate->untracked = NULL; + istate->cache_changed |= UNTRACKED_CHANGED; + } +} + static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *dir, int base_len, const struct pathspec *pathspec) @@ -1911,7 +1940,7 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d return NULL; if (!ident_in_untracked(dir->untracked)) { - warning(_("Untracked cache is disabled on this system.")); + warning(_("Untracked cache is disabled on this system or location.")); return NULL; } diff --git a/dir.h b/dir.h index 7b5855dd80..d56d2fb48f 100644 --- a/dir.h +++ b/dir.h @@ -27,7 +27,7 @@ struct exclude { int nowildcardlen; const char *base; int baselen; - int flags; + unsigned flags; /* EXC_FLAG_* */ /* * Counting starts from 1 for line numbers in ignore files, @@ -226,10 +226,10 @@ struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, * attr.c:path_matches() */ extern int match_basename(const char *, int, - const char *, int, int, int); + const char *, int, int, unsigned); extern int match_pathname(const char *, int, const char *, int, - const char *, int, int, int); + const char *, int, int, unsigned); extern struct exclude *last_exclude_matching(struct dir_struct *dir, const char *name, int *dtype); @@ -241,7 +241,7 @@ extern struct exclude_list *add_exclude_list(struct dir_struct *dir, extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, struct exclude_list *el, int check_index); extern void add_excludes_from_file(struct dir_struct *, const char *fname); -extern void parse_exclude_pattern(const char **string, int *patternlen, int *flags, int *nowildcardlen); +extern void parse_exclude_pattern(const char **string, int *patternlen, unsigned *flags, int *nowildcardlen); extern void add_exclude(const char *string, const char *base, int baselen, struct exclude_list *el, int srcpos); extern void clear_exclude_list(struct exclude_list *el); @@ -272,7 +272,6 @@ extern int remove_path(const char *path); extern int strcmp_icase(const char *a, const char *b); extern int strncmp_icase(const char *a, const char *b, size_t count); -extern int fnmatch_icase(const char *pattern, const char *string, int flags); /* * The prefix part of pattern must not contains wildcards. @@ -307,5 +306,6 @@ void untracked_cache_add_to_index(struct index_state *, const char *); void free_untracked_cache(struct untracked_cache *); struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz); void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked); -void add_untracked_ident(struct untracked_cache *); +void add_untracked_cache(struct index_state *istate); +void remove_untracked_cache(struct index_state *istate); #endif diff --git a/environment.c b/environment.c index 1cc4aab4ea..96160a75a5 100644 --- a/environment.c +++ b/environment.c @@ -25,11 +25,9 @@ int log_all_ref_updates = -1; /* unspecified */ int warn_ambiguous_refs = 1; int warn_on_object_refname_ambiguity = 1; int ref_paranoia = -1; -int repository_format_version; int repository_format_precious_objects; const char *git_commit_encoding; const char *git_log_output_encoding; -int shared_repository = PERM_UMASK; const char *apply_default_whitespace; const char *apply_default_ignorewhitespace; const char *git_attributes_file; @@ -64,8 +62,8 @@ int grafts_replace_parents = 1; int core_apply_sparse_checkout; int merge_log_config = -1; int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */ -struct startup_info *startup_info; unsigned long pack_size_limit_cfg; +enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; #ifndef PROTECT_HFS_DEFAULT #define PROTECT_HFS_DEFAULT 0 @@ -87,6 +85,13 @@ int auto_comment_line_char; /* Parallel index stat data preload? */ int core_preload_index = 1; +/* + * This is a hack for test programs like test-dump-untracked-cache to + * ensure that they do not modify the untracked cache when reading it. + * Do not use it otherwise! + */ +int ignore_untracked_cache_config; + /* This is set by setup_git_dir_gently() and/or git_default_config() */ char *git_work_tree_cfg; static char *work_tree; @@ -318,3 +323,24 @@ const char *get_commit_output_encoding(void) { return git_commit_encoding ? git_commit_encoding : "UTF-8"; } + +static int the_shared_repository = PERM_UMASK; +static int need_shared_repository_from_config = 1; + +void set_shared_repository(int value) +{ + the_shared_repository = value; + need_shared_repository_from_config = 0; +} + +int get_shared_repository(void) +{ + if (need_shared_repository_from_config) { + const char *var = "core.sharedrepository"; + const char *value; + if (!git_config_get_value(var, &value)) + the_shared_repository = git_config_perm(var, value); + need_shared_repository_from_config = 0; + } + return the_shared_repository; +} diff --git a/fast-import.c b/fast-import.c index 75f77480a2..9fc7093406 100644 --- a/fast-import.c +++ b/fast-import.c @@ -1886,7 +1886,7 @@ static int read_next_command(void) struct recent_command *rc; strbuf_detach(&command_buf, NULL); - stdin_eof = strbuf_getline(&command_buf, stdin, '\n'); + stdin_eof = strbuf_getline_lf(&command_buf, stdin); if (stdin_eof) return EOF; @@ -1958,7 +1958,7 @@ static int parse_data(struct strbuf *sb, uintmax_t limit, uintmax_t *len_res) strbuf_detach(&command_buf, NULL); for (;;) { - if (strbuf_getline(&command_buf, stdin, '\n') == EOF) + if (strbuf_getline_lf(&command_buf, stdin) == EOF) die("EOF in data (terminator '%s' not found)", term); if (term_len == command_buf.len && !strcmp(term, command_buf.buf)) diff --git a/fetch-pack.c b/fetch-pack.c index f96f6dfb35..b501d5c320 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -15,7 +15,6 @@ #include "version.h" #include "prio-queue.h" #include "sha1-array.h" -#include "sigchain.h" static int transfer_unpack_limit = -1; static int fetch_unpack_limit = -1; @@ -674,10 +673,8 @@ static int sideband_demux(int in, int out, void *data) int *xd = data; int ret; - sigchain_push(SIGPIPE, SIG_IGN); ret = recv_sideband("fetch-pack", xd[0], out); close(out); - sigchain_pop(SIGPIPE); return ret; } @@ -701,6 +698,7 @@ static int get_pack(struct fetch_pack_args *args, demux.proc = sideband_demux; demux.data = xd; demux.out = -1; + demux.isolate_sigpipe = 1; if (start_async(&demux)) die("fetch-pack: unable to fork off sideband" " demultiplexer"); diff --git a/fsck.c b/fsck.c index ca4c685377..3366b3fb62 100644 --- a/fsck.c +++ b/fsck.c @@ -59,6 +59,7 @@ FUNC(HAS_DOTGIT, WARN) \ FUNC(NULL_SHA1, WARN) \ FUNC(ZERO_PADDED_FILEMODE, WARN) \ + FUNC(NUL_IN_COMMIT, WARN) \ /* infos (reported as warnings, but ignored by default) */ \ FUNC(BAD_TAG_NAME, INFO) \ FUNC(MISSING_TAGGER_ENTRY, INFO) @@ -610,6 +611,7 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer, struct commit_graft *graft; unsigned parent_count, parent_line_count = 0, author_count; int err; + const char *buffer_begin = buffer; if (verify_headers(buffer, size, &commit->object, options)) return -1; @@ -666,9 +668,17 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer, err = fsck_ident(&buffer, &commit->object, options); if (err) return err; - if (!commit->tree) - return report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", sha1_to_hex(tree_sha1)); - + if (!commit->tree) { + err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", sha1_to_hex(tree_sha1)); + if (err) + return err; + } + if (memchr(buffer_begin, '\0', size)) { + err = report(options, &commit->object, FSCK_MSG_NUL_IN_COMMIT, + "NUL byte in the commit object body"); + if (err) + return err; + } return 0; } diff --git a/git-compat-util.h b/git-compat-util.h index 474395471f..1f8b5f3b1f 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -279,9 +279,6 @@ extern char *gitdirname(char *); #endif #include #include -#ifdef NO_HMAC_CTX_CLEANUP -#define HMAC_CTX_cleanup HMAC_cleanup -#endif #endif /* On most systems would have given us this, but diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 02c0445be1..d50c85ed7b 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -1156,7 +1156,7 @@ sub prepDirForOutput # FUTURE: This would more accurately emulate CVS by sending # another copy of sticky after processing the files in that # directory. Or intermediate: perhaps send all sticky's for - # $seendirs after after processing all files. + # $seendirs after processing all files. } # update \n @@ -2824,7 +2824,7 @@ sub statecleanup } # Return working directory CVS revision "1.X" out -# of the the working directory "entries" state, for the given filename. +# of the working directory "entries" state, for the given filename. # This is prefixed with a dash if the file is scheduled for removal # when it is committed. sub revparse @@ -2935,7 +2935,7 @@ sub filecleanup return $filename; } -# Remove prependdir from the path, so that is is relative to the directory +# Remove prependdir from the path, so that it is relative to the directory # the CVS client was started from, rather than the top of the project. # Essentially the inverse of filecleanup(). sub remove_prependdir diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh index 2b11b1d6fe..84d6cc021c 100755 --- a/git-difftool--helper.sh +++ b/git-difftool--helper.sh @@ -44,10 +44,10 @@ launch_merge_tool () { "$GIT_DIFF_PATH_TOTAL" "$MERGED" if use_ext_cmd then - printf "Launch '%s' [Y/n]: " \ + printf "Launch '%s' [Y/n]? " \ "$GIT_DIFFTOOL_EXTCMD" else - printf "Launch '%s' [Y/n]: " "$merge_tool" + printf "Launch '%s' [Y/n]? " "$merge_tool" fi read ans || return if test "$ans" = n diff --git a/git-difftool.perl b/git-difftool.perl index 488d14b153..ebd13baa6e 100755 --- a/git-difftool.perl +++ b/git-difftool.perl @@ -138,6 +138,7 @@ sub setup_dir_diff my %submodule; my %symlink; my @working_tree = (); + my %working_tree_dups = (); my @rawdiff = split('\0', $diffrtn); my $i = 0; @@ -188,6 +189,10 @@ sub setup_dir_diff } if ($rmode ne $null_mode) { + # Avoid duplicate working_tree entries + if ($working_tree_dups{$dst_path}++) { + next; + } my ($use, $wt_sha1) = use_wt_file($repo, $workdir, $dst_path, $rsha1); if ($use) { @@ -273,7 +278,7 @@ sub setup_dir_diff # temporary file to both the left and right directories to show the # change in the recorded SHA1 for the submodule. for my $path (keys %submodule) { - my $ok; + my $ok = 0; if (defined($submodule{$path}{left})) { $ok = write_to_file("$ldir/$path", "Subproject commit $submodule{$path}{left}"); @@ -289,7 +294,7 @@ sub setup_dir_diff # shows only the link itself, not the contents of the link target. # This loop replicates that behavior. for my $path (keys %symlink) { - my $ok; + my $ok = 0; if (defined($symlink{$path}{left})) { $ok = write_to_file("$ldir/$path", $symlink{$path}{left}); diff --git a/git-gui/po/glossary/txt-to-pot.sh b/git-gui/po/glossary/txt-to-pot.sh index 49bf7c5365..8249915d3c 100755 --- a/git-gui/po/glossary/txt-to-pot.sh +++ b/git-gui/po/glossary/txt-to-pot.sh @@ -11,7 +11,7 @@ if [ $# -eq 0 ] then cat < git-gui-glossary.pot +Usage: $(basename $0) git-gui-glossary.txt > git-gui-glossary.pot ! exit 1; fi @@ -33,7 +33,7 @@ cat <\n" "Language-Team: LANGUAGE \n" diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh index 54ac8e4846..92adcc0d07 100644 --- a/git-mergetool--lib.sh +++ b/git-mergetool--lib.sh @@ -100,7 +100,7 @@ check_unchanged () { while true do echo "$MERGED seems unchanged." - printf "Was the merge successful? [y/n] " + printf "Was the merge successful [y/n]? " read answer || return 1 case "$answer" in y*|Y*) return 0 ;; diff --git a/git-mergetool.sh b/git-mergetool.sh index 9f77e3a8bb..bf862705d8 100755 --- a/git-mergetool.sh +++ b/git-mergetool.sh @@ -126,7 +126,12 @@ resolve_deleted_merge () { case "$ans" in [mMcC]*) git add -- "$MERGED" - cleanup_temp_files --save-backup + if test "$merge_keep_backup" = "true" + then + cleanup_temp_files --save-backup + else + cleanup_temp_files + fi return 0 ;; [dD]*) @@ -135,6 +140,10 @@ resolve_deleted_merge () { return 0 ;; [aA]*) + if test "$merge_keep_temporaries" = "false" + then + cleanup_temp_files + fi return 1 ;; esac @@ -282,8 +291,14 @@ merge_file () { return fi - mv -- "$MERGED" "$BACKUP" - cp -- "$BACKUP" "$MERGED" + if test -f "$MERGED" + then + mv -- "$MERGED" "$BACKUP" + cp -- "$BACKUP" "$MERGED" + fi + # Create a parent directory to handle delete/delete conflicts + # where the base's directory no longer exists. + mkdir -p "$(dirname "$MERGED")" checkout_staged_file 1 "$MERGED" "$BASE" checkout_staged_file 2 "$MERGED" "$LOCAL" @@ -295,7 +310,9 @@ merge_file () { describe_file "$local_mode" "local" "$LOCAL" describe_file "$remote_mode" "remote" "$REMOTE" resolve_deleted_merge - return + status=$? + rmdir -p "$(dirname "$MERGED")" 2>/dev/null + return $status fi if is_symlink "$local_mode" || is_symlink "$remote_mode" @@ -396,7 +413,7 @@ done prompt_after_failed_merge () { while true do - printf "Continue merging other unresolved paths (y/n) ? " + printf "Continue merging other unresolved paths [y/n]? " read ans || return 1 case "$ans" in [yY]*) diff --git a/git-p4.py b/git-p4.py index c33dece5d2..e752153f6f 100755 --- a/git-p4.py +++ b/git-p4.py @@ -253,8 +253,8 @@ def p4_add(f): def p4_delete(f): p4_system(["delete", wildcard_encode(f)]) -def p4_edit(f): - p4_system(["edit", wildcard_encode(f)]) +def p4_edit(f, *options): + p4_system(["edit"] + list(options) + [wildcard_encode(f)]) def p4_revert(f): p4_system(["revert", wildcard_encode(f)]) @@ -1064,8 +1064,15 @@ def generatePointer(self, contentFile): if pointerProcess.wait(): os.remove(contentFile) die('git-lfs pointer command failed. Did you install the extension?') - pointerContents = [i+'\n' for i in pointerFile.split('\n')[2:][:-1]] - oid = pointerContents[1].split(' ')[1].split(':')[1][:-1] + + # Git LFS removed the preamble in the output of the 'pointer' command + # starting from version 1.2.0. Check for the preamble here to support + # earlier versions. + # c.f. https://github.com/github/git-lfs/commit/da2935d9a739592bc775c98d8ef4df9c72ea3b43 + if pointerFile.startswith('Git LFS pointer for'): + pointerFile = re.sub(r'Git LFS pointer for.*\n\n', '', pointerFile) + + oid = re.search(r'^oid \w+:(\w+)', pointerFile, re.MULTILINE).group(1) localLargeFile = os.path.join( os.getcwd(), '.git', 'lfs', 'objects', oid[:2], oid[2:4], @@ -1073,7 +1080,7 @@ def generatePointer(self, contentFile): ) # LFS Spec states that pointer files should not have the executable bit set. gitMode = '100644' - return (gitMode, pointerContents, localLargeFile) + return (gitMode, pointerFile, localLargeFile) def pushFile(self, localLargeFile): uploadProcess = subprocess.Popen( @@ -1554,6 +1561,7 @@ def applyCommit(self, id): diff = read_pipe_lines("git diff-tree -r %s \"%s^\" \"%s\"" % (self.diffOpts, id, id)) filesToAdd = set() + filesToChangeType = set() filesToDelete = set() editedFiles = set() pureRenameCopy = set() @@ -1614,6 +1622,8 @@ def applyCommit(self, id): os.unlink(dest) filesToDelete.add(src) editedFiles.add(dest) + elif modifier == "T": + filesToChangeType.add(path) else: die("unknown modifier %s for %s" % (modifier, path)) @@ -1673,6 +1683,8 @@ def applyCommit(self, id): # system(applyPatchCmd) + for f in filesToChangeType: + p4_edit(f, "-t", "auto") for f in filesToAdd: p4_add(f) for f in filesToDelete: diff --git a/git-parse-remote.sh b/git-parse-remote.sh index 55fe8d56c9..d3c39980f3 100644 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -56,11 +56,13 @@ get_remote_merge_branch () { error_on_missing_default_upstream () { cmd="$1" op_type="$2" - op_prep="$3" + op_prep="$3" # FIXME: op_prep is no longer used example="$4" branch_name=$(git symbolic-ref -q HEAD) + display_branch_name="${branch_name#refs/heads/}" # If there's only one remote, use that in the suggestion - remote="" + remote="$(gettext "")" + branch="$(gettext "")" if test $(git remote | wc -l) = 1 then remote=$(git remote) @@ -68,22 +70,32 @@ error_on_missing_default_upstream () { if test -z "$branch_name" then - echo "You are not currently on a branch. Please specify which -branch you want to $op_type $op_prep. See git-${cmd}(1) for details. - - $example -" + gettextln "You are not currently on a branch." else - echo "There is no tracking information for the current branch. -Please specify which branch you want to $op_type $op_prep. -See git-${cmd}(1) for details - - $example - -If you wish to set tracking information for this branch you can do so with: - - git branch --set-upstream-to=$remote/ ${branch_name#refs/heads/} -" + gettextln "There is no tracking information for the current branch." + fi + case "$op_type" in + rebase) + gettextln "Please specify which branch you want to rebase against." + ;; + merge) + gettextln "Please specify which branch you want to merge with." + ;; + *) + echo >&2 "BUG: unknown operation type: $op_type" + exit 1 + ;; + esac + eval_gettextln "See git-\${cmd}(1) for details." + echo + echo " $example" + echo + if test -n "$branch_name" + then + gettextln "If you wish to set tracking information for this branch you can do so with:" + echo + echo " git branch --set-upstream-to=$remote/$branch $display_branch_name" + echo fi exit 1 } diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index c0cfe88a3d..655ebaa471 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -82,6 +82,7 @@ rewritten_pending="$state_dir"/rewritten-pending cr=$(printf "\015") strategy_args=${strategy:+--strategy=$strategy} +test -n "$strategy_opts" && eval ' for strategy_opt in '"$strategy_opts"' do @@ -1233,7 +1234,8 @@ then git rev-list $revisions | while read rev do - if test -f "$rewritten"/$rev && test "$(sane_grep "$rev" "$state_dir"/not-cherry-picks)" = "" + if test -f "$rewritten"/$rev && + ! sane_grep "$rev" "$state_dir"/not-cherry-picks >/dev/null then # Use -f2 because if rev-list is telling us this commit is # not worthwhile, we don't want to track its multiple heads, diff --git a/git-send-email.perl b/git-send-email.perl index d356901348..69587856df 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -19,10 +19,10 @@ use 5.008; use strict; use warnings; +use POSIX qw/strftime/; use Term::ReadLine; use Getopt::Long; use Text::ParseWords; -use Data::Dumper; use Term::ANSIColor; use File::Temp qw/ tempdir tempfile /; use File::Spec::Functions qw(catfile); @@ -533,7 +533,7 @@ sub parse_sendmail_aliases { $aliases{$alias} = \@addr }}}, mailrc => sub { my $fh = shift; while (<$fh>) { - if (/^alias\s+(\S+)\s+(.*)$/) { + if (/^alias\s+(\S+)\s+(.*?)\s*$/) { # spaces delimit multiple addresses $aliases{$1} = [ quotewords('\s+', 0, $2) ]; }}}, @@ -827,9 +827,10 @@ sub file_declares_8bit_cte { # But it's a no-op to run sanitize_address on an already sanitized address. $sender = sanitize_address($sender); +my $to_whom = "To whom should the emails be sent (if anyone)?"; my $prompting = 0; if (!@initial_to && !defined $to_cmd) { - my $to = ask("Who should the emails be sent to (if any)? ", + my $to = ask("$to_whom ", default => "", valid_re => qr/\@.*\./, confirm_only => 1); push @initial_to, parse_address_line($to) if defined $to; # sanitized/validated later @@ -924,7 +925,7 @@ sub validate_address { cleanup_compose_files(); exit(0); } - $address = ask("Who should the email be sent to (if any)? ", + $address = ask("$to_whom ", default => "", valid_re => qr/\@.*\./, confirm_only => 1); } @@ -949,7 +950,7 @@ sub validate_address_list { sub make_message_id { my $uniq; if (!defined $message_id_stamp) { - $message_id_stamp = sprintf("%s-%s", time, $$); + $message_id_stamp = strftime("%Y%m%d%H%M%S.$$", gmtime(time)); $message_id_serial = 0; } $message_id_serial++; @@ -964,7 +965,7 @@ sub make_message_id { require Sys::Hostname; $du_part = 'user@' . Sys::Hostname::hostname(); } - my $message_id_template = "<%s-git-send-email-%s>"; + my $message_id_template = "<%s-%s>"; $message_id = sprintf($message_id_template, $uniq, $du_part); #print "new message id = $message_id\n"; # Was useful for debugging } diff --git a/git-sh-setup.sh b/git-sh-setup.sh index 4691fbcb64..c48139a494 100644 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -168,11 +168,11 @@ git_pager() { } sane_grep () { - GREP_OPTIONS= LC_ALL=C grep "$@" + GREP_OPTIONS= LC_ALL=C grep @@SANE_TEXT_GREP@@ "$@" } sane_egrep () { - GREP_OPTIONS= LC_ALL=C egrep "$@" + GREP_OPTIONS= LC_ALL=C egrep @@SANE_TEXT_GREP@@ "$@" } is_bare_repository () { diff --git a/git-submodule.sh b/git-submodule.sh index 9bc5c5f94d..d56207ea05 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -8,7 +8,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /') USAGE="[--quiet] add [-b ] [-f|--force] [--name ] [--reference ] [--] [] or: $dashless [--quiet] status [--cached] [--recursive] [--] [...] or: $dashless [--quiet] init [--] [...] - or: $dashless [--quiet] deinit [-f|--force] [--] ... + or: $dashless [--quiet] deinit [-f|--force] (--all| [--] ...) or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--reference ] [--recursive] [--] [...] or: $dashless [--quiet] summary [--cached|--files] [--summary-limit ] [commit] [--] [...] or: $dashless [--quiet] foreach [--recursive] @@ -413,8 +413,8 @@ cmd_foreach() die_if_unmatched "$mode" if test -e "$sm_path"/.git then - displaypath=$(relative_path "$sm_path") - say "$(eval_gettext "Entering '\$prefix\$displaypath'")" + displaypath=$(relative_path "$prefix$sm_path") + say "$(eval_gettext "Entering '\$displaypath'")" name=$(git submodule--helper name "$sm_path") ( prefix="$prefix$sm_path/" @@ -434,7 +434,7 @@ cmd_foreach() cmd_foreach "--recursive" "$@" fi ) <&3 3<&- || - die "$(eval_gettext "Stopping at '\$prefix\$displaypath'; script returned non-zero status.")" + die "$(eval_gettext "Stopping at '\$displaypath'; script returned non-zero status.")" fi done } @@ -473,7 +473,7 @@ cmd_init() die_if_unmatched "$mode" name=$(git submodule--helper name "$sm_path") || exit - displaypath=$(relative_path "$sm_path") + displaypath=$(relative_path "$prefix$sm_path") # Copy url setting when it is not set yet if test -z "$(git config "submodule.$name.url")" @@ -521,6 +521,7 @@ cmd_init() cmd_deinit() { # parse $args after "submodule ... deinit". + deinit_all= while test $# -ne 0 do case "$1" in @@ -530,6 +531,9 @@ cmd_deinit() -q|--quiet) GIT_QUIET=1 ;; + --all) + deinit_all=t + ;; --) shift break @@ -544,9 +548,14 @@ cmd_deinit() shift done - if test $# = 0 + if test -n "$deinit_all" && test "$#" -ne 0 then - die "$(eval_gettext "Use '.' if you really want to deinitialize all submodules")" + echo >&2 "$(eval_gettext "pathspec and --all are incompatible")" + usage + fi + if test $# = 0 && test -z "$deinit_all" + then + die "$(eval_gettext "Use '--all' if you really want to deinitialize all submodules")" fi git submodule--helper list --prefix "$wt_prefix" "$@" | @@ -591,6 +600,24 @@ cmd_deinit() done } +is_tip_reachable () ( + clear_local_git_env + cd "$1" && + rev=$(git rev-list -n 1 "$2" --not --all 2>/dev/null) && + test -z "$rev" +) + +fetch_in_submodule () ( + clear_local_git_env + cd "$1" && + case "$2" in + '') + git fetch ;; + *) + git fetch $(get_default_remote) "$2" ;; + esac +) + # # Update each submodule path to correct revision, using clone and checkout as needed # @@ -745,10 +772,15 @@ Maybe you want to use 'update --init'?")" then # Run fetch only if $sha1 isn't present or it # is not reachable from a ref. - (clear_local_git_env; cd "$sm_path" && - ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) && - test -z "$rev") || git-fetch)) || + is_tip_reachable "$sm_path" "$sha1" || + fetch_in_submodule "$sm_path" || die "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'")" + + # Now we tried the usual fetch, but $sha1 may + # not be reachable from any of the refs + is_tip_reachable "$sm_path" "$sha1" || + fetch_in_submodule "$sm_path" "$sha1" || + die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain $sha1. Direct fetching of that commit failed.")" fi # Is this something we just cloned? @@ -779,8 +811,8 @@ Maybe you want to use 'update --init'?")" ;; !*) command="${update_module#!}" - die_msg="$(eval_gettext "Execution of '\$command \$sha1' failed in submodule path '\$prefix\$sm_path'")" - say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': '\$command \$sha1'")" + die_msg="$(eval_gettext "Execution of '\$command \$sha1' failed in submodule path '\$displaypath'")" + say_msg="$(eval_gettext "Submodule path '\$displaypath': '\$command \$sha1'")" must_die_on_failure=yes ;; *) @@ -1136,6 +1168,7 @@ cmd_status() ( prefix="$displaypath/" clear_local_git_env + wt_prefix= cd "$sm_path" && eval cmd_status ) || diff --git a/git-svn.perl b/git-svn.perl index fa5f253065..05eced06cd 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -1745,11 +1745,12 @@ sub post_fetch_checkout { sub complete_svn_url { my ($url, $path) = @_; - $path = canonicalize_path($path); - # If the path is not a URL... - if ($path !~ m#^[a-z\+]+://#) { - if (!defined $url || $url !~ m#^[a-z\+]+://#) { + if ($path =~ m#^[a-z\+]+://#i) { # path is a URL + $path = canonicalize_url($path); + } else { + $path = canonicalize_path($path); + if (!defined $url || $url !~ m#^[a-z\+]+://#i) { fatal("E: '$path' is not a complete URL ", "and a separate URL is not specified"); } @@ -1764,11 +1765,12 @@ sub complete_url_ls_init { print STDERR "W: $switch not specified\n"; return; } - $repo_path = canonicalize_path($repo_path); - if ($repo_path =~ m#^[a-z\+]+://#) { + if ($repo_path =~ m#^[a-z\+]+://#i) { + $repo_path = canonicalize_url($repo_path); $ra = Git::SVN::Ra->new($repo_path); $repo_path = ''; } else { + $repo_path = canonicalize_path($repo_path); $repo_path =~ s#^/+##; unless ($ra) { fatal("E: '$repo_path' is not a complete URL ", diff --git a/git.c b/git.c index c19d6bf47b..968a8a4645 100644 --- a/git.c +++ b/git.c @@ -15,7 +15,6 @@ const char git_more_info_string[] = "concept guides. See 'git help ' or 'git help '\n" "to read about a specific subcommand or concept."); -static struct startup_info git_startup_info; static int use_pager = -1; static char *orig_cwd; static const char *env_names[] = { @@ -25,14 +24,14 @@ static const char *env_names[] = { GIT_PREFIX_ENVIRONMENT }; static char *orig_env[4]; -static int saved_environment; +static int save_restore_env_balance; -static void save_env(void) +static void save_env_before_alias(void) { int i; - if (saved_environment) - return; - saved_environment = 1; + + assert(save_restore_env_balance == 0); + save_restore_env_balance = 1; orig_cwd = xgetcwd(); for (i = 0; i < ARRAY_SIZE(env_names); i++) { orig_env[i] = getenv(env_names[i]); @@ -41,17 +40,25 @@ static void save_env(void) } } -static void restore_env(void) +static void restore_env(int external_alias) { int i; - if (orig_cwd && chdir(orig_cwd)) + + assert(save_restore_env_balance == 1); + save_restore_env_balance = 0; + if (!external_alias && orig_cwd && chdir(orig_cwd)) die_errno("could not move to %s", orig_cwd); free(orig_cwd); for (i = 0; i < ARRAY_SIZE(env_names); i++) { - if (orig_env[i]) + if (external_alias && + !strcmp(env_names[i], GIT_PREFIX_ENVIRONMENT)) + continue; + if (orig_env[i]) { setenv(env_names[i], orig_env[i], 1); - else + free(orig_env[i]); + } else { unsetenv(env_names[i]); + } } } @@ -226,14 +233,14 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) static int handle_alias(int *argcp, const char ***argv) { int envchanged = 0, ret = 0, saved_errno = errno; - const char *subdir; int count, option_count; const char **new_argv; const char *alias_command; char *alias_string; int unused_nongit; - subdir = setup_git_directory_gently(&unused_nongit); + save_env_before_alias(); + setup_git_directory_gently(&unused_nongit); alias_command = (*argv)[0]; alias_string = alias_lookup(alias_command); @@ -242,6 +249,7 @@ static int handle_alias(int *argcp, const char ***argv) struct child_process child = CHILD_PROCESS_INIT; commit_pager_choice(); + restore_env(1); child.use_shell = 1; argv_array_push(&child.args, alias_string + 1); @@ -287,8 +295,7 @@ static int handle_alias(int *argcp, const char ***argv) ret = 1; } - if (subdir && chdir(subdir)) - die_errno("Cannot change to '%s'", subdir); + restore_env(0); errno = saved_errno; @@ -303,7 +310,6 @@ static int handle_alias(int *argcp, const char ***argv) * RUN_SETUP for reading from the configuration file. */ #define NEED_WORK_TREE (1<<3) -#define NO_SETUP (1<<4) struct cmd_struct { const char *cmd; @@ -385,7 +391,7 @@ static struct cmd_struct commands[] = { { "cherry", cmd_cherry, RUN_SETUP }, { "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE }, { "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE }, - { "clone", cmd_clone, NO_SETUP }, + { "clone", cmd_clone }, { "column", cmd_column, RUN_SETUP_GENTLY }, { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE }, { "commit-tree", cmd_commit_tree, RUN_SETUP }, @@ -411,8 +417,8 @@ static struct cmd_struct commands[] = { { "hash-object", cmd_hash_object }, { "help", cmd_help }, { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY }, - { "init", cmd_init_db, NO_SETUP }, - { "init-db", cmd_init_db, NO_SETUP }, + { "init", cmd_init_db }, + { "init-db", cmd_init_db }, { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP_GENTLY }, { "log", cmd_log, RUN_SETUP }, { "ls-files", cmd_ls_files, RUN_SETUP }, @@ -529,12 +535,8 @@ static void handle_builtin(int argc, const char **argv) } builtin = get_builtin(cmd); - if (builtin) { - if (saved_environment && (builtin->option & NO_SETUP)) - restore_env(); - else - exit(run_builtin(builtin, argc, argv)); - } + if (builtin) + exit(run_builtin(builtin, argc, argv)); } static void execv_dashed_external(const char **argv) @@ -578,8 +580,17 @@ static int run_argv(int *argcp, const char ***argv) int done_alias = 0; while (1) { - /* See if it's a builtin */ - handle_builtin(*argcp, *argv); + /* + * If we tried alias and futzed with our environment, + * it no longer is safe to invoke builtins directly in + * general. We have to spawn them as dashed externals. + * + * NEEDSWORK: if we can figure out cases + * where it is safe to do, we can avoid spawning a new + * process. + */ + if (!done_alias) + handle_builtin(*argcp, *argv); /* .. then try the external ones */ execv_dashed_external(*argv); @@ -590,7 +601,6 @@ static int run_argv(int *argcp, const char ***argv) */ if (done_alias) break; - save_env(); if (!handle_alias(argcp, argv)) break; done_alias = 1; @@ -626,8 +636,6 @@ int main(int argc, char **av) const char *cmd; int done_help = 0; - startup_info = &git_startup_info; - cmd = git_extract_argv0_path(argv[0]); if (!cmd) cmd = "git-help"; diff --git a/git.spec.in b/git.spec.in index d61d537ef0..bfd1cfb63f 100644 --- a/git.spec.in +++ b/git.spec.in @@ -146,7 +146,7 @@ rm -rf $RPM_BUILD_ROOT %files -f bin-man-doc-files %defattr(-,root,root) %{_datadir}/git-core/ -%doc README COPYING Documentation/*.txt +%doc README.md COPYING Documentation/*.txt %{!?_without_docs: %doc Documentation/*.html Documentation/howto} %{!?_without_docs: %doc Documentation/technical} %{_sysconfdir}/bash_completion.d diff --git a/gitk-git/gitk b/gitk-git/gitk index 5f1255c860..805a1c7030 100755 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -3021,7 +3021,7 @@ proc bindall {event action} { } proc about {} { - global uifont NS + global bgcolor NS set w .about if {[winfo exists $w]} { raise $w @@ -3036,7 +3036,7 @@ Gitk - a commit viewer for git Copyright \u00a9 2005-2014 Paul Mackerras Use and redistribute under the terms of the GNU General Public License"] \ - -justify center -aspect 400 -border 2 -bg white -relief groove + -justify center -aspect 400 -border 2 -bg $bgcolor -relief groove pack $w.m -side top -fill x -padx 2 -pady 2 ${NS}::button $w.ok -text [mc "Close"] -command "destroy $w" -default active pack $w.ok -side bottom @@ -3047,7 +3047,7 @@ Use and redistribute under the terms of the GNU General Public License"] \ } proc keys {} { - global NS + global bgcolor NS set w .keys if {[winfo exists $w]} { raise $w @@ -3103,7 +3103,7 @@ proc keys {} { [mc "<%s-minus> Decrease font size" $M1T] [mc " Update"] " \ - -justify left -bg white -border 2 -relief groove + -justify left -bg $bgcolor -border 2 -relief groove pack $w.m -side top -fill both -padx 2 -pady 2 ${NS}::button $w.ok -text [mc "Close"] -command "destroy $w" -default active bind $w [list destroy $w] diff --git a/gitk-git/po/bg.po b/gitk-git/po/bg.po index 909a56463f..99aa77aa63 100644 --- a/gitk-git/po/bg.po +++ b/gitk-git/po/bg.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: gitk master\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-06-27 20:44+0300\n" -"PO-Revision-Date: 2015-06-27 20:46+0300\n" +"POT-Creation-Date: 2015-12-19 11:48+0200\n" +"PO-Revision-Date: 2015-12-19 11:49+0200\n" "Last-Translator: Alexander Shopov \n" "Language-Team: Bulgarian \n" "Language: bg\n" @@ -22,11 +22,11 @@ msgstr "" msgid "Couldn't get list of unmerged files:" msgstr "Списъкът с неслети файлове не може да бъде получен:" -#: gitk:212 gitk:2381 +#: gitk:212 gitk:2399 msgid "Color words" msgstr "Оцветяване на думите" -#: gitk:217 gitk:2381 gitk:8220 gitk:8253 +#: gitk:217 gitk:2399 gitk:8239 gitk:8272 msgid "Markup words" msgstr "Отбелязване на думите" @@ -59,15 +59,15 @@ msgstr "Грешка при изпълнение на „git log“:" msgid "Reading" msgstr "Прочитане" -#: gitk:496 gitk:4525 +#: gitk:496 gitk:4544 msgid "Reading commits..." msgstr "Прочитане на подаванията…" -#: gitk:499 gitk:1637 gitk:4528 +#: gitk:499 gitk:1637 gitk:4547 msgid "No commits selected" msgstr "Не са избрани подавания" -#: gitk:1445 gitk:4045 gitk:12432 +#: gitk:1445 gitk:4064 gitk:12469 msgid "Command line" msgstr "Команден ред" @@ -79,286 +79,294 @@ msgstr "Изходът от „git log“ не може да се анализи msgid "No commit information available" msgstr "Липсва информация за подавания" -#: gitk:1903 gitk:1932 gitk:4315 gitk:9669 gitk:11241 gitk:11521 +#: gitk:1903 gitk:1932 gitk:4334 gitk:9702 gitk:11274 gitk:11554 msgid "OK" msgstr "Добре" -#: gitk:1934 gitk:4317 gitk:9196 gitk:9275 gitk:9391 gitk:9440 gitk:9671 -#: gitk:11242 gitk:11522 +#: gitk:1934 gitk:4336 gitk:9215 gitk:9294 gitk:9424 gitk:9473 gitk:9704 +#: gitk:11275 gitk:11555 msgid "Cancel" msgstr "Отказ" -#: gitk:2069 +#: gitk:2083 msgid "&Update" -msgstr "Обновяване" +msgstr "&Обновяване" -#: gitk:2070 +#: gitk:2084 msgid "&Reload" -msgstr "Презареждане" +msgstr "&Презареждане" -#: gitk:2071 +#: gitk:2085 msgid "Reread re&ferences" -msgstr "Наново прочитане на настройките" +msgstr "&Наново прочитане на настройките" -#: gitk:2072 +#: gitk:2086 msgid "&List references" -msgstr "Изброяване на указателите" +msgstr "&Изброяване на указателите" -#: gitk:2074 +#: gitk:2088 msgid "Start git &gui" -msgstr "Стартиране на „git gui“" +msgstr "&Стартиране на „git gui“" -#: gitk:2076 +#: gitk:2090 msgid "&Quit" -msgstr "Спиране на програмата" +msgstr "&Спиране на програмата" -#: gitk:2068 +#: gitk:2082 msgid "&File" -msgstr "Файл" +msgstr "&Файл" -#: gitk:2080 +#: gitk:2094 msgid "&Preferences" -msgstr "Настройки" +msgstr "&Настройки" -#: gitk:2079 +#: gitk:2093 msgid "&Edit" -msgstr "Редактиране" +msgstr "&Редактиране" -#: gitk:2084 +#: gitk:2098 msgid "&New view..." -msgstr "Нов изглед…" +msgstr "&Нов изглед…" -#: gitk:2085 +#: gitk:2099 msgid "&Edit view..." -msgstr "Редактиране на изгледа…" +msgstr "&Редактиране на изгледа…" -#: gitk:2086 +#: gitk:2100 msgid "&Delete view" -msgstr "Изтриване на изгледа" +msgstr "&Изтриване на изгледа" -#: gitk:2088 gitk:4043 +#: gitk:2102 msgid "&All files" -msgstr "Всички файлове" +msgstr "&Всички файлове" -#: gitk:2083 gitk:4067 +#: gitk:2097 msgid "&View" -msgstr "Изглед" +msgstr "&Изглед" -#: gitk:2093 gitk:2103 gitk:3012 +#: gitk:2107 gitk:2117 msgid "&About gitk" -msgstr "Относно gitk" +msgstr "&Относно gitk" -#: gitk:2094 gitk:2108 +#: gitk:2108 gitk:2122 msgid "&Key bindings" -msgstr "Клавишни комбинации" +msgstr "&Клавишни комбинации" -#: gitk:2092 gitk:2107 +#: gitk:2106 gitk:2121 msgid "&Help" -msgstr "Помощ" +msgstr "Помо&щ" -#: gitk:2185 gitk:8652 +#: gitk:2199 gitk:8671 msgid "SHA1 ID:" msgstr "SHA1:" -#: gitk:2229 +#: gitk:2243 msgid "Row" msgstr "Ред" -#: gitk:2267 +#: gitk:2281 msgid "Find" msgstr "Търсене" -#: gitk:2295 +#: gitk:2309 msgid "commit" msgstr "подаване" -#: gitk:2299 gitk:2301 gitk:4687 gitk:4710 gitk:4734 gitk:6755 gitk:6827 -#: gitk:6912 +#: gitk:2313 gitk:2315 gitk:4706 gitk:4729 gitk:4753 gitk:6774 gitk:6846 +#: gitk:6931 msgid "containing:" msgstr "съдържащо:" -#: gitk:2302 gitk:3526 gitk:3531 gitk:4763 +#: gitk:2316 gitk:3545 gitk:3550 gitk:4782 msgid "touching paths:" msgstr "засягащо пътищата:" -#: gitk:2303 gitk:4777 +#: gitk:2317 gitk:4796 msgid "adding/removing string:" msgstr "добавящо/премахващо низ" -#: gitk:2304 gitk:4779 +#: gitk:2318 gitk:4798 msgid "changing lines matching:" msgstr "променящо редове напасващи:" -#: gitk:2313 gitk:2315 gitk:4766 +#: gitk:2327 gitk:2329 gitk:4785 msgid "Exact" msgstr "Точно" -#: gitk:2315 gitk:4854 gitk:6723 +#: gitk:2329 gitk:4873 gitk:6742 msgid "IgnCase" msgstr "Без регистър" -#: gitk:2315 gitk:4736 gitk:4852 gitk:6719 +#: gitk:2329 gitk:4755 gitk:4871 gitk:6738 msgid "Regexp" msgstr "Рег. израз" -#: gitk:2317 gitk:2318 gitk:4874 gitk:4904 gitk:4911 gitk:6848 gitk:6916 +#: gitk:2331 gitk:2332 gitk:4893 gitk:4923 gitk:4930 gitk:6867 gitk:6935 msgid "All fields" msgstr "Всички полета" -#: gitk:2318 gitk:4871 gitk:4904 gitk:6786 +#: gitk:2332 gitk:4890 gitk:4923 gitk:6805 msgid "Headline" msgstr "Първи ред" -#: gitk:2319 gitk:4871 gitk:6786 gitk:6916 gitk:7389 +#: gitk:2333 gitk:4890 gitk:6805 gitk:6935 gitk:7408 msgid "Comments" msgstr "Коментари" -#: gitk:2319 gitk:4871 gitk:4876 gitk:4911 gitk:6786 gitk:7324 gitk:8830 -#: gitk:8845 +#: gitk:2333 gitk:4890 gitk:4895 gitk:4930 gitk:6805 gitk:7343 gitk:8849 +#: gitk:8864 msgid "Author" msgstr "Автор" -#: gitk:2319 gitk:4871 gitk:6786 gitk:7326 +#: gitk:2333 gitk:4890 gitk:6805 gitk:7345 msgid "Committer" msgstr "Подаващ" -#: gitk:2350 +#: gitk:2367 msgid "Search" msgstr "Търсене" -#: gitk:2358 +#: gitk:2375 msgid "Diff" msgstr "Разлики" -#: gitk:2360 +#: gitk:2377 msgid "Old version" msgstr "Стара версия" -#: gitk:2362 +#: gitk:2379 msgid "New version" msgstr "Нова версия" -#: gitk:2364 +#: gitk:2382 msgid "Lines of context" msgstr "Контекст в редове" -#: gitk:2374 +#: gitk:2392 msgid "Ignore space change" msgstr "Празните знаци без значение" -#: gitk:2378 gitk:2380 gitk:7959 gitk:8206 +#: gitk:2396 gitk:2398 gitk:7978 gitk:8225 msgid "Line diff" msgstr "Поредови разлики" -#: gitk:2445 +#: gitk:2463 msgid "Patch" msgstr "Кръпка" -#: gitk:2447 +#: gitk:2465 msgid "Tree" msgstr "Дърво" -#: gitk:2617 gitk:2637 +#: gitk:2635 gitk:2656 msgid "Diff this -> selected" msgstr "Разлики между това и избраното" -#: gitk:2618 gitk:2638 +#: gitk:2636 gitk:2657 msgid "Diff selected -> this" msgstr "Разлики между избраното и това" -#: gitk:2619 gitk:2639 +#: gitk:2637 gitk:2658 msgid "Make patch" msgstr "Създаване на кръпка" -#: gitk:2620 gitk:9254 +#: gitk:2638 gitk:9273 msgid "Create tag" msgstr "Създаване на етикет" -#: gitk:2621 gitk:9371 +#: gitk:2639 +msgid "Copy commit summary" +msgstr "Копиране на информацията за подаване" + +#: gitk:2640 gitk:9404 msgid "Write commit to file" msgstr "Запазване на подаването във файл" -#: gitk:2622 gitk:9428 +#: gitk:2641 gitk:9461 msgid "Create new branch" msgstr "Създаване на нов клон" -#: gitk:2623 +#: gitk:2642 msgid "Cherry-pick this commit" msgstr "Отбиране на това подаване" -#: gitk:2624 +#: gitk:2643 msgid "Reset HEAD branch to here" msgstr "Привеждане на върха на клона към текущото подаване" -#: gitk:2625 +#: gitk:2644 msgid "Mark this commit" msgstr "Отбелязване на това подаване" -#: gitk:2626 +#: gitk:2645 msgid "Return to mark" msgstr "Връщане към отбелязаното подаване" -#: gitk:2627 +#: gitk:2646 msgid "Find descendant of this and mark" msgstr "Откриване и отбелязване на наследниците" -#: gitk:2628 +#: gitk:2647 msgid "Compare with marked commit" msgstr "Сравнение с отбелязаното подаване" -#: gitk:2629 gitk:2640 +#: gitk:2648 gitk:2659 msgid "Diff this -> marked commit" msgstr "Разлики между това и отбелязаното" -#: gitk:2630 gitk:2641 +#: gitk:2649 gitk:2660 msgid "Diff marked commit -> this" msgstr "Разлики между отбелязаното и това" -#: gitk:2631 +#: gitk:2650 msgid "Revert this commit" msgstr "Отмяна на това подаване" -#: gitk:2647 +#: gitk:2666 msgid "Check out this branch" msgstr "Изтегляне на този клон" -#: gitk:2648 +#: gitk:2667 msgid "Remove this branch" msgstr "Изтриване на този клон" -#: gitk:2649 +#: gitk:2668 msgid "Copy branch name" msgstr "Копиране на името на клона" -#: gitk:2656 +#: gitk:2675 msgid "Highlight this too" msgstr "Отбелязване и на това" -#: gitk:2657 +#: gitk:2676 msgid "Highlight this only" msgstr "Отбелязване само на това" -#: gitk:2658 +#: gitk:2677 msgid "External diff" msgstr "Външна програма за разлики" -#: gitk:2659 +#: gitk:2678 msgid "Blame parent commit" msgstr "Анотиране на родителското подаване" -#: gitk:2660 +#: gitk:2679 msgid "Copy path" msgstr "Копиране на пътя" -#: gitk:2667 +#: gitk:2686 msgid "Show origin of this line" msgstr "Показване на произхода на този ред" -#: gitk:2668 +#: gitk:2687 msgid "Run git gui blame on this line" msgstr "Изпълнение на „git gui blame“ върху този ред" -#: gitk:3014 +#: gitk:3031 +msgid "About gitk" +msgstr "Относно gitk" + +#: gitk:3033 msgid "" "\n" "Gitk - a commit viewer for git\n" @@ -374,316 +382,324 @@ msgstr "" "\n" "Използвайте и разпространявайте при условията на ОПЛ на ГНУ" -#: gitk:3022 gitk:3089 gitk:9857 +#: gitk:3041 gitk:3108 gitk:9890 msgid "Close" msgstr "Затваряне" -#: gitk:3043 +#: gitk:3062 msgid "Gitk key bindings" msgstr "Клавишни комбинации" -#: gitk:3046 +#: gitk:3065 msgid "Gitk key bindings:" msgstr "Клавишни комбинации:" -#: gitk:3048 +#: gitk:3067 #, tcl-format msgid "<%s-Q>\t\tQuit" msgstr "<%s-Q>\t\tСпиране на програмата" -#: gitk:3049 +#: gitk:3068 #, tcl-format msgid "<%s-W>\t\tClose window" msgstr "<%s-W>\t\tЗатваряне на прозореца" -#: gitk:3050 +#: gitk:3069 msgid "\t\tMove to first commit" msgstr "\t\tКъм първото подаване" -#: gitk:3051 +#: gitk:3070 msgid "\t\tMove to last commit" msgstr "\t\tКъм последното подаване" -#: gitk:3052 +#: gitk:3071 msgid ", p, k\tMove up one commit" msgstr ", p, k\tЕдно подаване нагоре" -#: gitk:3053 +#: gitk:3072 msgid ", n, j\tMove down one commit" msgstr ", n, j\tЕдно подаване надолу" -#: gitk:3054 +#: gitk:3073 msgid ", z, h\tGo back in history list" msgstr ", z, h\tНазад в историята" -#: gitk:3055 +#: gitk:3074 msgid ", x, l\tGo forward in history list" msgstr ", x, l\tНапред в историята" -#: gitk:3056 +#: gitk:3075 #, tcl-format msgid "<%s-n>\tGo to n-th parent of current commit in history list" msgstr "<%s-n>\tКъм n-тия родител на текущото подаване в историята" -#: gitk:3057 +#: gitk:3076 msgid "\tMove up one page in commit list" msgstr "\tСтраница нагоре в списъка с подаванията" -#: gitk:3058 +#: gitk:3077 msgid "\tMove down one page in commit list" msgstr "\tСтраница надолу в списъка с подаванията" -#: gitk:3059 +#: gitk:3078 #, tcl-format msgid "<%s-Home>\tScroll to top of commit list" msgstr "<%s-Home>\tКъм началото на списъка с подаванията" -#: gitk:3060 +#: gitk:3079 #, tcl-format msgid "<%s-End>\tScroll to bottom of commit list" msgstr "<%s-End>\tКъм края на списъка с подаванията" -#: gitk:3061 +#: gitk:3080 #, tcl-format msgid "<%s-Up>\tScroll commit list up one line" msgstr "<%s-Up>\tРед нагоре в списъка с подавания" -#: gitk:3062 +#: gitk:3081 #, tcl-format msgid "<%s-Down>\tScroll commit list down one line" msgstr "<%s-Down>\tРед надолу в списъка с подавания" -#: gitk:3063 +#: gitk:3082 #, tcl-format msgid "<%s-PageUp>\tScroll commit list up one page" msgstr "<%s-PageUp>\tСтраница нагоре в списъка с подавания" -#: gitk:3064 +#: gitk:3083 #, tcl-format msgid "<%s-PageDown>\tScroll commit list down one page" msgstr "<%s-PageDown>\tСтраница надолу в списъка с подавания" -#: gitk:3065 +#: gitk:3084 msgid "\tFind backwards (upwards, later commits)" msgstr "\tТърсене назад (визуално нагоре, исторически — последващи)" -#: gitk:3066 +#: gitk:3085 msgid "\tFind forwards (downwards, earlier commits)" msgstr "" "\tТърсене напред (визуално надолу, исторически — предхождащи)" -#: gitk:3067 +#: gitk:3086 msgid ", b\tScroll diff view up one page" msgstr ", b\tСтраница нагоре в изгледа за разлики" -#: gitk:3068 +#: gitk:3087 msgid "\tScroll diff view up one page" msgstr "\tСтраница надолу в изгледа за разлики" -#: gitk:3069 +#: gitk:3088 msgid "\t\tScroll diff view down one page" msgstr "\t\tСтраница надолу в изгледа за разлики" -#: gitk:3070 +#: gitk:3089 msgid "u\t\tScroll diff view up 18 lines" msgstr "u\t\t18 реда нагоре в изгледа за разлики" -#: gitk:3071 +#: gitk:3090 msgid "d\t\tScroll diff view down 18 lines" msgstr "d\t\t18 реда надолу в изгледа за разлики" -#: gitk:3072 +#: gitk:3091 #, tcl-format msgid "<%s-F>\t\tFind" msgstr "<%s-F>\t\tТърсене" -#: gitk:3073 +#: gitk:3092 #, tcl-format msgid "<%s-G>\t\tMove to next find hit" msgstr "<%s-G>\t\tКъм следващата поява" -#: gitk:3074 +#: gitk:3093 msgid "\tMove to next find hit" msgstr "\tКъм следващата поява" -#: gitk:3075 +#: gitk:3094 msgid "g\t\tGo to commit" msgstr "g\t\tКъм последното подаване" -#: gitk:3076 +#: gitk:3095 msgid "/\t\tFocus the search box" msgstr "/\t\tФокус върху полето за търсене" -#: gitk:3077 +#: gitk:3096 msgid "?\t\tMove to previous find hit" msgstr "?\t\tКъм предишната поява" -#: gitk:3078 +#: gitk:3097 msgid "f\t\tScroll diff view to next file" msgstr "f\t\tСледващ файл в изгледа за разлики" -#: gitk:3079 +#: gitk:3098 #, tcl-format msgid "<%s-S>\t\tSearch for next hit in diff view" msgstr "<%s-S>\t\tТърсене на следващата поява в изгледа за разлики" -#: gitk:3080 +#: gitk:3099 #, tcl-format msgid "<%s-R>\t\tSearch for previous hit in diff view" msgstr "<%s-R>\t\tТърсене на предишната поява в изгледа за разлики" -#: gitk:3081 +#: gitk:3100 #, tcl-format msgid "<%s-KP+>\tIncrease font size" msgstr "<%s-KP+>\tПо-голям размер на шрифта" -#: gitk:3082 +#: gitk:3101 #, tcl-format msgid "<%s-plus>\tIncrease font size" msgstr "<%s-plus>\tПо-голям размер на шрифта" -#: gitk:3083 +#: gitk:3102 #, tcl-format msgid "<%s-KP->\tDecrease font size" msgstr "<%s-KP->\tПо-малък размер на шрифта" -#: gitk:3084 +#: gitk:3103 #, tcl-format msgid "<%s-minus>\tDecrease font size" msgstr "<%s-minus>\tПо-малък размер на шрифта" -#: gitk:3085 +#: gitk:3104 msgid "\t\tUpdate" msgstr "\t\tОбновяване" -#: gitk:3550 gitk:3559 +#: gitk:3569 gitk:3578 #, tcl-format msgid "Error creating temporary directory %s:" msgstr "Грешка при създаването на временната директория „%s“:" -#: gitk:3572 +#: gitk:3591 #, tcl-format msgid "Error getting \"%s\" from %s:" msgstr "Грешка при получаването на „%s“ от %s:" -#: gitk:3635 +#: gitk:3654 msgid "command failed:" msgstr "неуспешно изпълнение на команда:" -#: gitk:3784 +#: gitk:3803 msgid "No such commit" msgstr "Такова подаване няма" -#: gitk:3798 +#: gitk:3817 msgid "git gui blame: command failed:" msgstr "„git gui blame“: неуспешно изпълнение на команда:" -#: gitk:3829 +#: gitk:3848 #, tcl-format msgid "Couldn't read merge head: %s" msgstr "Върхът за сливане не може да бъде прочетен: %s" -#: gitk:3837 +#: gitk:3856 #, tcl-format msgid "Error reading index: %s" msgstr "Грешка при прочитане на индекса: %s" -#: gitk:3862 +#: gitk:3881 #, tcl-format msgid "Couldn't start git blame: %s" msgstr "Командата „git blame“ не може да бъде стартирана: %s" -#: gitk:3865 gitk:6754 +#: gitk:3884 gitk:6773 msgid "Searching" msgstr "Търсене" -#: gitk:3897 +#: gitk:3916 #, tcl-format msgid "Error running git blame: %s" msgstr "Грешка при изпълнението на „git blame“: %s" -#: gitk:3925 +#: gitk:3944 #, tcl-format msgid "That line comes from commit %s, which is not in this view" msgstr "Този ред идва от подаването %s, което не е в изгледа" -#: gitk:3939 +#: gitk:3958 msgid "External diff viewer failed:" msgstr "Неуспешно изпълнение на външната програма за разлики:" -#: gitk:4070 +#: gitk:4062 +msgid "All files" +msgstr "Всички файлове" + +#: gitk:4086 +msgid "View" +msgstr "Изглед" + +#: gitk:4089 msgid "Gitk view definition" msgstr "Дефиниция на изглед в Gitk" -#: gitk:4074 +#: gitk:4093 msgid "Remember this view" msgstr "Запазване на този изглед" -#: gitk:4075 +#: gitk:4094 msgid "References (space separated list):" msgstr "Указатели (списък с разделител интервал):" -#: gitk:4076 +#: gitk:4095 msgid "Branches & tags:" msgstr "Клони и етикети:" -#: gitk:4077 +#: gitk:4096 msgid "All refs" msgstr "Всички указатели" -#: gitk:4078 +#: gitk:4097 msgid "All (local) branches" msgstr "Всички (локални) клони" -#: gitk:4079 +#: gitk:4098 msgid "All tags" msgstr "Всички етикети" -#: gitk:4080 +#: gitk:4099 msgid "All remote-tracking branches" msgstr "Всички следящи клони" -#: gitk:4081 +#: gitk:4100 msgid "Commit Info (regular expressions):" msgstr "Информация за подаване (рег. изр.):" -#: gitk:4082 +#: gitk:4101 msgid "Author:" msgstr "Автор:" -#: gitk:4083 +#: gitk:4102 msgid "Committer:" msgstr "Подал:" -#: gitk:4084 +#: gitk:4103 msgid "Commit Message:" msgstr "Съобщение при подаване:" -#: gitk:4085 +#: gitk:4104 msgid "Matches all Commit Info criteria" msgstr "Съвпадение по всички характеристики на подаването" -#: gitk:4086 +#: gitk:4105 msgid "Matches no Commit Info criteria" msgstr "Не съвпада по никоя от характеристиките на подаването" -#: gitk:4087 +#: gitk:4106 msgid "Changes to Files:" msgstr "Промени по файловете:" -#: gitk:4088 +#: gitk:4107 msgid "Fixed String" msgstr "Дословен низ" -#: gitk:4089 +#: gitk:4108 msgid "Regular Expression" msgstr "Регулярен израз" -#: gitk:4090 +#: gitk:4109 msgid "Search string:" msgstr "Низ за търсене:" -#: gitk:4091 +#: gitk:4110 msgid "" "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 " "15:27:38\"):" @@ -691,204 +707,204 @@ msgstr "" "Дата на подаване („2 weeks ago“ (преди 2 седмици), „2009-03-17 15:27:38“, " "„March 17, 2009 15:27:38“):" -#: gitk:4092 +#: gitk:4111 msgid "Since:" msgstr "От:" -#: gitk:4093 +#: gitk:4112 msgid "Until:" msgstr "До:" -#: gitk:4094 +#: gitk:4113 msgid "Limit and/or skip a number of revisions (positive integer):" msgstr "" "Ограничаване и/или прескачане на определен брой версии (неотрицателно цяло " "число):" -#: gitk:4095 +#: gitk:4114 msgid "Number to show:" msgstr "Брой показани:" -#: gitk:4096 +#: gitk:4115 msgid "Number to skip:" msgstr "Брой прескочени:" -#: gitk:4097 +#: gitk:4116 msgid "Miscellaneous options:" msgstr "Разни:" -#: gitk:4098 +#: gitk:4117 msgid "Strictly sort by date" msgstr "Подреждане по дата" -#: gitk:4099 +#: gitk:4118 msgid "Mark branch sides" msgstr "Отбелязване на страните по клона" -#: gitk:4100 +#: gitk:4119 msgid "Limit to first parent" msgstr "Само първия родител" -#: gitk:4101 +#: gitk:4120 msgid "Simple history" msgstr "Опростена история" -#: gitk:4102 +#: gitk:4121 msgid "Additional arguments to git log:" msgstr "Допълнителни аргументи към „git log“:" -#: gitk:4103 +#: gitk:4122 msgid "Enter files and directories to include, one per line:" msgstr "Въведете файловете и директориите за включване, по елемент на ред" -#: gitk:4104 +#: gitk:4123 msgid "Command to generate more commits to include:" msgstr "" "Команда за генерирането на допълнителни подавания, които да бъдат включени:" -#: gitk:4228 +#: gitk:4247 msgid "Gitk: edit view" msgstr "Gitk: редактиране на изглед" -#: gitk:4236 +#: gitk:4255 msgid "-- criteria for selecting revisions" msgstr "— критерии за избор на версии" -#: gitk:4241 +#: gitk:4260 msgid "View Name" msgstr "Име на изглед" -#: gitk:4316 +#: gitk:4335 msgid "Apply (F5)" msgstr "Прилагане (F5)" -#: gitk:4354 +#: gitk:4373 msgid "Error in commit selection arguments:" msgstr "Грешка в аргументите за избор на подавания:" -#: gitk:4409 gitk:4462 gitk:4924 gitk:4938 gitk:6208 gitk:12373 gitk:12374 +#: gitk:4428 gitk:4481 gitk:4943 gitk:4957 gitk:6227 gitk:12410 gitk:12411 msgid "None" msgstr "Няма" -#: gitk:5021 gitk:5026 +#: gitk:5040 gitk:5045 msgid "Descendant" msgstr "Наследник" -#: gitk:5022 +#: gitk:5041 msgid "Not descendant" msgstr "Не е наследник" -#: gitk:5029 gitk:5034 +#: gitk:5048 gitk:5053 msgid "Ancestor" msgstr "Предшественик" -#: gitk:5030 +#: gitk:5049 msgid "Not ancestor" msgstr "Не е предшественик" -#: gitk:5324 +#: gitk:5343 msgid "Local changes checked in to index but not committed" msgstr "Локални промени добавени към индекса, но неподадени" -#: gitk:5360 +#: gitk:5379 msgid "Local uncommitted changes, not checked in to index" msgstr "Локални промени извън индекса" -#: gitk:7134 +#: gitk:7153 msgid "and many more" msgstr "и още много" -#: gitk:7137 +#: gitk:7156 msgid "many" msgstr "много" -#: gitk:7328 +#: gitk:7347 msgid "Tags:" msgstr "Етикети:" -#: gitk:7345 gitk:7351 gitk:8825 +#: gitk:7364 gitk:7370 gitk:8844 msgid "Parent" msgstr "Родител" -#: gitk:7356 +#: gitk:7375 msgid "Child" msgstr "Дете" -#: gitk:7365 +#: gitk:7384 msgid "Branch" msgstr "Клон" -#: gitk:7368 +#: gitk:7387 msgid "Follows" msgstr "Следва" -#: gitk:7371 +#: gitk:7390 msgid "Precedes" msgstr "Предшества" -#: gitk:7966 +#: gitk:7985 #, tcl-format msgid "Error getting diffs: %s" msgstr "Грешка при получаването на разликите: %s" -#: gitk:8650 +#: gitk:8669 msgid "Goto:" msgstr "Към ред:" -#: gitk:8671 +#: gitk:8690 #, tcl-format msgid "Short SHA1 id %s is ambiguous" msgstr "Съкратената сума по SHA1 %s не е еднозначна" -#: gitk:8678 +#: gitk:8697 #, tcl-format msgid "Revision %s is not known" msgstr "Непозната версия %s" -#: gitk:8688 +#: gitk:8707 #, tcl-format msgid "SHA1 id %s is not known" msgstr "Непозната сума по SHA1 %s" -#: gitk:8690 +#: gitk:8709 #, tcl-format msgid "Revision %s is not in the current view" msgstr "Версия %s не е в текущия изглед" -#: gitk:8832 gitk:8847 +#: gitk:8851 gitk:8866 msgid "Date" msgstr "Дата" -#: gitk:8835 +#: gitk:8854 msgid "Children" msgstr "Деца" -#: gitk:8898 +#: gitk:8917 #, tcl-format msgid "Reset %s branch to here" msgstr "Зануляване на клона „%s“ към текущото подаване" -#: gitk:8900 +#: gitk:8919 msgid "Detached head: can't reset" msgstr "Несвързан връх: невъзможно зануляване" -#: gitk:9005 gitk:9011 +#: gitk:9024 gitk:9030 msgid "Skipping merge commit " msgstr "Пропускане на подаването на сливането" -#: gitk:9020 gitk:9025 +#: gitk:9039 gitk:9044 msgid "Error getting patch ID for " msgstr "Грешка при получаването на идентификатора на " -#: gitk:9021 gitk:9026 +#: gitk:9040 gitk:9045 msgid " - stopping\n" msgstr " — спиране\n" -#: gitk:9031 gitk:9034 gitk:9042 gitk:9056 gitk:9065 +#: gitk:9050 gitk:9053 gitk:9061 gitk:9075 gitk:9084 msgid "Commit " msgstr "Подаване" -#: gitk:9035 +#: gitk:9054 msgid "" " is the same patch as\n" " " @@ -896,7 +912,7 @@ msgstr "" " е същата кръпка като\n" " " -#: gitk:9043 +#: gitk:9062 msgid "" " differs from\n" " " @@ -904,7 +920,7 @@ msgstr "" " се различава от\n" " " -#: gitk:9045 +#: gitk:9064 msgid "" "Diff of commits:\n" "\n" @@ -912,130 +928,130 @@ msgstr "" "Разлика между подаванията:\n" "\n" -#: gitk:9057 gitk:9066 +#: gitk:9076 gitk:9085 #, tcl-format msgid " has %s children - stopping\n" msgstr " има %s деца — спиране\n" -#: gitk:9085 +#: gitk:9104 #, tcl-format msgid "Error writing commit to file: %s" msgstr "Грешка при запазването на подаването във файл: %s" -#: gitk:9091 +#: gitk:9110 #, tcl-format msgid "Error diffing commits: %s" msgstr "Грешка при изчисляването на разликите между подаванията: %s" -#: gitk:9137 +#: gitk:9156 msgid "Top" msgstr "Най-горе" -#: gitk:9138 +#: gitk:9157 msgid "From" msgstr "От" -#: gitk:9143 +#: gitk:9162 msgid "To" msgstr "До" -#: gitk:9167 +#: gitk:9186 msgid "Generate patch" msgstr "Генериране на кръпка" -#: gitk:9169 +#: gitk:9188 msgid "From:" msgstr "От:" -#: gitk:9178 +#: gitk:9197 msgid "To:" msgstr "До:" -#: gitk:9187 +#: gitk:9206 msgid "Reverse" msgstr "Обръщане" -#: gitk:9189 gitk:9385 +#: gitk:9208 gitk:9418 msgid "Output file:" msgstr "Запазване във файла:" -#: gitk:9195 +#: gitk:9214 msgid "Generate" msgstr "Генериране" -#: gitk:9233 +#: gitk:9252 msgid "Error creating patch:" msgstr "Грешка при създаването на кръпка:" -#: gitk:9256 gitk:9373 gitk:9430 +#: gitk:9275 gitk:9406 gitk:9463 msgid "ID:" msgstr "Идентификатор:" -#: gitk:9265 +#: gitk:9284 msgid "Tag name:" msgstr "Име на етикет:" -#: gitk:9268 +#: gitk:9287 msgid "Tag message is optional" msgstr "Съобщението за етикет е незадължително" -#: gitk:9270 +#: gitk:9289 msgid "Tag message:" msgstr "Съобщение за етикет:" -#: gitk:9274 gitk:9439 +#: gitk:9293 gitk:9472 msgid "Create" msgstr "Създаване" -#: gitk:9292 +#: gitk:9311 msgid "No tag name specified" msgstr "Липсва име на етикет" -#: gitk:9296 +#: gitk:9315 #, tcl-format msgid "Tag \"%s\" already exists" msgstr "Етикетът „%s“ вече съществува" -#: gitk:9306 +#: gitk:9325 msgid "Error creating tag:" msgstr "Грешка при създаването на етикет:" -#: gitk:9382 +#: gitk:9415 msgid "Command:" msgstr "Команда:" -#: gitk:9390 +#: gitk:9423 msgid "Write" msgstr "Запазване" -#: gitk:9408 +#: gitk:9441 msgid "Error writing commit:" msgstr "Грешка при запазването на подаването:" -#: gitk:9435 +#: gitk:9468 msgid "Name:" msgstr "Име:" -#: gitk:9458 +#: gitk:9491 msgid "Please specify a name for the new branch" msgstr "Укажете име за новия клон" -#: gitk:9463 +#: gitk:9496 #, tcl-format msgid "Branch '%s' already exists. Overwrite?" msgstr "Клонът „%s“ вече съществува. Да бъде ли презаписан?" -#: gitk:9530 +#: gitk:9563 #, tcl-format msgid "Commit %s is already included in branch %s -- really re-apply it?" msgstr "" "Подаването „%s“ вече е включено в клона „%s“ — да бъде ли приложено отново?" -#: gitk:9535 +#: gitk:9568 msgid "Cherry-picking" msgstr "Отбиране" -#: gitk:9544 +#: gitk:9577 #, tcl-format msgid "" "Cherry-pick failed because of local changes to file '%s'.\n" @@ -1044,7 +1060,7 @@ msgstr "" "Неуспешно отбиране, защото във файла „%s“ има локални промени.\n" "Подайте, занулете или ги скатайте и пробвайте отново." -#: gitk:9550 +#: gitk:9583 msgid "" "Cherry-pick failed because of merge conflict.\n" "Do you wish to run git citool to resolve it?" @@ -1052,20 +1068,20 @@ msgstr "" "Неуспешно отбиране поради конфликти при сливане.\n" "Искате ли да ги коригирате чрез „git citool“?" -#: gitk:9566 gitk:9624 +#: gitk:9599 gitk:9657 msgid "No changes committed" msgstr "Не са подадени промени" -#: gitk:9593 +#: gitk:9626 #, tcl-format msgid "Commit %s is not included in branch %s -- really revert it?" msgstr "Подаването „%s“ не е включено в клона „%s“. Да бъде ли отменено?" -#: gitk:9598 +#: gitk:9631 msgid "Reverting" msgstr "Отмяна" -#: gitk:9606 +#: gitk:9639 #, tcl-format msgid "" "Revert failed because of local changes to the following files:%s Please " @@ -1074,7 +1090,7 @@ msgstr "" "Неуспешна отмяна, защото във файла „%s“ има локални промени.\n" "Подайте, занулете или ги скатайте и пробвайте отново.<" -#: gitk:9610 +#: gitk:9643 msgid "" "Revert failed because of merge conflict.\n" " Do you wish to run git citool to resolve it?" @@ -1082,28 +1098,28 @@ msgstr "" "Неуспешно отмяна поради конфликти при сливане.\n" "Искате ли да ги коригирате чрез „git citool“?" -#: gitk:9653 +#: gitk:9686 msgid "Confirm reset" msgstr "Потвърждаване на зануляването" -#: gitk:9655 +#: gitk:9688 #, tcl-format msgid "Reset branch %s to %s?" msgstr "Да се занули ли клонът „%s“ към „%s“?" -#: gitk:9657 +#: gitk:9690 msgid "Reset type:" msgstr "Вид зануляване:" -#: gitk:9660 +#: gitk:9693 msgid "Soft: Leave working tree and index untouched" msgstr "Слабо: работното дърво и индекса остават същите" -#: gitk:9663 +#: gitk:9696 msgid "Mixed: Leave working tree untouched, reset index" msgstr "Смесено: работното дърво остава същото, индексът се занулява" -#: gitk:9666 +#: gitk:9699 msgid "" "Hard: Reset working tree and index\n" "(discard ALL local changes)" @@ -1111,19 +1127,19 @@ msgstr "" "Силно: зануляване и на работното дърво, и на индекса\n" "(*ВСИЧКИ* локални промени ще бъдат безвъзвратно загубени)" -#: gitk:9683 +#: gitk:9716 msgid "Resetting" msgstr "Зануляване" -#: gitk:9743 +#: gitk:9776 msgid "Checking out" msgstr "Изтегляне" -#: gitk:9796 +#: gitk:9829 msgid "Cannot delete the currently checked-out branch" msgstr "Текущо изтегленият клон не може да бъде изтрит" -#: gitk:9802 +#: gitk:9835 #, tcl-format msgid "" "The commits on branch %s aren't on any other branch.\n" @@ -1132,16 +1148,16 @@ msgstr "" "Подаванията на клона „%s“ не са на никой друг клон.\n" "Наистина ли да се изтрие клонът „%s“?" -#: gitk:9833 +#: gitk:9866 #, tcl-format msgid "Tags and heads: %s" msgstr "Етикети и върхове: %s" -#: gitk:9850 +#: gitk:9883 msgid "Filter" msgstr "Филтриране" -#: gitk:10146 +#: gitk:10179 msgid "" "Error reading commit topology information; branch and preceding/following " "tag information will be incomplete." @@ -1149,201 +1165,201 @@ msgstr "" "Грешка при прочитането на топологията на подаванията. Информацията за клона " "и предшестващите/следващите етикети ще е непълна." -#: gitk:11123 +#: gitk:11156 msgid "Tag" msgstr "Етикет" -#: gitk:11127 +#: gitk:11160 msgid "Id" msgstr "Идентификатор" -#: gitk:11210 +#: gitk:11243 msgid "Gitk font chooser" msgstr "Избор на шрифт за Gitk" -#: gitk:11227 +#: gitk:11260 msgid "B" msgstr "Ч" -#: gitk:11230 +#: gitk:11263 msgid "I" msgstr "К" -#: gitk:11348 +#: gitk:11381 msgid "Commit list display options" msgstr "Настройки на списъка с подавания" -#: gitk:11351 +#: gitk:11384 msgid "Maximum graph width (lines)" msgstr "Максимална широчина на графа (в редове)" -#: gitk:11355 +#: gitk:11388 #, no-tcl-format msgid "Maximum graph width (% of pane)" msgstr "Максимална широчина на графа (% от панела)" -#: gitk:11358 +#: gitk:11391 msgid "Show local changes" msgstr "Показване на локалните промени" -#: gitk:11361 +#: gitk:11394 msgid "Auto-select SHA1 (length)" msgstr "Автоматично избиране на SHA1 (дължина)" -#: gitk:11365 +#: gitk:11398 msgid "Hide remote refs" msgstr "Скриване на отдалечените указатели" -#: gitk:11369 +#: gitk:11402 msgid "Diff display options" msgstr "Настройки на показването на разликите" -#: gitk:11371 +#: gitk:11404 msgid "Tab spacing" msgstr "Широчина на табулатора" -#: gitk:11374 +#: gitk:11407 msgid "Display nearby tags/heads" msgstr "Извеждане на близките етикети и върхове" -#: gitk:11377 +#: gitk:11410 msgid "Maximum # tags/heads to show" msgstr "Максимален брой етикети/върхове за показване" -#: gitk:11380 +#: gitk:11413 msgid "Limit diffs to listed paths" msgstr "Разлика само в избраните пътища" -#: gitk:11383 +#: gitk:11416 msgid "Support per-file encodings" msgstr "Поддръжка на различни кодирания за всеки файл" -#: gitk:11389 gitk:11536 +#: gitk:11422 gitk:11569 msgid "External diff tool" msgstr "Външен инструмент за разлики" -#: gitk:11390 +#: gitk:11423 msgid "Choose..." msgstr "Избор…" -#: gitk:11395 +#: gitk:11428 msgid "General options" msgstr "Общи настройки" -#: gitk:11398 +#: gitk:11431 msgid "Use themed widgets" msgstr "Използване на тема за графичните обекти" -#: gitk:11400 +#: gitk:11433 msgid "(change requires restart)" msgstr "(промяната изисква рестартиране на Gitk)" -#: gitk:11402 +#: gitk:11435 msgid "(currently unavailable)" msgstr "(в момента недостъпно)" -#: gitk:11413 +#: gitk:11446 msgid "Colors: press to choose" msgstr "Цветове: избира се с натискане" -#: gitk:11416 +#: gitk:11449 msgid "Interface" msgstr "Интерфейс" -#: gitk:11417 +#: gitk:11450 msgid "interface" msgstr "интерфейс" -#: gitk:11420 +#: gitk:11453 msgid "Background" msgstr "Фон" -#: gitk:11421 gitk:11451 +#: gitk:11454 gitk:11484 msgid "background" msgstr "фон" -#: gitk:11424 +#: gitk:11457 msgid "Foreground" msgstr "Знаци" -#: gitk:11425 +#: gitk:11458 msgid "foreground" msgstr "знаци" -#: gitk:11428 +#: gitk:11461 msgid "Diff: old lines" msgstr "Разлика: стари редове" -#: gitk:11429 +#: gitk:11462 msgid "diff old lines" msgstr "разлика, стари редове" -#: gitk:11433 +#: gitk:11466 msgid "Diff: new lines" msgstr "Разлика: нови редове" -#: gitk:11434 +#: gitk:11467 msgid "diff new lines" msgstr "разлика, нови редове" -#: gitk:11438 +#: gitk:11471 msgid "Diff: hunk header" msgstr "Разлика: начало на парче" -#: gitk:11440 +#: gitk:11473 msgid "diff hunk header" msgstr "разлика, начало на парче" -#: gitk:11444 +#: gitk:11477 msgid "Marked line bg" msgstr "Фон на отбелязан ред" -#: gitk:11446 +#: gitk:11479 msgid "marked line background" msgstr "фон на отбелязан ред" -#: gitk:11450 +#: gitk:11483 msgid "Select bg" msgstr "Избор на фон" -#: gitk:11459 +#: gitk:11492 msgid "Fonts: press to choose" msgstr "Шрифтове: избира се с натискане" -#: gitk:11461 +#: gitk:11494 msgid "Main font" msgstr "Основен шрифт" -#: gitk:11462 +#: gitk:11495 msgid "Diff display font" msgstr "Шрифт за разликите" -#: gitk:11463 +#: gitk:11496 msgid "User interface font" msgstr "Шрифт на интерфейса" -#: gitk:11485 +#: gitk:11518 msgid "Gitk preferences" msgstr "Настройки на Gitk" -#: gitk:11494 +#: gitk:11527 msgid "General" msgstr "Общи" -#: gitk:11495 +#: gitk:11528 msgid "Colors" msgstr "Цветове" -#: gitk:11496 +#: gitk:11529 msgid "Fonts" msgstr "Шрифтове" -#: gitk:11546 +#: gitk:11579 #, tcl-format msgid "Gitk: choose color for %s" msgstr "Gitk: избор на цвят на „%s“" -#: gitk:12059 +#: gitk:12092 msgid "" "Sorry, gitk cannot run with this version of Tcl/Tk.\n" " Gitk requires at least Tcl/Tk 8.4." @@ -1351,15 +1367,15 @@ msgstr "" "Тази версия на Tcl/Tk не се поддържа от Gitk.\n" " Необходима ви е поне Tcl/Tk 8.4." -#: gitk:12269 +#: gitk:12302 msgid "Cannot find a git repository here." msgstr "Тук липсва хранилище на Git." -#: gitk:12316 +#: gitk:12349 #, tcl-format msgid "Ambiguous argument '%s': both revision and filename" msgstr "Нееднозначен аргумент „%s“: има и такава версия, и такъв файл" -#: gitk:12328 +#: gitk:12361 msgid "Bad arguments to gitk:" msgstr "Неправилни аргументи на gitk:" diff --git a/gitk-git/po/de.po b/gitk-git/po/de.po index d9ba4052e2..bde749ed8a 100644 --- a/gitk-git/po/de.po +++ b/gitk-git/po/de.po @@ -23,11 +23,11 @@ msgstr "Liste der nicht zusammengeführten Dateien nicht gefunden:" #: gitk:212 gitk:2381 msgid "Color words" -msgstr "" +msgstr "Wörter einfärben" #: gitk:217 gitk:2381 gitk:8220 gitk:8253 msgid "Markup words" -msgstr "" +msgstr "Wörter kennzeichnen" #: gitk:324 msgid "Error parsing revisions:" @@ -187,7 +187,7 @@ msgstr "Änderungen:" #: gitk:2304 gitk:4779 msgid "changing lines matching:" -msgstr "" +msgstr "Geänderte Zeilen entsprechen:" #: gitk:2313 gitk:2315 gitk:4766 msgid "Exact" @@ -248,7 +248,7 @@ msgstr "Leerzeichenänderungen ignorieren" #: gitk:2378 gitk:2380 gitk:7959 gitk:8206 msgid "Line diff" -msgstr "" +msgstr "Zeilenunterschied" #: gitk:2445 msgid "Patch" @@ -307,19 +307,16 @@ msgid "Compare with marked commit" msgstr "Mit Lesezeichen vergleichen" #: gitk:2629 gitk:2640 -#, fuzzy msgid "Diff this -> marked commit" -msgstr "Vergleich: diese -> gewählte" +msgstr "Vergleich: diese -> gewählte Version" #: gitk:2630 gitk:2641 -#, fuzzy msgid "Diff marked commit -> this" -msgstr "Vergleich: gewählte -> diese" +msgstr "Vergleich: gewählte -> diese Version" #: gitk:2631 -#, fuzzy msgid "Revert this commit" -msgstr "Lesezeichen setzen" +msgstr "Version umkehren" #: gitk:2647 msgid "Check out this branch" @@ -331,7 +328,7 @@ msgstr "Zweig löschen" #: gitk:2649 msgid "Copy branch name" -msgstr "" +msgstr "Zweigname kopieren" #: gitk:2656 msgid "Highlight this too" @@ -351,7 +348,7 @@ msgstr "Annotieren der Elternversion" #: gitk:2660 msgid "Copy path" -msgstr "" +msgstr "Pfad kopieren" #: gitk:2667 msgid "Show origin of this line" @@ -362,7 +359,6 @@ msgid "Run git gui blame on this line" msgstr "Diese Zeile annotieren (»git gui blame«)" #: gitk:3014 -#, fuzzy msgid "" "\n" "Gitk - a commit viewer for git\n" @@ -374,7 +370,7 @@ msgstr "" "\n" "Gitk - eine Visualisierung der Git-Historie\n" "\n" -"Copyright \\u00a9 2005-2010 Paul Mackerras\n" +"Copyright \\u00a9 2005-2014 Paul Mackerras\n" "\n" "Benutzung und Weiterverbreitung gemäß den Bedingungen der GNU General Public " "License" @@ -397,9 +393,9 @@ msgid "<%s-Q>\t\tQuit" msgstr "<%s-Q>\t\tBeenden" #: gitk:3049 -#, fuzzy, tcl-format +#, tcl-format msgid "<%s-W>\t\tClose window" -msgstr "<%s-F>\t\tSuchen" +msgstr "<%s-F>\t\tFenster schließen" #: gitk:3050 msgid "\t\tMove to first commit" @@ -410,19 +406,16 @@ msgid "\t\tMove to last commit" msgstr "\t\tZur ältesten Version springen" #: gitk:3052 -#, fuzzy msgid ", p, k\tMove up one commit" -msgstr ", p, i\tNächste neuere Version" +msgstr ", p, k\tNächste neuere Version" #: gitk:3053 -#, fuzzy msgid ", n, j\tMove down one commit" -msgstr ", n, k\tNächste ältere Version" +msgstr ", n, j\tNächste ältere Version" #: gitk:3054 -#, fuzzy msgid ", z, h\tGo back in history list" -msgstr ", z, j\tEine Version zurückgehen" +msgstr ", z, h\tEine Version zurückgehen" #: gitk:3055 msgid ", x, l\tGo forward in history list" @@ -431,7 +424,7 @@ msgstr ", x, l\tEine Version weitergehen" #: gitk:3056 #, tcl-format msgid "<%s-n>\tGo to n-th parent of current commit in history list" -msgstr "" +msgstr "<%s-n>\tZu n-ter Elternversion in Versionshistorie springen" #: gitk:3057 msgid "\tMove up one page in commit list" @@ -514,9 +507,8 @@ msgid "\tMove to next find hit" msgstr "\tWeitersuchen" #: gitk:3075 -#, fuzzy msgid "g\t\tGo to commit" -msgstr "\t\tZur ältesten Version springen" +msgstr "g\t\tZu Version springen" #: gitk:3076 msgid "/\t\tFocus the search box" @@ -673,9 +665,8 @@ msgid "Matches all Commit Info criteria" msgstr "Alle Versionsinformationen-Kriterien erfüllen" #: gitk:4086 -#, fuzzy msgid "Matches no Commit Info criteria" -msgstr "Alle Versionsinformationen-Kriterien erfüllen" +msgstr "keine Versionsinformationen-Kriterien erfüllen" #: gitk:4087 msgid "Changes to Files:" @@ -802,7 +793,7 @@ msgstr "Lokale Änderungen, nicht bereitgestellt" #: gitk:7134 msgid "and many more" -msgstr "" +msgstr "und weitere" #: gitk:7137 msgid "many" @@ -1066,34 +1057,31 @@ msgid "No changes committed" msgstr "Keine Änderungen eingetragen" #: gitk:9593 -#, fuzzy, tcl-format +#, tcl-format msgid "Commit %s is not included in branch %s -- really revert it?" msgstr "" -"Version »%s« ist bereits im Zweig »%s« enthalten -- trotzdem erneut " -"eintragen?" +"Version »%s« ist nicht im Zweig »%s« enthalten -- trotzdem umkehren?" #: gitk:9598 -#, fuzzy msgid "Reverting" -msgstr "Zurücksetzen" +msgstr "Umkehren" #: gitk:9606 -#, fuzzy, tcl-format +#, tcl-format msgid "" "Revert failed because of local changes to the following files:%s Please " "commit, reset or stash your changes and try again." msgstr "" -"Pflücken fehlgeschlagen, da noch lokale Änderungen in Datei »%s«\n" +"Umkehren fehlgeschlagen, da noch lokale Änderungen in Datei »%s«\n" "vorliegen. Bitte diese Änderungen eintragen, zurücksetzen oder\n" "zwischenspeichern (»git stash«) und dann erneut versuchen." #: gitk:9610 -#, fuzzy msgid "" "Revert failed because of merge conflict.\n" " Do you wish to run git citool to resolve it?" msgstr "" -"Pflücken fehlgeschlagen, da ein Zusammenführungs-Konflikt aufgetreten\n" +"Umkehren fehlgeschlagen, da ein Zusammenführungs-Konflikt aufgetreten\n" "ist. Soll das Zusammenführungs-Werkzeug (»git citool«) aufgerufen\n" "werden, um diesen Konflikt aufzulösen?" @@ -1206,9 +1194,8 @@ msgid "Show local changes" msgstr "Lokale Änderungen anzeigen" #: gitk:11361 -#, fuzzy msgid "Auto-select SHA1 (length)" -msgstr "SHA1-Hashwert automatisch auswählen" +msgstr "SHA1-Hashwert (Länge) automatisch auswählen" #: gitk:11365 msgid "Hide remote refs" @@ -1223,13 +1210,12 @@ msgid "Tab spacing" msgstr "Tabulatorbreite" #: gitk:11374 -#, fuzzy msgid "Display nearby tags/heads" -msgstr "Naheliegende Markierungen anzeigen" +msgstr "Naheliegende Markierungen/Zweigspitzen anzeigen" #: gitk:11377 msgid "Maximum # tags/heads to show" -msgstr "" +msgstr "Maximale Anzahl anzuzeigender Markierungen/Zweigspitzen" #: gitk:11380 msgid "Limit diffs to listed paths" @@ -1348,17 +1334,16 @@ msgid "Gitk preferences" msgstr "Gitk-Einstellungen" #: gitk:11494 -#, fuzzy msgid "General" -msgstr "Erzeugen" +msgstr "Allgemein" #: gitk:11495 msgid "Colors" -msgstr "" +msgstr "Farben" #: gitk:11496 msgid "Fonts" -msgstr "" +msgstr "Schriftarten" #: gitk:11546 #, tcl-format @@ -1370,6 +1355,8 @@ msgid "" "Sorry, gitk cannot run with this version of Tcl/Tk.\n" " Gitk requires at least Tcl/Tk 8.4." msgstr "" +"Entschuldigung, gitk kann nicht mit dieser Tcl/Tk Version ausgeführt werden.\n" +" Gitk erfordert mindestens Tcl/Tk 8.4." #: gitk:12269 msgid "Cannot find a git repository here." diff --git a/gitk-git/po/fr.po b/gitk-git/po/fr.po index 80f72fb453..c44f994fa5 100644 --- a/gitk-git/po/fr.po +++ b/gitk-git/po/fr.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the gitk package. # Translators: # Emmanuel Trillaud -# +# Jean-Noël Avila msgid "" msgstr "" "Project-Id-Version: gitk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-05-17 14:32+1000\n" -"PO-Revision-Date: 2009-11-19 22:13+0100\n" -"Last-Translator: Emmanuel Trillaud \n" +"POT-Creation-Date: 2016-01-22 22:04+0100\n" +"PO-Revision-Date: 2016-01-22 23:28+0100\n" +"Last-Translator: Jean-Noël Avila \n" "Language-Team: git@vger.kernel.org\n" "Language: \n" "MIME-Version: 1.0\n" @@ -23,13 +23,13 @@ msgstr "" msgid "Couldn't get list of unmerged files:" msgstr "Impossible de récupérer la liste des fichiers non fusionnés :" -#: gitk:212 gitk:2381 +#: gitk:212 gitk:2399 msgid "Color words" -msgstr "" +msgstr "Colorier les mots différents" -#: gitk:217 gitk:2381 gitk:8220 gitk:8253 +#: gitk:217 gitk:2399 gitk:8239 gitk:8272 msgid "Markup words" -msgstr "" +msgstr "Marquer les mots différents" #: gitk:324 msgid "Error parsing revisions:" @@ -47,13 +47,10 @@ msgstr "" # FIXME : améliorer la traduction de 'file limite' #: gitk:396 -#, fuzzy msgid "" "No files selected: --merge specified but no unmerged files are within file " "limit." -msgstr "" -"Aucun fichier sélectionné : --merge précisé mais aucun fichier non fusionné " -"n'est dans la limite des fichiers." +msgstr "Aucun fichier sélectionné : --merge précisé mais aucun fichier non fusionné n'est dans la limite des fichiers." #: gitk:418 gitk:566 msgid "Error executing git log:" @@ -63,15 +60,15 @@ msgstr "Erreur à l'exécution de git log :" msgid "Reading" msgstr "Lecture en cours" -#: gitk:496 gitk:4525 +#: gitk:496 gitk:4544 msgid "Reading commits..." msgstr "Lecture des commits..." -#: gitk:499 gitk:1637 gitk:4528 +#: gitk:499 gitk:1637 gitk:4547 msgid "No commits selected" msgstr "Aucun commit sélectionné" -#: gitk:1445 gitk:4045 gitk:12432 +#: gitk:1445 gitk:4064 gitk:12469 msgid "Command line" msgstr "Ligne de commande" @@ -83,290 +80,294 @@ msgstr "Impossible de lire la sortie de git log :" msgid "No commit information available" msgstr "Aucune information disponible sur le commit" -#: gitk:1903 gitk:1932 gitk:4315 gitk:9669 gitk:11241 gitk:11521 +#: gitk:1903 gitk:1932 gitk:4334 gitk:9702 gitk:11274 gitk:11554 msgid "OK" msgstr "OK" -#: gitk:1934 gitk:4317 gitk:9196 gitk:9275 gitk:9391 gitk:9440 gitk:9671 -#: gitk:11242 gitk:11522 +#: gitk:1934 gitk:4336 gitk:9215 gitk:9294 gitk:9424 gitk:9473 gitk:9704 +#: gitk:11275 gitk:11555 msgid "Cancel" msgstr "Annuler" -#: gitk:2069 +#: gitk:2083 msgid "&Update" msgstr "Mise à jour" -#: gitk:2070 +#: gitk:2084 msgid "&Reload" -msgstr "Recharger" +msgstr "&Recharger" -#: gitk:2071 +#: gitk:2085 msgid "Reread re&ferences" -msgstr "Relire les références" +msgstr "Relire les ré&férences" -#: gitk:2072 +#: gitk:2086 msgid "&List references" -msgstr "Lister les références" +msgstr "&Lister les références" -#: gitk:2074 +#: gitk:2088 msgid "Start git &gui" -msgstr "Démarrer git gui" +msgstr "Démarrer git &gui" -#: gitk:2076 +#: gitk:2090 msgid "&Quit" -msgstr "Quitter" +msgstr "&Quitter" -#: gitk:2068 +#: gitk:2082 msgid "&File" -msgstr "Fichier" +msgstr "&Fichier" -#: gitk:2080 +#: gitk:2094 msgid "&Preferences" msgstr "Préférences" -#: gitk:2079 +#: gitk:2093 msgid "&Edit" -msgstr "Éditer" +msgstr "&Éditer" -#: gitk:2084 +#: gitk:2098 msgid "&New view..." -msgstr "Nouvelle vue..." +msgstr "&Nouvelle vue..." -#: gitk:2085 +#: gitk:2099 msgid "&Edit view..." -msgstr "Éditer la vue..." +msgstr "&Éditer la vue..." -#: gitk:2086 +#: gitk:2100 msgid "&Delete view" msgstr "Supprimer la vue" -#: gitk:2088 gitk:4043 +#: gitk:2102 msgid "&All files" msgstr "Tous les fichiers" -#: gitk:2083 gitk:4067 +#: gitk:2097 msgid "&View" -msgstr "Vue" +msgstr "&Vue" -#: gitk:2093 gitk:2103 gitk:3012 +#: gitk:2107 gitk:2117 msgid "&About gitk" msgstr "À propos de gitk" -#: gitk:2094 gitk:2108 +#: gitk:2108 gitk:2122 msgid "&Key bindings" msgstr "Raccourcis clavier" -#: gitk:2092 gitk:2107 +#: gitk:2106 gitk:2121 msgid "&Help" msgstr "Aide" -#: gitk:2185 gitk:8652 +#: gitk:2199 gitk:8671 msgid "SHA1 ID:" msgstr "Id SHA1 :" -#: gitk:2229 +#: gitk:2243 msgid "Row" msgstr "Colonne" -#: gitk:2267 +#: gitk:2281 msgid "Find" msgstr "Recherche" -#: gitk:2295 +#: gitk:2309 msgid "commit" msgstr "commit" -#: gitk:2299 gitk:2301 gitk:4687 gitk:4710 gitk:4734 gitk:6755 gitk:6827 -#: gitk:6912 +#: gitk:2313 gitk:2315 gitk:4706 gitk:4729 gitk:4753 gitk:6774 gitk:6846 +#: gitk:6931 msgid "containing:" msgstr "contient :" -#: gitk:2302 gitk:3526 gitk:3531 gitk:4763 +#: gitk:2316 gitk:3545 gitk:3550 gitk:4782 msgid "touching paths:" msgstr "chemins modifiés :" -#: gitk:2303 gitk:4777 +#: gitk:2317 gitk:4796 msgid "adding/removing string:" msgstr "ajoute/supprime la chaîne :" -#: gitk:2304 gitk:4779 +#: gitk:2318 gitk:4798 msgid "changing lines matching:" -msgstr "" +msgstr "modifie les lignes vérifiant :" -#: gitk:2313 gitk:2315 gitk:4766 +#: gitk:2327 gitk:2329 gitk:4785 msgid "Exact" msgstr "Exact" -#: gitk:2315 gitk:4854 gitk:6723 +#: gitk:2329 gitk:4873 gitk:6742 msgid "IgnCase" msgstr "Ignorer la casse" -#: gitk:2315 gitk:4736 gitk:4852 gitk:6719 +#: gitk:2329 gitk:4755 gitk:4871 gitk:6738 msgid "Regexp" msgstr "Expression régulière" -#: gitk:2317 gitk:2318 gitk:4874 gitk:4904 gitk:4911 gitk:6848 gitk:6916 +#: gitk:2331 gitk:2332 gitk:4893 gitk:4923 gitk:4930 gitk:6867 gitk:6935 msgid "All fields" msgstr "Tous les champs" -#: gitk:2318 gitk:4871 gitk:4904 gitk:6786 +#: gitk:2332 gitk:4890 gitk:4923 gitk:6805 msgid "Headline" -msgstr "Surligner" +msgstr "Titre" -#: gitk:2319 gitk:4871 gitk:6786 gitk:6916 gitk:7389 +#: gitk:2333 gitk:4890 gitk:6805 gitk:6935 gitk:7408 msgid "Comments" msgstr "Commentaires" -#: gitk:2319 gitk:4871 gitk:4876 gitk:4911 gitk:6786 gitk:7324 gitk:8830 -#: gitk:8845 +#: gitk:2333 gitk:4890 gitk:4895 gitk:4930 gitk:6805 gitk:7343 gitk:8849 +#: gitk:8864 msgid "Author" msgstr "Auteur" -#: gitk:2319 gitk:4871 gitk:6786 gitk:7326 +#: gitk:2333 gitk:4890 gitk:6805 gitk:7345 msgid "Committer" -msgstr "Auteur du commit" +msgstr "Validateur" -#: gitk:2350 +#: gitk:2367 msgid "Search" msgstr "Rechercher" -#: gitk:2358 +#: gitk:2375 msgid "Diff" msgstr "Diff" -#: gitk:2360 +#: gitk:2377 msgid "Old version" msgstr "Ancienne version" -#: gitk:2362 +#: gitk:2379 msgid "New version" msgstr "Nouvelle version" -#: gitk:2364 +#: gitk:2382 msgid "Lines of context" msgstr "Lignes de contexte" -#: gitk:2374 +#: gitk:2392 msgid "Ignore space change" msgstr "Ignorer les modifications d'espace" -#: gitk:2378 gitk:2380 gitk:7959 gitk:8206 +#: gitk:2396 gitk:2398 gitk:7978 gitk:8225 msgid "Line diff" -msgstr "" +msgstr "différence par ligne" -#: gitk:2445 +#: gitk:2463 msgid "Patch" msgstr "Patch" -#: gitk:2447 +#: gitk:2465 msgid "Tree" msgstr "Arbre" -#: gitk:2617 gitk:2637 +#: gitk:2635 gitk:2656 msgid "Diff this -> selected" -msgstr "Diff entre ceci et la sélection" +msgstr "Diff ceci -> la sélection" -#: gitk:2618 gitk:2638 +#: gitk:2636 gitk:2657 msgid "Diff selected -> this" -msgstr "Diff entre sélection et ceci" +msgstr "Diff sélection -> ceci" -#: gitk:2619 gitk:2639 +#: gitk:2637 gitk:2658 msgid "Make patch" msgstr "Créer patch" -#: gitk:2620 gitk:9254 +#: gitk:2638 gitk:9273 msgid "Create tag" -msgstr "Créer tag" +msgstr "Créer étiquette" + +#: gitk:2639 +msgid "Copy commit summary" +msgstr "Copié le résumé du commit" -#: gitk:2621 gitk:9371 +#: gitk:2640 gitk:9404 msgid "Write commit to file" msgstr "Écrire le commit dans un fichier" -#: gitk:2622 gitk:9428 +#: gitk:2641 gitk:9461 msgid "Create new branch" msgstr "Créer une nouvelle branche" -#: gitk:2623 +#: gitk:2642 msgid "Cherry-pick this commit" msgstr "Cueillir (cherry-pick) ce commit" -#: gitk:2624 +#: gitk:2643 msgid "Reset HEAD branch to here" msgstr "Réinitialiser la branche HEAD vers cet état" -#: gitk:2625 +#: gitk:2644 msgid "Mark this commit" msgstr "Marquer ce commit" -#: gitk:2626 +#: gitk:2645 msgid "Return to mark" msgstr "Retourner à la marque" -#: gitk:2627 +#: gitk:2646 msgid "Find descendant of this and mark" msgstr "Chercher le descendant de ceci et le marquer" -#: gitk:2628 +#: gitk:2647 msgid "Compare with marked commit" msgstr "Comparer avec le commit marqué" -#: gitk:2629 gitk:2640 -#, fuzzy +#: gitk:2648 gitk:2659 msgid "Diff this -> marked commit" -msgstr "Diff entre ceci et la sélection" +msgstr "Diff ceci -> sélection" -#: gitk:2630 gitk:2641 -#, fuzzy +#: gitk:2649 gitk:2660 msgid "Diff marked commit -> this" -msgstr "Diff entre sélection et ceci" +msgstr "Diff entre sélection -> ceci" -#: gitk:2631 -#, fuzzy +#: gitk:2650 msgid "Revert this commit" -msgstr "Marquer ce commit" +msgstr "Défaire ce commit" -#: gitk:2647 +#: gitk:2666 msgid "Check out this branch" msgstr "Récupérer cette branche" -#: gitk:2648 +#: gitk:2667 msgid "Remove this branch" msgstr "Supprimer cette branche" -#: gitk:2649 +#: gitk:2668 msgid "Copy branch name" -msgstr "" +msgstr "Copier la nom de la branche" -#: gitk:2656 +#: gitk:2675 msgid "Highlight this too" msgstr "Surligner également ceci" -#: gitk:2657 +#: gitk:2676 msgid "Highlight this only" msgstr "Surligner seulement ceci" -#: gitk:2658 +#: gitk:2677 msgid "External diff" msgstr "Diff externe" -#: gitk:2659 +#: gitk:2678 msgid "Blame parent commit" msgstr "Blâmer le commit parent" -#: gitk:2660 +#: gitk:2679 msgid "Copy path" -msgstr "" +msgstr "Copier le chemin" -#: gitk:2667 +#: gitk:2686 msgid "Show origin of this line" msgstr "Montrer l'origine de cette ligne" -#: gitk:2668 +#: gitk:2687 msgid "Run git gui blame on this line" msgstr "Exécuter git gui blame sur cette ligne" -#: gitk:3014 -#, fuzzy +#: gitk:3031 +msgid "About gitk" +msgstr "À propos de gitk" + +#: gitk:3033 msgid "" "\n" "Gitk - a commit viewer for git\n" @@ -378,327 +379,329 @@ msgstr "" "\n" "Gitk - visualisateur de commit pour git\n" "\n" -"Copyright \\u00a9 2005-2010 Paul Mackerras\n" +"Copyright \\u00a9 2005-2014 Paul Mackerras\n" "\n" -"Utilisation et redistribution soumises aux termes de la GNU General Public " -"License" +"Utilisation et redistribution soumises aux termes de la GNU General Public License" -#: gitk:3022 gitk:3089 gitk:9857 +#: gitk:3041 gitk:3108 gitk:9890 msgid "Close" msgstr "Fermer" -#: gitk:3043 +#: gitk:3062 msgid "Gitk key bindings" msgstr "Raccourcis clavier de Gitk" -#: gitk:3046 +#: gitk:3065 msgid "Gitk key bindings:" msgstr "Raccourcis clavier de Gitk :" -#: gitk:3048 +#: gitk:3067 #, tcl-format msgid "<%s-Q>\t\tQuit" msgstr "<%s-Q>\t\tQuitter" -#: gitk:3049 -#, fuzzy, tcl-format +#: gitk:3068 +#, tcl-format msgid "<%s-W>\t\tClose window" -msgstr "<%s-F>\t\tRechercher" +msgstr "<%s-W>\t\tFermer la fenêtre" -#: gitk:3050 +#: gitk:3069 msgid "\t\tMove to first commit" msgstr "\t\tAller au premier commit" -#: gitk:3051 +#: gitk:3070 msgid "\t\tMove to last commit" msgstr "\t\tAller au dernier commit" -#: gitk:3052 -#, fuzzy +#: gitk:3071 msgid ", p, k\tMove up one commit" -msgstr ", p, i\t Aller au commit suivant" +msgstr ", p, k\t Aller au commit précédent" -#: gitk:3053 -#, fuzzy +#: gitk:3072 msgid ", n, j\tMove down one commit" -msgstr ", n, k\t Aller au commit précédent" +msgstr ", n, j\t Aller au commit suivant" -#: gitk:3054 -#, fuzzy +#: gitk:3073 msgid ", z, h\tGo back in history list" -msgstr ", z, j\tReculer dans l'historique" +msgstr ", z, h\tReculer dans l'historique" -#: gitk:3055 +#: gitk:3074 msgid ", x, l\tGo forward in history list" msgstr ", x, l\tAvancer dans l'historique" -#: gitk:3056 +#: gitk:3075 #, tcl-format msgid "<%s-n>\tGo to n-th parent of current commit in history list" -msgstr "" +msgstr "<%s-n>\tAller sur le n-ième parent du commit dans l'historique" -#: gitk:3057 +#: gitk:3076 msgid "\tMove up one page in commit list" msgstr "\tMonter d'une page dans la liste des commits" -#: gitk:3058 +#: gitk:3077 msgid "\tMove down one page in commit list" msgstr "\tDescendre d'une page dans la liste des commits" -#: gitk:3059 +#: gitk:3078 #, tcl-format msgid "<%s-Home>\tScroll to top of commit list" msgstr "<%s-Début>\tAller en haut de la liste des commits" -#: gitk:3060 +#: gitk:3079 #, tcl-format msgid "<%s-End>\tScroll to bottom of commit list" msgstr "<%s-End>\tAller en bas de la liste des commits" -#: gitk:3061 +#: gitk:3080 #, tcl-format msgid "<%s-Up>\tScroll commit list up one line" msgstr "<%s-Up>\tMonter d'une ligne dans la liste des commits" -#: gitk:3062 +#: gitk:3081 #, tcl-format msgid "<%s-Down>\tScroll commit list down one line" msgstr "<%s-Down>\tDescendre d'une ligne dans la liste des commits" -#: gitk:3063 +#: gitk:3082 #, tcl-format msgid "<%s-PageUp>\tScroll commit list up one page" msgstr "<%s-PageUp>\tMonter d'une page dans la liste des commits" -#: gitk:3064 +#: gitk:3083 #, tcl-format msgid "<%s-PageDown>\tScroll commit list down one page" msgstr "<%s-PageDown>\tDescendre d'une page dans la liste des commits" -#: gitk:3065 +#: gitk:3084 msgid "\tFind backwards (upwards, later commits)" msgstr "" "\tRecherche en arrière (vers l'avant, commits les plus anciens)" -#: gitk:3066 +#: gitk:3085 msgid "\tFind forwards (downwards, earlier commits)" msgstr "" "\tRecherche en avant (vers l'arrière, commit les plus récents)" -#: gitk:3067 +#: gitk:3086 msgid ", b\tScroll diff view up one page" msgstr ", b\tMonter d'une page dans la vue des diff" -#: gitk:3068 +#: gitk:3087 msgid "\tScroll diff view up one page" msgstr "\tMonter d'une page dans la vue des diff" -#: gitk:3069 +#: gitk:3088 msgid "\t\tScroll diff view down one page" msgstr "\t\tDescendre d'une page dans la vue des diff" -#: gitk:3070 +#: gitk:3089 msgid "u\t\tScroll diff view up 18 lines" msgstr "u\t\tMonter de 18 lignes dans la vue des diff" -#: gitk:3071 +#: gitk:3090 msgid "d\t\tScroll diff view down 18 lines" msgstr "d\t\tDescendre de 18 lignes dans la vue des diff" -#: gitk:3072 +#: gitk:3091 #, tcl-format msgid "<%s-F>\t\tFind" msgstr "<%s-F>\t\tRechercher" -#: gitk:3073 +#: gitk:3092 #, tcl-format msgid "<%s-G>\t\tMove to next find hit" msgstr "<%s-G>\t\tAller au résultat de recherche suivant" -#: gitk:3074 +#: gitk:3093 msgid "\tMove to next find hit" msgstr "\t\tAller au résultat de recherche suivant" -#: gitk:3075 -#, fuzzy +#: gitk:3094 msgid "g\t\tGo to commit" -msgstr "\t\tAller au dernier commit" +msgstr "g\t\tAller au commit" -#: gitk:3076 +#: gitk:3095 msgid "/\t\tFocus the search box" msgstr "/\t\tFocus sur la zone de recherche" -#: gitk:3077 +#: gitk:3096 msgid "?\t\tMove to previous find hit" msgstr "?\t\tAller au résultat de recherche précédent" -#: gitk:3078 +#: gitk:3097 msgid "f\t\tScroll diff view to next file" msgstr "f\t\tAller au prochain fichier dans la vue des diff" -#: gitk:3079 +#: gitk:3098 #, tcl-format msgid "<%s-S>\t\tSearch for next hit in diff view" msgstr "<%s-S>\t\tAller au résultat suivant dans la vue des diff" -#: gitk:3080 +#: gitk:3099 #, tcl-format msgid "<%s-R>\t\tSearch for previous hit in diff view" msgstr "<%s-R>\t\tAller au résultat précédent dans la vue des diff" -#: gitk:3081 +#: gitk:3100 #, tcl-format msgid "<%s-KP+>\tIncrease font size" msgstr "<%s-KP+>\tAugmenter la taille de la police" -#: gitk:3082 +#: gitk:3101 #, tcl-format msgid "<%s-plus>\tIncrease font size" msgstr "<%s-plus>\tAugmenter la taille de la police" -#: gitk:3083 +#: gitk:3102 #, tcl-format msgid "<%s-KP->\tDecrease font size" msgstr "<%s-KP->\tDiminuer la taille de la police" -#: gitk:3084 +#: gitk:3103 #, tcl-format msgid "<%s-minus>\tDecrease font size" msgstr "<%s-minus>\tDiminuer la taille de la police" -#: gitk:3085 +#: gitk:3104 msgid "\t\tUpdate" msgstr "\t\tMise à jour" -#: gitk:3550 gitk:3559 +#: gitk:3569 gitk:3578 #, tcl-format msgid "Error creating temporary directory %s:" msgstr "Erreur lors de la création du répertoire temporaire %s :" -#: gitk:3572 +#: gitk:3591 #, tcl-format msgid "Error getting \"%s\" from %s:" msgstr "Erreur en obtenant \"%s\" de %s:" -#: gitk:3635 +#: gitk:3654 msgid "command failed:" msgstr "échec de la commande :" -#: gitk:3784 +#: gitk:3803 msgid "No such commit" msgstr "Commit inexistant" -#: gitk:3798 +#: gitk:3817 msgid "git gui blame: command failed:" msgstr "git gui blame : échec de la commande :" -#: gitk:3829 +#: gitk:3848 #, tcl-format msgid "Couldn't read merge head: %s" msgstr "Impossible de lire le head de la fusion : %s" -#: gitk:3837 +#: gitk:3856 #, tcl-format msgid "Error reading index: %s" msgstr "Erreur à la lecture de l'index : %s" -#: gitk:3862 +#: gitk:3881 #, tcl-format msgid "Couldn't start git blame: %s" msgstr "Impossible de démarrer git blame : %s" -#: gitk:3865 gitk:6754 +#: gitk:3884 gitk:6773 msgid "Searching" msgstr "Recherche en cours" -#: gitk:3897 +#: gitk:3916 #, tcl-format msgid "Error running git blame: %s" msgstr "Erreur à l'exécution de git blame : %s" -#: gitk:3925 +#: gitk:3944 #, tcl-format msgid "That line comes from commit %s, which is not in this view" msgstr "Cette ligne est issue du commit %s, qui n'est pas dans cette vue" -#: gitk:3939 +#: gitk:3958 msgid "External diff viewer failed:" -msgstr "Échec de l'outil externe de visualisation des diff" +msgstr "Échec de l'outil externe de visualisation des diff :" + +#: gitk:4062 +msgid "All files" +msgstr "Tous les fichiers" -#: gitk:4070 +#: gitk:4086 +msgid "View" +msgstr "Vue" + +#: gitk:4089 msgid "Gitk view definition" msgstr "Définition des vues de Gitk" -#: gitk:4074 +#: gitk:4093 msgid "Remember this view" msgstr "Se souvenir de cette vue" -#: gitk:4075 +#: gitk:4094 msgid "References (space separated list):" msgstr "Références (liste d'éléments séparés par des espaces) :" -#: gitk:4076 +#: gitk:4095 msgid "Branches & tags:" -msgstr "Branches & tags :" +msgstr "Branches & étiquettes :" -#: gitk:4077 +#: gitk:4096 msgid "All refs" msgstr "Toutes les références" -#: gitk:4078 +#: gitk:4097 msgid "All (local) branches" msgstr "Toutes les branches (locales)" -#: gitk:4079 +#: gitk:4098 msgid "All tags" -msgstr "Tous les tags" +msgstr "Toutes les étiquettes" -#: gitk:4080 +#: gitk:4099 msgid "All remote-tracking branches" msgstr "Toutes les branches de suivi à distance" -#: gitk:4081 +#: gitk:4100 msgid "Commit Info (regular expressions):" msgstr "Info sur les commits (expressions régulières) :" -#: gitk:4082 +#: gitk:4101 msgid "Author:" msgstr "Auteur :" -#: gitk:4083 +#: gitk:4102 msgid "Committer:" -msgstr "Commiteur :" +msgstr "Validateur :" -#: gitk:4084 +#: gitk:4103 msgid "Commit Message:" msgstr "Message de commit :" -#: gitk:4085 +#: gitk:4104 msgid "Matches all Commit Info criteria" msgstr "Correspond à tous les critères d'Info sur les commits" -#: gitk:4086 -#, fuzzy +#: gitk:4105 msgid "Matches no Commit Info criteria" -msgstr "Correspond à tous les critères d'Info sur les commits" +msgstr "Ne correspond à aucun des critères d'Info sur les commits" -#: gitk:4087 +#: gitk:4106 msgid "Changes to Files:" msgstr "Changements des fichiers :" -#: gitk:4088 +#: gitk:4107 msgid "Fixed String" msgstr "Chaîne Figée" -#: gitk:4089 +#: gitk:4108 msgid "Regular Expression" msgstr "Expression Régulière" -#: gitk:4090 +#: gitk:4109 msgid "Search string:" msgstr "Recherche de la chaîne :" -#: gitk:4091 +#: gitk:4110 msgid "" "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 " "15:27:38\"):" @@ -706,204 +709,201 @@ msgstr "" "Dates des commits (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, " "2009 15:27:38\") :" -#: gitk:4092 +#: gitk:4111 msgid "Since:" -msgstr "De :" +msgstr "Depuis :" -#: gitk:4093 +#: gitk:4112 msgid "Until:" msgstr "Jusqu'au :" -#: gitk:4094 +#: gitk:4113 msgid "Limit and/or skip a number of revisions (positive integer):" msgstr "Limiter et/ou sauter un certain nombre (entier positif) de révisions :" -#: gitk:4095 +#: gitk:4114 msgid "Number to show:" msgstr "Nombre à afficher :" -#: gitk:4096 +#: gitk:4115 msgid "Number to skip:" msgstr "Nombre à sauter :" -#: gitk:4097 +#: gitk:4116 msgid "Miscellaneous options:" msgstr "Options diverses :" -#: gitk:4098 +#: gitk:4117 msgid "Strictly sort by date" msgstr "Trier par date" -# FIXME : traduction de "branch sides" -#: gitk:4099 -#, fuzzy +#: gitk:4118 msgid "Mark branch sides" -msgstr "Marquer les extrémités des branches" +msgstr "Indiquer les côtés des branches" -#: gitk:4100 +#: gitk:4119 msgid "Limit to first parent" msgstr "Limiter au premier ancêtre" -#: gitk:4101 +#: gitk:4120 msgid "Simple history" msgstr "Historique simple" -#: gitk:4102 +#: gitk:4121 msgid "Additional arguments to git log:" msgstr "Arguments supplémentaires de git log :" -#: gitk:4103 +#: gitk:4122 msgid "Enter files and directories to include, one per line:" msgstr "Saisir les fichiers et répertoires à inclure, un par ligne :" -#: gitk:4104 +#: gitk:4123 msgid "Command to generate more commits to include:" msgstr "Commande pour générer plus de commits à inclure :" -#: gitk:4228 +#: gitk:4247 msgid "Gitk: edit view" msgstr "Gitk : éditer la vue" -#: gitk:4236 +#: gitk:4255 msgid "-- criteria for selecting revisions" msgstr "-- critère pour la sélection des révisions" -#: gitk:4241 -#, fuzzy +#: gitk:4260 msgid "View Name" -msgstr "Nom de la vue :" +msgstr "Nom de la vue" -#: gitk:4316 +#: gitk:4335 msgid "Apply (F5)" msgstr "Appliquer (F5)" -#: gitk:4354 +#: gitk:4373 msgid "Error in commit selection arguments:" msgstr "Erreur dans les arguments de sélection des commits :" -#: gitk:4409 gitk:4462 gitk:4924 gitk:4938 gitk:6208 gitk:12373 gitk:12374 +#: gitk:4428 gitk:4481 gitk:4943 gitk:4957 gitk:6227 gitk:12410 gitk:12411 msgid "None" msgstr "Aucun" -#: gitk:5021 gitk:5026 +#: gitk:5040 gitk:5045 msgid "Descendant" msgstr "Descendant" -#: gitk:5022 +#: gitk:5041 msgid "Not descendant" msgstr "Pas un descendant" -#: gitk:5029 gitk:5034 +#: gitk:5048 gitk:5053 msgid "Ancestor" msgstr "Ancêtre" -#: gitk:5030 +#: gitk:5049 msgid "Not ancestor" msgstr "Pas un ancêtre" -#: gitk:5324 +#: gitk:5343 msgid "Local changes checked in to index but not committed" -msgstr "Modifications locales enregistrées dans l'index mais non commitées" +msgstr "Modifications locales enregistrées dans l'index mais non validées" -#: gitk:5360 +#: gitk:5379 msgid "Local uncommitted changes, not checked in to index" -msgstr "Modifications locales non enregistrées dans l'index et non commitées" +msgstr "Modifications locales non enregistrées dans l'index et non validées" -#: gitk:7134 +#: gitk:7153 msgid "and many more" -msgstr "" +msgstr "et beaucoup plus" -#: gitk:7137 +#: gitk:7156 msgid "many" msgstr "nombreux" -#: gitk:7328 +#: gitk:7347 msgid "Tags:" -msgstr "Tags :" +msgstr "Étiquettes :" -#: gitk:7345 gitk:7351 gitk:8825 +#: gitk:7364 gitk:7370 gitk:8844 msgid "Parent" msgstr "Parent" -#: gitk:7356 +#: gitk:7375 msgid "Child" msgstr "Enfant" -#: gitk:7365 +#: gitk:7384 msgid "Branch" msgstr "Branche" -#: gitk:7368 +#: gitk:7387 msgid "Follows" msgstr "Suit" -#: gitk:7371 +#: gitk:7390 msgid "Precedes" msgstr "Précède" -#: gitk:7966 +#: gitk:7985 #, tcl-format msgid "Error getting diffs: %s" msgstr "Erreur lors de la récupération des diff : %s" -#: gitk:8650 +#: gitk:8669 msgid "Goto:" msgstr "Aller à :" -#: gitk:8671 +#: gitk:8690 #, tcl-format msgid "Short SHA1 id %s is ambiguous" -msgstr "Id SHA1 court %s est ambigu" +msgstr "L'id SHA1 court %s est ambigu" -#: gitk:8678 +#: gitk:8697 #, tcl-format msgid "Revision %s is not known" -msgstr "Id SHA1 %s est inconnu" +msgstr "La révision %s est inconnu" -#: gitk:8688 +#: gitk:8707 #, tcl-format msgid "SHA1 id %s is not known" -msgstr "Id SHA1 %s est inconnu" +msgstr "L'id SHA1 %s est inconnu" -#: gitk:8690 +#: gitk:8709 #, tcl-format msgid "Revision %s is not in the current view" msgstr "La révision %s n'est pas dans la vue courante" -#: gitk:8832 gitk:8847 +#: gitk:8851 gitk:8866 msgid "Date" msgstr "Date" -#: gitk:8835 +#: gitk:8854 msgid "Children" msgstr "Enfants" -#: gitk:8898 +#: gitk:8917 #, tcl-format msgid "Reset %s branch to here" msgstr "Réinitialiser la branche %s vers cet état" -#: gitk:8900 +#: gitk:8919 msgid "Detached head: can't reset" msgstr "Head détaché : impossible de réinitialiser" -#: gitk:9005 gitk:9011 +#: gitk:9024 gitk:9030 msgid "Skipping merge commit " msgstr "Éviter le commit de la fusion " -#: gitk:9020 gitk:9025 +#: gitk:9039 gitk:9044 msgid "Error getting patch ID for " msgstr "Erreur à l'obtention de l'ID du patch pour " -#: gitk:9021 gitk:9026 +#: gitk:9040 gitk:9045 msgid " - stopping\n" msgstr " - arrêt en cours\n" -#: gitk:9031 gitk:9034 gitk:9042 gitk:9056 gitk:9065 +#: gitk:9050 gitk:9053 gitk:9061 gitk:9075 gitk:9084 msgid "Commit " msgstr "Commit " -#: gitk:9035 +#: gitk:9054 msgid "" " is the same patch as\n" " " @@ -911,7 +911,7 @@ msgstr "" "est le même patch que \n" " " -#: gitk:9043 +#: gitk:9062 msgid "" " differs from\n" " " @@ -919,240 +919,226 @@ msgstr "" " diffère de\n" " " -#: gitk:9045 +#: gitk:9064 msgid "" "Diff of commits:\n" "\n" -msgstr "" +msgstr "Diff des commits :\n\n" -#: gitk:9057 gitk:9066 +#: gitk:9076 gitk:9085 #, tcl-format msgid " has %s children - stopping\n" -msgstr "a %s enfants - arrêt en cours\n" +msgstr " a %s enfants - arrêt en cours\n" -#: gitk:9085 -#, fuzzy, tcl-format +#: gitk:9104 +#, tcl-format msgid "Error writing commit to file: %s" -msgstr "Erreur à l'ecriture du commit :" +msgstr "Erreur à l'écriture du commit dans le fichier : %s" -#: gitk:9091 -#, fuzzy, tcl-format +#: gitk:9110 +#, tcl-format msgid "Error diffing commits: %s" -msgstr "Erreur à l'ecriture du commit :" +msgstr "Erreur à la différence des commits : %s" -#: gitk:9137 +#: gitk:9156 msgid "Top" msgstr "Haut" -#: gitk:9138 +#: gitk:9157 msgid "From" msgstr "De" -#: gitk:9143 +#: gitk:9162 msgid "To" msgstr "À" -#: gitk:9167 +#: gitk:9186 msgid "Generate patch" msgstr "Générer le patch" -#: gitk:9169 +#: gitk:9188 msgid "From:" msgstr "De :" -#: gitk:9178 +#: gitk:9197 msgid "To:" msgstr "À :" -#: gitk:9187 +#: gitk:9206 msgid "Reverse" msgstr "Inverser" -#: gitk:9189 gitk:9385 +#: gitk:9208 gitk:9418 msgid "Output file:" msgstr "Fichier de sortie :" -#: gitk:9195 +#: gitk:9214 msgid "Generate" msgstr "Générer" -#: gitk:9233 +#: gitk:9252 msgid "Error creating patch:" msgstr "Erreur à la création du patch :" -#: gitk:9256 gitk:9373 gitk:9430 +#: gitk:9275 gitk:9406 gitk:9463 msgid "ID:" msgstr "ID :" -#: gitk:9265 +#: gitk:9284 msgid "Tag name:" -msgstr "Nom du Tag :" +msgstr "Nom de l'étiquette :" -#: gitk:9268 +#: gitk:9287 msgid "Tag message is optional" -msgstr "" +msgstr "Le message d'étiquette est optionnel" -#: gitk:9270 -#, fuzzy +#: gitk:9289 msgid "Tag message:" -msgstr "Nom du Tag :" +msgstr "Message d'étiquette :" -#: gitk:9274 gitk:9439 +#: gitk:9293 gitk:9472 msgid "Create" msgstr "Créer" -#: gitk:9292 +#: gitk:9311 msgid "No tag name specified" -msgstr "Aucun nom de tag spécifié" +msgstr "Aucun nom d'étiquette spécifié" -#: gitk:9296 +#: gitk:9315 #, tcl-format msgid "Tag \"%s\" already exists" -msgstr "Le tag \"%s\" existe déjà" +msgstr "L'étiquette \"%s\" existe déjà" -#: gitk:9306 +#: gitk:9325 msgid "Error creating tag:" -msgstr "Erreur à la création du tag :" +msgstr "Erreur à la création de l'étiquette :" -#: gitk:9382 +#: gitk:9415 msgid "Command:" msgstr "Commande :" -#: gitk:9390 +#: gitk:9423 msgid "Write" msgstr "Écrire" -#: gitk:9408 +#: gitk:9441 msgid "Error writing commit:" msgstr "Erreur à l'ecriture du commit :" -#: gitk:9435 +#: gitk:9468 msgid "Name:" msgstr "Nom :" -#: gitk:9458 +#: gitk:9491 msgid "Please specify a name for the new branch" msgstr "Veuillez spécifier un nom pour la nouvelle branche" -#: gitk:9463 +#: gitk:9496 #, tcl-format msgid "Branch '%s' already exists. Overwrite?" msgstr "La branche '%s' existe déjà. Écraser?" -#: gitk:9530 +#: gitk:9563 #, tcl-format msgid "Commit %s is already included in branch %s -- really re-apply it?" msgstr "" "Le Commit %s est déjà inclus dans la branche %s -- le ré-appliquer malgré " "tout?" -#: gitk:9535 +#: gitk:9568 msgid "Cherry-picking" -msgstr "Cueillir (Cherry-picking)" +msgstr "Picorer (Cherry-picking)" -#: gitk:9544 +#: gitk:9577 #, tcl-format msgid "" "Cherry-pick failed because of local changes to file '%s'.\n" "Please commit, reset or stash your changes and try again." msgstr "" -"La cueillette (cherry-pick) a échouée à cause de modifications locales du " -"fichier '%s'.\n" -"Veuillez commiter, réinitialiser ou stasher vos changements et essayer de " -"nouveau." +"Le picorage (cherry-pick) a échouée à cause de modifications locales du fichier '%s'.\n" +"Veuillez commiter, réinitialiser ou stasher vos changements et essayer de nouveau." -#: gitk:9550 +#: gitk:9583 msgid "" "Cherry-pick failed because of merge conflict.\n" "Do you wish to run git citool to resolve it?" msgstr "" -"La cueillette (cherry-pick) a échouée à cause d'un conflit lors d'une " -"fusion.\n" +"Le picorage (cherry-pick) a échouée à cause d'un conflit lors d'une fusion.\n" "Souhaitez-vous exécuter git citool pour le résoudre ?" -#: gitk:9566 gitk:9624 +#: gitk:9599 gitk:9657 msgid "No changes committed" -msgstr "Aucun changement commité" +msgstr "Aucune modification validée" -#: gitk:9593 -#, fuzzy, tcl-format +#: gitk:9626 +#, tcl-format msgid "Commit %s is not included in branch %s -- really revert it?" -msgstr "" -"Le Commit %s est déjà inclus dans la branche %s -- le ré-appliquer malgré " -"tout?" +msgstr "Le Commit %s n'est pas inclus dans la branche %s -- le défaire malgré tout?" -#: gitk:9598 -#, fuzzy +#: gitk:9631 msgid "Reverting" -msgstr "Réinitialisation" +msgstr "Commit défait" -#: gitk:9606 -#, fuzzy, tcl-format +#: gitk:9639 +#, tcl-format msgid "" "Revert failed because of local changes to the following files:%s Please " "commit, reset or stash your changes and try again." -msgstr "" -"La cueillette (cherry-pick) a échouée à cause de modifications locales du " -"fichier '%s'.\n" -"Veuillez commiter, réinitialiser ou stasher vos changements et essayer de " -"nouveau." +msgstr "Échec en tentant de défaire le commit à cause de modifications locales des fichiers : %s. Veuillez valider, réinitialiser ou remiser vos modifications et essayer de nouveau." -#: gitk:9610 -#, fuzzy +#: gitk:9643 msgid "" "Revert failed because of merge conflict.\n" " Do you wish to run git citool to resolve it?" msgstr "" -"La cueillette (cherry-pick) a échouée à cause d'un conflit lors d'une " -"fusion.\n" +"Échec en tentant de défaire à cause d'un conflit de fusion.\n" "Souhaitez-vous exécuter git citool pour le résoudre ?" -#: gitk:9653 +#: gitk:9686 msgid "Confirm reset" msgstr "Confirmer la réinitialisation" -#: gitk:9655 +#: gitk:9688 #, tcl-format msgid "Reset branch %s to %s?" msgstr "Réinitialiser la branche %s à %s?" -#: gitk:9657 +#: gitk:9690 msgid "Reset type:" msgstr "Type de réinitialisation :" -#: gitk:9660 +#: gitk:9693 msgid "Soft: Leave working tree and index untouched" msgstr "Douce : Laisse le répertoire de travail et l'index intacts" -#: gitk:9663 +#: gitk:9696 msgid "Mixed: Leave working tree untouched, reset index" msgstr "" "Hybride : Laisse le répertoire de travail dans son état courant, " "réinitialise l'index" -#: gitk:9666 +#: gitk:9699 msgid "" "Hard: Reset working tree and index\n" "(discard ALL local changes)" msgstr "" "Dure : Réinitialise le répertoire de travail et l'index\n" -"(abandonne TOUS les changements locaux)" +"(abandonne TOUTES les modifications locale)" -#: gitk:9683 +#: gitk:9716 msgid "Resetting" msgstr "Réinitialisation" # Fixme: Récupération est-il vraiment une mauvaise traduction? -#: gitk:9743 -#, fuzzy +#: gitk:9776 msgid "Checking out" -msgstr "Récupération" +msgstr "Extraction" -#: gitk:9796 +#: gitk:9829 msgid "Cannot delete the currently checked-out branch" -msgstr "Impossible de supprimer la branche en cours" +msgstr "Impossible de supprimer la branche extraite" -#: gitk:9802 +#: gitk:9835 #, tcl-format msgid "" "The commits on branch %s aren't on any other branch.\n" @@ -1161,16 +1147,16 @@ msgstr "" "Les commits de la branche %s ne sont dans aucune autre branche.\n" "Voulez-vous vraiment supprimer cette branche %s ?" -#: gitk:9833 +#: gitk:9866 #, tcl-format msgid "Tags and heads: %s" -msgstr "Tags et heads : %s" +msgstr "Étiquettes et heads : %s" -#: gitk:9850 +#: gitk:9883 msgid "Filter" msgstr "Filtrer" -#: gitk:10146 +#: gitk:10179 msgid "" "Error reading commit topology information; branch and preceding/following " "tag information will be incomplete." @@ -1179,207 +1165,202 @@ msgstr "" "informations sur les branches et les tags précédents/suivants seront " "incomplètes." -#: gitk:11123 +#: gitk:11156 msgid "Tag" -msgstr "Tag" +msgstr "Étiquette" -#: gitk:11127 +#: gitk:11160 msgid "Id" msgstr "Id" -#: gitk:11210 +#: gitk:11243 msgid "Gitk font chooser" msgstr "Sélecteur de police de Gitk" -#: gitk:11227 +#: gitk:11260 msgid "B" msgstr "B" -#: gitk:11230 +#: gitk:11263 msgid "I" msgstr "I" -#: gitk:11348 +#: gitk:11381 msgid "Commit list display options" msgstr "Options d'affichage de la liste des commits" -#: gitk:11351 +#: gitk:11384 msgid "Maximum graph width (lines)" msgstr "Longueur maximum du graphe (lignes)" # FIXME : Traduction standard de "pane"? -#: gitk:11355 -#, fuzzy, no-tcl-format +#: gitk:11388 +#, no-tcl-format msgid "Maximum graph width (% of pane)" -msgstr "Longueur maximum du graphe (% du panneau)" +msgstr "Largeur maximum du graphe (% du panneau)" -#: gitk:11358 +#: gitk:11391 msgid "Show local changes" -msgstr "Montrer les changements locaux" +msgstr "Montrer les modifications locales" -#: gitk:11361 -#, fuzzy +#: gitk:11394 msgid "Auto-select SHA1 (length)" -msgstr "Sélection auto. du SHA1" +msgstr "Sélection auto. du SHA1 (longueur)" -#: gitk:11365 +#: gitk:11398 msgid "Hide remote refs" msgstr "Cacher les refs distantes" -#: gitk:11369 +#: gitk:11402 msgid "Diff display options" msgstr "Options d'affichage des diff" -#: gitk:11371 +#: gitk:11404 msgid "Tab spacing" msgstr "Taille des tabulations" -#: gitk:11374 -#, fuzzy +#: gitk:11407 msgid "Display nearby tags/heads" msgstr "Afficher les tags les plus proches" -#: gitk:11377 +#: gitk:11410 msgid "Maximum # tags/heads to show" -msgstr "" +msgstr "Nombre maximum d'étiquettes/heads à afficher" -#: gitk:11380 +#: gitk:11413 msgid "Limit diffs to listed paths" msgstr "Limiter les différences aux chemins listés" -#: gitk:11383 +#: gitk:11416 msgid "Support per-file encodings" msgstr "Support pour un encodage des caractères par fichier" -#: gitk:11389 gitk:11536 +#: gitk:11422 gitk:11569 msgid "External diff tool" msgstr "Outil diff externe" -#: gitk:11390 +#: gitk:11423 msgid "Choose..." msgstr "Choisir..." -#: gitk:11395 -#, fuzzy +#: gitk:11428 msgid "General options" -msgstr "Générer le patch" +msgstr "Options générales" -#: gitk:11398 +#: gitk:11431 msgid "Use themed widgets" -msgstr "" +msgstr "Utiliser des widgets en thème" -#: gitk:11400 +#: gitk:11433 msgid "(change requires restart)" -msgstr "" +msgstr "(la modification nécessite un redémarrage)" -#: gitk:11402 +#: gitk:11435 msgid "(currently unavailable)" -msgstr "" +msgstr "(non disponible actuellement)" -#: gitk:11413 +#: gitk:11446 msgid "Colors: press to choose" msgstr "Couleurs : cliquer pour choisir" -#: gitk:11416 +#: gitk:11449 msgid "Interface" -msgstr "" +msgstr "Interface" -#: gitk:11417 -#, fuzzy +#: gitk:11450 msgid "interface" -msgstr "Police de l'interface utilisateur" +msgstr "interface" -#: gitk:11420 +#: gitk:11453 msgid "Background" msgstr "Arrière-plan" -#: gitk:11421 gitk:11451 +#: gitk:11454 gitk:11484 msgid "background" msgstr "arrière-plan" -#: gitk:11424 +#: gitk:11457 msgid "Foreground" msgstr "Premier plan" -#: gitk:11425 +#: gitk:11458 msgid "foreground" msgstr "premier plan" -#: gitk:11428 +#: gitk:11461 msgid "Diff: old lines" msgstr "Diff : anciennes lignes" -#: gitk:11429 +#: gitk:11462 msgid "diff old lines" msgstr "diff anciennes lignes" -#: gitk:11433 +#: gitk:11466 msgid "Diff: new lines" msgstr "Diff : nouvelles lignes" -#: gitk:11434 +#: gitk:11467 msgid "diff new lines" msgstr "diff nouvelles lignes" -#: gitk:11438 +#: gitk:11471 msgid "Diff: hunk header" msgstr "Diff : entête du hunk" -#: gitk:11440 +#: gitk:11473 msgid "diff hunk header" msgstr "diff : entête du hunk" -#: gitk:11444 +#: gitk:11477 msgid "Marked line bg" -msgstr "Arrière-plan de la ligne marquée" +msgstr "Fond de la ligne marquée" -#: gitk:11446 +#: gitk:11479 msgid "marked line background" -msgstr "Arrière-plan de la ligne marquée" +msgstr "Fond de la ligne marquée" -#: gitk:11450 +#: gitk:11483 msgid "Select bg" -msgstr "Sélectionner l'arrière-plan" +msgstr "Sélectionner le fond" -#: gitk:11459 +#: gitk:11492 msgid "Fonts: press to choose" msgstr "Polices : cliquer pour choisir" -#: gitk:11461 +#: gitk:11494 msgid "Main font" msgstr "Police principale" -#: gitk:11462 +#: gitk:11495 msgid "Diff display font" msgstr "Police d'affichage des diff" -#: gitk:11463 +#: gitk:11496 msgid "User interface font" msgstr "Police de l'interface utilisateur" -#: gitk:11485 +#: gitk:11518 msgid "Gitk preferences" msgstr "Préférences de Gitk" -#: gitk:11494 -#, fuzzy +#: gitk:11527 msgid "General" -msgstr "Générer" +msgstr "Général" -#: gitk:11495 +#: gitk:11528 msgid "Colors" -msgstr "" +msgstr "Couleurs" -#: gitk:11496 +#: gitk:11529 msgid "Fonts" -msgstr "" +msgstr "Polices" -#: gitk:11546 +#: gitk:11579 #, tcl-format msgid "Gitk: choose color for %s" msgstr "Gitk : choisir la couleur de %s" -#: gitk:12059 +#: gitk:12092 msgid "" "Sorry, gitk cannot run with this version of Tcl/Tk.\n" " Gitk requires at least Tcl/Tk 8.4." @@ -1387,16 +1368,16 @@ msgstr "" "Désolé, gitk ne peut être exécuté avec cette version de Tcl/Tk.\n" " Gitk requiert Tcl/Tk version 8.4 ou supérieur." -#: gitk:12269 +#: gitk:12302 msgid "Cannot find a git repository here." msgstr "Impossible de trouver un dépôt git ici." -#: gitk:12316 +#: gitk:12349 #, tcl-format msgid "Ambiguous argument '%s': both revision and filename" msgstr "Argument '%s' ambigu : à la fois une révision et un nom de fichier" -#: gitk:12328 +#: gitk:12361 msgid "Bad arguments to gitk:" msgstr "Arguments invalides pour gitk :" diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 05d7910b7c..2fddf750fa 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -3935,6 +3935,9 @@ sub run_highlighter { close $fd; open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ". + quote_command($^X, '-CO', '-MEncode=decode,FB_DEFAULT', '-pse', + '$_ = decode($fe, $_, FB_DEFAULT) if !utf8::decode($_);', + '--', "-fe=$fallback_encoding")." | ". quote_command($highlight_bin). " --replace-tabs=8 --fragment --syntax $syntax |" or die_error(500, "Couldn't open file or run syntax highlighter"); diff --git a/http.c b/http.c index 0da9e66398..1044f9ba0e 100644 --- a/http.c +++ b/http.c @@ -11,6 +11,11 @@ #include "gettext.h" #include "transport.h" +#if LIBCURL_VERSION_NUM >= 0x070a08 +long int git_curl_ipresolve = CURL_IPRESOLVE_WHATEVER; +#else +long int git_curl_ipresolve; +#endif int active_requests; int http_is_verbose; size_t http_post_buffer = 16 * LARGE_PACKET_MAX; @@ -57,16 +62,41 @@ static const char *ssl_key; #if LIBCURL_VERSION_NUM >= 0x070908 static const char *ssl_capath; #endif +#if LIBCURL_VERSION_NUM >= 0x072c00 +static const char *ssl_pinnedkey; +#endif static const char *ssl_cainfo; static long curl_low_speed_limit = -1; static long curl_low_speed_time = -1; static int curl_ftp_no_epsv; static const char *curl_http_proxy; +static const char *curl_no_proxy; +static const char *http_proxy_authmethod; +static struct { + const char *name; + long curlauth_param; +} proxy_authmethods[] = { + { "basic", CURLAUTH_BASIC }, + { "digest", CURLAUTH_DIGEST }, + { "negotiate", CURLAUTH_GSSNEGOTIATE }, + { "ntlm", CURLAUTH_NTLM }, +#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY + { "anyauth", CURLAUTH_ANY }, +#endif + /* + * CURLAUTH_DIGEST_IE has no corresponding command-line option in + * curl(1) and is not included in CURLAUTH_ANY, so we leave it out + * here, too + */ +}; +static struct credential proxy_auth = CREDENTIAL_INIT; +static const char *curl_proxyuserpwd; static const char *curl_cookie_file; static int curl_save_cookies; struct credential http_auth = CREDENTIAL_INIT; static int http_proactive_auth; static const char *user_agent; +static int curl_empty_auth; #if LIBCURL_VERSION_NUM >= 0x071700 /* Use CURLOPT_KEYPASSWD as is */ @@ -159,6 +189,9 @@ static void finish_active_slot(struct active_request_slot *slot) #else slot->results->auth_avail = 0; #endif + + curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CONNECTCODE, + &slot->results->http_connectcode); } /* Run callback if appropriate */ @@ -256,8 +289,11 @@ static int http_options(const char *var, const char *value, void *cb) if (!strcmp("http.proxy", var)) return git_config_string(&curl_http_proxy, var, value); + if (!strcmp("http.proxyauthmethod", var)) + return git_config_string(&http_proxy_authmethod, var, value); + if (!strcmp("http.cookiefile", var)) - return git_config_string(&curl_cookie_file, var, value); + return git_config_pathname(&curl_cookie_file, var, value); if (!strcmp("http.savecookies", var)) { curl_save_cookies = git_config_bool(var, value); return 0; @@ -273,14 +309,31 @@ static int http_options(const char *var, const char *value, void *cb) if (!strcmp("http.useragent", var)) return git_config_string(&user_agent, var, value); + if (!strcmp("http.emptyauth", var)) { + curl_empty_auth = git_config_bool(var, value); + return 0; + } + + if (!strcmp("http.pinnedpubkey", var)) { +#if LIBCURL_VERSION_NUM >= 0x072c00 + return git_config_pathname(&ssl_pinnedkey, var, value); +#else + warning(_("Public key pinning not supported with cURL < 7.44.0")); + return 0; +#endif + } + /* Fall back on the default ones */ return git_default_config(var, value, cb); } static void init_curl_http_auth(CURL *result) { - if (!http_auth.username) + if (!http_auth.username) { + if (curl_empty_auth) + curl_easy_setopt(result, CURLOPT_USERPWD, ":"); return; + } credential_fill(&http_auth); @@ -304,6 +357,64 @@ static void init_curl_http_auth(CURL *result) #endif } +/* *var must be free-able */ +static void var_override(const char **var, char *value) +{ + if (value) { + free((void *)*var); + *var = xstrdup(value); + } +} + +static void set_proxyauth_name_password(CURL *result) +{ +#if LIBCURL_VERSION_NUM >= 0x071301 + curl_easy_setopt(result, CURLOPT_PROXYUSERNAME, + proxy_auth.username); + curl_easy_setopt(result, CURLOPT_PROXYPASSWORD, + proxy_auth.password); +#else + struct strbuf s = STRBUF_INIT; + + strbuf_addstr_urlencode(&s, proxy_auth.username, 1); + strbuf_addch(&s, ':'); + strbuf_addstr_urlencode(&s, proxy_auth.password, 1); + curl_proxyuserpwd = strbuf_detach(&s, NULL); + curl_easy_setopt(result, CURLOPT_PROXYUSERPWD, curl_proxyuserpwd); +#endif +} + +static void init_curl_proxy_auth(CURL *result) +{ + if (proxy_auth.username) { + if (!proxy_auth.password) + credential_fill(&proxy_auth); + set_proxyauth_name_password(result); + } + + var_override(&http_proxy_authmethod, getenv("GIT_HTTP_PROXY_AUTHMETHOD")); + +#if LIBCURL_VERSION_NUM >= 0x070a07 /* CURLOPT_PROXYAUTH and CURLAUTH_ANY */ + if (http_proxy_authmethod) { + int i; + for (i = 0; i < ARRAY_SIZE(proxy_authmethods); i++) { + if (!strcmp(http_proxy_authmethod, proxy_authmethods[i].name)) { + curl_easy_setopt(result, CURLOPT_PROXYAUTH, + proxy_authmethods[i].curlauth_param); + break; + } + } + if (i == ARRAY_SIZE(proxy_authmethods)) { + warning("unsupported proxy authentication method %s: using anyauth", + http_proxy_authmethod); + curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY); + } + } + else + curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY); +#endif +} + static int has_cert_password(void) { if (ssl_cert == NULL || ssl_cert_password_required != 1) @@ -414,6 +525,10 @@ static CURL *get_curl_handle(void) #if LIBCURL_VERSION_NUM >= 0x070908 if (ssl_capath != NULL) curl_easy_setopt(result, CURLOPT_CAPATH, ssl_capath); +#endif +#if LIBCURL_VERSION_NUM >= 0x072c00 + if (ssl_pinnedkey != NULL) + curl_easy_setopt(result, CURLOPT_PINNEDPUBLICKEY, ssl_pinnedkey); #endif if (ssl_cainfo != NULL) curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo); @@ -462,10 +577,38 @@ static CURL *get_curl_handle(void) curl_easy_setopt(result, CURLOPT_USE_SSL, CURLUSESSL_TRY); #endif + /* + * CURL also examines these variables as a fallback; but we need to query + * them here in order to decide whether to prompt for missing password (cf. + * init_curl_proxy_auth()). + * + * Unlike many other common environment variables, these are historically + * lowercase only. It appears that CURL did not know this and implemented + * only uppercase variants, which was later corrected to take both - with + * the exception of http_proxy, which is lowercase only also in CURL. As + * the lowercase versions are the historical quasi-standard, they take + * precedence here, as in CURL. + */ + if (!curl_http_proxy) { + if (!strcmp(http_auth.protocol, "https")) { + var_override(&curl_http_proxy, getenv("HTTPS_PROXY")); + var_override(&curl_http_proxy, getenv("https_proxy")); + } else { + var_override(&curl_http_proxy, getenv("http_proxy")); + } + if (!curl_http_proxy) { + var_override(&curl_http_proxy, getenv("ALL_PROXY")); + var_override(&curl_http_proxy, getenv("all_proxy")); + } + } + if (curl_http_proxy) { curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy); #if LIBCURL_VERSION_NUM >= 0x071800 - if (starts_with(curl_http_proxy, "socks5")) + if (starts_with(curl_http_proxy, "socks5h")) + curl_easy_setopt(result, + CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME); + else if (starts_with(curl_http_proxy, "socks5")) curl_easy_setopt(result, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); else if (starts_with(curl_http_proxy, "socks4a")) @@ -475,10 +618,23 @@ static CURL *get_curl_handle(void) curl_easy_setopt(result, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); #endif - } -#if LIBCURL_VERSION_NUM >= 0x070a07 - curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY); + if (strstr(curl_http_proxy, "://")) + credential_from_url(&proxy_auth, curl_http_proxy); + else { + struct strbuf url = STRBUF_INIT; + strbuf_addf(&url, "http://%s", curl_http_proxy); + credential_from_url(&proxy_auth, url.buf); + strbuf_release(&url); + } + + curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host); +#if LIBCURL_VERSION_NUM >= 0x071304 + var_override(&curl_no_proxy, getenv("NO_PROXY")); + var_override(&curl_no_proxy, getenv("no_proxy")); + curl_easy_setopt(result, CURLOPT_NOPROXY, curl_no_proxy); #endif + } + init_curl_proxy_auth(result); set_curl_keepalive(result); @@ -519,6 +675,9 @@ void http_init(struct remote *remote, const char *url, int proactive_auth) if (remote && remote->http_proxy) curl_http_proxy = xstrdup(remote->http_proxy); + if (remote) + var_override(&http_proxy_authmethod, remote->http_proxy_authmethod); + pragma_header = curl_slist_append(pragma_header, "Pragma: no-cache"); no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:"); @@ -617,6 +776,18 @@ void http_cleanup(void) curl_http_proxy = NULL; } + if (proxy_auth.password) { + memset(proxy_auth.password, 0, strlen(proxy_auth.password)); + free(proxy_auth.password); + proxy_auth.password = NULL; + } + + free((void *)curl_proxyuserpwd); + curl_proxyuserpwd = NULL; + + free((void *)http_proxy_authmethod); + http_proxy_authmethod = NULL; + if (cert_auth.password != NULL) { memset(cert_auth.password, 0, strlen(cert_auth.password)); free(cert_auth.password); @@ -692,10 +863,14 @@ struct active_request_slot *get_active_slot(void) curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1); curl_easy_setopt(slot->curl, CURLOPT_RANGE, NULL); + +#if LIBCURL_VERSION_NUM >= 0x070a08 + curl_easy_setopt(slot->curl, CURLOPT_IPRESOLVE, git_curl_ipresolve); +#endif #ifdef LIBCURL_CAN_HANDLE_AUTH_ANY curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods); #endif - if (http_auth.password) + if (http_auth.password || curl_empty_auth) init_curl_http_auth(slot->curl); return slot; @@ -946,6 +1121,8 @@ static int handle_curl_result(struct slot_results *results) if (results->curl_result == CURLE_OK) { credential_approve(&http_auth); + if (proxy_auth.password) + credential_approve(&proxy_auth); return HTTP_OK; } else if (missing_target(results)) return HTTP_MISSING_TARGET; @@ -960,6 +1137,8 @@ static int handle_curl_result(struct slot_results *results) return HTTP_REAUTH; } } else { + if (results->http_connectcode == 407) + credential_reject(&proxy_auth); #if LIBCURL_VERSION_NUM >= 0x070c00 if (!curl_errorstr[0]) strlcpy(curl_errorstr, diff --git a/http.h b/http.h index 4f97b60b5c..4ef4bbda7d 100644 --- a/http.h +++ b/http.h @@ -54,6 +54,7 @@ struct slot_results { CURLcode curl_result; long http_code; long auth_avail; + long http_connectcode; }; struct active_request_slot { @@ -106,6 +107,7 @@ extern void http_init(struct remote *remote, const char *url, int proactive_auth); extern void http_cleanup(void); +extern long int git_curl_ipresolve; extern int active_requests; extern int http_is_verbose; extern size_t http_post_buffer; diff --git a/ident.c b/ident.c index daf7e1ea83..4fd82d1043 100644 --- a/ident.c +++ b/ident.c @@ -13,11 +13,14 @@ static struct strbuf git_default_date = STRBUF_INIT; static int default_email_is_bogus; static int default_name_is_bogus; +static int ident_use_config_only; + #define IDENT_NAME_GIVEN 01 #define IDENT_MAIL_GIVEN 02 #define IDENT_ALL_GIVEN (IDENT_NAME_GIVEN|IDENT_MAIL_GIVEN) static int committer_ident_explicitly_given; static int author_ident_explicitly_given; +static int ident_config_given; #ifdef NO_GECOS_IN_PWENT #define get_gecos(ignored) "&" @@ -76,7 +79,7 @@ static int add_mailname_host(struct strbuf *buf) strerror(errno)); return -1; } - if (strbuf_getline(&mailnamebuf, mailname, '\n') == EOF) { + if (strbuf_getline(&mailnamebuf, mailname) == EOF) { if (ferror(mailname)) warning("cannot read /etc/mailname: %s", strerror(errno)); @@ -345,32 +348,44 @@ const char *fmt_ident(const char *name, const char *email, int want_date = !(flag & IDENT_NO_DATE); int want_name = !(flag & IDENT_NO_NAME); - if (want_name && !name) - name = ident_default_name(); - if (!email) - email = ident_default_email(); - - if (want_name && !*name) { - struct passwd *pw; - - if (strict) { - if (name == git_default_name.buf) + if (want_name) { + int using_default = 0; + if (!name) { + if (strict && ident_use_config_only + && !(ident_config_given & IDENT_NAME_GIVEN)) { + fputs(env_hint, stderr); + die("no name was given and auto-detection is disabled"); + } + name = ident_default_name(); + using_default = 1; + if (strict && default_name_is_bogus) { fputs(env_hint, stderr); - die("empty ident name (for <%s>) not allowed", email); + die("unable to auto-detect name (got '%s')", name); + } + } + if (!*name) { + struct passwd *pw; + if (strict) { + if (using_default) + fputs(env_hint, stderr); + die("empty ident name (for <%s>) not allowed", email); + } + pw = xgetpwuid_self(NULL); + name = pw->pw_name; } - pw = xgetpwuid_self(NULL); - name = pw->pw_name; - } - - if (want_name && strict && - name == git_default_name.buf && default_name_is_bogus) { - fputs(env_hint, stderr); - die("unable to auto-detect name (got '%s')", name); } - if (strict && email == git_default_email.buf && default_email_is_bogus) { - fputs(env_hint, stderr); - die("unable to auto-detect email address (got '%s')", email); + if (!email) { + if (strict && ident_use_config_only + && !(ident_config_given & IDENT_MAIL_GIVEN)) { + fputs(env_hint, stderr); + die("no email was given and auto-detection is disabled"); + } + email = ident_default_email(); + if (strict && default_email_is_bogus) { + fputs(env_hint, stderr); + die("unable to auto-detect email address (got '%s')", email); + } } strbuf_reset(&ident); @@ -444,6 +459,11 @@ int author_ident_sufficiently_given(void) int git_ident_config(const char *var, const char *value, void *data) { + if (!strcmp(var, "user.useconfigonly")) { + ident_use_config_only = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "user.name")) { if (!value) return config_error_nonbool(var); @@ -451,6 +471,7 @@ int git_ident_config(const char *var, const char *value, void *data) strbuf_addstr(&git_default_name, value); committer_ident_explicitly_given |= IDENT_NAME_GIVEN; author_ident_explicitly_given |= IDENT_NAME_GIVEN; + ident_config_given |= IDENT_NAME_GIVEN; return 0; } @@ -461,6 +482,7 @@ int git_ident_config(const char *var, const char *value, void *data) strbuf_addstr(&git_default_email, value); committer_ident_explicitly_given |= IDENT_MAIL_GIVEN; author_ident_explicitly_given |= IDENT_MAIL_GIVEN; + ident_config_given |= IDENT_MAIL_GIVEN; return 0; } diff --git a/imap-send.c b/imap-send.c index 2c52027c84..938c691585 100644 --- a/imap-send.c +++ b/imap-send.c @@ -287,17 +287,20 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve SSL_library_init(); SSL_load_error_strings(); - if (use_tls_only) - meth = TLSv1_method(); - else - meth = SSLv23_method(); - + meth = SSLv23_method(); if (!meth) { ssl_socket_perror("SSLv23_method"); return -1; } ctx = SSL_CTX_new(meth); + if (!ctx) { + ssl_socket_perror("SSL_CTX_new"); + return -1; + } + + if (use_tls_only) + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); if (verify) SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); @@ -862,7 +865,6 @@ static char hexchar(unsigned int b) static char *cram(const char *challenge_64, const char *user, const char *pass) { int i, resp_len, encoded_len, decoded_len; - HMAC_CTX hmac; unsigned char hash[16]; char hex[33]; char *response, *response_64, *challenge; @@ -877,10 +879,8 @@ static char *cram(const char *challenge_64, const char *user, const char *pass) (unsigned char *)challenge_64, encoded_len); if (decoded_len < 0) die("invalid challenge %s", challenge_64); - HMAC_Init(&hmac, (unsigned char *)pass, strlen(pass), EVP_md5()); - HMAC_Update(&hmac, (unsigned char *)challenge, decoded_len); - HMAC_Final(&hmac, hash, NULL); - HMAC_CTX_cleanup(&hmac); + if (!HMAC(EVP_md5(), pass, strlen(pass), (unsigned char *)challenge, decoded_len, hash, NULL)) + die("HMAC error"); hex[32] = 0; for (i = 0; i < 16; i++) { @@ -890,7 +890,7 @@ static char *cram(const char *challenge_64, const char *user, const char *pass) /* response: " " */ response = xstrfmt("%s %s", user, hex); - resp_len = strlen(response) + 1; + resp_len = strlen(response); response_64 = xmallocz(ENCODED_SIZE(resp_len)); encoded_len = EVP_EncodeBlock((unsigned char *)response_64, @@ -1095,11 +1095,6 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, char *f srvc->pass = xstrdup(cred.password); } - if (CAP(NOLOGIN)) { - fprintf(stderr, "Skipping account %s@%s, server forbids LOGIN\n", srvc->user, srvc->host); - goto bail; - } - if (srvc->auth_method) { struct imap_cmd_cb cb; @@ -1123,6 +1118,11 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, char *f goto bail; } } else { + if (CAP(NOLOGIN)) { + fprintf(stderr, "Skipping account %s@%s, server forbids LOGIN\n", + srvc->user, srvc->host); + goto bail; + } if (!imap->buf.sock.ssl) imap_warn("*** IMAP Warning *** Password is being " "sent in the clear\n"); diff --git a/lockfile.c b/lockfile.c index 80d056d2ed..9268cdf325 100644 --- a/lockfile.c +++ b/lockfile.c @@ -149,13 +149,15 @@ static int lock_file_timeout(struct lock_file *lk, const char *path, void unable_to_lock_message(const char *path, int err, struct strbuf *buf) { if (err == EEXIST) { - strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n" - "If no other git process is currently running, this probably means a\n" - "git process crashed in this repository earlier. Make sure no other git\n" - "process is running and remove the file manually to continue.", + strbuf_addf(buf, _("Unable to create '%s.lock': %s.\n\n" + "Another git process seems to be running in this repository, e.g.\n" + "an editor opened by 'git commit'. Please make sure all processes\n" + "are terminated then try again. If it still fails, a git process\n" + "may have crashed in this repository earlier:\n" + "remove the file manually to continue."), absolute_path(path), strerror(err)); } else - strbuf_addf(buf, "Unable to create '%s.lock': %s", + strbuf_addf(buf, _("Unable to create '%s.lock': %s"), absolute_path(path), strerror(err)); } diff --git a/mailinfo.c b/mailinfo.c index f289941f7e..9f19ca1080 100644 --- a/mailinfo.c +++ b/mailinfo.c @@ -732,7 +732,7 @@ static int read_one_header_line(struct strbuf *line, FILE *in) struct strbuf continuation = STRBUF_INIT; /* Get the first part of the line. */ - if (strbuf_getline(line, in, '\n')) + if (strbuf_getline_lf(line, in)) return 0; /* @@ -756,7 +756,7 @@ static int read_one_header_line(struct strbuf *line, FILE *in) peek = fgetc(in); ungetc(peek, in); if (peek != ' ' && peek != '\t') break; - if (strbuf_getline(&continuation, in, '\n')) + if (strbuf_getline_lf(&continuation, in)) break; continuation.buf[0] = ' '; strbuf_rtrim(&continuation); @@ -769,7 +769,7 @@ static int read_one_header_line(struct strbuf *line, FILE *in) static int find_boundary(struct mailinfo *mi, struct strbuf *line) { - while (!strbuf_getline(line, mi->input, '\n')) { + while (!strbuf_getline_lf(line, mi->input)) { if (*(mi->content_top) && is_multipart_boundary(mi, line)) return 1; } @@ -820,7 +820,7 @@ static int handle_boundary(struct mailinfo *mi, struct strbuf *line) strbuf_release(&newline); /* replenish line */ - if (strbuf_getline(line, mi->input, '\n')) + if (strbuf_getline_lf(line, mi->input)) return 0; strbuf_addch(line, '\n'); return 1; diff --git a/mailmap.c b/mailmap.c index f4a0f1cf27..972623709f 100644 --- a/mailmap.c +++ b/mailmap.c @@ -250,7 +250,8 @@ int read_mailmap(struct string_list *map, char **repo_abbrev) git_mailmap_blob = "HEAD:.mailmap"; err |= read_mailmap_file(map, ".mailmap", repo_abbrev); - err |= read_mailmap_blob(map, git_mailmap_blob, repo_abbrev); + if (startup_info->have_repository) + err |= read_mailmap_blob(map, git_mailmap_blob, repo_abbrev); err |= read_mailmap_file(map, git_mailmap_file, repo_abbrev); return err; } diff --git a/merge-recursive.c b/merge-recursive.c index 8eabde20fb..b880ae50e7 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -482,6 +482,9 @@ static struct string_list *get_renames(struct merge_options *o, struct diff_options opts; renames = xcalloc(1, sizeof(struct string_list)); + if (!o->detect_rename) + return renames; + diff_setup(&opts); DIFF_OPT_SET(&opts, RECURSIVE); DIFF_OPT_CLR(&opts, RENAME_EMPTY); @@ -2039,6 +2042,7 @@ void init_merge_options(struct merge_options *o) o->diff_rename_limit = -1; o->merge_rename_limit = -1; o->renormalize = 0; + o->detect_rename = 1; merge_recursive_config(o); if (getenv("GIT_MERGE_VERBOSITY")) o->verbosity = @@ -2088,9 +2092,17 @@ int parse_merge_opt(struct merge_options *o, const char *s) o->renormalize = 1; else if (!strcmp(s, "no-renormalize")) o->renormalize = 0; - else if (skip_prefix(s, "rename-threshold=", &arg)) { + else if (!strcmp(s, "no-renames")) + o->detect_rename = 0; + else if (!strcmp(s, "find-renames")) { + o->detect_rename = 1; + o->rename_score = 0; + } + else if (skip_prefix(s, "find-renames=", &arg) || + skip_prefix(s, "rename-threshold=", &arg)) { if ((o->rename_score = parse_rename_score(&arg)) == -1 || *arg != 0) return -1; + o->detect_rename = 1; } else return -1; diff --git a/merge-recursive.h b/merge-recursive.h index 9e090a3470..52f0201f68 100644 --- a/merge-recursive.h +++ b/merge-recursive.h @@ -17,6 +17,7 @@ struct merge_options { unsigned renormalize : 1; long xdl_opts; int verbosity; + int detect_rename; int diff_rename_limit; int merge_rename_limit; int rename_score; diff --git a/notes-cache.c b/notes-cache.c index c4e9bb7f6c..5dfc5cbd08 100644 --- a/notes-cache.c +++ b/notes-cache.c @@ -32,14 +32,14 @@ void notes_cache_init(struct notes_cache *c, const char *name, const char *validity) { struct strbuf ref = STRBUF_INIT; - int flags = 0; + int flags = NOTES_INIT_WRITABLE; memset(c, 0, sizeof(*c)); c->validity = xstrdup(validity); strbuf_addf(&ref, "refs/notes/%s", name); if (!notes_cache_match_validity(ref.buf, validity)) - flags = NOTES_INIT_EMPTY; + flags |= NOTES_INIT_EMPTY; init_notes(&c->tree, ref.buf, combine_notes_overwrite, flags); strbuf_release(&ref); } @@ -49,7 +49,8 @@ int notes_cache_write(struct notes_cache *c) unsigned char tree_sha1[20]; unsigned char commit_sha1[20]; - if (!c || !c->tree.initialized || !c->tree.ref || !*c->tree.ref) + if (!c || !c->tree.initialized || !c->tree.update_ref || + !*c->tree.update_ref) return -1; if (!c->tree.dirty) return 0; @@ -59,8 +60,8 @@ int notes_cache_write(struct notes_cache *c) if (commit_tree(c->validity, strlen(c->validity), tree_sha1, NULL, commit_sha1, NULL, NULL) < 0) return -1; - if (update_ref("update notes cache", c->tree.ref, commit_sha1, NULL, - 0, UPDATE_REFS_QUIET_ON_ERR) < 0) + if (update_ref("update notes cache", c->tree.update_ref, commit_sha1, + NULL, 0, UPDATE_REFS_QUIET_ON_ERR) < 0) return -1; return 0; diff --git a/notes-utils.c b/notes-utils.c index 299e34bccc..24a33616a4 100644 --- a/notes-utils.c +++ b/notes-utils.c @@ -37,7 +37,7 @@ void commit_notes(struct notes_tree *t, const char *msg) if (!t) t = &default_notes_tree; - if (!t->initialized || !t->ref || !*t->ref) + if (!t->initialized || !t->update_ref || !*t->update_ref) die(_("Cannot commit uninitialized/unreferenced notes tree")); if (!t->dirty) return; /* don't have to commit an unchanged tree */ @@ -48,7 +48,7 @@ void commit_notes(struct notes_tree *t, const char *msg) create_notes_commit(t, NULL, buf.buf, buf.len, commit_sha1); strbuf_insert(&buf, 0, "notes: ", 7); /* commit message starts at index 7 */ - update_ref(buf.buf, t->ref, commit_sha1, NULL, 0, + update_ref(buf.buf, t->update_ref, commit_sha1, NULL, 0, UPDATE_REFS_DIE_ON_ERR); strbuf_release(&buf); @@ -148,7 +148,7 @@ struct notes_rewrite_cfg *init_copy_notes_for_rewrite(const char *cmd) free(c); return NULL; } - c->trees = load_notes_trees(c->refs); + c->trees = load_notes_trees(c->refs, NOTES_INIT_WRITABLE); string_list_clear(c->refs, 0); free(c->refs); return c; diff --git a/notes.c b/notes.c index 8b59ccdb11..88cf4747c1 100644 --- a/notes.c +++ b/notes.c @@ -1011,13 +1011,16 @@ void init_notes(struct notes_tree *t, const char *notes_ref, t->first_non_note = NULL; t->prev_non_note = NULL; t->ref = xstrdup_or_null(notes_ref); + t->update_ref = (flags & NOTES_INIT_WRITABLE) ? t->ref : NULL; t->combine_notes = combine_notes; t->initialized = 1; t->dirty = 0; if (flags & NOTES_INIT_EMPTY || !notes_ref || - read_ref(notes_ref, object_sha1)) + get_sha1_treeish(notes_ref, object_sha1)) return; + if (flags & NOTES_INIT_WRITABLE && read_ref(notes_ref, object_sha1)) + die("Cannot use notes ref %s", notes_ref); if (get_tree_entry(object_sha1, "", sha1, &mode)) die("Failed to read notes tree referenced by %s (%s)", notes_ref, sha1_to_hex(object_sha1)); @@ -1027,7 +1030,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref, load_subtree(t, &root_tree, t->root, 0); } -struct notes_tree **load_notes_trees(struct string_list *refs) +struct notes_tree **load_notes_trees(struct string_list *refs, int flags) { struct string_list_item *item; int counter = 0; @@ -1035,7 +1038,7 @@ struct notes_tree **load_notes_trees(struct string_list *refs) ALLOC_ARRAY(trees, refs->nr + 1); for_each_string_list_item(item, refs) { struct notes_tree *t = xcalloc(1, sizeof(struct notes_tree)); - init_notes(t, item->string, combine_notes_ignore, 0); + init_notes(t, item->string, combine_notes_ignore, flags); trees[counter++] = t; } trees[counter] = NULL; @@ -1071,7 +1074,7 @@ void init_display_notes(struct display_notes_opt *opt) item->string); } - display_notes_trees = load_notes_trees(&display_notes_refs); + display_notes_trees = load_notes_trees(&display_notes_refs, 0); string_list_clear(&display_notes_refs, 0); } @@ -1303,3 +1306,13 @@ void expand_notes_ref(struct strbuf *sb) else strbuf_insert(sb, 0, "refs/notes/", 11); } + +void expand_loose_notes_ref(struct strbuf *sb) +{ + unsigned char object[20]; + + if (get_sha1(sb->buf, object)) { + /* fallback to expand_notes_ref */ + expand_notes_ref(sb); + } +} diff --git a/notes.h b/notes.h index 2a3f923380..5345642cfd 100644 --- a/notes.h +++ b/notes.h @@ -44,6 +44,7 @@ extern struct notes_tree { struct int_node *root; struct non_note *first_non_note, *prev_non_note; char *ref; + char *update_ref; combine_notes_fn combine_notes; int initialized; int dirty; @@ -71,6 +72,13 @@ const char *default_notes_ref(void); */ #define NOTES_INIT_EMPTY 1 +/* + * By default, the notes tree is only readable, and the notes ref can be + * any treeish. The notes tree can however be made writable with this flag, + * in which case only strict ref names can be used. + */ +#define NOTES_INIT_WRITABLE 2 + /* * Initialize the given notes_tree with the notes tree structure at the given * ref. If given ref is NULL, the value of the $GIT_NOTES_REF environment @@ -276,7 +284,7 @@ void format_display_notes(const unsigned char *object_sha1, * Load the notes tree from each ref listed in 'refs'. The output is * an array of notes_tree*, terminated by a NULL. */ -struct notes_tree **load_notes_trees(struct string_list *refs); +struct notes_tree **load_notes_trees(struct string_list *refs, int flags); /* * Add all refs that match 'glob' to the 'list'. @@ -294,4 +302,11 @@ void string_list_add_refs_from_colon_sep(struct string_list *list, /* Expand inplace a note ref like "foo" or "notes/foo" into "refs/notes/foo" */ void expand_notes_ref(struct strbuf *sb); +/* + * Similar to expand_notes_ref, but will check whether the ref can be located + * via get_sha1 first, and only falls back to expand_notes_ref in the case + * where get_sha1 fails. + */ +void expand_loose_notes_ref(struct strbuf *sb); + #endif diff --git a/pack-bitmap.c b/pack-bitmap.c index d92394692e..b949e51716 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -33,9 +33,6 @@ static struct bitmap_index { /* Packfile to which this bitmap index belongs to */ struct packed_git *pack; - /* reverse index for the packfile */ - struct pack_revindex *reverse_index; - /* * Mark the first `reuse_objects` in the packfile as reused: * they will be sent as-is without using them for repacking @@ -308,7 +305,7 @@ static int load_pack_bitmap(void) bitmap_git.bitmaps = kh_init_sha1(); bitmap_git.ext_index.positions = kh_init_sha1_pos(); - bitmap_git.reverse_index = revindex_for_pack(bitmap_git.pack); + load_pack_revindex(bitmap_git.pack); if (!(bitmap_git.commits = read_bitmap_1(&bitmap_git)) || !(bitmap_git.trees = read_bitmap_1(&bitmap_git)) || @@ -380,7 +377,7 @@ static inline int bitmap_position_packfile(const unsigned char *sha1) if (!offset) return -1; - return find_revindex_position(bitmap_git.reverse_index, offset); + return find_revindex_position(bitmap_git.pack, offset); } static int bitmap_position(const unsigned char *sha1) @@ -626,7 +623,7 @@ static void show_objects_for_type( if (pos + offset < bitmap_git.reuse_objects) continue; - entry = &bitmap_git.reverse_index->revindex[pos + offset]; + entry = &bitmap_git.pack->revindex[pos + offset]; sha1 = nth_packed_object_sha1(bitmap_git.pack, entry->nr); if (bitmap_git.hashes) @@ -800,7 +797,7 @@ int reuse_partial_packfile_from_bitmap(struct packed_git **packfile, return -1; bitmap_git.reuse_objects = *entries = reuse_objects; - *up_to = bitmap_git.reverse_index->revindex[reuse_objects].offset; + *up_to = bitmap_git.pack->revindex[reuse_objects].offset; *packfile = bitmap_git.pack; return 0; @@ -1033,7 +1030,7 @@ int rebuild_existing_bitmaps(struct packing_data *mapping, struct revindex_entry *entry; struct object_entry *oe; - entry = &bitmap_git.reverse_index->revindex[i]; + entry = &bitmap_git.pack->revindex[i]; sha1 = nth_packed_object_sha1(bitmap_git.pack, entry->nr); oe = packlist_find(mapping, sha1, NULL); diff --git a/pack-revindex.c b/pack-revindex.c index f6a3613beb..96d51c3467 100644 --- a/pack-revindex.c +++ b/pack-revindex.c @@ -8,52 +8,13 @@ * size is easily available by examining the pack entry header). It is * also rather expensive to find the sha1 for an object given its offset. * - * We build a hashtable of existing packs (pack_revindex), and keep reverse - * index here -- pack index file is sorted by object name mapping to offset; - * this pack_revindex[].revindex array is a list of offset/index_nr pairs + * The pack index file is sorted by object name mapping to offset; + * this revindex array is a list of offset/index_nr pairs * ordered by offset, so if you know the offset of an object, next offset * is where its packed representation ends and the index_nr can be used to * get the object sha1 from the main index. */ -static struct pack_revindex *pack_revindex; -static int pack_revindex_hashsz; - -static int pack_revindex_ix(struct packed_git *p) -{ - unsigned long ui = (unsigned long)(intptr_t)p; - int i; - - ui = ui ^ (ui >> 16); /* defeat structure alignment */ - i = (int)(ui % pack_revindex_hashsz); - while (pack_revindex[i].p) { - if (pack_revindex[i].p == p) - return i; - if (++i == pack_revindex_hashsz) - i = 0; - } - return -1 - i; -} - -static void init_pack_revindex(void) -{ - int num; - struct packed_git *p; - - for (num = 0, p = packed_git; p; p = p->next) - num++; - if (!num) - return; - pack_revindex_hashsz = num * 11; - pack_revindex = xcalloc(pack_revindex_hashsz, sizeof(*pack_revindex)); - for (p = packed_git; p; p = p->next) { - num = pack_revindex_ix(p); - num = - 1 - num; - pack_revindex[num].p = p; - } - /* revindex elements are lazily initialized */ -} - /* * This is a least-significant-digit radix sort. * @@ -158,14 +119,13 @@ static void sort_revindex(struct revindex_entry *entries, unsigned n, off_t max) /* * Ordered list of offsets of objects in the pack. */ -static void create_pack_revindex(struct pack_revindex *rix) +static void create_pack_revindex(struct packed_git *p) { - struct packed_git *p = rix->p; unsigned num_ent = p->num_objects; unsigned i; const char *index = p->index_data; - ALLOC_ARRAY(rix->revindex, num_ent + 1); + ALLOC_ARRAY(p->revindex, num_ent + 1); index += 4 * 256; if (p->index_version > 1) { @@ -175,55 +135,42 @@ static void create_pack_revindex(struct pack_revindex *rix) for (i = 0; i < num_ent; i++) { uint32_t off = ntohl(*off_32++); if (!(off & 0x80000000)) { - rix->revindex[i].offset = off; + p->revindex[i].offset = off; } else { - rix->revindex[i].offset = + p->revindex[i].offset = ((uint64_t)ntohl(*off_64++)) << 32; - rix->revindex[i].offset |= + p->revindex[i].offset |= ntohl(*off_64++); } - rix->revindex[i].nr = i; + p->revindex[i].nr = i; } } else { for (i = 0; i < num_ent; i++) { uint32_t hl = *((uint32_t *)(index + 24 * i)); - rix->revindex[i].offset = ntohl(hl); - rix->revindex[i].nr = i; + p->revindex[i].offset = ntohl(hl); + p->revindex[i].nr = i; } } /* This knows the pack format -- the 20-byte trailer * follows immediately after the last object data. */ - rix->revindex[num_ent].offset = p->pack_size - 20; - rix->revindex[num_ent].nr = -1; - sort_revindex(rix->revindex, num_ent, p->pack_size); + p->revindex[num_ent].offset = p->pack_size - 20; + p->revindex[num_ent].nr = -1; + sort_revindex(p->revindex, num_ent, p->pack_size); } -struct pack_revindex *revindex_for_pack(struct packed_git *p) +void load_pack_revindex(struct packed_git *p) { - int num; - struct pack_revindex *rix; - - if (!pack_revindex_hashsz) - init_pack_revindex(); - - num = pack_revindex_ix(p); - if (num < 0) - die("internal error: pack revindex fubar"); - - rix = &pack_revindex[num]; - if (!rix->revindex) - create_pack_revindex(rix); - - return rix; + if (!p->revindex) + create_pack_revindex(p); } -int find_revindex_position(struct pack_revindex *pridx, off_t ofs) +int find_revindex_position(struct packed_git *p, off_t ofs) { int lo = 0; - int hi = pridx->p->num_objects + 1; - struct revindex_entry *revindex = pridx->revindex; + int hi = p->num_objects + 1; + struct revindex_entry *revindex = p->revindex; do { unsigned mi = lo + (hi - lo) / 2; @@ -241,11 +188,13 @@ int find_revindex_position(struct pack_revindex *pridx, off_t ofs) struct revindex_entry *find_pack_revindex(struct packed_git *p, off_t ofs) { - struct pack_revindex *pridx = revindex_for_pack(p); - int pos = find_revindex_position(pridx, ofs); + int pos; + + load_pack_revindex(p); + pos = find_revindex_position(p, ofs); if (pos < 0) return NULL; - return pridx->revindex + pos; + return p->revindex + pos; } diff --git a/pack-revindex.h b/pack-revindex.h index d737f98965..e262f3efe8 100644 --- a/pack-revindex.h +++ b/pack-revindex.h @@ -1,18 +1,15 @@ #ifndef PACK_REVINDEX_H #define PACK_REVINDEX_H +struct packed_git; + struct revindex_entry { off_t offset; unsigned int nr; }; -struct pack_revindex { - struct packed_git *p; - struct revindex_entry *revindex; -}; - -struct pack_revindex *revindex_for_pack(struct packed_git *p); -int find_revindex_position(struct pack_revindex *pridx, off_t ofs); +void load_pack_revindex(struct packed_git *p); +int find_revindex_position(struct packed_git *p, off_t ofs); struct revindex_entry *find_pack_revindex(struct packed_git *p, off_t ofs); diff --git a/path.c b/path.c index b214ac3fe6..6fbc4c38cc 100644 --- a/path.c +++ b/path.c @@ -134,7 +134,7 @@ static struct common_dir common_list[] = { * definite * definition * - * The trie would look look like: + * The trie would look like: * root: len = 0, children a and d non-NULL, value = NULL. * a: len = 2, contents = bc, value = (data for "abc") * d: len = 2, contents = ef, children i non-NULL, value = (data for "def") @@ -584,6 +584,9 @@ char *expand_user_path(const char *path) if (!home) goto return_null; strbuf_addstr(&user_path, home); +#ifdef GIT_WINDOWS_NATIVE + convert_slashes(user_path.buf); +#endif } else { struct passwd *pw = getpw_str(username, username_len); if (!pw) @@ -699,17 +702,17 @@ static int calc_shared_perm(int mode) { int tweak; - if (shared_repository < 0) - tweak = -shared_repository; + if (get_shared_repository() < 0) + tweak = -get_shared_repository(); else - tweak = shared_repository; + tweak = get_shared_repository(); if (!(mode & S_IWUSR)) tweak &= ~0222; if (mode & S_IXUSR) /* Copy read bits to execute bits */ tweak |= (tweak & 0444) >> 2; - if (shared_repository < 0) + if (get_shared_repository() < 0) mode = (mode & ~0777) | tweak; else mode |= tweak; @@ -722,7 +725,7 @@ int adjust_shared_perm(const char *path) { int old_mode, new_mode; - if (!shared_repository) + if (!get_shared_repository()) return 0; if (get_st_mode_bits(path, &old_mode) < 0) return -1; diff --git a/perl/Git.pm b/perl/Git.pm index 19ef081103..ce7e4e8da3 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -188,7 +188,8 @@ sub repository { }; if ($dir) { - $dir =~ m#^/# or $dir = $opts{Directory} . '/' . $dir; + _verify_require(); + File::Spec->file_name_is_absolute($dir) or $dir = $opts{Directory} . '/' . $dir; $opts{Repository} = abs_path($dir); # If --git-dir went ok, this shouldn't die either. @@ -392,7 +393,7 @@ sub command_close_pipe { Execute the given C in the same way as command_output_pipe() does but return both an input pipe filehandle and an output pipe filehandle. -The function will return return C<($pid, $pipe_in, $pipe_out, $ctx)>. +The function will return C<($pid, $pipe_in, $pipe_out, $ctx)>. See C for details. =cut diff --git a/perl/Git/SVN/Editor.pm b/perl/Git/SVN/Editor.pm index c50176eec9..4c4199afec 100644 --- a/perl/Git/SVN/Editor.pm +++ b/perl/Git/SVN/Editor.pm @@ -41,6 +41,7 @@ sub new { "$self->{svn_path}/" : ''; $self->{config} = $opts->{config}; $self->{mergeinfo} = $opts->{mergeinfo}; + $self->{pathnameencoding} = Git::config('svn.pathnameencoding'); return $self; } @@ -143,11 +144,12 @@ sub repo_path { sub url_path { my ($self, $path) = @_; + $path = $self->repo_path($path); if ($self->{url} =~ m#^https?://#) { # characters are taken from subversion/libsvn_subr/path.c $path =~ s#([^~a-zA-Z0-9_./!$&'()*+,-])#sprintf("%%%02X",ord($1))#eg; } - $self->{url} . '/' . $self->repo_path($path); + $self->{url} . '/' . $path; } sub rmdirs { diff --git a/perl/Git/SVN/GlobSpec.pm b/perl/Git/SVN/GlobSpec.pm index c95f5d76ca..a0a8d17621 100644 --- a/perl/Git/SVN/GlobSpec.pm +++ b/perl/Git/SVN/GlobSpec.pm @@ -8,19 +8,23 @@ sub new { $re =~ s!/+$!!g; # no need for trailing slashes my (@left, @right, @patterns); my $state = "left"; - my $die_msg = "Only one set of wildcard directories " . - "(e.g. '*' or '*/*/*') is supported: '$glob'\n"; + my $die_msg = "Only one set of wildcards " . + "(e.g. '*' or '*/*/*') is supported: $glob\n"; for my $part (split(m|/|, $glob)) { - if ($part =~ /\*/ && $part ne "*") { - die "Invalid pattern in '$glob': $part\n"; - } elsif ($pattern_ok && $part =~ /[{}]/ && + if ($pattern_ok && $part =~ /[{}]/ && $part !~ /^\{[^{}]+\}/) { die "Invalid pattern in '$glob': $part\n"; } - if ($part eq "*") { + my $nstars = $part =~ tr/*//; + if ($nstars > 1) { + die "Only one '*' is allowed in a pattern: '$part'\n"; + } + if ($part =~ /(.*)\*(.*)/) { die $die_msg if $state eq "right"; + my ($l, $r) = ($1, $2); $state = "pattern"; - push(@patterns, "[^/]*"); + my $pat = quotemeta($l) . '[^/]*' . quotemeta($r); + push(@patterns, $pat); } elsif ($pattern_ok && $part =~ /^\{(.*)\}$/) { die $die_msg if $state eq "right"; $state = "pattern"; diff --git a/po/TEAMS b/po/TEAMS index df12b5819c..56274ad4f3 100644 --- a/po/TEAMS +++ b/po/TEAMS @@ -11,7 +11,7 @@ Leader: Alex Henrie Language: de (German) Repository: https://github.com/ralfth/git-po-de -Leader: Ralf Thielow +Leader: Ralf Thielow Members: Thomas Rast Jan Krüger Christian Stimming diff --git a/po/ca.po b/po/ca.po index d364141a8d..46000d7d64 100644 --- a/po/ca.po +++ b/po/ca.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List \n" -"POT-Creation-Date: 2015-12-22 22:50+0800\n" -"PO-Revision-Date: 2015-12-27 21:42-0700\n" +"POT-Creation-Date: 2016-03-16 00:16+0800\n" +"PO-Revision-Date: 2016-03-19 23:51-0600\n" "Last-Translator: Alex Henrie \n" "Language-Team: Catalan\n" "Language: ca\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 1.8.6\n" +"X-Generator: Poedit 1.8.7\n" #: advice.c:55 #, c-format @@ -32,7 +32,7 @@ msgstr "" "'git add/rm ' segons sigui apropiat per a marcar la\n" "resolució i feu una comissió." -#: advice.c:101 builtin/merge.c:1225 +#: advice.c:101 builtin/merge.c:1226 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "No heu conclòs la vostra fusió (MERGE_HEAD existeix)." @@ -76,7 +76,7 @@ msgstr "format" msgid "archive format" msgstr "format d'arxiu" -#: archive.c:430 builtin/log.c:1229 +#: archive.c:430 builtin/log.c:1232 msgid "prefix" msgstr "prefix" @@ -84,10 +84,10 @@ msgstr "prefix" msgid "prepend prefix to each pathname in the archive" msgstr "anteposa el prefix a cada nom de camí en l'arxiu" -#: archive.c:432 builtin/archive.c:88 builtin/blame.c:2535 builtin/blame.c:2536 -#: builtin/config.c:58 builtin/fast-export.c:987 builtin/fast-export.c:989 -#: builtin/grep.c:707 builtin/hash-object.c:99 builtin/ls-files.c:446 -#: builtin/ls-files.c:449 builtin/notes.c:395 builtin/notes.c:558 +#: archive.c:432 builtin/archive.c:88 builtin/blame.c:2547 builtin/blame.c:2548 +#: builtin/config.c:60 builtin/fast-export.c:987 builtin/fast-export.c:989 +#: builtin/grep.c:720 builtin/hash-object.c:100 builtin/ls-files.c:459 +#: builtin/ls-files.c:462 builtin/notes.c:398 builtin/notes.c:561 #: builtin/read-tree.c:109 parse-options.h:153 msgid "file" msgstr "fitxer" @@ -120,7 +120,7 @@ msgstr "comprimeix millor" msgid "list supported archive formats" msgstr "allista els formats d'arxiu admesos" -#: archive.c:451 builtin/archive.c:90 builtin/clone.c:77 +#: archive.c:451 builtin/archive.c:90 builtin/clone.c:78 msgid "repo" msgstr "dipòsit" @@ -128,7 +128,7 @@ msgstr "dipòsit" msgid "retrieve the archive from remote repository " msgstr "recupera l'arxiu del dipòsit remot " -#: archive.c:453 builtin/archive.c:92 builtin/notes.c:479 +#: archive.c:453 builtin/archive.c:92 builtin/notes.c:482 msgid "command" msgstr "ordre" @@ -136,7 +136,7 @@ msgstr "ordre" msgid "path to the remote git-upload-archive command" msgstr "camí a l'ordre git-upload-archive remota" -#: attr.c:265 +#: attr.c:263 msgid "" "Negative patterns are ignored in git attributes\n" "Use '\\!' for literal leading exclamation." @@ -144,90 +144,107 @@ msgstr "" "Els patrons negatius s'ignoren en els atributs de git\n" "Useu '\\!' per exclamació capdavantera literal." -#: branch.c:61 +#: branch.c:53 +#, c-format +msgid "" +"\n" +"After fixing the error cause you may try to fix up\n" +"the remote tracking information by invoking\n" +"\"git branch --set-upstream-to=%s%s%s\"." +msgstr "" +"\n" +"Després de corregir la causa de l'error, podeu\n" +"intentar corregir la informació de seguiment remot\n" +"invocant \"git branch --set-upstream-to=%s%s%s\"." + +#: branch.c:67 #, c-format msgid "Not setting branch %s as its own upstream." msgstr "No establint la branca %s com a la seva pròpia font." -#: branch.c:84 +#: branch.c:93 #, c-format msgid "Branch %s set up to track remote branch %s from %s by rebasing." msgstr "" "La branca %s està configurada per a seguir la branca remota %s de %s per " "rebasar." -#: branch.c:85 +#: branch.c:94 #, c-format msgid "Branch %s set up to track remote branch %s from %s." msgstr "La branca %s està configurada per a seguir la branca remota %s de %s." -#: branch.c:89 +#: branch.c:98 #, c-format msgid "Branch %s set up to track local branch %s by rebasing." msgstr "" "La branca %s està configurada per a seguir la branca local %s per rebasar." -#: branch.c:90 +#: branch.c:99 #, c-format msgid "Branch %s set up to track local branch %s." msgstr "La branca %s està configurada per a seguir la branca local %s." -#: branch.c:95 +#: branch.c:104 #, c-format msgid "Branch %s set up to track remote ref %s by rebasing." msgstr "" "La branca %s està configurada per a seguir la referència remota %s per " "rebasar." -#: branch.c:96 +#: branch.c:105 #, c-format msgid "Branch %s set up to track remote ref %s." msgstr "La branca %s està configurada per a seguir la referència remota %s." -#: branch.c:100 +#: branch.c:109 #, c-format msgid "Branch %s set up to track local ref %s by rebasing." msgstr "" "La branca %s està configurada per a seguir la referència local %s per " "rebasar." -#: branch.c:101 +#: branch.c:110 #, c-format msgid "Branch %s set up to track local ref %s." msgstr "La branca %s està configurada per a seguir la referència local %s." -#: branch.c:134 +#: branch.c:119 +msgid "Unable to write upstream branch configuration" +msgstr "No es pot escriure la configuració de la branca font" + +#: branch.c:156 #, c-format msgid "Not tracking: ambiguous information for ref %s" msgstr "No seguint: informació ambigua per a la referència %s" -#: branch.c:163 +#: branch.c:185 #, c-format msgid "'%s' is not a valid branch name." msgstr "'%s' no és un nom de branca vàlid." -#: branch.c:168 +#: branch.c:190 #, c-format msgid "A branch named '%s' already exists." msgstr "Una branca amb nom '%s' ja existeix." -#: branch.c:176 +#: branch.c:198 msgid "Cannot force update the current branch." msgstr "No es pot actualitzar la branca actual a la força." -#: branch.c:196 +#: branch.c:218 #, c-format msgid "Cannot setup tracking information; starting point '%s' is not a branch." msgstr "" "No es pot configurar la informació de seguiment; el punt inicial '%s' no és " "una branca." -#: branch.c:198 +#: branch.c:220 #, c-format msgid "the requested upstream branch '%s' does not exist" msgstr "la branca font demanada '%s' no existeix" -#: branch.c:200 +#: branch.c:222 msgid "" "\n" "If you are planning on basing your work on an upstream\n" @@ -248,22 +265,22 @@ msgstr "" "\"git push -u\" per a establir la configuració font\n" "mentre pugeu." -#: branch.c:244 +#: branch.c:266 #, c-format msgid "Not a valid object name: '%s'." msgstr "No és un nom d'objecte vàlid: '%s'." -#: branch.c:264 +#: branch.c:286 #, c-format msgid "Ambiguous object name: '%s'." msgstr "Nom d'objecte ambigu: '%s'." -#: branch.c:269 +#: branch.c:291 #, c-format msgid "Not a valid branch point: '%s'." msgstr "No és un punt de ramificació vàlid: '%s'." -#: branch.c:322 +#: branch.c:344 #, c-format msgid "'%s' is already checked out at '%s'" msgstr "'%s' ja s'ha agafat a '%s'" @@ -287,10 +304,10 @@ msgstr "no s'ha pogut obrir '%s'" msgid "Repository lacks these prerequisite commits:" msgstr "Al dipòsit li manquen aquestes comissions prerequisits:" -#: bundle.c:163 ref-filter.c:1372 sequencer.c:636 sequencer.c:1083 -#: builtin/blame.c:2734 builtin/commit.c:1045 builtin/log.c:334 -#: builtin/log.c:849 builtin/log.c:1461 builtin/log.c:1694 builtin/merge.c:358 -#: builtin/shortlog.c:158 +#: bundle.c:163 ref-filter.c:1462 sequencer.c:627 sequencer.c:1074 +#: builtin/blame.c:2754 builtin/commit.c:1045 builtin/log.c:334 +#: builtin/log.c:852 builtin/log.c:1467 builtin/log.c:1700 builtin/merge.c:358 +#: builtin/shortlog.c:170 msgid "revision walk setup failed" msgstr "la configuració del passeig per revisions ha fallat" @@ -329,7 +346,7 @@ msgstr "El rev-list s'ha mort" msgid "ref '%s' is excluded by the rev-list options" msgstr "les opcions de la llista de revisions exclouen la referència '%s'" -#: bundle.c:443 builtin/log.c:157 builtin/log.c:1369 builtin/shortlog.c:261 +#: bundle.c:443 builtin/log.c:157 builtin/log.c:1372 builtin/shortlog.c:273 #, c-format msgid "unrecognized argument: %s" msgstr "paràmetre no reconegut: %s" @@ -352,8 +369,8 @@ msgstr "L'index-pack s'ha mort" msgid "invalid color value: %.*s" msgstr "valor de color no vàlid: %.*s" -#: commit.c:40 builtin/am.c:452 builtin/am.c:488 builtin/am.c:1520 -#: builtin/am.c:2149 +#: commit.c:40 builtin/am.c:437 builtin/am.c:473 builtin/am.c:1505 +#: builtin/am.c:2135 #, c-format msgid "could not parse %s" msgstr "no s'ha pogut analitzar %s" @@ -367,59 +384,64 @@ msgstr "%s %s no és una comissió!" msgid "memory exhausted" msgstr "memòria esgotada" -#: config.c:474 config.c:476 +#: config.c:475 config.c:477 #, c-format -msgid "bad config file line %d in %s" -msgstr "línia de fitxer de configuració dolenta %d en %s" +msgid "bad config line %d in %s %s" +msgstr "línia de fitxer de configuració dolenta %d en %s %s" -#: config.c:592 +#: config.c:593 #, c-format -msgid "bad numeric config value '%s' for '%s' in %s: %s" -msgstr "valor de configuració numèrica dolent '%s' per '%s' en %s: %s" +msgid "bad numeric config value '%s' for '%s' in %s %s: %s" +msgstr "valor de configuració numèrica dolent '%s' per '%s' en %s %s: %s" -#: config.c:594 +#: config.c:595 #, c-format msgid "bad numeric config value '%s' for '%s': %s" msgstr "valor de configuració numèrica dolent '%s' per '%s': %s" -#: config.c:679 +#: config.c:680 #, c-format msgid "failed to expand user dir in: '%s'" msgstr "s'ha fallat en expandir el directori d'usuari en '%s'" -#: config.c:757 config.c:768 +#: config.c:758 config.c:769 #, c-format msgid "bad zlib compression level %d" msgstr "nivell de compressió de zlib dolent %d" -#: config.c:890 +#: config.c:891 #, c-format msgid "invalid mode for object creation: %s" msgstr "mode de creació d'objecte no vàlid: %s" -#: config.c:1216 +#: config.c:1220 msgid "unable to parse command-line config" msgstr "no s'ha pogut analitzar la configuració de la línia d'ordres" -#: config.c:1277 +#: config.c:1281 msgid "unknown error occured while reading the configuration files" msgstr "ha ocorregut un error desconegut en llegir els fitxers de configuració" -#: config.c:1601 +#: config.c:1629 #, c-format msgid "unable to parse '%s' from command-line config" msgstr "no s'ha pogut analitzar '%s' de la configuració de la línia d'ordres" -#: config.c:1603 +#: config.c:1631 #, c-format msgid "bad config variable '%s' in file '%s' at line %d" msgstr "variable de configuració dolenta '%s' en el fitxer '%s' a la línia %d" -#: config.c:1662 +#: config.c:1690 #, c-format msgid "%s has multiple values" msgstr "%s té múltiples valors" +#: config.c:2226 +#, c-format +msgid "Could not set '%s' to '%s'" +msgstr "No s'ha pogut establir '%s' com a '%s'" + #: connected.c:69 msgid "Could not run 'git rev-list'" msgstr "No s'ha pogut executar 'git rev-list'" @@ -536,16 +558,16 @@ msgstr "" "Errors trobats en la variable de configuració 'diff.dirstat':\n" "%s" -#: diff.c:3000 +#: diff.c:2997 #, c-format msgid "external diff died, stopping at %s" msgstr "El diff external s'ha mort, aturant a %s" -#: diff.c:3396 +#: diff.c:3393 msgid "--follow requires exactly one pathspec" msgstr "--follow requereix exactament una especificació de camí" -#: diff.c:3559 +#: diff.c:3556 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -554,18 +576,19 @@ msgstr "" "S'ha fallat en analitzar el paràmetre d'opció de --dirstat/-X:\n" "%s" -#: diff.c:3573 +#: diff.c:3570 #, c-format msgid "Failed to parse --submodule option parameter: '%s'" msgstr "S'ha fallat en analitzar el paràmetre d'opció de --submodule: %s" -#: dir.c:1915 +#: dir.c:2004 msgid "failed to get kernel name and information" msgstr "s'ha fallat en obtenir el nombre i la informació del nucli" -#: dir.c:1998 -msgid "Untracked cache is disabled on this system." -msgstr "La memòria cau no seguida està deshabilitada en aquest sistema." +#: dir.c:2123 +msgid "Untracked cache is disabled on this system or location." +msgstr "" +"La memòria cau no seguida està inhabilitada en aquest sistema o ubicació." #: gpg-interface.c:166 gpg-interface.c:237 msgid "could not run gpg." @@ -604,20 +627,20 @@ msgstr "'%s': %s" msgid "'%s': short read %s" msgstr "'%s': lectura curta %s" -#: help.c:207 +#: help.c:205 #, c-format msgid "available git commands in '%s'" msgstr "ordres de git disponibles en '%s'" -#: help.c:214 +#: help.c:212 msgid "git commands available from elsewhere on your $PATH" msgstr "ordres de git disponibles d'altres llocs en el vostre $PATH" -#: help.c:246 +#: help.c:244 msgid "These are common Git commands used in various situations:" msgstr "Aquestes són ordres del Git comunament usades en diverses situacions:" -#: help.c:311 +#: help.c:309 #, c-format msgid "" "'%s' appears to be a git command, but we were not\n" @@ -626,11 +649,11 @@ msgstr "" "'%s' sembla una ordre de git, però no hem pogut\n" "executar-la. Pot ser que git-%s estigui estropejat?" -#: help.c:368 +#: help.c:366 msgid "Uh oh. Your system reports no Git commands at all." msgstr "Ai. El vostre sistema no informa de cap ordre de Git." -#: help.c:390 +#: help.c:388 #, c-format msgid "" "WARNING: You called a Git command named '%s', which does not exist.\n" @@ -639,17 +662,17 @@ msgstr "" "AVÍS: Heu invocat una ordre de Git amb nom '%s', la qual no existeix.\n" "Continuant sota l'assumpció que volíeu dir '%s'" -#: help.c:395 +#: help.c:393 #, c-format msgid "in %0.1f seconds automatically..." msgstr "en %0.1f segons automàticament..." -#: help.c:402 +#: help.c:400 #, c-format msgid "git: '%s' is not a git command. See 'git --help'." msgstr "git: '%s' no és una ordre de git. Vegeu 'git --help'." -#: help.c:406 help.c:466 +#: help.c:404 help.c:464 msgid "" "\n" "Did you mean this?" @@ -663,7 +686,7 @@ msgstr[1] "" "\n" "Volíeu dir un d'aquests?" -#: help.c:462 +#: help.c:460 #, c-format msgid "%s: %s - %s" msgstr "%s: %s - %s" @@ -672,8 +695,8 @@ msgstr "%s: %s - %s" msgid "failed to read the cache" msgstr "s'ha fallat en llegir la memòria cau" -#: merge.c:94 builtin/am.c:2022 builtin/am.c:2057 builtin/checkout.c:376 -#: builtin/checkout.c:587 builtin/clone.c:722 +#: merge.c:94 builtin/am.c:2008 builtin/am.c:2043 builtin/checkout.c:376 +#: builtin/checkout.c:587 builtin/clone.c:730 msgid "unable to write new index file" msgstr "no s'ha pogut escriure un fitxer d'índex nou" @@ -691,64 +714,64 @@ msgstr "addinfo_cache ha fallat per al camí '%s'" msgid "error building trees" msgstr "error en construir arbres" -#: merge-recursive.c:686 +#: merge-recursive.c:689 #, c-format msgid "failed to create path '%s'%s" msgstr "s'ha fallat en crear el camí '%s' %s" -#: merge-recursive.c:697 +#: merge-recursive.c:700 #, c-format msgid "Removing %s to make room for subdirectory\n" msgstr "Eliminant %s per a fer espai per al subdirectori\n" -#: merge-recursive.c:711 merge-recursive.c:732 +#: merge-recursive.c:714 merge-recursive.c:735 msgid ": perhaps a D/F conflict?" msgstr ": potser un conflicte D/F?" -#: merge-recursive.c:722 +#: merge-recursive.c:725 #, c-format msgid "refusing to lose untracked file at '%s'" msgstr "refusant perdre el fitxer no seguit a '%s'" -#: merge-recursive.c:762 +#: merge-recursive.c:765 #, c-format msgid "cannot read object %s '%s'" msgstr "no es pot llegir l'objecte %s '%s'" -#: merge-recursive.c:764 +#: merge-recursive.c:767 #, c-format msgid "blob expected for %s '%s'" msgstr "blob esperat per a %s '%s'" -#: merge-recursive.c:787 builtin/clone.c:369 +#: merge-recursive.c:790 builtin/clone.c:374 #, c-format msgid "failed to open '%s'" msgstr "s'ha fallat en obrir '%s'" -#: merge-recursive.c:795 +#: merge-recursive.c:798 #, c-format msgid "failed to symlink '%s'" msgstr "s'ha fallat en fer l'enllaç simbòlic '%s'" -#: merge-recursive.c:798 +#: merge-recursive.c:801 #, c-format msgid "do not know what to do with %06o %s '%s'" msgstr "no se sap què fer amb %06o %s '%s'" -#: merge-recursive.c:936 +#: merge-recursive.c:939 msgid "Failed to execute internal merge" msgstr "S'ha fallat en executar la fusió interna" -#: merge-recursive.c:940 +#: merge-recursive.c:943 #, c-format msgid "Unable to add %s to database" msgstr "no s'ha pogut afegir %s a la base de dades" -#: merge-recursive.c:956 +#: merge-recursive.c:959 msgid "unsupported object type in the tree" msgstr "tipus d'objecte no compatible en l'arbre" -#: merge-recursive.c:1031 merge-recursive.c:1045 +#: merge-recursive.c:1034 merge-recursive.c:1048 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -757,7 +780,7 @@ msgstr "" "CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de %s " "s'ha deixat en l'arbre." -#: merge-recursive.c:1037 merge-recursive.c:1050 +#: merge-recursive.c:1040 merge-recursive.c:1053 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -766,20 +789,20 @@ msgstr "" "CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de %s " "s'ha deixat en l'arbre a %s." -#: merge-recursive.c:1091 +#: merge-recursive.c:1094 msgid "rename" msgstr "canvia de nom" -#: merge-recursive.c:1091 +#: merge-recursive.c:1094 msgid "renamed" msgstr "canviat de nom" -#: merge-recursive.c:1147 +#: merge-recursive.c:1150 #, c-format msgid "%s is a directory in %s adding as %s instead" msgstr "%s és un directori en %s; afegint com a %s en lloc" -#: merge-recursive.c:1169 +#: merge-recursive.c:1172 #, c-format msgid "" "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s" @@ -788,147 +811,147 @@ msgstr "" "CONFLICTE (canvi de nom/canvi de nom): Canvi de nom \"%s\"->\"%s\" en la " "branca \"%s\" canvi de nom \"%s\"->\"%s\" en \"%s\"%s" -#: merge-recursive.c:1174 +#: merge-recursive.c:1177 msgid " (left unresolved)" msgstr " (deixat sense resolució)" -#: merge-recursive.c:1228 +#: merge-recursive.c:1231 #, c-format msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" msgstr "" "CONFLICTE (canvi de nom/canvi de nom): Canvi de nom %s->%s en %s. Canvi de " "nom %s->%s en %s" -#: merge-recursive.c:1258 +#: merge-recursive.c:1261 #, c-format msgid "Renaming %s to %s and %s to %s instead" msgstr "Canviant el nom de %s a %s i %s a %s en lloc d'això" -#: merge-recursive.c:1457 +#: merge-recursive.c:1460 #, c-format msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s" msgstr "" "CONFLICTE (canvi de nom/afegiment): Canvi de nom %s->%s en %s. %s afegit en " "%s" -#: merge-recursive.c:1467 +#: merge-recursive.c:1470 #, c-format msgid "Adding merged %s" msgstr "Afegint %s fusionat" -#: merge-recursive.c:1472 merge-recursive.c:1674 +#: merge-recursive.c:1475 merge-recursive.c:1677 #, c-format msgid "Adding as %s instead" msgstr "Afegint com a %s en lloc d'això" -#: merge-recursive.c:1523 +#: merge-recursive.c:1526 #, c-format msgid "cannot read object %s" msgstr "no es pot llegir l'objecte %s" -#: merge-recursive.c:1526 +#: merge-recursive.c:1529 #, c-format msgid "object %s is not a blob" msgstr "L'objecte %s no és un blob" -#: merge-recursive.c:1578 +#: merge-recursive.c:1581 msgid "modify" msgstr "modifica" -#: merge-recursive.c:1578 +#: merge-recursive.c:1581 msgid "modified" msgstr "modificat" -#: merge-recursive.c:1588 +#: merge-recursive.c:1591 msgid "content" msgstr "contingut" -#: merge-recursive.c:1595 +#: merge-recursive.c:1598 msgid "add/add" msgstr "afegiment/afegiment" -#: merge-recursive.c:1629 +#: merge-recursive.c:1632 #, c-format msgid "Skipped %s (merged same as existing)" msgstr "%s saltat (el fusionat és igual a l'existent)" -#: merge-recursive.c:1643 +#: merge-recursive.c:1646 #, c-format msgid "Auto-merging %s" msgstr "Autofusionant %s" -#: merge-recursive.c:1647 git-submodule.sh:1025 +#: merge-recursive.c:1650 git-submodule.sh:1048 msgid "submodule" msgstr "submòdul" -#: merge-recursive.c:1648 +#: merge-recursive.c:1651 #, c-format msgid "CONFLICT (%s): Merge conflict in %s" msgstr "CONFLICTE (%s): Conflicte de fusió en %s" -#: merge-recursive.c:1734 +#: merge-recursive.c:1737 #, c-format msgid "Removing %s" msgstr "Eliminant %s" -#: merge-recursive.c:1759 +#: merge-recursive.c:1762 msgid "file/directory" msgstr "fitxer/directori" -#: merge-recursive.c:1765 +#: merge-recursive.c:1768 msgid "directory/file" msgstr "directori/fitxer" -#: merge-recursive.c:1770 +#: merge-recursive.c:1773 #, c-format msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" msgstr "" "CONFLICTE (%s): Hi ha un directori amb nom %s en %s. Afegint %s com a %s" -#: merge-recursive.c:1780 +#: merge-recursive.c:1783 #, c-format msgid "Adding %s" msgstr "Afegint %s" -#: merge-recursive.c:1797 +#: merge-recursive.c:1800 msgid "Fatal merge failure, shouldn't happen." msgstr "Fallat de fusió fatal; això no ha de passar." -#: merge-recursive.c:1816 +#: merge-recursive.c:1819 msgid "Already up-to-date!" msgstr "Ja al dia!" -#: merge-recursive.c:1825 +#: merge-recursive.c:1828 #, c-format msgid "merging of trees %s and %s failed" msgstr "la fusió dels arbres %s i %s ha fallat" -#: merge-recursive.c:1855 +#: merge-recursive.c:1858 #, c-format msgid "Unprocessed path??? %s" msgstr "Camí no processat??? %s" -#: merge-recursive.c:1903 +#: merge-recursive.c:1906 msgid "Merging:" msgstr "Fusionant:" -#: merge-recursive.c:1916 +#: merge-recursive.c:1919 #, c-format msgid "found %u common ancestor:" msgid_plural "found %u common ancestors:" msgstr[0] "s'ha trobat %u avantpassat:" msgstr[1] "s'han trobat %u avantpassats:" -#: merge-recursive.c:1953 +#: merge-recursive.c:1956 msgid "merge returned no commit" msgstr "la fusió no ha retornat cap comissió" -#: merge-recursive.c:2010 +#: merge-recursive.c:2013 #, c-format msgid "Could not parse object '%s'" msgstr "No s'ha pogut analitzar l'objecte '%s'" -#: merge-recursive.c:2021 builtin/merge.c:645 +#: merge-recursive.c:2024 builtin/merge.c:646 msgid "Unable to write index." msgstr "No s'ha pogut escriure l'índex." @@ -986,7 +1009,7 @@ msgstr "-NUM" #: parse-options-cb.c:108 #, c-format msgid "malformed object name '%s'" -msgstr "nom d'objecte mal format '%s'" +msgstr "nom de camp mal format '%s'" #: path.c:752 #, c-format @@ -1047,12 +1070,12 @@ msgid "%s: pathspec magic not supported by this command: %s" msgstr "" "%s: aquesta ordre no és compatible amb la màgia d'especificació de camí: %s" -#: pathspec.c:432 +#: pathspec.c:433 #, c-format msgid "pathspec '%s' is beyond a symbolic link" msgstr "l'especificació de camí '%s' és més enllà d'un enllaç simbòlic" -#: pathspec.c:441 +#: pathspec.c:442 msgid "" "There is nothing to exclude from by :(exclude) patterns.\n" "Perhaps you forgot to add either ':/' or '.' ?" @@ -1086,164 +1109,249 @@ msgstr "" "GIT_INDEX_VERSION establert, però el valor no és vàlid.\n" "Usant la versió %i" -#: refs.c:543 builtin/merge.c:760 builtin/merge.c:871 builtin/merge.c:973 -#: builtin/merge.c:983 +#: refs.c:543 builtin/merge.c:761 builtin/merge.c:872 builtin/merge.c:974 +#: builtin/merge.c:984 #, c-format msgid "Could not open '%s' for writing" msgstr "No s'ha pogut obrir '%s' per a escriptura" -#: refs/files-backend.c:2359 +#: refs/files-backend.c:2374 #, c-format msgid "could not delete reference %s: %s" msgstr "no s'ha pogut suprimir la referència %s: %s" -#: refs/files-backend.c:2362 +#: refs/files-backend.c:2377 #, c-format msgid "could not delete references: %s" msgstr "no s'ha pogut suprimir les referències: %s" -#: refs/files-backend.c:2371 +#: refs/files-backend.c:2386 #, c-format msgid "could not remove reference %s" msgstr "no s'ha pogut eliminar la referència %s" -#: ref-filter.c:245 +#: ref-filter.c:55 #, c-format -msgid "format: %%(end) atom used without corresponding atom" -msgstr "format: s'ha usat l'àtom %%(end) sense l'àtom corresponent" +msgid "expected format: %%(color:)" +msgstr "format esperat: %%(color:)" + +#: ref-filter.c:57 +#, c-format +msgid "unrecognized color: %%(color:%s)" +msgstr "color no reconegut: %%(color:%s)" + +#: ref-filter.c:71 +#, c-format +msgid "unrecognized format: %%(%s)" +msgstr "format no reconegut: %%(%s)" + +#: ref-filter.c:77 +#, c-format +msgid "%%(body) does not take arguments" +msgstr "%%(body) no accepta paràmetres" -#: ref-filter.c:704 +#: ref-filter.c:84 +#, c-format +msgid "%%(subject) does not take arguments" +msgstr "%%(subject) no accepta paràmetres" + +#: ref-filter.c:101 #, c-format msgid "positive value expected contents:lines=%s" msgstr "valor positiu esperat contents:lines=%s" -#: ref-filter.c:833 +#: ref-filter.c:103 #, c-format -msgid "expected format: %%(color:)" -msgstr "format esperat: %%(color:)" +msgid "unrecognized %%(contents) argument: %s" +msgstr "paràmetre %%(contents) no reconegut: %s" -#: ref-filter.c:835 -msgid "unable to parse format" -msgstr "no s'ha pogut analitzar el format" +#: ref-filter.c:113 +#, c-format +msgid "unrecognized %%(objectname) argument: %s" +msgstr "paràmetre %%(objectname) no reconegut: %s" -#: ref-filter.c:870 +#: ref-filter.c:135 #, c-format msgid "expected format: %%(align:,)" msgstr "format esperat: %%(align:,)" -#: ref-filter.c:893 +#: ref-filter.c:147 +#, c-format +msgid "unrecognized position:%s" +msgstr "posició no reconeguda:%s" + +#: ref-filter.c:151 +#, c-format +msgid "unrecognized width:%s" +msgstr "amplada no reconeguda:%s" + +#: ref-filter.c:157 #, c-format -msgid "improper format entered align:%s" -msgstr "format impropi introduït align:%s" +msgid "unrecognized %%(align) argument: %s" +msgstr "paràmetre %%(align) no reconegut: %s" -#: ref-filter.c:898 +#: ref-filter.c:161 #, c-format msgid "positive width expected with the %%(align) atom" msgstr "amplada positiva esperada amb l'àtom %%(align)" -#: ref-filter.c:1219 +#: ref-filter.c:244 +#, c-format +msgid "malformed field name: %.*s" +msgstr "nom d'objecte mal format: %.*s" + +#: ref-filter.c:270 +#, c-format +msgid "unknown field name: %.*s" +msgstr "nom de camp desconegut: %.*s" + +#: ref-filter.c:372 +#, c-format +msgid "format: %%(end) atom used without corresponding atom" +msgstr "format: s'ha usat l'àtom %%(end) sense l'àtom corresponent" + +#: ref-filter.c:424 +#, c-format +msgid "malformed format string %s" +msgstr "cadena de format mal format %s" + +#: ref-filter.c:878 +msgid ":strip= requires a positive integer argument" +msgstr ":strip= requereix un paràmetre enter positiu" + +#: ref-filter.c:883 +#, c-format +msgid "ref '%s' does not have %ld components to :strip" +msgstr "la referència '%s' no té %ld components per a :strip" + +#: ref-filter.c:1046 +#, c-format +msgid "unknown %.*s format %s" +msgstr "format de %.*s desconegut %s" + +#: ref-filter.c:1066 ref-filter.c:1097 +#, c-format +msgid "missing object %s for %s" +msgstr "manca l'objecte %s per a %s" + +#: ref-filter.c:1069 ref-filter.c:1100 +#, c-format +msgid "parse_object_buffer failed on %s for %s" +msgstr "parse_object_buffer ha fallat en %s per a %s" + +#: ref-filter.c:1311 #, c-format msgid "malformed object at '%s'" msgstr "objecte mal format a '%s'" -#: ref-filter.c:1561 +#: ref-filter.c:1373 +#, c-format +msgid "ignoring ref with broken name %s" +msgstr "ignorant la referència amb nom trencat %s" + +#: ref-filter.c:1378 +#, c-format +msgid "ignoring broken ref %s" +msgstr "ignorant la referència trencada %s" + +#: ref-filter.c:1651 #, c-format msgid "format: %%(end) atom missing" msgstr "format: manca l'àtom %%(end)" -#: ref-filter.c:1615 +#: ref-filter.c:1705 #, c-format msgid "malformed object name %s" msgstr "nom d'objecte %s mal format" -#: remote.c:756 +#: remote.c:745 #, c-format msgid "Cannot fetch both %s and %s to %s" msgstr "No es pot obtenir ambdós %s i %s a %s" -#: remote.c:760 +#: remote.c:749 #, c-format msgid "%s usually tracks %s, not %s" msgstr "%s generalment segueix %s, no %s" -#: remote.c:764 +#: remote.c:753 #, c-format msgid "%s tracks both %s and %s" msgstr "%s segueix ambdós %s i %s" -#: remote.c:772 +#: remote.c:761 msgid "Internal error" msgstr "Error intern" -#: remote.c:1687 remote.c:1730 +#: remote.c:1677 remote.c:1720 msgid "HEAD does not point to a branch" msgstr "HEAD no assenyala cap branca" -#: remote.c:1696 +#: remote.c:1686 #, c-format msgid "no such branch: '%s'" msgstr "no hi ha tal branca: '%s'" -#: remote.c:1699 +#: remote.c:1689 #, c-format msgid "no upstream configured for branch '%s'" msgstr "cap font configurada per a la branca '%s'" -#: remote.c:1705 +#: remote.c:1695 #, c-format msgid "upstream branch '%s' not stored as a remote-tracking branch" msgstr "La branca font '%s' no s'emmagatzema com a branca amb seguiment remot" -#: remote.c:1720 +#: remote.c:1710 #, c-format msgid "push destination '%s' on remote '%s' has no local tracking branch" msgstr "" "el destí de pujada '%s' en el remot '%s' no té cap branca seguidora local" -#: remote.c:1735 +#: remote.c:1725 #, c-format msgid "branch '%s' has no remote for pushing" msgstr "la branca '%s' no té cap remot al qual pujar" -#: remote.c:1746 +#: remote.c:1736 #, c-format msgid "push refspecs for '%s' do not include '%s'" msgstr "les especificacions de referència de '%s' no inclouen '%s'" -#: remote.c:1759 +#: remote.c:1749 msgid "push has no destination (push.default is 'nothing')" msgstr "push no té destí (push.default és 'nothing')" -#: remote.c:1781 +#: remote.c:1771 msgid "cannot resolve 'simple' push to a single destination" msgstr "no es pot resoldre una pujada 'simple' a un sol destí" -#: remote.c:2083 +#: remote.c:2073 #, c-format msgid "Your branch is based on '%s', but the upstream is gone.\n" msgstr "La vostra branca està basada en '%s', però la font no hi és.\n" -#: remote.c:2087 +#: remote.c:2077 msgid " (use \"git branch --unset-upstream\" to fixup)\n" msgstr " (useu \"git branch --unset-upstream\" per a arreglar)\n" -#: remote.c:2090 +#: remote.c:2080 #, c-format msgid "Your branch is up-to-date with '%s'.\n" msgstr "La vostra branca està al dia amb '%s'.\n" -#: remote.c:2094 +#: remote.c:2084 #, 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] "La vostra branca està davant de '%s' per %d comissió.\n" msgstr[1] "La vostra branca està davant de '%s' per %d comissions.\n" -#: remote.c:2100 +#: remote.c:2090 msgid " (use \"git push\" to publish your local commits)\n" msgstr " (useu \"git push\" per a publicar les vostres comissions locals)\n" -#: remote.c:2103 +#: remote.c:2093 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -1255,11 +1363,11 @@ msgstr[1] "" "La vostra branca està darrere de '%s' per %d comissions, i pot avançar-se " "ràpidament.\n" -#: remote.c:2111 +#: remote.c:2101 msgid " (use \"git pull\" to update your local branch)\n" msgstr " (useu \"git pull\" per a actualitzar la vostra branca local)\n" -#: remote.c:2114 +#: remote.c:2104 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -1274,28 +1382,28 @@ msgstr[1] "" "La vostra branca i '%s' s'han divergit,\n" "i tenen %d i %d comissions distintes cada una, respectivament.\n" -#: remote.c:2124 +#: remote.c:2114 msgid " (use \"git pull\" to merge the remote branch into yours)\n" msgstr " (useu \"git pull\" per a fusionar la branca remota a la vostra)\n" -#: revision.c:2193 +#: revision.c:2131 msgid "your current branch appears to be broken" msgstr "la vostra branca actual sembla trencada" -#: revision.c:2196 +#: revision.c:2134 #, c-format msgid "your current branch '%s' does not have any commits yet" msgstr "la vostra branca actual '%s' encara no té cap comissió" -#: revision.c:2390 +#: revision.c:2328 msgid "--first-parent is incompatible with --bisect" msgstr "--first-parent és incompatible amb --bisect" -#: run-command.c:90 +#: run-command.c:92 msgid "open /dev/null failed" msgstr "s'ha fallat en obrir /dev/null" -#: run-command.c:92 +#: run-command.c:94 #, c-format msgid "dup2(%d,%d) failed" msgstr "dup2(%d,%d) ha fallat" @@ -1320,7 +1428,7 @@ msgstr "" msgid "the receiving end does not support --atomic push" msgstr "el destí receptor no admet pujar --atomic" -#: sequencer.c:183 +#: sequencer.c:174 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add ' or 'git rm '" @@ -1328,7 +1436,7 @@ msgstr "" "després de resoldre els conflictes, marqueu els camins\n" "corregits amb 'git add ' o 'git rm '" -#: sequencer.c:186 +#: sequencer.c:177 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add ' or 'git rm '\n" @@ -1338,67 +1446,67 @@ msgstr "" "corregits amb 'git add ' o 'git rm '\n" "i cometeu el resultat amb 'git commit'" -#: sequencer.c:199 sequencer.c:842 sequencer.c:922 +#: sequencer.c:190 sequencer.c:833 sequencer.c:913 #, c-format msgid "Could not write to %s" msgstr "No s'ha pogut escriure a %s" -#: sequencer.c:202 +#: sequencer.c:193 #, c-format msgid "Error wrapping up %s" msgstr "Error en finalitzar %s" -#: sequencer.c:217 +#: sequencer.c:208 msgid "Your local changes would be overwritten by cherry-pick." msgstr "Els vostres canvis locals se sobreescriurien pel recull de cireres." -#: sequencer.c:219 +#: sequencer.c:210 msgid "Your local changes would be overwritten by revert." msgstr "Els vostres canvis locals se sobreescriurien per la reversió." -#: sequencer.c:222 +#: sequencer.c:213 msgid "Commit your changes or stash them to proceed." msgstr "Cometeu els vostres canvis o emmagatzemeu-los per a procedir." #. TRANSLATORS: %s will be "revert" or "cherry-pick" -#: sequencer.c:309 +#: sequencer.c:300 #, c-format msgid "%s: Unable to write new index file" msgstr "%s: No s'ha pogut escriure un fitxer d'índex nou" -#: sequencer.c:327 +#: sequencer.c:318 msgid "Could not resolve HEAD commit\n" msgstr "No s'ha pogut resoldre la comissió HEAD\n" -#: sequencer.c:347 +#: sequencer.c:338 msgid "Unable to update cache tree\n" msgstr "No s'ha pogut actualitzar l'arbre cau\n" -#: sequencer.c:399 +#: sequencer.c:390 #, c-format msgid "Could not parse commit %s\n" msgstr "No s'ha pogut analitzar la comissió %s\n" -#: sequencer.c:404 +#: sequencer.c:395 #, c-format msgid "Could not parse parent commit %s\n" msgstr "No s'ha pogut analitzar la comissió mare %s\n" -#: sequencer.c:469 +#: sequencer.c:460 msgid "Your index file is unmerged." msgstr "El vostre fitxer d'índex està sense fusionar." -#: sequencer.c:488 +#: sequencer.c:479 #, c-format msgid "Commit %s is a merge but no -m option was given." msgstr "La comissió %s és una fusió però no s'ha donat cap opció -m." -#: sequencer.c:496 +#: sequencer.c:487 #, c-format msgid "Commit %s does not have parent %d" msgstr "La comissió %s no té mare %d" -#: sequencer.c:500 +#: sequencer.c:491 #, c-format msgid "Mainline was specified but commit %s is not a merge." msgstr "" @@ -1406,162 +1514,178 @@ msgstr "" #. TRANSLATORS: The first %s will be "revert" or #. "cherry-pick", the second %s a SHA1 -#: sequencer.c:513 +#: sequencer.c:504 #, c-format msgid "%s: cannot parse parent commit %s" msgstr "%s: no es pot analitzar la comissió mare %s" -#: sequencer.c:517 +#: sequencer.c:508 #, c-format msgid "Cannot get commit message for %s" msgstr "No es pot obtenir el missatge de comissió de %s" -#: sequencer.c:603 +#: sequencer.c:594 #, c-format msgid "could not revert %s... %s" msgstr "no s'ha pogut revertir %s...%s" -#: sequencer.c:604 +#: sequencer.c:595 #, c-format msgid "could not apply %s... %s" msgstr "no s'ha pogut aplicar %s...%s" -#: sequencer.c:639 +#: sequencer.c:630 msgid "empty commit set passed" msgstr "conjunt de comissions buit passat" -#: sequencer.c:647 +#: sequencer.c:638 #, c-format msgid "git %s: failed to read the index" msgstr "git %s: s'ha fallat en llegir l'índex" -#: sequencer.c:651 +#: sequencer.c:642 #, c-format msgid "git %s: failed to refresh the index" msgstr "git %s: s'ha fallat en actualitzar l'índex" -#: sequencer.c:711 +#: sequencer.c:702 #, c-format msgid "Cannot %s during a %s" msgstr "No es pot %s durant un %s" -#: sequencer.c:733 +#: sequencer.c:724 #, c-format msgid "Could not parse line %d." msgstr "No s'ha pogut analitzar la línia %d." -#: sequencer.c:738 +#: sequencer.c:729 msgid "No commits parsed." msgstr "Cap comissió analitzada." -#: sequencer.c:750 +#: sequencer.c:741 #, c-format msgid "Could not open %s" msgstr "No s'ha pogut obrir %s" -#: sequencer.c:754 +#: sequencer.c:745 #, c-format msgid "Could not read %s." msgstr "No s'ha pogut llegir %s." -#: sequencer.c:761 +#: sequencer.c:752 #, c-format msgid "Unusable instruction sheet: %s" msgstr "Full d'instruccions inusable: %s" -#: sequencer.c:791 +#: sequencer.c:782 #, c-format msgid "Invalid key: %s" msgstr "Clau no vàlida: %s" -#: sequencer.c:794 builtin/pull.c:47 builtin/pull.c:49 +#: sequencer.c:785 builtin/pull.c:50 builtin/pull.c:52 #, c-format msgid "Invalid value for %s: %s" msgstr "Valor no vàlid per a %s: %s" -#: sequencer.c:804 +#: sequencer.c:795 #, c-format msgid "Malformed options sheet: %s" msgstr "Full d'opcions mal format: %s" -#: sequencer.c:823 +#: sequencer.c:814 msgid "a cherry-pick or revert is already in progress" msgstr "un recull de cireres o una reversió ja està en curs" -#: sequencer.c:824 +#: sequencer.c:815 msgid "try \"git cherry-pick (--continue | --quit | --abort)\"" msgstr "intenteu \"git cherry-pick (--continue | --quit | --abort)\"" -#: sequencer.c:828 +#: sequencer.c:819 #, c-format msgid "Could not create sequencer directory %s" msgstr "No s'ha pogut crear el directori de seqüenciador %s" -#: sequencer.c:844 sequencer.c:926 +#: sequencer.c:835 sequencer.c:917 #, c-format msgid "Error wrapping up %s." msgstr "Error en finalitzar %s." -#: sequencer.c:863 sequencer.c:996 +#: sequencer.c:854 sequencer.c:987 msgid "no cherry-pick or revert in progress" msgstr "ni hi ha cap recull de cireres ni cap reversió en curs" -#: sequencer.c:865 +#: sequencer.c:856 msgid "cannot resolve HEAD" msgstr "no es pot resoldre HEAD" -#: sequencer.c:867 +#: sequencer.c:858 msgid "cannot abort from a branch yet to be born" msgstr "no es pot avortar des d'una branca que encara ha de nàixer" -#: sequencer.c:887 builtin/apply.c:4287 +#: sequencer.c:878 builtin/apply.c:4287 #, c-format msgid "cannot open %s: %s" msgstr "no es pot obrir %s: %s" -#: sequencer.c:890 +#: sequencer.c:881 #, c-format msgid "cannot read %s: %s" msgstr "no es pot llegir %s: %s" -#: sequencer.c:891 +#: sequencer.c:882 msgid "unexpected end of file" msgstr "final de fitxer inesperat" -#: sequencer.c:897 +#: sequencer.c:888 #, c-format msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" msgstr "el fitxer HEAD emmagatzemat abans del recull de cireres '%s' és malmès" -#: sequencer.c:919 +#: sequencer.c:910 #, c-format msgid "Could not format %s." msgstr "No s'ha pogut formatar %s." -#: sequencer.c:1064 +#: sequencer.c:1055 #, c-format msgid "%s: can't cherry-pick a %s" msgstr "%s: no es pot recollir com a cirera un %s" -#: sequencer.c:1067 +#: sequencer.c:1058 #, c-format msgid "%s: bad revision" msgstr "%s: revisió dolenta" -#: sequencer.c:1101 +#: sequencer.c:1092 msgid "Can't revert as initial commit" msgstr "No es pot revertir com a comissió inicial" -#: sequencer.c:1102 +#: sequencer.c:1093 msgid "Can't cherry-pick into empty head" msgstr "No es pot recollir cireres en un cap buit" -#: setup.c:248 +#: setup.c:246 #, c-format msgid "failed to read %s" msgstr "s'ha fallat en llegir %s" -#: sha1_name.c:463 +#: sha1_file.c:1080 +msgid "offset before end of packfile (broken .idx?)" +msgstr "desplaçament abans de la fi del fitxer de paquet (.idx trencat?)" + +#: sha1_file.c:2459 +#, c-format +msgid "offset before start of pack index for %s (corrupt index?)" +msgstr "" +"desplaçament abans d'inici d'índex de paquet per a %s (índex corromput?)" + +#: sha1_file.c:2463 +#, c-format +msgid "offset beyond end of pack index for %s (truncated index?)" +msgstr "" +"desplaçament més enllà de la fi d'índex de paquet per a %s (índex truncat?)" + +#: sha1_name.c:462 msgid "" "Git normally never creates a ref that ends with 40 hex characters\n" "because it will be ignored when you just specify 40-hex. These refs\n" @@ -1585,62 +1709,86 @@ msgstr "" "suprimiu-les. Desactiveu aquest missatge executant\n" "\"git config advice.objectNameWarning false\"" -#: submodule.c:61 submodule.c:95 +#: submodule.c:62 submodule.c:96 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first" msgstr "" "No es pot canviar un .gitmodules no fusionat, primer resoldreu els " "conflictes de fusió" -#: submodule.c:65 submodule.c:99 +#: submodule.c:66 submodule.c:100 #, c-format msgid "Could not find section in .gitmodules where path=%s" msgstr "No s'ha pogut trobar la secció en .gitmodules on path=%s" -#: submodule.c:73 +#: submodule.c:74 #, c-format msgid "Could not update .gitmodules entry %s" msgstr "No s'ha pogut actualitzar l'entrada de .gitmodules %s" -#: submodule.c:106 +#: submodule.c:107 #, c-format msgid "Could not remove .gitmodules entry for %s" msgstr "No s'ha pogut eliminar l'entrada de .gitmodules per a %s" -#: submodule.c:117 +#: submodule.c:118 msgid "staging updated .gitmodules failed" msgstr "L'allistament del .gitmodules actualitzat ha fallat" -#: submodule.c:1040 +#: trailer.c:237 #, c-format -msgid "Could not set core.worktree in %s" -msgstr "No s'ha pogut establir core.worktree en %s" +msgid "running trailer command '%s' failed" +msgstr "l'execució de l'ordre de remolc '%s' ha fallat" -#: trailer.c:491 trailer.c:495 trailer.c:499 trailer.c:553 trailer.c:557 -#: trailer.c:561 +#: trailer.c:492 trailer.c:496 trailer.c:500 trailer.c:554 trailer.c:558 +#: trailer.c:562 #, c-format msgid "unknown value '%s' for key '%s'" msgstr "valor desconegut '%s' per a la clau '%s'" -#: trailer.c:543 trailer.c:548 builtin/remote.c:296 +#: trailer.c:544 trailer.c:549 builtin/remote.c:289 #, c-format msgid "more than one %s" msgstr "més d'un %s" -#: trailer.c:581 +#: trailer.c:582 #, c-format msgid "empty trailer token in trailer '%.*s'" msgstr "fitxa de remolc buida en el remolc '%.*s'" -#: trailer.c:701 +#: trailer.c:702 #, c-format msgid "could not read input file '%s'" msgstr "no s'ha pogut llegir el fitxer d'entrada '%s'" -#: trailer.c:704 +#: trailer.c:705 msgid "could not read from stdin" msgstr "No s'ha pogut llegir des d'stdin" -#: transport-helper.c:1025 +#: trailer.c:857 builtin/am.c:42 +#, c-format +msgid "could not stat %s" +msgstr "no s'ha pogut fer stat a %s" + +#: trailer.c:859 +#, c-format +msgid "file %s is not a regular file" +msgstr "el fitxer %s no és un fitxer regular" + +#: trailer.c:861 +#, c-format +msgid "file %s is not writable by user" +msgstr "el fitxer %s no és gravable per l'usuari" + +#: trailer.c:873 +msgid "could not open temporary file" +msgstr "no s'ha pogut obrir el fitxer temporal" + +#: trailer.c:912 +#, c-format +msgid "could not rename temporary file to %s" +msgstr "no s'ha pogut canviar el nom del fitxer temporal a %s" + +#: transport-helper.c:1041 #, c-format msgid "Could not read ref %s" msgstr "No s'ha pogut llegir la referència %s" @@ -1678,47 +1826,47 @@ msgstr "número de port no vàlid" msgid "invalid '..' path segment" msgstr "segment de camí '..' no vàlid" -#: wrapper.c:219 wrapper.c:362 +#: wrapper.c:222 wrapper.c:381 #, c-format msgid "could not open '%s' for reading and writing" msgstr "no s'ha pogut obrir '%s' per a lectura i escriptura" -#: wrapper.c:221 wrapper.c:364 +#: wrapper.c:224 wrapper.c:383 #, c-format msgid "could not open '%s' for writing" msgstr "no s'ha pogut obrir '%s' per a escriptura" -#: wrapper.c:223 wrapper.c:366 builtin/am.c:338 builtin/commit.c:1691 -#: builtin/merge.c:1074 builtin/pull.c:380 +#: wrapper.c:226 wrapper.c:385 builtin/am.c:323 builtin/commit.c:1691 +#: builtin/merge.c:1075 builtin/pull.c:387 #, c-format msgid "could not open '%s' for reading" msgstr "no s'ha pogut obrir '%s' per a lectura" -#: wrapper.c:579 +#: wrapper.c:611 #, c-format msgid "unable to access '%s': %s" msgstr "no s'ha pogut accedir a '%s': %s" -#: wrapper.c:600 +#: wrapper.c:632 #, c-format msgid "unable to access '%s'" msgstr "no s'ha pogut accedir a '%s'" -#: wrapper.c:608 +#: wrapper.c:640 msgid "unable to get current working directory" msgstr "no s'ha pogut obtenir el directori de treball actual" -#: wrapper.c:635 +#: wrapper.c:667 #, c-format msgid "could not open %s for writing" msgstr "no s'ha pogut obrir '%s' per a escriptura" -#: wrapper.c:646 builtin/am.c:425 +#: wrapper.c:678 builtin/am.c:410 #, c-format msgid "could not write to %s" msgstr "no s'ha pogut escriure a %s" -#: wrapper.c:652 +#: wrapper.c:684 #, c-format msgid "could not close %s" msgstr "no s'ha pogut tancar %s" @@ -2189,7 +2337,11 @@ msgstr "no hi és" msgid "behind " msgstr "darrere " -#: compat/precompose_utf8.c:56 builtin/clone.c:408 +#: wt-status.c:1680 wt-status.c:1683 +msgid "ahead " +msgstr "davant per " + +#: compat/precompose_utf8.c:57 builtin/clone.c:413 #, c-format msgid "failed to unlink '%s'" msgstr "s'ha fallat en desenllaçar '%s'" @@ -2216,7 +2368,7 @@ msgstr "elimina '%s'\n" msgid "Unstaged changes after refreshing the index:" msgstr "Canvis no allistats després d'actualitzar l'índex:" -#: builtin/add.c:194 builtin/rev-parse.c:796 +#: builtin/add.c:194 builtin/rev-parse.c:797 msgid "Could not read the index" msgstr "No s'ha pogut llegir l'índex" @@ -2252,15 +2404,15 @@ msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" "Els camins següents s'ignoren per un dels vostres fitxers .gitignore:\n" -#: builtin/add.c:249 builtin/clean.c:894 builtin/fetch.c:108 builtin/mv.c:110 -#: builtin/prune-packed.c:55 builtin/pull.c:182 builtin/push.c:543 -#: builtin/remote.c:1345 builtin/rm.c:268 builtin/send-pack.c:162 +#: builtin/add.c:249 builtin/clean.c:870 builtin/fetch.c:112 builtin/mv.c:111 +#: builtin/prune-packed.c:55 builtin/pull.c:189 builtin/push.c:511 +#: builtin/remote.c:1330 builtin/rm.c:268 builtin/send-pack.c:162 msgid "dry run" msgstr "marxa en sec" -#: builtin/add.c:250 builtin/apply.c:4571 builtin/check-ignore.c:19 +#: builtin/add.c:250 builtin/apply.c:4561 builtin/check-ignore.c:19 #: builtin/commit.c:1322 builtin/count-objects.c:85 builtin/fsck.c:558 -#: builtin/log.c:1645 builtin/mv.c:109 builtin/read-tree.c:114 +#: builtin/log.c:1651 builtin/mv.c:110 builtin/read-tree.c:114 msgid "be verbose" msgstr "sigues detallat" @@ -2268,7 +2420,7 @@ msgstr "sigues detallat" msgid "interactive picking" msgstr "recull interactiu" -#: builtin/add.c:253 builtin/checkout.c:1153 builtin/reset.c:286 +#: builtin/add.c:253 builtin/checkout.c:1155 builtin/reset.c:286 msgid "select hunks interactively" msgstr "selecciona els trossos interactivament" @@ -2337,139 +2489,134 @@ msgstr "Res especificat, res afegit.\n" msgid "Maybe you wanted to say 'git add .'?\n" msgstr "Potser volíeu dir 'git add .'?\n" -#: builtin/add.c:358 builtin/check-ignore.c:172 builtin/clean.c:938 -#: builtin/commit.c:337 builtin/mv.c:130 builtin/reset.c:235 builtin/rm.c:298 -#: builtin/submodule--helper.c:40 +#: builtin/add.c:358 builtin/check-ignore.c:172 builtin/clean.c:914 +#: builtin/commit.c:337 builtin/mv.c:131 builtin/reset.c:235 builtin/rm.c:298 +#: builtin/submodule--helper.c:35 msgid "index file corrupt" msgstr "fitxer d'índex malmès" -#: builtin/add.c:439 builtin/apply.c:4669 builtin/mv.c:279 builtin/rm.c:430 +#: builtin/add.c:439 builtin/apply.c:4659 builtin/mv.c:280 builtin/rm.c:430 msgid "Unable to write new index file" msgstr "no s'ha pogut escriure un fitxer d'índex nou" -#: builtin/am.c:42 -#, c-format -msgid "could not stat %s" -msgstr "no s'ha pogut fer stat a '%s'" - -#: builtin/am.c:271 builtin/commit.c:738 builtin/merge.c:1077 +#: builtin/am.c:256 builtin/commit.c:738 builtin/merge.c:1078 #, c-format msgid "could not read '%s'" msgstr "no s'ha pogut llegir '%s'" -#: builtin/am.c:445 +#: builtin/am.c:430 msgid "could not parse author script" msgstr "no s'ha pogut analitzar l'script d'autor" -#: builtin/am.c:522 +#: builtin/am.c:507 #, c-format msgid "'%s' was deleted by the applypatch-msg hook" msgstr "s'ha suprimit '%s' per el ganxo applypatch-msg" -#: builtin/am.c:563 builtin/notes.c:300 +#: builtin/am.c:548 builtin/notes.c:300 #, c-format msgid "Malformed input line: '%s'." msgstr "Línia d'entrada mal formada: '%s'." -#: builtin/am.c:600 builtin/notes.c:315 +#: builtin/am.c:585 builtin/notes.c:315 #, c-format msgid "Failed to copy notes from '%s' to '%s'" msgstr "S'ha fallat en copiar les notes de '%s' a '%s'" -#: builtin/am.c:626 +#: builtin/am.c:611 msgid "fseek failed" msgstr "fseek ha fallat" -#: builtin/am.c:787 builtin/am.c:875 +#: builtin/am.c:772 builtin/am.c:860 #, c-format msgid "could not open '%s' for reading: %s" msgstr "no s'ha pogut obrir '%s' per a lectura: %s" -#: builtin/am.c:794 +#: builtin/am.c:779 #, c-format msgid "could not open '%s' for writing: %s" msgstr "no s'ha pogut obrir '%s' per a escriptura: %s" -#: builtin/am.c:803 +#: builtin/am.c:788 #, c-format msgid "could not parse patch '%s'" msgstr "no s'ha pogut analitzar el pedaç '%s'" -#: builtin/am.c:868 +#: builtin/am.c:853 msgid "Only one StGIT patch series can be applied at once" msgstr "només una sèrie de pedaços StGIT es pot aplicar a la vegada" -#: builtin/am.c:916 +#: builtin/am.c:901 msgid "invalid timestamp" msgstr "marca de temps no vàlida" -#: builtin/am.c:919 builtin/am.c:927 +#: builtin/am.c:904 builtin/am.c:912 msgid "invalid Date line" msgstr "línia Date no vàlida" -#: builtin/am.c:924 +#: builtin/am.c:909 msgid "invalid timezone offset" msgstr "desplaçament de zona de temps no vàlid" -#: builtin/am.c:1011 +#: builtin/am.c:996 msgid "Patch format detection failed." msgstr "La detecció de format de pedaç ha fallat." -#: builtin/am.c:1016 builtin/clone.c:373 +#: builtin/am.c:1001 builtin/clone.c:378 #, c-format msgid "failed to create directory '%s'" msgstr "s'ha fallat en crear el directori '%s'" -#: builtin/am.c:1020 +#: builtin/am.c:1005 msgid "Failed to split patches." msgstr "S'ha fallat en dividir els pedaços." -#: builtin/am.c:1152 builtin/commit.c:363 +#: builtin/am.c:1137 builtin/commit.c:363 msgid "unable to write index file" msgstr "no s'ha pogut escriure el fitxer d'índex" -#: builtin/am.c:1203 +#: builtin/am.c:1188 #, c-format msgid "When you have resolved this problem, run \"%s --continue\"." msgstr "Quan hàgiu resolt aquest problema, executeu \"%s --continue\"." -#: builtin/am.c:1204 +#: builtin/am.c:1189 #, c-format msgid "If you prefer to skip this patch, run \"%s --skip\" instead." msgstr "Si preferiu saltar aquest pedaç, executeu \"%s --skip\" en lloc." -#: builtin/am.c:1205 +#: builtin/am.c:1190 #, c-format msgid "To restore the original branch and stop patching, run \"%s --abort\"." msgstr "" "Per a restaurar la branca original i deixar d'apedaçar, executeu \"%s --abort" "\"." -#: builtin/am.c:1343 +#: builtin/am.c:1328 msgid "Patch is empty. Was it split wrong?" msgstr "El pedaç és buit. S'ha dividit malament?" -#: builtin/am.c:1417 builtin/log.c:1347 +#: builtin/am.c:1402 builtin/log.c:1350 #, c-format msgid "invalid ident line: %s" msgstr "línia d'identitat no vàlida: %s" -#: builtin/am.c:1444 +#: builtin/am.c:1429 #, c-format msgid "unable to parse commit %s" msgstr "no s'ha pogut analitzar la comissió %s" -#: builtin/am.c:1646 +#: builtin/am.c:1631 msgid "Repository lacks necessary blobs to fall back on 3-way merge." msgstr "" "Al dipòsit li manquen els blobs necessaris per a retrocedir a una fusió de 3 " "vies." -#: builtin/am.c:1648 +#: builtin/am.c:1633 msgid "Using index info to reconstruct a base tree..." msgstr "Usant la informació d'índex per a reconstruir un arbre base..." -#: builtin/am.c:1667 +#: builtin/am.c:1652 msgid "" "Did you hand edit your patch?\n" "It does not apply to blobs recorded in its index." @@ -2477,38 +2624,38 @@ msgstr "" "Heu editat el vostre pedaç a mà?\n" "No s'aplica als blobs recordats en el seu índex." -#: builtin/am.c:1673 +#: builtin/am.c:1658 msgid "Falling back to patching base and 3-way merge..." msgstr "Retrocedint a apedaçar la base i fusionar de 3 vies..." -#: builtin/am.c:1688 +#: builtin/am.c:1673 msgid "Failed to merge in the changes." msgstr "S'ha fallat en fusionar els canvis." -#: builtin/am.c:1712 builtin/merge.c:632 +#: builtin/am.c:1697 builtin/merge.c:633 msgid "git write-tree failed to write a tree" msgstr "git write-tree ha fallat en escriure un arbre" -#: builtin/am.c:1719 +#: builtin/am.c:1704 msgid "applying to an empty history" msgstr "aplicant a una història buida" -#: builtin/am.c:1732 builtin/commit.c:1755 builtin/merge.c:829 -#: builtin/merge.c:854 +#: builtin/am.c:1717 builtin/commit.c:1755 builtin/merge.c:830 +#: builtin/merge.c:855 msgid "failed to write commit object" msgstr "s'ha fallat en escriure l'objecte de comissió" -#: builtin/am.c:1764 builtin/am.c:1768 +#: builtin/am.c:1749 builtin/am.c:1753 #, c-format msgid "cannot resume: %s does not exist." msgstr "no es pot reprendre: %s no existeix." -#: builtin/am.c:1784 +#: builtin/am.c:1769 msgid "cannot be interactive without stdin connected to a terminal." msgstr "" "no es pot ser interactiu sense que stdin sigui connectat a un terminal." -#: builtin/am.c:1789 +#: builtin/am.c:1774 msgid "Commit Body is:" msgstr "El cos de la comissió és:" @@ -2516,37 +2663,37 @@ msgstr "El cos de la comissió és:" #. in your translation. The program will only accept English #. input at this point. #. -#: builtin/am.c:1799 +#: builtin/am.c:1784 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: " msgstr "" "Voleu aplicar-lo? [y]es/[n]o/[e]dita/[v]isualitza el pedaç/[a]ccepta'ls " "tots: " -#: builtin/am.c:1849 +#: builtin/am.c:1834 #, c-format msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Índex brut: no es pot aplicar pedaços (bruts: %s)" -#: builtin/am.c:1884 builtin/am.c:1955 +#: builtin/am.c:1869 builtin/am.c:1941 #, c-format msgid "Applying: %.*s" msgstr "Aplicant: %.*s" -#: builtin/am.c:1900 +#: builtin/am.c:1885 msgid "No changes -- Patch already applied." msgstr "Sense canvis -- El pedaç ja s'ha aplicat." -#: builtin/am.c:1908 +#: builtin/am.c:1893 #, c-format msgid "Patch failed at %s %.*s" msgstr "El pedaç ha fallat a %s %.*s" -#: builtin/am.c:1914 +#: builtin/am.c:1899 #, c-format msgid "The copy of the patch that failed is found in: %s" msgstr "La còpia del pedaç que ha fallat es troba en: %s" -#: builtin/am.c:1958 +#: builtin/am.c:1944 msgid "" "No changes - did you forget to use 'git add'?\n" "If there is nothing left to stage, chances are that something else\n" @@ -2556,7 +2703,7 @@ msgstr "" "Si no hi ha res a allistar, probablement alguna altra cosa\n" "ja ha introduït els mateixos canvis; potser voleu ometre aquest pedaç." -#: builtin/am.c:1965 +#: builtin/am.c:1951 msgid "" "You still have unmerged paths in your index.\n" "Did you forget to use 'git add'?" @@ -2564,17 +2711,17 @@ msgstr "" "Encara teniu camins sense fusionar en el vostre índex.\n" "Heu oblidat d'usar 'git add'?" -#: builtin/am.c:2073 builtin/am.c:2077 builtin/am.c:2089 builtin/reset.c:308 +#: builtin/am.c:2059 builtin/am.c:2063 builtin/am.c:2075 builtin/reset.c:308 #: builtin/reset.c:316 #, c-format msgid "Could not parse object '%s'." msgstr "No s'ha pogut analitzar l'objecte '%s'." -#: builtin/am.c:2125 +#: builtin/am.c:2111 msgid "failed to clean index" msgstr "s'ha fallat en netejar l'índex" -#: builtin/am.c:2159 +#: builtin/am.c:2145 msgid "" "You seem to have moved HEAD since the last 'am' failure.\n" "Not rewinding to ORIG_HEAD" @@ -2582,154 +2729,154 @@ msgstr "" "Sembla que heu mogut HEAD després de l'última fallada de 'am'.\n" "No rebobinant a ORIG_HEAD" -#: builtin/am.c:2220 +#: builtin/am.c:2206 #, c-format msgid "Invalid value for --patch-format: %s" msgstr "Valor no vàlid per a --patch-format: %s" -#: builtin/am.c:2253 +#: builtin/am.c:2239 msgid "git am [] [(|)...]" msgstr "git am [] [(|)...]" -#: builtin/am.c:2254 +#: builtin/am.c:2240 msgid "git am [] (--continue | --skip | --abort)" msgstr "git am [] (--continue | --skip | --abort)" -#: builtin/am.c:2260 +#: builtin/am.c:2246 msgid "run interactively" msgstr "executa interactivament" -#: builtin/am.c:2262 +#: builtin/am.c:2248 msgid "historical option -- no-op" msgstr "opció històrica -- no-op" -#: builtin/am.c:2264 +#: builtin/am.c:2250 msgid "allow fall back on 3way merging if needed" msgstr "permet retrocedir a una fusió de 3 vies si és necessari" -#: builtin/am.c:2265 builtin/init-db.c:474 builtin/prune-packed.c:57 +#: builtin/am.c:2251 builtin/init-db.c:474 builtin/prune-packed.c:57 #: builtin/repack.c:171 msgid "be quiet" msgstr "calla" -#: builtin/am.c:2267 +#: builtin/am.c:2253 msgid "add a Signed-off-by line to the commit message" msgstr "afegeix una línia Signed-off-by al missatge de comissió" -#: builtin/am.c:2270 +#: builtin/am.c:2256 msgid "recode into utf8 (default)" msgstr "recodifica en utf8 (per defecte)" -#: builtin/am.c:2272 +#: builtin/am.c:2258 msgid "pass -k flag to git-mailinfo" msgstr "passa la bandera -k al git-mailinfo" -#: builtin/am.c:2274 +#: builtin/am.c:2260 msgid "pass -b flag to git-mailinfo" msgstr "passa la bandera -b al git-mailinfo" -#: builtin/am.c:2276 +#: builtin/am.c:2262 msgid "pass -m flag to git-mailinfo" msgstr "passa la bandera -m al git-mailinfo" -#: builtin/am.c:2278 +#: builtin/am.c:2264 msgid "pass --keep-cr flag to git-mailsplit for mbox format" msgstr "passa la bandera --keep-cr al git-mailsplit pel format mbox" -#: builtin/am.c:2281 +#: builtin/am.c:2267 msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr" msgstr "" "no passis la bandera --keep-cr al git-mailsplit independent de am.keepcr" -#: builtin/am.c:2284 +#: builtin/am.c:2270 msgid "strip everything before a scissors line" msgstr "despulla tot abans d'una línia de tissores" -#: builtin/am.c:2285 builtin/apply.c:4554 +#: builtin/am.c:2271 builtin/apply.c:4544 msgid "action" msgstr "acció" -#: builtin/am.c:2286 builtin/am.c:2289 builtin/am.c:2292 builtin/am.c:2295 -#: builtin/am.c:2298 builtin/am.c:2301 builtin/am.c:2304 builtin/am.c:2307 -#: builtin/am.c:2313 +#: builtin/am.c:2272 builtin/am.c:2275 builtin/am.c:2278 builtin/am.c:2281 +#: builtin/am.c:2284 builtin/am.c:2287 builtin/am.c:2290 builtin/am.c:2293 +#: builtin/am.c:2299 msgid "pass it through git-apply" msgstr "passa-ho a través del git-apply" -#: builtin/am.c:2294 builtin/apply.c:4578 +#: builtin/am.c:2280 builtin/apply.c:4568 msgid "root" msgstr "arrel" -#: builtin/am.c:2297 builtin/am.c:2300 builtin/apply.c:4516 -#: builtin/apply.c:4519 builtin/clone.c:85 builtin/fetch.c:93 -#: builtin/pull.c:167 builtin/submodule--helper.c:78 -#: builtin/submodule--helper.c:166 builtin/submodule--helper.c:169 +#: builtin/am.c:2283 builtin/am.c:2286 builtin/apply.c:4506 +#: builtin/apply.c:4509 builtin/clone.c:86 builtin/fetch.c:95 +#: builtin/pull.c:171 builtin/submodule--helper.c:72 +#: builtin/submodule--helper.c:160 builtin/submodule--helper.c:163 msgid "path" msgstr "camí" -#: builtin/am.c:2303 builtin/fmt-merge-msg.c:666 builtin/fmt-merge-msg.c:669 -#: builtin/grep.c:693 builtin/merge.c:198 builtin/pull.c:127 +#: builtin/am.c:2289 builtin/fmt-merge-msg.c:666 builtin/fmt-merge-msg.c:669 +#: builtin/grep.c:704 builtin/merge.c:198 builtin/pull.c:131 builtin/pull.c:185 #: builtin/repack.c:178 builtin/repack.c:182 builtin/show-branch.c:645 #: builtin/show-ref.c:175 builtin/tag.c:340 parse-options.h:132 #: parse-options.h:134 parse-options.h:244 msgid "n" msgstr "n" -#: builtin/am.c:2306 builtin/apply.c:4522 +#: builtin/am.c:2292 builtin/apply.c:4512 msgid "num" msgstr "número" -#: builtin/am.c:2309 builtin/for-each-ref.c:37 builtin/replace.c:438 +#: builtin/am.c:2295 builtin/for-each-ref.c:37 builtin/replace.c:438 #: builtin/tag.c:372 msgid "format" msgstr "format" -#: builtin/am.c:2310 +#: builtin/am.c:2296 msgid "format the patch(es) are in" msgstr "el format en el qual estan els pedaços" -#: builtin/am.c:2316 +#: builtin/am.c:2302 msgid "override error message when patch failure occurs" msgstr "" "passa per alt el missatge d'error quan s'ocorre una fallada en apedaçar" -#: builtin/am.c:2318 +#: builtin/am.c:2304 msgid "continue applying patches after resolving a conflict" msgstr "segueix aplicant pedaços després de resoldre un conflicte" -#: builtin/am.c:2321 +#: builtin/am.c:2307 msgid "synonyms for --continue" msgstr "sinònims de --continue" -#: builtin/am.c:2324 +#: builtin/am.c:2310 msgid "skip the current patch" msgstr "salta el pedaç actual" -#: builtin/am.c:2327 +#: builtin/am.c:2313 msgid "restore the original branch and abort the patching operation." msgstr "restaura la branca original i avorta l'operació d'apedaçament." -#: builtin/am.c:2331 +#: builtin/am.c:2317 msgid "lie about committer date" msgstr "menteix sobre la data del comitent" -#: builtin/am.c:2333 +#: builtin/am.c:2319 msgid "use current timestamp for author date" msgstr "usa el marc de temps actual per la data d'autor" -#: builtin/am.c:2335 builtin/commit.c:1593 builtin/merge.c:225 -#: builtin/pull.c:155 builtin/revert.c:92 builtin/tag.c:355 +#: builtin/am.c:2321 builtin/commit.c:1593 builtin/merge.c:225 +#: builtin/pull.c:159 builtin/revert.c:92 builtin/tag.c:355 msgid "key-id" msgstr "ID de clau" -#: builtin/am.c:2336 +#: builtin/am.c:2322 msgid "GPG-sign commits" msgstr "firma les comissions amb GPG" -#: builtin/am.c:2339 +#: builtin/am.c:2325 msgid "(internal use for git-rebase)" msgstr "(ús intern per al git-rebase)" -#: builtin/am.c:2354 +#: builtin/am.c:2340 msgid "" "The -b/--binary option has been a no-op for long time, and\n" "it will be removed. Please do not use it anymore." @@ -2737,18 +2884,18 @@ msgstr "" "Fa molt que l'opció -b/--binary no ha fet res, i\n" "s'eliminarà. Si us plau, no l'useu més." -#: builtin/am.c:2361 +#: builtin/am.c:2347 msgid "failed to read the index" msgstr "s'ha fallat en llegir l'índex" -#: builtin/am.c:2376 +#: builtin/am.c:2362 #, c-format msgid "previous rebase directory %s still exists but mbox given." msgstr "" "un directori de rebasament anterior %s encara existeix però s'ha donat una " "bústia." -#: builtin/am.c:2400 +#: builtin/am.c:2386 #, c-format msgid "" "Stray %s directory found.\n" @@ -2757,7 +2904,7 @@ msgstr "" "Directori %s extraviat trobat.\n" "Useu \"git am --abort\" per a eliminar-lo." -#: builtin/am.c:2406 +#: builtin/am.c:2392 msgid "Resolve operation not in progress, we are not resuming." msgstr "Operació de resolució no en curs; no reprenem." @@ -3108,135 +3255,135 @@ msgstr "entrada no reconeguda" msgid "unable to read index file" msgstr "no es pot llegir el fitxer d'índex" -#: builtin/apply.c:4517 +#: builtin/apply.c:4507 msgid "don't apply changes matching the given path" msgstr "no apliquis els canvis que coincideixin amb el camí donat" -#: builtin/apply.c:4520 +#: builtin/apply.c:4510 msgid "apply changes matching the given path" msgstr "aplica els canvis que coincideixin amb el camí donat" -#: builtin/apply.c:4523 +#: builtin/apply.c:4513 msgid "remove leading slashes from traditional diff paths" msgstr "" "elimina barres obliqües inicials dels camins de diferència " "tradicionals" -#: builtin/apply.c:4526 +#: builtin/apply.c:4516 msgid "ignore additions made by the patch" msgstr "ignora afegiments fets pel pedaç" -#: builtin/apply.c:4528 +#: builtin/apply.c:4518 msgid "instead of applying the patch, output diffstat for the input" msgstr "" "en lloc d'aplicar el pedaç, emet les estadístiques de diferència de l'entrada" -#: builtin/apply.c:4532 +#: builtin/apply.c:4522 msgid "show number of added and deleted lines in decimal notation" msgstr "mostra el nombre de línies afegides i suprimides en notació decimal" -#: builtin/apply.c:4534 +#: builtin/apply.c:4524 msgid "instead of applying the patch, output a summary for the input" msgstr "en lloc d'aplicar el pedaç, emet un resum de l'entrada" -#: builtin/apply.c:4536 +#: builtin/apply.c:4526 msgid "instead of applying the patch, see if the patch is applicable" msgstr "en lloc d'aplicar el pedaç, veges si el pedaç és aplicable" -#: builtin/apply.c:4538 +#: builtin/apply.c:4528 msgid "make sure the patch is applicable to the current index" msgstr "assegura que el pedaç sigui aplicable a l'índex actual" -#: builtin/apply.c:4540 +#: builtin/apply.c:4530 msgid "apply a patch without touching the working tree" msgstr "aplica un pedaç sense tocar l'arbre de treball" -#: builtin/apply.c:4542 +#: builtin/apply.c:4532 msgid "accept a patch that touches outside the working area" msgstr "accepta un pedaç que toqui fora de l'àrea de treball" -#: builtin/apply.c:4544 +#: builtin/apply.c:4534 msgid "also apply the patch (use with --stat/--summary/--check)" msgstr "aplica el pedaç també (useu amb --stat/--summary/--check)" -#: builtin/apply.c:4546 +#: builtin/apply.c:4536 msgid "attempt three-way merge if a patch does not apply" msgstr "intenta una fusió de tres vies si el pedaç no s'aplica" -#: builtin/apply.c:4548 +#: builtin/apply.c:4538 msgid "build a temporary index based on embedded index information" msgstr "construeix un índex temporal basat en la informació d'índex incrustada" -#: builtin/apply.c:4550 builtin/checkout-index.c:198 builtin/ls-files.c:412 +#: builtin/apply.c:4541 builtin/checkout-index.c:169 builtin/ls-files.c:425 msgid "paths are separated with NUL character" msgstr "els camins se separen amb el caràcter NUL" -#: builtin/apply.c:4553 +#: builtin/apply.c:4543 msgid "ensure at least lines of context match" msgstr "assegura't que almenys línies de context coincideixin" -#: builtin/apply.c:4555 +#: builtin/apply.c:4545 msgid "detect new or modified lines that have whitespace errors" msgstr "" "detecta les línies noves o modificades que tinguin errors d'espai en blanc" -#: builtin/apply.c:4558 builtin/apply.c:4561 +#: builtin/apply.c:4548 builtin/apply.c:4551 msgid "ignore changes in whitespace when finding context" msgstr "ignora els canvis d'espai en blanc en cercar context" -#: builtin/apply.c:4564 +#: builtin/apply.c:4554 msgid "apply the patch in reverse" msgstr "aplica el pedaç al revés" -#: builtin/apply.c:4566 +#: builtin/apply.c:4556 msgid "don't expect at least one line of context" msgstr "no esperis almenys una línia de context" -#: builtin/apply.c:4568 +#: builtin/apply.c:4558 msgid "leave the rejected hunks in corresponding *.rej files" msgstr "deixa els trossos rebutjats en fitxers *.reg coresspondents" -#: builtin/apply.c:4570 +#: builtin/apply.c:4560 msgid "allow overlapping hunks" msgstr "permet trossos encavalcants" -#: builtin/apply.c:4573 +#: builtin/apply.c:4563 msgid "tolerate incorrectly detected missing new-line at the end of file" msgstr "tolera una línia nova incorrectament detectada al final del fitxer" -#: builtin/apply.c:4576 +#: builtin/apply.c:4566 msgid "do not trust the line counts in the hunk headers" msgstr "no confiïs en els recomptes de línia en les capçaleres dels trossos" -#: builtin/apply.c:4579 +#: builtin/apply.c:4569 msgid "prepend to all filenames" msgstr "anteposa a tots els noms de fitxer" -#: builtin/apply.c:4601 +#: builtin/apply.c:4591 msgid "--3way outside a repository" msgstr "--3way fora d'un dipòsit" -#: builtin/apply.c:4609 +#: builtin/apply.c:4599 msgid "--index outside a repository" msgstr "--index fora d'un dipòsit" -#: builtin/apply.c:4612 +#: builtin/apply.c:4602 msgid "--cached outside a repository" msgstr "--cached fora d'un dipòsit" -#: builtin/apply.c:4631 +#: builtin/apply.c:4621 #, c-format msgid "can't open patch '%s'" msgstr "no es pot obrir el pedaç '%s'" -#: builtin/apply.c:4645 +#: builtin/apply.c:4635 #, c-format msgid "squelched %d whitespace error" msgid_plural "squelched %d whitespace errors" msgstr[0] "%d error d'espai en blanc omès" msgstr[1] "%d errors d'espai en blanc omesos" -#: builtin/apply.c:4651 builtin/apply.c:4661 +#: builtin/apply.c:4641 builtin/apply.c:4651 #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." @@ -3290,109 +3437,117 @@ msgstr "realitza 'git bisect next'" msgid "update BISECT_HEAD instead of checking out the current commit" msgstr "actualitza BISECT_HEAD en lloc d'agafar la comissió actual" -#: builtin/blame.c:32 +#: builtin/blame.c:33 msgid "git blame [] [] [] [--] " msgstr "git blame [] [] [] [--] fitxer" -#: builtin/blame.c:37 +#: builtin/blame.c:38 msgid " are documented in git-rev-list(1)" msgstr "es documenten les en git-rev-list(1)" -#: builtin/blame.c:2519 +#: builtin/blame.c:1782 +msgid "Blaming lines" +msgstr "Culpant les línies" + +#: builtin/blame.c:2530 msgid "Show blame entries as we find them, incrementally" msgstr "Mostra les entrades de culpa mentre les trobem, incrementalment" -#: builtin/blame.c:2520 +#: builtin/blame.c:2531 msgid "Show blank SHA-1 for boundary commits (Default: off)" msgstr "" "Mostra un SHA-1 en blanc per les comissions de frontera (Per defecte: " "desactivat)" -#: builtin/blame.c:2521 +#: builtin/blame.c:2532 msgid "Do not treat root commits as boundaries (Default: off)" msgstr "" "No tractis les comissions d'arrel com a límits (Per defecte: desactivat)" -#: builtin/blame.c:2522 +#: builtin/blame.c:2533 msgid "Show work cost statistics" msgstr "Mostra les estadístiques de preu de treball" -#: builtin/blame.c:2523 +#: builtin/blame.c:2534 +msgid "Force progress reporting" +msgstr "Força l'informe de progrés" + +#: builtin/blame.c:2535 msgid "Show output score for blame entries" msgstr "Mostra la puntuació de sortida de les entrades de culpa" -#: builtin/blame.c:2524 +#: builtin/blame.c:2536 msgid "Show original filename (Default: auto)" msgstr "Mostra el nom de fitxer original (Per defecte: automàtic)" -#: builtin/blame.c:2525 +#: builtin/blame.c:2537 msgid "Show original linenumber (Default: off)" msgstr "Mostra el número de línia original (Per defecte: desactivat)" -#: builtin/blame.c:2526 +#: builtin/blame.c:2538 msgid "Show in a format designed for machine consumption" msgstr "Presenta en un format dissenyat per consumpció per màquina" -#: builtin/blame.c:2527 +#: builtin/blame.c:2539 msgid "Show porcelain format with per-line commit information" msgstr "Mostra el format de porcellana amb informació de comissió per línia" -#: builtin/blame.c:2528 +#: builtin/blame.c:2540 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "" "Usa el mateix mode de sortida que git-annotate (Per defecte: desactivat)" -#: builtin/blame.c:2529 +#: builtin/blame.c:2541 msgid "Show raw timestamp (Default: off)" msgstr "Mostra la marca de temps crua (Per defecte: desactivat)" -#: builtin/blame.c:2530 +#: builtin/blame.c:2542 msgid "Show long commit SHA1 (Default: off)" msgstr "Mostra l'SHA1 de comissió llarg (Per defecte: desactivat)" -#: builtin/blame.c:2531 +#: builtin/blame.c:2543 msgid "Suppress author name and timestamp (Default: off)" msgstr "Omet el nom d'autor i la marca de temps (Per defecte: desactivat)" -#: builtin/blame.c:2532 +#: builtin/blame.c:2544 msgid "Show author email instead of name (Default: off)" msgstr "" "Mostra l'adreça de correu electrònic de l'autor en lloc del nom (Per " "defecte: desactivat)" -#: builtin/blame.c:2533 +#: builtin/blame.c:2545 msgid "Ignore whitespace differences" msgstr "Ignora les diferències d'espai en blanc" -#: builtin/blame.c:2534 +#: builtin/blame.c:2546 msgid "Spend extra cycles to find better match" msgstr "Gasta cicles extres per a trobar una coincidència millor" -#: builtin/blame.c:2535 +#: builtin/blame.c:2547 msgid "Use revisions from instead of calling git-rev-list" msgstr "Usa les revisions de en lloc d'invocar git-rev-list" -#: builtin/blame.c:2536 +#: builtin/blame.c:2548 msgid "Use 's contents as the final image" msgstr "Usa els continguts de com a la imatge final" -#: builtin/blame.c:2537 builtin/blame.c:2538 +#: builtin/blame.c:2549 builtin/blame.c:2550 msgid "score" msgstr "puntuació" -#: builtin/blame.c:2537 +#: builtin/blame.c:2549 msgid "Find line copies within and across files" msgstr "Troba còpies de línia dins i a través dels fitxers" -#: builtin/blame.c:2538 +#: builtin/blame.c:2550 msgid "Find line movements within and across files" msgstr "Troba moviments de línia dins i a través dels fitxers" -#: builtin/blame.c:2539 +#: builtin/blame.c:2551 msgid "n,m" msgstr "n,m" -#: builtin/blame.c:2539 +#: builtin/blame.c:2551 msgid "Process only line range n,m, counting from 1" msgstr "Processa només el rang de línies n,m, comptant des d'1" @@ -3402,7 +3557,7 @@ msgstr "Processa només el rang de línies n,m, comptant des d'1" #. takes 22 places, is the longest among various forms of #. relative timestamps, but your language may need more or #. fewer display columns. -#: builtin/blame.c:2620 +#: builtin/blame.c:2640 msgid "4 years, 11 months ago" msgstr "fa 4 anys i 11 mesos" @@ -3604,196 +3759,196 @@ msgstr "" "La branca està canviada de nom, però l'actualització del fitxer de " "configuració ha fallat" -#: builtin/branch.c:587 +#: builtin/branch.c:586 #, c-format msgid "could not write branch description template: %s" msgstr "no s'ha pogut escriure la plantilla de descripció de branca: %s" -#: builtin/branch.c:616 +#: builtin/branch.c:615 msgid "Generic options" msgstr "Opcions genèriques" -#: builtin/branch.c:618 +#: builtin/branch.c:617 msgid "show hash and subject, give twice for upstream branch" msgstr "mostra el hash i l'assumpte, doneu dues vegades per la branca font" -#: builtin/branch.c:619 +#: builtin/branch.c:618 msgid "suppress informational messages" msgstr "omet els missatges informatius" -#: builtin/branch.c:620 +#: builtin/branch.c:619 msgid "set up tracking mode (see git-pull(1))" msgstr "configura el mode de seguiment (vegeu git-pull(1))" -#: builtin/branch.c:622 +#: builtin/branch.c:621 msgid "change upstream info" msgstr "canvia la informació de font" -#: builtin/branch.c:626 +#: builtin/branch.c:625 msgid "use colored output" msgstr "usa sortida colorada" -#: builtin/branch.c:627 +#: builtin/branch.c:626 msgid "act on remote-tracking branches" msgstr "actua en branques amb seguiment remot" -#: builtin/branch.c:629 builtin/branch.c:630 +#: builtin/branch.c:628 builtin/branch.c:629 msgid "print only branches that contain the commit" msgstr "imprimeix només les branques que continguin la comissió" -#: builtin/branch.c:633 +#: builtin/branch.c:632 msgid "Specific git-branch actions:" msgstr "Accions de git-branch específiques:" -#: builtin/branch.c:634 +#: builtin/branch.c:633 msgid "list both remote-tracking and local branches" msgstr "llista les branques amb seguiment remot i les locals" -#: builtin/branch.c:636 +#: builtin/branch.c:635 msgid "delete fully merged branch" msgstr "suprimeix la branca si està completament fusionada" -#: builtin/branch.c:637 +#: builtin/branch.c:636 msgid "delete branch (even if not merged)" msgstr "suprimeix la branca (encara que no estigui fusionada)" -#: builtin/branch.c:638 +#: builtin/branch.c:637 msgid "move/rename a branch and its reflog" msgstr "mou/canvia de nom una branca i el seu registre de referència" -#: builtin/branch.c:639 +#: builtin/branch.c:638 msgid "move/rename a branch, even if target exists" msgstr "mou/canvia de nom una branca, encara que el destí existeixi" -#: builtin/branch.c:640 +#: builtin/branch.c:639 msgid "list branch names" msgstr "llista els noms de branca" -#: builtin/branch.c:641 +#: builtin/branch.c:640 msgid "create the branch's reflog" msgstr "crea el registre de referència de la branca" -#: builtin/branch.c:643 +#: builtin/branch.c:642 msgid "edit the description for the branch" msgstr "edita la descripció de la branca" -#: builtin/branch.c:644 +#: builtin/branch.c:643 msgid "force creation, move/rename, deletion" msgstr "força creació, moviment/canvi de nom, supressió" -#: builtin/branch.c:645 +#: builtin/branch.c:644 msgid "print only branches that are merged" msgstr "imprimeix només les branques que s'han fusionat" -#: builtin/branch.c:646 +#: builtin/branch.c:645 msgid "print only branches that are not merged" msgstr "imprimeix només les branques que no s'han fusionat" -#: builtin/branch.c:647 +#: builtin/branch.c:646 msgid "list branches in columns" msgstr "llista les branques en columnes" -#: builtin/branch.c:648 builtin/for-each-ref.c:38 builtin/tag.c:366 +#: builtin/branch.c:647 builtin/for-each-ref.c:38 builtin/tag.c:366 msgid "key" msgstr "clau" -#: builtin/branch.c:649 builtin/for-each-ref.c:39 builtin/tag.c:367 +#: builtin/branch.c:648 builtin/for-each-ref.c:39 builtin/tag.c:367 msgid "field name to sort on" msgstr "nom del camp en el qual ordenar" -#: builtin/branch.c:651 builtin/for-each-ref.c:41 builtin/notes.c:398 -#: builtin/notes.c:401 builtin/notes.c:561 builtin/notes.c:564 +#: builtin/branch.c:650 builtin/for-each-ref.c:41 builtin/notes.c:401 +#: builtin/notes.c:404 builtin/notes.c:564 builtin/notes.c:567 #: builtin/tag.c:369 msgid "object" msgstr "objecte" -#: builtin/branch.c:652 +#: builtin/branch.c:651 msgid "print only branches of the object" msgstr "imprimeix només les branques de l'objecte" -#: builtin/branch.c:670 +#: builtin/branch.c:669 msgid "Failed to resolve HEAD as a valid ref." msgstr "S'ha fallat en resoldre HEAD com a referència vàlida." -#: builtin/branch.c:674 builtin/clone.c:697 +#: builtin/branch.c:673 builtin/clone.c:705 msgid "HEAD not found below refs/heads!" msgstr "HEAD no trobat sota refs/heads!" -#: builtin/branch.c:694 +#: builtin/branch.c:693 msgid "--column and --verbose are incompatible" msgstr "--column i --verbose són incompatibles" -#: builtin/branch.c:705 builtin/branch.c:747 +#: builtin/branch.c:704 builtin/branch.c:746 msgid "branch name required" msgstr "cal el nom de branca" -#: builtin/branch.c:723 +#: builtin/branch.c:722 msgid "Cannot give description to detached HEAD" msgstr "No es pot donar descripció a un HEAD separat" -#: builtin/branch.c:728 +#: builtin/branch.c:727 msgid "cannot edit description of more than one branch" msgstr "no es pot editar la descripció de més d'una branca" -#: builtin/branch.c:735 +#: builtin/branch.c:734 #, c-format msgid "No commit on branch '%s' yet." msgstr "Encara no hi ha comissió en la branca '%s'." -#: builtin/branch.c:738 +#: builtin/branch.c:737 #, c-format msgid "No branch named '%s'." msgstr "No hi ha branca amb nom '%s'." -#: builtin/branch.c:753 +#: builtin/branch.c:752 msgid "too many branches for a rename operation" msgstr "hi ha massa branques per a una operació de canvi de nom" -#: builtin/branch.c:758 +#: builtin/branch.c:757 msgid "too many branches to set new upstream" msgstr "hi ha massa branques per a establir una nova font" -#: builtin/branch.c:762 +#: builtin/branch.c:761 #, c-format msgid "" "could not set upstream of HEAD to %s when it does not point to any branch." msgstr "" "no s'ha pogut establir la font de HEAD com a %s quan no assenyala cap branca." -#: builtin/branch.c:765 builtin/branch.c:787 builtin/branch.c:808 +#: builtin/branch.c:764 builtin/branch.c:786 builtin/branch.c:807 #, c-format msgid "no such branch '%s'" msgstr "no hi ha tal branca '%s'" -#: builtin/branch.c:769 +#: builtin/branch.c:768 #, c-format msgid "branch '%s' does not exist" msgstr "la branca '%s' no existeix" -#: builtin/branch.c:781 +#: builtin/branch.c:780 msgid "too many branches to unset upstream" msgstr "hi ha massa branques per a desestablir la font" -#: builtin/branch.c:785 +#: builtin/branch.c:784 msgid "could not unset upstream of HEAD when it does not point to any branch." msgstr "" "no s'ha pogut desestablir la font de HEAD perquè no assenyala cap branca." -#: builtin/branch.c:791 +#: builtin/branch.c:790 #, c-format msgid "Branch '%s' has no upstream information" msgstr "La branca '%s' no té informació de font" -#: builtin/branch.c:805 +#: builtin/branch.c:804 msgid "it does not make sense to create 'HEAD' manually" msgstr "no té sentit crear 'HEAD' manualment" -#: builtin/branch.c:811 +#: builtin/branch.c:810 msgid "-a and -r options to 'git branch' do not make sense with a branch name" msgstr "" "les opcions -a i -r a 'git branch' no tenen sentit amb un nom de branca" -#: builtin/branch.c:814 +#: builtin/branch.c:813 #, c-format msgid "" "The --set-upstream flag is deprecated and will be removed. Consider using --" @@ -3802,7 +3957,7 @@ msgstr "" "La bandera --set-upstream està desaprovada i s'eliminarà. Considereu usar --" "track o --set-upstream-to\n" -#: builtin/branch.c:831 +#: builtin/branch.c:830 #, c-format msgid "" "\n" @@ -3813,12 +3968,12 @@ msgstr "" "Si volíeu fer '%s' seguir '%s', feu això:\n" "\n" -#: builtin/branch.c:832 +#: builtin/branch.c:831 #, c-format msgid " git branch -d %s\n" msgstr " git branch -d %s\n" -#: builtin/branch.c:833 +#: builtin/branch.c:832 #, c-format msgid " git branch --set-upstream-to %s\n" msgstr " git branch --set-upstream-to %s\n" @@ -3914,7 +4069,7 @@ msgstr "informa de tots els atributs establerts en el fitxer" msgid "use .gitattributes only from the index" msgstr "usa .gitattributes només des de l'índex" -#: builtin/check-attr.c:21 builtin/check-ignore.c:22 builtin/hash-object.c:96 +#: builtin/check-attr.c:21 builtin/check-ignore.c:22 builtin/hash-object.c:97 msgid "read file names from stdin" msgstr "llegeix els noms de fitxer d'stdin" @@ -3922,7 +4077,7 @@ msgstr "llegeix els noms de fitxer d'stdin" msgid "terminate input and output records by a NUL character" msgstr "acaba els registres d'entrada i de sortida amb un caràcter NUL" -#: builtin/check-ignore.c:18 builtin/checkout.c:1134 builtin/gc.c:325 +#: builtin/check-ignore.c:18 builtin/checkout.c:1136 builtin/gc.c:325 msgid "suppress progress reporting" msgstr "omet el reportatge de progrés" @@ -3975,49 +4130,53 @@ msgstr "no s'ha pogut analitzar el contacte: %s" msgid "no contacts specified" msgstr "no hi ha contactes especificats" -#: builtin/checkout-index.c:126 +#: builtin/checkout-index.c:127 msgid "git checkout-index [] [--] [...]" msgstr "git checkout-index [] [--] [...]" -#: builtin/checkout-index.c:188 +#: builtin/checkout-index.c:144 +msgid "stage should be between 1 and 3 or all" +msgstr "l'etapa ha de ser entre 1 i 3 o all" + +#: builtin/checkout-index.c:160 msgid "check out all files in the index" msgstr "agafa tots els fitxers en l'índex" -#: builtin/checkout-index.c:189 +#: builtin/checkout-index.c:161 msgid "force overwrite of existing files" msgstr "força la sobreescriptura de fitxers existents" -#: builtin/checkout-index.c:191 +#: builtin/checkout-index.c:163 msgid "no warning for existing files and files not in index" msgstr "cap avís per a fitxers existents i fitxers no en l'índex" -#: builtin/checkout-index.c:193 +#: builtin/checkout-index.c:165 msgid "don't checkout new files" msgstr "no agafis fitxers nous" -#: builtin/checkout-index.c:195 +#: builtin/checkout-index.c:167 msgid "update stat information in the index file" msgstr "actualitza la informació d'estadístiques en el fitxer d'índex" -#: builtin/checkout-index.c:201 +#: builtin/checkout-index.c:171 msgid "read list of paths from the standard input" msgstr "llegeix la llista de camins des de l'entrada estàndard" -#: builtin/checkout-index.c:203 +#: builtin/checkout-index.c:173 msgid "write the content to temporary files" msgstr "escriu el contingut a fitxers temporals" -#: builtin/checkout-index.c:204 builtin/column.c:30 +#: builtin/checkout-index.c:174 builtin/column.c:30 +#: builtin/submodule--helper.c:166 builtin/submodule--helper.c:169 #: builtin/submodule--helper.c:172 builtin/submodule--helper.c:175 -#: builtin/submodule--helper.c:178 builtin/submodule--helper.c:181 msgid "string" msgstr "cadena" -#: builtin/checkout-index.c:205 +#: builtin/checkout-index.c:175 msgid "when creating files, prepend " msgstr "en crear fitxers, anteposa " -#: builtin/checkout-index.c:208 +#: builtin/checkout-index.c:177 msgid "copy out the files from named stage" msgstr "copia els fitxers des de l'etapa anomenada" @@ -4098,37 +4257,41 @@ msgstr "No es pot fer reflog per a '%s': %s\n" msgid "HEAD is now at" msgstr "HEAD ara és a" -#: builtin/checkout.c:668 +#: builtin/checkout.c:665 builtin/clone.c:659 +msgid "unable to update HEAD" +msgstr "no s'ha pogut actualitzar HEAD" + +#: builtin/checkout.c:669 #, c-format msgid "Reset branch '%s'\n" msgstr "Restableix la branca '%s'\n" -#: builtin/checkout.c:671 +#: builtin/checkout.c:672 #, c-format msgid "Already on '%s'\n" msgstr "Ja en '%s'\n" -#: builtin/checkout.c:675 +#: builtin/checkout.c:676 #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "S'ha agafat i restablert la branca '%s'\n" -#: builtin/checkout.c:677 builtin/checkout.c:1066 +#: builtin/checkout.c:678 builtin/checkout.c:1068 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "S'ha agafat la branca nova '%s'\n" -#: builtin/checkout.c:679 +#: builtin/checkout.c:680 #, c-format msgid "Switched to branch '%s'\n" msgstr "S'ha agafat la branca '%s'\n" -#: builtin/checkout.c:731 +#: builtin/checkout.c:732 #, c-format msgid " ... and %d more.\n" msgstr " ... i %d més.\n" -#: builtin/checkout.c:737 +#: builtin/checkout.c:738 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -4151,7 +4314,7 @@ msgstr[1] "" "\n" "%s\n" -#: builtin/checkout.c:756 +#: builtin/checkout.c:757 #, c-format msgid "" "If you want to keep it by creating a new branch, this may be a good time\n" @@ -4178,150 +4341,150 @@ msgstr[1] "" " git branch %s\n" "\n" -#: builtin/checkout.c:792 +#: builtin/checkout.c:793 msgid "internal error in revision walk" msgstr "error intern en el passeig per revisions" -#: builtin/checkout.c:796 +#: builtin/checkout.c:797 msgid "Previous HEAD position was" msgstr "La posició de HEAD anterior era" -#: builtin/checkout.c:823 builtin/checkout.c:1061 +#: builtin/checkout.c:824 builtin/checkout.c:1063 msgid "You are on a branch yet to be born" msgstr "Sou en una branca que encara ha de nàixer" -#: builtin/checkout.c:968 +#: builtin/checkout.c:969 #, c-format msgid "only one reference expected, %d given." msgstr "només una referència esperada, %d donades." -#: builtin/checkout.c:1007 builtin/worktree.c:213 +#: builtin/checkout.c:1009 builtin/worktree.c:211 #, c-format msgid "invalid reference: %s" msgstr "referència no vàlida: %s" -#: builtin/checkout.c:1036 +#: builtin/checkout.c:1038 #, c-format msgid "reference is not a tree: %s" msgstr "la referència no és un arbre: %s" -#: builtin/checkout.c:1075 +#: builtin/checkout.c:1077 msgid "paths cannot be used with switching branches" msgstr "els camins no es poden usar amb canvi de branca" -#: builtin/checkout.c:1078 builtin/checkout.c:1082 +#: builtin/checkout.c:1080 builtin/checkout.c:1084 #, c-format msgid "'%s' cannot be used with switching branches" msgstr "'%s' no es pot usar amb canvi de branca" -#: builtin/checkout.c:1086 builtin/checkout.c:1089 builtin/checkout.c:1094 -#: builtin/checkout.c:1097 +#: builtin/checkout.c:1088 builtin/checkout.c:1091 builtin/checkout.c:1096 +#: builtin/checkout.c:1099 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "'%s' no es pot usar amb '%s'" -#: builtin/checkout.c:1102 +#: builtin/checkout.c:1104 #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "No es pot canviar la branca a la no comissió '%s'" -#: builtin/checkout.c:1135 builtin/checkout.c:1137 builtin/clone.c:83 -#: builtin/remote.c:165 builtin/remote.c:167 builtin/worktree.c:320 -#: builtin/worktree.c:322 +#: builtin/checkout.c:1137 builtin/checkout.c:1139 builtin/clone.c:84 +#: builtin/remote.c:165 builtin/remote.c:167 builtin/worktree.c:318 +#: builtin/worktree.c:320 msgid "branch" msgstr "branca" -#: builtin/checkout.c:1136 +#: builtin/checkout.c:1138 msgid "create and checkout a new branch" msgstr "crea i agafa una branca nova" -#: builtin/checkout.c:1138 +#: builtin/checkout.c:1140 msgid "create/reset and checkout a branch" msgstr "crea/restableix i agafa una branca" -#: builtin/checkout.c:1139 +#: builtin/checkout.c:1141 msgid "create reflog for new branch" msgstr "crea un registre de referència per a la branca nova" -#: builtin/checkout.c:1140 +#: builtin/checkout.c:1142 msgid "detach the HEAD at named commit" msgstr "separa el HEAD a la comissió anomenada" -#: builtin/checkout.c:1141 +#: builtin/checkout.c:1143 msgid "set upstream info for new branch" msgstr "estableix la informació de font de la branca nova" -#: builtin/checkout.c:1143 +#: builtin/checkout.c:1145 msgid "new-branch" msgstr "branca-nova" -#: builtin/checkout.c:1143 +#: builtin/checkout.c:1145 msgid "new unparented branch" msgstr "branca òrfena nova" -#: builtin/checkout.c:1144 +#: builtin/checkout.c:1146 msgid "checkout our version for unmerged files" msgstr "agafa la versió nostra dels fitxers sense fusionar" -#: builtin/checkout.c:1146 +#: builtin/checkout.c:1148 msgid "checkout their version for unmerged files" msgstr "agafa la versió seva dels fitxers sense fusionar" -#: builtin/checkout.c:1148 +#: builtin/checkout.c:1150 msgid "force checkout (throw away local modifications)" msgstr "agafa a la força (descarta qualsevulla modificació local)" -#: builtin/checkout.c:1149 +#: builtin/checkout.c:1151 msgid "perform a 3-way merge with the new branch" msgstr "realitza una fusió de 3 vies amb la branca nova" -#: builtin/checkout.c:1150 builtin/merge.c:227 +#: builtin/checkout.c:1152 builtin/merge.c:227 msgid "update ignored files (default)" msgstr "actualitza els fitxers ignorats (per defecte)" -#: builtin/checkout.c:1151 builtin/log.c:1266 parse-options.h:250 +#: builtin/checkout.c:1153 builtin/log.c:1269 parse-options.h:250 msgid "style" msgstr "estil" -#: builtin/checkout.c:1152 +#: builtin/checkout.c:1154 msgid "conflict style (merge or diff3)" msgstr "estil de conflicte (fusió o diff3)" -#: builtin/checkout.c:1155 +#: builtin/checkout.c:1157 msgid "do not limit pathspecs to sparse entries only" msgstr "no limitis les especificacions de camí només a entrades disperses" -#: builtin/checkout.c:1157 +#: builtin/checkout.c:1159 msgid "second guess 'git checkout '" msgstr "dubta 'git checkout '" -#: builtin/checkout.c:1159 +#: builtin/checkout.c:1161 msgid "do not check if another worktree is holding the given ref" msgstr "no comprovis si altre arbre de treball té la referència donada" -#: builtin/checkout.c:1160 builtin/clone.c:57 builtin/fetch.c:112 -#: builtin/merge.c:224 builtin/pull.c:109 builtin/push.c:558 +#: builtin/checkout.c:1162 builtin/clone.c:58 builtin/fetch.c:116 +#: builtin/merge.c:224 builtin/pull.c:113 builtin/push.c:526 #: builtin/send-pack.c:168 msgid "force progress reporting" msgstr "força l'informe de progrés" -#: builtin/checkout.c:1191 +#: builtin/checkout.c:1193 msgid "-b, -B and --orphan are mutually exclusive" msgstr "-b, -B i --orphan són mutualment exclusius" -#: builtin/checkout.c:1208 +#: builtin/checkout.c:1210 msgid "--track needs a branch name" msgstr "--track necessita un nom de branca" -#: builtin/checkout.c:1213 +#: builtin/checkout.c:1215 msgid "Missing branch name; try -b" msgstr "Manca el nom de branca; proveu -b" -#: builtin/checkout.c:1249 +#: builtin/checkout.c:1251 msgid "invalid path specification" msgstr "especificació de camí no vàlida" -#: builtin/checkout.c:1256 +#: builtin/checkout.c:1258 #, c-format msgid "" "Cannot update paths and switch to branch '%s' at the same time.\n" @@ -4330,12 +4493,12 @@ msgstr "" "No es poden actualitzar els camins i canviar a la branca '%s' a la vegada.\n" "Volíeu agafar '%s', la qual no es pot resoldre com a comissió?" -#: builtin/checkout.c:1261 +#: builtin/checkout.c:1263 #, c-format msgid "git checkout: --detach does not take a path argument '%s'" msgstr "git checkout: --detach no accepta un paràmetre de camí '%s'" -#: builtin/checkout.c:1265 +#: builtin/checkout.c:1267 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -4374,7 +4537,7 @@ msgstr "Saltaria el dipòsit %s\n" msgid "failed to remove %s" msgstr "s'ha fallat en eliminar %s" -#: builtin/clean.c:315 +#: builtin/clean.c:291 msgid "" "Prompt help:\n" "1 - select a numbered item\n" @@ -4386,7 +4549,7 @@ msgstr "" "foo - selecciona un ítem basat en un prefix únic\n" " - (buit) no seleccionis res" -#: builtin/clean.c:319 +#: builtin/clean.c:295 msgid "" "Prompt help:\n" "1 - select a single item\n" @@ -4406,36 +4569,36 @@ msgstr "" "* - tria tots els ítems\n" " - (buit) finalitza la selecció" -#: builtin/clean.c:535 +#: builtin/clean.c:511 #, c-format msgid "Huh (%s)?" msgstr "Perdó (%s)?" -#: builtin/clean.c:677 +#: builtin/clean.c:653 #, c-format msgid "Input ignore patterns>> " msgstr "Introduïu els patrons a ignorar>> " -#: builtin/clean.c:714 +#: builtin/clean.c:690 #, c-format msgid "WARNING: Cannot find items matched by: %s" msgstr "AVÍS: No es pot trobar ítems que coincideixin amb: %s" -#: builtin/clean.c:735 +#: builtin/clean.c:711 msgid "Select items to delete" msgstr "Selecciona els ítems a suprimir" #. TRANSLATORS: Make sure to keep [y/N] as is -#: builtin/clean.c:776 +#: builtin/clean.c:752 #, c-format msgid "Remove %s [y/N]? " msgstr "Voleu eliminar %s [y/N]? " -#: builtin/clean.c:801 +#: builtin/clean.c:777 msgid "Bye." msgstr "Adéu." -#: builtin/clean.c:809 +#: builtin/clean.c:785 msgid "" "clean - start cleaning\n" "filter by pattern - exclude items from deletion\n" @@ -4453,62 +4616,62 @@ msgstr "" "help - aquesta pantalla\n" "? - ajuda de selecció de l'avís" -#: builtin/clean.c:836 +#: builtin/clean.c:812 msgid "*** Commands ***" msgstr "*** Ordres ***" -#: builtin/clean.c:837 +#: builtin/clean.c:813 msgid "What now" msgstr "I ara què" -#: builtin/clean.c:845 +#: builtin/clean.c:821 msgid "Would remove the following item:" msgid_plural "Would remove the following items:" msgstr[0] "Eliminaria l'ítem següent:" msgstr[1] "Eliminaria els ítems següents:" -#: builtin/clean.c:862 +#: builtin/clean.c:838 msgid "No more files to clean, exiting." msgstr "No hi ha més fitxers a netejar; sortint." -#: builtin/clean.c:893 +#: builtin/clean.c:869 msgid "do not print names of files removed" msgstr "no imprimeixis els noms dels fitxers eliminats" -#: builtin/clean.c:895 +#: builtin/clean.c:871 msgid "force" msgstr "força" -#: builtin/clean.c:896 +#: builtin/clean.c:872 msgid "interactive cleaning" msgstr "neteja interactiva" -#: builtin/clean.c:898 +#: builtin/clean.c:874 msgid "remove whole directories" msgstr "elimina directoris sencers" -#: builtin/clean.c:899 builtin/describe.c:407 builtin/grep.c:709 -#: builtin/ls-files.c:443 builtin/name-rev.c:307 builtin/show-ref.c:182 +#: builtin/clean.c:875 builtin/describe.c:407 builtin/grep.c:722 +#: builtin/ls-files.c:456 builtin/name-rev.c:307 builtin/show-ref.c:182 msgid "pattern" msgstr "patró" -#: builtin/clean.c:900 +#: builtin/clean.c:876 msgid "add to ignore rules" msgstr "afegiu per a ignorar les regles" -#: builtin/clean.c:901 +#: builtin/clean.c:877 msgid "remove ignored files, too" msgstr "elimina els fitxers ignorats, també" -#: builtin/clean.c:903 +#: builtin/clean.c:879 msgid "remove only ignored files" msgstr "elimina només els fitxers ignorats" -#: builtin/clean.c:921 +#: builtin/clean.c:897 msgid "-x and -X cannot be used together" msgstr "-x i -X no es poden usar junts" -#: builtin/clean.c:925 +#: builtin/clean.c:901 msgid "" "clean.requireForce set to true and neither -i, -n, nor -f given; refusing to " "clean" @@ -4516,7 +4679,7 @@ msgstr "" "clean.requireForce està establerta a veritat i ni -i, -n ni -f s'ha donat; " "refusant netejar" -#: builtin/clean.c:928 +#: builtin/clean.c:904 msgid "" "clean.requireForce defaults to true and neither -i, -n, nor -f given; " "refusing to clean" @@ -4528,146 +4691,162 @@ msgstr "" msgid "git clone [] [--] []" msgstr "git clone [] [--] []" -#: builtin/clone.c:59 +#: builtin/clone.c:60 msgid "don't create a checkout" msgstr "no facis cap agafament" -#: builtin/clone.c:60 builtin/clone.c:62 builtin/init-db.c:469 +#: builtin/clone.c:61 builtin/clone.c:63 builtin/init-db.c:469 msgid "create a bare repository" msgstr "crea un dipòsit nu" -#: builtin/clone.c:64 +#: builtin/clone.c:65 msgid "create a mirror repository (implies bare)" msgstr "crea un dipòsit reflectit (implica bare)" -#: builtin/clone.c:66 +#: builtin/clone.c:67 msgid "to clone from a local repository" msgstr "per a clonar des d'un dipòsit local" -#: builtin/clone.c:68 +#: builtin/clone.c:69 msgid "don't use local hardlinks, always copy" msgstr "no usis enllaços durs locals, sempre copia" -#: builtin/clone.c:70 +#: builtin/clone.c:71 msgid "setup as shared repository" msgstr "configura com a dipòsit compartit" -#: builtin/clone.c:72 builtin/clone.c:74 +#: builtin/clone.c:73 builtin/clone.c:75 msgid "initialize submodules in the clone" msgstr "inicialitza els submòduls en el clon" -#: builtin/clone.c:75 builtin/init-db.c:466 +#: builtin/clone.c:76 builtin/init-db.c:466 msgid "template-directory" msgstr "directori-de-plantilla" -#: builtin/clone.c:76 builtin/init-db.c:467 +#: builtin/clone.c:77 builtin/init-db.c:467 msgid "directory from which templates will be used" msgstr "directori del qual les plantilles s'usaran" -#: builtin/clone.c:78 builtin/submodule--helper.c:179 +#: builtin/clone.c:79 builtin/submodule--helper.c:173 msgid "reference repository" msgstr "dipòsit de referència" -#: builtin/clone.c:80 +#: builtin/clone.c:81 msgid "use --reference only while cloning" msgstr "usa --reference només en clonar" -#: builtin/clone.c:81 builtin/column.c:26 builtin/merge-file.c:44 +#: builtin/clone.c:82 builtin/column.c:26 builtin/merge-file.c:44 msgid "name" msgstr "nom" -#: builtin/clone.c:82 +#: builtin/clone.c:83 msgid "use instead of 'origin' to track upstream" msgstr "usa en lloc de 'origin' per a seguir la font" -#: builtin/clone.c:84 +#: builtin/clone.c:85 msgid "checkout instead of the remote's HEAD" msgstr "agafa en lloc del HEAD del remot" -#: builtin/clone.c:86 +#: builtin/clone.c:87 msgid "path to git-upload-pack on the remote" msgstr "camí a git-upload-pack en el remot" -#: builtin/clone.c:87 builtin/fetch.c:113 builtin/grep.c:654 builtin/pull.c:186 +#: builtin/clone.c:88 builtin/fetch.c:117 builtin/grep.c:665 builtin/pull.c:193 msgid "depth" msgstr "profunditat" -#: builtin/clone.c:88 +#: builtin/clone.c:89 msgid "create a shallow clone of that depth" msgstr "crea un clon superficial de tal profunditat" -#: builtin/clone.c:90 +#: builtin/clone.c:91 msgid "clone only one branch, HEAD or --branch" msgstr "clona només una branca, HEAD o --branch" -#: builtin/clone.c:91 builtin/init-db.c:475 +#: builtin/clone.c:92 builtin/init-db.c:475 msgid "gitdir" msgstr "directori de git" -#: builtin/clone.c:92 builtin/init-db.c:476 +#: builtin/clone.c:93 builtin/init-db.c:476 msgid "separate git dir from working tree" msgstr "separa el directori de git de l'arbre de treball" -#: builtin/clone.c:93 +#: builtin/clone.c:94 msgid "key=value" msgstr "clau=valor" -#: builtin/clone.c:94 +#: builtin/clone.c:95 msgid "set config inside the new repository" msgstr "estableix la configuració dins del dipòsit nou" -#: builtin/clone.c:300 +#: builtin/clone.c:96 builtin/fetch.c:131 builtin/push.c:536 +msgid "use IPv4 addresses only" +msgstr "usa només les adreces IPv4" + +#: builtin/clone.c:98 builtin/fetch.c:133 builtin/push.c:538 +msgid "use IPv6 addresses only" +msgstr "usa només les adreces IPv6" + +#: builtin/clone.c:239 +msgid "" +"No directory name could be guessed.\n" +"Please specify a directory on the command line" +msgstr "" +"No s'ha pogut endevinar cap nom de directori.\n" +"Si us plau, especifiqueu un directori en la línia d'ordres" + +#: builtin/clone.c:305 #, c-format msgid "reference repository '%s' as a linked checkout is not supported yet." msgstr "" "Encara no se suporta el dipòsit de referència '%s' com a agafament enllaçat." -#: builtin/clone.c:302 +#: builtin/clone.c:307 #, c-format msgid "reference repository '%s' is not a local repository." msgstr "el dipòsit de referència '%s' no és un dipòsit local." -#: builtin/clone.c:307 +#: builtin/clone.c:312 #, c-format msgid "reference repository '%s' is shallow" msgstr "el dipòsit de referència '%s' és superficial" -#: builtin/clone.c:310 +#: builtin/clone.c:315 #, c-format msgid "reference repository '%s' is grafted" msgstr "el dipòsit de referència '%s' és empeltat" -#: builtin/clone.c:375 builtin/diff.c:84 +#: builtin/clone.c:380 builtin/diff.c:84 #, c-format msgid "failed to stat '%s'" msgstr "s'ha fallat en fer stat a '%s'" -#: builtin/clone.c:377 +#: builtin/clone.c:382 #, c-format msgid "%s exists and is not a directory" msgstr "%s existeix i no és directori" -#: builtin/clone.c:391 +#: builtin/clone.c:396 #, c-format msgid "failed to stat %s\n" msgstr "s'ha fallat en fer stat a '%s'\n" -#: builtin/clone.c:413 +#: builtin/clone.c:418 #, c-format msgid "failed to create link '%s'" msgstr "s'ha fallat en crear l'enllaç '%s'" -#: builtin/clone.c:417 +#: builtin/clone.c:422 #, c-format msgid "failed to copy file to '%s'" msgstr "s'ha fallat en copiar el fitxer a '%s'" -#: builtin/clone.c:442 builtin/clone.c:626 +#: builtin/clone.c:447 builtin/clone.c:631 #, c-format msgid "done.\n" msgstr "fet.\n" -#: builtin/clone.c:454 +#: builtin/clone.c:459 msgid "" "Clone succeeded, but checkout failed.\n" "You can inspect what was checked out with 'git status'\n" @@ -4678,119 +4857,128 @@ msgstr "" "'git status' i tornar a intentar l'agafament amb\n" "'git checkout -f HEAD'\n" -#: builtin/clone.c:531 +#: builtin/clone.c:536 #, c-format msgid "Could not find remote branch %s to clone." msgstr "No s'ha pogut trobar la branca remota %s per a clonar." -#: builtin/clone.c:621 +#: builtin/clone.c:626 #, c-format msgid "Checking connectivity... " msgstr "Provant connectivitat... " -#: builtin/clone.c:624 +#: builtin/clone.c:629 msgid "remote did not send all necessary objects" msgstr "el remot no ha enviat tots els objectes necessaris" -#: builtin/clone.c:688 +#: builtin/clone.c:647 +#, c-format +msgid "unable to update %s" +msgstr "no s'ha pogut actualizar %s" + +#: builtin/clone.c:696 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n" msgstr "" "el HEAD remot es refereix a una referència que no existeix; no s'ha pogut " "agafar.\n" -#: builtin/clone.c:719 +#: builtin/clone.c:727 msgid "unable to checkout working tree" msgstr "no s'ha pogut agafar l'arbre de treball" -#: builtin/clone.c:808 +#: builtin/clone.c:753 +msgid "unable to write parameters to config file" +msgstr "no s'ha pogut escriure les paràmetres al fitxer de configuració" + +#: builtin/clone.c:816 msgid "cannot repack to clean up" msgstr "no es pot reempaquetar per a netejar" -#: builtin/clone.c:810 +#: builtin/clone.c:818 msgid "cannot unlink temporary alternates file" msgstr "no es pot desenllaçar el fitxer d'alternatives temporal" -#: builtin/clone.c:842 +#: builtin/clone.c:850 msgid "Too many arguments." msgstr "Hi ha massa paràmetres." -#: builtin/clone.c:846 +#: builtin/clone.c:854 msgid "You must specify a repository to clone." msgstr "Heu d'especificar un dipòsit per a clonar." -#: builtin/clone.c:857 +#: builtin/clone.c:865 #, c-format msgid "--bare and --origin %s options are incompatible." msgstr "les opcions --bare i --origin %s són incompatibles." -#: builtin/clone.c:860 +#: builtin/clone.c:868 msgid "--bare and --separate-git-dir are incompatible." msgstr "--bare i --separate-git-dir són incompatibles." -#: builtin/clone.c:873 +#: builtin/clone.c:881 #, c-format msgid "repository '%s' does not exist" msgstr "el dipòsit '%s' no existeix" -#: builtin/clone.c:879 builtin/fetch.c:1166 +#: builtin/clone.c:887 builtin/fetch.c:1174 #, c-format msgid "depth %s is not a positive number" msgstr "la profunditat %s no és nombre positiu" -#: builtin/clone.c:889 +#: builtin/clone.c:897 #, c-format msgid "destination path '%s' already exists and is not an empty directory." msgstr "el camí destí '%s' ja existeix i no és un directori buit." -#: builtin/clone.c:899 +#: builtin/clone.c:907 #, c-format msgid "working tree '%s' already exists." msgstr "l'arbre de treball '%s' ja existeix." -#: builtin/clone.c:914 builtin/clone.c:925 builtin/submodule--helper.c:224 -#: builtin/worktree.c:221 builtin/worktree.c:248 +#: builtin/clone.c:922 builtin/clone.c:933 builtin/submodule--helper.c:218 +#: builtin/worktree.c:219 builtin/worktree.c:246 #, c-format msgid "could not create leading directories of '%s'" msgstr "no s'ha pogut crear els directoris inicials de '%s'" -#: builtin/clone.c:917 +#: builtin/clone.c:925 #, c-format msgid "could not create work tree dir '%s'" msgstr "no s'ha pogut crear el directori d'arbre de treball '%s'" -#: builtin/clone.c:935 +#: builtin/clone.c:943 #, c-format msgid "Cloning into bare repository '%s'...\n" msgstr "Clonant al dipòsit nu '%s'...\n" -#: builtin/clone.c:937 +#: builtin/clone.c:945 #, c-format msgid "Cloning into '%s'...\n" msgstr "Clonant a '%s'...\n" -#: builtin/clone.c:975 +#: builtin/clone.c:984 msgid "--depth is ignored in local clones; use file:// instead." msgstr "--depth s'ignora en els clons locals; useu file:// en lloc d'això." -#: builtin/clone.c:978 +#: builtin/clone.c:987 msgid "source repository is shallow, ignoring --local" msgstr "el dipòsit font és superficial, ignorant --local" -#: builtin/clone.c:983 +#: builtin/clone.c:992 msgid "--local is ignored" msgstr "--local s'ignora" -#: builtin/clone.c:987 +#: builtin/clone.c:996 #, c-format msgid "Don't know how to clone %s" msgstr "No se sap com clonar %s" -#: builtin/clone.c:1036 builtin/clone.c:1044 +#: builtin/clone.c:1045 builtin/clone.c:1053 #, c-format msgid "Remote branch %s not found in upstream %s" msgstr "La branca remota %s no es troba en la font %s" -#: builtin/clone.c:1047 +#: builtin/clone.c:1056 msgid "You appear to have cloned an empty repository." msgstr "Sembla que heu clonat un dipòsit buit." @@ -5004,7 +5192,7 @@ msgstr "" msgid "could not lookup commit %s" msgstr "no s'ha pogut trobar la comissió %s" -#: builtin/commit.c:702 builtin/shortlog.c:273 +#: builtin/commit.c:702 builtin/shortlog.c:285 #, c-format msgid "(reading log message from standard input)\n" msgstr "(llegint el missatge de registre des de l'entrada estàndard)\n" @@ -5191,8 +5379,8 @@ msgstr "mostra l'estat concisament" msgid "show branch information" msgstr "mostra la informació de branca" -#: builtin/commit.c:1328 builtin/commit.c:1609 builtin/push.c:544 -#: builtin/worktree.c:423 +#: builtin/commit.c:1328 builtin/commit.c:1609 builtin/push.c:512 +#: builtin/worktree.c:430 msgid "machine-readable output" msgstr "sortida llegible per màquina" @@ -5283,8 +5471,8 @@ msgstr "data" msgid "override date for commit" msgstr "data corregida de la comissió" -#: builtin/commit.c:1582 builtin/merge.c:218 builtin/notes.c:392 -#: builtin/notes.c:555 builtin/tag.c:349 +#: builtin/commit.c:1582 builtin/merge.c:218 builtin/notes.c:395 +#: builtin/notes.c:558 builtin/tag.c:349 msgid "message" msgstr "missatge" @@ -5321,7 +5509,7 @@ msgstr "" msgid "the commit is authored by me now (used with -C/-c/--amend)" msgstr "l'autor de la comissió ja sóc jo (s'usa amb -C/-c/--amend)" -#: builtin/commit.c:1588 builtin/log.c:1216 builtin/revert.c:86 +#: builtin/commit.c:1588 builtin/log.c:1219 builtin/revert.c:86 msgid "add Signed-off-by:" msgstr "afegeix Signed-off-by:" @@ -5345,7 +5533,7 @@ msgstr "com despullar els espais i #comentaris del missatge" msgid "include status in commit message template" msgstr "inclou l'estat en la plantilla de missatge de comissió" -#: builtin/commit.c:1594 builtin/merge.c:226 builtin/pull.c:156 +#: builtin/commit.c:1594 builtin/merge.c:226 builtin/pull.c:160 #: builtin/revert.c:93 msgid "GPG sign commit" msgstr "firma la comissió amb GPG" @@ -5437,140 +5625,146 @@ msgstr "" "que la quota no estigui excedida, i després\n" "\"git reset HEAD\" per a recuperar." -#: builtin/config.c:8 +#: builtin/config.c:9 msgid "git config []" msgstr "git config []" -#: builtin/config.c:54 +#: builtin/config.c:56 msgid "Config file location" msgstr "Ubicació del fitxer de configuració" -#: builtin/config.c:55 +#: builtin/config.c:57 msgid "use global config file" msgstr "usa el fitxer de configuració global" -#: builtin/config.c:56 +#: builtin/config.c:58 msgid "use system config file" msgstr "usa el fitxer de configuració del sistema" -#: builtin/config.c:57 +#: builtin/config.c:59 msgid "use repository config file" msgstr "usa el fitxer de configuració del dipòsit" -#: builtin/config.c:58 +#: builtin/config.c:60 msgid "use given config file" msgstr "usa el fitxer de configuració donat" -#: builtin/config.c:59 +#: builtin/config.c:61 msgid "blob-id" msgstr "ID de blob" -#: builtin/config.c:59 +#: builtin/config.c:61 msgid "read config from given blob object" msgstr "llegeix la configuració de l'objecte de blob donat" -#: builtin/config.c:60 +#: builtin/config.c:62 msgid "Action" msgstr "Acció" -#: builtin/config.c:61 +#: builtin/config.c:63 msgid "get value: name [value-regex]" msgstr "obtén valor: nom [regex-de-valors]" -#: builtin/config.c:62 +#: builtin/config.c:64 msgid "get all values: key [value-regex]" msgstr "obtén tots els valors: clau [regex-de-valors]" -#: builtin/config.c:63 +#: builtin/config.c:65 msgid "get values for regexp: name-regex [value-regex]" msgstr "obtén valors de regexp: regex-de-noms [regex-de-valors]" -#: builtin/config.c:64 +#: builtin/config.c:66 msgid "get value specific for the URL: section[.var] URL" msgstr "obtén el valor específic per a l'URL: secció[.variable] URL" -#: builtin/config.c:65 +#: builtin/config.c:67 msgid "replace all matching variables: name value [value_regex]" msgstr "" "reemplaça totes les variables que coincideixen: nom valor [regex_de_valors]" -#: builtin/config.c:66 +#: builtin/config.c:68 msgid "add a new variable: name value" msgstr "afegeix una variable nova: nom valor" -#: builtin/config.c:67 +#: builtin/config.c:69 msgid "remove a variable: name [value-regex]" msgstr "elimina una variable: nom [regex-de-valors]" -#: builtin/config.c:68 +#: builtin/config.c:70 msgid "remove all matches: name [value-regex]" msgstr "elimina totes les coincidències: nom [regex-de-valors]" -#: builtin/config.c:69 +#: builtin/config.c:71 msgid "rename section: old-name new-name" msgstr "canvia el nom de secció: nom-antic nom-nou" -#: builtin/config.c:70 +#: builtin/config.c:72 msgid "remove a section: name" msgstr "elimina una secció: nom" -#: builtin/config.c:71 +#: builtin/config.c:73 msgid "list all" msgstr "llista tots" -#: builtin/config.c:72 +#: builtin/config.c:74 msgid "open an editor" msgstr "obre un editor" -#: builtin/config.c:73 +#: builtin/config.c:75 msgid "find the color configured: slot [default]" msgstr "troba el color configurat: ranura [per defecte]" -#: builtin/config.c:74 +#: builtin/config.c:76 msgid "find the color setting: slot [stdout-is-tty]" msgstr "troba l'ajust de color: ranura [stdout-és-tty]" -#: builtin/config.c:75 +#: builtin/config.c:77 msgid "Type" msgstr "Tipus" -#: builtin/config.c:76 +#: builtin/config.c:78 msgid "value is \"true\" or \"false\"" msgstr "el valor és \"true\" o \"false\"" -#: builtin/config.c:77 +#: builtin/config.c:79 msgid "value is decimal number" msgstr "el valor és un nombre decimal" -#: builtin/config.c:78 +#: builtin/config.c:80 msgid "value is --bool or --int" msgstr "el valor és --bool o --int" -#: builtin/config.c:79 +#: builtin/config.c:81 msgid "value is a path (file or directory name)" msgstr "el valor és un camí (nom de fitxer o directori)" -#: builtin/config.c:80 +#: builtin/config.c:82 msgid "Other" msgstr "Altre" -#: builtin/config.c:81 +#: builtin/config.c:83 msgid "terminate values with NUL byte" msgstr "acaba els valors amb un octet NUL" -#: builtin/config.c:82 +#: builtin/config.c:84 msgid "show variable names only" msgstr "mostra només els noms de variable" -#: builtin/config.c:83 +#: builtin/config.c:85 msgid "respect include directives on lookup" msgstr "respecta les directives d'inclusió en cercar" -#: builtin/config.c:303 +#: builtin/config.c:86 +msgid "show origin of config (file, standard input, blob, command line)" +msgstr "" +"mostra l'origen de la configuració (fitxer, entrada estàndar, blob, línia " +"d'ordres)" + +#: builtin/config.c:328 msgid "unable to parse default color value" msgstr "no s'ha pogut analitzar el valor de color per defecte" -#: builtin/config.c:441 +#: builtin/config.c:469 #, c-format msgid "" "# This is Git's per-user configuration file.\n" @@ -5585,7 +5779,7 @@ msgstr "" "#\tname = %s\n" "#\temail = %s\n" -#: builtin/config.c:575 +#: builtin/config.c:611 #, c-format msgid "cannot create configuration file %s" msgstr "no es pot crear el fitxer de configuració '%s'" @@ -5835,162 +6029,166 @@ msgstr "git fetch --multiple [] [( | )...]" msgid "git fetch --all []" msgstr "git fetch --all []" -#: builtin/fetch.c:90 builtin/pull.c:162 +#: builtin/fetch.c:92 builtin/pull.c:166 msgid "fetch from all remotes" msgstr "obtén de tots els remots" -#: builtin/fetch.c:92 builtin/pull.c:165 +#: builtin/fetch.c:94 builtin/pull.c:169 msgid "append to .git/FETCH_HEAD instead of overwriting" msgstr "annexa a .git/FETCH_HEAD en lloc de sobreescriure" -#: builtin/fetch.c:94 builtin/pull.c:168 +#: builtin/fetch.c:96 builtin/pull.c:172 msgid "path to upload pack on remote end" msgstr "camí al qual pujar el paquet al costat remot" -#: builtin/fetch.c:95 builtin/pull.c:170 +#: builtin/fetch.c:97 builtin/pull.c:174 msgid "force overwrite of local branch" msgstr "força la sobreescriptura de la branca local" -#: builtin/fetch.c:97 +#: builtin/fetch.c:99 msgid "fetch from multiple remotes" msgstr "obtén de múltiples remots" -#: builtin/fetch.c:99 builtin/pull.c:172 +#: builtin/fetch.c:101 builtin/pull.c:176 msgid "fetch all tags and associated objects" msgstr "obtén totes les etiquetes i tots els objectes associats" -#: builtin/fetch.c:101 +#: builtin/fetch.c:103 msgid "do not fetch all tags (--no-tags)" msgstr "no obtinguis les etiquetes (--no-tags)" -#: builtin/fetch.c:103 builtin/pull.c:175 +#: builtin/fetch.c:105 +msgid "number of submodules fetched in parallel" +msgstr "nombre de submòduls obtinguts en paral·lel" + +#: builtin/fetch.c:107 builtin/pull.c:179 msgid "prune remote-tracking branches no longer on remote" msgstr "poda les branques amb seguiment remot que ja no estiguin en el remot" -#: builtin/fetch.c:104 builtin/pull.c:178 +#: builtin/fetch.c:108 builtin/pull.c:182 msgid "on-demand" msgstr "sota demanda" -#: builtin/fetch.c:105 builtin/pull.c:179 +#: builtin/fetch.c:109 builtin/pull.c:183 msgid "control recursive fetching of submodules" msgstr "controla l'obtenció recursiva de submòduls" -#: builtin/fetch.c:109 builtin/pull.c:184 +#: builtin/fetch.c:113 builtin/pull.c:191 msgid "keep downloaded pack" msgstr "retén el paquet baixat" -#: builtin/fetch.c:111 +#: builtin/fetch.c:115 msgid "allow updating of HEAD ref" msgstr "permet l'actualització de la referència HEAD" -#: builtin/fetch.c:114 builtin/pull.c:187 +#: builtin/fetch.c:118 builtin/pull.c:194 msgid "deepen history of shallow clone" msgstr "aprofundeix la història d'un clon superficial" -#: builtin/fetch.c:116 builtin/pull.c:190 +#: builtin/fetch.c:120 builtin/pull.c:197 msgid "convert to a complete repository" msgstr "converteix en un dipòsit complet" -#: builtin/fetch.c:118 builtin/log.c:1233 +#: builtin/fetch.c:122 builtin/log.c:1236 msgid "dir" msgstr "directori" -#: builtin/fetch.c:119 +#: builtin/fetch.c:123 msgid "prepend this to submodule path output" msgstr "anteposa això a la sortida de camí del submòdul" -#: builtin/fetch.c:122 +#: builtin/fetch.c:126 msgid "default mode for recursion" msgstr "mode de recursivitat per defecte" -#: builtin/fetch.c:124 builtin/pull.c:193 +#: builtin/fetch.c:128 builtin/pull.c:200 msgid "accept refs that update .git/shallow" msgstr "accepta les referències que actualitzin .git/shallow" -#: builtin/fetch.c:125 builtin/pull.c:195 +#: builtin/fetch.c:129 builtin/pull.c:202 msgid "refmap" msgstr "mapa de referències" -#: builtin/fetch.c:126 builtin/pull.c:196 +#: builtin/fetch.c:130 builtin/pull.c:203 msgid "specify fetch refmap" msgstr "mostra el mapa de referències d'obtenció" -#: builtin/fetch.c:378 +#: builtin/fetch.c:386 msgid "Couldn't find remote ref HEAD" msgstr "No s'ha pogut trobar la referència HEAD remota" -#: builtin/fetch.c:458 +#: builtin/fetch.c:466 #, c-format msgid "object %s not found" msgstr "objecte %s no trobat" -#: builtin/fetch.c:463 +#: builtin/fetch.c:471 msgid "[up to date]" msgstr "[al dia]" -#: builtin/fetch.c:477 +#: builtin/fetch.c:485 #, c-format msgid "! %-*s %-*s -> %s (can't fetch in current branch)" msgstr "! %-*s %-*s -> %s (no es pot obtenir en la branca actual)" -#: builtin/fetch.c:478 builtin/fetch.c:566 +#: builtin/fetch.c:486 builtin/fetch.c:574 msgid "[rejected]" msgstr "[rebutjat]" -#: builtin/fetch.c:489 +#: builtin/fetch.c:497 msgid "[tag update]" msgstr "[actualització d'etiqueta]" -#: builtin/fetch.c:491 builtin/fetch.c:526 builtin/fetch.c:544 +#: builtin/fetch.c:499 builtin/fetch.c:534 builtin/fetch.c:552 msgid " (unable to update local ref)" msgstr " (no s'ha pogut actualitzar la referència local)" -#: builtin/fetch.c:509 +#: builtin/fetch.c:517 msgid "[new tag]" msgstr "[etiqueta nova]" -#: builtin/fetch.c:512 +#: builtin/fetch.c:520 msgid "[new branch]" msgstr "[branca nova]" -#: builtin/fetch.c:515 +#: builtin/fetch.c:523 msgid "[new ref]" msgstr "[referència nova]" -#: builtin/fetch.c:561 +#: builtin/fetch.c:569 msgid "unable to update local ref" msgstr "no s'ha pogut actualitzar la referència local" -#: builtin/fetch.c:561 +#: builtin/fetch.c:569 msgid "forced update" msgstr "actualització forçada" -#: builtin/fetch.c:568 +#: builtin/fetch.c:576 msgid "(non-fast-forward)" msgstr "(sense avanç ràpid)" -#: builtin/fetch.c:602 builtin/fetch.c:843 +#: builtin/fetch.c:610 builtin/fetch.c:851 #, c-format msgid "cannot open %s: %s\n" msgstr "no es pot obrir %s: %s\n" -#: builtin/fetch.c:611 +#: builtin/fetch.c:619 #, c-format msgid "%s did not send all necessary objects\n" msgstr "%s no ha enviat tots els objectes necessaris\n" -#: builtin/fetch.c:629 +#: builtin/fetch.c:637 #, c-format msgid "reject %s because shallow roots are not allowed to be updated" msgstr "" "rebutja %s perquè no es permet que les arrels superficials s'actualitzin" -#: builtin/fetch.c:716 builtin/fetch.c:808 +#: builtin/fetch.c:724 builtin/fetch.c:816 #, c-format msgid "From %.*s\n" msgstr "De %.*s\n" -#: builtin/fetch.c:727 +#: builtin/fetch.c:735 #, c-format msgid "" "some local refs could not be updated; try running\n" @@ -6000,55 +6198,55 @@ msgstr "" " intenteu executar 'git remote prune %s' per a eliminar\n" " qualsevulla branca antiga o conflictiva" -#: builtin/fetch.c:779 +#: builtin/fetch.c:787 #, c-format msgid " (%s will become dangling)" msgstr " (%s es tornarà penjant)" -#: builtin/fetch.c:780 +#: builtin/fetch.c:788 #, c-format msgid " (%s has become dangling)" msgstr " (%s s'ha tornat penjant)" -#: builtin/fetch.c:812 +#: builtin/fetch.c:820 msgid "[deleted]" msgstr "[suprimit]" -#: builtin/fetch.c:813 builtin/remote.c:1040 +#: builtin/fetch.c:821 builtin/remote.c:1025 msgid "(none)" msgstr "(cap)" -#: builtin/fetch.c:833 +#: builtin/fetch.c:841 #, c-format msgid "Refusing to fetch into current branch %s of non-bare repository" msgstr "Refusant obtenir en la branca actual %s d'un dipòsit no nu" -#: builtin/fetch.c:852 +#: builtin/fetch.c:860 #, c-format msgid "Option \"%s\" value \"%s\" is not valid for %s" msgstr "L'opció \"%s\" amb valor \"%s\" no és vàlida per a %s" -#: builtin/fetch.c:855 +#: builtin/fetch.c:863 #, c-format msgid "Option \"%s\" is ignored for %s\n" msgstr "S'ignora l'opció \"%s\" per a %s\n" -#: builtin/fetch.c:911 +#: builtin/fetch.c:920 #, c-format msgid "Don't know how to fetch from %s" msgstr "No se sap com obtenir de %s" -#: builtin/fetch.c:1072 +#: builtin/fetch.c:1080 #, c-format msgid "Fetching %s\n" msgstr "Obtenint %s\n" -#: builtin/fetch.c:1074 builtin/remote.c:96 +#: builtin/fetch.c:1082 builtin/remote.c:96 #, c-format msgid "Could not fetch %s" msgstr "No s'ha pogut obtenir %s" -#: builtin/fetch.c:1092 +#: builtin/fetch.c:1100 msgid "" "No remote repository specified. Please, specify either a URL or a\n" "remote name from which new revisions should be fetched." @@ -6056,32 +6254,32 @@ msgstr "" "Cap dipòsit remot especificat. Si us plau, especifiqueu o un URL o\n" "un nom remot del qual es deuen obtenir les revisions noves." -#: builtin/fetch.c:1115 +#: builtin/fetch.c:1123 msgid "You need to specify a tag name." msgstr "Necessiteu especificar un nom d'etiqueta." -#: builtin/fetch.c:1157 +#: builtin/fetch.c:1165 msgid "--depth and --unshallow cannot be used together" msgstr "--depth i --unshallow no es poden usar junts" -#: builtin/fetch.c:1159 +#: builtin/fetch.c:1167 msgid "--unshallow on a complete repository does not make sense" msgstr "--unshallow en un dipòsit complet no té sentit" -#: builtin/fetch.c:1179 +#: builtin/fetch.c:1187 msgid "fetch --all does not take a repository argument" msgstr "fetch --all no accepta un paràmetre de dipòsit" -#: builtin/fetch.c:1181 +#: builtin/fetch.c:1189 msgid "fetch --all does not make sense with refspecs" msgstr "fetch --all no té sentit amb especificacions de referència" -#: builtin/fetch.c:1192 +#: builtin/fetch.c:1200 #, c-format msgid "No such remote or remote group: %s" msgstr "No hi ha tal remot ni tal grup remot: %s" -#: builtin/fetch.c:1200 +#: builtin/fetch.c:1208 msgid "Fetching a group and specifying refspecs does not make sense" msgstr "Obtenir un grup i especificar referències no té sentit" @@ -6308,228 +6506,242 @@ msgstr "" msgid "git grep [] [-e] [...] [[--] ...]" msgstr "git grep [] [-e] [...] [[--] ...]" -#: builtin/grep.c:218 +#: builtin/grep.c:219 #, c-format msgid "grep: failed to create thread: %s" msgstr "grep: s'ha fallat en crear fil: %s" -#: builtin/grep.c:441 builtin/grep.c:476 +#: builtin/grep.c:277 +#, c-format +msgid "invalid number of threads specified (%d) for %s" +msgstr "s'ha especificat un nombre de fils no vàlid (%d) per a %s" + +#: builtin/grep.c:452 builtin/grep.c:487 #, c-format msgid "unable to read tree (%s)" msgstr "no s'ha pogut llegir l'arbre (%s)" -#: builtin/grep.c:491 +#: builtin/grep.c:502 #, c-format msgid "unable to grep from object of type %s" msgstr "no es pot fer grep des d'un objecte de tipus %s" -#: builtin/grep.c:547 +#: builtin/grep.c:558 #, c-format msgid "switch `%c' expects a numerical value" msgstr "l'opció `%c' espera un valor numèric" -#: builtin/grep.c:564 +#: builtin/grep.c:575 #, c-format msgid "cannot open '%s'" msgstr "no es pot obrir '%s'" -#: builtin/grep.c:633 +#: builtin/grep.c:644 msgid "search in index instead of in the work tree" msgstr "cerca en l'índex en lloc de l'arbre de treball" -#: builtin/grep.c:635 +#: builtin/grep.c:646 msgid "find in contents not managed by git" msgstr "cerca en continguts no gestionats per git" -#: builtin/grep.c:637 +#: builtin/grep.c:648 msgid "search in both tracked and untracked files" msgstr "cerca tant en fitxers seguits com en no seguits" -#: builtin/grep.c:639 +#: builtin/grep.c:650 msgid "ignore files specified via '.gitignore'" msgstr "ignora els fitxers especificats mitjançant '.gitignore'" -#: builtin/grep.c:642 +#: builtin/grep.c:653 msgid "show non-matching lines" msgstr "mostra les línies no coincidents" -#: builtin/grep.c:644 +#: builtin/grep.c:655 msgid "case insensitive matching" msgstr "coincidència insensible a majúscula i minúscula" -#: builtin/grep.c:646 +#: builtin/grep.c:657 msgid "match patterns only at word boundaries" msgstr "coincideix amb els patrons només als límits de paraula" -#: builtin/grep.c:648 +#: builtin/grep.c:659 msgid "process binary files as text" msgstr "processa els fitxers binaris com a text" -#: builtin/grep.c:650 +#: builtin/grep.c:661 msgid "don't match patterns in binary files" msgstr "no coincideixis amb els patrons en els fitxers binaris" -#: builtin/grep.c:653 +#: builtin/grep.c:664 msgid "process binary files with textconv filters" msgstr "processa els fitxers binaris amb filtres de textconv" -#: builtin/grep.c:655 +#: builtin/grep.c:666 msgid "descend at most levels" msgstr "descendeix com a màxim nivells" -#: builtin/grep.c:659 +#: builtin/grep.c:670 msgid "use extended POSIX regular expressions" msgstr "usa les expressions regulars POSIX esteses" -#: builtin/grep.c:662 +#: builtin/grep.c:673 msgid "use basic POSIX regular expressions (default)" msgstr "usa les expressions regulars POSIX bàsiques (per defecte)" -#: builtin/grep.c:665 +#: builtin/grep.c:676 msgid "interpret patterns as fixed strings" msgstr "interpreta els patrons com a cadenes fixes" -#: builtin/grep.c:668 +#: builtin/grep.c:679 msgid "use Perl-compatible regular expressions" msgstr "usa les expressions regulars compatibles amb Perl" -#: builtin/grep.c:671 +#: builtin/grep.c:682 msgid "show line numbers" msgstr "mostra els números de línia" -#: builtin/grep.c:672 +#: builtin/grep.c:683 msgid "don't show filenames" msgstr "no mostris els noms de fitxer" -#: builtin/grep.c:673 +#: builtin/grep.c:684 msgid "show filenames" msgstr "mostra els noms de fitxer" -#: builtin/grep.c:675 +#: builtin/grep.c:686 msgid "show filenames relative to top directory" msgstr "mostra els noms de fitxer relatius al directori superior" -#: builtin/grep.c:677 +#: builtin/grep.c:688 msgid "show only filenames instead of matching lines" msgstr "mostra només els noms de fitxer en lloc de les línies coincidents" -#: builtin/grep.c:679 +#: builtin/grep.c:690 msgid "synonym for --files-with-matches" msgstr "sinònim de --files-with-matches" -#: builtin/grep.c:682 +#: builtin/grep.c:693 msgid "show only the names of files without match" msgstr "mostra només els noms dels fitxers sense coincidència" -#: builtin/grep.c:684 +#: builtin/grep.c:695 msgid "print NUL after filenames" msgstr "imprimeix NUL després dels noms de fitxer" -#: builtin/grep.c:686 +#: builtin/grep.c:697 msgid "show the number of matches instead of matching lines" msgstr "mostra el nombre de coincidències en lloc de les línies coincidents" -#: builtin/grep.c:687 +#: builtin/grep.c:698 msgid "highlight matches" msgstr "ressalta les coincidències" -#: builtin/grep.c:689 +#: builtin/grep.c:700 msgid "print empty line between matches from different files" msgstr "imprimeix una línia buida entre coincidències de fitxers distints" -#: builtin/grep.c:691 +#: builtin/grep.c:702 msgid "show filename only once above matches from same file" msgstr "" "mostra el nom de fitxer només una vegada a dalt de les coincidències del " "mateix fitxer" -#: builtin/grep.c:694 +#: builtin/grep.c:705 msgid "show context lines before and after matches" msgstr "mostra línies de context abans i després d'una coincidència" -#: builtin/grep.c:697 +#: builtin/grep.c:708 msgid "show context lines before matches" msgstr "mostra línies de context abans d'una coincidència" -#: builtin/grep.c:699 +#: builtin/grep.c:710 msgid "show context lines after matches" msgstr "mostra línies de context després d'una coincidència" -#: builtin/grep.c:700 +#: builtin/grep.c:712 +msgid "use worker threads" +msgstr "usa fils obrers" + +#: builtin/grep.c:713 msgid "shortcut for -C NUM" msgstr "drecera per -C NUM" -#: builtin/grep.c:703 +#: builtin/grep.c:716 msgid "show a line with the function name before matches" msgstr "mostra una línia amb el nom de funció abans de les coincidències" -#: builtin/grep.c:705 +#: builtin/grep.c:718 msgid "show the surrounding function" msgstr "mostra la funció circumdant" -#: builtin/grep.c:708 +#: builtin/grep.c:721 msgid "read patterns from file" msgstr "llegeix els patrons des d'un fitxer" -#: builtin/grep.c:710 +#: builtin/grep.c:723 msgid "match " msgstr "coincideix amb " -#: builtin/grep.c:712 +#: builtin/grep.c:725 msgid "combine patterns specified with -e" msgstr "combina els patrons especificats amb -e" -#: builtin/grep.c:724 +#: builtin/grep.c:737 msgid "indicate hit with exit status without output" msgstr "indica coincidència amb estat de sortida sense sortida textual" -#: builtin/grep.c:726 +#: builtin/grep.c:739 msgid "show only matches from files that match all patterns" msgstr "" "mostra només les coincidències dels fitxers que coincideixin amb tots els " "patrons" -#: builtin/grep.c:728 +#: builtin/grep.c:741 msgid "show parse tree for grep expression" msgstr "mostra l'arbre d'anàlisis de l'expressió de grep" -#: builtin/grep.c:732 +#: builtin/grep.c:745 msgid "pager" msgstr "paginador" -#: builtin/grep.c:732 +#: builtin/grep.c:745 msgid "show matching files in the pager" msgstr "mostra els fitxers coincidents en el paginador" -#: builtin/grep.c:735 +#: builtin/grep.c:748 msgid "allow calling of grep(1) (ignored by this build)" msgstr "permet la invocació de grep(1) (ignorat per aquesta compilació)" -#: builtin/grep.c:793 +#: builtin/grep.c:811 msgid "no pattern given." msgstr "cap patró donat." -#: builtin/grep.c:851 +#: builtin/grep.c:843 builtin/index-pack.c:1475 +#, c-format +msgid "invalid number of threads specified (%d)" +msgstr "s'ha especificat un nombre de fils no vàlid (%d)" + +#: builtin/grep.c:873 msgid "--open-files-in-pager only works on the worktree" msgstr "--open-files-in-pager només funciona en l'arbre de treball" -#: builtin/grep.c:877 +#: builtin/grep.c:899 msgid "--cached or --untracked cannot be used with --no-index." msgstr "--cached o --untracked no es pot usar amb --no-index." -#: builtin/grep.c:882 +#: builtin/grep.c:904 msgid "--no-index or --untracked cannot be used with revs." msgstr "--no-index o --untracked no es pot usar amb revisions." -#: builtin/grep.c:885 +#: builtin/grep.c:907 msgid "--[no-]exclude-standard cannot be used for tracked contents." msgstr "--[no-]exclude-standard no es pot usar per als continguts seguits." -#: builtin/grep.c:893 +#: builtin/grep.c:915 msgid "both --cached and trees are given." msgstr "s'han donat ambdós --caches i arbres." -#: builtin/hash-object.c:80 +#: builtin/hash-object.c:81 msgid "" "git hash-object [-t ] [-w] [--path= | --no-filters] [--stdin] " "[--] ..." @@ -6537,38 +6749,38 @@ msgstr "" "git hash-object [-t ] [-w] [--path= | --no-filters] [--stdin] " "[--] ..." -#: builtin/hash-object.c:81 +#: builtin/hash-object.c:82 msgid "git hash-object --stdin-paths" msgstr "git hash-object --stdin-paths" -#: builtin/hash-object.c:92 +#: builtin/hash-object.c:93 msgid "type" msgstr "tipus" -#: builtin/hash-object.c:92 +#: builtin/hash-object.c:93 msgid "object type" msgstr "tipus d'objecte" -#: builtin/hash-object.c:93 +#: builtin/hash-object.c:94 msgid "write the object into the object database" msgstr "escriu l'objecte a la base de dades d'objectes" -#: builtin/hash-object.c:95 +#: builtin/hash-object.c:96 msgid "read the object from stdin" msgstr "llegeix l'objecte des d'stdin" -#: builtin/hash-object.c:97 +#: builtin/hash-object.c:98 msgid "store file as is without filters" msgstr "emmagatzema el fitxer tal com és sense filtres" -#: builtin/hash-object.c:98 +#: builtin/hash-object.c:99 msgid "" "just hash any random garbage to create corrupt objects for debugging Git" msgstr "" "només suma qualsevulla brossa aleatòria per a crear objectes malmesos per a " "depurar al Git" -#: builtin/hash-object.c:99 +#: builtin/hash-object.c:100 msgid "process file as it were from this path" msgstr "processa el fitxer com si fos d'aquest camí" @@ -6619,7 +6831,7 @@ msgstr "la versió d'emacsclient '%d' és massa vella (< 22)." msgid "failed to exec '%s': %s" msgstr "s'ha fallat en executar '%s': %s" -#: builtin/help.c:208 +#: builtin/help.c:205 #, c-format msgid "" "'%s': path for unsupported man viewer.\n" @@ -6628,7 +6840,7 @@ msgstr "" "'%s': camí a un visualitzador de manuals no compatible.\n" "Si us plau, considereu usar 'man..cmd' en lloc d'això." -#: builtin/help.c:220 +#: builtin/help.c:217 #, c-format msgid "" "'%s': cmd for supported man viewer.\n" @@ -6637,61 +6849,61 @@ msgstr "" "'%s': ordre per a un visualitzador de manuals compatible.\n" "Si us plau, considereu usar 'man..path' en lloc d'això." -#: builtin/help.c:337 +#: builtin/help.c:334 #, c-format msgid "'%s': unknown man viewer." msgstr "'%s': visualitzador de manuals desconegut" -#: builtin/help.c:354 +#: builtin/help.c:351 msgid "no man viewer handled the request" msgstr "cap visualitzador de manuals ha gestionat la sol·licitud" -#: builtin/help.c:362 +#: builtin/help.c:359 msgid "no info viewer handled the request" msgstr "cap visualitzador d'informació ha gestionat la sol·licitud" -#: builtin/help.c:411 +#: builtin/help.c:408 msgid "Defining attributes per path" msgstr "La definició d'atributs per camí" -#: builtin/help.c:412 +#: builtin/help.c:409 msgid "Everyday Git With 20 Commands Or So" msgstr "Git quotidià amb més o menys 20 ordres" -#: builtin/help.c:413 +#: builtin/help.c:410 msgid "A Git glossary" msgstr "Un glossari de Git" -#: builtin/help.c:414 +#: builtin/help.c:411 msgid "Specifies intentionally untracked files to ignore" msgstr "Especifica els fitxers intencionalment no seguits a ignorar" -#: builtin/help.c:415 +#: builtin/help.c:412 msgid "Defining submodule properties" msgstr "La definició de les propietats de submòduls" -#: builtin/help.c:416 +#: builtin/help.c:413 msgid "Specifying revisions and ranges for Git" msgstr "L'especificació de revisions i rangs per al Git" -#: builtin/help.c:417 +#: builtin/help.c:414 msgid "A tutorial introduction to Git (for version 1.5.1 or newer)" msgstr "Una introducció tutorial al Git (per a la versió 1.5.1 o més nou)" -#: builtin/help.c:418 +#: builtin/help.c:415 msgid "An overview of recommended workflows with Git" msgstr "Una visió de conjunt de fluxos de treball recomanats amb Git" -#: builtin/help.c:430 +#: builtin/help.c:427 msgid "The common Git guides are:\n" msgstr "Les guies de Git comunes són:\n" -#: builtin/help.c:451 builtin/help.c:468 +#: builtin/help.c:448 builtin/help.c:465 #, c-format msgid "usage: %s%s" msgstr "ús: %s%s" -#: builtin/help.c:484 +#: builtin/help.c:481 #, c-format msgid "`git %s' is aliased to `%s'" msgstr "`git %s' és un àlies de `%s'" @@ -6927,60 +7139,55 @@ msgstr "no es pot emmagatzemar el fitxer d'índex" msgid "bad pack.indexversion=%" msgstr "pack.indexversion=% dolent" -#: builtin/index-pack.c:1475 -#, c-format -msgid "invalid number of threads specified (%d)" -msgstr "s'ha especificat un nombre de fils no vàlid (%d)" - -#: builtin/index-pack.c:1479 builtin/index-pack.c:1663 +#: builtin/index-pack.c:1479 builtin/index-pack.c:1664 #, c-format msgid "no threads support, ignoring %s" msgstr "no hi ha suport de fils, ignorant %s" -#: builtin/index-pack.c:1537 +#: builtin/index-pack.c:1538 #, c-format msgid "Cannot open existing pack file '%s'" msgstr "No es pot obrir el fitxer de paquet existent '%s'" -#: builtin/index-pack.c:1539 +#: builtin/index-pack.c:1540 #, c-format msgid "Cannot open existing pack idx file for '%s'" msgstr "No es pot obrir el fitxer d'índex de paquets existent de '%s'" -#: builtin/index-pack.c:1586 +#: builtin/index-pack.c:1587 #, c-format msgid "non delta: %d object" msgid_plural "non delta: %d objects" msgstr[0] "sense delta: %d objecte" msgstr[1] "sense delta: %d objectes" -#: builtin/index-pack.c:1593 +#: builtin/index-pack.c:1594 #, c-format msgid "chain length = %d: %lu object" msgid_plural "chain length = %d: %lu objects" msgstr[0] "longitud de cadena = %d: %lu objecte" msgstr[1] "longitud de cadena = %d: %lu objectes" -#: builtin/index-pack.c:1623 +#: builtin/index-pack.c:1624 msgid "Cannot come back to cwd" msgstr "No es pot tornar al directori de treball actual" -#: builtin/index-pack.c:1675 builtin/index-pack.c:1678 -#: builtin/index-pack.c:1690 builtin/index-pack.c:1694 +#: builtin/index-pack.c:1676 builtin/index-pack.c:1679 +#: builtin/index-pack.c:1691 builtin/index-pack.c:1695 #, c-format msgid "bad %s" msgstr "%s dolent" -#: builtin/index-pack.c:1708 +#: builtin/index-pack.c:1709 msgid "--fix-thin cannot be used without --stdin" msgstr "--fix-thin no es pot usar sense --stdin" -#: builtin/index-pack.c:1712 builtin/index-pack.c:1721 +#: builtin/index-pack.c:1713 builtin/index-pack.c:1722 #, c-format msgid "packfile name '%s' does not end with '.pack'" msgstr "el nom de fitxer de paquet '%s' no acaba amb '.pack'" -#: builtin/index-pack.c:1729 +#: builtin/index-pack.c:1730 msgid "--verify with no packfile name given" msgstr "s'ha donat --verify sense nom de fitxer de paquet" @@ -7106,24 +7313,32 @@ msgstr "No es pot accedir a l'arbre de treball '%s'" #: builtin/interpret-trailers.c:15 msgid "" -"git interpret-trailers [--trim-empty] [(--trailer [(=|:)])...] " -"[...]" +"git interpret-trailers [--in-place] [--trim-empty] [(--trailer " +"[(=|:)])...] [...]" msgstr "" -"git interpret-trailers [--trim-empty] [(--trailer [(=|:)])...] " -"[...]" +"git interpret-trailers [--in-place] [--trim-empty] [(--trailer " +"[(=|:)])...] [...]" + +#: builtin/interpret-trailers.c:26 +msgid "edit files in place" +msgstr "edita els fitxers in situ" -#: builtin/interpret-trailers.c:25 +#: builtin/interpret-trailers.c:27 msgid "trim empty trailers" msgstr "escurça els remolcs buits" -#: builtin/interpret-trailers.c:26 +#: builtin/interpret-trailers.c:28 msgid "trailer" msgstr "remolc" -#: builtin/interpret-trailers.c:27 +#: builtin/interpret-trailers.c:29 msgid "trailer(s) to add" msgstr "remolcs a afegir" +#: builtin/interpret-trailers.c:42 +msgid "no input file given for in-place editing" +msgstr "no s'ha donat cap fitxer d'entrada per a edició in situ" + #: builtin/log.c:43 msgid "git log [] [] [[--] ...]" msgstr "git log [] [] [[--] ...]" @@ -7177,225 +7392,225 @@ msgstr "No es pot llegir l'objecte %s" msgid "Unknown type: %d" msgstr "Tipus desconegut: %d" -#: builtin/log.c:714 +#: builtin/log.c:715 msgid "format.headers without value" msgstr "format.headers sense valor" -#: builtin/log.c:798 +#: builtin/log.c:801 msgid "name of output directory is too long" msgstr "el nom del directori de sortida és massa llarg" -#: builtin/log.c:813 +#: builtin/log.c:816 #, c-format msgid "Cannot open patch file %s" msgstr "No es pot obrir el fitxer de pedaç %s" -#: builtin/log.c:827 +#: builtin/log.c:830 msgid "Need exactly one range." msgstr "Cal exactament un rang." -#: builtin/log.c:837 +#: builtin/log.c:840 msgid "Not a range." msgstr "No és un rang." -#: builtin/log.c:943 +#: builtin/log.c:946 msgid "Cover letter needs email format" msgstr "La carta de presentació necessita el format de correu electrònic" -#: builtin/log.c:1022 +#: builtin/log.c:1025 #, c-format msgid "insane in-reply-to: %s" msgstr "in-reply-to boig: %s" -#: builtin/log.c:1050 +#: builtin/log.c:1053 msgid "git format-patch [] [ | ]" msgstr "git format-patch [] [ | ]" -#: builtin/log.c:1095 +#: builtin/log.c:1098 msgid "Two output directories?" msgstr "Dos directoris de sortida?" -#: builtin/log.c:1211 +#: builtin/log.c:1214 msgid "use [PATCH n/m] even with a single patch" msgstr "usa [PATCH n/m] fins i tot amb un sol pedaç" -#: builtin/log.c:1214 +#: builtin/log.c:1217 msgid "use [PATCH] even with multiple patches" msgstr "usa [PATCH] fins i tot amb múltiples pedaços" -#: builtin/log.c:1218 +#: builtin/log.c:1221 msgid "print patches to standard out" msgstr "imprimeix els pedaços a la sortida estàndard" -#: builtin/log.c:1220 +#: builtin/log.c:1223 msgid "generate a cover letter" msgstr "genera una carta de presentació" -#: builtin/log.c:1222 +#: builtin/log.c:1225 msgid "use simple number sequence for output file names" msgstr "usa una seqüència de números per als noms dels fitxers de sortida" -#: builtin/log.c:1223 +#: builtin/log.c:1226 msgid "sfx" msgstr "sufix" -#: builtin/log.c:1224 +#: builtin/log.c:1227 msgid "use instead of '.patch'" msgstr "usa en lloc de '.patch'" -#: builtin/log.c:1226 +#: builtin/log.c:1229 msgid "start numbering patches at instead of 1" msgstr "comença numerant els pedaços a en lloc d'1" -#: builtin/log.c:1228 +#: builtin/log.c:1231 msgid "mark the series as Nth re-roll" msgstr "marca la sèrie com a l'enèsima llançada" -#: builtin/log.c:1230 +#: builtin/log.c:1233 msgid "Use [] instead of [PATCH]" msgstr "Usa [] en lloc de [PATCH]" -#: builtin/log.c:1233 +#: builtin/log.c:1236 msgid "store resulting files in " msgstr "emmagatzema els fitxers resultants a " -#: builtin/log.c:1236 +#: builtin/log.c:1239 msgid "don't strip/add [PATCH]" msgstr "no despullis/afegeixis [PATCH]" -#: builtin/log.c:1239 +#: builtin/log.c:1242 msgid "don't output binary diffs" msgstr "no emetis diferències binàries" -#: builtin/log.c:1241 +#: builtin/log.c:1244 msgid "output all-zero hash in From header" msgstr "emet un hash de tots zeros en la capçalera From" -#: builtin/log.c:1243 +#: builtin/log.c:1246 msgid "don't include a patch matching a commit upstream" msgstr "no incloguis pedaços que coincideixin amb comissions a la font" -#: builtin/log.c:1245 +#: builtin/log.c:1248 msgid "show patch format instead of default (patch + stat)" msgstr "" "mostra el format de pedaç en lloc del per defecte (pedaç + estadístiques)" -#: builtin/log.c:1247 +#: builtin/log.c:1250 msgid "Messaging" msgstr "Missatgeria" -#: builtin/log.c:1248 +#: builtin/log.c:1251 msgid "header" msgstr "capçalera" -#: builtin/log.c:1249 +#: builtin/log.c:1252 msgid "add email header" msgstr "afegeix una capçalera de correu electrònic" -#: builtin/log.c:1250 builtin/log.c:1252 +#: builtin/log.c:1253 builtin/log.c:1255 msgid "email" msgstr "correu electrònic" -#: builtin/log.c:1250 +#: builtin/log.c:1253 msgid "add To: header" msgstr "afegeix la capçalera To:" -#: builtin/log.c:1252 +#: builtin/log.c:1255 msgid "add Cc: header" msgstr "afegeix la capçalera Cc:" -#: builtin/log.c:1254 +#: builtin/log.c:1257 msgid "ident" msgstr "identitat" -#: builtin/log.c:1255 +#: builtin/log.c:1258 msgid "set From address to (or committer ident if absent)" msgstr "" "estableix l'adreça From a (o la identitat del comitent si manca)" -#: builtin/log.c:1257 +#: builtin/log.c:1260 msgid "message-id" msgstr "ID de missatge" -#: builtin/log.c:1258 +#: builtin/log.c:1261 msgid "make first mail a reply to " msgstr "fes del primer missatge una resposta a " -#: builtin/log.c:1259 builtin/log.c:1262 +#: builtin/log.c:1262 builtin/log.c:1265 msgid "boundary" msgstr "límit" -#: builtin/log.c:1260 +#: builtin/log.c:1263 msgid "attach the patch" msgstr "ajunta el pedaç" -#: builtin/log.c:1263 +#: builtin/log.c:1266 msgid "inline the patch" msgstr "posa el pedaç en el cos" -#: builtin/log.c:1267 +#: builtin/log.c:1270 msgid "enable message threading, styles: shallow, deep" msgstr "habilita l'enfilada de missatges, estils: shallow, deep" -#: builtin/log.c:1269 +#: builtin/log.c:1272 msgid "signature" msgstr "firma" -#: builtin/log.c:1270 +#: builtin/log.c:1273 msgid "add a signature" msgstr "afegeix una firma" -#: builtin/log.c:1272 +#: builtin/log.c:1275 msgid "add a signature from a file" msgstr "afegeix una firma des d'un fitxer" -#: builtin/log.c:1273 +#: builtin/log.c:1276 msgid "don't print the patch filenames" msgstr "no imprimeixis els noms de fitxer del pedaç" -#: builtin/log.c:1362 +#: builtin/log.c:1365 msgid "-n and -k are mutually exclusive." msgstr "-n i -k són mutualment exclusius." -#: builtin/log.c:1364 +#: builtin/log.c:1367 msgid "--subject-prefix and -k are mutually exclusive." msgstr "--subject-prefix i -k són mutualment exclusius." -#: builtin/log.c:1372 +#: builtin/log.c:1375 msgid "--name-only does not make sense" msgstr "--name-only no té sentit" -#: builtin/log.c:1374 +#: builtin/log.c:1377 msgid "--name-status does not make sense" msgstr "--name-status no té sentit" -#: builtin/log.c:1376 +#: builtin/log.c:1379 msgid "--check does not make sense" msgstr "--check no té sentit" -#: builtin/log.c:1401 +#: builtin/log.c:1407 msgid "standard output, or directory, which one?" msgstr "sortida estàndard o directori, quin dels dos?" -#: builtin/log.c:1403 +#: builtin/log.c:1409 #, c-format msgid "Could not create directory '%s'" msgstr "No s'ha pogut crear el directori '%s'" -#: builtin/log.c:1500 +#: builtin/log.c:1506 #, c-format msgid "unable to read signature file '%s'" msgstr "no s'ha pogut llegir el fitxer de firma '%s'" -#: builtin/log.c:1563 +#: builtin/log.c:1569 msgid "Failed to create output files" msgstr "S'ha fallat en crear els fitxers de sortida" -#: builtin/log.c:1611 +#: builtin/log.c:1617 msgid "git cherry [-v] [ [ []]]" msgstr "git cherry [-v] [ [ []]]" -#: builtin/log.c:1665 +#: builtin/log.c:1671 #, c-format msgid "" "Could not find a tracked remote branch, please specify manually.\n" @@ -7403,105 +7618,156 @@ msgstr "" "No s'ha pogut trobar una branca remota seguida. Si us plau, especifiqueu " " manualment.\n" -#: builtin/log.c:1676 builtin/log.c:1678 builtin/log.c:1690 +#: builtin/log.c:1682 builtin/log.c:1684 builtin/log.c:1696 #, c-format msgid "Unknown commit %s" msgstr "Comissió desconeguda %s" -#: builtin/ls-files.c:358 +#: builtin/ls-files.c:378 msgid "git ls-files [] [...]" msgstr "git ls-files [] [...]" -#: builtin/ls-files.c:415 +#: builtin/ls-files.c:427 msgid "identify the file status with tags" msgstr "identifica l'estat de fitxer amb etiquetes" -#: builtin/ls-files.c:417 +#: builtin/ls-files.c:429 msgid "use lowercase letters for 'assume unchanged' files" msgstr "usa lletres minúscules per als fitxers 'assume unchanged'" -#: builtin/ls-files.c:419 +#: builtin/ls-files.c:431 msgid "show cached files in the output (default)" msgstr "" "mostra en la sortida els fitxers desats en la memòria cau (per defecte)" -#: builtin/ls-files.c:421 +#: builtin/ls-files.c:433 msgid "show deleted files in the output" msgstr "mostra en la sortida els fitxers suprimits" -#: builtin/ls-files.c:423 +#: builtin/ls-files.c:435 msgid "show modified files in the output" msgstr "mostra en la sortida els fitxers modificats" -#: builtin/ls-files.c:425 +#: builtin/ls-files.c:437 msgid "show other files in the output" msgstr "mostra en la sortida els altres fitxers" -#: builtin/ls-files.c:427 +#: builtin/ls-files.c:439 msgid "show ignored files in the output" msgstr "mostra en la sortida els fitxers ignorats" -#: builtin/ls-files.c:430 +#: builtin/ls-files.c:442 msgid "show staged contents' object name in the output" msgstr "mostra en la sortida el nom d'objecte dels continguts allistats" -#: builtin/ls-files.c:432 +#: builtin/ls-files.c:444 msgid "show files on the filesystem that need to be removed" msgstr "mostra els fitxers en el sistema de fitxers que s'han d'eliminar" -#: builtin/ls-files.c:434 +#: builtin/ls-files.c:446 msgid "show 'other' directories' names only" msgstr "mostra només els noms dels directoris 'other'" -#: builtin/ls-files.c:437 +#: builtin/ls-files.c:448 +msgid "show line endings of files" +msgstr "mostra els terminis de línia dels fitxers" + +#: builtin/ls-files.c:450 msgid "don't show empty directories" msgstr "no mostris els directoris buits" -#: builtin/ls-files.c:440 +#: builtin/ls-files.c:453 msgid "show unmerged files in the output" msgstr "mostra en la sortida els fitxers sense fusionar" -#: builtin/ls-files.c:442 +#: builtin/ls-files.c:455 msgid "show resolve-undo information" msgstr "mostra la informació de resolució de desfet" -#: builtin/ls-files.c:444 +#: builtin/ls-files.c:457 msgid "skip files matching pattern" msgstr "salta els fitxers coincidents amb el patró" -#: builtin/ls-files.c:447 +#: builtin/ls-files.c:460 msgid "exclude patterns are read from " msgstr "els patrons d'exclusió es llegeixen de " -#: builtin/ls-files.c:450 +#: builtin/ls-files.c:463 msgid "read additional per-directory exclude patterns in " msgstr "llegeix els patrons addicionals d'exclusió per directori en " -#: builtin/ls-files.c:452 +#: builtin/ls-files.c:465 msgid "add the standard git exclusions" msgstr "afegeix les exclusions estàndards de git" -#: builtin/ls-files.c:455 +#: builtin/ls-files.c:468 msgid "make the output relative to the project top directory" msgstr "fes que la sortida sigui relativa al directori superior del projecte" -#: builtin/ls-files.c:458 +#: builtin/ls-files.c:471 msgid "if any is not in the index, treat this as an error" msgstr "si qualsevol no és en l'índex, tracta això com a error" -#: builtin/ls-files.c:459 +#: builtin/ls-files.c:472 msgid "tree-ish" msgstr "arbre" -#: builtin/ls-files.c:460 +#: builtin/ls-files.c:473 msgid "pretend that paths removed since are still present" msgstr "" "pretén que els camins eliminats després de encara siguin presents" -#: builtin/ls-files.c:462 +#: builtin/ls-files.c:475 msgid "show debugging data" msgstr "mostra les dades de depuració" +#: builtin/ls-remote.c:7 +msgid "" +"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=]\n" +" [-q | --quiet] [--exit-code] [--get-url]\n" +" [--symref] [ [...]]" +msgstr "" +"git ls-remote [--heads] [--tags] [--refs]\n" +" [--upload-pack=] [-q | --quiet]\n" +" [--exit-code] [--get-url] [--symref]\n" +" [ [...]]" + +#: builtin/ls-remote.c:50 +msgid "do not print remote URL" +msgstr "no imprimeixis l'URL remot" + +#: builtin/ls-remote.c:51 builtin/ls-remote.c:53 +msgid "exec" +msgstr "executable" + +#: builtin/ls-remote.c:52 builtin/ls-remote.c:54 +msgid "path of git-upload-pack on the remote host" +msgstr "camí a git-upload-pack en la màquina remota" + +#: builtin/ls-remote.c:56 +msgid "limit to tags" +msgstr "limita a etiquetes" + +#: builtin/ls-remote.c:57 +msgid "limit to heads" +msgstr "limita a caps" + +#: builtin/ls-remote.c:58 +msgid "do not show peeled tags" +msgstr "no mostris les etiquetes pelades" + +#: builtin/ls-remote.c:60 +msgid "take url..insteadOf into account" +msgstr "tingues en compte url..insteadOf" + +#: builtin/ls-remote.c:62 +msgid "exit with exit code 2 if no matching refs are found" +msgstr "surt amb codi de sortida 2 si no es troba cap referència coincident" + +#: builtin/ls-remote.c:64 +msgid "show underlying ref in addition to the object pointed by it" +msgstr "mostra la referència subjacent en adició a l'objecte que senyali" + #: builtin/ls-tree.c:28 msgid "git ls-tree [] [...]" msgstr "git ls-tree [] [...]" @@ -7570,33 +7836,33 @@ msgstr "Les estratègies disponibles són:" msgid "Available custom strategies are:" msgstr "Les estratègies personalitzades disponibles són:" -#: builtin/merge.c:193 builtin/pull.c:119 +#: builtin/merge.c:193 builtin/pull.c:123 msgid "do not show a diffstat at the end of the merge" msgstr "no mostris les estadístiques de diferència al final de la fusió" -#: builtin/merge.c:196 builtin/pull.c:122 +#: builtin/merge.c:196 builtin/pull.c:126 msgid "show a diffstat at the end of the merge" msgstr "mostra les estadístiques de diferència al final de la fusió" -#: builtin/merge.c:197 builtin/pull.c:125 +#: builtin/merge.c:197 builtin/pull.c:129 msgid "(synonym to --stat)" msgstr "(sinònim de --stat)" -#: builtin/merge.c:199 builtin/pull.c:128 +#: builtin/merge.c:199 builtin/pull.c:132 msgid "add (at most ) entries from shortlog to merge commit message" msgstr "" "afegeix (com a màxim ) entrades del registre curt al missatge de comissió " "de fusió" -#: builtin/merge.c:202 builtin/pull.c:131 +#: builtin/merge.c:202 builtin/pull.c:135 msgid "create a single commit instead of doing a merge" msgstr "crea una única comissió en lloc de fusionar" -#: builtin/merge.c:204 builtin/pull.c:134 +#: builtin/merge.c:204 builtin/pull.c:138 msgid "perform a commit if the merge succeeds (default)" msgstr "realitza una comissió si la fusió té èxit (per defecte)" -#: builtin/merge.c:206 builtin/pull.c:137 +#: builtin/merge.c:206 builtin/pull.c:141 msgid "edit message before committing" msgstr "edita el missatge abans de cometre" @@ -7604,7 +7870,7 @@ msgstr "edita el missatge abans de cometre" msgid "allow fast-forward (default)" msgstr "permet l'avanç ràpid (per defecte)" -#: builtin/merge.c:209 builtin/pull.c:143 +#: builtin/merge.c:209 builtin/pull.c:147 msgid "abort if fast-forward is not possible" msgstr "avorta si l'avanç ràpid no és possible" @@ -7612,20 +7878,20 @@ msgstr "avorta si l'avanç ràpid no és possible" msgid "Verify that the named commit has a valid GPG signature" msgstr "Verifica que la comissió anomenada tingui una firma GPG vàlida" -#: builtin/merge.c:214 builtin/notes.c:767 builtin/pull.c:148 +#: builtin/merge.c:214 builtin/notes.c:770 builtin/pull.c:152 #: builtin/revert.c:89 msgid "strategy" msgstr "estratègia" -#: builtin/merge.c:215 builtin/pull.c:149 +#: builtin/merge.c:215 builtin/pull.c:153 msgid "merge strategy to use" msgstr "estratègia de fusió a usar" -#: builtin/merge.c:216 builtin/pull.c:152 +#: builtin/merge.c:216 builtin/pull.c:156 msgid "option=value" msgstr "opció=valor" -#: builtin/merge.c:217 builtin/pull.c:153 +#: builtin/merge.c:217 builtin/pull.c:157 msgid "option for selected merge strategy" msgstr "opció per a l'estratègia de fusió seleccionada" @@ -7663,8 +7929,8 @@ msgstr " (res a aixafar)" msgid "Squash commit -- not updating HEAD\n" msgstr "Comissió d'aixafada -- no actualitzant HEAD\n" -#: builtin/merge.c:344 builtin/merge.c:763 builtin/merge.c:975 -#: builtin/merge.c:988 +#: builtin/merge.c:344 builtin/merge.c:764 builtin/merge.c:976 +#: builtin/merge.c:989 #, c-format msgid "Could not write to '%s'" msgstr "No s'ha pogut escriure al '%s'" @@ -7682,41 +7948,41 @@ msgstr "Finalitzant SQUASH_MSG" msgid "No merge message -- not updating HEAD\n" msgstr "Cap missatge de fusió -- no actualitzant HEAD\n" -#: builtin/merge.c:447 +#: builtin/merge.c:448 #, c-format msgid "'%s' does not point to a commit" msgstr "'%s' no assenyala una comissió" -#: builtin/merge.c:537 +#: builtin/merge.c:538 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Cadena branch.%s.mergeoptions dolenta: %s" -#: builtin/merge.c:656 +#: builtin/merge.c:657 msgid "Not handling anything other than two heads merge." msgstr "No gestionant res a part de la fusió de dos caps." -#: builtin/merge.c:670 +#: builtin/merge.c:671 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "Opció desconeguda de merge-recursive: -X%s" -#: builtin/merge.c:683 +#: builtin/merge.c:684 #, c-format msgid "unable to write %s" msgstr "no s'ha pogut escriure %s" -#: builtin/merge.c:772 +#: builtin/merge.c:773 #, c-format msgid "Could not read from '%s'" msgstr "No s'ha pogut llegir de '%s'" -#: builtin/merge.c:781 +#: builtin/merge.c:782 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "No cometent la fusió; useu 'git commit' per a completar la fusió.\n" -#: builtin/merge.c:787 +#: builtin/merge.c:788 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -7732,54 +7998,54 @@ msgstr "" "S'ignoraran les línies que comencin amb '%c', i un missatge buit\n" "avorta la comissió.\n" -#: builtin/merge.c:811 +#: builtin/merge.c:812 msgid "Empty commit message." msgstr "Missatge de comissió buit." -#: builtin/merge.c:823 +#: builtin/merge.c:824 #, c-format msgid "Wonderful.\n" msgstr "Meravellós.\n" -#: builtin/merge.c:878 +#: builtin/merge.c:879 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" "La fusió automàtica ha fallat; arregleu els conflictes i després cometeu el " "resultat.\n" -#: builtin/merge.c:894 +#: builtin/merge.c:895 #, c-format msgid "'%s' is not a commit" msgstr "'%s' no és una comissió" -#: builtin/merge.c:935 +#: builtin/merge.c:936 msgid "No current branch." msgstr "Cap branca actual." -#: builtin/merge.c:937 +#: builtin/merge.c:938 msgid "No remote for the current branch." msgstr "No hi ha cap remot per a la branca actual." -#: builtin/merge.c:939 +#: builtin/merge.c:940 msgid "No default upstream defined for the current branch." msgstr "No hi ha cap font per defecte definida per a la branca actual." -#: builtin/merge.c:944 +#: builtin/merge.c:945 #, c-format msgid "No remote-tracking branch for %s from %s" msgstr "No hi ha cap branca amb seguiment remot per a %s de %s" -#: builtin/merge.c:1079 +#: builtin/merge.c:1080 #, c-format msgid "could not close '%s'" msgstr "no s'ha pogut tancar '%s'" -#: builtin/merge.c:1206 +#: builtin/merge.c:1207 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "No hi ha fusió a avortar (manca MERGE_HEAD)." -#: builtin/merge.c:1222 +#: builtin/merge.c:1223 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you merge." @@ -7787,7 +8053,7 @@ msgstr "" "No heu conclòs la vostra fusió (MERGE_HEAD existeix).\n" "Si us plau, cometeu els vostres canvis abans de fusionar." -#: builtin/merge.c:1229 +#: builtin/merge.c:1230 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you merge." @@ -7795,103 +8061,103 @@ msgstr "" "No heu conclòs el vostre recull de cireres (CHERRY_PICK_HEAD existeix).\n" "Si us plau, cometeu els vostres canvis abans de fusionar." -#: builtin/merge.c:1232 +#: builtin/merge.c:1233 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "" "No heu conclòs el vostre recull de cireres (CHERRY_PICK_HEAD existeix)." -#: builtin/merge.c:1241 +#: builtin/merge.c:1242 msgid "You cannot combine --squash with --no-ff." msgstr "No podeu combinar --squash amb --no-ff." -#: builtin/merge.c:1249 +#: builtin/merge.c:1250 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "" "No hi ha una comissió especificada i merge.defaultToUpstream no està " "establert." -#: builtin/merge.c:1266 +#: builtin/merge.c:1267 msgid "Squash commit into empty head not supported yet" msgstr "Aixafar una comissió a un cap buit encara no es permet" -#: builtin/merge.c:1268 +#: builtin/merge.c:1269 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "Una comissió no d'avanç ràpid no té sentit a un cap buit" -#: builtin/merge.c:1274 +#: builtin/merge.c:1275 #, c-format msgid "%s - not something we can merge" msgstr "%s - no és una cosa que puguem fusionar" -#: builtin/merge.c:1276 +#: builtin/merge.c:1277 msgid "Can merge only exactly one commit into empty head" msgstr "Es pot fusionar no més d'exactament una comissió a un cap buit" -#: builtin/merge.c:1331 +#: builtin/merge.c:1332 #, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "La comissió %s té una firma GPG no fiable, suposadament de %s." -#: builtin/merge.c:1334 +#: builtin/merge.c:1335 #, c-format msgid "Commit %s has a bad GPG signature allegedly by %s." msgstr "La comissió %s té una firma GPG dolenta suposadament de %s." -#: builtin/merge.c:1337 +#: builtin/merge.c:1338 #, c-format msgid "Commit %s does not have a GPG signature." msgstr "La comissió %s no té firma GPG." -#: builtin/merge.c:1340 +#: builtin/merge.c:1341 #, c-format msgid "Commit %s has a good GPG signature by %s\n" msgstr "La comissió %s té una firma GPG bona de %s\n" -#: builtin/merge.c:1423 +#: builtin/merge.c:1424 #, c-format msgid "Updating %s..%s\n" msgstr "Actualitzant %s..%s\n" -#: builtin/merge.c:1460 +#: builtin/merge.c:1461 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "Intentant una fusió molt trivial en l'índex...\n" -#: builtin/merge.c:1467 +#: builtin/merge.c:1468 #, c-format msgid "Nope.\n" msgstr "No.\n" -#: builtin/merge.c:1499 +#: builtin/merge.c:1500 msgid "Not possible to fast-forward, aborting." msgstr "No és possible avançar ràpidament, avortant." -#: builtin/merge.c:1522 builtin/merge.c:1601 +#: builtin/merge.c:1523 builtin/merge.c:1602 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "Rebobinant l'arbre a la pristina...\n" -#: builtin/merge.c:1526 +#: builtin/merge.c:1527 #, c-format msgid "Trying merge strategy %s...\n" msgstr "Intentant l'estratègia de fusió %s...\n" -#: builtin/merge.c:1592 +#: builtin/merge.c:1593 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "Cap estratègia de fusió ha gestionat la fusió.\n" -#: builtin/merge.c:1594 +#: builtin/merge.c:1595 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "L'estratègia de fusió %s ha fallat.\n" -#: builtin/merge.c:1603 +#: builtin/merge.c:1604 #, c-format msgid "Using the %s to prepare resolving by hand.\n" msgstr "Usant el %s per a preparar la resolució a mà.\n" -#: builtin/merge.c:1615 +#: builtin/merge.c:1616 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -7979,19 +8245,19 @@ msgstr "no avisis de conflictes" msgid "set labels for file1/orig-file/file2" msgstr "estableix les etiquetes per a fitxer1/fitxer-original/fitxer2" -#: builtin/mktree.c:64 +#: builtin/mktree.c:65 msgid "git mktree [-z] [--missing] [--batch]" msgstr "git mktree [-z] [--missing] [--batch]" -#: builtin/mktree.c:150 +#: builtin/mktree.c:152 msgid "input is NUL terminated" msgstr "l'entrada és acabada amb NUL" -#: builtin/mktree.c:151 builtin/write-tree.c:24 +#: builtin/mktree.c:153 builtin/write-tree.c:24 msgid "allow missing objects" msgstr "permet els objectes absents" -#: builtin/mktree.c:152 +#: builtin/mktree.c:154 msgid "allow creation of more than one tree" msgstr "permet la creació de més d'un arbre" @@ -7999,92 +8265,92 @@ msgstr "permet la creació de més d'un arbre" msgid "git mv [] ... " msgstr "git mv [] ... " -#: builtin/mv.c:69 +#: builtin/mv.c:70 #, c-format msgid "Directory %s is in index and no submodule?" msgstr "El directori %s és en l'índex i no hi ha cap submòdul?" -#: builtin/mv.c:71 +#: builtin/mv.c:72 msgid "Please stage your changes to .gitmodules or stash them to proceed" msgstr "" "Si us plau, allisteu els vostres canvis a .gitmodules o emmagatzemeu-los per " "a procedir" -#: builtin/mv.c:89 +#: builtin/mv.c:90 #, c-format msgid "%.*s is in index" msgstr "%.*s és en l'índex" -#: builtin/mv.c:111 +#: builtin/mv.c:112 msgid "force move/rename even if target exists" msgstr "força el moviment / canvi de nom encara que el destí existeixi" -#: builtin/mv.c:112 +#: builtin/mv.c:113 msgid "skip move/rename errors" msgstr "omet els errors de moviment / canvi de nom" -#: builtin/mv.c:151 +#: builtin/mv.c:152 #, c-format msgid "destination '%s' is not a directory" msgstr "el destí '%s' no és un directori" -#: builtin/mv.c:162 +#: builtin/mv.c:163 #, c-format msgid "Checking rename of '%s' to '%s'\n" msgstr "Comprovant el canvi de nom de '%s' a '%s'\n" -#: builtin/mv.c:166 +#: builtin/mv.c:167 msgid "bad source" msgstr "font dolenta" -#: builtin/mv.c:169 +#: builtin/mv.c:170 msgid "can not move directory into itself" msgstr "no es pot moure un directori a dins d'ell mateix" -#: builtin/mv.c:172 +#: builtin/mv.c:173 msgid "cannot move directory over file" msgstr "no es pot moure un directori sobre un fitxer" -#: builtin/mv.c:181 +#: builtin/mv.c:182 msgid "source directory is empty" msgstr "el directori font està buit" -#: builtin/mv.c:206 +#: builtin/mv.c:207 msgid "not under version control" msgstr "no està sota control de versions" -#: builtin/mv.c:209 +#: builtin/mv.c:210 msgid "destination exists" msgstr "el destí existeix" -#: builtin/mv.c:217 +#: builtin/mv.c:218 #, c-format msgid "overwriting '%s'" msgstr "sobreescrivint '%s'" -#: builtin/mv.c:220 +#: builtin/mv.c:221 msgid "Cannot overwrite" msgstr "No es pot sobreescriure" -#: builtin/mv.c:223 +#: builtin/mv.c:224 msgid "multiple sources for the same target" msgstr "múltiples fonts per al mateix destí" -#: builtin/mv.c:225 +#: builtin/mv.c:226 msgid "destination directory does not exist" msgstr "el directori destí no existeix" -#: builtin/mv.c:232 +#: builtin/mv.c:233 #, c-format msgid "%s, source=%s, destination=%s" msgstr "%s, origen=%s, destí=%s" -#: builtin/mv.c:253 +#: builtin/mv.c:254 #, c-format msgid "Renaming %s to %s\n" msgstr "Canviant el nom de %s a %s\n" -#: builtin/mv.c:256 builtin/remote.c:728 builtin/repack.c:365 +#: builtin/mv.c:257 builtin/remote.c:714 builtin/repack.c:365 #, c-format msgid "renaming '%s' failed" msgstr "el canvi del nom de '%s' ha fallat" @@ -8287,9 +8553,9 @@ msgid "could not open or read '%s'" msgstr "no s'ha pogut obrir o llegir '%s'" #: builtin/notes.c:253 builtin/notes.c:304 builtin/notes.c:306 -#: builtin/notes.c:366 builtin/notes.c:421 builtin/notes.c:507 -#: builtin/notes.c:512 builtin/notes.c:590 builtin/notes.c:653 -#: builtin/notes.c:877 builtin/tag.c:456 +#: builtin/notes.c:369 builtin/notes.c:424 builtin/notes.c:510 +#: builtin/notes.c:515 builtin/notes.c:593 builtin/notes.c:656 +#: builtin/notes.c:880 builtin/tag.c:456 #, c-format msgid "Failed to resolve '%s' as a valid ref." msgstr "S'ha fallat en resoldre '%s' com a referència vàlida." @@ -8304,42 +8570,42 @@ msgstr "S'ha fallat en llegir l'objecte '%s'." msgid "Cannot read note data from non-blob object '%s'." msgstr "No es pot llegir les dades de node de l'objecte no de blob '%s'." -#: builtin/notes.c:359 builtin/notes.c:414 builtin/notes.c:490 -#: builtin/notes.c:502 builtin/notes.c:578 builtin/notes.c:646 -#: builtin/notes.c:942 +#: builtin/notes.c:362 builtin/notes.c:417 builtin/notes.c:493 +#: builtin/notes.c:505 builtin/notes.c:581 builtin/notes.c:649 +#: builtin/notes.c:945 msgid "too many parameters" msgstr "massa paràmetres" -#: builtin/notes.c:372 builtin/notes.c:659 +#: builtin/notes.c:375 builtin/notes.c:662 #, c-format msgid "No note found for object %s." msgstr "No s'ha trobat cap nota per a l'objecte %s." -#: builtin/notes.c:393 builtin/notes.c:556 +#: builtin/notes.c:396 builtin/notes.c:559 msgid "note contents as a string" msgstr "anota els continguts com a cadena" -#: builtin/notes.c:396 builtin/notes.c:559 +#: builtin/notes.c:399 builtin/notes.c:562 msgid "note contents in a file" msgstr "anota els continguts en un fitxer" -#: builtin/notes.c:399 builtin/notes.c:562 +#: builtin/notes.c:402 builtin/notes.c:565 msgid "reuse and edit specified note object" msgstr "reusa i edita l'objecte de nota especificat" -#: builtin/notes.c:402 builtin/notes.c:565 +#: builtin/notes.c:405 builtin/notes.c:568 msgid "reuse specified note object" msgstr "reusa l'objecte de nota especificat" -#: builtin/notes.c:405 builtin/notes.c:568 +#: builtin/notes.c:408 builtin/notes.c:571 msgid "allow storing empty note" msgstr "permet l'emmagatzematge d'una nota buida" -#: builtin/notes.c:406 builtin/notes.c:477 +#: builtin/notes.c:409 builtin/notes.c:480 msgid "replace existing notes" msgstr "reemplaça les notes existents" -#: builtin/notes.c:431 +#: builtin/notes.c:434 #, c-format msgid "" "Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite " @@ -8348,30 +8614,30 @@ msgstr "" "No es pot afegir les notes. S'han trobat notes existents de l'objecte %s. " "Useu '-f' per a sobreescriure les notes existents." -#: builtin/notes.c:446 builtin/notes.c:525 +#: builtin/notes.c:449 builtin/notes.c:528 #, c-format msgid "Overwriting existing notes for object %s\n" msgstr "Sobreescrivint les notes existents de l'objecte %s\n" -#: builtin/notes.c:457 builtin/notes.c:618 builtin/notes.c:882 +#: builtin/notes.c:460 builtin/notes.c:621 builtin/notes.c:885 #, c-format msgid "Removing note for object %s\n" msgstr "Eliminant la nota de l'objecte %s\n" -#: builtin/notes.c:478 +#: builtin/notes.c:481 msgid "read objects from stdin" msgstr "llegeix els objectes des d'stdin" -#: builtin/notes.c:480 +#: builtin/notes.c:483 msgid "load rewriting config for (implies --stdin)" msgstr "" "carrega la configuració de reescriptura per a (implica --stdin)" -#: builtin/notes.c:498 +#: builtin/notes.c:501 msgid "too few parameters" msgstr "hi ha massa pocs paràmetres" -#: builtin/notes.c:519 +#: builtin/notes.c:522 #, c-format msgid "" "Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite " @@ -8380,12 +8646,12 @@ msgstr "" "No es pot copiar les notes. S'han trobat notes existents de l'objecte %s. " "Useu '-f' per a sobreescriure les notes existents." -#: builtin/notes.c:531 +#: builtin/notes.c:534 #, c-format msgid "Missing notes on source object %s. Cannot copy." msgstr "Manquen notes a l'objecte font %s. No es pot copiar." -#: builtin/notes.c:583 +#: builtin/notes.c:586 #, c-format msgid "" "The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n" @@ -8394,15 +8660,15 @@ msgstr "" "S'han desaprovat les opcions -m/-F/-c/-C en favor de la subordre 'edit'.\n" "Si us plau, useu 'git notes add -f -m/-F/-c/-C' en lloc d'això.\n" -#: builtin/notes.c:764 +#: builtin/notes.c:767 msgid "General options" msgstr "Opcions generals" -#: builtin/notes.c:766 +#: builtin/notes.c:769 msgid "Merge options" msgstr "Opcions de fusió" -#: builtin/notes.c:768 +#: builtin/notes.c:771 msgid "" "resolve notes conflicts using the given strategy (manual/ours/theirs/union/" "cat_sort_uniq)" @@ -8410,49 +8676,49 @@ msgstr "" "resol els conflictes de nota usant l'estratègia donada (manual/ours/theirs/" "union/cat_sort_uniq)" -#: builtin/notes.c:770 +#: builtin/notes.c:773 msgid "Committing unmerged notes" msgstr "Cometent les notes sense fusionar" -#: builtin/notes.c:772 +#: builtin/notes.c:775 msgid "finalize notes merge by committing unmerged notes" msgstr "finalitza la fusió de notes cometent les notes sense fusionar" -#: builtin/notes.c:774 +#: builtin/notes.c:777 msgid "Aborting notes merge resolution" msgstr "Avortant la resolució de fusió de notes" -#: builtin/notes.c:776 +#: builtin/notes.c:779 msgid "abort notes merge" msgstr "avorta la fusió de notes" -#: builtin/notes.c:853 +#: builtin/notes.c:856 #, c-format msgid "A notes merge into %s is already in-progress at %s" msgstr "Una fusió de notes a %s ja està en curs a %s" -#: builtin/notes.c:880 +#: builtin/notes.c:883 #, c-format msgid "Object %s has no note\n" msgstr "L'objecte %s no té cap nota\n" -#: builtin/notes.c:892 +#: builtin/notes.c:895 msgid "attempt to remove non-existent note is not an error" msgstr "l'intent d'eliminar una nota no existent no és un error" -#: builtin/notes.c:895 +#: builtin/notes.c:898 msgid "read object names from the standard input" msgstr "llegeix els noms d'objecte des de l'entrada estàndard" -#: builtin/notes.c:976 +#: builtin/notes.c:979 msgid "notes-ref" msgstr "referència de notes" -#: builtin/notes.c:977 +#: builtin/notes.c:980 msgid "use notes from " msgstr "usa les notes de " -#: builtin/notes.c:1012 builtin/remote.c:1647 +#: builtin/notes.c:1015 builtin/remote.c:1626 #, c-format msgid "Unknown subcommand: %s" msgstr "Subordre desconeguda: %s" @@ -8476,176 +8742,176 @@ msgstr "" msgid "deflate error (%d)" msgstr "error de deflació (%d)" -#: builtin/pack-objects.c:771 +#: builtin/pack-objects.c:772 msgid "Writing objects" msgstr "Escrivint els objectes" -#: builtin/pack-objects.c:1011 +#: builtin/pack-objects.c:1012 msgid "disabling bitmap writing, as some objects are not being packed" msgstr "" "inhabilitant l'escriptura de mapes de bits, perquè alguns objectes no " "s'estan empaquetant" -#: builtin/pack-objects.c:2171 +#: builtin/pack-objects.c:2172 msgid "Compressing objects" msgstr "Comprimint objectes" -#: builtin/pack-objects.c:2568 +#: builtin/pack-objects.c:2558 #, c-format msgid "unsupported index version %s" msgstr "versió d'índex no compatible %s" -#: builtin/pack-objects.c:2572 +#: builtin/pack-objects.c:2562 #, c-format msgid "bad index version '%s'" msgstr "versió d'índex dolenta '%s'" -#: builtin/pack-objects.c:2602 +#: builtin/pack-objects.c:2592 msgid "do not show progress meter" msgstr "no mostris l'indicador de progrés" -#: builtin/pack-objects.c:2604 +#: builtin/pack-objects.c:2594 msgid "show progress meter" msgstr "mostra l'indicador de progrés" -#: builtin/pack-objects.c:2606 +#: builtin/pack-objects.c:2596 msgid "show progress meter during object writing phase" msgstr "mostra l'indicador de progrés durant la fase d'escriptura d'objectes" -#: builtin/pack-objects.c:2609 +#: builtin/pack-objects.c:2599 msgid "similar to --all-progress when progress meter is shown" msgstr "similar a --all-progress quan l'indicador de progrés es mostra" -#: builtin/pack-objects.c:2610 +#: builtin/pack-objects.c:2600 msgid "version[,offset]" msgstr "versió[,desplaçament]" -#: builtin/pack-objects.c:2611 +#: builtin/pack-objects.c:2601 msgid "write the pack index file in the specified idx format version" msgstr "" "escriu el fitxer d'índex de paquet en la versió de format d'índex " "especificada" -#: builtin/pack-objects.c:2614 +#: builtin/pack-objects.c:2604 msgid "maximum size of each output pack file" msgstr "mida màxima de cada fitxer de paquet de sortida" -#: builtin/pack-objects.c:2616 +#: builtin/pack-objects.c:2606 msgid "ignore borrowed objects from alternate object store" msgstr "" "ignora els objectes prestats d'un emmagatzemament d'objectes alternatiu" -#: builtin/pack-objects.c:2618 +#: builtin/pack-objects.c:2608 msgid "ignore packed objects" msgstr "ignora els objectes empaquetats" -#: builtin/pack-objects.c:2620 +#: builtin/pack-objects.c:2610 msgid "limit pack window by objects" msgstr "limita la finestra d'empaquetament per objectes" -#: builtin/pack-objects.c:2622 +#: builtin/pack-objects.c:2612 msgid "limit pack window by memory in addition to object limit" msgstr "" "limita la finestra d'empaquetament per memòria a més del límit d'objectes" -#: builtin/pack-objects.c:2624 +#: builtin/pack-objects.c:2614 msgid "maximum length of delta chain allowed in the resulting pack" msgstr "longitud màxima de la cadena de deltes permesa en el paquet resultant" -#: builtin/pack-objects.c:2626 +#: builtin/pack-objects.c:2616 msgid "reuse existing deltas" msgstr "reusa les deltes existents" -#: builtin/pack-objects.c:2628 +#: builtin/pack-objects.c:2618 msgid "reuse existing objects" msgstr "reusa els objectes existents" -#: builtin/pack-objects.c:2630 +#: builtin/pack-objects.c:2620 msgid "use OFS_DELTA objects" msgstr "usa objectes OFS_DELTA" -#: builtin/pack-objects.c:2632 +#: builtin/pack-objects.c:2622 msgid "use threads when searching for best delta matches" msgstr "usa fils en cercar les millores coincidències de delta" -#: builtin/pack-objects.c:2634 +#: builtin/pack-objects.c:2624 msgid "do not create an empty pack output" msgstr "no creïs una emissió de paquet buida" -#: builtin/pack-objects.c:2636 +#: builtin/pack-objects.c:2626 msgid "read revision arguments from standard input" msgstr "llegeix els paràmetres de revisió des de l'entrada estàndard" -#: builtin/pack-objects.c:2638 +#: builtin/pack-objects.c:2628 msgid "limit the objects to those that are not yet packed" msgstr "limita els objectes als quals encara no s'hagin empaquetat" -#: builtin/pack-objects.c:2641 +#: builtin/pack-objects.c:2631 msgid "include objects reachable from any reference" msgstr "inclou els objectes abastables de qualsevulla referència" -#: builtin/pack-objects.c:2644 +#: builtin/pack-objects.c:2634 msgid "include objects referred by reflog entries" msgstr "" "inclou els objectes als quals facin referència les entrades del registre de " "referències" -#: builtin/pack-objects.c:2647 +#: builtin/pack-objects.c:2637 msgid "include objects referred to by the index" msgstr "inclou els objectes als quals faci referència l'índex" -#: builtin/pack-objects.c:2650 +#: builtin/pack-objects.c:2640 msgid "output pack to stdout" msgstr "emet el paquet a stdout" -#: builtin/pack-objects.c:2652 +#: builtin/pack-objects.c:2642 msgid "include tag objects that refer to objects to be packed" msgstr "" "inclou els objectes d'etiqueta que facin referència als objectes a empaquetar" -#: builtin/pack-objects.c:2654 +#: builtin/pack-objects.c:2644 msgid "keep unreachable objects" msgstr "retén els objectes inabastables" -#: builtin/pack-objects.c:2655 parse-options.h:142 +#: builtin/pack-objects.c:2645 parse-options.h:142 msgid "time" msgstr "hora" -#: builtin/pack-objects.c:2656 +#: builtin/pack-objects.c:2646 msgid "unpack unreachable objects newer than