diff options
229 files changed, 6870 insertions, 1494 deletions
diff --git a/Documentation/RelNotes-1.5.4.7.txt b/Documentation/RelNotes-1.5.4.7.txt new file mode 100644 index 0000000000..9065a0e273 --- /dev/null +++ b/Documentation/RelNotes-1.5.4.7.txt @@ -0,0 +1,10 @@ +GIT v1.5.4.7 Release Notes +========================== + +Fixes since 1.5.4.7 +------------------- + + * Removed support for an obsolete gitweb request URI, whose + implementation ran "git diff" Porcelain, instead of using plumbing, + which would have run an external diff command specified in the + repository configuration as the gitweb user. diff --git a/Documentation/RelNotes-1.5.5.6.txt b/Documentation/RelNotes-1.5.5.6.txt new file mode 100644 index 0000000000..d5e85cb70e --- /dev/null +++ b/Documentation/RelNotes-1.5.5.6.txt @@ -0,0 +1,10 @@ +GIT v1.5.5.6 Release Notes +========================== + +Fixes since 1.5.5.5 +------------------- + + * Removed support for an obsolete gitweb request URI, whose + implementation ran "git diff" Porcelain, instead of using plumbing, + which would have run an external diff command specified in the + repository configuration as the gitweb user. diff --git a/Documentation/RelNotes-1.5.6.6.txt b/Documentation/RelNotes-1.5.6.6.txt new file mode 100644 index 0000000000..79da23db5a --- /dev/null +++ b/Documentation/RelNotes-1.5.6.6.txt @@ -0,0 +1,10 @@ +GIT v1.5.6.6 Release Notes +========================== + +Fixes since 1.5.6.5 +------------------- + + * Removed support for an obsolete gitweb request URI, whose + implementation ran "git diff" Porcelain, instead of using plumbing, + which would have run an external diff command specified in the + repository configuration as the gitweb user. diff --git a/Documentation/RelNotes-1.6.0.6.txt b/Documentation/RelNotes-1.6.0.6.txt new file mode 100644 index 0000000000..64ece1ffd5 --- /dev/null +++ b/Documentation/RelNotes-1.6.0.6.txt @@ -0,0 +1,33 @@ +GIT v1.6.0.6 Release Notes +========================== + +Fixes since 1.6.0.5 +------------------- + + * "git fsck" had a deep recursion that wasted stack space. + + * "git fast-export" and "git fast-import" choked on an old style + annotated tag that lack the tagger information. + + * "git mergetool -- file" did not correctly skip "--" marker that + signals the end of options list. + + * "git show $tag" segfaulted when an annotated $tag pointed at a + nonexistent object. + + * "git show 2>error" when the standard output is automatically redirected + to the pager redirected the standard error to the pager as well; there + was no need to. + + * "git send-email" did not correctly handle list of addresses when + they had quoted comma (e.g. "Lastname, Givenname" <mail@addre.ss>). + + * Logic to discover branch ancestry in "git svn" was unreliable when + the process to fetch history was interrupted. + + * Removed support for an obsolete gitweb request URI, whose + implementation ran "git diff" Porcelain, instead of using plumbing, + which would have run an external diff command specified in the + repository configuration as the gitweb user. + +Also contains numerous documentation typofixes. diff --git a/Documentation/RelNotes-1.6.1.1.txt b/Documentation/RelNotes-1.6.1.1.txt new file mode 100644 index 0000000000..88454c1973 --- /dev/null +++ b/Documentation/RelNotes-1.6.1.1.txt @@ -0,0 +1,59 @@ +GIT v1.6.1.1 Release Notes +========================== + +Fixes since v1.6.1 +------------------ + +* "git add frotz/nitfol" when "frotz" is a submodule should have errored + out, but it didn't. + +* "git apply" took file modes from the patch text and updated the mode + bits of the target tree even when the patch was not about mode changes. + +* "git bisect view" on Cygwin did not launch gitk + +* "git checkout $tree" did not trigger an error. + +* "git commit" tried to remove COMMIT_EDITMSG from the work tree by mistake. + +* "git describe --all" complained when a commit is described with a tag, + which was nonsense. + +* "git diff --no-index --" did not trigger no-index (aka "use git-diff as + a replacement of diff on untracked files") behaviour. + +* "git format-patch -1 HEAD" on a root commit failed to produce patch + text. + +* "git fsck branch" did not work as advertised; instead it behaved the same + way as "git fsck". + +* "git log --pretty=format:%s" did not handle a multi-line subject the + same way as built-in log listers (i.e. shortlog, --pretty=oneline, etc.) + +* "git daemon", and "git merge-file" are more careful when freopen fails + and barf, instead of going on and writing to unopened filehandle. + +* "git http-push" did not like some RFC 4918 compliant DAV server + responses. + +* "git merge -s recursive" mistakenly overwritten an untracked file in the + work tree upon delete/modify conflict. + +* "git merge -s recursive" didn't leave the index unmerged for entries with + rename/delete conflictd. + +* "git merge -s recursive" clobbered untracked files in the work tree. + +* "git mv -k" with more than one errorneous paths misbehaved. + +* "git read-tree -m -u" hence branch switching incorrectly lost a + subdirectory in rare cases. + +* "git rebase -i" issued an unnecessary error message upon a user error of + marking the first commit to be "squash"ed. + +* "git shortlog" did not format a commit message with multi-line + subject correctly. + +Many documentation updates. diff --git a/Documentation/RelNotes-1.6.1.2.txt b/Documentation/RelNotes-1.6.1.2.txt new file mode 100644 index 0000000000..230aa3d8e8 --- /dev/null +++ b/Documentation/RelNotes-1.6.1.2.txt @@ -0,0 +1,39 @@ +GIT v1.6.1.2 Release Notes +========================== + +Fixes since v1.6.1.1 +-------------------- + +* The logic for rename detectin in internal diff used by commands like + "git diff" and "git blame" have been optimized to avoid loading the same + blob repeatedly. + +* We did not allow writing out a blob that is larger than 2GB for no good + reason. + +* "git format-patch -o $dir", when $dir is a relative directory, used it + as relative to the root of the work tree, not relative to the current + directory. + +* v1.6.1 introduced an optimization for "git push" into a repository (A) + that borrows its objects from another repository (B) to avoid sending + objects that are available in repository B, when they are not yet used + by repository A. However the code on the "git push" sender side was + buggy and did not work when repository B had new objects that are not + known by the sender. This caused pushing into a "forked" repository + served by v1.6.1 software using "git push" from v1.6.1 sometimes did not + work. The bug was purely on the "git push" sender side, and has been + corrected. + +* "git status -v" did not paint its diff output in colour even when + color.ui configuration was set. + +* "git ls-tree" learned --full-tree option to help Porcelain scripts that + want to always see the full path regardless of the current working + directory. + +* "git grep" incorrectly searched in work tree paths even when they are + marked as assume-unchanged. It now searches in the index entries. + +* "git gc" with no grace period needlessly ejected packed but unreachable + objects in their loose form, only to delete them right away. diff --git a/Documentation/RelNotes-1.6.1.3.txt b/Documentation/RelNotes-1.6.1.3.txt new file mode 100644 index 0000000000..6f0bde156a --- /dev/null +++ b/Documentation/RelNotes-1.6.1.3.txt @@ -0,0 +1,32 @@ +GIT v1.6.1.3 Release Notes +========================== + +Fixes since v1.6.1.2 +-------------------- + +* "git diff --binary | git apply" pipeline did not work well when + a binary blob is changed to a symbolic link. + +* Some combinations of -b/-w/--ignore-space-at-eol to "git diff" did + not work as expected. + +* "git grep" did not pass the -I (ignore binary) option when + calling out an external grep program. + +* "git log" and friends include HEAD to the set of starting points + when --all is given. This makes a difference when you are not + on any branch. + +* "git mv" to move an untracked file to overwrite a tracked + contents misbehaved. + +* "git merge -s octopus" with many potential merge bases did not + work correctly. + +* RPM binary package installed the html manpages in a wrong place. + +Also includes minor documentation fixes and updates. + + +-- +git shortlog --no-merges v1.6.1.2-33-gc789350.. diff --git a/Documentation/RelNotes-1.6.1.4.txt b/Documentation/RelNotes-1.6.1.4.txt new file mode 100644 index 0000000000..a9f1a6b8b5 --- /dev/null +++ b/Documentation/RelNotes-1.6.1.4.txt @@ -0,0 +1,19 @@ +GIT v1.6.1.4 Release Notes +========================== + +Fixes since v1.6.1.3 +-------------------- + +* "git fast-export" produced wrong output with some parents missing from + commits, when the history is clock-skewed. + +* "git fast-import" sometimes failed to read back objects it just wrote + out and aborted, because it failed to flush stale cached data. + +* "git repack" did not error out when necessary object was missing in the + repository. + +Also includes minor documentation fixes and updates. + +-- +git shortlog --no-merges v1.6.1.3.. diff --git a/Documentation/RelNotes-1.6.1.txt b/Documentation/RelNotes-1.6.1.txt index 0405309743..adb7ccab0a 100644 --- a/Documentation/RelNotes-1.6.1.txt +++ b/Documentation/RelNotes-1.6.1.txt @@ -230,6 +230,13 @@ Fixes since v1.6.0 All of the fixes in v1.6.0.X maintenance series are included in this release, unless otherwise noted. +* Porcelains implemented as shell scripts were utterly confused when you + entered to a subdirectory of a work tree from sideways, following a + symbolic link (this may need to be backported to older releases later). + +* Tracking symbolic links would work better on filesystems whose lstat() + returns incorrect st_size value for them. + * "git add" and "git update-index" incorrectly allowed adding S/F when S is a tracked symlink that points at a directory D that has a path F in it (we still need to fix a similar nonsense when S is a submodule and F @@ -244,6 +251,20 @@ release, unless otherwise noted. * "git filter-branch" failed to rewrite a tag name with slashes in it. +* "git http-push" did not understand URI scheme other than opaquelocktoken + when acquiring a lock from the server (this may need to be backported to + older releases later). + +* After "git rebase -p" stopped with conflicts while replaying a merge, + "git rebase --continue" did not work (may need to be backported to older + releases). + +* "git revert" records relative to which parent a revert was made when + reverting a merge. Together with new documentation that explains issues + around reverting a merge and merging from the updated branch later, this + hopefully will reduce user confusion (this may need to be backported to + older releases later). + * "git rm --cached" used to allow an empty blob that was added earlier to be removed without --force, even when the file in the work tree has since been modified. @@ -260,6 +281,6 @@ release, unless otherwise noted. -- exec >/var/tmp/1 -O=v1.6.1-rc1-55-gd8af75d +O=v1.6.1-rc3-74-gf66bc5f echo O=$(git describe master) git shortlog --no-merges $O..master ^maint diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index f0295c60f5..ba07c8c571 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -222,6 +222,9 @@ D-C-O. Indeed you are encouraged to do so. Do not forget to place an in-body "From: " line at the beginning to properly attribute the change to its true author (see (2) above). +Also notice that a real name is used in the Signed-off-by: line. Please +don't hide your real name. + Some people also put extra tags at the end. "Acked-by:" says that the patch was reviewed by the person who diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt index 1ab1b96cf9..7f28432254 100644 --- a/Documentation/blame-options.txt +++ b/Documentation/blame-options.txt @@ -41,6 +41,13 @@ of lines before or after the line given by <start>. -S <revs-file>:: Use revs from revs-file instead of calling linkgit:git-rev-list[1]. +--reverse:: + Walk history forward instead of backward. Instead of showing + the revision in which a line appeared, this shows the last + revision in which a line has existed. This requires a range of + revision like START..END where the path to blame exists in + START. + -p:: --porcelain:: Show in a format designed for machine consumption. diff --git a/Documentation/config.txt b/Documentation/config.txt index b233fe5352..2ed868c81a 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -601,10 +601,6 @@ diff.autorefreshindex:: affects only 'git-diff' Porcelain, and not lower level 'diff' commands, such as 'git-diff-files'. -diff.suppress-blank-empty:: - A boolean to inhibit the standard behavior of printing a space - before each empty output line. Defaults to false. - diff.external:: If this config variable is set, diff generation is not performed using the internal diff machinery, but using the @@ -639,6 +635,10 @@ diff.renames:: will enable basic rename detection. If set to "copies" or "copy", it will detect copies, as well. +diff.suppressBlankEmpty:: + A boolean to inhibit the standard behavior of printing a space + before each empty output line. Defaults to false. + fetch.unpackLimit:: If the number of objects fetched over the git native transfer is below this @@ -702,7 +702,9 @@ gc.packrefs:: gc.pruneexpire:: When 'git-gc' is run, it will call 'prune --expire 2.weeks.ago'. - Override the grace period with this config variable. + Override the grace period with this config variable. The value + "now" may be used to disable this grace period and always prune + unreachable objects immediately. gc.reflogexpire:: 'git-reflog expire' removes reflog entries older than @@ -839,6 +841,57 @@ gui.blamehistoryctx:: Context` menu item is invoked from 'git gui blame'. If this variable is set to zero, the whole history is shown. +guitool.<name>.cmd:: + Specifies the shell command line to execute when the corresponding item + of the linkgit:git-gui[1] `Tools` menu is invoked. This option is + mandatory for every tool. The command is executed from the root of + the working directory, and in the environment it receives the name of + the tool as 'GIT_GUITOOL', the name of the currently selected file as + 'FILENAME', and the name of the current branch as 'CUR_BRANCH' (if + the head is detached, 'CUR_BRANCH' is empty). + +guitool.<name>.needsfile:: + Run the tool only if a diff is selected in the GUI. It guarantees + that 'FILENAME' is not empty. + +guitool.<name>.noconsole:: + Run the command silently, without creating a window to display its + output. + +guitool.<name>.norescan:: + Don't rescan the working directory for changes after the tool + finishes execution. + +guitool.<name>.confirm:: + Show a confirmation dialog before actually running the tool. + +guitool.<name>.argprompt:: + Request a string argument from the user, and pass it to the tool + through the 'ARGS' environment variable. Since requesting an + argument implies confirmation, the 'confirm' option has no effect + if this is enabled. If the option is set to 'true', 'yes', or '1', + the dialog uses a built-in generic prompt; otherwise the exact + value of the variable is used. + +guitool.<name>.revprompt:: + Request a single valid revision from the user, and set the + 'REVISION' environment variable. In other aspects this option + is similar to 'argprompt', and can be used together with it. + +guitool.<name>.revunmerged:: + Show only unmerged branches in the 'revprompt' subdialog. + This is useful for tools similar to merge or rebase, but not + for things like checkout or reset. + +guitool.<name>.title:: + Specifies the title to use for the prompt dialog. The default + is the tool name. + +guitool.<name>.prompt:: + Specifies the general prompt string to display at the top of + the dialog, before subsections for 'argprompt' and 'revprompt'. + The default value includes the actual command. + help.browser:: Specify the browser that will be used to display help in the 'web' format. See linkgit:git-help[1]. diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt index aafd3a3941..1eeb1c7683 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.txt @@ -58,7 +58,7 @@ Possible status letters are: be committed) - X: "unknown" change type (most probably a bug, please report it) -Status letters C and M are always followed by a score (denoting the +Status letters C and R are always followed by a score (denoting the percentage of similarity between the source and target of the move or copy), and are the only ones to be so. diff --git a/Documentation/diff-generate-patch.txt b/Documentation/diff-generate-patch.txt index 517e1eba3c..0f25ba7e38 100644 --- a/Documentation/diff-generate-patch.txt +++ b/Documentation/diff-generate-patch.txt @@ -143,15 +143,15 @@ different from it. A `-` character in the column N means that the line appears in fileN but it does not appear in the result. A `+` character -in the column N means that the line appears in the last file, +in the column N means that the line appears in the result, and fileN does not have that line (in other words, the line was added, from the point of view of that parent). In the above example output, the function signature was changed from both files (hence two `-` removals from both file1 and file2, plus `++` to mean one line that was added does not appear -in either file1 nor file2). Also two other lines are the same -from file1 but do not appear in file2 (hence prefixed with ` +`). +in either file1 nor file2). Also eight other lines are the same +from file1 but do not appear in file2 (hence prefixed with `{plus}`). When shown by `git diff-tree -c`, it compares the parents of a merge commit with the merge result (i.e. file1..fileN are the diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index c62b45cdba..b432d2518a 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -19,16 +19,12 @@ endif::git-format-patch[] ifndef::git-format-patch[] -p:: +-u:: Generate patch (see section on generating patches). {git-diff? This is the default.} endif::git-format-patch[] --u:: - Synonym for "-p". - -U<n>:: - Shorthand for "--unified=<n>". - --unified=<n>:: Generate diffs with <n> lines of context instead of the usual three. Implies "-p". @@ -190,31 +186,25 @@ endif::git-format-patch[] can name which subdirectory to make the output relative to by giving a <path> as an argument. +-a:: --text:: Treat all files as text. --a:: - Shorthand for "--text". - --ignore-space-at-eol:: Ignore changes in whitespace at EOL. +-b:: --ignore-space-change:: Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent. --b:: - Shorthand for "--ignore-space-change". - +-w:: --ignore-all-space:: Ignore whitespace when comparing lines. This ignores differences even if one line has whitespace where the other line has none. --w:: - Shorthand for "--ignore-all-space". - --exit-code:: Make the program exit with codes similar to diff(1). That is, it exits with 1 if there were differences and diff --git a/Documentation/everyday.txt b/Documentation/everyday.txt index e598cdda45..9310b650d3 100644 --- a/Documentation/everyday.txt +++ b/Documentation/everyday.txt @@ -98,7 +98,7 @@ Use a tarball as a starting point for a new repository.:: ------------ $ tar zxf frotz.tar.gz $ cd frotz -$ git-init +$ git init $ git add . <1> $ git commit -m "import of frotz source tree." $ git tag v2.43 <2> diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index 7c129cb24f..e4c711bbd2 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -136,7 +136,7 @@ $ git add Documentation/\\*.txt ------------ + Note that the asterisk `\*` is quoted from the shell in this -example; this lets the command to include the files from +example; this lets the command include the files from subdirectories of `Documentation/` directory. * Considers adding content from all git-*.sh scripts: @@ -145,7 +145,7 @@ subdirectories of `Documentation/` directory. $ git add git-*.sh ------------ + -Because this example lets shell expand the asterisk (i.e. you are +Because this example lets the shell expand the asterisk (i.e. you are listing the files explicitly), it does not consider `subdir/git-foo.sh`. @@ -198,8 +198,8 @@ one deletion). update:: - This shows the status information and gives prompt - "Update>>". When the prompt ends with double '>>', you can + This shows the status information and issues an "Update>>" + prompt. When the prompt ends with double '>>', you can make more than one selection, concatenated with whitespace or comma. Also you can say ranges. E.g. "2-5 7,9" to choose 2,3,4,5,7,9 from the list. If the second number in a range is @@ -238,8 +238,8 @@ add untracked:: patch:: - This lets you choose one path out of 'status' like selection. - After choosing the path, it presents diff between the index + This lets you choose one path out of a 'status' like selection. + After choosing the path, it presents the diff between the index and the working tree file and asks you if you want to stage the change of each hunk. You can say: diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index e726510ab1..32f2b85a10 100644 --- a/Documentation/git-apply.txt +++ b/Documentation/git-apply.txt @@ -159,7 +159,7 @@ on the command line, and ignored if there is any include pattern. considered whitespace errors. + By default, the command outputs warning messages but applies the patch. -When `git-apply is used for statistics and not applying a +When `git-apply` is used for statistics and not applying a patch, it defaults to `nowarn`. + You can use different `<action>` to control this diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt index fba374d652..cc934e55c3 100644 --- a/Documentation/git-blame.txt +++ b/Documentation/git-blame.txt @@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [--incremental] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [--since=<date>] - [<rev> | --contents <file>] [--] <file> + [<rev> | --contents <file> | --reverse <rev>] [--] <file> DESCRIPTION ----------- diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index 168333a588..5ece6cc805 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -27,7 +27,7 @@ the first namespace level. When <paths> are given, this command does *not* switch branches. It updates the named paths in the working tree from -the index file, or from a named commit. In +the index file, or from a named <tree-ish> (most often a commit). In this case, the `-b` options is meaningless and giving either of them results in an error. <tree-ish> argument can be used to specify a specific tree-ish (i.e. commit, tag or tree) @@ -127,9 +127,13 @@ the conflicted merge in the specified paths. <new_branch>:: Name for the new branch. +<tree-ish>:: + Tree to checkout from (when paths are given). If not specified, + the index will be used. + <branch>:: - Branch to checkout; may be any object ID that resolves to a - commit. Defaults to HEAD. + Branch to checkout (when no paths are given); may be any object + ID that resolves to a commit. Defaults to HEAD. + When this parameter names a non-branch (but still a valid commit object), your HEAD becomes 'detached'. @@ -187,8 +191,8 @@ $ git checkout hello.c <3> ------------ + <1> switch branch -<2> take out a file out of other commit -<3> restore hello.c from HEAD of current branch +<2> take a file out of another commit +<3> restore hello.c from the index + If you have an unfortunate branch that is named `hello.c`, this step would be confused as an instruction to switch to that branch. @@ -232,7 +236,6 @@ the `-m` option, you would see something like this: ------------ $ git checkout -m mytopic Auto-merging frotz -merge: warning: conflicts during merge ERROR: Merge conflict in frotz fatal: merge program failed ------------ diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 95f08b9114..4072f40d7a 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -117,7 +117,7 @@ then the cloned repository will become corrupt. --origin <name>:: -o <name>:: Instead of using the remote name 'origin' to keep track - of the upstream repository, use <name> instead. + of the upstream repository, use <name>. --upload-pack <upload-pack>:: -u <upload-pack>:: diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 6203461f41..b5d81be7ec 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -166,7 +166,7 @@ FROM UPSTREAM REBASE" section in linkgit:git-rebase[1].) 'git-commit' if any paths are given on the command line, in which case this option can be omitted. If this option is specified together with '--amend', then - no paths need be specified, which can be used to amend + no paths need to be specified, which can be used to amend the last commit without committing changes that have already been staged. diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 28e1861094..19a8917b83 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -279,7 +279,7 @@ If you want to know all the values for a multivar, do: % git config --get-all core.gitproxy ------------ -If you like to live dangerous, you can replace *all* core.gitproxy by a +If you like to live dangerously, you can replace *all* core.gitproxy by a new one with ------------ diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt index f1a570a874..36f00aed67 100644 --- a/Documentation/git-daemon.txt +++ b/Documentation/git-daemon.txt @@ -110,9 +110,9 @@ OPTIONS --user-path:: --user-path=path:: - Allow ~user notation to be used in requests. When + Allow {tilde}user notation to be used in requests. When specified with no parameter, requests to - git://host/~alice/foo is taken as a request to access + git://host/{tilde}alice/foo is taken as a request to access 'foo' repository in the home directory of user `alice`. If `--user-path=path` is specified, the same request is taken as a request to access `path/foo` repository in diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt index 3d79f05995..a30c5ac966 100644 --- a/Documentation/git-describe.txt +++ b/Documentation/git-describe.txt @@ -43,7 +43,7 @@ OPTIONS Automatically implies --tags. --abbrev=<n>:: - Instead of using the default 8 hexadecimal digits as the + Instead of using the default 7 hexadecimal digits as the abbreviated object name, use <n> digits. --candidates=<n>:: diff --git a/Documentation/git-diff-files.txt b/Documentation/git-diff-files.txt index 5c8c1d95a8..c526141564 100644 --- a/Documentation/git-diff-files.txt +++ b/Documentation/git-diff-files.txt @@ -21,7 +21,10 @@ OPTIONS ------- include::diff-options.txt[] --1 -2 -3 or --base --ours --theirs, and -0:: +-1 --base:: +-2 --ours:: +-3 --theirs:: +-0:: Diff against the "base" version, "our branch" or "their branch" respectively. With these options, diffs for merged entries are not shown. diff --git a/Documentation/git-diff-tree.txt b/Documentation/git-diff-tree.txt index 5d48664e62..23b7abd3c6 100644 --- a/Documentation/git-diff-tree.txt +++ b/Documentation/git-diff-tree.txt @@ -43,7 +43,7 @@ include::diff-options.txt[] show tree entry itself as well as subtrees. Implies -r. --root:: - When '--root' is specified the initial commit will be showed as a big + When '--root' is specified the initial commit will be shown as a big creation event. This is equivalent to a diff against the NULL tree. --stdin:: @@ -63,7 +63,7 @@ and terminated by a newline) is printed before the difference. When comparing commits, the ID of the first (or only) commit, followed by a newline, is printed. + -The following flags further affects the behavior when comparing +The following flags further affect the behavior when comparing commits (but not trees). -m:: diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt index 99a1c3158d..0c9eb567cb 100644 --- a/Documentation/git-fast-export.txt +++ b/Documentation/git-fast-export.txt @@ -65,6 +65,12 @@ If the backend uses a similar \--import-marks file, this allows for incremental bidirectional exporting of the repository by keeping the marks the same across runs. +--fake-missing-tagger:: + Some old repositories have tags without a tagger. The + fast-import protocol was pretty strict about that, and did not + allow that. So fake a tagger to be able to fast-import the + output. + EXAMPLES -------- diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 11a7d77261..1f577b8016 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -39,15 +39,11 @@ There are two ways to specify which commits to operate on. REVISIONS" section in linkgit:git-rev-parse[1]) means the commits in the specified range. -A single commit, when interpreted as a <revision range> -expression, means "everything that leads to that commit", but -if you write 'git format-patch <commit>', the previous rule -applies to that command line and you do not get "everything -since the beginning of the time". If you want to format -everything since project inception to one commit, say "git -format-patch \--root <commit>" to make it clear that it is the -latter case. If you want to format a single commit, you can do -this with "git format-patch -1 <commit>". +The first rule takes precedence in the case of a single <commit>. To +apply the second rule, i.e., format everything since the beginning of +history up until <commit>, use the '\--root' option: "git format-patch +\--root <commit>". If you want to format only <commit> itself, you +can do this with "git format-patch -1 <commit>". By default, each output file is numbered sequentially from 1, and uses the first line of the commit message (massaged for pathname safety) as @@ -170,6 +166,13 @@ not add any suffix. applied. By default the contents of changes in those files are encoded in the patch. +--root:: + Treat the revision argument as a <revision range>, even if it + is just a single commit (that would normally be treated as a + <since>). Note that root commits included in the specified + range are always formatted as creation patches, independently + of this flag. + CONFIGURATION ------------- You can specify extra mail header lines to be added to each message diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt index d5a7647219..287c4fc5e0 100644 --- a/Documentation/git-fsck.txt +++ b/Documentation/git-fsck.txt @@ -79,7 +79,8 @@ that aren't readable from any of the specified head nodes. So for example - git fsck --unreachable HEAD $(cat .git/refs/heads/*) + git fsck --unreachable HEAD \ + $(git for-each-ref --format="%(objectname)" refs/heads) will do quite a _lot_ of verification on the tree. There are a few extra validity tests to be added (make sure that tree objects are diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt index 4c7262f1cd..db6ebccd6d 100644 --- a/Documentation/git-ls-tree.txt +++ b/Documentation/git-ls-tree.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git ls-tree' [-d] [-r] [-t] [-l] [-z] - [--name-only] [--name-status] [--full-name] [--abbrev=[<n>]] + [--name-only] [--name-status] [--full-name] [--full-tree] [--abbrev=[<n>]] <tree-ish> [paths...] DESCRIPTION @@ -30,6 +30,8 @@ in the current working directory. Note that: 'sub/dir' in 'HEAD'). You don't want to give a tree that is not at the root level (e.g. 'git ls-tree -r HEAD:sub dir') in this case, as that would result in asking for 'sub/sub/dir' in the 'HEAD' commit. + However, the current working directory can be ignored by passing + --full-tree option. OPTIONS ------- @@ -66,6 +68,10 @@ OPTIONS Instead of showing the path names relative to the current working directory, show the full path names. +--full-tree:: + Do not limit the listing to the current working directory. + Implies --full-name. + paths:: When paths are given, show them (note that this isn't really raw pathnames, but rather a list of patterns to match). Otherwise diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt index 31eccea5bc..8d95aaa304 100644 --- a/Documentation/git-mailinfo.txt +++ b/Documentation/git-mailinfo.txt @@ -13,7 +13,7 @@ SYNOPSIS DESCRIPTION ----------- -Reading a single e-mail message from the standard input, and +Reads a single e-mail message from the standard input, and writes the commit log message in <msg> file, and the patches in <patch> file. The author name, e-mail and e-mail subject are written out to the standard output to be used by 'git-am' diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 6150b1b959..ac6421178c 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -9,7 +9,7 @@ git-push - Update remote refs along with associated objects SYNOPSIS -------- [verse] -'git push' [--all | --mirror] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] +'git push' [--all | --mirror | --tags] [--dry-run] [--receive-pack=<git-receive-pack>] [--repo=<repository>] [-f | --force] [-v | --verbose] [<repository> <refspec>...] @@ -28,36 +28,39 @@ OPTIONS ------- <repository>:: The "remote" repository that is destination of a push - operation. See the section <<URLS,GIT URLS>> below. + operation. This parameter can be either a URL + (see the section <<URLS,GIT URLS>> below) or the name + of a remote (see the section <<REMOTES,REMOTES>> below). <refspec>...:: - The canonical format of a <refspec> parameter is - `+?<src>:<dst>`; that is, an optional plus `{plus}`, followed - by the source ref, followed by a colon `:`, followed by - the destination ref. + The format of a <refspec> parameter is an optional plus + `{plus}`, followed by the source ref <src>, followed + by a colon `:`, followed by the destination ref <dst>. + It is used to specify with what <src> object the <dst> ref + in the remote repository is to be updated. + -The <src> side represents the source branch (or arbitrary -"SHA1 expression", such as `master~4` (four parents before the -tip of `master` branch); see linkgit:git-rev-parse[1]) that you -want to push. The <dst> side represents the destination location. +The <src> is often the name of the branch you would want to push, but +it can be any arbitrary "SHA-1 expression", such as `master~4` or +`HEAD` (see linkgit:git-rev-parse[1]). + -The local ref that matches <src> is used -to fast forward the remote ref that matches <dst> (or, if no <dst> was -specified, the same ref that <src> referred to locally). If -the optional leading plus `+` is used, the remote ref is updated -even if it does not result in a fast forward update. +The <dst> tells which ref on the remote side is updated with this +push. Arbitrary expressions cannot be used here, an actual ref must +be named. If `:`<dst> is omitted, the same ref as <src> will be +updated. + -`tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`. +The object referenced by <src> is used to fast forward the ref <dst> +on the remote side. If the optional leading plus `{plus}` is used, the +remote ref is updated even if it does not result in a fast forward +update. + -A parameter <ref> without a colon pushes the <ref> from the source -repository to the destination repository under the same name. +`tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`. + Pushing an empty <src> allows you to delete the <dst> ref from the remote repository. + The special refspec `:` (or `+:` to allow non-fast forward updates) -directs git to push "matching" heads: for every head that exists on -the local side, the remote side is updated if a head of the same name +directs git to push "matching" branches: for every branch that exists on +the local side, the remote side is updated if a branch of the same name already exists on the remote side. This is the default operation mode if no explicit refspec is found (that is neither on the command line nor in any Push line of the corresponding remotes file---see below). @@ -86,14 +89,12 @@ nor in any Push line of the corresponding remotes file---see below). line. --receive-pack=<git-receive-pack>:: +--exec=<git-receive-pack>:: Path to the 'git-receive-pack' program on the remote end. Sometimes useful when pushing to a remote repository over ssh, and you do not have the program in a directory on the default $PATH. ---exec=<git-receive-pack>:: - Same as \--receive-pack=<git-receive-pack>. - -f:: --force:: Usually, the command refuses to update a remote ref that is @@ -191,9 +192,9 @@ git push origin master:: with it. If `master` did not exist remotely, it would be created. -git push origin :experimental:: - Find a ref that matches `experimental` in the `origin` repository - (e.g. `refs/heads/experimental`), and delete it. +git push origin HEAD:: + A handy way to push the current branch to the same name on the + remote. git push origin master:satellite/master dev:satellite/dev:: Use the source ref that matches `master` (e.g. `refs/heads/master`) @@ -201,6 +202,11 @@ git push origin master:satellite/master dev:satellite/dev:: `refs/remotes/satellite/master`) in the `origin` repository, then do the same for `dev` and `satellite/dev`. +git push origin HEAD:master:: + Push the current branch to the remote ref matching `master` in the + `origin` repository. This form is convenient to push the current + branch without thinking about its local name. + git push origin master:refs/heads/experimental:: Create the branch `experimental` in the `origin` repository by copying the current `master` branch. This form is only @@ -208,6 +214,11 @@ git push origin master:refs/heads/experimental:: the local name and the remote name are different; otherwise, the ref name on its own will work. +git push origin :experimental:: + Find a ref that matches `experimental` in the `origin` repository + (e.g. `refs/heads/experimental`), and delete it. + + Author ------ Written by Junio C Hamano <gitster@pobox.com>, later rewritten in C diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt index 6b2f8c4de7..514f03c979 100644 --- a/Documentation/git-receive-pack.txt +++ b/Documentation/git-receive-pack.txt @@ -86,7 +86,7 @@ post-receive Hook ----------------- After all refs were updated (or attempted to be updated), if any ref update was successful, and if $GIT_DIR/hooks/post-receive -file exists and is executable, it will be invoke once with no +file exists and is executable, it will be invoked once with no parameters. The standard input of the hook will be one line for each successfully updated ref: @@ -133,7 +133,7 @@ post-update Hook ---------------- After all other processing, if at least one ref was updated, and if $GIT_DIR/hooks/post-update file exists and is executable, then -post-update will called with the list of refs that have been updated. +post-update will be called with the list of refs that have been updated. This can be used to implement any repository wide cleanup tasks. The exit code from this hook invocation is ignored; the only thing diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt index d99236e14d..7f7a5445c7 100644 --- a/Documentation/git-reflog.txt +++ b/Documentation/git-reflog.txt @@ -28,7 +28,7 @@ updated. This command is to manage the information recorded in it. The subcommand "expire" is used to prune older reflog entries. Entries older than `expire` time, or entries older than -`expire-unreachable` time and are not reachable from the current +`expire-unreachable` time and not reachable from the current tip, are removed from the reflog. This is typically not used directly by the end users -- instead, see linkgit:git-gc[1]. @@ -71,7 +71,7 @@ them. which in turn defaults to 90 days. --expire-unreachable=<time>:: - Entries older than this time and are not reachable from + Entries older than this time and not reachable from the current tip of the branch are pruned. Without the option it is taken from configuration `gc.reflogExpireUnreachable`, which in turn defaults to diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt index 52aab5e680..2049f3d97b 100644 --- a/Documentation/git-reset.txt +++ b/Documentation/git-reset.txt @@ -130,7 +130,7 @@ Undo a merge or pull:: $ git pull <1> Auto-merging nitfol CONFLICT (content): Merge conflict in nitfol -Automatic merge failed/prevented; fix up by hand +Automatic merge failed; fix conflicts and then commit the result. $ git reset --hard <2> $ git pull . topic/branch <3> Updating from 41223... to 13134... @@ -177,6 +177,8 @@ $ git reset <3> <3> At this point the index file still has all the WIP changes you committed as 'snapshot WIP'. This updates the index to show your WIP files as uncommitted. ++ +See also linkgit:git-stash[1]. Reset a single file in the index:: + diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt index caa07298a6..5e1175800a 100644 --- a/Documentation/git-revert.txt +++ b/Documentation/git-revert.txt @@ -44,6 +44,14 @@ OPTIONS option specifies the parent number (starting from 1) of the mainline and allows revert to reverse the change relative to the specified parent. ++ +Reverting a merge commit declares that you will never want the tree changes +brought in by the merge. As a result, later merges will only bring in tree +changes introduced by commits that are not ancestors of the previously +reverted merge. This may or may not be what you want. ++ +See the link:howto/revert-a-faulty-merge.txt[revert-a-faulty-merge How-To] for +more details. --no-edit:: With this option, 'git-revert' will not start the commit diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 12788667d4..66bf3b2fcd 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -19,6 +19,19 @@ The header of the email is configurable by command line options. If not specified on the command line, the user will be prompted with a ReadLine enabled interface to provide the necessary information. +There are two formats accepted for patch files: + +1. mbox format files ++ +This is what linkgit:git-format-patch[1] generates. Most headers and MIME +formatting are ignored. + +2. The original format used by Greg Kroah-Hartman's 'send_lots_of_email.pl' +script ++ +This format expects the first line of the file to contain the "Cc:" value +and the "Subject:" of the message as the second line. + OPTIONS ------- @@ -34,6 +47,7 @@ The --bcc option must be repeated for each user you want on the bcc list. --cc:: Specify a starting "Cc:" value for each email. + Default is the value of 'sendemail.cc'. + The --cc option must be repeated for each user you want on the cc list. @@ -197,12 +211,6 @@ Administering --[no-]validate:: Perform sanity checks on patches. Currently, validation means the following: - ---[no-]format-patch:: - When an argument may be understood either as a reference or as a file name, - choose to understand it as a format-patch argument ('--format-patch') - or as a file name ('--no-format-patch'). By default, when such a conflict - occurs, git send-email will fail. + -- * Warn of patches that contain lines longer than 998 characters; this @@ -212,6 +220,12 @@ Administering Default is the value of 'sendemail.validate'; if this is not set, default to '--validate'. +--[no-]format-patch:: + When an argument may be understood either as a reference or as a file name, + choose to understand it as a format-patch argument ('--format-patch') + or as a file name ('--no-format-patch'). By default, when such a conflict + occurs, git send-email will fail. + CONFIGURATION ------------- diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.txt index ff420f8f8c..3f8d973af1 100644 --- a/Documentation/git-shell.txt +++ b/Documentation/git-shell.txt @@ -18,8 +18,9 @@ of server-side GIT commands implementing the pull/push functionality. The commands can be executed only by the '-c' option; the shell is not interactive. -Currently, only the 'git-receive-pack' and 'git-upload-pack' commands -are permitted to be called, with a single required argument. +Currently, only three commands are permitted to be called, 'git-receive-pack' +'git-upload-pack' with a single required argument or 'cvs server' (to invoke +'git-cvsserver'). Author ------ diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt index 7ccf31ccc4..8f7c0e226d 100644 --- a/Documentation/git-shortlog.txt +++ b/Documentation/git-shortlog.txt @@ -48,15 +48,41 @@ OPTIONS FILES ----- -If the file `.mailmap` exists, it will be used for mapping author -email addresses to a real author name. One mapping per line, first -the author name followed by the email address enclosed by -'<' and '>'. Use hash '#' for comments. Example: +If a file `.mailmap` exists at the toplevel of the repository, +it is used to map an author email address to a canonical real name. This +can be used to coalesce together commits by the same person where their +name was spelled differently (whether with the same email address or +not). + +Each line in the file consists, in this order, of the canonical real name +of an author, whitespace, and an email address (enclosed by '<' and '>') +to map to the name. Use hash '#' for comments, either on their own line, +or after the email address. + +A canonical name may appear in more than one line, associated with +different email addresses, but it doesn't make sense for a given address +to appear more than once (if that happens, a later line overrides the +earlier ones). + +So, for example, if your history contains commits by two authors, Jane +and Joe, whose names appear in the repository under several forms: + +------------ +Joe Developer <joe@example.com> +Joe R. Developer <joe@example.com> +Jane Doe <jane@example.com> +Jane Doe <jane@laptop.(none)> +Jane D. <jane@desktop.(none)> +------------ + +Then, supposing Joe wants his middle name initial used, and Jane prefers +her family name fully spelled out, a proper `.mailmap` file would look like: ------------ -# Keep alphabetized -Adam Morrow <adam@localhost.localdomain> -Eve Jones <eve@laptop.(none)> +# Note how we don't need an entry for <jane@laptop.(none)>, because the +# real name of that author is correct already, and coalesced directly. +Jane Doe <jane@desktop.(none)> +Joe R. Developer <joe@random.com> ------------ Author diff --git a/Documentation/git-show-branch.txt b/Documentation/git-show-branch.txt index d3f258869f..8277577a6f 100644 --- a/Documentation/git-show-branch.txt +++ b/Documentation/git-show-branch.txt @@ -30,7 +30,7 @@ OPTIONS ------- <rev>:: Arbitrary extended SHA1 expression (see linkgit:git-rev-parse[1]) - that typically names a branch HEAD or a tag. + that typically names a branch head or a tag. <glob>:: A glob pattern that matches branch or tag names under @@ -172,7 +172,7 @@ only the primary branches. In addition, if you happen to be on your topic branch, it is shown as well. ------------ -$ git show-branch --reflog='10,1 hour ago' --list master +$ git show-branch --reflog="10,1 hour ago" --list master ------------ shows 10 reflog entries going back from the tip as of 1 hour ago. diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index babaa9bc46..2f207fbbda 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -87,7 +87,7 @@ use by subsequent users cloning the superproject. If the URL is given relative to the superproject's repository, the presumption is the superproject and submodule repositories will be kept together in the same relative location, and only the -superproject's URL need be provided: git-submodule will correctly +superproject's URL needs to be provided: git-submodule will correctly locate the submodule using the relative URL in .gitmodules. status:: diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 046ab3542b..3546acffb5 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -63,6 +63,7 @@ OPTIONS are printed when using -l. The default is not to print any annotation lines. If no number is given to `-n`, only the first line is printed. + If the tag is not annotated, the commit message is displayed instead. -l <pattern>:: List tags with names that match the given pattern (or all if no pattern is given). @@ -70,7 +71,7 @@ OPTIONS -m <msg>:: Use the given tag message (instead of prompting). - If multiple `-m` options are given, there values are + If multiple `-m` options are given, their values are concatenated as separate paragraphs. Implies `-a` if none of `-a`, `-s`, or `-u <key-id>` is given. @@ -207,7 +208,7 @@ determines who are interested in whose tags. A one-shot pull is a sign that a commit history is now crossing the boundary between one circle of people (e.g. "people who are -primarily interested in networking part of the kernel") who may +primarily interested in the networking part of the kernel") who may have their own set of tags (e.g. "this is the third release candidate from the networking group to be proposed for general consumption with 2.6.21 release") to another circle of people diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt index 1d9d81a702..25e0bbea86 100644 --- a/Documentation/git-update-index.txt +++ b/Documentation/git-update-index.txt @@ -55,7 +55,7 @@ OPTIONS default behavior is to error out. This option makes 'git-update-index' continue anyway. ---ignore-submodules: +--ignore-submodules:: Do not try to update submodules. This option is only respected when passed before --refresh. @@ -78,9 +78,9 @@ OPTIONS --assume-unchanged:: --no-assume-unchanged:: - When these flags are specified, the object name recorded + When these flags are specified, the object names recorded for the paths are not updated. Instead, these options - sets and unsets the "assume unchanged" bit for the + set and unset the "assume unchanged" bit for the paths. When the "assume unchanged" bit is on, git stops checking the working tree files for possible modifications, so you need to manually unset the bit to @@ -122,7 +122,7 @@ you will need to handle the situation manually. 'git-update-index' refuses an attempt to add `path/file`. Similarly if a file `path/file` exists, a file `path` cannot be added. With --replace flag, existing entries - that conflicts with the entry being added are + that conflict with the entry being added are automatically removed with warning messages. --stdin:: diff --git a/Documentation/git.txt b/Documentation/git.txt index 585af7a0d0..17dc8b2019 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,9 +43,15 @@ unreleased) version of git, that is available from 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v1.6.0.5/git.html[documentation for release 1.6.0.5] +* link:v1.6.1/git.html[documentation for release 1.6.1] * release notes for + link:RelNotes-1.6.1.txt[1.6.1]. + +* link:v1.6.0.6/git.html[documentation for release 1.6.0.6] + +* release notes for + link:RelNotes-1.6.0.6.txt[1.6.0.6], link:RelNotes-1.6.0.5.txt[1.6.0.5], link:RelNotes-1.6.0.4.txt[1.6.0.4], link:RelNotes-1.6.0.3.txt[1.6.0.3], @@ -53,9 +59,10 @@ Documentation for older releases are available here: link:RelNotes-1.6.0.1.txt[1.6.0.1], link:RelNotes-1.6.0.txt[1.6.0]. -* link:v1.5.6.5/git.html[documentation for release 1.5.6.5] +* link:v1.5.6.6/git.html[documentation for release 1.5.6.6] * release notes for + link:RelNotes-1.5.6.6.txt[1.5.6.6], link:RelNotes-1.5.6.5.txt[1.5.6.5], link:RelNotes-1.5.6.4.txt[1.5.6.4], link:RelNotes-1.5.6.3.txt[1.5.6.3], @@ -63,18 +70,22 @@ Documentation for older releases are available here: link:RelNotes-1.5.6.1.txt[1.5.6.1], link:RelNotes-1.5.6.txt[1.5.6]. -* link:v1.5.5.4/git.html[documentation for release 1.5.5.4] +* link:v1.5.5.6/git.html[documentation for release 1.5.5.6] * release notes for + link:RelNotes-1.5.5.6.txt[1.5.5.6], + link:RelNotes-1.5.5.5.txt[1.5.5.5], link:RelNotes-1.5.5.4.txt[1.5.5.4], link:RelNotes-1.5.5.3.txt[1.5.5.3], link:RelNotes-1.5.5.2.txt[1.5.5.2], link:RelNotes-1.5.5.1.txt[1.5.5.1], link:RelNotes-1.5.5.txt[1.5.5]. -* link:v1.5.4.5/git.html[documentation for release 1.5.4.5] +* link:v1.5.4.7/git.html[documentation for release 1.5.4.7] * release notes for + link:RelNotes-1.5.4.7.txt[1.5.4.7], + link:RelNotes-1.5.4.6.txt[1.5.4.6], link:RelNotes-1.5.4.5.txt[1.5.4.5], link:RelNotes-1.5.4.4.txt[1.5.4.4], link:RelNotes-1.5.4.3.txt[1.5.4.3], diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 8af22eccac..82c10fa0fd 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -59,9 +59,9 @@ attribute. When deciding what attributes are assigned to a path, git consults `$GIT_DIR/info/attributes` file (which has the highest precedence), `.gitattributes` file in the same directory as the -path in question, and its parent directories (the further the -directory that contains `.gitattributes` is from the path in -question, the lower its precedence). +path in question, and its parent directories up to the toplevel of the +work tree (the further the directory that contains `.gitattributes` +is from the path in question, the lower its precedence). If you wish to affect only a single repository (i.e., to assign attributes to files that are particular to one user's workflow), then diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt index 96bf353d13..e4dd5518c8 100644 --- a/Documentation/gitcore-tutorial.txt +++ b/Documentation/gitcore-tutorial.txt @@ -899,7 +899,7 @@ file, which had no differences in the `mybranch` branch), and say: ---------------- Auto-merging hello CONFLICT (content): Merge conflict in hello - Automatic merge failed; fix up by hand + Automatic merge failed; fix conflicts and then commit the result. ---------------- It tells you that it did an "Automatic merge", which @@ -993,14 +993,14 @@ would be different) ---------------- Updating from ae3a2da... to a80b4aa.... -Fast forward +Fast forward (no commit created; -m option ignored) example | 1 + hello | 1 + 2 files changed, 2 insertions(+), 0 deletions(-) ---------------- -Because your branch did not contain anything more than what are -already merged into the `master` branch, the merge operation did +Because your branch did not contain anything more than what had +already been merged into the `master` branch, the merge operation did not actually do a merge. Instead, it just updated the top of the tree of your branch to that of the `master` branch. This is often called 'fast forward' merge. @@ -1265,9 +1265,8 @@ file, using 3-way merge. This is done by giving ------------ $ git merge-index git-merge-one-file hello -Auto-merging hello. -merge: warning: conflicts during merge -ERROR: Merge conflict in hello. +Auto-merging hello +ERROR: Merge conflict in hello fatal: merge program failed ------------ @@ -1353,7 +1352,7 @@ $ GIT_DIR=my-git.git git init ------------ Make sure this directory is available for others you want your -changes to be pulled by via the transport of your choice. Also +changes to be pulled via the transport of your choice. Also you need to make sure that you have the 'git-receive-pack' program on the `$PATH`. @@ -1447,7 +1446,7 @@ public repository you might want to repack & prune often, or never. If you run `git repack` again at this point, it will say -"Nothing to pack". Once you continue your development and +"Nothing new to pack.". Once you continue your development and accumulate the changes, running `git repack` again will create a new pack, that contains objects created since you packed your repository the last time. We recommend that you pack your project @@ -1512,7 +1511,7 @@ You can repack this private repository whenever you feel like. 6. Push your changes to the public repository, and announce it to the public. -7. Every once in a while, "git-repack" the public repository. +7. Every once in a while, 'git-repack' the public repository. Go back to step 5. and continue working. diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 5faaaa5fed..28a8abcf52 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -20,6 +20,10 @@ directory to trigger action at certain points. When all disabled. To enable a hook, rename it by removing its `.sample` suffix. +NOTE: It is also a requirement for a given hook to be executable. +However - in a freshly initialized repository - the `.sample` files are +executable by default. + This document describes the currently defined hooks. applypatch-msg @@ -86,7 +90,7 @@ This hook is invoked by 'git-commit' right after preparing the default log message, and before the editor is started. It takes one to three parameters. The first is the name of the file -that the commit log message. The second is the source of the commit +that contains the commit log message. The second is the source of the commit message, and can be: `message` (if a `-m` or `-F` option was given); `template` (if a `-t` option was given or the configuration option `commit.template` is set); `merge` (if the diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt index 59321a2e82..7df3cef46f 100644 --- a/Documentation/gitignore.txt +++ b/Documentation/gitignore.txt @@ -31,8 +31,8 @@ precedence, the last matching pattern decides the outcome): * Patterns read from a `.gitignore` file in the same directory as the path, or in any parent directory, with patterns in the - higher level files (up to the root) being overridden by those in - lower level files down to the directory containing the file. + higher level files (up to the toplevel of the work tree) being overridden + by those in lower level files down to the directory containing the file. These patterns match relative to the location of the `.gitignore` file. A project normally includes such `.gitignore` files in its repository, containing patterns for diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt index 317f6317c2..4673a75a98 100644 --- a/Documentation/gitk.txt +++ b/Documentation/gitk.txt @@ -21,7 +21,7 @@ git repository. OPTIONS ------- -To control which revisions to shown, the command takes options applicable to +To control which revisions to show, the command takes options applicable to the 'git-rev-list' command (see linkgit:git-rev-list[1]). This manual page describes only the most frequently used options. @@ -80,7 +80,7 @@ Examples -------- gitk v2.6.12.. include/scsi drivers/scsi:: - Show as the changes since version 'v2.6.12' that changed any + Show the changes since version 'v2.6.12' that changed any file in the include/scsi or drivers/scsi subdirectories gitk --since="2 weeks ago" \-- gitk:: diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt index a969b3fbc3..1befca98d4 100644 --- a/Documentation/gitrepository-layout.txt +++ b/Documentation/gitrepository-layout.txt @@ -134,7 +134,8 @@ hooks:: Hooks are customization scripts used by various git commands. A handful of sample hooks are installed when 'git-init' is run, but all of them are disabled by - default. To enable, they need to be made executable. + default. To enable, the `.sample` suffix has to be + removed from the filename by renaming. Read linkgit:githooks[5] for more details about each hook. diff --git a/Documentation/gittutorial.txt b/Documentation/gittutorial.txt index 7892244ef1..458fafdb2c 100644 --- a/Documentation/gittutorial.txt +++ b/Documentation/gittutorial.txt @@ -590,7 +590,7 @@ list. When the history has lines of development that diverged and then merged back together, the order in which 'git-log' presents those commits is meaningless. -Most projects with multiple contributors (such as the linux kernel, +Most projects with multiple contributors (such as the Linux kernel, or git itself) have frequent merges, and 'gitk' does a better job of visualizing their history. For example, @@ -642,7 +642,7 @@ digressions that may be interesting at this point are: * linkgit:git-format-patch[1], linkgit:git-am[1]: These convert series of git commits into emailed patches, and vice versa, - useful for projects such as the linux kernel which rely heavily + useful for projects such as the Linux kernel which rely heavily on emailed patches. * linkgit:git-bisect[1]: When there is a regression in your diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt index 9b4a4f45e9..9afca755ed 100644 --- a/Documentation/glossary-content.txt +++ b/Documentation/glossary-content.txt @@ -183,7 +183,8 @@ to point at the new commit. and potentially aborted, and allow for a post-notification after the operation is done. The hook scripts are found in the `$GIT_DIR/hooks/` directory, and are enabled by simply - making them executable. + removing the `.sample` suffix from the filename. In earlier versions + of git you had to make them executable. [[def_index]]index:: A collection of files with stat information, whose contents are stored diff --git a/Documentation/howto/revert-a-faulty-merge.txt b/Documentation/howto/revert-a-faulty-merge.txt new file mode 100644 index 0000000000..39b1da440a --- /dev/null +++ b/Documentation/howto/revert-a-faulty-merge.txt @@ -0,0 +1,179 @@ +Date: Fri, 19 Dec 2008 00:45:19 -0800 +From: Linus Torvalds <torvalds@linux-foundation.org>, Junio C Hamano <gitster@pobox.com> +Subject: Re: Odd merge behaviour involving reverts +Abstract: Sometimes a branch that was already merged to the mainline + is later found to be faulty. Linus and Junio give guidance on + recovering from such a premature merge and continuing development + after the offending branch is fixed. +Message-ID: <7vocz8a6zk.fsf@gitster.siamese.dyndns.org> +References: <alpine.LFD.2.00.0812181949450.14014@localhost.localdomain> + +Alan <alan@clueserver.org> said: + + I have a master branch. We have a branch off of that that some + developers are doing work on. They claim it is ready. We merge it + into the master branch. It breaks something so we revert the merge. + They make changes to the code. they get it to a point where they say + it is ok and we merge again. + + When examined, we find that code changes made before the revert are + not in the master branch, but code changes after are in the master + branch. + +and asked for help recovering from this situation. + +The history immediately after the "revert of the merge" would look like +this: + + ---o---o---o---M---x---x---W + / + ---A---B + +where A and B are on the side development that was not so good, M is the +merge that brings these premature changes into the mainline, x are changes +unrelated to what the side branch did and already made on the mainline, +and W is the "revert of the merge M" (doesn't W look M upside down?). +IOW, "diff W^..W" is similar to "diff -R M^..M". + +Such a "revert" of a merge can be made with: + + $ git revert -m 1 M + +After the develpers of the side branch fixes their mistakes, the history +may look like this: + + ---o---o---o---M---x---x---W---x + / + ---A---B-------------------C---D + +where C and D are to fix what was broken in A and B, and you may already +have some other changes on the mainline after W. + +If you merge the updated side branch (with D at its tip), none of the +changes made in A nor B will be in the result, because they were reverted +by W. That is what Alan saw. + +Linus explains the situation: + + Reverting a regular commit just effectively undoes what that commit + did, and is fairly straightforward. But reverting a merge commit also + undoes the _data_ that the commit changed, but it does absolutely + nothing to the effects on _history_ that the merge had. + + So the merge will still exist, and it will still be seen as joining + the two branches together, and future merges will see that merge as + the last shared state - and the revert that reverted the merge brought + in will not affect that at all. + + So a "revert" undoes the data changes, but it's very much _not_ an + "undo" in the sense that it doesn't undo the effects of a commit on + the repository history. + + So if you think of "revert" as "undo", then you're going to always + miss this part of reverts. Yes, it undoes the data, but no, it doesn't + undo history. + +In such a situation, you would want to first revert the previous revert, +which would make the history look like this: + + ---o---o---o---M---x---x---W---x---Y + / + ---A---B-------------------C---D + +where Y is the revert of W. Such a "revert of the revert" can be done +with: + + $ git revert W + +This history would (ignoring possible conflicts between what W and W..Y +changed) be equivalent to not having W nor Y at all in the history: + + ---o---o---o---M---x---x-------x---- + / + ---A---B-------------------C---D + +and merging the side branch again will not have conflict arising from an +earlier revert and revert of the revert. + + ---o---o---o---M---x---x-------x-------* + / / + ---A---B-------------------C---D + +Of course the changes made in C and D still can conflict with what was +done by any of the x, but that is just a normal merge conflict. + +On the other hand, if the developers of the side branch discarded their +faulty A and B, and redone the changes on top of the updated mainline +after the revert, the history would have looked like this: + + ---o---o---o---M---x---x---W---x---x + / \ + ---A---B A'--B'--C' + +If you reverted the revert in such a case as in the previous example: + + ---o---o---o---M---x---x---W---x---x---Y---* + / \ / + ---A---B A'--B'--C' + +where Y is the revert of W, A' and B'are rerolled A and B, and there may +also be a further fix-up C' on the side branch. "diff Y^..Y" is similar +to "diff -R W^..W" (which in turn means it is similar to "diff M^..M"), +and "diff A'^..C'" by definition would be similar but different from that, +because it is a rerolled series of the earlier change. There will be a +lot of overlapping changes that result in conflicts. So do not do "revert +of revert" blindly without thinking.. + + ---o---o---o---M---x---x---W---x---x + / \ + ---A---B A'--B'--C' + +In the history with rebased side branch, W (and M) are behind the merge +base of the updated branch and the tip of the mainline, and they should +merge without the past faulty merge and its revert getting in the way. + +To recap, these are two very different scenarios, and they want two very +different resolution strategies: + + - If the faulty side branch was fixed by adding corrections on top, then + doing a revert of the previous revert would be the right thing to do. + + - If the faulty side branch whose effects were discarded by an earlier + revert of a merge was rebuilt from scratch (i.e. rebasing and fixing, + as you seem to have interpreted), then re-merging the result without + doing anything else fancy would be the right thing to do. + +However, there are things to keep in mind when reverting a merge (and +reverting such a revert). + +For example, think about what reverting a merge (and then reverting the +revert) does to bisectability. Ignore the fact that the revert of a revert +is undoing it - just think of it as a "single commit that does a lot". +Because that is what it does. + +When you have a problem you are chasing down, and you hit a "revert this +merge", what you're hitting is essentially a single commit that contains +all the changes (but obviously in reverse) of all the commits that got +merged. So it's debugging hell, because now you don't have lots of small +changes that you can try to pinpoint which _part_ of it changes. + +But does it all work? Sure it does. You can revert a merge, and from a +purely technical angle, git did it very naturally and had no real +troubles. It just considered it a change from "state before merge" to +"state after merge", and that was it. Nothing complicated, nothing odd, +nothing really dangerous. Git will do it without even thinking about it. + +So from a technical angle, there's nothing wrong with reverting a merge, +but from a workflow angle it's something that you generally should try to +avoid. + +If at all possible, for example, if you find a problem that got merged +into the main tree, rather than revert the merge, try _really_ hard to +bisect the problem down into the branch you merged, and just fix it, or +try to revert the individual commit that caused it. + +Yes, it's more complex, and no, it's not always going to work (sometimes +the answer is: "oops, I really shouldn't have merged it, because it wasn't +ready yet, and I really need to undo _all_ of the merge"). So then you +really should revert the merge, but when you want to re-do the merge, you +now need to do it by reverting the revert. diff --git a/Documentation/i18n.txt b/Documentation/i18n.txt index 2cdacd94cd..708da6ca31 100644 --- a/Documentation/i18n.txt +++ b/Documentation/i18n.txt @@ -7,11 +7,11 @@ At the core level, git is character encoding agnostic. to be what lstat(2) and creat(2) accepts. There is no such thing as pathname encoding translation. - - The contents of the blob objects are uninterpreted sequence + - The contents of the blob objects are uninterpreted sequences of bytes. There is no encoding translation at the core level. - - The commit log messages are uninterpreted sequence of non-NUL + - The commit log messages are uninterpreted sequences of non-NUL bytes. Although we encourage that the commit log messages are encoded diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index f18d33e00b..0a8a948e6f 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -30,7 +30,7 @@ This is designed to be as compact as possible. commit <sha1> Author: <author> - Date: <author date> + Date: <author date> <title line> @@ -49,9 +49,9 @@ This is designed to be as compact as possible. * 'fuller' commit <sha1> - Author: <author> + Author: <author> AuthorDate: <author date> - Commit: <committer> + Commit: <committer> CommitDate: <committer date> <title line> diff --git a/Documentation/pull-fetch-param.txt b/Documentation/pull-fetch-param.txt index ebdd948cd2..f9811f2473 100644 --- a/Documentation/pull-fetch-param.txt +++ b/Documentation/pull-fetch-param.txt @@ -5,15 +5,14 @@ of a remote (see the section <<REMOTES,REMOTES>> below). <refspec>:: - The canonical format of a <refspec> parameter is - `+?<src>:<dst>`; that is, an optional plus `{plus}`, followed - by the source ref, followed by a colon `:`, followed by - the destination ref. + The format of a <refspec> parameter is an optional plus + `{plus}`, followed by the source ref <src>, followed + by a colon `:`, followed by the destination ref <dst>. + The remote ref that matches <src> is fetched, and if <dst> is not empty string, the local ref that matches it is fast forwarded using <src>. -Again, if the optional plus `+` is used, the local ref +If the optional plus `+` is used, the local ref is updated even if it does not result in a fast forward update. + diff --git a/Documentation/technical/api-history-graph.txt b/Documentation/technical/api-history-graph.txt index e9559790a3..d66e61b1ec 100644 --- a/Documentation/technical/api-history-graph.txt +++ b/Documentation/technical/api-history-graph.txt @@ -148,22 +148,22 @@ outputting that information, if desired. ------------ * * -M +* |\ * | | | * | \ \ | \ \ -M-. \ \ +*-. \ \ |\ \ \ \ | | * | | | | | | | * | | | | | * -| | | | | M +| | | | | * | | | | | |\ | | | | | | * | * | | | | | -| | | | | M \ +| | | | | * \ | | | | | |\ | | | | | * | | | | | | | * | | | diff --git a/Documentation/technical/api-strbuf.txt b/Documentation/technical/api-strbuf.txt index a8ee2fe6a1..985800e43a 100644 --- a/Documentation/technical/api-strbuf.txt +++ b/Documentation/technical/api-strbuf.txt @@ -21,7 +21,7 @@ allocated memory or not), use `strbuf_detach()` to unwrap a memory buffer from its strbuf shell in a safe way. That is the sole supported way. This will give you a malloced buffer that you can later `free()`. + -However, it it totally safe to modify anything in the string pointed by +However, it is totally safe to modify anything in the string pointed by the `buf` member, between the indices `0` and `len-1` (inclusive). . The `buf` member is a byte array that has at least `len + 1` bytes diff --git a/Documentation/urls.txt b/Documentation/urls.txt index fa34c67471..5355ebc0f3 100644 --- a/Documentation/urls.txt +++ b/Documentation/urls.txt @@ -6,10 +6,10 @@ to name the remote repository: =============================================================== - rsync://host.xz/path/to/repo.git/ -- http://host.xz/path/to/repo.git/ -- https://host.xz/path/to/repo.git/ -- git://host.xz/path/to/repo.git/ -- git://host.xz/~user/path/to/repo.git/ +- http://host.xz{startsb}:port{endsb}/path/to/repo.git/ +- https://host.xz{startsb}:port{endsb}/path/to/repo.git/ +- git://host.xz{startsb}:port{endsb}/path/to/repo.git/ +- git://host.xz{startsb}:port{endsb}/~user/path/to/repo.git/ - ssh://{startsb}user@{endsb}host.xz{startsb}:port{endsb}/path/to/repo.git/ - ssh://{startsb}user@{endsb}host.xz/path/to/repo.git/ - ssh://{startsb}user@{endsb}host.xz/~user/path/to/repo.git/ diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index d4b1e90f94..96af8977f6 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -59,7 +59,7 @@ project in mind, here are some interesting examples: ------------------------------------------------ # git itself (approx. 10MB download): $ git clone git://git.kernel.org/pub/scm/git/git.git - # the linux kernel (approx. 150MB download): + # the Linux kernel (approx. 150MB download): $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git ------------------------------------------------ @@ -1009,7 +1009,7 @@ $ git init If you have some initial content (say, a tarball): ------------------------------------------------- -$ tar -xzvf project.tar.gz +$ tar xzvf project.tar.gz $ cd project $ git init $ git add . # include everything below ./ in the first commit: @@ -1340,7 +1340,7 @@ These will display all commits which exist only on HEAD or on MERGE_HEAD, and which touch an unmerged file. You may also use linkgit:git-mergetool[1], which lets you merge the -unmerged files using external tools such as emacs or kdiff3. +unmerged files using external tools such as Emacs or kdiff3. Each time you resolve the conflicts in a file and update the index: @@ -1507,7 +1507,7 @@ so on a different branch and then coming back), unstash the work-in-progress changes. ------------------------------------------------ -$ git stash "work in progress for foo feature" +$ git stash save "work in progress for foo feature" ------------------------------------------------ This command will save your changes away to the `stash`, and diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 6c7465c758..550a0ae371 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.6.0.2.GIT +DEF_VER=v1.6.1.3.GIT LF=' ' @@ -645,6 +645,7 @@ ifeq ($(uname_S),Darwin) endif NO_STRLCPY = YesPlease NO_MEMMEM = YesPlease + THREADED_DELTA_SEARCH = YesPlease endif ifeq ($(uname_S),SunOS) NEEDS_SOCKET = YesPlease @@ -1352,7 +1353,7 @@ endif ### Testing rules -TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-parse-options$X test-path-utils$X +TEST_PROGRAMS = test-chmtime$X test-dump-cache-tree$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-parse-options$X test-path-utils$X all:: $(TEST_PROGRAMS) @@ -24,7 +24,7 @@ It was originally written by Linus Torvalds with help of a group of hackers around the net. It is currently maintained by Junio C Hamano. Please read the file INSTALL for installation instructions. -See Documentation/tutorial.txt to get started, then see +See Documentation/gittutorial.txt to get started, then see Documentation/everyday.txt for a useful minimum set of commands, and "man git-commandname" for documentation of each command. CVS users may also want to read Documentation/cvs-migration.txt. @@ -1 +1 @@ -Documentation/RelNotes-1.6.1.txt
\ No newline at end of file +Documentation/RelNotes-1.6.1.4.txt
\ No newline at end of file @@ -64,6 +64,8 @@ const char *make_absolute_path(const char *path) len = readlink(buf, next_buf, PATH_MAX); if (len < 0) die ("Invalid symlink: %s", buf); + if (PATH_MAX <= len) + die("symbolic link too long: %s", buf); next_buf[len] = '\0'; buf = next_buf; buf_index = 1 - buf_index; diff --git a/builtin-add.c b/builtin-add.c index 719de8b0f2..ac98c8354d 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -68,6 +68,33 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p free(seen); } +static void treat_gitlinks(const char **pathspec) +{ + int i; + + if (!pathspec || !*pathspec) + return; + + for (i = 0; i < active_nr; i++) { + struct cache_entry *ce = active_cache[i]; + if (S_ISGITLINK(ce->ce_mode)) { + int len = ce_namelen(ce), j; + for (j = 0; pathspec[j]; j++) { + int len2 = strlen(pathspec[j]); + if (len2 <= len || pathspec[j][len] != '/' || + memcmp(ce->name, pathspec[j], len)) + continue; + if (len2 == len + 1) + /* strip trailing slash */ + pathspec[j] = xstrndup(ce->name, len); + else + die ("Path '%s' is in submodule '%.*s'", + pathspec[j], len, ce->name); + } + } + } +} + static void fill_directory(struct dir_struct *dir, const char **pathspec, int ignored_too) { @@ -261,6 +288,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) if (read_cache() < 0) die("index file corrupt"); + treat_gitlinks(pathspec); if (add_new_files) /* This picks up the paths that are not tracked */ diff --git a/builtin-apply.c b/builtin-apply.c index 4c4d1e1774..58d998577e 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -630,7 +630,7 @@ static int gitdiff_index(const char *line, struct patch *patch) memcpy(patch->new_sha1_prefix, line, len); patch->new_sha1_prefix[len] = 0; if (*ptr == ' ') - patch->new_mode = patch->old_mode = strtoul(ptr+1, NULL, 8); + patch->old_mode = strtoul(ptr+1, NULL, 8); return 0; } @@ -1253,8 +1253,9 @@ static char *inflate_it(const void *data, unsigned long size, stream.avail_in = size; stream.next_out = out = xmalloc(inflated_size); stream.avail_out = inflated_size; - inflateInit(&stream); - st = inflate(&stream, Z_FINISH); + git_inflate_init(&stream); + st = git_inflate(&stream, Z_FINISH); + git_inflate_end(&stream); if ((st != Z_STREAM_END) || stream.total_out != inflated_size) { free(out); return NULL; @@ -1559,10 +1560,8 @@ static int read_old_data(struct stat *st, const char *path, struct strbuf *buf) { switch (st->st_mode & S_IFMT) { case S_IFLNK: - strbuf_grow(buf, st->st_size); - if (readlink(path, buf->buf, st->st_size) != st->st_size) - return -1; - strbuf_setlen(buf, st->st_size); + if (strbuf_readlink(buf, path, st->st_size) < 0) + return error("unable to read symlink %s", path); return 0; case S_IFREG: if (strbuf_read_file(buf, path, st->st_size) != st->st_size) @@ -2437,7 +2436,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s return error("%s: %s", old_name, strerror(errno)); } - if (!cached) + if (!cached && !tpatch) st_mode = ce_mode_from_stat(*ce, st->st_mode); if (patch->is_new < 0) @@ -2449,6 +2448,8 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s if (st_mode != patch->old_mode) fprintf(stderr, "warning: %s has type %o, expected %o\n", old_name, st_mode, patch->old_mode); + if (!patch->new_mode && !patch->is_delete) + patch->new_mode = st_mode; return 0; is_new: diff --git a/builtin-blame.c b/builtin-blame.c index a0d60145f2..9b9f5442a2 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -19,6 +19,7 @@ #include "string-list.h" #include "mailmap.h" #include "parse-options.h" +#include "utf8.h" static char blame_usage[] = "git blame [options] [rev-opts] [rev] [--] file"; @@ -1618,13 +1619,14 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt) printf(" %*d", max_orig_digits, ent->s_lno + 1 + cnt); - if (!(opt & OUTPUT_NO_AUTHOR)) - printf(" (%-*.*s %10s", - longest_author, longest_author, - ci.author, + if (!(opt & OUTPUT_NO_AUTHOR)) { + int pad = longest_author - utf8_strwidth(ci.author); + printf(" (%s%*s %10s", + ci.author, pad, "", format_time(ci.author_time, ci.author_tz, show_raw_time)); + } printf(" %*d) ", max_digits, ent->lno + 1 + cnt); } @@ -1755,7 +1757,7 @@ static void find_alignment(struct scoreboard *sb, int *option) if (!(suspect->commit->object.flags & METAINFO_SHOWN)) { suspect->commit->object.flags |= METAINFO_SHOWN; get_commit_info(suspect->commit, &ci, 1); - num = strlen(ci.author); + num = utf8_strwidth(ci.author); if (longest_author < num) longest_author = num; } @@ -1996,7 +1998,6 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con if (!contents_from || strcmp("-", contents_from)) { struct stat st; const char *read_from; - unsigned long fin_size; if (contents_from) { if (stat(contents_from, &st) < 0) @@ -2008,7 +2009,6 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con die("Cannot lstat %s", path); read_from = path; } - fin_size = xsize_t(st.st_size); mode = canon_mode(st.st_mode); switch (st.st_mode & S_IFMT) { case S_IFREG: @@ -2016,9 +2016,8 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con die("cannot open or read %s", read_from); break; case S_IFLNK: - if (readlink(read_from, buf.buf, buf.alloc) != fin_size) + if (strbuf_readlink(&buf, read_from, st.st_size) < 0) die("cannot readlink %s", read_from); - buf.len = fin_size; break; default: die("unsupported file type %s", read_from); diff --git a/builtin-checkout.c b/builtin-checkout.c index c2c05613b6..b5dd9c07b4 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -681,8 +681,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) argv++; argc--; + new.name = arg; if ((new.commit = lookup_commit_reference_gently(rev, 1))) { - new.name = arg; setup_branch_path(&new); if (resolve_ref(new.path, rev, 1, NULL)) new.commit = lookup_commit_reference(rev); diff --git a/builtin-commit.c b/builtin-commit.c index 2b499fa543..72dd0b9553 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -224,7 +224,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix) const char **pathspec = NULL; if (interactive) { - interactive_add(argc, argv, prefix); + if (interactive_add(argc, argv, prefix) != 0) + die("interactive add failed"); if (read_cache_preload(NULL) < 0) die("index file corrupt"); commit_style = COMMIT_AS_IS; @@ -624,7 +625,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix) if (!commitable && !in_merge && !allow_empty && !(amend && is_a_merge(head_sha1))) { run_status(stdout, index_file, prefix, 0); - unlink(commit_editmsg); return 0; } @@ -866,6 +866,9 @@ int cmd_status(int argc, const char **argv, const char *prefix) if (wt_status_use_color == -1) wt_status_use_color = git_use_color_default; + if (diff_use_color_default == -1) + diff_use_color_default = git_use_color_default; + argc = parse_and_validate_options(argc, argv, builtin_status_usage, prefix); index_file = prepare_index(argc, argv, prefix); @@ -932,11 +935,6 @@ static int git_commit_config(const char *k, const char *v, void *cb) return git_status_config(k, v, cb); } -static const char commit_utf8_warn[] = -"Warning: commit message does not conform to UTF-8.\n" -"You may want to amend it after fixing the message, or set the config\n" -"variable i18n.commitencoding to the encoding your project uses.\n"; - int cmd_commit(int argc, const char **argv, const char *prefix) { struct strbuf sb = STRBUF_INIT; @@ -950,6 +948,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix) git_config(git_commit_config, NULL); + if (wt_status_use_color == -1) + wt_status_use_color = git_use_color_default; + argc = parse_and_validate_options(argc, argv, builtin_commit_usage, prefix); index_file = prepare_index(argc, argv, prefix); diff --git a/builtin-describe.c b/builtin-describe.c index d2cfb1b083..3a007ed1ca 100644 --- a/builtin-describe.c +++ b/builtin-describe.c @@ -158,7 +158,7 @@ static void display_name(struct commit_name *n) n->tag = lookup_tag(n->sha1); if (!n->tag || parse_tag(n->tag) || !n->tag->tag) die("annotated tag %s not available", n->path); - if (strcmp(n->tag->tag, n->path)) + if (strcmp(n->tag->tag, all ? n->path + 5 : n->path)) warning("tag '%s' is really '%s' here", n->tag->tag, n->path); } diff --git a/builtin-fast-export.c b/builtin-fast-export.c index 7d5d57ad75..fdf4ae9ebd 100644 --- a/builtin-fast-export.c +++ b/builtin-fast-export.c @@ -24,6 +24,7 @@ static const char *fast_export_usage[] = { static int progress; static enum { VERBATIM, WARN, STRIP, ABORT } signed_tag_mode = ABORT; +static int fake_missing_tagger; static int parse_opt_signed_tag_mode(const struct option *opt, const char *arg, int unset) @@ -297,10 +298,17 @@ static void handle_tag(const char *name, struct tag *tag) message_size = strlen(message); } tagger = memmem(buf, message ? message - buf : size, "\ntagger ", 8); - if (!tagger) - die ("No tagger for tag %s", sha1_to_hex(tag->object.sha1)); - tagger++; - tagger_end = strchrnul(tagger, '\n'); + if (!tagger) { + if (fake_missing_tagger) + tagger = "tagger Unspecified Tagger " + "<unspecified-tagger> 0 +0000"; + else + tagger = ""; + tagger_end = tagger + strlen(tagger); + } else { + tagger++; + tagger_end = strchrnul(tagger, '\n'); + } /* handle signed tags */ if (message) { @@ -326,9 +334,10 @@ static void handle_tag(const char *name, struct tag *tag) if (!prefixcmp(name, "refs/tags/")) name += 10; - printf("tag %s\nfrom :%d\n%.*s\ndata %d\n%.*s\n", + printf("tag %s\nfrom :%d\n%.*s%sdata %d\n%.*s\n", name, get_object_mark(tag->tagged), (int)(tagger_end - tagger), tagger, + tagger == tagger_end ? "" : "\n", (int)message_size, (int)message_size, message ? message : ""); } @@ -483,9 +492,14 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) "Dump marks to this file"), OPT_STRING(0, "import-marks", &import_filename, "FILE", "Import marks from this file"), + OPT_BOOLEAN(0, "fake-missing-tagger", &fake_missing_tagger, + "Fake a tagger when tags lack one"), OPT_END() }; + if (argc == 1) + usage_with_options (fast_export_usage, options); + /* we handle encodings */ git_config(git_default_config, NULL); @@ -500,6 +514,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) get_tags_and_duplicates(&revs.pending, &extra_refs); + revs.topo_order = 1; if (prepare_revision_walk(&revs)) die("revision walk setup failed"); revs.diffopt.format_callback = show_filemodify; diff --git a/builtin-fsck.c b/builtin-fsck.c index 297b2c41c6..5c4c77adaa 100644 --- a/builtin-fsck.c +++ b/builtin-fsck.c @@ -628,7 +628,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) } heads = 0; - for (i = 1; i < argc; i++) { + for (i = 0; i < argc; i++) { const char *arg = argv[i]; if (!get_sha1(arg, head_sha1)) { struct object *obj = lookup_object(head_sha1); diff --git a/builtin-gc.c b/builtin-gc.c index 781df601c5..f8eae4adb4 100644 --- a/builtin-gc.c +++ b/builtin-gc.c @@ -188,7 +188,9 @@ static int need_to_gc(void) * there is no need. */ if (too_many_packs()) - append_option(argv_repack, "-A", MAX_ADD); + append_option(argv_repack, + !strcmp(prune_expire, "now") ? "-a" : "-A", + MAX_ADD); else if (!too_many_loose_objects()) return 0; @@ -243,7 +245,9 @@ int cmd_gc(int argc, const char **argv, const char *prefix) "run \"git gc\" manually. See " "\"git help gc\" for more information.\n"); } else - append_option(argv_repack, "-A", MAX_ADD); + append_option(argv_repack, + !strcmp(prune_expire, "now") ? "-a" : "-A", + MAX_ADD); if (pack_refs && run_command_v_opt(argv_pack_refs, RUN_GIT_CMD)) return error(FAILED_RUN, argv_pack_refs[0]); diff --git a/builtin-grep.c b/builtin-grep.c index 624f86e287..3f12ba3826 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -20,6 +20,8 @@ #endif #endif +static int builtin_grep; + /* * git grep pathspecs are somewhat different from diff-tree pathspecs; * pathname wildcards are allowed. @@ -289,6 +291,8 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached) push_arg("-E"); if (opt->regflags & REG_ICASE) push_arg("-i"); + if (opt->binary == GREP_BINARY_NOMATCH) + push_arg("-I"); if (opt->word_regexp) push_arg("-w"); if (opt->name_only) @@ -389,7 +393,7 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached) * we grep through the checked-out files. It tends to * be a lot more optimized */ - if (!cached) { + if (!cached && !builtin_grep) { hit = external_grep(opt, paths, cached); if (hit >= 0) return hit; @@ -402,7 +406,12 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached) continue; if (!pathspec_matches(paths, ce->name)) continue; - if (cached) { + /* + * If CE_VALID is on, we assume worktree file and its cache entry + * are identical, even if worktree file has been modified, so use + * cache version instead + */ + if (cached || (ce->ce_flags & CE_VALID)) { if (ce_stage(ce)) continue; hit |= grep_sha1(opt, ce->sha1, ce->name, 0); @@ -545,6 +554,10 @@ int cmd_grep(int argc, const char **argv, const char *prefix) cached = 1; continue; } + if (!strcmp("--no-ext-grep", arg)) { + builtin_grep = 1; + continue; + } if (!strcmp("-a", arg) || !strcmp("--text", arg)) { opt.binary = GREP_BINARY_TEXT; diff --git a/builtin-log.c b/builtin-log.c index 840daf9078..60f8dd8604 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -340,7 +340,13 @@ int cmd_show(int argc, const char **argv, const char *prefix) t->tag, diff_get_color_opt(&rev.diffopt, DIFF_RESET)); ret = show_object(o->sha1, 1, &rev); - objects[i].item = parse_object(t->tagged->sha1); + if (ret) + break; + o = parse_object(t->tagged->sha1); + if (!o) + ret = error("Could not read object %s", + sha1_to_hex(t->tagged->sha1)); + objects[i].item = o; i--; break; } @@ -547,6 +553,7 @@ static const char *get_oneline_for_filename(struct commit *commit, static FILE *realstdout = NULL; static const char *output_directory = NULL; +static int outdir_offset; static int reopen_stdout(const char *oneline, int nr, int total) { @@ -573,7 +580,7 @@ static int reopen_stdout(const char *oneline, int nr, int total) strcpy(filename + len, fmt_patch_suffix); } - fprintf(realstdout, "%s\n", filename); + fprintf(realstdout, "%s\n", filename + outdir_offset); if (freopen(filename, "w", stdout) == NULL) return error("Cannot open patch file %s",filename); @@ -734,6 +741,27 @@ static const char *clean_message_id(const char *msg_id) return xmemdupz(a, z - a); } +static const char *set_outdir(const char *prefix, const char *output_directory) +{ + if (output_directory && is_absolute_path(output_directory)) + return output_directory; + + if (!prefix || !*prefix) { + if (output_directory) + return output_directory; + /* The user did not explicitly ask for "./" */ + outdir_offset = 2; + return "./"; + } + + outdir_offset = strlen(prefix); + if (!output_directory) + return prefix; + + return xstrdup(prefix_filename(prefix, outdir_offset, + output_directory)); +} + int cmd_format_patch(int argc, const char **argv, const char *prefix) { struct commit *commit; @@ -911,8 +939,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff) DIFF_OPT_SET(&rev.diffopt, BINARY); - if (!output_directory && !use_stdout) - output_directory = prefix; + if (!use_stdout) + output_directory = set_outdir(prefix, output_directory); if (output_directory) { if (use_stdout) @@ -938,6 +966,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) * get_revision() to do the usual traversal. */ } + + /* + * We cannot move this anywhere earlier because we do want to + * know if --root was given explicitly from the comand line. + */ + rev.show_root_diff = 1; + if (cover_letter) { /* remember the range */ int i; diff --git a/builtin-ls-tree.c b/builtin-ls-tree.c index cb61717685..5b63e6eada 100644 --- a/builtin-ls-tree.c +++ b/builtin-ls-tree.c @@ -23,7 +23,7 @@ static int chomp_prefix; static const char *ls_tree_prefix; static const char ls_tree_usage[] = - "git ls-tree [-d] [-r] [-t] [-l] [-z] [--name-only] [--name-status] [--full-name] [--abbrev[=<n>]] <tree-ish> [path...]"; + "git ls-tree [-d] [-r] [-t] [-l] [-z] [--name-only] [--name-status] [--full-name] [--full-tree] [--abbrev[=<n>]] <tree-ish> [path...]"; static int show_recursive(const char *base, int baselen, const char *pathname) { @@ -156,6 +156,11 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) chomp_prefix = 0; break; } + if (!strcmp(argv[1]+2, "full-tree")) { + ls_tree_prefix = prefix = NULL; + chomp_prefix = 0; + break; + } if (!prefixcmp(argv[1]+2, "abbrev=")) { abbrev = strtoul(argv[1]+9, NULL, 10); if (abbrev && abbrev < MINIMUM_ABBREV) diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c index e890f7a6d1..dacc8ac2d0 100644 --- a/builtin-mailinfo.c +++ b/builtin-mailinfo.c @@ -430,13 +430,6 @@ static struct strbuf *decode_b_segment(const struct strbuf *b_seg) c -= 'a' - 26; else if ('0' <= c && c <= '9') c -= '0' - 52; - else if (c == '=') { - /* padding is almost like (c == 0), except we do - * not output NUL resulting only from it; - * for now we just trust the data. - */ - c = 0; - } else continue; /* garbage */ switch (pos++) { @@ -514,7 +507,25 @@ static int decode_header_bq(struct strbuf *it) rfc2047 = 1; if (in != ep) { - strbuf_add(&outbuf, in, ep - in); + /* + * We are about to process an encoded-word + * that begins at ep, but there is something + * before the encoded word. + */ + char *scan; + for (scan = in; scan < ep; scan++) + if (!isspace(*scan)) + break; + + if (scan != ep || in == it->buf) { + /* + * We should not lose that "something", + * unless we have just processed an + * encoded-word, and there is only LWS + * before the one we are about to process. + */ + strbuf_add(&outbuf, in, ep - in); + } in = ep; } /* E.g. @@ -860,6 +871,7 @@ static void handle_info(void) } output_header_lines(fout, "Subject", hdr); } else if (!memcmp(header[i], "From", 4)) { + cleanup_space(hdr); handle_from(hdr); fprintf(fout, "Author: %s\n", name.buf); fprintf(fout, "Email: %s\n", email.buf); diff --git a/builtin-merge-file.c b/builtin-merge-file.c index 9d4e874809..96edb97a83 100644 --- a/builtin-merge-file.c +++ b/builtin-merge-file.c @@ -51,8 +51,11 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, options, merge_file_usage, 0); if (argc != 3) usage_with_options(merge_file_usage, options); - if (quiet) - freopen("/dev/null", "w", stderr); + if (quiet) { + if (!freopen("/dev/null", "w", stderr)) + return error("failed to redirect stderr to /dev/null: " + "%s\n", strerror(errno)); + } for (i = 0; i < 3; i++) { if (!names[i]) diff --git a/builtin-mv.c b/builtin-mv.c index 4f65b5ae9b..01270fefdf 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -162,7 +162,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } argc += last - first; } - } else if (lstat(dst, &st) == 0) { + } else if (cache_name_pos(src, length) < 0) + bad = "not under version control"; + else if (lstat(dst, &st) == 0) { bad = "destination exists"; if (force) { /* @@ -177,9 +179,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } else bad = "Cannot overwrite"; } - } else if (cache_name_pos(src, length) < 0) - bad = "not under version control"; - else if (string_list_has_string(&src_for_dst, dst)) + } else if (string_list_has_string(&src_for_dst, dst)) bad = "multiple sources for the same target"; else string_list_insert(dst, &src_for_dst); @@ -192,6 +192,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) memmove(destination + i, destination + i + 1, (argc - i) * sizeof(char *)); + i--; } } else die ("%s, source=%s, destination=%s", diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index cedef52fd3..7234d76f6e 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -195,16 +195,16 @@ static int check_pack_inflate(struct packed_git *p, int st; memset(&stream, 0, sizeof(stream)); - inflateInit(&stream); + git_inflate_init(&stream); do { in = use_pack(p, w_curs, offset, &stream.avail_in); stream.next_in = in; stream.next_out = fakebuf; stream.avail_out = sizeof(fakebuf); - st = inflate(&stream, Z_FINISH); + st = git_inflate(&stream, Z_FINISH); offset += stream.next_in - in; } while (st == Z_OK || st == Z_BUF_ERROR); - inflateEnd(&stream); + git_inflate_end(&stream); return (st == Z_STREAM_END && stream.total_out == expect && stream.total_in == len) ? 0 : -1; @@ -488,9 +488,8 @@ static void write_pack_file(void) } else { char tmpname[PATH_MAX]; int fd; - snprintf(tmpname, sizeof(tmpname), - "%s/pack/tmp_pack_XXXXXX", get_object_directory()); - fd = xmkstemp(tmpname); + fd = odb_mkstemp(tmpname, sizeof(tmpname), + "pack/tmp_pack_XXXXXX"); pack_tmp_name = xstrdup(tmpname); f = sha1fd(fd, pack_tmp_name); } @@ -1294,7 +1293,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, max_size = trg_entry->delta_size; ref_depth = trg->depth; } - max_size = max_size * (max_depth - src->depth) / + max_size = (uint64_t)max_size * (max_depth - src->depth) / (max_depth - ref_depth + 1); if (max_size == 0) return 0; diff --git a/builtin-remote.c b/builtin-remote.c index abc8dd8389..db18bcfc97 100644 --- a/builtin-remote.c +++ b/builtin-remote.c @@ -298,7 +298,7 @@ static int add_known_remote(struct remote *remote, void *cb_data) struct branches_for_remote { struct remote *remote; - struct string_list *branches; + struct string_list *branches, *skipped; struct known_remotes *keep; }; @@ -323,6 +323,16 @@ static int add_branch_for_removal(const char *refname, return 0; } + /* don't delete non-remote refs */ + if (prefixcmp(refname, "refs/remotes")) { + /* advise user how to delete local branches */ + if (!prefixcmp(refname, "refs/heads/")) + string_list_append(abbrev_branch(refname), + branches->skipped); + /* silently skip over other non-remote refs */ + return 0; + } + /* make sure that symrefs are deleted */ if (flags & REF_ISSYMREF) return unlink(git_path("%s", refname)); @@ -542,8 +552,11 @@ static int rm(int argc, const char **argv) struct strbuf buf = STRBUF_INIT; struct known_remotes known_remotes = { NULL, NULL }; struct string_list branches = { NULL, 0, 0, 1 }; - struct branches_for_remote cb_data = { NULL, &branches, &known_remotes }; - int i; + struct string_list skipped = { NULL, 0, 0, 1 }; + struct branches_for_remote cb_data = { + NULL, &branches, &skipped, &known_remotes + }; + int i, result; if (argc != 2) usage_with_options(builtin_remote_usage, options); @@ -583,14 +596,26 @@ static int rm(int argc, const char **argv) * refs, which are invalidated when deleting a branch. */ cb_data.remote = remote; - i = for_each_ref(add_branch_for_removal, &cb_data); + result = for_each_ref(add_branch_for_removal, &cb_data); strbuf_release(&buf); - if (!i) - i = remove_branches(&branches); + if (!result) + result = remove_branches(&branches); string_list_clear(&branches, 1); - return i; + if (skipped.nr) { + fprintf(stderr, skipped.nr == 1 ? + "Note: A non-remote branch was not removed; " + "to delete it, use:\n" : + "Note: Non-remote branches were not removed; " + "to delete them, use:\n"); + for (i = 0; i < skipped.nr; i++) + fprintf(stderr, " git branch -d %s\n", + skipped.items[i].string); + } + string_list_clear(&skipped, 0); + + return result; } static void show_list(const char *title, struct string_list *list, diff --git a/builtin-rev-list.c b/builtin-rev-list.c index 857742a14f..436afa45f5 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -608,6 +608,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) if (!strcmp(arg, "--bisect-all")) { bisect_list = 1; bisect_find_all = 1; + revs.show_decorations = 1; continue; } if (!strcmp(arg, "--bisect-vars")) { diff --git a/builtin-revert.c b/builtin-revert.c index 4038b4118d..09d08fa3e3 100644 --- a/builtin-revert.c +++ b/builtin-revert.c @@ -352,6 +352,11 @@ static int revert_or_cherry_pick(int argc, const char **argv) add_to_msg(oneline_body + 1); add_to_msg("\"\n\nThis reverts commit "); add_to_msg(sha1_to_hex(commit->object.sha1)); + + if (commit->parents->next) { + add_to_msg(", reversing\nchanges made to "); + add_to_msg(sha1_to_hex(parent->object.sha1)); + } add_to_msg(".\n"); } else { base = parent; @@ -382,6 +387,7 @@ static int revert_or_cherry_pick(int argc, const char **argv) (write_cache(index_fd, active_cache, active_nr) || commit_locked_index(&index_lock))) die("%s: Unable to write new index file", me); + rollback_lock_file(&index_lock); if (!clean) { add_to_msg("\nConflicts:\n\n"); diff --git a/builtin-send-pack.c b/builtin-send-pack.c index a9fdbf9d45..d65d019692 100644 --- a/builtin-send-pack.c +++ b/builtin-send-pack.c @@ -15,6 +15,20 @@ static struct send_pack_args args = { /* .receivepack = */ "git-receive-pack", }; +static int feed_object(const unsigned char *sha1, int fd, int negative) +{ + char buf[42]; + + if (negative && !has_sha1_file(sha1)) + return 1; + + memcpy(buf + negative, sha1_to_hex(sha1), 40); + if (negative) + buf[0] = '^'; + buf[40 + negative] = '\n'; + return write_or_whine(fd, buf, 41 + negative, "send-pack: send refs"); +} + /* * Make a pack stream and spit it out into file descriptor fd */ @@ -35,7 +49,6 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext }; struct child_process po; int i; - char buf[42]; if (args.use_thin_pack) argv[4] = "--thin"; @@ -51,31 +64,17 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext * We feed the pack-objects we just spawned with revision * parameters by writing to the pipe. */ - for (i = 0; i < extra->nr; i++) { - memcpy(buf + 1, sha1_to_hex(&extra->array[i][0]), 40); - buf[0] = '^'; - buf[41] = '\n'; - if (!write_or_whine(po.in, buf, 42, "send-pack: send refs")) + for (i = 0; i < extra->nr; i++) + if (!feed_object(extra->array[i], po.in, 1)) break; - } while (refs) { if (!is_null_sha1(refs->old_sha1) && - has_sha1_file(refs->old_sha1)) { - memcpy(buf + 1, sha1_to_hex(refs->old_sha1), 40); - buf[0] = '^'; - buf[41] = '\n'; - if (!write_or_whine(po.in, buf, 42, - "send-pack: send refs")) - break; - } - if (!is_null_sha1(refs->new_sha1)) { - memcpy(buf, sha1_to_hex(refs->new_sha1), 40); - buf[40] = '\n'; - if (!write_or_whine(po.in, buf, 41, - "send-pack: send refs")) - break; - } + !feed_object(refs->old_sha1, po.in, 1)) + break; + if (!is_null_sha1(refs->new_sha1) && + !feed_object(refs->new_sha1, po.in, 0)) + break; refs = refs->next; } diff --git a/builtin-shortlog.c b/builtin-shortlog.c index d03f14fdad..e49290687f 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -29,6 +29,9 @@ static int compare_by_number(const void *a1, const void *a2) return -1; } +const char *format_subject(struct strbuf *sb, const char *msg, + const char *line_separator); + static void insert_one_record(struct shortlog *log, const char *author, const char *oneline) @@ -41,6 +44,7 @@ static void insert_one_record(struct shortlog *log, size_t len; const char *eol; const char *boemail, *eoemail; + struct strbuf subject = STRBUF_INIT; boemail = strchr(author, '<'); if (!boemail) @@ -89,9 +93,8 @@ static void insert_one_record(struct shortlog *log, while (*oneline && isspace(*oneline) && *oneline != '\n') oneline++; len = eol - oneline; - while (len && isspace(oneline[len-1])) - len--; - buffer = xmemdupz(oneline, len); + format_subject(&subject, oneline, " "); + buffer = strbuf_detach(&subject, NULL); if (dot3) { int dot3len = strlen(dot3); diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c index 47ed610677..9a773239ca 100644 --- a/builtin-unpack-objects.c +++ b/builtin-unpack-objects.c @@ -99,10 +99,10 @@ static void *get_data(unsigned long size) stream.avail_out = size; stream.next_in = fill(1); stream.avail_in = len; - inflateInit(&stream); + git_inflate_init(&stream); for (;;) { - int ret = inflate(&stream, 0); + int ret = git_inflate(&stream, 0); use(len - stream.avail_in); if (stream.total_out == size && ret == Z_STREAM_END) break; @@ -118,7 +118,7 @@ static void *get_data(unsigned long size) stream.next_in = fill(1); stream.avail_in = len; } - inflateEnd(&stream); + git_inflate_end(&stream); return buf; } diff --git a/builtin-update-index.c b/builtin-update-index.c index 65d5775107..daca0f775e 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -742,8 +742,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) if (newfd < 0) { if (refresh_flags & REFRESH_QUIET) exit(128); - die("unable to create '%s.lock': %s", - get_index_file(), strerror(lock_error)); + unable_to_lock_index_die(get_index_file(), lock_error); } if (write_cache(newfd, active_cache, active_nr) || commit_locked_index(lock_file)) @@ -240,6 +240,8 @@ int create_bundle(struct bundle_header *header, const char *path, return error("unrecognized argument: %s'", argv[i]); } + object_array_remove_duplicates(&revs.pending); + for (i = 0; i < revs.pending.nr; i++) { struct object_array_entry *e = revs.pending.objects + i; unsigned char sha1[20]; @@ -18,6 +18,10 @@ #define deflateBound(c,s) ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11) #endif +void git_inflate_init(z_streamp strm); +void git_inflate_end(z_streamp strm); +int git_inflate(z_streamp strm, int flush); + #if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT) #define DTYPE(de) ((de)->d_type) #else @@ -480,6 +484,7 @@ struct lock_file { }; #define LOCK_DIE_ON_ERROR 1 #define LOCK_NODEREF 2 +extern NORETURN void unable_to_lock_index_die(const char *path, int err); extern int hold_lock_file_for_update(struct lock_file *, const char *path, int); extern int hold_lock_file_for_append(struct lock_file *, const char *path, int); extern int commit_lock_file(struct lock_file *); @@ -620,7 +625,7 @@ int is_directory(const char *); const char *make_absolute_path(const char *path); const char *make_nonrelative_path(const char *path); const char *make_relative_path(const char *abs, const char *base); -int normalize_absolute_path(char *buf, const char *path); +int normalize_path_copy(char *dst, const char *src); int longest_ancestor_length(const char *path, const char *prefix_list); /* Read and unpack a sha1 file into memory, write memory to a sha1 file */ @@ -821,6 +826,7 @@ extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t extern void close_pack_windows(struct packed_git *); extern void unuse_pack(struct pack_window **); extern void free_pack_by_name(const char *); +extern void clear_delta_base_cache(void); extern struct packed_git *add_packed_git(const char *, int, int); extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t); extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t); diff --git a/combine-diff.c b/combine-diff.c index ec8df39bb0..bccc018ab2 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -703,15 +703,15 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, goto deleted_file; if (S_ISLNK(st.st_mode)) { - size_t len = xsize_t(st.st_size); - result_size = len; - result = xmalloc(len + 1); - if (result_size != readlink(elem->path, result, len)) { + struct strbuf buf = STRBUF_INIT; + + if (strbuf_readlink(&buf, elem->path, st.st_size) < 0) { error("readlink(%s): %s", elem->path, strerror(errno)); return; } - result[len] = 0; + result_size = buf.len; + result = strbuf_detach(&buf, NULL); elem->mode = canon_mode(st.st_mode); } else if (0 <= (fd = open(elem->path, O_RDONLY)) && @@ -636,10 +636,7 @@ int git_config(config_fn_t fn, void *data) char *repo_config = NULL; const char *home = NULL; - /* $GIT_CONFIG makes git read _only_ the given config file, - * $GIT_CONFIG_LOCAL will make it process it in addition to the - * global config file, the same way it would the per-repository - * config file otherwise. */ + /* Setting $GIT_CONFIG makes git read _only_ the given config file. */ if (config_exclusive_filename) return git_config_from_file(fn, config_exclusive_filename, data); if (git_config_system() && !access(git_etc_gitconfig(), R_OK)) diff --git a/configure.ac b/configure.ac index 8821b5080a..0a5fc8c6f6 100644 --- a/configure.ac +++ b/configure.ac @@ -127,7 +127,7 @@ else SAVE_LDFLAGS="${LDFLAGS}" LDFLAGS="${SAVE_LDFLAGS} -Wl,-rpath,/" AC_LINK_IFELSE(AC_LANG_PROGRAM([], []), [ld_wl_rpath=yes], [ld_wl_rpath=no]) - LDFLAGS="${SAVE_LD_FLAGS}" + LDFLAGS="${SAVE_LDFLAGS}" ]) if test "$ld_wl_rpath" = "yes"; then AC_SUBST(CC_LD_DYNPATH, [-Wl,-rpath,]) @@ -136,7 +136,7 @@ else SAVE_LDFLAGS="${LDFLAGS}" LDFLAGS="${SAVE_LDFLAGS} -rpath /" AC_LINK_IFELSE(AC_LANG_PROGRAM([], []), [ld_rpath=yes], [ld_rpath=no]) - LDFLAGS="${SAVE_LD_FLAGS}" + LDFLAGS="${SAVE_LDFLAGS}" ]) if test "$ld_rpath" = "yes"; then AC_SUBST(CC_LD_DYNPATH, [-rpath]) @@ -480,8 +480,8 @@ char *get_port(char *host) char *p = strchr(host, ':'); if (p) { - strtol(p+1, &end, 10); - if (*end == '\0') { + long port = strtol(p + 1, &end, 10); + if (end != p + 1 && *end == '\0' && 0 <= port && port < 65536) { *p = '\0'; return p+1; } diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index c79c98ffec..3889cfb5aa 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -935,6 +935,11 @@ _git_log () __git_has_doubledash && return local cur="${COMP_WORDS[COMP_CWORD]}" + local g="$(git rev-parse --git-dir 2>/dev/null)" + local merge="" + if [ -f "$g/MERGE_HEAD" ]; then + merge="--merge" + fi case "$cur" in --pretty=*) __gitcomp " @@ -966,7 +971,7 @@ _git_log () --decorate --diff-filter= --color-words --walk-reflogs --parents --children --full-history - --merge + $merge " return ;; @@ -1155,7 +1160,7 @@ _git_config () ;; color.*.*) __gitcomp " - black red green yellow blue magenta cyan white + normal black red green yellow blue magenta cyan white bold dim ul blink reverse " return @@ -1179,7 +1184,7 @@ _git_config () branch.*.*) local pfx="${cur%.*}." cur="${cur##*.}" - __gitcomp "remote merge" "$pfx" "$cur" + __gitcomp "remote merge mergeoptions" "$pfx" "$cur" return ;; branch.*) @@ -1192,7 +1197,7 @@ _git_config () local pfx="${cur%.*}." cur="${cur##*.}" __gitcomp " - url fetch push skipDefaultUpdate + url proxy fetch push mirror skipDefaultUpdate receivepack uploadpack tagopt " "$pfx" "$cur" return @@ -1206,85 +1211,161 @@ _git_config () esac __gitcomp " apply.whitespace - core.fileMode - core.gitProxy - core.ignoreStat - core.preferSymlinkRefs - core.logAllRefUpdates - core.loosecompression - core.repositoryFormatVersion - core.sharedRepository - core.warnAmbiguousRefs - core.compression - core.packedGitWindowSize - core.packedGitLimit + branch.autosetupmerge + branch.autosetuprebase clean.requireForce color.branch color.branch.current color.branch.local - color.branch.remote color.branch.plain + color.branch.remote color.diff - color.diff.plain - color.diff.meta + color.diff.commit color.diff.frag - color.diff.old + color.diff.meta color.diff.new - color.diff.commit + color.diff.old + color.diff.plain color.diff.whitespace + color.interactive + color.interactive.header + color.interactive.help + color.interactive.prompt color.pager color.status - color.status.header color.status.added color.status.changed + color.status.header + color.status.nobranch color.status.untracked + color.status.updated + color.ui + commit.template + core.autocrlf + core.bare + core.compression + core.deltaBaseCacheLimit + core.editor + core.excludesfile + core.fileMode + core.fsyncobjectfiles + core.gitProxy + core.ignoreCygwinFSTricks + core.ignoreStat + core.logAllRefUpdates + core.loosecompression + core.packedGitLimit + core.packedGitWindowSize + core.pager + core.preferSymlinkRefs + core.preloadindex + core.quotepath + core.repositoryFormatVersion + core.safecrlf + core.sharedRepository + core.symlinks + core.trustctime + core.warnAmbiguousRefs + core.whitespace + core.worktree + diff.autorefreshindex + diff.external + diff.mnemonicprefix diff.renameLimit + diff.renameLimit. diff.renames fetch.unpackLimit format.headers - format.subjectprefix - gitcvs.enabled - gitcvs.logfile - gitcvs.allbinary - gitcvs.dbname gitcvs.dbdriver gitcvs.dbuser gitcvs.dbpass - gitcvs.dbtablenameprefix + format.numbered + format.pretty + format.suffix + gc.aggressiveWindow + gc.auto + gc.autopacklimit gc.packrefs + gc.pruneexpire gc.reflogexpire gc.reflogexpireunreachable gc.rerereresolved gc.rerereunresolved - http.sslVerify - http.sslCert - http.sslKey - http.sslCAInfo - http.sslCAPath - http.maxRequests + gitcvs.allbinary + gitcvs.dbTableNamePrefix + gitcvs.dbdriver + gitcvs.dbname + gitcvs.dbpass + gitcvs.dbuser + gitcvs.enabled + gitcvs.logfile + gitcvs.usecrlfattr + gui.blamehistoryctx + gui.commitmsgwidth + gui.copyblamethreshold + gui.diffcontext + gui.encoding + gui.fastcopyblame + gui.matchtrackingbranch + gui.newbranchtemplate + gui.pruneduringfetch + gui.spellingdictionary + gui.trustmtime + help.autocorrect + help.browser + help.format http.lowSpeedLimit http.lowSpeedTime + http.maxRequests http.noEPSV + http.proxy + http.sslCAInfo + http.sslCAPath + http.sslCert + http.sslKey + http.sslVerify i18n.commitEncoding i18n.logOutputEncoding + instaweb.browser + instaweb.httpd + instaweb.local + instaweb.modulepath + instaweb.port + log.date log.showroot + man.viewer + merge.conflictstyle + merge.log + merge.renameLimit + merge.stat merge.tool - merge.summary merge.verbosity - pack.window - pack.depth - pack.windowMemory + mergetool.keepBackup pack.compression - pack.deltaCacheSize pack.deltaCacheLimit + pack.deltaCacheSize + pack.depth + pack.indexVersion + pack.packSizeLimit + pack.threads + pack.window + pack.windowMemory pull.octopus pull.twohead - repack.useDeltaBaseOffset + receive.denyCurrentBranch + receive.denyDeletes + receive.denyNonFastForwards + receive.fsckObjects + receive.unpackLimit + repack.usedeltabaseoffset + rerere.autoupdate + rerere.enabled showbranch.default + status.relativePaths + status.showUntrackedFiles tar.umask transfer.unpackLimit - receive.unpackLimit - receive.denyNonFastForwards - user.name user.email + user.name user.signingkey + web.browser branch. remote. " } @@ -1675,7 +1756,7 @@ _gitk () local cur="${COMP_WORDS[COMP_CWORD]}" local g="$(git rev-parse --git-dir 2>/dev/null)" local merge="" - if [ -f $g/MERGE_HEAD ]; then + if [ -f "$g/MERGE_HEAD" ]; then merge="--merge" fi case "$cur" in diff --git a/contrib/examples/README b/contrib/examples/README new file mode 100644 index 0000000000..6946f3dd2a --- /dev/null +++ b/contrib/examples/README @@ -0,0 +1,3 @@ +These are original scripted implementations, kept primarily for their +reference value to any aspiring plumbing users who want to learn how +pieces can be fit together. diff --git a/contrib/fast-import/import-zips.py b/contrib/fast-import/import-zips.py index c674fa2d1b..7051a83a59 100755 --- a/contrib/fast-import/import-zips.py +++ b/contrib/fast-import/import-zips.py @@ -44,7 +44,8 @@ for zipfile in argv[1:]: common_prefix = name[:name.rfind('/') + 1] else: while not name.startswith(common_prefix): - common_prefix = name[:name.rfind('/') + 1] + last_slash = common_prefix[:-1].rfind('/') + 1 + common_prefix = common_prefix[:last_slash] mark[name] = ':' + str(next_mark) next_mark += 1 diff --git a/contrib/workdir/git-new-workdir b/contrib/workdir/git-new-workdir index 7959eab902..993cacf324 100755 --- a/contrib/workdir/git-new-workdir +++ b/contrib/workdir/git-new-workdir @@ -22,7 +22,7 @@ branch=$3 # want to make sure that what is pointed to has a .git directory ... git_dir=$(cd "$orig_git" 2>/dev/null && git rev-parse --git-dir 2>/dev/null) || - die "\"$orig_git\" is not a git repository!" + die "Not a git repository: \"$orig_git\"" case "$git_dir" in .git) @@ -150,7 +150,6 @@ static char *path_ok(char *directory) { static char rpath[PATH_MAX]; static char interp_path[PATH_MAX]; - int retried_path = 0; char *path; char *dir; @@ -219,22 +218,15 @@ static char *path_ok(char *directory) dir = rpath; } - do { - path = enter_repo(dir, strict_paths); - if (path) - break; - + path = enter_repo(dir, strict_paths); + if (!path && base_path && base_path_relaxed) { /* * if we fail and base_path_relaxed is enabled, try without * prefixing the base path */ - if (base_path && base_path_relaxed && !retried_path) { - dir = directory; - retried_path = 1; - continue; - } - break; - } while (1); + dir = directory; + path = enter_repo(dir, strict_paths); + } if (!path) { logerror("'%s': unable to chdir or not a git archive", dir); @@ -405,6 +397,14 @@ static void make_service_overridable(const char *name, int ena) die("No such service %s", name); } +static char *xstrdup_tolower(const char *str) +{ + char *p, *dup = xstrdup(str); + for (p = dup; *p; p++) + *p = tolower(*p); + return dup; +} + /* * Separate the "extra args" information as supplied by the client connection. */ @@ -413,7 +413,6 @@ static void parse_extra_args(char *extra_args, int buflen) char *val; int vallen; char *end = extra_args + buflen; - char *hp; while (extra_args < end && *extra_args) { saw_extended_args = 1; @@ -431,7 +430,7 @@ static void parse_extra_args(char *extra_args, int buflen) tcp_port = xstrdup(port); } free(hostname); - hostname = xstrdup(host); + hostname = xstrdup_tolower(host); } /* On to the next one */ @@ -440,19 +439,10 @@ static void parse_extra_args(char *extra_args, int buflen) } /* - * Replace literal host with lowercase-ized hostname. - */ - hp = hostname; - if (!hp) - return; - for ( ; *hp; hp++) - *hp = tolower(*hp); - - /* * Locate canonical hostname and its IP address. */ + if (hostname) { #ifndef NO_IPV6 - { struct addrinfo hints; struct addrinfo *ai, *ai0; int gai; @@ -476,9 +466,7 @@ static void parse_extra_args(char *extra_args, int buflen) } freeaddrinfo(ai0); } - } #else - { struct hostent *hent; struct sockaddr_in sa; char **ap; @@ -499,8 +487,8 @@ static void parse_extra_args(char *extra_args, int buflen) canon_hostname = xstrdup(hent->h_name); free(ip_address); ip_address = xstrdup(addrbuf); - } #endif + } } @@ -953,12 +941,8 @@ int main(int argc, char **argv) char *arg = argv[i]; if (!prefixcmp(arg, "--listen=")) { - char *p = arg + 9; - char *ph = listen_addr = xmalloc(strlen(arg + 9) + 1); - while (*p) - *ph++ = tolower(*p++); - *ph = 0; - continue; + listen_addr = xstrdup_tolower(arg + 9); + continue; } if (!prefixcmp(arg, "--port=")) { char *end; @@ -1118,7 +1102,9 @@ int main(int argc, char **argv) struct sockaddr *peer = (struct sockaddr *)&ss; socklen_t slen = sizeof(ss); - freopen("/dev/null", "w", stderr); + if (!freopen("/dev/null", "w", stderr)) + die("failed to redirect stderr to /dev/null: %s", + strerror(errno)); if (getpeername(0, peer, &slen)) peer = NULL; diff --git a/diff-no-index.c b/diff-no-index.c index b60d3455da..a3e47a76e4 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -173,8 +173,10 @@ void diff_no_index(struct rev_info *revs, /* Were we asked to do --no-index explicitly? */ for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "--")) - return; + if (!strcmp(argv[i], "--")) { + i++; + break; + } if (!strcmp(argv[i], "--no-index")) no_index = 1; if (argv[i][0] != '-') @@ -198,22 +200,17 @@ void diff_no_index(struct rev_info *revs, die("git diff %s takes two paths", no_index ? "--no-index" : "[--no-index]"); - /* - * If the user asked for our exit code then don't start a - * pager or we would end up reporting its exit code instead. - */ - if (!DIFF_OPT_TST(&revs->diffopt, EXIT_WITH_STATUS)) - setup_pager(); - diff_setup(&revs->diffopt); - if (!revs->diffopt.output_format) - revs->diffopt.output_format = DIFF_FORMAT_PATCH; for (i = 1; i < argc - 2; ) { int j; if (!strcmp(argv[i], "--no-index")) i++; - else if (!strcmp(argv[1], "-q")) + else if (!strcmp(argv[i], "-q")) { options |= DIFF_SILENT_ON_REMOVED; + i++; + } + else if (!strcmp(argv[i], "--")) + i++; else { j = diff_opt_parse(&revs->diffopt, argv + i, argc - i); if (!j) @@ -222,6 +219,13 @@ void diff_no_index(struct rev_info *revs, } } + /* + * If the user asked for our exit code then don't start a + * pager or we would end up reporting its exit code instead. + */ + if (!DIFF_OPT_TST(&revs->diffopt, EXIT_WITH_STATUS)) + setup_pager(); + if (prefix) { int len = strlen(prefix); @@ -241,6 +245,9 @@ void diff_no_index(struct rev_info *revs, else revs->diffopt.paths = argv + argc - 2; revs->diffopt.nr_paths = 2; + revs->diffopt.skip_stat_unmatch = 1; + if (!revs->diffopt.output_format) + revs->diffopt.output_format = DIFF_FORMAT_PATCH; DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); DIFF_OPT_SET(&revs->diffopt, NO_INDEX); @@ -118,7 +118,9 @@ int git_diff_basic_config(const char *var, const char *value, void *cb) } /* like GNU diff's --suppress-blank-empty option */ - if (!strcmp(var, "diff.suppress-blank-empty")) { + if (!strcmp(var, "diff.suppressblankempty") || + /* for backwards compatibility */ + !strcmp(var, "diff.suppress-blank-empty")) { diff_suppress_blank_empty = git_config_bool(var, value); return 0; } @@ -1773,19 +1775,18 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) s->size = xsize_t(st.st_size); if (!s->size) goto empty; - if (size_only) - return 0; if (S_ISLNK(st.st_mode)) { - int ret; - s->data = xmalloc(s->size); - s->should_free = 1; - ret = readlink(s->path, s->data, s->size); - if (ret < 0) { - free(s->data); + struct strbuf sb = STRBUF_INIT; + + if (strbuf_readlink(&sb, s->path, s->size)) goto err_empty; - } + s->size = sb.len; + s->data = strbuf_detach(&sb, NULL); + s->should_free = 1; return 0; } + if (size_only) + return 0; fd = open(s->path, O_RDONLY); if (fd < 0) goto err_empty; @@ -1883,13 +1884,12 @@ static void prepare_temp_file(const char *name, if (S_ISLNK(st.st_mode)) { int ret; char buf[PATH_MAX + 1]; /* ought to be SYMLINK_MAX */ - size_t sz = xsize_t(st.st_size); - if (sizeof(buf) <= st.st_size) - die("symlink too long: %s", name); - ret = readlink(name, buf, sz); + ret = readlink(name, buf, sizeof(buf)); if (ret < 0) die("readlink(%s)", name); - prep_temp_blob(temp, buf, sz, + if (ret == sizeof(buf)) + die("symlink too long: %s", name); + prep_temp_blob(temp, buf, ret, (one->sha1_valid ? one->sha1 : null_sha1), (one->sha1_valid ? @@ -1999,16 +1999,86 @@ static void run_external_diff(const char *pgm, } } +static int similarity_index(struct diff_filepair *p) +{ + return p->score * 100 / MAX_SCORE; +} + +static void fill_metainfo(struct strbuf *msg, + const char *name, + const char *other, + struct diff_filespec *one, + struct diff_filespec *two, + struct diff_options *o, + struct diff_filepair *p) +{ + strbuf_init(msg, PATH_MAX * 2 + 300); + switch (p->status) { + case DIFF_STATUS_COPIED: + strbuf_addf(msg, "similarity index %d%%", similarity_index(p)); + strbuf_addstr(msg, "\ncopy from "); + quote_c_style(name, msg, NULL, 0); + strbuf_addstr(msg, "\ncopy to "); + quote_c_style(other, msg, NULL, 0); + strbuf_addch(msg, '\n'); + break; + case DIFF_STATUS_RENAMED: + strbuf_addf(msg, "similarity index %d%%", similarity_index(p)); + strbuf_addstr(msg, "\nrename from "); + quote_c_style(name, msg, NULL, 0); + strbuf_addstr(msg, "\nrename to "); + quote_c_style(other, msg, NULL, 0); + strbuf_addch(msg, '\n'); + break; + case DIFF_STATUS_MODIFIED: + if (p->score) { + strbuf_addf(msg, "dissimilarity index %d%%\n", + similarity_index(p)); + break; + } + /* fallthru */ + default: + /* nothing */ + ; + } + if (one && two && hashcmp(one->sha1, two->sha1)) { + int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV; + + if (DIFF_OPT_TST(o, BINARY)) { + mmfile_t mf; + if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) || + (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two))) + abbrev = 40; + } + strbuf_addf(msg, "index %.*s..%.*s", + abbrev, sha1_to_hex(one->sha1), + abbrev, sha1_to_hex(two->sha1)); + if (one->mode == two->mode) + strbuf_addf(msg, " %06o", one->mode); + strbuf_addch(msg, '\n'); + } + if (msg->len) + strbuf_setlen(msg, msg->len - 1); +} + static void run_diff_cmd(const char *pgm, const char *name, const char *other, const char *attr_path, struct diff_filespec *one, struct diff_filespec *two, - const char *xfrm_msg, + struct strbuf *msg, struct diff_options *o, - int complete_rewrite) + struct diff_filepair *p) { + const char *xfrm_msg = NULL; + int complete_rewrite = (p->status == DIFF_STATUS_MODIFIED) && p->score; + + if (msg) { + fill_metainfo(msg, name, other, one, two, o, p); + xfrm_msg = msg->len ? msg->buf : NULL; + } + if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL)) pgm = NULL; else { @@ -2048,11 +2118,6 @@ static void diff_fill_sha1_info(struct diff_filespec *one) hashclr(one->sha1); } -static int similarity_index(struct diff_filepair *p) -{ - return p->score * 100 / MAX_SCORE; -} - static void strip_prefix(int prefix_length, const char **namep, const char **otherp) { /* Strip the prefix but do not molest /dev/null and absolute paths */ @@ -2066,13 +2131,11 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) { const char *pgm = external_diff(); struct strbuf msg; - char *xfrm_msg; struct diff_filespec *one = p->one; struct diff_filespec *two = p->two; const char *name; const char *other; const char *attr_path; - int complete_rewrite = 0; name = p->one->path; other = (strcmp(name, p->two->path) ? p->two->path : NULL); @@ -2082,83 +2145,34 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) if (DIFF_PAIR_UNMERGED(p)) { run_diff_cmd(pgm, name, NULL, attr_path, - NULL, NULL, NULL, o, 0); + NULL, NULL, NULL, o, p); return; } diff_fill_sha1_info(one); diff_fill_sha1_info(two); - strbuf_init(&msg, PATH_MAX * 2 + 300); - switch (p->status) { - case DIFF_STATUS_COPIED: - strbuf_addf(&msg, "similarity index %d%%", similarity_index(p)); - strbuf_addstr(&msg, "\ncopy from "); - quote_c_style(name, &msg, NULL, 0); - strbuf_addstr(&msg, "\ncopy to "); - quote_c_style(other, &msg, NULL, 0); - strbuf_addch(&msg, '\n'); - break; - case DIFF_STATUS_RENAMED: - strbuf_addf(&msg, "similarity index %d%%", similarity_index(p)); - strbuf_addstr(&msg, "\nrename from "); - quote_c_style(name, &msg, NULL, 0); - strbuf_addstr(&msg, "\nrename to "); - quote_c_style(other, &msg, NULL, 0); - strbuf_addch(&msg, '\n'); - break; - case DIFF_STATUS_MODIFIED: - if (p->score) { - strbuf_addf(&msg, "dissimilarity index %d%%\n", - similarity_index(p)); - complete_rewrite = 1; - break; - } - /* fallthru */ - default: - /* nothing */ - ; - } - - if (hashcmp(one->sha1, two->sha1)) { - int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV; - - if (DIFF_OPT_TST(o, BINARY)) { - mmfile_t mf; - if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) || - (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two))) - abbrev = 40; - } - strbuf_addf(&msg, "index %.*s..%.*s", - abbrev, sha1_to_hex(one->sha1), - abbrev, sha1_to_hex(two->sha1)); - if (one->mode == two->mode) - strbuf_addf(&msg, " %06o", one->mode); - strbuf_addch(&msg, '\n'); - } - - if (msg.len) - strbuf_setlen(&msg, msg.len - 1); - xfrm_msg = msg.len ? msg.buf : NULL; - if (!pgm && DIFF_FILE_VALID(one) && DIFF_FILE_VALID(two) && (S_IFMT & one->mode) != (S_IFMT & two->mode)) { - /* a filepair that changes between file and symlink + /* + * a filepair that changes between file and symlink * needs to be split into deletion and creation. */ struct diff_filespec *null = alloc_filespec(two->path); run_diff_cmd(NULL, name, other, attr_path, - one, null, xfrm_msg, o, 0); + one, null, &msg, o, p); free(null); + strbuf_release(&msg); + null = alloc_filespec(one->path); run_diff_cmd(NULL, name, other, attr_path, - null, two, xfrm_msg, o, 0); + null, two, &msg, o, p); free(null); } else run_diff_cmd(pgm, name, other, attr_path, - one, two, xfrm_msg, o, complete_rewrite); + one, two, &msg, o, p); strbuf_release(&msg); } diff --git a/diffcore-rename.c b/diffcore-rename.c index 168a95b541..0b0d6b8c8c 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -153,9 +153,9 @@ static int estimate_similarity(struct diff_filespec *src, * is a possible size - we really should have a flag to * say whether the size is valid or not!) */ - if (!src->cnt_data && diff_populate_filespec(src, 0)) + if (!src->cnt_data && diff_populate_filespec(src, 1)) return 0; - if (!dst->cnt_data && diff_populate_filespec(dst, 0)) + if (!dst->cnt_data && diff_populate_filespec(dst, 1)) return 0; max_size = ((src->size > dst->size) ? src->size : dst->size); @@ -173,6 +173,11 @@ static int estimate_similarity(struct diff_filespec *src, if (base_size * (MAX_SCORE-minimum_score) < delta_size * MAX_SCORE) return 0; + if (!src->cnt_data && diff_populate_filespec(src, 0)) + return 0; + if (!dst->cnt_data && diff_populate_filespec(dst, 0)) + return 0; + delta_limit = (unsigned long) (base_size * (MAX_SCORE-minimum_score) / MAX_SCORE); if (diffcore_count_changes(src, dst, @@ -134,7 +134,7 @@ int match_pathspec(const char **pathspec, const char *name, int namelen, int pre static int no_wildcard(const char *string) { - return string[strcspn(string, "*?[{")] == '\0'; + return string[strcspn(string, "*?[{\\")] == '\0'; } void add_exclude(const char *string, const char *base, diff --git a/exec_cmd.c b/exec_cmd.c index cdd35f9195..351fec2e9e 100644 --- a/exec_cmd.c +++ b/exec_cmd.c @@ -25,6 +25,10 @@ void git_set_argv0_path(const char *path) void git_set_argv_exec_path(const char *exec_path) { argv_exec_path = exec_path; + /* + * Propagate this setting to external programs. + */ + setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1); } diff --git a/fast-import.c b/fast-import.c index 3c035a5788..f246d5347b 100644 --- a/fast-import.c +++ b/fast-import.c @@ -43,7 +43,7 @@ Format of STDIN stream: new_tag ::= 'tag' sp tag_str lf 'from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf - 'tagger' sp name '<' email '>' when lf + ('tagger' sp name '<' email '>' when lf)? tag_msg; tag_msg ::= data; @@ -554,6 +554,10 @@ static void *pool_alloc(size_t len) struct mem_pool *p; void *r; + /* round up to a 'uintmax_t' alignment */ + if (len & (sizeof(uintmax_t) - 1)) + len += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1)); + for (p = mem_pool; p; p = p->next_pool) if ((p->end - p->next_free >= len)) break; @@ -572,9 +576,6 @@ static void *pool_alloc(size_t len) } r = p->next_free; - /* round out to a 'uintmax_t' alignment */ - if (len & (sizeof(uintmax_t) - 1)) - len += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1)); p->next_free += len; return r; } @@ -815,9 +816,8 @@ static void start_packfile(void) struct pack_header hdr; int pack_fd; - snprintf(tmpfile, sizeof(tmpfile), - "%s/pack/tmp_pack_XXXXXX", get_object_directory()); - pack_fd = xmkstemp(tmpfile); + pack_fd = odb_mkstemp(tmpfile, sizeof(tmpfile), + "pack/tmp_pack_XXXXXX"); p = xcalloc(1, sizeof(*p) + strlen(tmpfile) + 2); strcpy(p->pack_name, tmpfile); p->pack_fd = pack_fd; @@ -877,9 +877,8 @@ static char *create_index(void) c = next; } - snprintf(tmpfile, sizeof(tmpfile), - "%s/pack/tmp_idx_XXXXXX", get_object_directory()); - idx_fd = xmkstemp(tmpfile); + idx_fd = odb_mkstemp(tmpfile, sizeof(tmpfile), + "pack/tmp_idx_XXXXXX"); f = sha1fd(idx_fd, tmpfile); sha1write(f, array, 256 * sizeof(int)); git_SHA1_Init(&ctx); @@ -905,9 +904,7 @@ static char *keep_pack(char *curr_index_name) chmod(pack_data->pack_name, 0444); chmod(curr_index_name, 0444); - snprintf(name, sizeof(name), "%s/pack/pack-%s.keep", - get_object_directory(), sha1_to_hex(pack_data->sha1)); - keep_fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600); + keep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1); if (keep_fd < 0) die("cannot create keep file"); write_or_die(keep_fd, keep_msg, strlen(keep_msg)); @@ -943,6 +940,7 @@ static void end_packfile(void) { struct packed_git *old_p = pack_data, *new_p; + clear_delta_base_cache(); if (object_count) { char *idx_name; int i; @@ -982,8 +980,10 @@ static void end_packfile(void) pack_id++; } - else + else { + close(old_p->pack_fd); unlink(old_p->pack_name); + } free(old_p); /* We can't carry a delta across packfiles. */ @@ -1745,9 +1745,12 @@ static int validate_raw_date(const char *src, char *result, int maxlen) { const char *orig_src = src; char *endp, sign; + unsigned long date; + + errno = 0; - strtoul(src, &endp, 10); - if (endp == src || *endp != ' ') + date = strtoul(src, &endp, 10); + if (errno || endp == src || *endp != ' ') return -1; src = endp + 1; @@ -1755,8 +1758,8 @@ static int validate_raw_date(const char *src, char *result, int maxlen) return -1; sign = *src; - strtoul(src + 1, &endp, 10); - if (endp == src || *endp || (endp - orig_src) >= maxlen) + date = strtoul(src + 1, &endp, 10); + if (errno || endp == src || *endp || (endp - orig_src) >= maxlen) return -1; strcpy(result, orig_src); @@ -1866,12 +1869,13 @@ static void file_change_m(struct branch *b) if (!p) die("Corrupt mode: %s", command_buf.buf); switch (mode) { + case 0644: + case 0755: + mode |= S_IFREG; case S_IFREG | 0644: case S_IFREG | 0755: case S_IFLNK: case S_IFGITLINK: - case 0644: - case 0755: /* ok */ break; default: @@ -1938,7 +1942,7 @@ static void file_change_m(struct branch *b) typename(type), command_buf.buf); } - tree_content_set(&b->branch_tree, p, sha1, S_IFREG | mode, NULL); + tree_content_set(&b->branch_tree, p, sha1, mode, NULL); } static void file_change_d(struct branch *b) @@ -2262,23 +2266,27 @@ static void parse_new_tag(void) read_next_command(); /* tagger ... */ - if (prefixcmp(command_buf.buf, "tagger ")) - die("Expected tagger command, got %s", command_buf.buf); - tagger = parse_ident(command_buf.buf + 7); + if (!prefixcmp(command_buf.buf, "tagger ")) { + tagger = parse_ident(command_buf.buf + 7); + read_next_command(); + } else + tagger = NULL; /* tag payload/message */ - read_next_command(); parse_data(&msg); /* build the tag object */ strbuf_reset(&new_data); + strbuf_addf(&new_data, - "object %s\n" - "type %s\n" - "tag %s\n" - "tagger %s\n" - "\n", - sha1_to_hex(sha1), commit_type, t->name, tagger); + "object %s\n" + "type %s\n" + "tag %s\n", + sha1_to_hex(sha1), commit_type, t->name); + if (tagger) + strbuf_addf(&new_data, + "tagger %s\n", tagger); + strbuf_addch(&new_data, '\n'); strbuf_addbuf(&new_data, &msg); free(tagger); diff --git a/git-bisect.sh b/git-bisect.sh index 17a35f6adc..10ad340920 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -284,62 +284,74 @@ filter_skipped() { _skip="$2" if [ -z "$_skip" ]; then - eval "$_eval" + eval "$_eval" | { + while read line + do + echo "$line &&" + done + echo ':' + } return fi # Let's parse the output of: # "git rev-list --bisect-vars --bisect-all ..." - eval "$_eval" | while read hash line - do - case "$VARS,$FOUND,$TRIED,$hash" in - # We display some vars. - 1,*,*,*) echo "$hash $line" ;; - - # Split line. - ,*,*,---*) ;; - - # We had nothing to search. + eval "$_eval" | { + VARS= FOUND= TRIED= + while read hash line + do + case "$VARS,$FOUND,$TRIED,$hash" in + 1,*,*,*) + # "bisect_foo=bar" read from rev-list output. + echo "$hash &&" + ;; + ,*,*,---*) + # Separator + ;; ,,,bisect_rev*) - echo "bisect_rev=" + # We had nothing to search. + echo "bisect_rev= &&" VARS=1 ;; - - # We did not find a good bisect rev. - # This should happen only if the "bad" - # commit is also a "skip" commit. ,,*,bisect_rev*) - echo "bisect_rev=$TRIED" + # We did not find a good bisect rev. + # This should happen only if the "bad" + # commit is also a "skip" commit. + echo "bisect_rev='$TRIED' &&" VARS=1 ;; - - # We are searching. ,,*,*) + # We are searching. TRIED="${TRIED:+$TRIED|}$hash" case "$_skip" in *$hash*) ;; *) - echo "bisect_rev=$hash" - echo "bisect_tried=\"$TRIED\"" + echo "bisect_rev=$hash &&" + echo "bisect_tried='$TRIED' &&" FOUND=1 ;; esac ;; - - # We have already found a rev to be tested. - ,1,*,bisect_rev*) VARS=1 ;; - ,1,*,*) ;; - - # ??? - *) die "filter_skipped error " \ - "VARS: '$VARS' " \ - "FOUND: '$FOUND' " \ - "TRIED: '$TRIED' " \ - "hash: '$hash' " \ - "line: '$line'" - ;; - esac - done + ,1,*,bisect_rev*) + # We have already found a rev to be tested. + VARS=1 + ;; + ,1,*,*) + ;; + *) + # Unexpected input + echo "die 'filter_skipped error'" + die "filter_skipped error " \ + "VARS: '$VARS' " \ + "FOUND: '$FOUND' " \ + "TRIED: '$TRIED' " \ + "hash: '$hash' " \ + "line: '$line'" + ;; + esac + done + echo ':' + } } exit_if_skipped_commits () { @@ -508,7 +520,7 @@ bisect_visualize() { if test $# = 0 then - case "${DISPLAY+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" in + case "${DISPLAY+set}${SESSIONNAME+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" in '') set git log ;; set*) set gitk ;; esac diff --git a/git-compat-util.h b/git-compat-util.h index e20b1e858c..124bb94b15 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -303,6 +303,8 @@ extern ssize_t xwrite(int fd, const void *buf, size_t len); extern int xdup(int fd); extern FILE *xfdopen(int fd, const char *mode); extern int xmkstemp(char *template); +extern int odb_mkstemp(char *template, size_t limit, const char *pattern); +extern int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1); static inline size_t xsize_t(off_t len) { diff --git a/git-filter-branch.sh b/git-filter-branch.sh index c106f45af7..0897b5971a 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -98,7 +98,7 @@ OPTIONS_SPEC= . git-sh-setup if [ "$(is_bare_repository)" = false ]; then - git diff-files --quiet && + git diff-files --ignore-submodules --quiet && git diff-index --cached --quiet HEAD -- || die "Cannot rewrite branch(es) with a dirty working directory." fi @@ -442,19 +442,20 @@ rm -rf "$tempdir" trap - 0 +unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE +test -z "$ORIG_GIT_DIR" || { + GIT_DIR="$ORIG_GIT_DIR" && export GIT_DIR +} +test -z "$ORIG_GIT_WORK_TREE" || { + GIT_WORK_TREE="$ORIG_GIT_WORK_TREE" && + export GIT_WORK_TREE +} +test -z "$ORIG_GIT_INDEX_FILE" || { + GIT_INDEX_FILE="$ORIG_GIT_INDEX_FILE" && + export GIT_INDEX_FILE +} + if [ "$(is_bare_repository)" = false ]; then - unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE - test -z "$ORIG_GIT_DIR" || { - GIT_DIR="$ORIG_GIT_DIR" && export GIT_DIR - } - test -z "$ORIG_GIT_WORK_TREE" || { - GIT_WORK_TREE="$ORIG_GIT_WORK_TREE" && - export GIT_WORK_TREE - } - test -z "$ORIG_GIT_INDEX_FILE" || { - GIT_INDEX_FILE="$ORIG_GIT_INDEX_FILE" && - export GIT_INDEX_FILE - } git read-tree -u -m HEAD fi diff --git a/git-gui/GIT-VERSION-GEN b/git-gui/GIT-VERSION-GEN index 4e709ebe77..b3f937eace 100755 --- a/git-gui/GIT-VERSION-GEN +++ b/git-gui/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=0.11.GITGUI +DEF_VER=0.12.GITGUI LF=' ' diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index 8a4b42dbd7..e018e076f8 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -2630,6 +2630,20 @@ proc usage {} { exit 1 } +proc normalize_relpath {path} { + set elements {} + foreach item [file split $path] { + if {$item eq {.}} continue + if {$item eq {..} && [llength $elements] > 0 + && [lindex $elements end] ne {..}} { + set elements [lrange $elements 0 end-1] + continue + } + lappend elements $item + } + return [eval file join $elements] +} + # -- Not a normal commit type invocation? Do that instead! # switch -- $subcommand { @@ -2648,7 +2662,7 @@ blame { foreach a $argv { if {$is_path || [file exists $_prefix$a]} { if {$path ne {}} usage - set path $_prefix$a + set path [normalize_relpath $_prefix$a] break } elseif {$a eq {--}} { if {$path ne {}} { @@ -2671,7 +2685,7 @@ blame { unset is_path if {$head ne {} && $path eq {}} { - set path $_prefix$head + set path [normalize_relpath $_prefix$head] set head {} } @@ -3315,7 +3329,6 @@ by %s: {^GIT_PAGER$} - {^GIT_TRACE$} - {^GIT_CONFIG$} - - {^GIT_CONFIG_LOCAL$} - {^GIT_(AUTHOR|COMMITTER)_DATE$} { append msg " - $name\n" incr ignored_env diff --git a/git-gui/lib/blame.tcl b/git-gui/lib/blame.tcl index c1cd7f3b92..1f3b08f9ef 100644 --- a/git-gui/lib/blame.tcl +++ b/git-gui/lib/blame.tcl @@ -940,9 +940,8 @@ method _showcommit {cur_w lno} { catch { set fd [git_read cat-file commit $cmit] fconfigure $fd -encoding binary -translation lf - if {[catch {set enc $repo_config(i18n.commitencoding)}]} { - set enc utf-8 - } + # By default commits are assumed to be in utf-8 + set enc utf-8 while {[gets $fd line] > 0} { if {[string match {encoding *} $line]} { set enc [string tolower [string range $line 9 end]] diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl index 334514996a..9cc8410595 100644 --- a/git-gui/lib/commit.tcl +++ b/git-gui/lib/commit.tcl @@ -27,9 +27,8 @@ You are currently in the middle of a merge that has not been fully completed. Y if {[catch { set fd [git_read cat-file commit $curHEAD] fconfigure $fd -encoding binary -translation lf - if {[catch {set enc $repo_config(i18n.commitencoding)}]} { - set enc utf-8 - } + # By default commits are assumed to be in utf-8 + set enc utf-8 while {[gets $fd line] > 0} { if {[string match {parent *} $line]} { lappend parents [string range $line 7 end] @@ -208,7 +207,7 @@ A good commit message has the following format: if {$use_enc ne {}} { fconfigure $msg_wt -encoding $use_enc } else { - puts stderr [mc "warning: Tcl does not support encoding '%s'." $enc] + error_popup [mc "warning: Tcl does not support encoding '%s'." $enc] fconfigure $msg_wt -encoding utf-8 } puts $msg_wt $msg diff --git a/git-gui/po/de.po b/git-gui/po/de.po index 5c04812b1a..a6f730b4eb 100644 --- a/git-gui/po/de.po +++ b/git-gui/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: git-gui\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-10-25 13:32+0200\n" -"PO-Revision-Date: 2008-10-25 22:47+0200\n" +"POT-Creation-Date: 2008-12-06 20:51+0100\n" +"PO-Revision-Date: 2008-12-06 21:22+0100\n" "Last-Translator: Christian Stimming <stimming@tuhh.de>\n" "Language-Team: German\n" "MIME-Version: 1.0\n" @@ -86,17 +86,15 @@ msgstr "Dateistatus aktualisieren..." msgid "Scanning for modified files ..." msgstr "Nach geänderten Dateien suchen..." -#: git-gui.sh:1325 -#, fuzzy +#: git-gui.sh:1367 msgid "Calling prepare-commit-msg hook..." -msgstr "Aufrufen der Vor-Eintragen-Kontrolle..." +msgstr "Aufrufen der Eintragen-Vorbereiten-Kontrolle..." -#: git-gui.sh:1342 -#, fuzzy +#: git-gui.sh:1384 msgid "Commit declined by prepare-commit-msg hook." -msgstr "Eintragen abgelehnt durch Vor-Eintragen-Kontrolle (»pre-commit hook«)." +msgstr "Eintragen abgelehnt durch Eintragen-Vorbereiten-Kontrolle (»prepare-commit hook«)." -#: git-gui.sh:1502 lib/browser.tcl:246 +#: git-gui.sh:1542 lib/browser.tcl:246 msgid "Ready." msgstr "Bereit." @@ -180,7 +178,11 @@ msgstr "Zusammenführen" msgid "Remote" msgstr "Andere Archive" -#: git-gui.sh:2242 +#: git-gui.sh:2293 +msgid "Tools" +msgstr "Werkzeuge" + +#: git-gui.sh:2302 msgid "Explore Working Copy" msgstr "Arbeitskopie im Dateimanager" @@ -363,7 +365,11 @@ msgstr "Einstellungen..." msgid "Options..." msgstr "Optionen..." -#: git-gui.sh:2113 lib/choose_repository.tcl:47 +#: git-gui.sh:2576 +msgid "Remove..." +msgstr "Entfernen..." + +#: git-gui.sh:2585 lib/choose_repository.tcl:50 msgid "Help" msgstr "Hilfe" @@ -371,7 +377,11 @@ msgstr "Hilfe" msgid "Online Documentation" msgstr "Online-Dokumentation" -#: git-gui.sh:2238 +#: git-gui.sh:2614 lib/choose_repository.tcl:47 lib/choose_repository.tcl:56 +msgid "Show SSH Key" +msgstr "SSH-Schlüssel anzeigen" + +#: git-gui.sh:2707 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" msgstr "" @@ -548,7 +558,11 @@ msgstr "Version:" msgid "Copy Commit" msgstr "Version kopieren" -#: lib/blame.tcl:260 +#: lib/blame.tcl:275 +msgid "Find Text..." +msgstr "Text suchen..." + +#: lib/blame.tcl:284 msgid "Do Full Copy Detection" msgstr "Volle Kopie-Erkennung" @@ -609,12 +623,11 @@ msgstr "Eintragender:" msgid "Original File:" msgstr "Ursprüngliche Datei:" -#: lib/blame.tcl:1013 -#, fuzzy +#: lib/blame.tcl:1021 msgid "Cannot find HEAD commit:" -msgstr "Elternversion kann nicht gefunden werden:" +msgstr "Zweigspitze (»HEAD«) kann nicht gefunden werden:" -#: lib/blame.tcl:1068 +#: lib/blame.tcl:1076 msgid "Cannot find parent commit:" msgstr "Elternversion kann nicht gefunden werden:" @@ -1049,7 +1062,7 @@ msgstr "Zuletzt benutztes Projektarchiv öffnen:" msgid "Failed to create repository %s:" msgstr "Projektarchiv »%s« konnte nicht erstellt werden:" -#: lib/choose_repository.tcl:381 lib/choose_repository.tcl:478 +#: lib/choose_repository.tcl:387 msgid "Directory:" msgstr "Verzeichnis:" @@ -1058,12 +1071,12 @@ msgstr "Verzeichnis:" msgid "Git Repository" msgstr "Git Projektarchiv" -#: lib/choose_repository.tcl:437 +#: lib/choose_repository.tcl:442 #, tcl-format msgid "Directory %s already exists." msgstr "Verzeichnis »%s« existiert bereits." -#: lib/choose_repository.tcl:441 +#: lib/choose_repository.tcl:446 #, tcl-format msgid "File %s already exists." msgstr "Datei »%s« existiert bereits." @@ -1072,11 +1085,11 @@ msgstr "Datei »%s« existiert bereits." msgid "Clone" msgstr "Klonen" -#: lib/choose_repository.tcl:467 +#: lib/choose_repository.tcl:473 msgid "Source Location:" -msgstr "" +msgstr "Herkunft:" -#: lib/choose_repository.tcl:478 +#: lib/choose_repository.tcl:484 msgid "Target Directory:" msgstr "Zielverzeichnis:" @@ -1565,20 +1578,24 @@ msgid "" "LOCAL: deleted\n" "REMOTE:\n" msgstr "" +"LOKAL: gelöscht\n" +"ANDERES:\n" #: lib/diff.tcl:125 msgid "" "REMOTE: deleted\n" "LOCAL:\n" msgstr "" +"ANDERES: gelöscht\n" +"LOKAL:\n" #: lib/diff.tcl:132 msgid "LOCAL:\n" -msgstr "" +msgstr "LOKAL:\n" #: lib/diff.tcl:135 msgid "REMOTE:\n" -msgstr "" +msgstr "ANDERES:\n" #: lib/diff.tcl:197 lib/diff.tcl:296 #, tcl-format @@ -1603,6 +1620,8 @@ msgid "" "* Untracked file is %d bytes.\n" "* Showing only first %d bytes.\n" msgstr "" +"* Datei nicht unter Versionskontrolle, Dateigröße %d Bytes.\n" +"* Nur erste %d Bytes werden angezeigt.\n" #: lib/diff.tcl:228 #, tcl-format @@ -1611,8 +1630,11 @@ msgid "" "* Untracked file clipped here by %s.\n" "* To see the entire file, use an external editor.\n" msgstr "" +"\n" +"* Datei nicht unter Versionskontrolle, hier abgeschnitten durch %s.\n" +"* Zum Ansehen der vollständigen Datei externen Editor benutzen.\n" -#: lib/diff.tcl:437 +#: lib/diff.tcl:436 msgid "Failed to unstage selected hunk." msgstr "" "Fehler beim Herausnehmen des gewählten Kontexts aus der Bereitstellung." @@ -2045,7 +2067,7 @@ msgstr "Namensvorschlag für neue Zweige" #: lib/option.tcl:155 msgid "Default File Contents Encoding" -msgstr "Vorgestellte Zeichenkodierung" +msgstr "Voreingestellte Zeichenkodierung" #: lib/option.tcl:203 msgid "Change" @@ -2113,19 +2135,18 @@ msgid "Do Nothing Else Now" msgstr "Nichts tun" #: lib/remote_add.tcl:101 -#, fuzzy msgid "Please supply a remote name." -msgstr "Bitte geben Sie einen Zweignamen an." +msgstr "Bitte geben Sie einen Namen des anderen Archivs an." #: lib/remote_add.tcl:114 -#, fuzzy, tcl-format +#, tcl-format msgid "'%s' is not an acceptable remote name." -msgstr "»%s« ist kein zulässiger Zweigname." +msgstr "»%s« ist kein zulässiger Name eines anderen Archivs." #: lib/remote_add.tcl:125 -#, fuzzy, tcl-format +#, tcl-format msgid "Failed to add remote '%s' of location '%s'." -msgstr "Fehler beim Umbenennen von »%s«." +msgstr "Fehler beim Hinzufügen des anderen Archivs »%s« aus Herkunftsort »%s«." #: lib/remote_add.tcl:133 lib/transport.tcl:6 #, tcl-format @@ -2133,16 +2154,18 @@ msgid "fetch %s" msgstr "»%s« anfordern" #: lib/remote_add.tcl:134 -#, fuzzy, tcl-format +#, tcl-format msgid "Fetching the %s" -msgstr "Änderungen »%s« von »%s« anfordern" +msgstr "»%s« anfordern" #: lib/remote_add.tcl:157 #, tcl-format msgid "Do not know how to initialize repository at location '%s'." -msgstr "Initialisieren eines anderen Archivs an Adresse »%s« ist nicht möglich." +msgstr "" +"Initialisieren eines anderen Archivs an Adresse »%s« ist nicht möglich." -#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:71 +#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:63 +#: lib/transport.tcl:81 #, tcl-format msgid "push %s" msgstr "»%s« versenden..." @@ -2266,9 +2289,9 @@ msgstr "Nächster" msgid "Prev" msgstr "Voriger" -#: lib/search.tcl:24 +#: lib/search.tcl:25 msgid "Case-Sensitive" -msgstr "" +msgstr "Groß-/Kleinschreibung unterscheiden" #: lib/shortcut.tcl:20 lib/shortcut.tcl:61 msgid "Cannot write shortcut:" @@ -2315,11 +2338,182 @@ msgstr "Unerwartetes EOF vom Rechtschreibprüfungsprogramm" msgid "Spell Checker Failed" msgstr "Rechtschreibprüfung fehlgeschlagen" +#: lib/sshkey.tcl:31 +msgid "No keys found." +msgstr "Keine Schlüssel gefunden." + +#: lib/sshkey.tcl:34 +#, tcl-format +msgid "Found a public key in: %s" +msgstr "Öffentlicher Schlüssel gefunden in: %s" + +#: lib/sshkey.tcl:40 +msgid "Generate Key" +msgstr "Schlüssel erzeugen" + +#: lib/sshkey.tcl:56 +msgid "Copy To Clipboard" +msgstr "In Zwischenablage kopieren" + +#: lib/sshkey.tcl:70 +msgid "Your OpenSSH Public Key" +msgstr "Ihr OpenSSH öffenlicher Schlüssel" + +#: lib/sshkey.tcl:78 +msgid "Generating..." +msgstr "Erzeugen..." + +#: lib/sshkey.tcl:84 +#, tcl-format +msgid "" +"Could not start ssh-keygen:\n" +"\n" +"%s" +msgstr "" +"Konnte »ssh-keygen« nicht starten:\n" +"\n" +"%s" + +#: lib/sshkey.tcl:111 +msgid "Generation failed." +msgstr "Schlüsselerzeugung fehlgeschlagen." + +#: lib/sshkey.tcl:118 +msgid "Generation succeded, but no keys found." +msgstr "Schlüsselerzeugung erfolgreich, aber keine Schlüssel gefunden." + +#: lib/sshkey.tcl:121 +#, tcl-format +msgid "Your key is in: %s" +msgstr "Ihr Schlüssel ist abgelegt in: %s" + #: lib/status_bar.tcl:83 #, tcl-format msgid "%s ... %*i of %*i %s (%3i%%)" msgstr "%s ... %*i von %*i %s (%3i%%)" +#: lib/tools_dlg.tcl:22 +msgid "Add Tool" +msgstr "Werkzeug hinzufügen" + +#: lib/tools_dlg.tcl:28 +msgid "Add New Tool Command" +msgstr "Neues Kommando für Werkzeug hinzufügen" + +#: lib/tools_dlg.tcl:33 +msgid "Add globally" +msgstr "Global hinzufügen" + +#: lib/tools_dlg.tcl:45 +msgid "Tool Details" +msgstr "Einzelheiten des Werkzeugs" + +#: lib/tools_dlg.tcl:48 +msgid "Use '/' separators to create a submenu tree:" +msgstr "Benutzen Sie einen Schrägstrich »/«, um Untermenüs zu erstellen:" + +#: lib/tools_dlg.tcl:61 +msgid "Command:" +msgstr "Kommando:" + +#: lib/tools_dlg.tcl:74 +msgid "Show a dialog before running" +msgstr "Bestätigungsfrage vor Starten anzeigen" + +#: lib/tools_dlg.tcl:80 +msgid "Ask the user to select a revision (sets $REVISION)" +msgstr "Benutzer nach Version fragen (setzt $REVISION)" + +#: lib/tools_dlg.tcl:85 +msgid "Ask the user for additional arguments (sets $ARGS)" +msgstr "Benutzer nach zusätzlichen Argumenten fragen (setzt $ARGS)" + +#: lib/tools_dlg.tcl:92 +msgid "Don't show the command output window" +msgstr "Kein Ausgabefenster zeigen" + +#: lib/tools_dlg.tcl:97 +msgid "Run only if a diff is selected ($FILENAME not empty)" +msgstr "Nur starten, wenn ein Vergleich gewählt ist ($FILENAME ist nicht leer)" + +#: lib/tools_dlg.tcl:121 +msgid "Please supply a name for the tool." +msgstr "Bitte geben Sie einen Werkzeugnamen an." + +#: lib/tools_dlg.tcl:129 +#, tcl-format +msgid "Tool '%s' already exists." +msgstr "Werkzeug »%s« existiert bereits." + +#: lib/tools_dlg.tcl:151 +#, tcl-format +msgid "" +"Could not add tool:\n" +"%s" +msgstr "" +"Werkzeug konnte nicht hinzugefügt werden:\n" +"\n" +"%s" + +#: lib/tools_dlg.tcl:190 +msgid "Remove Tool" +msgstr "Werkzeug entfernen" + +#: lib/tools_dlg.tcl:196 +msgid "Remove Tool Commands" +msgstr "Werkzeugkommandos entfernen" + +#: lib/tools_dlg.tcl:200 +msgid "Remove" +msgstr "Entfernen" + +#: lib/tools_dlg.tcl:236 +msgid "(Blue denotes repository-local tools)" +msgstr "(Werkzeuge für lokales Archiv werden in Blau angezeigt)" + +#: lib/tools_dlg.tcl:297 +#, tcl-format +msgid "Run Command: %s" +msgstr "Kommando aufrufen: %s" + +#: lib/tools_dlg.tcl:311 +msgid "Arguments" +msgstr "Argumente" + +#: lib/tools_dlg.tcl:348 +msgid "OK" +msgstr "Ok" + +#: lib/tools.tcl:75 +#, tcl-format +msgid "Running %s requires a selected file." +msgstr "Um »%s« zu starten, muss eine Datei ausgewählt sein." + +#: lib/tools.tcl:90 +#, tcl-format +msgid "Are you sure you want to run %s?" +msgstr "Wollen Sie %s wirklich starten?" + +#: lib/tools.tcl:110 +#, tcl-format +msgid "Tool: %s" +msgstr "Werkzeug: %s" + +#: lib/tools.tcl:111 +#, tcl-format +msgid "Running: %s" +msgstr "Starten: %s" + +#: lib/tools.tcl:149 +#, tcl-format +msgid "Tool completed succesfully: %s" +msgstr "Werkzeug erfolgreich abgeschlossen: %s" + +#: lib/tools.tcl:151 +#, tcl-format +msgid "Tool failed: %s" +msgstr "Werkzeug fehlgeschlagen: %s" + #: lib/transport.tcl:7 #, tcl-format msgid "Fetching new changes from %s" @@ -2340,7 +2534,12 @@ msgstr "Übernahmezweige aufräumen und entfernen, die in »%s« gelöscht wurde msgid "Pushing changes to %s" msgstr "Änderungen nach »%s« versenden" -#: lib/transport.tcl:72 +#: lib/transport.tcl:64 +#, tcl-format +msgid "Mirroring to %s" +msgstr "Spiegeln nach %s" + +#: lib/transport.tcl:82 #, tcl-format msgid "Pushing %s %s to %s" msgstr "%s %s nach %s versenden" diff --git a/git-gui/po/git-gui.pot b/git-gui/po/git-gui.pot index 58db67c217..15aea0dc64 100644 --- a/git-gui/po/git-gui.pot +++ b/git-gui/po/git-gui.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-11-16 13:56-0800\n" +"POT-Creation-Date: 2008-12-08 08:31-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -234,25 +234,25 @@ msgstr "" msgid "Redo" msgstr "" -#: git-gui.sh:2378 git-gui.sh:2923 +#: git-gui.sh:2378 git-gui.sh:2937 msgid "Cut" msgstr "" -#: git-gui.sh:2381 git-gui.sh:2926 git-gui.sh:3000 git-gui.sh:3082 +#: git-gui.sh:2381 git-gui.sh:2940 git-gui.sh:3014 git-gui.sh:3096 #: lib/console.tcl:69 msgid "Copy" msgstr "" -#: git-gui.sh:2384 git-gui.sh:2929 +#: git-gui.sh:2384 git-gui.sh:2943 msgid "Paste" msgstr "" -#: git-gui.sh:2387 git-gui.sh:2932 lib/branch_delete.tcl:26 +#: git-gui.sh:2387 git-gui.sh:2946 lib/branch_delete.tcl:26 #: lib/remote_branch_delete.tcl:38 msgid "Delete" msgstr "" -#: git-gui.sh:2391 git-gui.sh:2936 git-gui.sh:3086 lib/console.tcl:71 +#: git-gui.sh:2391 git-gui.sh:2950 git-gui.sh:3100 lib/console.tcl:71 msgid "Select All" msgstr "" @@ -284,15 +284,15 @@ msgstr "" msgid "Commit@@verb" msgstr "" -#: git-gui.sh:2443 git-gui.sh:2864 +#: git-gui.sh:2443 git-gui.sh:2878 msgid "New Commit" msgstr "" -#: git-gui.sh:2451 git-gui.sh:2871 +#: git-gui.sh:2451 git-gui.sh:2885 msgid "Amend Last Commit" msgstr "" -#: git-gui.sh:2461 git-gui.sh:2825 lib/remote_branch_delete.tcl:99 +#: git-gui.sh:2461 git-gui.sh:2839 lib/remote_branch_delete.tcl:99 msgid "Rescan" msgstr "" @@ -312,15 +312,15 @@ msgstr "" msgid "Revert Changes" msgstr "" -#: git-gui.sh:2491 git-gui.sh:3069 +#: git-gui.sh:2491 git-gui.sh:3083 msgid "Show Less Context" msgstr "" -#: git-gui.sh:2495 git-gui.sh:3073 +#: git-gui.sh:2495 git-gui.sh:3087 msgid "Show More Context" msgstr "" -#: git-gui.sh:2502 git-gui.sh:2838 git-gui.sh:2947 +#: git-gui.sh:2502 git-gui.sh:2852 git-gui.sh:2961 msgid "Sign Off" msgstr "" @@ -354,7 +354,7 @@ msgstr "" msgid "Preferences..." msgstr "" -#: git-gui.sh:2565 git-gui.sh:3115 +#: git-gui.sh:2565 git-gui.sh:3129 msgid "Options..." msgstr "" @@ -374,124 +374,124 @@ msgstr "" msgid "Show SSH Key" msgstr "" -#: git-gui.sh:2707 +#: git-gui.sh:2721 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" msgstr "" -#: git-gui.sh:2740 +#: git-gui.sh:2754 msgid "Current Branch:" msgstr "" -#: git-gui.sh:2761 +#: git-gui.sh:2775 msgid "Staged Changes (Will Commit)" msgstr "" -#: git-gui.sh:2781 +#: git-gui.sh:2795 msgid "Unstaged Changes" msgstr "" -#: git-gui.sh:2831 +#: git-gui.sh:2845 msgid "Stage Changed" msgstr "" -#: git-gui.sh:2850 lib/transport.tcl:93 lib/transport.tcl:182 +#: git-gui.sh:2864 lib/transport.tcl:104 lib/transport.tcl:193 msgid "Push" msgstr "" -#: git-gui.sh:2885 +#: git-gui.sh:2899 msgid "Initial Commit Message:" msgstr "" -#: git-gui.sh:2886 +#: git-gui.sh:2900 msgid "Amended Commit Message:" msgstr "" -#: git-gui.sh:2887 +#: git-gui.sh:2901 msgid "Amended Initial Commit Message:" msgstr "" -#: git-gui.sh:2888 +#: git-gui.sh:2902 msgid "Amended Merge Commit Message:" msgstr "" -#: git-gui.sh:2889 +#: git-gui.sh:2903 msgid "Merge Commit Message:" msgstr "" -#: git-gui.sh:2890 +#: git-gui.sh:2904 msgid "Commit Message:" msgstr "" -#: git-gui.sh:2939 git-gui.sh:3090 lib/console.tcl:73 +#: git-gui.sh:2953 git-gui.sh:3104 lib/console.tcl:73 msgid "Copy All" msgstr "" -#: git-gui.sh:2963 lib/blame.tcl:104 +#: git-gui.sh:2977 lib/blame.tcl:104 msgid "File:" msgstr "" -#: git-gui.sh:3078 +#: git-gui.sh:3092 msgid "Refresh" msgstr "" -#: git-gui.sh:3099 +#: git-gui.sh:3113 msgid "Decrease Font Size" msgstr "" -#: git-gui.sh:3103 +#: git-gui.sh:3117 msgid "Increase Font Size" msgstr "" -#: git-gui.sh:3111 lib/blame.tcl:281 +#: git-gui.sh:3125 lib/blame.tcl:281 msgid "Encoding" msgstr "" -#: git-gui.sh:3122 +#: git-gui.sh:3136 msgid "Apply/Reverse Hunk" msgstr "" -#: git-gui.sh:3127 +#: git-gui.sh:3141 msgid "Apply/Reverse Line" msgstr "" -#: git-gui.sh:3137 +#: git-gui.sh:3151 msgid "Run Merge Tool" msgstr "" -#: git-gui.sh:3142 +#: git-gui.sh:3156 msgid "Use Remote Version" msgstr "" -#: git-gui.sh:3146 +#: git-gui.sh:3160 msgid "Use Local Version" msgstr "" -#: git-gui.sh:3150 +#: git-gui.sh:3164 msgid "Revert To Base" msgstr "" -#: git-gui.sh:3169 +#: git-gui.sh:3183 msgid "Unstage Hunk From Commit" msgstr "" -#: git-gui.sh:3170 +#: git-gui.sh:3184 msgid "Unstage Line From Commit" msgstr "" -#: git-gui.sh:3172 +#: git-gui.sh:3186 msgid "Stage Hunk For Commit" msgstr "" -#: git-gui.sh:3173 +#: git-gui.sh:3187 msgid "Stage Line For Commit" msgstr "" -#: git-gui.sh:3196 +#: git-gui.sh:3210 msgid "Initializing..." msgstr "" -#: git-gui.sh:3301 +#: git-gui.sh:3315 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -502,14 +502,14 @@ msgid "" "\n" msgstr "" -#: git-gui.sh:3331 +#: git-gui.sh:3345 msgid "" "\n" "This is due to a known issue with the\n" "Tcl binary distributed by Cygwin." msgstr "" -#: git-gui.sh:3336 +#: git-gui.sh:3350 #, tcl-format msgid "" "\n" @@ -589,43 +589,43 @@ msgstr "" msgid "Loading annotation..." msgstr "" -#: lib/blame.tcl:964 +#: lib/blame.tcl:963 msgid "Author:" msgstr "" -#: lib/blame.tcl:968 +#: lib/blame.tcl:967 msgid "Committer:" msgstr "" -#: lib/blame.tcl:973 +#: lib/blame.tcl:972 msgid "Original File:" msgstr "" -#: lib/blame.tcl:1021 +#: lib/blame.tcl:1020 msgid "Cannot find HEAD commit:" msgstr "" -#: lib/blame.tcl:1076 +#: lib/blame.tcl:1075 msgid "Cannot find parent commit:" msgstr "" -#: lib/blame.tcl:1091 +#: lib/blame.tcl:1090 msgid "Unable to display parent" msgstr "" -#: lib/blame.tcl:1092 lib/diff.tcl:297 +#: lib/blame.tcl:1091 lib/diff.tcl:297 msgid "Error loading diff:" msgstr "" -#: lib/blame.tcl:1232 +#: lib/blame.tcl:1231 msgid "Originally By:" msgstr "" -#: lib/blame.tcl:1238 +#: lib/blame.tcl:1237 msgid "In File:" msgstr "" -#: lib/blame.tcl:1243 +#: lib/blame.tcl:1242 msgid "Copied Or Moved Here By:" msgstr "" @@ -642,7 +642,7 @@ msgstr "" #: lib/checkout_op.tcl:544 lib/choose_font.tcl:43 lib/merge.tcl:172 #: lib/option.tcl:125 lib/remote_add.tcl:32 lib/remote_branch_delete.tcl:42 #: lib/tools_dlg.tcl:40 lib/tools_dlg.tcl:204 lib/tools_dlg.tcl:352 -#: lib/transport.tcl:97 +#: lib/transport.tcl:108 msgid "Cancel" msgstr "" @@ -1254,19 +1254,19 @@ msgid "" "current merge activity.\n" msgstr "" -#: lib/commit.tcl:49 +#: lib/commit.tcl:48 msgid "Error loading commit data for amend:" msgstr "" -#: lib/commit.tcl:76 +#: lib/commit.tcl:75 msgid "Unable to obtain your identity:" msgstr "" -#: lib/commit.tcl:81 +#: lib/commit.tcl:80 msgid "Invalid GIT_COMMITTER_IDENT:" msgstr "" -#: lib/commit.tcl:133 +#: lib/commit.tcl:132 msgid "" "Last scanned state does not match repository state.\n" "\n" @@ -1276,7 +1276,7 @@ msgid "" "The rescan will be automatically started now.\n" msgstr "" -#: lib/commit.tcl:156 +#: lib/commit.tcl:155 #, tcl-format msgid "" "Unmerged files cannot be committed.\n" @@ -1285,7 +1285,7 @@ msgid "" "before committing.\n" msgstr "" -#: lib/commit.tcl:164 +#: lib/commit.tcl:163 #, tcl-format msgid "" "Unknown file state %s detected.\n" @@ -1293,14 +1293,14 @@ msgid "" "File %s cannot be committed by this program.\n" msgstr "" -#: lib/commit.tcl:172 +#: lib/commit.tcl:171 msgid "" "No changes to commit.\n" "\n" "You must stage at least 1 file before you can commit.\n" msgstr "" -#: lib/commit.tcl:187 +#: lib/commit.tcl:186 msgid "" "Please supply a commit message.\n" "\n" @@ -1311,45 +1311,45 @@ msgid "" "- Remaining lines: Describe why this change is good.\n" msgstr "" -#: lib/commit.tcl:211 +#: lib/commit.tcl:210 #, tcl-format msgid "warning: Tcl does not support encoding '%s'." msgstr "" -#: lib/commit.tcl:227 +#: lib/commit.tcl:226 msgid "Calling pre-commit hook..." msgstr "" -#: lib/commit.tcl:242 +#: lib/commit.tcl:241 msgid "Commit declined by pre-commit hook." msgstr "" -#: lib/commit.tcl:265 +#: lib/commit.tcl:264 msgid "Calling commit-msg hook..." msgstr "" -#: lib/commit.tcl:280 +#: lib/commit.tcl:279 msgid "Commit declined by commit-msg hook." msgstr "" -#: lib/commit.tcl:293 +#: lib/commit.tcl:292 msgid "Committing changes..." msgstr "" -#: lib/commit.tcl:309 +#: lib/commit.tcl:308 msgid "write-tree failed:" msgstr "" -#: lib/commit.tcl:310 lib/commit.tcl:354 lib/commit.tcl:374 +#: lib/commit.tcl:309 lib/commit.tcl:353 lib/commit.tcl:373 msgid "Commit failed." msgstr "" -#: lib/commit.tcl:327 +#: lib/commit.tcl:326 #, tcl-format msgid "Commit %s appears to be corrupt" msgstr "" -#: lib/commit.tcl:332 +#: lib/commit.tcl:331 msgid "" "No changes to commit.\n" "\n" @@ -1358,19 +1358,19 @@ msgid "" "A rescan will be automatically started now.\n" msgstr "" -#: lib/commit.tcl:339 +#: lib/commit.tcl:338 msgid "No changes to commit." msgstr "" -#: lib/commit.tcl:353 +#: lib/commit.tcl:352 msgid "commit-tree failed:" msgstr "" -#: lib/commit.tcl:373 +#: lib/commit.tcl:372 msgid "update-ref failed:" msgstr "" -#: lib/commit.tcl:461 +#: lib/commit.tcl:460 #, tcl-format msgid "Created commit %s: %s" msgstr "" @@ -1999,7 +1999,8 @@ msgstr "" msgid "Do not know how to initialize repository at location '%s'." msgstr "" -#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:71 +#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:63 +#: lib/transport.tcl:81 #, tcl-format msgid "push %s" msgstr "" @@ -2017,11 +2018,11 @@ msgstr "" msgid "From Repository" msgstr "" -#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123 +#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:134 msgid "Remote:" msgstr "" -#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138 +#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:149 msgid "Arbitrary Location:" msgstr "" @@ -2336,35 +2337,40 @@ msgstr "" msgid "Pushing changes to %s" msgstr "" -#: lib/transport.tcl:72 +#: lib/transport.tcl:64 +#, tcl-format +msgid "Mirroring to %s" +msgstr "" + +#: lib/transport.tcl:82 #, tcl-format msgid "Pushing %s %s to %s" msgstr "" -#: lib/transport.tcl:89 +#: lib/transport.tcl:100 msgid "Push Branches" msgstr "" -#: lib/transport.tcl:103 +#: lib/transport.tcl:114 msgid "Source Branches" msgstr "" -#: lib/transport.tcl:120 +#: lib/transport.tcl:131 msgid "Destination Repository" msgstr "" -#: lib/transport.tcl:158 +#: lib/transport.tcl:169 msgid "Transfer Options" msgstr "" -#: lib/transport.tcl:160 +#: lib/transport.tcl:171 msgid "Force overwrite existing branch (may discard changes)" msgstr "" -#: lib/transport.tcl:164 +#: lib/transport.tcl:175 msgid "Use thin pack (for slow network connections)" msgstr "" -#: lib/transport.tcl:168 +#: lib/transport.tcl:179 msgid "Include tags" msgstr "" diff --git a/git-gui/po/hu.po b/git-gui/po/hu.po index 8ec43392d4..f761b64152 100644 --- a/git-gui/po/hu.po +++ b/git-gui/po/hu.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: git-gui-i 18n\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-11-16 13:56-0800\n" -"PO-Revision-Date: 2008-11-17 23:03+0100\n" +"POT-Creation-Date: 2008-12-08 08:31-0800\n" +"PO-Revision-Date: 2008-12-10 15:00+0100\n" "Last-Translator: Miklos Vajna <vmiklos@frugalware.org>\n" "Language-Team: Hungarian\n" "MIME-Version: 1.0\n" @@ -241,25 +241,25 @@ msgstr "Visszavonás" msgid "Redo" msgstr "Mégis" -#: git-gui.sh:2378 git-gui.sh:2923 +#: git-gui.sh:2378 git-gui.sh:2937 msgid "Cut" msgstr "Kivágás" -#: git-gui.sh:2381 git-gui.sh:2926 git-gui.sh:3000 git-gui.sh:3082 +#: git-gui.sh:2381 git-gui.sh:2940 git-gui.sh:3014 git-gui.sh:3096 #: lib/console.tcl:69 msgid "Copy" msgstr "Másolás" -#: git-gui.sh:2384 git-gui.sh:2929 +#: git-gui.sh:2384 git-gui.sh:2943 msgid "Paste" msgstr "Beillesztés" -#: git-gui.sh:2387 git-gui.sh:2932 lib/branch_delete.tcl:26 +#: git-gui.sh:2387 git-gui.sh:2946 lib/branch_delete.tcl:26 #: lib/remote_branch_delete.tcl:38 msgid "Delete" msgstr "Törlés" -#: git-gui.sh:2391 git-gui.sh:2936 git-gui.sh:3086 lib/console.tcl:71 +#: git-gui.sh:2391 git-gui.sh:2950 git-gui.sh:3100 lib/console.tcl:71 msgid "Select All" msgstr "Mindent kiválaszt" @@ -291,15 +291,15 @@ msgstr "Kész" msgid "Commit@@verb" msgstr "Commit@@ige" -#: git-gui.sh:2443 git-gui.sh:2864 +#: git-gui.sh:2443 git-gui.sh:2878 msgid "New Commit" msgstr "Új commit" -#: git-gui.sh:2451 git-gui.sh:2871 +#: git-gui.sh:2451 git-gui.sh:2885 msgid "Amend Last Commit" msgstr "Utolsó commit javítása" -#: git-gui.sh:2461 git-gui.sh:2825 lib/remote_branch_delete.tcl:99 +#: git-gui.sh:2461 git-gui.sh:2839 lib/remote_branch_delete.tcl:99 msgid "Rescan" msgstr "Keresés újra" @@ -319,15 +319,15 @@ msgstr "Commitba való kiválasztás visszavonása" msgid "Revert Changes" msgstr "Változtatások visszaállítása" -#: git-gui.sh:2491 git-gui.sh:3069 +#: git-gui.sh:2491 git-gui.sh:3083 msgid "Show Less Context" msgstr "Kevesebb környezet mutatása" -#: git-gui.sh:2495 git-gui.sh:3073 +#: git-gui.sh:2495 git-gui.sh:3087 msgid "Show More Context" msgstr "Több környezet mutatása" -#: git-gui.sh:2502 git-gui.sh:2838 git-gui.sh:2947 +#: git-gui.sh:2502 git-gui.sh:2852 git-gui.sh:2961 msgid "Sign Off" msgstr "Aláír" @@ -361,7 +361,7 @@ msgstr "Névjegy: %s" msgid "Preferences..." msgstr "Beállítások..." -#: git-gui.sh:2565 git-gui.sh:3115 +#: git-gui.sh:2565 git-gui.sh:3129 msgid "Options..." msgstr "Opciók..." @@ -381,125 +381,125 @@ msgstr "Online dokumentáció" msgid "Show SSH Key" msgstr "SSH kulcs mutatása" -#: git-gui.sh:2707 +#: git-gui.sh:2721 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" msgstr "" "végzetes hiba: nem érhető el a(z) %s útvonal: Nincs ilyen fájl vagy könyvtár" -#: git-gui.sh:2740 +#: git-gui.sh:2754 msgid "Current Branch:" msgstr "Jelenlegi branch:" -#: git-gui.sh:2761 +#: git-gui.sh:2775 msgid "Staged Changes (Will Commit)" msgstr "Kiválasztott változtatások (commitolva lesz)" -#: git-gui.sh:2781 +#: git-gui.sh:2795 msgid "Unstaged Changes" msgstr "Kiválasztatlan változtatások" -#: git-gui.sh:2831 +#: git-gui.sh:2845 msgid "Stage Changed" msgstr "Változtatások kiválasztása" -#: git-gui.sh:2850 lib/transport.tcl:93 lib/transport.tcl:182 +#: git-gui.sh:2864 lib/transport.tcl:104 lib/transport.tcl:193 msgid "Push" msgstr "Push" -#: git-gui.sh:2885 +#: git-gui.sh:2899 msgid "Initial Commit Message:" msgstr "Kezdeti commit üzenet:" -#: git-gui.sh:2886 +#: git-gui.sh:2900 msgid "Amended Commit Message:" msgstr "Javító commit üzenet:" -#: git-gui.sh:2887 +#: git-gui.sh:2901 msgid "Amended Initial Commit Message:" msgstr "Kezdeti javító commit üzenet:" -#: git-gui.sh:2888 +#: git-gui.sh:2902 msgid "Amended Merge Commit Message:" msgstr "Javító merge commit üzenet:" -#: git-gui.sh:2889 +#: git-gui.sh:2903 msgid "Merge Commit Message:" msgstr "Merge commit üzenet:" -#: git-gui.sh:2890 +#: git-gui.sh:2904 msgid "Commit Message:" msgstr "Commit üzenet:" -#: git-gui.sh:2939 git-gui.sh:3090 lib/console.tcl:73 +#: git-gui.sh:2953 git-gui.sh:3104 lib/console.tcl:73 msgid "Copy All" msgstr "Összes másolása" -#: git-gui.sh:2963 lib/blame.tcl:104 +#: git-gui.sh:2977 lib/blame.tcl:104 msgid "File:" msgstr "Fájl:" -#: git-gui.sh:3078 +#: git-gui.sh:3092 msgid "Refresh" msgstr "Frissítés" -#: git-gui.sh:3099 +#: git-gui.sh:3113 msgid "Decrease Font Size" msgstr "Font méret csökkentése" -#: git-gui.sh:3103 +#: git-gui.sh:3117 msgid "Increase Font Size" msgstr "Fönt méret növelése" -#: git-gui.sh:3111 lib/blame.tcl:281 +#: git-gui.sh:3125 lib/blame.tcl:281 msgid "Encoding" msgstr "Kódolás" -#: git-gui.sh:3122 +#: git-gui.sh:3136 msgid "Apply/Reverse Hunk" msgstr "Hunk alkalmazása/visszaállítása" -#: git-gui.sh:3127 +#: git-gui.sh:3141 msgid "Apply/Reverse Line" msgstr "Sor alkalmazása/visszaállítása" -#: git-gui.sh:3137 +#: git-gui.sh:3151 msgid "Run Merge Tool" msgstr "Merge eszköz futtatása" -#: git-gui.sh:3142 +#: git-gui.sh:3156 msgid "Use Remote Version" msgstr "Távoli verzió használata" -#: git-gui.sh:3146 +#: git-gui.sh:3160 msgid "Use Local Version" msgstr "Helyi verzió használata" -#: git-gui.sh:3150 +#: git-gui.sh:3164 msgid "Revert To Base" msgstr "Visszaállítás az alaphoz" -#: git-gui.sh:3169 +#: git-gui.sh:3183 msgid "Unstage Hunk From Commit" msgstr "Hunk törlése commitból" -#: git-gui.sh:3170 +#: git-gui.sh:3184 msgid "Unstage Line From Commit" msgstr "A sor kiválasztásának törlése" -#: git-gui.sh:3172 +#: git-gui.sh:3186 msgid "Stage Hunk For Commit" msgstr "Hunk kiválasztása commitba" -#: git-gui.sh:3173 +#: git-gui.sh:3187 msgid "Stage Line For Commit" msgstr "Sor kiválasztása commitba" -#: git-gui.sh:3196 +#: git-gui.sh:3210 msgid "Initializing..." msgstr "Inicializálás..." -#: git-gui.sh:3301 +#: git-gui.sh:3315 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -516,7 +516,7 @@ msgstr "" "indított folyamatok által:\n" "\n" -#: git-gui.sh:3331 +#: git-gui.sh:3345 msgid "" "\n" "This is due to a known issue with the\n" @@ -526,7 +526,7 @@ msgstr "" "Ez a Cygwin által terjesztett Tcl binárisban\n" "lévő ismert hiba miatt van." -#: git-gui.sh:3336 +#: git-gui.sh:3350 #, tcl-format msgid "" "\n" @@ -612,43 +612,43 @@ msgstr "Futtatás másolás-érzékelésen keresztül..." msgid "Loading annotation..." msgstr "Az annotáció betöltése..." -#: lib/blame.tcl:964 +#: lib/blame.tcl:963 msgid "Author:" msgstr "Szerző:" -#: lib/blame.tcl:968 +#: lib/blame.tcl:967 msgid "Committer:" msgstr "Commiter:" -#: lib/blame.tcl:973 +#: lib/blame.tcl:972 msgid "Original File:" msgstr "Eredeti fájl:" -#: lib/blame.tcl:1021 +#: lib/blame.tcl:1020 msgid "Cannot find HEAD commit:" msgstr "Nem található a HEAD commit:" -#: lib/blame.tcl:1076 +#: lib/blame.tcl:1075 msgid "Cannot find parent commit:" msgstr "Nem található a szülő commit:" -#: lib/blame.tcl:1091 +#: lib/blame.tcl:1090 msgid "Unable to display parent" msgstr "Nem lehet megjeleníteni a szülőt" -#: lib/blame.tcl:1092 lib/diff.tcl:297 +#: lib/blame.tcl:1091 lib/diff.tcl:297 msgid "Error loading diff:" msgstr "Hiba a diff betöltése közben:" -#: lib/blame.tcl:1232 +#: lib/blame.tcl:1231 msgid "Originally By:" msgstr "Eredeti szerző:" -#: lib/blame.tcl:1238 +#: lib/blame.tcl:1237 msgid "In File:" msgstr "Ebben a fájlban:" -#: lib/blame.tcl:1243 +#: lib/blame.tcl:1242 msgid "Copied Or Moved Here By:" msgstr "Ide másolta vagy helyezte:" @@ -665,7 +665,7 @@ msgstr "Checkout" #: lib/checkout_op.tcl:544 lib/choose_font.tcl:43 lib/merge.tcl:172 #: lib/option.tcl:125 lib/remote_add.tcl:32 lib/remote_branch_delete.tcl:42 #: lib/tools_dlg.tcl:40 lib/tools_dlg.tcl:204 lib/tools_dlg.tcl:352 -#: lib/transport.tcl:97 +#: lib/transport.tcl:108 msgid "Cancel" msgstr "Mégsem" @@ -1317,19 +1317,19 @@ msgstr "" "A jelenlegi merge még nem teljesen fejeződött be. Csak akkor javíthat egy " "előbbi commitot, hogyha megszakítja a jelenlegi merge folyamatot.\n" -#: lib/commit.tcl:49 +#: lib/commit.tcl:48 msgid "Error loading commit data for amend:" msgstr "Hiba a javítandó commit adat betöltése közben:" -#: lib/commit.tcl:76 +#: lib/commit.tcl:75 msgid "Unable to obtain your identity:" msgstr "Nem sikerült megállapítani az azonosítót:" -#: lib/commit.tcl:81 +#: lib/commit.tcl:80 msgid "Invalid GIT_COMMITTER_IDENT:" msgstr "Érvénytelen GIT_COMMITTER_IDENT:" -#: lib/commit.tcl:133 +#: lib/commit.tcl:132 msgid "" "Last scanned state does not match repository state.\n" "\n" @@ -1346,7 +1346,7 @@ msgstr "" "\n" "Az újrakeresés most automatikusan el fog indulni.\n" -#: lib/commit.tcl:156 +#: lib/commit.tcl:155 #, tcl-format msgid "" "Unmerged files cannot be committed.\n" @@ -1359,7 +1359,7 @@ msgstr "" "A(z) %s fájlban ütközések vannak. Egyszer azokat ki kell javítani, majd " "hozzá ki kell választani a fájlt mielőtt commitolni lehetne.\n" -#: lib/commit.tcl:164 +#: lib/commit.tcl:163 #, tcl-format msgid "" "Unknown file state %s detected.\n" @@ -1370,7 +1370,7 @@ msgstr "" "\n" "A(z) %s fájlt nem tudja ez a program commitolni.\n" -#: lib/commit.tcl:172 +#: lib/commit.tcl:171 msgid "" "No changes to commit.\n" "\n" @@ -1380,7 +1380,7 @@ msgstr "" "\n" "Legalább egy fájl ki kell választani, hogy commitolni lehessen.\n" -#: lib/commit.tcl:187 +#: lib/commit.tcl:186 msgid "" "Please supply a commit message.\n" "\n" @@ -1398,45 +1398,45 @@ msgstr "" "- Második sor: Üres\n" "- A többi sor: Leírja, hogy miért jó ez a változtatás.\n" -#: lib/commit.tcl:211 +#: lib/commit.tcl:210 #, tcl-format msgid "warning: Tcl does not support encoding '%s'." msgstr "figyelmeztetés: a Tcl nem támogatja a(z) '%s' kódolást." -#: lib/commit.tcl:227 +#: lib/commit.tcl:226 msgid "Calling pre-commit hook..." msgstr "A pre-commit hurok meghívása..." -#: lib/commit.tcl:242 +#: lib/commit.tcl:241 msgid "Commit declined by pre-commit hook." msgstr "A commitot megakadályozta a pre-commit hurok. " -#: lib/commit.tcl:265 +#: lib/commit.tcl:264 msgid "Calling commit-msg hook..." msgstr "A commit-msg hurok meghívása..." -#: lib/commit.tcl:280 +#: lib/commit.tcl:279 msgid "Commit declined by commit-msg hook." msgstr "A commiot megakadályozta a commit-msg hurok." -#: lib/commit.tcl:293 +#: lib/commit.tcl:292 msgid "Committing changes..." msgstr "A változtatások commitolása..." -#: lib/commit.tcl:309 +#: lib/commit.tcl:308 msgid "write-tree failed:" msgstr "a write-tree sikertelen:" -#: lib/commit.tcl:310 lib/commit.tcl:354 lib/commit.tcl:374 +#: lib/commit.tcl:309 lib/commit.tcl:353 lib/commit.tcl:373 msgid "Commit failed." msgstr "A commit nem sikerült." -#: lib/commit.tcl:327 +#: lib/commit.tcl:326 #, tcl-format msgid "Commit %s appears to be corrupt" msgstr "A(z) %s commit sérültnek tűnik" -#: lib/commit.tcl:332 +#: lib/commit.tcl:331 msgid "" "No changes to commit.\n" "\n" @@ -1450,19 +1450,19 @@ msgstr "" "\n" "Az újrakeresés most automatikusan el fog indulni.\n" -#: lib/commit.tcl:339 +#: lib/commit.tcl:338 msgid "No changes to commit." msgstr "Nincs commitolandó változtatás." -#: lib/commit.tcl:353 +#: lib/commit.tcl:352 msgid "commit-tree failed:" msgstr "a commit-tree sikertelen:" -#: lib/commit.tcl:373 +#: lib/commit.tcl:372 msgid "update-ref failed:" msgstr "az update-ref sikertelen:" -#: lib/commit.tcl:461 +#: lib/commit.tcl:460 #, tcl-format msgid "Created commit %s: %s" msgstr "Létrejött a %s commit: %s" @@ -2168,7 +2168,8 @@ msgstr "A(z) %s letöltése" msgid "Do not know how to initialize repository at location '%s'." msgstr "Nem tudni, hogy hogy kell a(z) '%s' helyen repót inicializálni." -#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:71 +#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:63 +#: lib/transport.tcl:81 #, tcl-format msgid "push %s" msgstr "%s push-olása" @@ -2186,11 +2187,11 @@ msgstr "Távoli Branch törlése" msgid "From Repository" msgstr "Forrás repó" -#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123 +#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:134 msgid "Remote:" msgstr "Távoli:" -#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138 +#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:149 msgid "Arbitrary Location:" msgstr "Önkényes hely:" @@ -2519,38 +2520,43 @@ msgstr "A %s repóból törölt követő branchek törlése" msgid "Pushing changes to %s" msgstr "Változások pusholása ide: %s" -#: lib/transport.tcl:72 +#: lib/transport.tcl:64 +#, tcl-format +msgid "Mirroring to %s" +msgstr "Tükrözés a következő helyre: %s" + +#: lib/transport.tcl:82 #, tcl-format msgid "Pushing %s %s to %s" msgstr "Pusholás: %s %s, ide: %s" -#: lib/transport.tcl:89 +#: lib/transport.tcl:100 msgid "Push Branches" msgstr "Branchek pusholása" -#: lib/transport.tcl:103 +#: lib/transport.tcl:114 msgid "Source Branches" msgstr "Forrás branchek" -#: lib/transport.tcl:120 +#: lib/transport.tcl:131 msgid "Destination Repository" msgstr "Cél repó" -#: lib/transport.tcl:158 +#: lib/transport.tcl:169 msgid "Transfer Options" msgstr "Átviteli opciók" -#: lib/transport.tcl:160 +#: lib/transport.tcl:171 msgid "Force overwrite existing branch (may discard changes)" msgstr "" "Létező branch felülírásának erőltetése (lehet, hogy el fog dobni " "változtatásokat)" -#: lib/transport.tcl:164 +#: lib/transport.tcl:175 msgid "Use thin pack (for slow network connections)" msgstr "Vékony csomagok használata (lassú hálózati kapcsolatok számára)" -#: lib/transport.tcl:168 +#: lib/transport.tcl:179 msgid "Include tags" msgstr "Tageket is" diff --git a/git-gui/po/it.po b/git-gui/po/it.po index 2ee30844f8..294e595887 100644 --- a/git-gui/po/it.po +++ b/git-gui/po/it.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: git-gui\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-11-16 13:56-0800\n" -"PO-Revision-Date: 2008-11-17 16:04+0100\n" +"POT-Creation-Date: 2008-12-08 08:31-0800\n" +"PO-Revision-Date: 2008-12-09 13:04+0100\n" "Last-Translator: Michele Ballabio <barra_cuda@katamail.com>\n" "Language-Team: Italian <tp@lists.linux.it>\n" "MIME-Version: 1.0\n" @@ -242,25 +242,25 @@ msgstr "Annulla" msgid "Redo" msgstr "Ripeti" -#: git-gui.sh:2378 git-gui.sh:2923 +#: git-gui.sh:2378 git-gui.sh:2937 msgid "Cut" msgstr "Taglia" -#: git-gui.sh:2381 git-gui.sh:2926 git-gui.sh:3000 git-gui.sh:3082 +#: git-gui.sh:2381 git-gui.sh:2940 git-gui.sh:3014 git-gui.sh:3096 #: lib/console.tcl:69 msgid "Copy" msgstr "Copia" -#: git-gui.sh:2384 git-gui.sh:2929 +#: git-gui.sh:2384 git-gui.sh:2943 msgid "Paste" msgstr "Incolla" -#: git-gui.sh:2387 git-gui.sh:2932 lib/branch_delete.tcl:26 +#: git-gui.sh:2387 git-gui.sh:2946 lib/branch_delete.tcl:26 #: lib/remote_branch_delete.tcl:38 msgid "Delete" msgstr "Elimina" -#: git-gui.sh:2391 git-gui.sh:2936 git-gui.sh:3086 lib/console.tcl:71 +#: git-gui.sh:2391 git-gui.sh:2950 git-gui.sh:3100 lib/console.tcl:71 msgid "Select All" msgstr "Seleziona tutto" @@ -292,15 +292,15 @@ msgstr "Fatto" msgid "Commit@@verb" msgstr "Nuova revisione" -#: git-gui.sh:2443 git-gui.sh:2864 +#: git-gui.sh:2443 git-gui.sh:2878 msgid "New Commit" msgstr "Nuova revisione" -#: git-gui.sh:2451 git-gui.sh:2871 +#: git-gui.sh:2451 git-gui.sh:2885 msgid "Amend Last Commit" msgstr "Correggi l'ultima revisione" -#: git-gui.sh:2461 git-gui.sh:2825 lib/remote_branch_delete.tcl:99 +#: git-gui.sh:2461 git-gui.sh:2839 lib/remote_branch_delete.tcl:99 msgid "Rescan" msgstr "Analizza nuovamente" @@ -320,15 +320,15 @@ msgstr "Annulla preparazione" msgid "Revert Changes" msgstr "Annulla modifiche" -#: git-gui.sh:2491 git-gui.sh:3069 +#: git-gui.sh:2491 git-gui.sh:3083 msgid "Show Less Context" msgstr "Mostra meno contesto" -#: git-gui.sh:2495 git-gui.sh:3073 +#: git-gui.sh:2495 git-gui.sh:3087 msgid "Show More Context" msgstr "Mostra più contesto" -#: git-gui.sh:2502 git-gui.sh:2838 git-gui.sh:2947 +#: git-gui.sh:2502 git-gui.sh:2852 git-gui.sh:2961 msgid "Sign Off" msgstr "Sign Off" @@ -362,7 +362,7 @@ msgstr "Informazioni su %s" msgid "Preferences..." msgstr "Preferenze..." -#: git-gui.sh:2565 git-gui.sh:3115 +#: git-gui.sh:2565 git-gui.sh:3129 msgid "Options..." msgstr "Opzioni..." @@ -382,126 +382,126 @@ msgstr "Documentazione sul web" msgid "Show SSH Key" msgstr "Mostra chave SSH" -#: git-gui.sh:2707 +#: git-gui.sh:2721 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" msgstr "" "errore grave: impossibile effettuare lo stat del path %s: file o directory " "non trovata" -#: git-gui.sh:2740 +#: git-gui.sh:2754 msgid "Current Branch:" msgstr "Ramo attuale:" -#: git-gui.sh:2761 +#: git-gui.sh:2775 msgid "Staged Changes (Will Commit)" msgstr "Modifiche preparate (saranno nella nuova revisione)" -#: git-gui.sh:2781 +#: git-gui.sh:2795 msgid "Unstaged Changes" msgstr "Modifiche non preparate" -#: git-gui.sh:2831 +#: git-gui.sh:2845 msgid "Stage Changed" msgstr "Prepara modificati" -#: git-gui.sh:2850 lib/transport.tcl:93 lib/transport.tcl:182 +#: git-gui.sh:2864 lib/transport.tcl:104 lib/transport.tcl:193 msgid "Push" msgstr "Propaga (Push)" -#: git-gui.sh:2885 +#: git-gui.sh:2899 msgid "Initial Commit Message:" msgstr "Messaggio di revisione iniziale:" -#: git-gui.sh:2886 +#: git-gui.sh:2900 msgid "Amended Commit Message:" msgstr "Messaggio di revisione corretto:" -#: git-gui.sh:2887 +#: git-gui.sh:2901 msgid "Amended Initial Commit Message:" msgstr "Messaggio iniziale di revisione corretto:" -#: git-gui.sh:2888 +#: git-gui.sh:2902 msgid "Amended Merge Commit Message:" msgstr "Messaggio di fusione corretto:" -#: git-gui.sh:2889 +#: git-gui.sh:2903 msgid "Merge Commit Message:" msgstr "Messaggio di fusione:" -#: git-gui.sh:2890 +#: git-gui.sh:2904 msgid "Commit Message:" msgstr "Messaggio di revisione:" -#: git-gui.sh:2939 git-gui.sh:3090 lib/console.tcl:73 +#: git-gui.sh:2953 git-gui.sh:3104 lib/console.tcl:73 msgid "Copy All" msgstr "Copia tutto" -#: git-gui.sh:2963 lib/blame.tcl:104 +#: git-gui.sh:2977 lib/blame.tcl:104 msgid "File:" msgstr "File:" -#: git-gui.sh:3078 +#: git-gui.sh:3092 msgid "Refresh" msgstr "Rinfresca" -#: git-gui.sh:3099 +#: git-gui.sh:3113 msgid "Decrease Font Size" msgstr "Diminuisci dimensione caratteri" -#: git-gui.sh:3103 +#: git-gui.sh:3117 msgid "Increase Font Size" msgstr "Aumenta dimensione caratteri" -#: git-gui.sh:3111 lib/blame.tcl:281 +#: git-gui.sh:3125 lib/blame.tcl:281 msgid "Encoding" msgstr "Codifica" -#: git-gui.sh:3122 +#: git-gui.sh:3136 msgid "Apply/Reverse Hunk" msgstr "Applica/Inverti sezione" -#: git-gui.sh:3127 +#: git-gui.sh:3141 msgid "Apply/Reverse Line" msgstr "Applica/Inverti riga" -#: git-gui.sh:3137 +#: git-gui.sh:3151 msgid "Run Merge Tool" msgstr "Avvia programma esterno per la risoluzione dei conflitti" -#: git-gui.sh:3142 +#: git-gui.sh:3156 msgid "Use Remote Version" msgstr "Usa versione remota" -#: git-gui.sh:3146 +#: git-gui.sh:3160 msgid "Use Local Version" msgstr "Usa versione locale" -#: git-gui.sh:3150 +#: git-gui.sh:3164 msgid "Revert To Base" msgstr "Ritorna alla revisione comune" -#: git-gui.sh:3169 +#: git-gui.sh:3183 msgid "Unstage Hunk From Commit" msgstr "Annulla preparazione della sezione per una nuova revisione" -#: git-gui.sh:3170 +#: git-gui.sh:3184 msgid "Unstage Line From Commit" msgstr "Annulla preparazione della linea per una nuova revisione" -#: git-gui.sh:3172 +#: git-gui.sh:3186 msgid "Stage Hunk For Commit" msgstr "Prepara sezione per una nuova revisione" -#: git-gui.sh:3173 +#: git-gui.sh:3187 msgid "Stage Line For Commit" msgstr "Prepara linea per una nuova revisione" -#: git-gui.sh:3196 +#: git-gui.sh:3210 msgid "Initializing..." msgstr "Inizializzazione..." -#: git-gui.sh:3301 +#: git-gui.sh:3315 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -518,7 +518,7 @@ msgstr "" "da %s:\n" "\n" -#: git-gui.sh:3331 +#: git-gui.sh:3345 msgid "" "\n" "This is due to a known issue with the\n" @@ -528,7 +528,7 @@ msgstr "" "Ciò è dovuto a un problema conosciuto\n" "causato dall'eseguibile Tcl distribuito da Cygwin." -#: git-gui.sh:3336 +#: git-gui.sh:3350 #, tcl-format msgid "" "\n" @@ -613,43 +613,43 @@ msgstr "Ricerca accurata delle copie in corso..." msgid "Loading annotation..." msgstr "Caricamento annotazioni..." -#: lib/blame.tcl:964 +#: lib/blame.tcl:963 msgid "Author:" msgstr "Autore:" -#: lib/blame.tcl:968 +#: lib/blame.tcl:967 msgid "Committer:" msgstr "Revisione creata da:" -#: lib/blame.tcl:973 +#: lib/blame.tcl:972 msgid "Original File:" msgstr "File originario:" -#: lib/blame.tcl:1021 +#: lib/blame.tcl:1020 msgid "Cannot find HEAD commit:" msgstr "Impossibile trovare la revisione HEAD:" -#: lib/blame.tcl:1076 +#: lib/blame.tcl:1075 msgid "Cannot find parent commit:" msgstr "Impossibile trovare la revisione precedente:" -#: lib/blame.tcl:1091 +#: lib/blame.tcl:1090 msgid "Unable to display parent" msgstr "Impossibile visualizzare la revisione precedente" -#: lib/blame.tcl:1092 lib/diff.tcl:297 +#: lib/blame.tcl:1091 lib/diff.tcl:297 msgid "Error loading diff:" msgstr "Errore nel caricamento delle differenze:" -#: lib/blame.tcl:1232 +#: lib/blame.tcl:1231 msgid "Originally By:" msgstr "In origine da:" -#: lib/blame.tcl:1238 +#: lib/blame.tcl:1237 msgid "In File:" msgstr "Nel file:" -#: lib/blame.tcl:1243 +#: lib/blame.tcl:1242 msgid "Copied Or Moved Here By:" msgstr "Copiato o spostato qui da:" @@ -666,7 +666,7 @@ msgstr "Attiva" #: lib/checkout_op.tcl:544 lib/choose_font.tcl:43 lib/merge.tcl:172 #: lib/option.tcl:125 lib/remote_add.tcl:32 lib/remote_branch_delete.tcl:42 #: lib/tools_dlg.tcl:40 lib/tools_dlg.tcl:204 lib/tools_dlg.tcl:352 -#: lib/transport.tcl:97 +#: lib/transport.tcl:108 msgid "Cancel" msgstr "Annulla" @@ -1324,19 +1324,19 @@ msgstr "" "completata. Non puoi correggere la revisione precedente a meno che prima tu " "non interrompa l'operazione di fusione in corso.\n" -#: lib/commit.tcl:49 +#: lib/commit.tcl:48 msgid "Error loading commit data for amend:" msgstr "Errore durante il caricamento dei dati della revisione da correggere:" -#: lib/commit.tcl:76 +#: lib/commit.tcl:75 msgid "Unable to obtain your identity:" msgstr "Impossibile ottenere la tua identità:" -#: lib/commit.tcl:81 +#: lib/commit.tcl:80 msgid "Invalid GIT_COMMITTER_IDENT:" msgstr "GIT_COMMITTER_IDENT non valida:" -#: lib/commit.tcl:133 +#: lib/commit.tcl:132 msgid "" "Last scanned state does not match repository state.\n" "\n" @@ -1353,7 +1353,7 @@ msgstr "" "\n" "La nuova analisi comincerà ora.\n" -#: lib/commit.tcl:156 +#: lib/commit.tcl:155 #, tcl-format msgid "" "Unmerged files cannot be committed.\n" @@ -1366,7 +1366,7 @@ msgstr "" "Il file %s presenta dei conflitti. Devi risolverli e preparare il file per " "creare una nuova revisione prima di effettuare questa azione.\n" -#: lib/commit.tcl:164 +#: lib/commit.tcl:163 #, tcl-format msgid "" "Unknown file state %s detected.\n" @@ -1377,7 +1377,7 @@ msgstr "" "\n" "Questo programma non può creare una revisione contenente il file %s.\n" -#: lib/commit.tcl:172 +#: lib/commit.tcl:171 msgid "" "No changes to commit.\n" "\n" @@ -1388,7 +1388,7 @@ msgstr "" "Devi preparare per una nuova revisione almeno 1 file prima di effettuare " "questa operazione.\n" -#: lib/commit.tcl:187 +#: lib/commit.tcl:186 msgid "" "Please supply a commit message.\n" "\n" @@ -1406,45 +1406,45 @@ msgstr "" "- Seconda linea: vuota.\n" "- Terza linea: spiega a cosa serve la tua modifica.\n" -#: lib/commit.tcl:211 +#: lib/commit.tcl:210 #, tcl-format msgid "warning: Tcl does not support encoding '%s'." msgstr "attenzione: Tcl non supporta la codifica '%s'." -#: lib/commit.tcl:227 +#: lib/commit.tcl:226 msgid "Calling pre-commit hook..." msgstr "Avvio pre-commit hook..." -#: lib/commit.tcl:242 +#: lib/commit.tcl:241 msgid "Commit declined by pre-commit hook." msgstr "Revisione rifiutata dal pre-commit hook." -#: lib/commit.tcl:265 +#: lib/commit.tcl:264 msgid "Calling commit-msg hook..." msgstr "Avvio commit-msg hook..." -#: lib/commit.tcl:280 +#: lib/commit.tcl:279 msgid "Commit declined by commit-msg hook." msgstr "Revisione rifiutata dal commit-msg hook." -#: lib/commit.tcl:293 +#: lib/commit.tcl:292 msgid "Committing changes..." msgstr "Archiviazione modifiche..." -#: lib/commit.tcl:309 +#: lib/commit.tcl:308 msgid "write-tree failed:" msgstr "write-tree non riuscito:" -#: lib/commit.tcl:310 lib/commit.tcl:354 lib/commit.tcl:374 +#: lib/commit.tcl:309 lib/commit.tcl:353 lib/commit.tcl:373 msgid "Commit failed." msgstr "Impossibile creare una nuova revisione." -#: lib/commit.tcl:327 +#: lib/commit.tcl:326 #, tcl-format msgid "Commit %s appears to be corrupt" msgstr "La revisione %s sembra essere danneggiata" -#: lib/commit.tcl:332 +#: lib/commit.tcl:331 msgid "" "No changes to commit.\n" "\n" @@ -1458,19 +1458,19 @@ msgstr "" "\n" "Si procederà subito ad una nuova analisi.\n" -#: lib/commit.tcl:339 +#: lib/commit.tcl:338 msgid "No changes to commit." msgstr "Nessuna modifica per la nuova revisione." -#: lib/commit.tcl:353 +#: lib/commit.tcl:352 msgid "commit-tree failed:" msgstr "commit-tree non riuscito:" -#: lib/commit.tcl:373 +#: lib/commit.tcl:372 msgid "update-ref failed:" msgstr "update-ref non riuscito:" -#: lib/commit.tcl:461 +#: lib/commit.tcl:460 #, tcl-format msgid "Created commit %s: %s" msgstr "Creata revisione %s: %s" @@ -2186,7 +2186,8 @@ msgstr "Recupero %s" msgid "Do not know how to initialize repository at location '%s'." msgstr "Impossibile inizializzare l'archivio posto in '%s'." -#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:71 +#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:63 +#: lib/transport.tcl:81 #, tcl-format msgid "push %s" msgstr "propaga verso %s" @@ -2204,11 +2205,11 @@ msgstr "Elimina ramo remoto" msgid "From Repository" msgstr "Da archivio" -#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123 +#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:134 msgid "Remote:" msgstr "Remoto:" -#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138 +#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:149 msgid "Arbitrary Location:" msgstr "Posizione specifica:" @@ -2537,35 +2538,40 @@ msgstr "Effettua potatura dei duplicati locali di rami remoti cancellati da %s" msgid "Pushing changes to %s" msgstr "Propagazione modifiche a %s" -#: lib/transport.tcl:72 +#: lib/transport.tcl:64 +#, tcl-format +msgid "Mirroring to %s" +msgstr "Mirroring verso %s" + +#: lib/transport.tcl:82 #, tcl-format msgid "Pushing %s %s to %s" msgstr "Propagazione %s %s a %s" -#: lib/transport.tcl:89 +#: lib/transport.tcl:100 msgid "Push Branches" msgstr "Propaga rami" -#: lib/transport.tcl:103 +#: lib/transport.tcl:114 msgid "Source Branches" msgstr "Rami di origine" -#: lib/transport.tcl:120 +#: lib/transport.tcl:131 msgid "Destination Repository" msgstr "Archivio di destinazione" -#: lib/transport.tcl:158 +#: lib/transport.tcl:169 msgid "Transfer Options" msgstr "Opzioni di trasferimento" -#: lib/transport.tcl:160 +#: lib/transport.tcl:171 msgid "Force overwrite existing branch (may discard changes)" msgstr "Sovrascrivi ramo esistente (alcune modifiche potrebbero essere perse)" -#: lib/transport.tcl:164 +#: lib/transport.tcl:175 msgid "Use thin pack (for slow network connections)" msgstr "Utilizza 'thin pack' (per connessioni lente)" -#: lib/transport.tcl:168 +#: lib/transport.tcl:179 msgid "Include tags" msgstr "Includi etichette" diff --git a/git-gui/po/ja.po b/git-gui/po/ja.po index 8ba64177fa..09d60bef74 100644 --- a/git-gui/po/ja.po +++ b/git-gui/po/ja.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: git-gui\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-11-16 13:56-0800\n" -"PO-Revision-Date: 2008-11-26 19:17+0900\n" +"POT-Creation-Date: 2008-12-08 08:31-0800\n" +"PO-Revision-Date: 2008-12-09 06:27+0900\n" "Last-Translator: しらいし ななこ <nanako3@lavabit.com>\n" "Language-Team: Japanese\n" "MIME-Version: 1.0\n" @@ -2501,7 +2501,12 @@ msgstr "%s から削除されたトラッキング・ブランチを刈ってい msgid "Pushing changes to %s" msgstr "%s へ変更をプッシュしています" -#: lib/transport.tcl:72 +#: lib/transport.tcl:64 +#, tcl-format +msgid "Mirroring to %s" +msgstr "%s へミラーしています" + +#: lib/transport.tcl:82 #, tcl-format msgid "Pushing %s %s to %s" msgstr "%3$s へ %1$s %2$s をプッシュしています" diff --git a/git-gui/po/nb.po b/git-gui/po/nb.po new file mode 100644 index 0000000000..1c5137d84c --- /dev/null +++ b/git-gui/po/nb.po @@ -0,0 +1,2484 @@ +# Norwegian (Bokmål) translation of git-gui. +# Copyright (C) 2007-2008 Shawn Pearce, et al. +# This file is distributed under the same license as the git-gui package. +# +# Fredrik Skolmli <fredrik@frsk.net>, 2008. +# +msgid "" +msgstr "" +"Project-Id-Version: nb\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-11-16 13:56-0800\n" +"PO-Revision-Date: 2008-12-03 16:05+0100\n" +"Last-Translator: Fredrik Skolmli <fredrik@frsk.net>\n" +"Language-Team: Norwegian Bokmål\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: git-gui.sh:41 git-gui.sh:737 git-gui.sh:751 git-gui.sh:764 git-gui.sh:847 +#: git-gui.sh:866 +msgid "git-gui: fatal error" +msgstr "git-gui: Kritisk feil" + +#: git-gui.sh:689 +#, tcl-format +msgid "Invalid font specified in %s:" +msgstr "Ugyldig font spesifisert i %s:" + +#: git-gui.sh:723 +msgid "Main Font" +msgstr "Hovedskrifttype" + +#: git-gui.sh:724 +msgid "Diff/Console Font" +msgstr "Diff-/Konsollskrifttype" + +#: git-gui.sh:738 +msgid "Cannot find git in PATH." +msgstr "Kan ikke finne git i PATH" + +#: git-gui.sh:765 +msgid "Cannot parse Git version string:" +msgstr "Kan ikke tyde Git's oppgitte versjon:" + +#: git-gui.sh:783 +#, tcl-format +msgid "" +"Git version cannot be determined.\n" +"\n" +"%s claims it is version '%s'.\n" +"\n" +"%s requires at least Git 1.5.0 or later.\n" +"\n" +"Assume '%s' is version 1.5.0?\n" +msgstr "" +"Kan ikke avgjøre hvilken Git-versjon du har.\n" +"\n" +"%s sier versjonen er '%s'.\n" +"\n" +"%s krever Git versjon 1.5.0 eller nyere.\n" +"\n" +"Anta at '%s' er versjon 1.5.0?\n" + +#: git-gui.sh:1062 +msgid "Git directory not found:" +msgstr "Git-katalog ikke funnet:" + +#: git-gui.sh:1069 +msgid "Cannot move to top of working directory:" +msgstr "Kan ikke gå til toppen av arbeidskatalogen:" + +#: git-gui.sh:1076 +msgid "Cannot use funny .git directory:" +msgstr "" + +#: git-gui.sh:1081 +msgid "No working directory" +msgstr "Ingen arbeidskatalog" + +#: git-gui.sh:1247 lib/checkout_op.tcl:305 +msgid "Refreshing file status..." +msgstr "Oppdaterer filstatus..." + +#: git-gui.sh:1303 +msgid "Scanning for modified files ..." +msgstr "Søker etter endrede filer..." + +#: git-gui.sh:1367 +msgid "Calling prepare-commit-msg hook..." +msgstr "" + +#: git-gui.sh:1384 +msgid "Commit declined by prepare-commit-msg hook." +msgstr "" + +#: git-gui.sh:1542 lib/browser.tcl:246 +msgid "Ready." +msgstr "Klar." + +#: git-gui.sh:1819 +msgid "Unmodified" +msgstr "Uendret" + +#: git-gui.sh:1821 +msgid "Modified, not staged" +msgstr "Endret, ikke køet" + +#: git-gui.sh:1822 git-gui.sh:1830 +msgid "Staged for commit" +msgstr "Køet for innsjekking" + +#: git-gui.sh:1823 git-gui.sh:1831 +msgid "Portions staged for commit" +msgstr "Delvis køet for innsjekking" + +#: git-gui.sh:1824 git-gui.sh:1832 +msgid "Staged for commit, missing" +msgstr "Klar for innsjekking, fraværende" + +#: git-gui.sh:1826 +msgid "File type changed, not staged" +msgstr "Filtype endret, ikke køet" + +#: git-gui.sh:1827 +msgid "File type changed, staged" +msgstr "Filtype endret, køet" + +#: git-gui.sh:1829 +msgid "Untracked, not staged" +msgstr "Usporet, ikke køet" + +#: git-gui.sh:1834 +msgid "Missing" +msgstr "Fraværende" + +#: git-gui.sh:1835 +msgid "Staged for removal" +msgstr "Køet for fjerning" + +#: git-gui.sh:1836 +msgid "Staged for removal, still present" +msgstr "Køet for fjerning, fortsatt tilstede" + +#: git-gui.sh:1838 git-gui.sh:1839 git-gui.sh:1840 git-gui.sh:1841 +#: git-gui.sh:1842 git-gui.sh:1843 +msgid "Requires merge resolution" +msgstr "Sammenslåingen krever konflikthåndtering" + +#: git-gui.sh:1878 +msgid "Starting gitk... please wait..." +msgstr "Starter gitk... Vennligst vent..." + +#: git-gui.sh:1887 +msgid "Couldn't find gitk in PATH" +msgstr "Kunne ikke finne gitk i PATH" + +#: git-gui.sh:2280 lib/choose_repository.tcl:36 +msgid "Repository" +msgstr "Arkiv" + +#: git-gui.sh:2281 +msgid "Edit" +msgstr "Redigere" + +#: git-gui.sh:2283 lib/choose_rev.tcl:561 +msgid "Branch" +msgstr "Gren" + +#: git-gui.sh:2286 lib/choose_rev.tcl:548 +msgid "Commit@@noun" +msgstr "Innsjekking" + +#: git-gui.sh:2289 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 +msgid "Merge" +msgstr "Sammenslåing" + +#: git-gui.sh:2290 lib/choose_rev.tcl:557 +msgid "Remote" +msgstr "Fjernarkiv" + +#: git-gui.sh:2293 +msgid "Tools" +msgstr "Verktøy" + +#: git-gui.sh:2302 +msgid "Explore Working Copy" +msgstr "Utforsk arbeidskopien" + +#: git-gui.sh:2307 +msgid "Browse Current Branch's Files" +msgstr "Utforsk denne grens filer" + +#: git-gui.sh:2311 +msgid "Browse Branch Files..." +msgstr "Bla igjennom filer på gren..." + +#: git-gui.sh:2316 +msgid "Visualize Current Branch's History" +msgstr "Visualiser denne grens historikk" + +#: git-gui.sh:2320 +msgid "Visualize All Branch History" +msgstr "Visualiser alle greners historikk" + +#: git-gui.sh:2327 +#, tcl-format +msgid "Browse %s's Files" +msgstr "Bla i filene til %s" + +#: git-gui.sh:2329 +#, tcl-format +msgid "Visualize %s's History" +msgstr "Visualiser historien til %s" + +#: git-gui.sh:2334 lib/database.tcl:27 lib/database.tcl:67 +msgid "Database Statistics" +msgstr "Databasestatistikk" + +#: git-gui.sh:2337 lib/database.tcl:34 +msgid "Compress Database" +msgstr "Kompress databasen" + +#: git-gui.sh:2340 +msgid "Verify Database" +msgstr "Verifiser databasen" + +#: git-gui.sh:2347 git-gui.sh:2351 git-gui.sh:2355 lib/shortcut.tcl:7 +#: lib/shortcut.tcl:39 lib/shortcut.tcl:71 +msgid "Create Desktop Icon" +msgstr "Lag skrivebordsikon" + +#: git-gui.sh:2363 lib/choose_repository.tcl:183 lib/choose_repository.tcl:191 +msgid "Quit" +msgstr "Avslutt" + +#: git-gui.sh:2371 +msgid "Undo" +msgstr "Angre" + +#: git-gui.sh:2374 +msgid "Redo" +msgstr "Gjør om" + +#: git-gui.sh:2378 git-gui.sh:2923 +msgid "Cut" +msgstr "Klipp ut" + +#: git-gui.sh:2381 git-gui.sh:2926 git-gui.sh:3000 git-gui.sh:3082 +#: lib/console.tcl:69 +msgid "Copy" +msgstr "Kopier" + +#: git-gui.sh:2384 git-gui.sh:2929 +msgid "Paste" +msgstr "Lim inn" + +#: git-gui.sh:2387 git-gui.sh:2932 lib/branch_delete.tcl:26 +#: lib/remote_branch_delete.tcl:38 +msgid "Delete" +msgstr "Slett" + +#: git-gui.sh:2391 git-gui.sh:2936 git-gui.sh:3086 lib/console.tcl:71 +msgid "Select All" +msgstr "Velg alle" + +#: git-gui.sh:2400 +msgid "Create..." +msgstr "Opprett..." + +#: git-gui.sh:2406 +msgid "Checkout..." +msgstr "Sjekk ut..." + +#: git-gui.sh:2412 +msgid "Rename..." +msgstr "Endre navn..." + +#: git-gui.sh:2417 +msgid "Delete..." +msgstr "Slett..." + +#: git-gui.sh:2422 +msgid "Reset..." +msgstr "Tilbakestill..." + +#: git-gui.sh:2432 +msgid "Done" +msgstr "Ferdig" + +#: git-gui.sh:2434 +msgid "Commit@@verb" +msgstr "Sjekk inn" + +#: git-gui.sh:2443 git-gui.sh:2864 +msgid "New Commit" +msgstr "Ny innsjekking" + +#: git-gui.sh:2451 git-gui.sh:2871 +msgid "Amend Last Commit" +msgstr "Legg til forrige innsjekking" + +#: git-gui.sh:2461 git-gui.sh:2825 lib/remote_branch_delete.tcl:99 +msgid "Rescan" +msgstr "Søk på ny" + +#: git-gui.sh:2467 +msgid "Stage To Commit" +msgstr "Legg til i innsjekkingskøen" + +#: git-gui.sh:2473 +msgid "Stage Changed Files To Commit" +msgstr "Legg til endrede filer i innsjekkingskøen" + +#: git-gui.sh:2479 +msgid "Unstage From Commit" +msgstr "Fjern fra innsjekkingskøen" + +#: git-gui.sh:2484 lib/index.tcl:410 +msgid "Revert Changes" +msgstr "Tilbakestill endringer" + +#: git-gui.sh:2491 git-gui.sh:3069 +msgid "Show Less Context" +msgstr "Vis mindre innhold" + +#: git-gui.sh:2495 git-gui.sh:3073 +msgid "Show More Context" +msgstr "Vis mer innhold" + +#: git-gui.sh:2502 git-gui.sh:2838 git-gui.sh:2947 +msgid "Sign Off" +msgstr "Signér" + +#: git-gui.sh:2518 +msgid "Local Merge..." +msgstr "Lokal sammenslåing..." + +#: git-gui.sh:2523 +msgid "Abort Merge..." +msgstr "Avbryt sammenslåing..." + +#: git-gui.sh:2535 git-gui.sh:2575 +msgid "Add..." +msgstr "Legg til..." + +#: git-gui.sh:2539 +msgid "Push..." +msgstr "Send..." + +#: git-gui.sh:2543 +msgid "Delete Branch..." +msgstr "Fjern gren..." + +#: git-gui.sh:2553 git-gui.sh:2589 lib/about.tcl:14 +#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:53 +#, tcl-format +msgid "About %s" +msgstr "Om %s" + +#: git-gui.sh:2557 +msgid "Preferences..." +msgstr "Innstillinger..." + +#: git-gui.sh:2565 git-gui.sh:3115 +msgid "Options..." +msgstr "Alternativer..." + +#: git-gui.sh:2576 +msgid "Remove..." +msgstr "Fjern..." + +#: git-gui.sh:2585 lib/choose_repository.tcl:50 +msgid "Help" +msgstr "Hjelp" + +#: git-gui.sh:2611 +msgid "Online Documentation" +msgstr "Online dokumentasjon" + +#: git-gui.sh:2614 lib/choose_repository.tcl:47 lib/choose_repository.tcl:56 +msgid "Show SSH Key" +msgstr "Vis SSH-nøkkel" + +#: git-gui.sh:2707 +#, tcl-format +msgid "fatal: cannot stat path %s: No such file or directory" +msgstr "" +"kritisk: kunne ikke finne status for sti %s: Ingen slik fil eller katalog" + +#: git-gui.sh:2740 +msgid "Current Branch:" +msgstr "Nåværende gren:" + +#: git-gui.sh:2761 +msgid "Staged Changes (Will Commit)" +msgstr "Køede endringer (til innsjekking)" + +#: git-gui.sh:2781 +msgid "Unstaged Changes" +msgstr "Ukøede endringer" + +#: git-gui.sh:2831 +msgid "Stage Changed" +msgstr "Kø endret" + +#: git-gui.sh:2850 lib/transport.tcl:93 lib/transport.tcl:182 +msgid "Push" +msgstr "Send" + +#: git-gui.sh:2885 +msgid "Initial Commit Message:" +msgstr "Innledende innsjekkingsmelding:" + +#: git-gui.sh:2886 +msgid "Amended Commit Message:" +msgstr "Utdypt innsjekkingsmelding" + +#: git-gui.sh:2887 +msgid "Amended Initial Commit Message:" +msgstr "Utdypt innledende innsjekkingsmelding:" + +#: git-gui.sh:2888 +msgid "Amended Merge Commit Message:" +msgstr "Utdypt innsjekkingsmelding for sammenslåing:" + +#: git-gui.sh:2889 +msgid "Merge Commit Message:" +msgstr "Revisjonsmelding for sammenslåing:" + +#: git-gui.sh:2890 +msgid "Commit Message:" +msgstr "Revisjonsmelding:" + +#: git-gui.sh:2939 git-gui.sh:3090 lib/console.tcl:73 +msgid "Copy All" +msgstr "Kopier alle" + +#: git-gui.sh:2963 lib/blame.tcl:104 +msgid "File:" +msgstr "Fil:" + +#: git-gui.sh:3078 +msgid "Refresh" +msgstr "Oppdater" + +#: git-gui.sh:3099 +msgid "Decrease Font Size" +msgstr "Gjør teksten mindre" + +#: git-gui.sh:3103 +msgid "Increase Font Size" +msgstr "Gjør teksten større" + +#: git-gui.sh:3111 lib/blame.tcl:281 +msgid "Encoding" +msgstr "Tekstkoding" + +#: git-gui.sh:3122 +msgid "Apply/Reverse Hunk" +msgstr "Bruk/tilbakestill del" + +#: git-gui.sh:3127 +msgid "Apply/Reverse Line" +msgstr "Bruk/tilbakestill linje" + +#: git-gui.sh:3137 +msgid "Run Merge Tool" +msgstr "Start sammenslåingsprosess" + +#: git-gui.sh:3142 +msgid "Use Remote Version" +msgstr "Bruk versjon fra fjernarkiv" + +#: git-gui.sh:3146 +msgid "Use Local Version" +msgstr "Bruk lokal versjon" + +#: git-gui.sh:3150 +msgid "Revert To Base" +msgstr "Tilbakestill til baseversjonen" + +#: git-gui.sh:3169 +msgid "Unstage Hunk From Commit" +msgstr "Fjern delen fra innsjekkingskøen" + +#: git-gui.sh:3170 +msgid "Unstage Line From Commit" +msgstr "Fjern linjen fra innsjekkingskøen" + +#: git-gui.sh:3172 +msgid "Stage Hunk For Commit" +msgstr "Legg del i innsjekkingskøen" + +#: git-gui.sh:3173 +msgid "Stage Line For Commit" +msgstr "Legg til linje i innsjekkingskøen" + +#: git-gui.sh:3196 +msgid "Initializing..." +msgstr "Initsialiserer..." + +#: git-gui.sh:3301 +#, tcl-format +msgid "" +"Possible environment issues exist.\n" +"\n" +"The following environment variables are probably\n" +"going to be ignored by any Git subprocess run\n" +"by %s:\n" +"\n" +msgstr "" + +#: git-gui.sh:3331 +msgid "" +"\n" +"This is due to a known issue with the\n" +"Tcl binary distributed by Cygwin." +msgstr "" + +#: git-gui.sh:3336 +#, tcl-format +msgid "" +"\n" +"\n" +"A good replacement for %s\n" +"is placing values for the user.name and\n" +"user.email settings into your personal\n" +"~/.gitconfig file.\n" +msgstr "" + +#: lib/about.tcl:26 +msgid "git-gui - a graphical user interface for Git." +msgstr "git-gui - Et grafisk brukergrensesnitt for Git." + +#: lib/blame.tcl:72 +msgid "File Viewer" +msgstr "Filviser" + +#: lib/blame.tcl:78 +msgid "Commit:" +msgstr "Innsjekking:" + +#: lib/blame.tcl:271 +msgid "Copy Commit" +msgstr "Kopier innsjekking" + +#: lib/blame.tcl:275 +msgid "Find Text..." +msgstr "Søk etter tekst..." + +#: lib/blame.tcl:284 +msgid "Do Full Copy Detection" +msgstr "Gjennomfør full deteksjon av kopieringer" + +#: lib/blame.tcl:288 +msgid "Show History Context" +msgstr "Vis historikkens innhold" + +#: lib/blame.tcl:291 +msgid "Blame Parent Commit" +msgstr "" + +#: lib/blame.tcl:450 +#, tcl-format +msgid "Reading %s..." +msgstr "Leser %s..." + +#: lib/blame.tcl:557 +msgid "Loading copy/move tracking annotations..." +msgstr "" + +#: lib/blame.tcl:577 +msgid "lines annotated" +msgstr "" + +#: lib/blame.tcl:769 +msgid "Loading original location annotations..." +msgstr "" + +#: lib/blame.tcl:772 +msgid "Annotation complete." +msgstr "" + +#: lib/blame.tcl:802 +msgid "Busy" +msgstr "Opptatt" + +#: lib/blame.tcl:803 +msgid "Annotation process is already running." +msgstr "" + +#: lib/blame.tcl:842 +msgid "Running thorough copy detection..." +msgstr "Kjører kopidetektering..." + +#: lib/blame.tcl:910 +msgid "Loading annotation..." +msgstr "" + +#: lib/blame.tcl:964 +msgid "Author:" +msgstr "Forfatter:" + +#: lib/blame.tcl:968 +msgid "Committer:" +msgstr "Innsjekker:" + +#: lib/blame.tcl:973 +msgid "Original File:" +msgstr "Opprinnelig fil:" + +#: lib/blame.tcl:1021 +msgid "Cannot find HEAD commit:" +msgstr "Finner ikke HEAD's innsjekking:" + +#: lib/blame.tcl:1076 +msgid "Cannot find parent commit:" +msgstr "Kan ikke finne innsjekkingens forelder:" + +#: lib/blame.tcl:1091 +msgid "Unable to display parent" +msgstr "Kan ikke vise forelder" + +#: lib/blame.tcl:1092 lib/diff.tcl:297 +msgid "Error loading diff:" +msgstr "Feil ved innlasting av forskjell:" + +#: lib/blame.tcl:1232 +msgid "Originally By:" +msgstr "Opprinnelig av:" + +#: lib/blame.tcl:1238 +msgid "In File:" +msgstr "I fil:" + +#: lib/blame.tcl:1243 +msgid "Copied Or Moved Here By:" +msgstr "Kopiert eller flyttet hit av:" + +#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19 +msgid "Checkout Branch" +msgstr "Sjekk ut gren" + +#: lib/branch_checkout.tcl:23 +msgid "Checkout" +msgstr "Utsjekking" + +#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35 +#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:282 +#: lib/checkout_op.tcl:544 lib/choose_font.tcl:43 lib/merge.tcl:172 +#: lib/option.tcl:125 lib/remote_add.tcl:32 lib/remote_branch_delete.tcl:42 +#: lib/tools_dlg.tcl:40 lib/tools_dlg.tcl:204 lib/tools_dlg.tcl:352 +#: lib/transport.tcl:97 +msgid "Cancel" +msgstr "Avbryt" + +#: lib/branch_checkout.tcl:32 lib/browser.tcl:287 lib/tools_dlg.tcl:328 +msgid "Revision" +msgstr "Revisjon" + +#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:280 +msgid "Options" +msgstr "Valg" + +#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92 +msgid "Fetch Tracking Branch" +msgstr "Hent sporet gren" + +#: lib/branch_checkout.tcl:44 +msgid "Detach From Local Branch" +msgstr "Koble bort lokal gren" + +#: lib/branch_create.tcl:22 +msgid "Create Branch" +msgstr "Opprett gren" + +#: lib/branch_create.tcl:27 +msgid "Create New Branch" +msgstr "Opprett ny gren" + +#: lib/branch_create.tcl:31 lib/choose_repository.tcl:377 +msgid "Create" +msgstr "Opprett" + +#: lib/branch_create.tcl:40 +msgid "Branch Name" +msgstr "Navn på gren" + +#: lib/branch_create.tcl:43 lib/remote_add.tcl:39 lib/tools_dlg.tcl:50 +msgid "Name:" +msgstr "Navn:" + +#: lib/branch_create.tcl:58 +msgid "Match Tracking Branch Name" +msgstr "Bruk navn på sporet gren" + +#: lib/branch_create.tcl:66 +msgid "Starting Revision" +msgstr "Starter revisjon" + +#: lib/branch_create.tcl:72 +msgid "Update Existing Branch:" +msgstr "Oppdater eksisterende gren:" + +#: lib/branch_create.tcl:75 +msgid "No" +msgstr "Nei" + +#: lib/branch_create.tcl:80 +msgid "Fast Forward Only" +msgstr "Kun hurtigfremspoling" + +#: lib/branch_create.tcl:85 lib/checkout_op.tcl:536 +msgid "Reset" +msgstr "Tilbakestill" + +#: lib/branch_create.tcl:97 +msgid "Checkout After Creation" +msgstr "Sjekk ut etter oppretting" + +#: lib/branch_create.tcl:131 +msgid "Please select a tracking branch." +msgstr "Velg en gren som skal følges." + +#: lib/branch_create.tcl:140 +#, tcl-format +msgid "Tracking branch %s is not a branch in the remote repository." +msgstr "Den fulgte grenen %s er ikke en gren i fjernarkivet." + +#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86 +msgid "Please supply a branch name." +msgstr "Angi et navn for grenen." + +#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106 +#, tcl-format +msgid "'%s' is not an acceptable branch name." +msgstr "'%s' kan ikke brukes som navn på en gren." + +#: lib/branch_delete.tcl:15 +msgid "Delete Branch" +msgstr "Fjern gren" + +#: lib/branch_delete.tcl:20 +msgid "Delete Local Branch" +msgstr "Fjern lokal gren" + +#: lib/branch_delete.tcl:37 +msgid "Local Branches" +msgstr "Lokale grener" + +#: lib/branch_delete.tcl:52 +msgid "Delete Only If Merged Into" +msgstr "Fjern kun ved sammenslåing" + +#: lib/branch_delete.tcl:54 +msgid "Always (Do not perform merge test.)" +msgstr "Alltid (Ikke utfør sammenslåingstest.)" + +#: lib/branch_delete.tcl:103 +#, tcl-format +msgid "The following branches are not completely merged into %s:" +msgstr "Følgende grener er ikke fullstendig slått sammen med %s:" + +#: lib/branch_delete.tcl:115 +msgid "" +"Recovering deleted branches is difficult. \n" +"\n" +" Delete the selected branches?" +msgstr "" +"Gjenoppretting av fjernede grener er vanskelig. \n" +"\n" +" Fjern valgte grener?" + +#: lib/branch_delete.tcl:141 +#, tcl-format +msgid "" +"Failed to delete branches:\n" +"%s" +msgstr "" +"Kunne ikke fjerne grener:\n" +"%s" + +#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22 +msgid "Rename Branch" +msgstr "Gi gren nytt navn" + +#: lib/branch_rename.tcl:26 +msgid "Rename" +msgstr "Endre navn" + +#: lib/branch_rename.tcl:36 +msgid "Branch:" +msgstr "Gren:" + +#: lib/branch_rename.tcl:39 +msgid "New Name:" +msgstr "Nytt navn:" + +#: lib/branch_rename.tcl:75 +msgid "Please select a branch to rename." +msgstr "Vennligst velg grenen du vil endre navn på." + +#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:201 +#, tcl-format +msgid "Branch '%s' already exists." +msgstr "Grenen '%s' eksisterer allerede." + +#: lib/branch_rename.tcl:117 +#, tcl-format +msgid "Failed to rename '%s'." +msgstr "Kunne ikke endre navnet '%s'." + +#: lib/browser.tcl:17 +msgid "Starting..." +msgstr "Starter..." + +#: lib/browser.tcl:26 +msgid "File Browser" +msgstr "Utforsker" + +#: lib/browser.tcl:126 lib/browser.tcl:143 +#, tcl-format +msgid "Loading %s..." +msgstr "Laster %s..." + +#: lib/browser.tcl:187 +msgid "[Up To Parent]" +msgstr "[Opp til forelder]" + +#: lib/browser.tcl:267 lib/browser.tcl:273 +msgid "Browse Branch Files" +msgstr "Bla igjennom grenens filer" + +#: lib/browser.tcl:278 lib/choose_repository.tcl:394 +#: lib/choose_repository.tcl:480 lib/choose_repository.tcl:491 +#: lib/choose_repository.tcl:995 +msgid "Browse" +msgstr "Bla igjennom" + +#: lib/checkout_op.tcl:84 +#, tcl-format +msgid "Fetching %s from %s" +msgstr "Henter %s fra %s" + +#: lib/checkout_op.tcl:132 +#, tcl-format +msgid "fatal: Cannot resolve %s" +msgstr "kritisk: Kan ikke åpne %s" + +#: lib/checkout_op.tcl:145 lib/console.tcl:81 lib/database.tcl:31 +#: lib/sshkey.tcl:53 +msgid "Close" +msgstr "Lukk" + +#: lib/checkout_op.tcl:174 +#, tcl-format +msgid "Branch '%s' does not exist." +msgstr "Grenen '%s' eksisterer ikke." + +#: lib/checkout_op.tcl:193 +#, tcl-format +msgid "Failed to configure simplified git-pull for '%s'." +msgstr "Kunne ikke konfigurere forenklet git-pull for '%s'." + +#: lib/checkout_op.tcl:228 +#, tcl-format +msgid "" +"Branch '%s' already exists.\n" +"\n" +"It cannot fast-forward to %s.\n" +"A merge is required." +msgstr "" +"Grenen '%s' eksisterer allerede.\n" +"\n" +"Den kan ikke hurtigfremspoles til %s.\n" +"En sammenslåing er påkrevd." + +#: lib/checkout_op.tcl:242 +#, tcl-format +msgid "Merge strategy '%s' not supported." +msgstr "Sammenslåingsstrategien '%s' er ikke støttet." + +#: lib/checkout_op.tcl:261 +#, tcl-format +msgid "Failed to update '%s'." +msgstr "Kunne ikke oppdatere '%s'." + +#: lib/checkout_op.tcl:273 +msgid "Staging area (index) is already locked." +msgstr "Køområdet (index) er allerede låst." + +#: lib/checkout_op.tcl:288 +msgid "" +"Last scanned state does not match repository state.\n" +"\n" +"Another Git program has modified this repository since the last scan. A " +"rescan must be performed before the current branch can be changed.\n" +"\n" +"The rescan will be automatically started now.\n" +msgstr "" + +#: lib/checkout_op.tcl:344 +#, tcl-format +msgid "Updating working directory to '%s'..." +msgstr "Oppdaterer arbeidskatalogen til '%s'..." + +#: lib/checkout_op.tcl:345 +msgid "files checked out" +msgstr "filer sjekket ut" + +#: lib/checkout_op.tcl:375 +#, tcl-format +msgid "Aborted checkout of '%s' (file level merging is required)." +msgstr "Avbrøt utsjekkingen av '%s' (sammenslåing på filnivå kreves)." + +#: lib/checkout_op.tcl:376 +msgid "File level merge required." +msgstr "Sammenslåing på filnivå kreves" + +#: lib/checkout_op.tcl:380 +#, tcl-format +msgid "Staying on branch '%s'." +msgstr "Blir stående på grenen '%s'." + +#: lib/checkout_op.tcl:451 +msgid "" +"You are no longer on a local branch.\n" +"\n" +"If you wanted to be on a branch, create one now starting from 'This Detached " +"Checkout'." +msgstr "" + +#: lib/checkout_op.tcl:468 lib/checkout_op.tcl:472 +#, tcl-format +msgid "Checked out '%s'." +msgstr "Sjekket ut '%s'." + +#: lib/checkout_op.tcl:500 +#, tcl-format +msgid "Resetting '%s' to '%s' will lose the following commits:" +msgstr "" +"Tilbakestilling av '%s' til '%s' vil medføre tap av følgende innsjekkinger:" + +#: lib/checkout_op.tcl:522 +msgid "Recovering lost commits may not be easy." +msgstr "" +"Det vil kanskje ikke være så enkelt å gjenopprette en tapt innsjekking." + +#: lib/checkout_op.tcl:527 +#, tcl-format +msgid "Reset '%s'?" +msgstr "Tilbakestill '%s'?" + +#: lib/checkout_op.tcl:532 lib/merge.tcl:164 lib/tools_dlg.tcl:343 +msgid "Visualize" +msgstr "Visualiser" + +#: lib/checkout_op.tcl:600 +#, tcl-format +msgid "" +"Failed to set current branch.\n" +"\n" +"This working directory is only partially switched. We successfully updated " +"your files, but failed to update an internal Git file.\n" +"\n" +"This should not have occurred. %s will now close and give up." +msgstr "" + +#: lib/choose_font.tcl:39 +msgid "Select" +msgstr "Velg" + +#: lib/choose_font.tcl:53 +msgid "Font Family" +msgstr "Skrifttype-familie" + +#: lib/choose_font.tcl:74 +msgid "Font Size" +msgstr "Skriftstørrelse" + +#: lib/choose_font.tcl:91 +msgid "Font Example" +msgstr "Skrifteksempel" + +#: lib/choose_font.tcl:103 +msgid "" +"This is example text.\n" +"If you like this text, it can be your font." +msgstr "" +"Dette er en eksempeltekst.\n" +"Hvis du liker hvordan teksten ser ut, kan du velge dette som din skrifttype." + +#: lib/choose_repository.tcl:28 +msgid "Git Gui" +msgstr "Git Gui" + +#: lib/choose_repository.tcl:87 lib/choose_repository.tcl:382 +msgid "Create New Repository" +msgstr "Opprett nytt arkiv" + +#: lib/choose_repository.tcl:93 +msgid "New..." +msgstr "Ny..." + +#: lib/choose_repository.tcl:100 lib/choose_repository.tcl:465 +msgid "Clone Existing Repository" +msgstr "Klon eksistererende arkiv" + +#: lib/choose_repository.tcl:106 +msgid "Clone..." +msgstr "Klon..." + +#: lib/choose_repository.tcl:113 lib/choose_repository.tcl:983 +msgid "Open Existing Repository" +msgstr "Åpne eksistererende arkiv" + +#: lib/choose_repository.tcl:119 +msgid "Open..." +msgstr "Åpne..." + +#: lib/choose_repository.tcl:132 +msgid "Recent Repositories" +msgstr "Nylig brukte arkiv" + +#: lib/choose_repository.tcl:138 +msgid "Open Recent Repository:" +msgstr "Åpne nylig brukt arkiv:" + +#: lib/choose_repository.tcl:302 lib/choose_repository.tcl:309 +#: lib/choose_repository.tcl:316 +#, tcl-format +msgid "Failed to create repository %s:" +msgstr "Kunne ikke opprette arkivet %s:" + +#: lib/choose_repository.tcl:387 +msgid "Directory:" +msgstr "Mappe:" + +#: lib/choose_repository.tcl:417 lib/choose_repository.tcl:544 +#: lib/choose_repository.tcl:1017 +msgid "Git Repository" +msgstr "Git arkiv" + +#: lib/choose_repository.tcl:442 +#, tcl-format +msgid "Directory %s already exists." +msgstr "Mappen %s eksisterer allerede." + +#: lib/choose_repository.tcl:446 +#, tcl-format +msgid "File %s already exists." +msgstr "Filen %s eksisterer allerede." + +#: lib/choose_repository.tcl:460 +msgid "Clone" +msgstr "Klon" + +#: lib/choose_repository.tcl:473 +msgid "Source Location:" +msgstr "Kildeplassering:" + +#: lib/choose_repository.tcl:484 +msgid "Target Directory:" +msgstr "Destinasjonsmappe:" + +#: lib/choose_repository.tcl:496 +msgid "Clone Type:" +msgstr "Klontype:" + +#: lib/choose_repository.tcl:502 +msgid "Standard (Fast, Semi-Redundant, Hardlinks)" +msgstr "Standard (rask, delvis redundant, hardlinker)" + +#: lib/choose_repository.tcl:508 +msgid "Full Copy (Slower, Redundant Backup)" +msgstr "Full kopi (tregere, redundant sikkerhetskopi)" + +#: lib/choose_repository.tcl:514 +msgid "Shared (Fastest, Not Recommended, No Backup)" +msgstr "Delt (raskest, ikke anbefalt, ingen sikkerhetskopiering)" + +#: lib/choose_repository.tcl:550 lib/choose_repository.tcl:597 +#: lib/choose_repository.tcl:743 lib/choose_repository.tcl:813 +#: lib/choose_repository.tcl:1023 lib/choose_repository.tcl:1031 +#, tcl-format +msgid "Not a Git repository: %s" +msgstr "Ikke et Git-arkiv: %s" + +#: lib/choose_repository.tcl:586 +msgid "Standard only available for local repository." +msgstr "Standard er kun tilgjengelig for lokalt arkiv." + +#: lib/choose_repository.tcl:590 +msgid "Shared only available for local repository." +msgstr "Delt er kun tilgjengelig for lokalt arkiv." + +#: lib/choose_repository.tcl:611 +#, tcl-format +msgid "Location %s already exists." +msgstr "Stedet %s eksisterer allerede." + +#: lib/choose_repository.tcl:622 +msgid "Failed to configure origin" +msgstr "Kunne ikke konfigurere kildeoppføring" + +#: lib/choose_repository.tcl:634 +msgid "Counting objects" +msgstr "Teller objekter" + +#: lib/choose_repository.tcl:635 +msgid "buckets" +msgstr "bøtter" + +#: lib/choose_repository.tcl:659 +#, tcl-format +msgid "Unable to copy objects/info/alternates: %s" +msgstr "Kunne ikke kopiere objekter/informasjon/alternativt: %s" + +#: lib/choose_repository.tcl:695 +#, tcl-format +msgid "Nothing to clone from %s." +msgstr "Ingenting å klone fra %s." + +#: lib/choose_repository.tcl:697 lib/choose_repository.tcl:911 +#: lib/choose_repository.tcl:923 +msgid "The 'master' branch has not been initialized." +msgstr "Grenen 'master' har ikke blitt initsialisert." + +#: lib/choose_repository.tcl:710 +msgid "Hardlinks are unavailable. Falling back to copying." +msgstr "Harde linker er utilgjengelig. Går tilbake til kopiering." + +#: lib/choose_repository.tcl:722 +#, tcl-format +msgid "Cloning from %s" +msgstr "Kloner fra %s" + +#: lib/choose_repository.tcl:753 +msgid "Copying objects" +msgstr "Kopierer objekter" + +#: lib/choose_repository.tcl:754 +msgid "KiB" +msgstr "kB" + +#: lib/choose_repository.tcl:778 +#, tcl-format +msgid "Unable to copy object: %s" +msgstr "Kunne ikke kopiere objekt: %s" + +#: lib/choose_repository.tcl:788 +msgid "Linking objects" +msgstr "Lenker objekter" + +#: lib/choose_repository.tcl:789 +msgid "objects" +msgstr "objekter" + +#: lib/choose_repository.tcl:797 +#, tcl-format +msgid "Unable to hardlink object: %s" +msgstr "Kunne ikke opprette hardlink med objektet: %s" + +#: lib/choose_repository.tcl:852 +msgid "Cannot fetch branches and objects. See console output for details." +msgstr "Kunne ikke hente grener og objekter. Se utdata i konsoll for detaljer." + +#: lib/choose_repository.tcl:863 +msgid "Cannot fetch tags. See console output for details." +msgstr "Kunne ikke hente tagger. Se utdata i konsoll for detaljer." + +#: lib/choose_repository.tcl:887 +msgid "Cannot determine HEAD. See console output for details." +msgstr "Kan ikke bestemme HEAD. Se utdata i konsoll for detaljer." + +#: lib/choose_repository.tcl:896 +#, tcl-format +msgid "Unable to cleanup %s" +msgstr "Kunne ikke rydde opp %s" + +#: lib/choose_repository.tcl:902 +msgid "Clone failed." +msgstr "Kloning feilet." + +#: lib/choose_repository.tcl:909 +msgid "No default branch obtained." +msgstr "Ingen standardgren hentet." + +#: lib/choose_repository.tcl:920 +#, tcl-format +msgid "Cannot resolve %s as a commit." +msgstr "Kan ikke finne %s som en innsjekking." + +#: lib/choose_repository.tcl:932 +msgid "Creating working directory" +msgstr "Oppretter arbeidskatalog" + +#: lib/choose_repository.tcl:933 lib/index.tcl:65 lib/index.tcl:128 +#: lib/index.tcl:196 +msgid "files" +msgstr "filer" + +#: lib/choose_repository.tcl:962 +msgid "Initial file checkout failed." +msgstr "Initsialiserende utsjekking feilet." + +#: lib/choose_repository.tcl:978 +msgid "Open" +msgstr "Åpne" + +#: lib/choose_repository.tcl:988 +msgid "Repository:" +msgstr "Arkiv:" + +#: lib/choose_repository.tcl:1037 +#, tcl-format +msgid "Failed to open repository %s:" +msgstr "Kunne ikke åpne arkivet %s:" + +#: lib/choose_rev.tcl:53 +msgid "This Detached Checkout" +msgstr "Denne frakoblede utsjekkingen" + +#: lib/choose_rev.tcl:60 +msgid "Revision Expression:" +msgstr "Revisjonsuttrykk:" + +#: lib/choose_rev.tcl:74 +msgid "Local Branch" +msgstr "Lokal gren" + +#: lib/choose_rev.tcl:79 +msgid "Tracking Branch" +msgstr "Sporet gren" + +#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:538 +msgid "Tag" +msgstr "Tag" + +#: lib/choose_rev.tcl:317 +#, tcl-format +msgid "Invalid revision: %s" +msgstr "Ugyldig revisjon: %s" + +#: lib/choose_rev.tcl:338 +msgid "No revision selected." +msgstr "Ingen revisjoner valgt." + +#: lib/choose_rev.tcl:346 +msgid "Revision expression is empty." +msgstr "Revisjonsuttrykk er tomt." + +#: lib/choose_rev.tcl:531 +msgid "Updated" +msgstr "Oppdatert" + +#: lib/choose_rev.tcl:559 +msgid "URL" +msgstr "URL" + +#: lib/commit.tcl:9 +msgid "" +"There is nothing to amend.\n" +"\n" +"You are about to create the initial commit. There is no commit before this " +"to amend.\n" +msgstr "" +"Det er ingenting å legge til.\n" +"\n" +"Du er i ferd med å lage den initsialiserende revisjonen. Det er ingen " +"tidligere revisjoner å tilføye.\n" + +#: lib/commit.tcl:18 +msgid "" +"Cannot amend while merging.\n" +"\n" +"You are currently in the middle of a merge that has not been fully " +"completed. You cannot amend the prior commit unless you first abort the " +"current merge activity.\n" +msgstr "" +"Kan ikke tilføye under sammenslåing.\n" +"\n" +"Du er for øyeblikket under en pågående sammenslåing som ikke er fullført. Du " +"kan ikke tilføye en tidligere revisjon med mindre du først avbryter denne " +"sammenslåingen.\n" + +#: lib/commit.tcl:49 +msgid "Error loading commit data for amend:" +msgstr "Feil ved innhenting av revisjonsdata for tilføying:" + +#: lib/commit.tcl:76 +msgid "Unable to obtain your identity:" +msgstr "Kunne ikke avgjøre din identitet:" + +#: lib/commit.tcl:81 +msgid "Invalid GIT_COMMITTER_IDENT:" +msgstr "Ugyldig GIT_COMMITTER_IDENT:" + +#: lib/commit.tcl:133 +msgid "" +"Last scanned state does not match repository state.\n" +"\n" +"Another Git program has modified this repository since the last scan. A " +"rescan must be performed before another commit can be created.\n" +"\n" +"The rescan will be automatically started now.\n" +msgstr "" + +#: lib/commit.tcl:156 +#, tcl-format +msgid "" +"Unmerged files cannot be committed.\n" +"\n" +"File %s has merge conflicts. You must resolve them and stage the file " +"before committing.\n" +msgstr "" + +#: lib/commit.tcl:164 +#, tcl-format +msgid "" +"Unknown file state %s detected.\n" +"\n" +"File %s cannot be committed by this program.\n" +msgstr "" +"Ukjent filstatus %s er funnet.\n" +"\n" +"Filen %s kan ikke sjekkes inn av dette programmet.\n" + +#: lib/commit.tcl:172 +msgid "" +"No changes to commit.\n" +"\n" +"You must stage at least 1 file before you can commit.\n" +msgstr "" +"Ingen endringer å sjekke inn.\n" +"\n" +"Du må køe minst en fil før du kan sjekke inn noe.\n" + +#: lib/commit.tcl:187 +msgid "" +"Please supply a commit message.\n" +"\n" +"A good commit message has the following format:\n" +"\n" +"- First line: Describe in one sentence what you did.\n" +"- Second line: Blank\n" +"- Remaining lines: Describe why this change is good.\n" +msgstr "" +"Vennligst angi en revisjonsmelding.\n" +"\n" +"En god melding har følgende format:\n" +"\n" +"- Første linje: En beskrivelse av hva du har gjort i én setning.\n" +"- Andre linje: Blank\n" +"- Resterende linjer: Forklar hvorfor denne endringen er bra.\n" + +#: lib/commit.tcl:211 +#, tcl-format +msgid "warning: Tcl does not support encoding '%s'." +msgstr "advarsel: Tcl støtter ikke denne tegnkodingen '%s'." + +#: lib/commit.tcl:227 +msgid "Calling pre-commit hook..." +msgstr "" + +#: lib/commit.tcl:242 +msgid "Commit declined by pre-commit hook." +msgstr "" + +#: lib/commit.tcl:265 +msgid "Calling commit-msg hook..." +msgstr "" + +#: lib/commit.tcl:280 +msgid "Commit declined by commit-msg hook." +msgstr "" + +#: lib/commit.tcl:293 +msgid "Committing changes..." +msgstr "Sjekker inn endringer..." + +#: lib/commit.tcl:309 +msgid "write-tree failed:" +msgstr "Skriving til tre feilet:" + +#: lib/commit.tcl:310 lib/commit.tcl:354 lib/commit.tcl:374 +msgid "Commit failed." +msgstr "Innsjekking feilet." + +#: lib/commit.tcl:327 +#, tcl-format +msgid "Commit %s appears to be corrupt" +msgstr "Revisjon %s ser ut til å være korrupt" + +#: lib/commit.tcl:332 +msgid "" +"No changes to commit.\n" +"\n" +"No files were modified by this commit and it was not a merge commit.\n" +"\n" +"A rescan will be automatically started now.\n" +msgstr "" +"Ingen endringer til innsjekking.\n" +"\n" +"Ingen filer ble endret av denne revisjonen, og det var ikke en revisjon fra " +"en sammenslåing.\n" +"\n" +"Et nytt søk vil bli startet automatisk.\n" + +#: lib/commit.tcl:339 +msgid "No changes to commit." +msgstr "Ingen endringer til innsekking." + +#: lib/commit.tcl:353 +msgid "commit-tree failed:" +msgstr "commit-tree feilet:" + +#: lib/commit.tcl:373 +msgid "update-ref failed:" +msgstr "update-ref feilet:" + +#: lib/commit.tcl:461 +#, tcl-format +msgid "Created commit %s: %s" +msgstr "Opprettet innsjekking %s: %s" + +#: lib/console.tcl:59 +msgid "Working... please wait..." +msgstr "Jobber... Vennligst vent..." + +#: lib/console.tcl:186 +msgid "Success" +msgstr "Suksess" + +#: lib/console.tcl:200 +msgid "Error: Command Failed" +msgstr "Feil: Kommandoen feilet" + +#: lib/database.tcl:43 +msgid "Number of loose objects" +msgstr "Antall løse objekter" + +#: lib/database.tcl:44 +msgid "Disk space used by loose objects" +msgstr "Diskplass brukt av løse objekter" + +#: lib/database.tcl:45 +msgid "Number of packed objects" +msgstr "Antall pakkede objekter" + +#: lib/database.tcl:46 +msgid "Number of packs" +msgstr "Antall pakker" + +#: lib/database.tcl:47 +msgid "Disk space used by packed objects" +msgstr "Diskplass brukt av pakkede objekter" + +#: lib/database.tcl:48 +msgid "Packed objects waiting for pruning" +msgstr "Pakkede objekter som avventer fjerning" + +#: lib/database.tcl:49 +msgid "Garbage files" +msgstr "Avfallsfiler" + +#: lib/database.tcl:72 +msgid "Compressing the object database" +msgstr "Komprimerer objektdatabasen" + +#: lib/database.tcl:83 +msgid "Verifying the object database with fsck-objects" +msgstr "Verifiserer objektdatabasen med fsck-objects" + +#: lib/database.tcl:108 +#, tcl-format +msgid "" +"This repository currently has approximately %i loose objects.\n" +"\n" +"To maintain optimal performance it is strongly recommended that you compress " +"the database when more than %i loose objects exist.\n" +"\n" +"Compress the database now?" +msgstr "" +"Dette arkivet inneholder omtrent %i 'løse' objekter.\n" +"\n" +"For å sikre en optimal ytelse er det sterkt anbefalt at du komprimerer " +"databasen når det er flere enn %i 'løse' objekter i den.\n" +"\n" +"Komprimere databasen nå?" + +#: lib/date.tcl:25 +#, tcl-format +msgid "Invalid date from Git: %s" +msgstr "Ugyldig dato fra Git: %s" + +#: lib/diff.tcl:59 +#, tcl-format +msgid "" +"No differences detected.\n" +"\n" +"%s has no changes.\n" +"\n" +"The modification date of this file was updated by another application, but " +"the content within the file was not changed.\n" +"\n" +"A rescan will be automatically started to find other files which may have " +"the same state." +msgstr "" +"Ingen forandringer funnet.\n" +"\n" +"%s har ingen endringer.\n" +"\n" +"Tidsstempelet for endring på denne filen ble oppdatert av en annen " +" applikasjon, men innholdet er uendret.\n" +"\n" +"En gjennomsøking vil nå starte automatisk for å se om andre filer har " +"status." + +#: lib/diff.tcl:99 +#, tcl-format +msgid "Loading diff of %s..." +msgstr "Laster inn forskjellene av %s..." + +#: lib/diff.tcl:120 +msgid "" +"LOCAL: deleted\n" +"REMOTE:\n" +msgstr "LOKAL: slettet\n" +"FJERN:\n" + +#: lib/diff.tcl:125 +msgid "" +"REMOTE: deleted\n" +"LOCAL:\n" +msgstr "FJERN: slettet\n" +"LOKAL:\n" + +#: lib/diff.tcl:132 +msgid "LOCAL:\n" +msgstr "LOKAL:\n" + +#: lib/diff.tcl:135 +msgid "REMOTE:\n" +msgstr "FJERN:\n" + +#: lib/diff.tcl:197 lib/diff.tcl:296 +#, tcl-format +msgid "Unable to display %s" +msgstr "Kan ikke vise %s" + +#: lib/diff.tcl:198 +msgid "Error loading file:" +msgstr "Feil ved lesing av fil: %s" + +#: lib/diff.tcl:205 +msgid "Git Repository (subproject)" +msgstr "Git-arkiv (underprosjekt)" + +#: lib/diff.tcl:217 +msgid "* Binary file (not showing content)." +msgstr "* Binærfil (viser ikke innhold)" + +#: lib/diff.tcl:222 +#, tcl-format +msgid "" +"* Untracked file is %d bytes.\n" +"* Showing only first %d bytes.\n" +msgstr "" +"* Usporet fil er %d bytes.\n" +"* Viser bare %d første bytes.\n" + +#: lib/diff.tcl:228 +#, tcl-format +msgid "" +"\n" +"* Untracked file clipped here by %s.\n" +"* To see the entire file, use an external editor.\n" +msgstr "" +"\n" +"* Usporede filer klippet her av %s.\n" +"* For å se hele filen, bruk et eksternt redigeringsverktøy.\n" + +#: lib/diff.tcl:436 +msgid "Failed to unstage selected hunk." +msgstr "Kunne ikke fjerne den valgte delen fra innsjekkingskøen." + +#: lib/diff.tcl:443 +msgid "Failed to stage selected hunk." +msgstr "Kunne ikke legge til den valgte delen i innsjekkingskøen." + +#: lib/diff.tcl:509 +msgid "Failed to unstage selected line." +msgstr "Kunne ikke fjerne den valgte linjen fra innsjekkingskøen." + +#: lib/diff.tcl:517 +msgid "Failed to stage selected line." +msgstr "Kunne ikke legge til den valgte linjen i innsjekkingskøen." + +#: lib/encoding.tcl:443 +msgid "Default" +msgstr "Standard" + +#: lib/encoding.tcl:448 +#, tcl-format +msgid "System (%s)" +msgstr "Systemets (%s)" + +#: lib/encoding.tcl:459 lib/encoding.tcl:465 +msgid "Other" +msgstr "Andre" + +#: lib/error.tcl:20 lib/error.tcl:114 +msgid "error" +msgstr "feil" + +#: lib/error.tcl:36 +msgid "warning" +msgstr "advarsel" + +#: lib/error.tcl:94 +msgid "You must correct the above errors before committing." +msgstr "Du må rette de ovenstående feilene før innsjekking." + +#: lib/index.tcl:6 +msgid "Unable to unlock the index." +msgstr "Kunne ikke låse opp indexen." + +#: lib/index.tcl:15 +msgid "Index Error" +msgstr "Feil på index" + +#: lib/index.tcl:21 +msgid "" +"Updating the Git index failed. A rescan will be automatically started to " +"resynchronize git-gui." +msgstr "" +"Oppdatering av Git's index mislyktes. Et nytt søk vil bli startet for å " +"resynkronisere git-gui." + +#: lib/index.tcl:27 +msgid "Continue" +msgstr "Fortsett" + +#: lib/index.tcl:31 +msgid "Unlock Index" +msgstr "Lås opp index" + +#: lib/index.tcl:287 +#, tcl-format +msgid "Unstaging %s from commit" +msgstr "Fjerner %s fra innsjekkingskøen" + +#: lib/index.tcl:326 +msgid "Ready to commit." +msgstr "Klar til innsjekking." + +#: lib/index.tcl:339 +#, tcl-format +msgid "Adding %s" +msgstr "Legger til %s" + +#: lib/index.tcl:396 +#, tcl-format +msgid "Revert changes in file %s?" +msgstr "Reverter endringene i filen %s?" + +#: lib/index.tcl:398 +#, tcl-format +msgid "Revert changes in these %i files?" +msgstr "Reverter endringene i disse %i filene?" + +#: lib/index.tcl:406 +msgid "Any unstaged changes will be permanently lost by the revert." +msgstr "Endringer som ikke ligger i innsjekkingskøen vil bli tapt av denne " +"reverteringen" + +#: lib/index.tcl:409 +msgid "Do Nothing" +msgstr "Ikke gjør noe" + +#: lib/index.tcl:427 +msgid "Reverting selected files" +msgstr "Reverterer valgte filer" + +#: lib/index.tcl:431 +#, tcl-format +msgid "Reverting %s" +msgstr "Reverterer %s" + +#: lib/merge.tcl:13 +msgid "" +"Cannot merge while amending.\n" +"\n" +"You must finish amending this commit before starting any type of merge.\n" +msgstr "" +"Kunne ikke slå sammen under utvidelse.\n" +"\n" +"Du må først fullføre utvidelsen av denne revisjonen før du kan starte en " +"sammenslåing.\n" + +#: lib/merge.tcl:27 +msgid "" +"Last scanned state does not match repository state.\n" +"\n" +"Another Git program has modified this repository since the last scan. A " +"rescan must be performed before a merge can be performed.\n" +"\n" +"The rescan will be automatically started now.\n" +msgstr "" + +#: lib/merge.tcl:45 +#, tcl-format +msgid "" +"You are in the middle of a conflicted merge.\n" +"\n" +"File %s has merge conflicts.\n" +"\n" +"You must resolve them, stage the file, and commit to complete the current " +"merge. Only then can you begin another merge.\n" +msgstr "" + +#: lib/merge.tcl:55 +#, tcl-format +msgid "" +"You are in the middle of a change.\n" +"\n" +"File %s is modified.\n" +"\n" +"You should complete the current commit before starting a merge. Doing so " +"will help you abort a failed merge, should the need arise.\n" +msgstr "" + +#: lib/merge.tcl:107 +#, tcl-format +msgid "%s of %s" +msgstr "%s av %s" + +#: lib/merge.tcl:120 +#, tcl-format +msgid "Merging %s and %s..." +msgstr "Slår sammen %s og %s" + +#: lib/merge.tcl:131 +msgid "Merge completed successfully." +msgstr "Vellykket sammenslåing fullført." + +#: lib/merge.tcl:133 +msgid "Merge failed. Conflict resolution is required." +msgstr "Sammenslåing feilet. Håndtering av konflikten kreves." + +#: lib/merge.tcl:158 +#, tcl-format +msgid "Merge Into %s" +msgstr "Slå sammen inn i %s" + +#: lib/merge.tcl:177 +msgid "Revision To Merge" +msgstr "Revisjon til sammenslåing" + +#: lib/merge.tcl:212 +msgid "" +"Cannot abort while amending.\n" +"\n" +"You must finish amending this commit.\n" +msgstr "" +"Kan ikke avbryte under utvidelse av revisjon.\n" +"\n" +"Du må fullføre utvidelsen av denne revisjonen.\n" + +#: lib/merge.tcl:222 +msgid "" +"Abort merge?\n" +"\n" +"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n" +"\n" +"Continue with aborting the current merge?" +msgstr "" +"Avbryt sammenslåing?\n" +"\n" +"Avbryting av pågående sammenslåing vil føre til at *alle* endringer som ikke " +" er sjekket inn, vil gå tapt.\n" +"\n" +"Fortsette med å avbryte den pågående sammenslåingen?" + +#: lib/merge.tcl:228 +msgid "" +"Reset changes?\n" +"\n" +"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n" +"\n" +"Continue with resetting the current changes?" +msgstr "" +"Nullstill endringer?\n" +"\n" +"Nullstilling av endringer vil føre til at *alle* endringer som ikke er " +"sjekket inn går tapt.\n" +"\n" +"Fortsette med nullstilling av endringer?" + +#: lib/merge.tcl:239 +msgid "Aborting" +msgstr "Avbryter" + +#: lib/merge.tcl:239 +msgid "files reset" +msgstr "filer tilbakestilt" + +#: lib/merge.tcl:267 +msgid "Abort failed." +msgstr "Avbryting feilet." + +#: lib/merge.tcl:269 +msgid "Abort completed. Ready." +msgstr "Avbryting fullført. Klar." + +#: lib/mergetool.tcl:8 +msgid "Force resolution to the base version?" +msgstr "Tving håndtering til opprinnelig versjon?" + +#: lib/mergetool.tcl:9 +msgid "Force resolution to this branch?" +msgstr "Tving håndtering i denne grenen?" + +#: lib/mergetool.tcl:10 +msgid "Force resolution to the other branch?" +msgstr "Tving håndtering i den andre grenen?" + +#: lib/mergetool.tcl:14 +#, tcl-format +msgid "" +"Note that the diff shows only conflicting changes.\n" +"\n" +"%s will be overwritten.\n" +"\n" +"This operation can be undone only by restarting the merge." +msgstr "" +"Merk deg at endringsvisningen kun viser motstridende endringer.\n" +"\n" +"%s vil bli overskrevet.\n" +"\n" +"Denne operasjonen kan kun bli angret ved å starte sammenslåingen på ny." + +#: lib/mergetool.tcl:45 +#, tcl-format +msgid "File %s seems to have unresolved conflicts, still stage?" +msgstr "Filen %s ser ut til å ha uløste konflikter, skal filen likevel køes?" + +#: lib/mergetool.tcl:60 +#, tcl-format +msgid "Adding resolution for %s" +msgstr "Legger til løsninge på konflikt for %s" + +#: lib/mergetool.tcl:141 +msgid "Cannot resolve deletion or link conflicts using a tool" +msgstr "" + +#: lib/mergetool.tcl:146 +msgid "Conflict file does not exist" +msgstr "Konfliktfil eksisterer ikke" + +#: lib/mergetool.tcl:264 +#, tcl-format +msgid "Not a GUI merge tool: '%s'" +msgstr "" + +#: lib/mergetool.tcl:268 +#, tcl-format +msgid "Unsupported merge tool '%s'" +msgstr "" + +#: lib/mergetool.tcl:303 +msgid "Merge tool is already running, terminate it?" +msgstr "" + +#: lib/mergetool.tcl:323 +#, tcl-format +msgid "" +"Error retrieving versions:\n" +"%s" +msgstr "" +"Kunne ikke hente versjoner:\n" +"%s" + +#: lib/mergetool.tcl:343 +#, tcl-format +msgid "" +"Could not start the merge tool:\n" +"\n" +"%s" +msgstr "" + +#: lib/mergetool.tcl:347 +msgid "Running merge tool..." +msgstr "" + +#: lib/mergetool.tcl:375 lib/mergetool.tcl:383 +msgid "Merge tool failed." +msgstr "" + +#: lib/option.tcl:11 +#, tcl-format +msgid "Invalid global encoding '%s'" +msgstr "" + +#: lib/option.tcl:19 +#, tcl-format +msgid "Invalid repo encoding '%s'" +msgstr "" + +#: lib/option.tcl:117 +msgid "Restore Defaults" +msgstr "Gjennopprett standardverdier" + +#: lib/option.tcl:121 +msgid "Save" +msgstr "Lagre" + +#: lib/option.tcl:131 +#, tcl-format +msgid "%s Repository" +msgstr "%s arkiv" + +#: lib/option.tcl:132 +msgid "Global (All Repositories)" +msgstr "Globalt (alle arkiv)" + +#: lib/option.tcl:138 +msgid "User Name" +msgstr "Navn" + +#: lib/option.tcl:139 +msgid "Email Address" +msgstr "Epost-adresse" + +#: lib/option.tcl:141 +msgid "Summarize Merge Commits" +msgstr "Oppsummer innsjekkinger fra sammenslåinger" + +#: lib/option.tcl:142 +msgid "Merge Verbosity" +msgstr "Detaljenivå på sammenslåing" + +#: lib/option.tcl:143 +msgid "Show Diffstat After Merge" +msgstr "Vis endringsstatistikk etter sammenslåing" + +#: lib/option.tcl:144 +msgid "Use Merge Tool" +msgstr "Bruk sammenslåingsverktøy" + +#: lib/option.tcl:146 +msgid "Trust File Modification Timestamps" +msgstr "Stol på filers tid for endring" + +#: lib/option.tcl:147 +msgid "Prune Tracking Branches During Fetch" +msgstr "" + +#: lib/option.tcl:148 +msgid "Match Tracking Branches" +msgstr "" + +#: lib/option.tcl:149 +msgid "Blame Copy Only On Changed Files" +msgstr "" + +#: lib/option.tcl:150 +msgid "Minimum Letters To Blame Copy On" +msgstr "" + +#: lib/option.tcl:151 +msgid "Blame History Context Radius (days)" +msgstr "" + +#: lib/option.tcl:152 +msgid "Number of Diff Context Lines" +msgstr "Antall linjer sammenhengende endringer" + +#: lib/option.tcl:153 +msgid "Commit Message Text Width" +msgstr "Tekstbredde for vindu til innsjekkingsmeldinger" + +#: lib/option.tcl:154 +msgid "New Branch Name Template" +msgstr "Mal for navn på nye grener" + +#: lib/option.tcl:155 +msgid "Default File Contents Encoding" +msgstr "Standard tekstenkoding for innhold i filer" + +#: lib/option.tcl:203 +msgid "Change" +msgstr "Endre" + +#: lib/option.tcl:230 +msgid "Spelling Dictionary:" +msgstr "Stavebokordlister:" + +#: lib/option.tcl:254 +msgid "Change Font" +msgstr "Endre skrifttype" + +#: lib/option.tcl:258 +#, tcl-format +msgid "Choose %s" +msgstr "Velg %s" + +#: lib/option.tcl:264 +msgid "pt." +msgstr "pt." + +#: lib/option.tcl:278 +msgid "Preferences" +msgstr "Egenskaper" + +#: lib/option.tcl:314 +msgid "Failed to completely save options:" +msgstr "Kunne ikke lagre alternativ:" + +#: lib/remote.tcl:163 +msgid "Remove Remote" +msgstr "Fjern fjernarkiv" + +#: lib/remote.tcl:168 +msgid "Prune from" +msgstr "Fjern fra" + +#: lib/remote.tcl:173 +msgid "Fetch from" +msgstr "Hent fra" + +#: lib/remote.tcl:215 +msgid "Push to" +msgstr "Send til" + +#: lib/remote_add.tcl:19 +msgid "Add Remote" +msgstr "Legg til fjernarkiv" + +#: lib/remote_add.tcl:24 +msgid "Add New Remote" +msgstr "Legg til nytt fjernarkiv" + +#: lib/remote_add.tcl:28 lib/tools_dlg.tcl:36 +msgid "Add" +msgstr "Legg til" + +#: lib/remote_add.tcl:37 +msgid "Remote Details" +msgstr "Detaljer for fjernarkiv" + +#: lib/remote_add.tcl:50 +msgid "Location:" +msgstr "Lokasjon:" + +#: lib/remote_add.tcl:62 +msgid "Further Action" +msgstr "Videre handling" + +#: lib/remote_add.tcl:65 +msgid "Fetch Immediately" +msgstr "Hent umiddelbart" + +#: lib/remote_add.tcl:71 +msgid "Initialize Remote Repository and Push" +msgstr "Initsialiser og send til fjernarkiv" + +#: lib/remote_add.tcl:77 +msgid "Do Nothing Else Now" +msgstr "Ikke gjør mer nå" + +#: lib/remote_add.tcl:101 +msgid "Please supply a remote name." +msgstr "Vennligst angi et navn for fjernarkivet." + +#: lib/remote_add.tcl:114 +#, tcl-format +msgid "'%s' is not an acceptable remote name." +msgstr "'%s' er ikke et tillatt navn for et fjernarkiv." + +#: lib/remote_add.tcl:125 +#, tcl-format +msgid "Failed to add remote '%s' of location '%s'." +msgstr "Kunne ikke legge til fjernarkivet '%s' på '%s'." + +#: lib/remote_add.tcl:133 lib/transport.tcl:6 +#, tcl-format +msgid "fetch %s" +msgstr "hent %s" + +#: lib/remote_add.tcl:134 +#, tcl-format +msgid "Fetching the %s" +msgstr "Henter %s" + +#: lib/remote_add.tcl:157 +#, tcl-format +msgid "Do not know how to initialize repository at location '%s'." +msgstr "Vet ikke hvordan arkiv på '%s' skal opprettes." + +#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:71 +#, tcl-format +msgid "push %s" +msgstr "send %s" + +#: lib/remote_add.tcl:164 +#, tcl-format +msgid "Setting up the %s (at %s)" +msgstr "Initsialiserer %s (på %s)" + +#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34 +msgid "Delete Branch Remotely" +msgstr "Fjern gren fra fjernarkiv" + +#: lib/remote_branch_delete.tcl:47 +msgid "From Repository" +msgstr "Fra arkiv" + +#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123 +msgid "Remote:" +msgstr "Fjernarkiv:" + +#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138 +msgid "Arbitrary Location:" +msgstr "Vilkårlig lokasjon:" + +#: lib/remote_branch_delete.tcl:84 +msgid "Branches" +msgstr "Grener" + +#: lib/remote_branch_delete.tcl:109 +msgid "Delete Only If" +msgstr "Slett kun hvis" + +#: lib/remote_branch_delete.tcl:111 +msgid "Merged Into:" +msgstr "Slått sammen i:" + +#: lib/remote_branch_delete.tcl:119 +msgid "Always (Do not perform merge checks)" +msgstr "Alltid (Ikke utfør sammenslåingskontroll)" + +#: lib/remote_branch_delete.tcl:152 +msgid "A branch is required for 'Merged Into'." +msgstr "En gren kreves for 'sammenslåing i'." + +#: lib/remote_branch_delete.tcl:184 +#, tcl-format +msgid "" +"The following branches are not completely merged into %s:\n" +"\n" +" - %s" +msgstr "" +"Følgende grener er ikke fullestendig sammenslått med %s:\n" +"\n" +" - %s" + +#: lib/remote_branch_delete.tcl:189 +#, tcl-format +msgid "" +"One or more of the merge tests failed because you have not fetched the " +"necessary commits. Try fetching from %s first." +msgstr "" +"En eller flere av testene som blir kjørt under sammenslåing feilet fordi du" +"ikke har hentet inn de nødvendige innsjekkingene. Prøv å hent disse fra %s" +"først" + +#: lib/remote_branch_delete.tcl:207 +msgid "Please select one or more branches to delete." +msgstr "Velg en eller flere grener som skal fjernes." + +#: lib/remote_branch_delete.tcl:216 +msgid "" +"Recovering deleted branches is difficult.\n" +"\n" +"Delete the selected branches?" +msgstr "" +"Gjenoppretting av fjernede grener er vanskelig.\n" +"\n" +"Fjern den merkede grenen?" + +#: lib/remote_branch_delete.tcl:226 +#, tcl-format +msgid "Deleting branches from %s" +msgstr "Fjerner grenene fra %s" + +#: lib/remote_branch_delete.tcl:286 +msgid "No repository selected." +msgstr "Ingen arkiv valgt." + +#: lib/remote_branch_delete.tcl:291 +#, tcl-format +msgid "Scanning %s..." +msgstr "Søker %s..." + +#: lib/search.tcl:21 +msgid "Find:" +msgstr "Finn:" + +#: lib/search.tcl:23 +msgid "Next" +msgstr "Neste" + +#: lib/search.tcl:24 +msgid "Prev" +msgstr "Forrige" + +#: lib/search.tcl:25 +msgid "Case-Sensitive" +msgstr "Skiller på store og små bokstaver" + +#: lib/shortcut.tcl:20 lib/shortcut.tcl:61 +msgid "Cannot write shortcut:" +msgstr "Kan ikke opprette snarvei:" + +#: lib/shortcut.tcl:136 +msgid "Cannot write icon:" +msgstr "Kan ikke opprette ikon:" + +#: lib/spellcheck.tcl:57 +msgid "Unsupported spell checker" +msgstr "Stavekontrolleren er ikke støttet" + +#: lib/spellcheck.tcl:65 +msgid "Spell checking is unavailable" +msgstr "Stavekontroll er ikke tilgjengelig" + +#: lib/spellcheck.tcl:68 +msgid "Invalid spell checking configuration" +msgstr "Ugyldig stavekontroll-konfigurasjon" + +#: lib/spellcheck.tcl:70 +#, tcl-format +msgid "Reverting dictionary to %s." +msgstr "Reverterer ordbok til %s." + +#: lib/spellcheck.tcl:73 +msgid "Spell checker silently failed on startup" +msgstr "Stavekontrollen feilet stille under oppstart" + +#: lib/spellcheck.tcl:80 +msgid "Unrecognized spell checker" +msgstr "Stavekontrolleren er ukjent" + +#: lib/spellcheck.tcl:186 +msgid "No Suggestions" +msgstr "Ingen forslag" + +#: lib/spellcheck.tcl:388 +msgid "Unexpected EOF from spell checker" +msgstr "Uventet slutt på filen fra stavekontrollen" + +#: lib/spellcheck.tcl:392 +msgid "Spell Checker Failed" +msgstr "Stavekontroll mislyktes" + +#: lib/sshkey.tcl:31 +msgid "No keys found." +msgstr "Ingen nøkler funnet." + +#: lib/sshkey.tcl:34 +#, tcl-format +msgid "Found a public key in: %s" +msgstr "Funnet en offentlig nøkkel i: %s" + +#: lib/sshkey.tcl:40 +msgid "Generate Key" +msgstr "Generer nøkkel" + +#: lib/sshkey.tcl:56 +msgid "Copy To Clipboard" +msgstr "Kopier til utklippstavlen" + +#: lib/sshkey.tcl:70 +msgid "Your OpenSSH Public Key" +msgstr "Din offentlige OpenSSH-nøkkel" + +#: lib/sshkey.tcl:78 +msgid "Generating..." +msgstr "Genererer..." + +#: lib/sshkey.tcl:84 +#, tcl-format +msgid "" +"Could not start ssh-keygen:\n" +"\n" +"%s" +msgstr "" +"Kunne ikke starte ssh-keygen:\n" +"\n" +"%s" + +#: lib/sshkey.tcl:111 +msgid "Generation failed." +msgstr "Generering feilet." + +#: lib/sshkey.tcl:118 +msgid "Generation succeded, but no keys found." +msgstr "Generering vellykket, men ingen nøkler er funnet." + +#: lib/sshkey.tcl:121 +#, tcl-format +msgid "Your key is in: %s" +msgstr "Nøkkelen din ligger i: %s" + +#: lib/status_bar.tcl:83 +#, tcl-format +msgid "%s ... %*i of %*i %s (%3i%%)" +msgstr "%s ... %*i av %*i %s (%3i%%)" + +#: lib/tools.tcl:75 +#, tcl-format +msgid "Running %s requires a selected file." +msgstr "Å kjøre %s krever at en fil er valgt" + +#: lib/tools.tcl:90 +#, tcl-format +msgid "Are you sure you want to run %s?" +msgstr "Er du sikker på at du vil kjøre %s?" + +#: lib/tools.tcl:110 +#, tcl-format +msgid "Tool: %s" +msgstr "Verktøy: %s" + +#: lib/tools.tcl:111 +#, tcl-format +msgid "Running: %s" +msgstr "Kjører: %s" + +#: lib/tools.tcl:149 +#, tcl-format +msgid "Tool completed succesfully: %s" +msgstr "Verktøyet ble fullført med suksess: %s" + +#: lib/tools.tcl:151 +#, tcl-format +msgid "Tool failed: %s" +msgstr "Verktøy feilet: %s" + +#: lib/tools_dlg.tcl:22 +msgid "Add Tool" +msgstr "Legg til verktøy" + +#: lib/tools_dlg.tcl:28 +msgid "Add New Tool Command" +msgstr "Legg til ny verktøykommando" + +#: lib/tools_dlg.tcl:33 +msgid "Add globally" +msgstr "Legg til globalt" + +#: lib/tools_dlg.tcl:45 +msgid "Tool Details" +msgstr "Verktøydetaljer" + +#: lib/tools_dlg.tcl:48 +msgid "Use '/' separators to create a submenu tree:" +msgstr "Bruk '/'-separator for å lage undermenyer:" + +#: lib/tools_dlg.tcl:61 +msgid "Command:" +msgstr "Kommando:" + +#: lib/tools_dlg.tcl:74 +msgid "Show a dialog before running" +msgstr "Vis en dialog før start" + +#: lib/tools_dlg.tcl:80 +msgid "Ask the user to select a revision (sets $REVISION)" +msgstr "Spør brukeren om å velge en revisjon (setter $REVISION)" + +#: lib/tools_dlg.tcl:85 +msgid "Ask the user for additional arguments (sets $ARGS)" +msgstr "Spør brukeren for ytterligere paramtere (setter $ARGS)" + +#: lib/tools_dlg.tcl:92 +msgid "Don't show the command output window" +msgstr "Ikke vis kommandoens utdata i vinduet" + +#: lib/tools_dlg.tcl:97 +msgid "Run only if a diff is selected ($FILENAME not empty)" +msgstr "Kjør kun om forskjellene er markert ($FILENAME er ikke tom)" + +#: lib/tools_dlg.tcl:121 +msgid "Please supply a name for the tool." +msgstr "Vennligst angi et navn for dette verktøyet." + +#: lib/tools_dlg.tcl:129 +#, tcl-format +msgid "Tool '%s' already exists." +msgstr "Verktøyet '%s' eksisterer allerede." + +#: lib/tools_dlg.tcl:151 +#, tcl-format +msgid "" +"Could not add tool:\n" +"%s" +msgstr "" +"Kunne ikke legge til verktøyet:\n" +"%s" + +#: lib/tools_dlg.tcl:190 +msgid "Remove Tool" +msgstr "Fjern verktøyet" + +#: lib/tools_dlg.tcl:196 +msgid "Remove Tool Commands" +msgstr "Fjern verktøyskommandoen" + +#: lib/tools_dlg.tcl:200 +msgid "Remove" +msgstr "Fjern" + +#: lib/tools_dlg.tcl:236 +msgid "(Blue denotes repository-local tools)" +msgstr "(Blue angir lokale verktøy til arkivet)" + +#: lib/tools_dlg.tcl:297 +#, tcl-format +msgid "Run Command: %s" +msgstr "Kjør kommando: %s" + +#: lib/tools_dlg.tcl:311 +msgid "Arguments" +msgstr "Argumenter" + +#: lib/tools_dlg.tcl:348 +msgid "OK" +msgstr "OK" + +#: lib/transport.tcl:7 +#, tcl-format +msgid "Fetching new changes from %s" +msgstr "Henter nye endringer fra %s" + +#: lib/transport.tcl:18 +#, tcl-format +msgid "remote prune %s" +msgstr "slett fjernarkiv %s" + +#: lib/transport.tcl:19 +#, tcl-format +msgid "Pruning tracking branches deleted from %s" +msgstr "Fjrner sporing av grener slettet fra %s" + +#: lib/transport.tcl:26 +#, tcl-format +msgid "Pushing changes to %s" +msgstr "Sender endringer til %s" + +#: lib/transport.tcl:72 +#, tcl-format +msgid "Pushing %s %s to %s" +msgstr "Sender %s %s til %s" + +#: lib/transport.tcl:89 +msgid "Push Branches" +msgstr "Send grener" + +#: lib/transport.tcl:103 +msgid "Source Branches" +msgstr "Kildegrener" + +#: lib/transport.tcl:120 +msgid "Destination Repository" +msgstr "Destinasjonsarkiv" + +#: lib/transport.tcl:158 +msgid "Transfer Options" +msgstr "Overføringsalternativer" + +#: lib/transport.tcl:160 +msgid "Force overwrite existing branch (may discard changes)" +msgstr "Tving overskrivning av eksisterende gren (kan forkaste endringer)" + +#: lib/transport.tcl:164 +msgid "Use thin pack (for slow network connections)" +msgstr "Bruk tynne pakker (for tregere nettverkstilkoblinger)" + +#: lib/transport.tcl:168 +msgid "Include tags" +msgstr "Inkluder tagger" diff --git a/git-gui/po/sv.po b/git-gui/po/sv.po index d434220b13..167654c709 100644 --- a/git-gui/po/sv.po +++ b/git-gui/po/sv.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: sv\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-11-16 13:56-0800\n" -"PO-Revision-Date: 2008-11-21 08:35+0100\n" +"POT-Creation-Date: 2008-12-08 08:31-0800\n" +"PO-Revision-Date: 2008-12-10 09:49+0100\n" "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" "MIME-Version: 1.0\n" @@ -87,11 +87,15 @@ msgstr "Söker efter ändrade filer..." #: git-gui.sh:1367 msgid "Calling prepare-commit-msg hook..." -msgstr "Anropar kroken för förberedning av incheckningsmeddelande (prepare-commit-msg)..." +msgstr "" +"Anropar kroken för förberedelse av incheckningsmeddelande (prepare-commit-" +"msg)..." #: git-gui.sh:1384 msgid "Commit declined by prepare-commit-msg hook." -msgstr "Incheckningen avvisades av kroken för förberedning av incheckningsmeddelande (prepare-commit-msg)." +msgstr "" +"Incheckningen avvisades av kroken för förberedelse av incheckningsmeddelande " +"(prepare-commit-msg)." #: git-gui.sh:1542 lib/browser.tcl:246 msgid "Ready." @@ -241,25 +245,25 @@ msgstr "Ångra" msgid "Redo" msgstr "Gör om" -#: git-gui.sh:2378 git-gui.sh:2923 +#: git-gui.sh:2378 git-gui.sh:2937 msgid "Cut" msgstr "Klipp ut" -#: git-gui.sh:2381 git-gui.sh:2926 git-gui.sh:3000 git-gui.sh:3082 +#: git-gui.sh:2381 git-gui.sh:2940 git-gui.sh:3014 git-gui.sh:3096 #: lib/console.tcl:69 msgid "Copy" msgstr "Kopiera" -#: git-gui.sh:2384 git-gui.sh:2929 +#: git-gui.sh:2384 git-gui.sh:2943 msgid "Paste" msgstr "Klistra in" -#: git-gui.sh:2387 git-gui.sh:2932 lib/branch_delete.tcl:26 +#: git-gui.sh:2387 git-gui.sh:2946 lib/branch_delete.tcl:26 #: lib/remote_branch_delete.tcl:38 msgid "Delete" msgstr "Ta bort" -#: git-gui.sh:2391 git-gui.sh:2936 git-gui.sh:3086 lib/console.tcl:71 +#: git-gui.sh:2391 git-gui.sh:2950 git-gui.sh:3100 lib/console.tcl:71 msgid "Select All" msgstr "Markera alla" @@ -291,15 +295,15 @@ msgstr "Färdig" msgid "Commit@@verb" msgstr "Checka in" -#: git-gui.sh:2443 git-gui.sh:2864 +#: git-gui.sh:2443 git-gui.sh:2878 msgid "New Commit" msgstr "Ny incheckning" -#: git-gui.sh:2451 git-gui.sh:2871 +#: git-gui.sh:2451 git-gui.sh:2885 msgid "Amend Last Commit" msgstr "Lägg till föregående incheckning" -#: git-gui.sh:2461 git-gui.sh:2825 lib/remote_branch_delete.tcl:99 +#: git-gui.sh:2461 git-gui.sh:2839 lib/remote_branch_delete.tcl:99 msgid "Rescan" msgstr "Sök på nytt" @@ -319,15 +323,15 @@ msgstr "Ta bort från incheckningskö" msgid "Revert Changes" msgstr "Återställ ändringar" -#: git-gui.sh:2491 git-gui.sh:3069 +#: git-gui.sh:2491 git-gui.sh:3083 msgid "Show Less Context" msgstr "Visa mindre sammanhang" -#: git-gui.sh:2495 git-gui.sh:3073 +#: git-gui.sh:2495 git-gui.sh:3087 msgid "Show More Context" msgstr "Visa mer sammanhang" -#: git-gui.sh:2502 git-gui.sh:2838 git-gui.sh:2947 +#: git-gui.sh:2502 git-gui.sh:2852 git-gui.sh:2961 msgid "Sign Off" msgstr "Skriv under" @@ -361,7 +365,7 @@ msgstr "Om %s" msgid "Preferences..." msgstr "Inställningar..." -#: git-gui.sh:2565 git-gui.sh:3115 +#: git-gui.sh:2565 git-gui.sh:3129 msgid "Options..." msgstr "Alternativ..." @@ -381,125 +385,125 @@ msgstr "Webbdokumentation" msgid "Show SSH Key" msgstr "Visa SSH-nyckel" -#: git-gui.sh:2707 +#: git-gui.sh:2721 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" msgstr "" "ödesdigert: kunde inte ta status på sökvägen %s: Fil eller katalog saknas" -#: git-gui.sh:2740 +#: git-gui.sh:2754 msgid "Current Branch:" msgstr "Aktuell gren:" -#: git-gui.sh:2761 +#: git-gui.sh:2775 msgid "Staged Changes (Will Commit)" msgstr "Köade ändringar (kommer att checkas in)" -#: git-gui.sh:2781 +#: git-gui.sh:2795 msgid "Unstaged Changes" msgstr "Oköade ändringar" -#: git-gui.sh:2831 +#: git-gui.sh:2845 msgid "Stage Changed" msgstr "Köa ändrade" -#: git-gui.sh:2850 lib/transport.tcl:93 lib/transport.tcl:182 +#: git-gui.sh:2864 lib/transport.tcl:104 lib/transport.tcl:193 msgid "Push" msgstr "Sänd" -#: git-gui.sh:2885 +#: git-gui.sh:2899 msgid "Initial Commit Message:" msgstr "Inledande incheckningsmeddelande:" -#: git-gui.sh:2886 +#: git-gui.sh:2900 msgid "Amended Commit Message:" msgstr "Utökat incheckningsmeddelande:" -#: git-gui.sh:2887 +#: git-gui.sh:2901 msgid "Amended Initial Commit Message:" msgstr "Utökat inledande incheckningsmeddelande:" -#: git-gui.sh:2888 +#: git-gui.sh:2902 msgid "Amended Merge Commit Message:" msgstr "Utökat incheckningsmeddelande för sammanslagning:" -#: git-gui.sh:2889 +#: git-gui.sh:2903 msgid "Merge Commit Message:" msgstr "Incheckningsmeddelande för sammanslagning:" -#: git-gui.sh:2890 +#: git-gui.sh:2904 msgid "Commit Message:" msgstr "Incheckningsmeddelande:" -#: git-gui.sh:2939 git-gui.sh:3090 lib/console.tcl:73 +#: git-gui.sh:2953 git-gui.sh:3104 lib/console.tcl:73 msgid "Copy All" msgstr "Kopiera alla" -#: git-gui.sh:2963 lib/blame.tcl:104 +#: git-gui.sh:2977 lib/blame.tcl:104 msgid "File:" msgstr "Fil:" -#: git-gui.sh:3078 +#: git-gui.sh:3092 msgid "Refresh" msgstr "Uppdatera" -#: git-gui.sh:3099 +#: git-gui.sh:3113 msgid "Decrease Font Size" msgstr "Minska teckensnittsstorlek" -#: git-gui.sh:3103 +#: git-gui.sh:3117 msgid "Increase Font Size" msgstr "Öka teckensnittsstorlek" -#: git-gui.sh:3111 lib/blame.tcl:281 +#: git-gui.sh:3125 lib/blame.tcl:281 msgid "Encoding" msgstr "Teckenkodning" -#: git-gui.sh:3122 +#: git-gui.sh:3136 msgid "Apply/Reverse Hunk" msgstr "Använd/återställ del" -#: git-gui.sh:3127 +#: git-gui.sh:3141 msgid "Apply/Reverse Line" msgstr "Använd/återställ rad" -#: git-gui.sh:3137 +#: git-gui.sh:3151 msgid "Run Merge Tool" msgstr "Starta verktyg för sammanslagning" -#: git-gui.sh:3142 +#: git-gui.sh:3156 msgid "Use Remote Version" msgstr "Använd versionen från fjärrarkivet" -#: git-gui.sh:3146 +#: git-gui.sh:3160 msgid "Use Local Version" msgstr "Använd lokala versionen" -#: git-gui.sh:3150 +#: git-gui.sh:3164 msgid "Revert To Base" msgstr "Återställ till basversionen" -#: git-gui.sh:3169 +#: git-gui.sh:3183 msgid "Unstage Hunk From Commit" msgstr "Ta bort del ur incheckningskö" -#: git-gui.sh:3170 +#: git-gui.sh:3184 msgid "Unstage Line From Commit" msgstr "Ta bort rad ur incheckningskö" -#: git-gui.sh:3172 +#: git-gui.sh:3186 msgid "Stage Hunk For Commit" msgstr "Ställ del i incheckningskö" -#: git-gui.sh:3173 +#: git-gui.sh:3187 msgid "Stage Line For Commit" msgstr "Ställ rad i incheckningskö" -#: git-gui.sh:3196 +#: git-gui.sh:3210 msgid "Initializing..." msgstr "Initierar..." -#: git-gui.sh:3301 +#: git-gui.sh:3315 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -516,7 +520,7 @@ msgstr "" "av %s:\n" "\n" -#: git-gui.sh:3331 +#: git-gui.sh:3345 msgid "" "\n" "This is due to a known issue with the\n" @@ -526,7 +530,7 @@ msgstr "" "Detta beror på ett känt problem med\n" "Tcl-binären som följer med Cygwin." -#: git-gui.sh:3336 +#: git-gui.sh:3350 #, tcl-format msgid "" "\n" @@ -612,43 +616,43 @@ msgstr "Kör grundlig kopieringsigenkänning..." msgid "Loading annotation..." msgstr "Läser in annotering..." -#: lib/blame.tcl:964 +#: lib/blame.tcl:963 msgid "Author:" msgstr "Författare:" -#: lib/blame.tcl:968 +#: lib/blame.tcl:967 msgid "Committer:" msgstr "Incheckare:" -#: lib/blame.tcl:973 +#: lib/blame.tcl:972 msgid "Original File:" msgstr "Ursprunglig fil:" -#: lib/blame.tcl:1021 +#: lib/blame.tcl:1020 msgid "Cannot find HEAD commit:" msgstr "Hittar inte incheckning för HEAD:" -#: lib/blame.tcl:1076 +#: lib/blame.tcl:1075 msgid "Cannot find parent commit:" msgstr "Hittar inte föräldraincheckning:" -#: lib/blame.tcl:1091 +#: lib/blame.tcl:1090 msgid "Unable to display parent" msgstr "Kan inte visa förälder" -#: lib/blame.tcl:1092 lib/diff.tcl:297 +#: lib/blame.tcl:1091 lib/diff.tcl:297 msgid "Error loading diff:" msgstr "Fel vid inläsning av differens:" -#: lib/blame.tcl:1232 +#: lib/blame.tcl:1231 msgid "Originally By:" msgstr "Ursprungligen av:" -#: lib/blame.tcl:1238 +#: lib/blame.tcl:1237 msgid "In File:" msgstr "I filen:" -#: lib/blame.tcl:1243 +#: lib/blame.tcl:1242 msgid "Copied Or Moved Here By:" msgstr "Kopierad eller flyttad hit av:" @@ -665,7 +669,7 @@ msgstr "Checka ut" #: lib/checkout_op.tcl:544 lib/choose_font.tcl:43 lib/merge.tcl:172 #: lib/option.tcl:125 lib/remote_add.tcl:32 lib/remote_branch_delete.tcl:42 #: lib/tools_dlg.tcl:40 lib/tools_dlg.tcl:204 lib/tools_dlg.tcl:352 -#: lib/transport.tcl:97 +#: lib/transport.tcl:108 msgid "Cancel" msgstr "Avbryt" @@ -1314,19 +1318,19 @@ msgstr "" "utöka tidigare incheckningar om du inte först avbryter den pågående " "sammanslagningen.\n" -#: lib/commit.tcl:49 +#: lib/commit.tcl:48 msgid "Error loading commit data for amend:" msgstr "Fel vid inläsning av incheckningsdata för utökning:" -#: lib/commit.tcl:76 +#: lib/commit.tcl:75 msgid "Unable to obtain your identity:" msgstr "Kunde inte hämta din identitet:" -#: lib/commit.tcl:81 +#: lib/commit.tcl:80 msgid "Invalid GIT_COMMITTER_IDENT:" msgstr "Felaktig GIT_COMMITTER_IDENT:" -#: lib/commit.tcl:133 +#: lib/commit.tcl:132 msgid "" "Last scanned state does not match repository state.\n" "\n" @@ -1342,7 +1346,7 @@ msgstr "" "\n" "Sökningen kommer att startas automatiskt nu.\n" -#: lib/commit.tcl:156 +#: lib/commit.tcl:155 #, tcl-format msgid "" "Unmerged files cannot be committed.\n" @@ -1355,7 +1359,7 @@ msgstr "" "Filen %s har sammanslagningskonflikter. Du måste lösa dem och köa filen " "innan du checkar in den.\n" -#: lib/commit.tcl:164 +#: lib/commit.tcl:163 #, tcl-format msgid "" "Unknown file state %s detected.\n" @@ -1366,7 +1370,7 @@ msgstr "" "\n" "Filen %s kan inte checkas in av programmet.\n" -#: lib/commit.tcl:172 +#: lib/commit.tcl:171 msgid "" "No changes to commit.\n" "\n" @@ -1376,7 +1380,7 @@ msgstr "" "\n" "Du måste köa åtminstone en fil innan du kan checka in.\n" -#: lib/commit.tcl:187 +#: lib/commit.tcl:186 msgid "" "Please supply a commit message.\n" "\n" @@ -1394,45 +1398,45 @@ msgstr "" "- Andra raden: Tom\n" "- Följande rader: Beskriv varför det här är en bra ändring.\n" -#: lib/commit.tcl:211 +#: lib/commit.tcl:210 #, tcl-format msgid "warning: Tcl does not support encoding '%s'." msgstr "varning: Tcl stöder inte teckenkodningen \"%s\"." -#: lib/commit.tcl:227 +#: lib/commit.tcl:226 msgid "Calling pre-commit hook..." msgstr "Anropar kroken före incheckning (pre-commit)..." -#: lib/commit.tcl:242 +#: lib/commit.tcl:241 msgid "Commit declined by pre-commit hook." msgstr "Incheckningen avvisades av kroken före incheckning (pre-commit)." -#: lib/commit.tcl:265 +#: lib/commit.tcl:264 msgid "Calling commit-msg hook..." msgstr "Anropar kroken för incheckningsmeddelande (commit-msg)..." -#: lib/commit.tcl:280 +#: lib/commit.tcl:279 msgid "Commit declined by commit-msg hook." msgstr "Incheckning avvisad av kroken för incheckningsmeddelande (commit-msg)." -#: lib/commit.tcl:293 +#: lib/commit.tcl:292 msgid "Committing changes..." msgstr "Checkar in ändringar..." -#: lib/commit.tcl:309 +#: lib/commit.tcl:308 msgid "write-tree failed:" msgstr "write-tree misslyckades:" -#: lib/commit.tcl:310 lib/commit.tcl:354 lib/commit.tcl:374 +#: lib/commit.tcl:309 lib/commit.tcl:353 lib/commit.tcl:373 msgid "Commit failed." msgstr "Incheckningen misslyckades." -#: lib/commit.tcl:327 +#: lib/commit.tcl:326 #, tcl-format msgid "Commit %s appears to be corrupt" msgstr "Incheckningen %s verkar vara trasig" -#: lib/commit.tcl:332 +#: lib/commit.tcl:331 msgid "" "No changes to commit.\n" "\n" @@ -1446,19 +1450,19 @@ msgstr "" "\n" "En sökning kommer att startas automatiskt nu.\n" -#: lib/commit.tcl:339 +#: lib/commit.tcl:338 msgid "No changes to commit." msgstr "Inga ändringar att checka in." -#: lib/commit.tcl:353 +#: lib/commit.tcl:352 msgid "commit-tree failed:" msgstr "commit-tree misslyckades:" -#: lib/commit.tcl:373 +#: lib/commit.tcl:372 msgid "update-ref failed:" msgstr "update-ref misslyckades:" -#: lib/commit.tcl:461 +#: lib/commit.tcl:460 #, tcl-format msgid "Created commit %s: %s" msgstr "Skapade incheckningen %s: %s" @@ -1565,14 +1569,16 @@ msgstr "Läser differens för %s..." msgid "" "LOCAL: deleted\n" "REMOTE:\n" -msgstr "LOKAL: borttagen\n" +msgstr "" +"LOKAL: borttagen\n" "FJÄRR:\n" #: lib/diff.tcl:125 msgid "" "REMOTE: deleted\n" "LOCAL:\n" -msgstr "FJÄRR: borttagen\n" +msgstr "" +"FJÄRR: borttagen\n" "LOKAL:\n" #: lib/diff.tcl:132 @@ -1605,7 +1611,8 @@ msgstr "* Binärfil (visar inte innehållet)." msgid "" "* Untracked file is %d bytes.\n" "* Showing only first %d bytes.\n" -msgstr "* Den ospårade filen är %d byte.\n" +msgstr "" +"* Den ospårade filen är %d byte.\n" "* Visar endast inledande %d byte.\n" #: lib/diff.tcl:228 @@ -1935,7 +1942,8 @@ msgstr "Verktyget för sammanslagning körs redan. Vill du avsluta det?" msgid "" "Error retrieving versions:\n" "%s" -msgstr "Fel vid hämtning av versioner:\n" +msgstr "" +"Fel vid hämtning av versioner:\n" "%s" #: lib/mergetool.tcl:343 @@ -1944,7 +1952,8 @@ msgid "" "Could not start the merge tool:\n" "\n" "%s" -msgstr "Kunde inte starta verktyg för sammanslagning:\n" +msgstr "" +"Kunde inte starta verktyg för sammanslagning:\n" "\n" "%s" @@ -2157,7 +2166,8 @@ msgstr "Hämtar %s" msgid "Do not know how to initialize repository at location '%s'." msgstr "Vet inte hur arkivet på platsen \"%s\" skall initieras." -#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:71 +#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:63 +#: lib/transport.tcl:81 #, tcl-format msgid "push %s" msgstr "sänd %s" @@ -2175,11 +2185,11 @@ msgstr "Ta bort gren från fjärrarkiv" msgid "From Repository" msgstr "Från arkiv" -#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123 +#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:134 msgid "Remote:" msgstr "Fjärrarkiv:" -#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138 +#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:149 msgid "Arbitrary Location:" msgstr "Godtycklig plats:" @@ -2343,7 +2353,8 @@ msgid "" "Could not start ssh-keygen:\n" "\n" "%s" -msgstr "Kunde inte starta ssh-keygen:\n" +msgstr "" +"Kunde inte starta ssh-keygen:\n" "\n" "%s" @@ -2388,7 +2399,7 @@ msgstr "Exekverar: %s" #: lib/tools.tcl:149 #, tcl-format msgid "Tool completed succesfully: %s" -msgstr "Verktyget avslutades framgångsrikt." +msgstr "Verktyget avslutades framgångsrikt: %s" #: lib/tools.tcl:151 #, tcl-format @@ -2453,7 +2464,8 @@ msgstr "Verktyget \"%s\" finns redan." msgid "" "Could not add tool:\n" "%s" -msgstr "Kunde inte lägga till verktyget:\n" +msgstr "" +"Kunde inte lägga till verktyget:\n" "%s" #: lib/tools_dlg.tcl:190 @@ -2505,36 +2517,41 @@ msgstr "Tar bort spårande grenar som tagits bort från %s" msgid "Pushing changes to %s" msgstr "Sänder ändringar till %s" -#: lib/transport.tcl:72 +#: lib/transport.tcl:64 +#, tcl-format +msgid "Mirroring to %s" +msgstr "Speglar till %s" + +#: lib/transport.tcl:82 #, tcl-format msgid "Pushing %s %s to %s" msgstr "Sänder %s %s till %s" -#: lib/transport.tcl:89 +#: lib/transport.tcl:100 msgid "Push Branches" msgstr "Sänd grenar" -#: lib/transport.tcl:103 +#: lib/transport.tcl:114 msgid "Source Branches" msgstr "Källgrenar" -#: lib/transport.tcl:120 +#: lib/transport.tcl:131 msgid "Destination Repository" msgstr "Destinationsarkiv" -#: lib/transport.tcl:158 +#: lib/transport.tcl:169 msgid "Transfer Options" msgstr "Överföringsalternativ" -#: lib/transport.tcl:160 +#: lib/transport.tcl:171 msgid "Force overwrite existing branch (may discard changes)" msgstr "Tvinga överskrivning av befintlig gren (kan kasta bort ändringar)" -#: lib/transport.tcl:164 +#: lib/transport.tcl:175 msgid "Use thin pack (for slow network connections)" msgstr "Använd tunt paket (för långsamma nätverksanslutningar)" -#: lib/transport.tcl:168 +#: lib/transport.tcl:179 msgid "Include tags" msgstr "Ta med taggar" diff --git a/git-mergetool.sh b/git-mergetool.sh index 94187c306c..d4078a6aff 100755 --- a/git-mergetool.sh +++ b/git-mergetool.sh @@ -296,6 +296,7 @@ do esac ;; --) + shift break ;; -*) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 1172e47571..1ceb57ae83 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -115,9 +115,18 @@ mark_action_done () { } make_patch () { - parent_sha1=$(git rev-parse --verify "$1"^) || - die "Cannot get patch for $1^" - git diff-tree -p "$parent_sha1".."$1" > "$DOTEST"/patch + sha1_and_parents="$(git rev-list --parents -1 "$1")" + case "$sha1_and_parents" in + ?*' '?*' '?*) + git diff --cc $sha1_and_parents + ;; + ?*' '?*) + git diff-tree -p "$1^!" + ;; + *) + echo "Root commit" + ;; + esac > "$DOTEST"/patch test -f "$DOTEST"/message || git cat-file commit "$1" | sed "1,/^$/d" > "$DOTEST"/message test -f "$DOTEST"/author-script || @@ -256,9 +265,8 @@ pick_one_preserving_merges () { output git merge $STRATEGY -m "$msg" \ $new_parents then - git rerere printf "%s\n" "$msg" > "$GIT_DIR"/MERGE_MSG - die Error redoing merge $sha1 + die_with_patch $sha1 "Error redoing merge $sha1" fi ;; *) @@ -341,7 +349,7 @@ do_next () { squash|s) comment_for_reflog squash - has_action "$DONE" || + test -f "$DONE" && has_action "$DONE" || die "Cannot 'squash' without a previous commit" mark_action_done @@ -352,17 +360,15 @@ do_next () { pick_one -n $sha1 || failed=t case "$(peek_next_command)" in squash|s) - EDIT_COMMIT= USE_OUTPUT=output MSG_OPT=-F - MSG_FILE="$MSG" + EDIT_OR_FILE="$MSG" cp "$MSG" "$SQUASH_MSG" ;; *) - EDIT_COMMIT=-e USE_OUTPUT= MSG_OPT= - MSG_FILE= + EDIT_OR_FILE=-e rm -f "$SQUASH_MSG" || exit cp "$MSG" "$GIT_DIR"/SQUASH_MSG rm -f "$GIT_DIR"/MERGE_MSG || exit @@ -376,7 +382,8 @@ do_next () { GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \ GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \ GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" \ - $USE_OUTPUT git commit --no-verify $MSG_OPT "$MSG_FILE" $EDIT_COMMIT || failed=t + $USE_OUTPUT git commit --no-verify \ + $MSG_OPT "$EDIT_OR_FILE" || failed=t fi if test $failed = t then diff --git a/git-repack.sh b/git-repack.sh index 458a497af8..00c597e97c 100755 --- a/git-repack.sh +++ b/git-repack.sh @@ -88,32 +88,79 @@ if [ -z "$names" ]; then echo Nothing new to pack. fi fi -for name in $names ; do - fullbases="$fullbases pack-$name" - chmod a-w "$PACKTMP-$name.pack" - chmod a-w "$PACKTMP-$name.idx" - mkdir -p "$PACKDIR" || exit +# Ok we have prepared all new packfiles. +mkdir -p "$PACKDIR" || exit + +# First see if there are packs of the same name and if so +# if we can move them out of the way (this can happen if we +# repacked immediately after packing fully. +rollback= +failed= +for name in $names +do for sfx in pack idx do - if test -f "$PACKDIR/pack-$name.$sfx" - then - mv -f "$PACKDIR/pack-$name.$sfx" \ - "$PACKDIR/old-pack-$name.$sfx" - fi - done && + file=pack-$name.$sfx + test -f "$PACKDIR/$file" || continue + rm -f "$PACKDIR/old-$file" && + mv "$PACKDIR/$file" "$PACKDIR/old-$file" || { + failed=t + break + } + rollback="$rollback $file" + done + test -z "$failed" || break +done + +# If renaming failed for any of them, roll the ones we have +# already renamed back to their original names. +if test -n "$failed" +then + rollback_failure= + for file in $rollback + do + mv "$PACKDIR/old-$file" "$PACKDIR/$file" || + rollback_failure="$rollback_failure $file" + done + if test -n "$rollback_failure" + then + echo >&2 "WARNING: Some packs in use have been renamed by" + echo >&2 "WARNING: prefixing old- to their name, in order to" + echo >&2 "WARNING: replace them with the new version of the" + echo >&2 "WARNING: file. But the operation failed, and" + echo >&2 "WARNING: attempt to rename them back to their" + echo >&2 "WARNING: original names also failed." + echo >&2 "WARNING: Please rename them in $PACKDIR manually:" + for file in $rollback_failure + do + echo >&2 "WARNING: old-$file -> $file" + done + fi + exit 1 +fi + +# Now the ones with the same name are out of the way... +fullbases= +for name in $names +do + fullbases="$fullbases pack-$name" + chmod a-w "$PACKTMP-$name.pack" + chmod a-w "$PACKTMP-$name.idx" mv -f "$PACKTMP-$name.pack" "$PACKDIR/pack-$name.pack" && - mv -f "$PACKTMP-$name.idx" "$PACKDIR/pack-$name.idx" && - test -f "$PACKDIR/pack-$name.pack" && - test -f "$PACKDIR/pack-$name.idx" || { - echo >&2 "Couldn't replace the existing pack with updated one." - echo >&2 "The original set of packs have been saved as" - echo >&2 "old-pack-$name.{pack,idx} in $PACKDIR." - exit 1 - } - rm -f "$PACKDIR/old-pack-$name.pack" "$PACKDIR/old-pack-$name.idx" + mv -f "$PACKTMP-$name.idx" "$PACKDIR/pack-$name.idx" || + exit +done + +# Remove the "old-" files +for name in $names +do + rm -f "$PACKDIR/old-pack-$name.idx" + rm -f "$PACKDIR/old-pack-$name.pack" done +# End of pack replacement. + if test "$remove_redundant" = t then # We know $existing are all redundant. @@ -134,5 +181,5 @@ fi case "$no_update_info" in t) : ;; -*) git-update-server-info ;; +*) git update-server-info ;; esac diff --git a/git-send-email.perl b/git-send-email.perl index 3112f769cd..77ca8fe880 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -20,6 +20,7 @@ use strict; use warnings; use Term::ReadLine; use Getopt::Long; +use Text::ParseWords; use Data::Dumper; use Term::ANSIColor; use File::Temp qw/ tempdir /; @@ -359,6 +360,10 @@ foreach my $entry (@bcclist) { die "Comma in --bcclist entry: $entry'\n" unless $entry !~ m/,/; } +sub split_addrs { + return quotewords('\s*,\s*', 1, @_); +} + my %aliases; my %parse_alias = ( # multiline formats can be supported in the future @@ -367,7 +372,7 @@ my %parse_alias = ( my ($alias, $addr) = ($1, $2); $addr =~ s/#.*$//; # mutt allows # comments # commas delimit multiple addresses - $aliases{$alias} = [ split(/\s*,\s*/, $addr) ]; + $aliases{$alias} = [ split_addrs($addr) ]; }}}, mailrc => sub { my $fh = shift; while (<$fh>) { if (/^alias\s+(\S+)\s+(.*)$/) { @@ -379,7 +384,7 @@ my %parse_alias = ( chomp $x; $x .= $1 while(defined($_ = <$fh>) && /^ +(.*)$/); $x =~ /^(\S+)$f\t\(?([^\t]+?)\)?(:?$f){0,2}$/ or next; - $aliases{$1} = [ split(/\s*,\s*/, $2) ]; + $aliases{$1} = [ split_addrs($2) ]; }}, gnus => sub { my $fh = shift; while (<$fh>) { if (/\(define-mail-alias\s+"(\S+?)"\s+"(\S+?)"\)/) { @@ -588,7 +593,7 @@ if (!@to) { } my $to = $_; - push @to, split /,\s*/, $to; + push @to, split_addrs($to); $prompting++; } diff --git a/git-sh-setup.sh b/git-sh-setup.sh index dbdf209ec0..2142308bcc 100755 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -85,8 +85,27 @@ cd_to_toplevel () { cdup=$(git rev-parse --show-cdup) if test ! -z "$cdup" then - cd "$cdup" || { - echo >&2 "Cannot chdir to $cdup, the toplevel of the working tree" + case "$cdup" in + /*) + # Not quite the same as if we did "cd -P '$cdup'" when + # $cdup contains ".." after symlink path components. + # Don't fix that case at least until Git switches to + # "cd -P" across the board. + phys="$cdup" + ;; + ..|../*|*/..|*/../*) + # Interpret $cdup relative to the physical, not logical, cwd. + # Probably /bin/pwd is more portable than passing -P to cd or pwd. + phys="$(unset PWD; /bin/pwd)/$cdup" + ;; + *) + # There's no "..", so no need to make things absolute. + phys="$cdup" + ;; + esac + + cd "$phys" || { + echo >&2 "Cannot chdir to $phys, the toplevel of the working tree" exit 1 } fi diff --git a/git-svn.perl b/git-svn.perl index 2c206e9178..ad01e182df 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -5015,8 +5015,7 @@ sub minimize_connections { } } if (@emptied) { - my $file = $ENV{GIT_CONFIG} || $ENV{GIT_CONFIG_LOCAL} || - "$ENV{GIT_DIR}/config"; + my $file = $ENV{GIT_CONFIG} || "$ENV{GIT_DIR}/config"; print STDERR <<EOF; The following [svn-remote] sections in your config file ($file) are empty and can be safely removed: @@ -2,6 +2,7 @@ #include "exec_cmd.h" #include "cache.h" #include "quote.h" +#include "run-command.h" const char git_usage_string[] = "git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]"; @@ -219,7 +220,7 @@ struct cmd_struct { int option; }; -static int run_command(struct cmd_struct *p, int argc, const char **argv) +static int run_builtin(struct cmd_struct *p, int argc, const char **argv) { int status; struct stat st; @@ -384,7 +385,7 @@ static void handle_internal_command(int argc, const char **argv) struct cmd_struct *p = commands+i; if (strcmp(p->cmd, cmd)) continue; - exit(run_command(p, argc, argv)); + exit(run_builtin(p, argc, argv)); } } @@ -392,6 +393,7 @@ static void execv_dashed_external(const char **argv) { struct strbuf cmd = STRBUF_INIT; const char *tmp; + int status; strbuf_addf(&cmd, "git-%s", argv[0]); @@ -406,10 +408,17 @@ static void execv_dashed_external(const char **argv) trace_argv_printf(argv, "trace: exec:"); - /* execvp() can only ever return if it fails */ - execvp(cmd.buf, (char **)argv); - - trace_printf("trace: exec failed: %s\n", strerror(errno)); + /* + * if we fail because the command is not found, it is + * OK to return. Otherwise, we just pass along the status code. + */ + status = run_command_v_opt(argv, 0); + if (status != -ERR_RUN_COMMAND_EXEC) { + if (IS_RUN_COMMAND_ERR(status)) + die("unable to run '%s'", argv[0]); + exit(-status); + } + errno = ENOENT; /* as if we called execvp */ argv[0] = tmp; diff --git a/git.spec.in b/git.spec.in index 069ace050d..4be0834f0b 100644 --- a/git.spec.in +++ b/git.spec.in @@ -97,7 +97,7 @@ BuildRequires: perl(Error) %description -n perl-Git Perl interface to Git -%define path_settings ETC_GITCONFIG=/etc/gitconfig prefix=%{_prefix} mandir=%{_mandir} htmldir=%{_docdir}/%{name}-core-%{version} +%define path_settings ETC_GITCONFIG=/etc/gitconfig prefix=%{_prefix} mandir=%{_mandir} htmldir=%{_docdir}/%{name}-%{version} %prep %setup -q @@ -190,6 +190,9 @@ rm -rf $RPM_BUILD_ROOT # No files for you! %changelog +* Mon Feb 04 2009 David J. Mellor <dmellor@whistlingcat.com> +- fixed broken git help -w after renaming the git-core package to git. + * Fri Sep 12 2008 Quy Tonthat <qtonthat@gmail.com> - move git-cvsserver to bindir. diff --git a/gitk-git/gitk b/gitk-git/gitk index 64a873d2ef..dc2a439618 100644 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -1601,13 +1601,14 @@ proc parsecommit {id contents listed} { set header [string range $contents 0 [expr {$hdrend - 1}]] set comment [string range $contents [expr {$hdrend + 2}] end] foreach line [split $header "\n"] { + set line [split $line " "] set tag [lindex $line 0] if {$tag == "author"} { set audate [lindex $line end-1] - set auname [lrange $line 1 end-2] + set auname [join [lrange $line 1 end-2] " "] } elseif {$tag == "committer"} { set comdate [lindex $line end-1] - set comname [lrange $line 1 end-2] + set comname [join [lrange $line 1 end-2] " "] } } set headline {} @@ -2279,7 +2280,7 @@ proc makewindow {} { bindkey b prevfile bindkey d "$ctext yview scroll 18 units" bindkey u "$ctext yview scroll -18 units" - bindkey / {dofind 1 1} + bindkey / {focus $fstring} bindkey <Key-Return> {dofind 1 1} bindkey ? {dofind -1 1} bindkey f nextfile @@ -2660,7 +2661,7 @@ proc keys {} { [mc "<%s-F> Find" $M1T] [mc "<%s-G> Move to next find hit" $M1T] [mc "<Return> Move to next find hit"] -[mc "/ Move to next find hit, or redo find"] +[mc "/ Focus the search box"] [mc "? Move to previous find hit"] [mc "f Scroll diff view to next file"] [mc "<%s-S> Search for next hit in diff view" $M1T] @@ -3318,8 +3319,27 @@ proc index_sha1 {fname} { return {} } +# Turn an absolute path into one relative to the current directory +proc make_relative {f} { + set elts [file split $f] + set here [file split [pwd]] + set ei 0 + set hi 0 + set res {} + foreach d $here { + if {$ei < $hi || $ei >= [llength $elts] || [lindex $elts $ei] ne $d} { + lappend res ".." + } else { + incr ei + } + incr hi + } + set elts [concat $res [lrange $elts $ei end]] + return [eval file join $elts] +} + proc external_blame {parent_idx {line {}}} { - global flist_menu_file + global flist_menu_file gitdir global nullid nullid2 global parentlist selectedline currentid @@ -3338,7 +3358,12 @@ proc external_blame {parent_idx {line {}}} { if {$line ne {} && $line > 1} { lappend cmdline "--line=$line" } - lappend cmdline $base_commit $flist_menu_file + set f [file join [file dirname $gitdir] $flist_menu_file] + # Unfortunately it seems git gui blame doesn't like + # being given an absolute path... + set f [make_relative $f] + lappend cmdline $base_commit $f + puts "cmdline={$cmdline}" if {[catch {eval exec $cmdline &} err]} { error_popup "[mc "git gui blame: command failed:"] $err" } @@ -3382,6 +3407,8 @@ proc show_line_source {} { error_popup [mc "Error reading index: %s" $err] return } + } else { + set id $parents($curview,$currentid) } } else { set id [lindex $parents($curview,$currentid) $pi] @@ -3398,7 +3425,7 @@ proc show_line_source {} { } else { lappend blameargs $id } - lappend blameargs -- $flist_menu_file + lappend blameargs -- [file join [file dirname $gitdir] $flist_menu_file] if {[catch { set f [open $blameargs r] } err]} { @@ -7953,7 +7980,7 @@ proc rowmenu {x y id} { if {$id ne $nullid && $id ne $nullid2} { set menu $rowctxmenu if {$mainhead ne {}} { - $menu entryconfigure 7 -label [mc "Reset %s branch to here" $mainhead] + $menu entryconfigure 7 -label [mc "Reset %s branch to here" $mainhead] -state normal } else { $menu entryconfigure 7 -label [mc "Detached head: can't reset" $mainhead] -state disabled } @@ -10079,15 +10106,11 @@ proc doprefs {} { -font optionfont spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct grid x $top.maxpctl $top.maxpct -sticky w - frame $top.showlocal - label $top.showlocal.l -text [mc "Show local changes"] -font optionfont - checkbutton $top.showlocal.b -variable showlocalchanges - pack $top.showlocal.b $top.showlocal.l -side left + checkbutton $top.showlocal -text [mc "Show local changes"] \ + -font optionfont -variable showlocalchanges grid x $top.showlocal -sticky w - frame $top.autoselect - label $top.autoselect.l -text [mc "Auto-select SHA1"] -font optionfont - checkbutton $top.autoselect.b -variable autoselect - pack $top.autoselect.b $top.autoselect.l -side left + checkbutton $top.autoselect -text [mc "Auto-select SHA1"] \ + -font optionfont -variable autoselect grid x $top.autoselect -sticky w label $top.ddisp -text [mc "Diff display options"] @@ -10095,20 +10118,14 @@ proc doprefs {} { label $top.tabstopl -text [mc "Tab spacing"] -font optionfont spinbox $top.tabstop -from 1 -to 20 -width 4 -textvariable tabstop grid x $top.tabstopl $top.tabstop -sticky w - frame $top.ntag - label $top.ntag.l -text [mc "Display nearby tags"] -font optionfont - checkbutton $top.ntag.b -variable showneartags - pack $top.ntag.b $top.ntag.l -side left + checkbutton $top.ntag -text [mc "Display nearby tags"] \ + -font optionfont -variable showneartags grid x $top.ntag -sticky w - frame $top.ldiff - label $top.ldiff.l -text [mc "Limit diffs to listed paths"] -font optionfont - checkbutton $top.ldiff.b -variable limitdiffs - pack $top.ldiff.b $top.ldiff.l -side left + checkbutton $top.ldiff -text [mc "Limit diffs to listed paths"] \ + -font optionfont -variable limitdiffs grid x $top.ldiff -sticky w - frame $top.lattr - label $top.lattr.l -text [mc "Support per-file encodings"] -font optionfont - checkbutton $top.lattr.b -variable perfile_attrs - pack $top.lattr.b $top.lattr.l -side left + checkbutton $top.lattr -text [mc "Support per-file encodings"] \ + -font optionfont -variable perfile_attrs grid x $top.lattr -sticky w entry $top.extdifft -textvariable extdifftool @@ -10124,26 +10141,26 @@ proc doprefs {} { grid $top.cdisp - -sticky w -pady 10 label $top.bg -padx 40 -relief sunk -background $bgcolor button $top.bgbut -text [mc "Background"] -font optionfont \ - -command [list choosecolor bgcolor {} $top.bg background setbg] + -command [list choosecolor bgcolor {} $top.bg [mc "background"] setbg] grid x $top.bgbut $top.bg -sticky w label $top.fg -padx 40 -relief sunk -background $fgcolor button $top.fgbut -text [mc "Foreground"] -font optionfont \ - -command [list choosecolor fgcolor {} $top.fg foreground setfg] + -command [list choosecolor fgcolor {} $top.fg [mc "foreground"] setfg] grid x $top.fgbut $top.fg -sticky w label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0] button $top.diffoldbut -text [mc "Diff: old lines"] -font optionfont \ - -command [list choosecolor diffcolors 0 $top.diffold "diff old lines" \ + -command [list choosecolor diffcolors 0 $top.diffold [mc "diff old lines"] \ [list $ctext tag conf d0 -foreground]] grid x $top.diffoldbut $top.diffold -sticky w label $top.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1] button $top.diffnewbut -text [mc "Diff: new lines"] -font optionfont \ - -command [list choosecolor diffcolors 1 $top.diffnew "diff new lines" \ + -command [list choosecolor diffcolors 1 $top.diffnew [mc "diff new lines"] \ [list $ctext tag conf dresult -foreground]] grid x $top.diffnewbut $top.diffnew -sticky w label $top.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2] button $top.hunksepbut -text [mc "Diff: hunk header"] -font optionfont \ -command [list choosecolor diffcolors 2 $top.hunksep \ - "diff hunk header" \ + [mc "diff hunk header"] \ [list $ctext tag conf hunksep -foreground]] grid x $top.hunksepbut $top.hunksep -sticky w label $top.markbgsep -padx 40 -relief sunk -background $markbgcolor @@ -10154,7 +10171,7 @@ proc doprefs {} { grid x $top.markbgbut $top.markbgsep -sticky w label $top.selbgsep -padx 40 -relief sunk -background $selectbgcolor button $top.selbgbut -text [mc "Select bg"] -font optionfont \ - -command [list choosecolor selectbgcolor {} $top.selbgsep background setselbg] + -command [list choosecolor selectbgcolor {} $top.selbgsep [mc "background"] setselbg] grid x $top.selbgbut $top.selbgsep -sticky w label $top.cfont -text [mc "Fonts: press to choose"] @@ -10897,4 +10914,9 @@ if {[info exists permviews]} { addviewmenu $n } } + +if {[tk windowingsystem] eq "win32"} { + focus -force . +} + getcommits {} diff --git a/gitk-git/po/de.po b/gitk-git/po/de.po index e0a6deeded..825dc98f74 100644 --- a/gitk-git/po/de.po +++ b/gitk-git/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: git-gui\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-10-25 13:18+0200\n" -"PO-Revision-Date: 2008-10-25 13:23+0200\n" +"POT-Creation-Date: 2008-12-06 20:40+0100\n" +"PO-Revision-Date: 2008-12-06 20:45+0100\n" "Last-Translator: Christian Stimming <stimming@tuhh.de>\n" "Language-Team: German\n" "MIME-Version: 1.0\n" @@ -90,7 +90,11 @@ msgstr "Zweige neu laden" msgid "List references" msgstr "Zweige/Markierungen auflisten" -#: gitk:1815 +#: gitk:1915 +msgid "Start git gui" +msgstr "»git gui« starten" + +#: gitk:1917 msgid "Quit" msgstr "Beenden" @@ -295,7 +299,15 @@ msgstr "Externer Vergleich" msgid "Blame parent commit" msgstr "Annotieren der Elternversion" -#: gitk:2488 +#: gitk:2360 +msgid "Show origin of this line" +msgstr "Herkunft dieser Zeile anzeigen" + +#: gitk:2361 +msgid "Run git gui blame on this line" +msgstr "Annotieren (»git gui blame«) von dieser Zeile" + +#: gitk:2606 msgid "" "\n" "Gitk - a commit viewer for git\n" @@ -501,7 +513,38 @@ msgstr "Version nicht gefunden" msgid "git gui blame: command failed:" msgstr "git gui blame: Kommando fehlgeschlagen:" -#: gitk:3092 +#: gitk:3398 +#, tcl-format +msgid "Couldn't read merge head: %s" +msgstr "Zusammenführungs-Spitze konnte nicht gelesen werden: %s" + +#: gitk:3406 +#, tcl-format +msgid "Error reading index: %s" +msgstr "Fehler beim Lesen der Bereitstellung (»index«): %s" + +#: gitk:3431 +#, tcl-format +msgid "Couldn't start git blame: %s" +msgstr "»git blame« konnte nicht gestartet werden: %s" + +#: gitk:3434 gitk:6160 +msgid "Searching" +msgstr "Suchen" + +#: gitk:3466 +#, tcl-format +msgid "Error running git blame: %s" +msgstr "Fehler beim Ausführen von »git blame«: %s" + +#: gitk:3494 +#, tcl-format +msgid "That line comes from commit %s, which is not in this view" +msgstr "" +"Diese Zeile stammt aus Version %s, welche nicht in dieser Ansicht gezeigt " +"wird." + +#: gitk:3508 msgid "External diff viewer failed:" msgstr "Externes Vergleich-(Diff-)Programm fehlgeschlagen:" @@ -509,11 +552,7 @@ msgstr "Externes Vergleich-(Diff-)Programm fehlgeschlagen:" msgid "Gitk view definition" msgstr "Gitk Ansichten" -#: gitk:3225 -msgid "Name" -msgstr "Name" - -#: gitk:3228 +#: gitk:3630 msgid "Remember this view" msgstr "Diese Ansicht speichern" @@ -521,15 +560,55 @@ msgstr "Diese Ansicht speichern" msgid "Commits to include (arguments to git log):" msgstr "Versionen anzeigen (Argumente von git-log):" -#: gitk:3239 +#: gitk:3632 +msgid "Use all refs" +msgstr "Alle Zweige verwenden" + +#: gitk:3633 +msgid "Strictly sort by date" +msgstr "Streng nach Datum sortieren" + +#: gitk:3634 +msgid "Mark branch sides" +msgstr "Zweig-Seiten markieren" + +#: gitk:3635 +msgid "Since date:" +msgstr "Von Datum:" + +#: gitk:3636 +msgid "Until date:" +msgstr "Bis Datum:" + +#: gitk:3637 +msgid "Max count:" +msgstr "Max. Anzahl:" + +#: gitk:3638 +msgid "Skip:" +msgstr "Überspringen:" + +#: gitk:3639 +msgid "Limit to first parent" +msgstr "Auf erste Elternversion beschränken" + +#: gitk:3640 msgid "Command to generate more commits to include:" msgstr "Versionsliste durch folgendes Kommando erzeugen lassen:" -#: gitk:3246 +#: gitk:3749 +msgid "Name" +msgstr "Name" + +#: gitk:3797 msgid "Enter files and directories to include, one per line:" msgstr "Folgende Dateien und Verzeichnisse anzeigen (eine pro Zeile):" -#: gitk:3293 +#: gitk:3811 +msgid "Apply (F5)" +msgstr "Anwenden (F5)" + +#: gitk:3849 msgid "Error in commit selection arguments:" msgstr "Fehler in den ausgewählten Versionen:" @@ -569,11 +648,7 @@ msgstr "Lokale Änderungen bereitgestellt, aber nicht eingetragen" msgid "Local uncommitted changes, not checked in to index" msgstr "Lokale Änderungen, nicht bereitgestellt" -#: gitk:5549 -msgid "Searching" -msgstr "Suchen" - -#: gitk:6049 +#: gitk:6673 msgid "Tags:" msgstr "Markierungen:" @@ -597,11 +672,12 @@ msgstr "Folgt auf" msgid "Precedes" msgstr "Vorgänger von" -#: gitk:6378 -msgid "Error getting merge diffs:" -msgstr "Fehler beim Laden des Vergleichs:" +#: gitk:7209 +#, tcl-format +msgid "Error getting diffs: %s" +msgstr "Fehler beim Laden des Vergleichs: %s" -#: gitk:7113 +#: gitk:7748 msgid "Goto:" msgstr "Gehe zu:" @@ -722,7 +798,12 @@ msgstr "Name:" msgid "Please specify a name for the new branch" msgstr "Bitte geben Sie einen Namen für den neuen Zweig an." -#: gitk:7703 +#: gitk:8328 +#, tcl-format +msgid "Branch '%s' already exists. Overwrite?" +msgstr "Zweig »%s« existiert bereits. Soll er überschrieben werden?" + +#: gitk:8394 #, tcl-format msgid "Commit %s is already included in branch %s -- really re-apply it?" msgstr "" @@ -733,7 +814,26 @@ msgstr "" msgid "Cherry-picking" msgstr "Version pflücken" -#: gitk:7720 +#: gitk:8408 +#, 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 "" +"Pflücken 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:8414 +msgid "" +"Cherry-pick 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" +"ist. Soll das »git citool« (Zusammenführungs-Werkzeug) aufgerufen\n" +"werden, um diesen Konflikt aufzulösen?" + +#: gitk:8430 msgid "No changes committed" msgstr "Keine Änderungen eingetragen" @@ -889,23 +989,51 @@ msgstr "Farben: Klicken zum Wählen" msgid "Background" msgstr "Hintergrund" -#: gitk:9435 +#: gitk:10153 gitk:10183 +msgid "background" +msgstr "Hintergrund" + +#: gitk:10156 msgid "Foreground" msgstr "Vordergrund" -#: gitk:9439 +#: gitk:10157 +msgid "foreground" +msgstr "Vordergrund" + +#: gitk:10160 msgid "Diff: old lines" msgstr "Vergleich: Alte Zeilen" -#: gitk:9444 +#: gitk:10161 +msgid "diff old lines" +msgstr "Vergleich - Alte Zeilen" + +#: gitk:10165 msgid "Diff: new lines" msgstr "Vergleich: Neue Zeilen" -#: gitk:9449 +#: gitk:10166 +msgid "diff new lines" +msgstr "Vergleich - Neue Zeilen" + +#: gitk:10170 msgid "Diff: hunk header" msgstr "Vergleich: Änderungstitel" -#: gitk:9455 +#: gitk:10172 +msgid "diff hunk header" +msgstr "Vergleich - Änderungstitel" + +#: gitk:10176 +msgid "Marked line bg" +msgstr "Markierte Zeile Hintergrund" + +#: gitk:10178 +msgid "marked line background" +msgstr "markierte Zeile Hintergrund" + +#: gitk:10182 msgid "Select bg" msgstr "Hintergrundfarbe Auswählen" diff --git a/gitweb/README b/gitweb/README index 825162a0b6..19ae28ef9b 100644 --- a/gitweb/README +++ b/gitweb/README @@ -214,6 +214,11 @@ not include variables usually directly set during build): Rename detection options for git-diff and git-diff-tree. By default ('-M'); set it to ('-C') or ('-C', '-C') to also detect copies, or set it to () if you don't want to have renames detection. + * $prevent_xss + If true, some gitweb features are disabled to prevent content in + repositories from launching cross-site scripting (XSS) attacks. Set this + to true if you don't trust the content of your repositories. The default + is false. Projects list file format @@ -260,7 +265,9 @@ You can use the following files in repository: A .html file (HTML fragment) which is included on the gitweb project summary page inside <div> block element. You can use it for longer description of a project, to provide links (for example to project's - homepage), etc. + homepage), etc. This is recognized only if XSS prevention is off + ($prevent_xss is false); a way to include a readme safely when XSS + prevention is on may be worked out in the future. * description (or gitweb.description) Short (shortened by default to 25 characters in the projects list page) single line description of a project (of a repository). Plain text file; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 6eb370d8de..bdaa4e9463 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -132,6 +132,10 @@ our $fallback_encoding = 'latin1'; # - one might want to include '-B' option, e.g. '-B', '-M' our @diff_opts = ('-M'); # taken from git_commit +# Disables features that would allow repository owners to inject script into +# the gitweb domain. +our $prevent_xss = 0; + # information about snapshot formats that gitweb is capable of serving our %known_snapshot_formats = ( # name => { @@ -2147,8 +2151,9 @@ sub git_get_projects_list { my $subdir = substr($File::Find::name, $pfxlen + 1); # we check related file in $projectroot - if (check_export_ok("$projectroot/$filter/$subdir")) { - push @list, { path => ($filter ? "$filter/" : '') . $subdir }; + my $path = ($filter ? "$filter/" : '') . $subdir; + if (check_export_ok("$projectroot/$path")) { + push @list, { path => $path }; $File::Find::prune = 1; } }, @@ -4493,7 +4498,9 @@ sub git_summary { print "</table>\n"; - if (-s "$projectroot/$project/README.html") { + # If XSS prevention is on, we don't include README.html. + # TODO: Allow a readme in some safe format. + if (!$prevent_xss && -s "$projectroot/$project/README.html") { print "<div class=\"title\">readme</div>\n" . "<div class=\"readme\">\n"; insert_file("$projectroot/$project/README.html"); @@ -4738,10 +4745,21 @@ sub git_blob_plain { $save_as .= '.txt'; } + # With XSS prevention on, blobs of all types except a few known safe + # ones are served with "Content-Disposition: attachment" to make sure + # they don't run in our security domain. For certain image types, + # blob view writes an <img> tag referring to blob_plain view, and we + # want to be sure not to break that by serving the image as an + # attachment (though Firefox 3 doesn't seem to care). + my $sandbox = $prevent_xss && + $type !~ m!^(?:text/plain|image/(?:gif|png|jpeg))$!; + print $cgi->header( -type => $type, -expires => $expires, - -content_disposition => 'inline; filename="' . $save_as . '"'); + -content_disposition => + ($sandbox ? 'attachment' : 'inline') + . '; filename="' . $save_as . '"'); undef $/; binmode STDOUT, ':raw'; print <$fd>; @@ -5285,43 +5303,9 @@ sub git_blobdiff { or die_error(500, "Open git-diff-tree failed"); } - # old/legacy style URI - if (!%diffinfo && # if new style URI failed - defined $hash && defined $hash_parent) { - # fake git-diff-tree raw output - $diffinfo{'from_mode'} = $diffinfo{'to_mode'} = "blob"; - $diffinfo{'from_id'} = $hash_parent; - $diffinfo{'to_id'} = $hash; - if (defined $file_name) { - if (defined $file_parent) { - $diffinfo{'status'} = '2'; - $diffinfo{'from_file'} = $file_parent; - $diffinfo{'to_file'} = $file_name; - } else { # assume not renamed - $diffinfo{'status'} = '1'; - $diffinfo{'from_file'} = $file_name; - $diffinfo{'to_file'} = $file_name; - } - } else { # no filename given - $diffinfo{'status'} = '2'; - $diffinfo{'from_file'} = $hash_parent; - $diffinfo{'to_file'} = $hash; - } - - # non-textual hash id's can be cached - if ($hash =~ m/^[0-9a-fA-F]{40}$/ && - $hash_parent =~ m/^[0-9a-fA-F]{40}$/) { - $expires = '+1d'; - } - - # open patch output - open $fd, "-|", git_cmd(), "diff", @diff_opts, - '-p', ($format eq 'html' ? "--full-index" : ()), - $hash_parent, $hash, "--" - or die_error(500, "Open git-diff failed"); - } else { - die_error(400, "Missing one of the blob diff parameters") - unless %diffinfo; + # old/legacy style URI -- not generated anymore since 1.4.3. + if (!%diffinfo) { + die_error('404 Not Found', "Missing one of the blob diff parameters") } # header diff --git a/hash-object.c b/hash-object.c index 846e91a231..adfd5336a3 100644 --- a/hash-object.c +++ b/hash-object.c @@ -81,8 +81,6 @@ int main(int argc, const char **argv) type = blob_type; - git_config(git_default_config, NULL); - argc = parse_options(argc, argv, hash_object_options, hash_object_usage, 0); if (write_object) { @@ -92,6 +90,8 @@ int main(int argc, const char **argv) vpath = prefix_filename(prefix, prefix_length, vpath); } + git_config(git_default_config, NULL); + if (stdin_paths) { if (hashstdin) errstr = "Can't use --stdin-paths with --stdin"; diff --git a/http-push.c b/http-push.c index 5cecef434a..cb5bf95a73 100644 --- a/http-push.c +++ b/http-push.c @@ -87,6 +87,7 @@ static struct object_list *objects; struct repo { char *url; + char *path; int path_len; int has_info_refs; int can_update_info_refs; @@ -208,7 +209,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb, do { request->stream.next_out = expn; request->stream.avail_out = sizeof(expn); - request->zret = inflate(&request->stream, Z_SYNC_FLUSH); + request->zret = git_inflate(&request->stream, Z_SYNC_FLUSH); git_SHA1_Update(&request->c, expn, sizeof(expn) - request->stream.avail_out); } while (request->stream.avail_in && request->zret == Z_OK); @@ -268,7 +269,7 @@ static void start_fetch_loose(struct transfer_request *request) memset(&request->stream, 0, sizeof(request->stream)); - inflateInit(&request->stream); + git_inflate_init(&request->stream); git_SHA1_Init(&request->c); @@ -309,7 +310,7 @@ static void start_fetch_loose(struct transfer_request *request) file; also rewind to the beginning of the local file. */ if (prev_read == -1) { memset(&request->stream, 0, sizeof(request->stream)); - inflateInit(&request->stream); + git_inflate_init(&request->stream); git_SHA1_Init(&request->c); if (prev_posn>0) { prev_posn = 0; @@ -595,7 +596,7 @@ static int refresh_lock(struct remote_lock *lock) lock->refreshing = 1; if_header = xmalloc(strlen(lock->token) + 25); - sprintf(if_header, "If: (<opaquelocktoken:%s>)", lock->token); + sprintf(if_header, "If: (<%s>)", lock->token); sprintf(timeout_header, "Timeout: Second-%ld", lock->timeout); dav_headers = curl_slist_append(dav_headers, if_header); dav_headers = curl_slist_append(dav_headers, timeout_header); @@ -741,7 +742,7 @@ static void finish_request(struct transfer_request *request) if (request->http_code == 416) fprintf(stderr, "Warning: requested range invalid; we may already have all the data.\n"); - inflateEnd(&request->stream); + git_inflate_end(&request->stream); git_SHA1_Final(request->real_sha1, &request->c); if (request->zret != Z_STREAM_END) { unlink(request->tmpfile); @@ -1120,10 +1121,8 @@ static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed) lock->timeout = strtol(ctx->cdata + 7, NULL, 10); } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) { - if (!prefixcmp(ctx->cdata, "opaquelocktoken:")) { - lock->token = xmalloc(strlen(ctx->cdata) - 15); - strcpy(lock->token, ctx->cdata + 16); - } + lock->token = xmalloc(strlen(ctx->cdata) + 1); + strcpy(lock->token, ctx->cdata); } } } @@ -1202,7 +1201,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout) /* Make sure leading directories exist for the remote ref */ ep = strchr(url + strlen(remote->url) + 1, '/'); while (ep) { - *ep = 0; + char saved_character = ep[1]; + ep[1] = '\0'; slot = get_active_slot(); slot->results = &results; curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); @@ -1224,7 +1224,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout) free(url); return NULL; } - *ep = '/'; + ep[1] = saved_character; ep = strchr(ep + 1, '/'); } @@ -1308,7 +1308,7 @@ static int unlock_remote(struct remote_lock *lock) int rc = 0; lock_token_header = xmalloc(strlen(lock->token) + 31); - sprintf(lock_token_header, "Lock-Token: <opaquelocktoken:%s>", + sprintf(lock_token_header, "Lock-Token: <%s>", lock->token); dav_headers = curl_slist_append(dav_headers, lock_token_header); @@ -1426,9 +1426,17 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed) ls->userFunc(ls); } } else if (!strcmp(ctx->name, DAV_PROPFIND_NAME) && ctx->cdata) { - ls->dentry_name = xmalloc(strlen(ctx->cdata) - - remote->path_len + 1); - strcpy(ls->dentry_name, ctx->cdata + remote->path_len); + char *path = ctx->cdata; + if (*ctx->cdata == 'h') { + path = strstr(path, "//"); + if (path) { + path = strchr(path+2, '/'); + } + } + if (path) { + path += remote->path_len; + ls->dentry_name = xstrdup(path); + } } else if (!strcmp(ctx->name, DAV_PROPFIND_COLLECTION)) { ls->dentry_flags |= IS_DIR; } @@ -1439,6 +1447,12 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed) } } +/* + * NEEDSWORK: remote_ls() ignores info/refs on the remote side. But it + * should _only_ heed the information from that file, instead of trying to + * determine the refs from the remote file system (badly: it does not even + * know about packed-refs). + */ static void remote_ls(const char *path, int flags, void (*userFunc)(struct remote_ls_ctx *ls), void *userData) @@ -1722,7 +1736,7 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock) struct curl_slist *dav_headers = NULL; if_header = xmalloc(strlen(lock->token) + 25); - sprintf(if_header, "If: (<opaquelocktoken:%s>)", lock->token); + sprintf(if_header, "If: (<%s>)", lock->token); dav_headers = curl_slist_append(dav_headers, if_header); strbuf_addf(&out_buffer.buf, "%s\n", sha1_to_hex(sha1)); @@ -1941,7 +1955,7 @@ static void update_remote_info_refs(struct remote_lock *lock) add_remote_info_ref, &buffer.buf); if (!aborted) { if_header = xmalloc(strlen(lock->token) + 25); - sprintf(if_header, "If: (<opaquelocktoken:%s>)", lock->token); + sprintf(if_header, "If: (<%s>)", lock->token); dav_headers = curl_slist_append(dav_headers, if_header); slot = get_active_slot(); @@ -2208,10 +2222,11 @@ int main(int argc, char **argv) if (!remote->url) { char *path = strstr(arg, "//"); remote->url = arg; + remote->path_len = strlen(arg); if (path) { - path = strchr(path+2, '/'); - if (path) - remote->path_len = strlen(path); + remote->path = strchr(path+2, '/'); + if (remote->path) + remote->path_len = strlen(remote->path); } continue; } @@ -2240,8 +2255,9 @@ int main(int argc, char **argv) rewritten_url = xmalloc(strlen(remote->url)+2); strcpy(rewritten_url, remote->url); strcat(rewritten_url, "/"); + remote->path = rewritten_url + (remote->path - remote->url); + remote->path_len++; remote->url = rewritten_url; - ++remote->path_len; } /* Verify DAV compliance/lock support */ diff --git a/http-walker.c b/http-walker.c index 7271c7d19d..0dbad3c888 100644 --- a/http-walker.c +++ b/http-walker.c @@ -82,7 +82,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb, do { obj_req->stream.next_out = expn; obj_req->stream.avail_out = sizeof(expn); - obj_req->zret = inflate(&obj_req->stream, Z_SYNC_FLUSH); + obj_req->zret = git_inflate(&obj_req->stream, Z_SYNC_FLUSH); git_SHA1_Update(&obj_req->c, expn, sizeof(expn) - obj_req->stream.avail_out); } while (obj_req->stream.avail_in && obj_req->zret == Z_OK); @@ -142,7 +142,7 @@ static void start_object_request(struct walker *walker, memset(&obj_req->stream, 0, sizeof(obj_req->stream)); - inflateInit(&obj_req->stream); + git_inflate_init(&obj_req->stream); git_SHA1_Init(&obj_req->c); @@ -183,7 +183,7 @@ static void start_object_request(struct walker *walker, file; also rewind to the beginning of the local file. */ if (prev_read == -1) { memset(&obj_req->stream, 0, sizeof(obj_req->stream)); - inflateInit(&obj_req->stream); + git_inflate_init(&obj_req->stream); git_SHA1_Init(&obj_req->c); if (prev_posn>0) { prev_posn = 0; @@ -243,7 +243,7 @@ static void finish_object_request(struct object_request *obj_req) return; } - inflateEnd(&obj_req->stream); + git_inflate_end(&obj_req->stream); git_SHA1_Final(obj_req->real_sha1, &obj_req->c); if (obj_req->zret != Z_STREAM_END) { unlink(obj_req->tmpfile); diff --git a/index-pack.c b/index-pack.c index 60ed41a993..7697b1dfe3 100644 --- a/index-pack.c +++ b/index-pack.c @@ -171,9 +171,8 @@ static char *open_pack_file(char *pack_name) input_fd = 0; if (!pack_name) { static char tmpfile[PATH_MAX]; - snprintf(tmpfile, sizeof(tmpfile), - "%s/pack/tmp_pack_XXXXXX", get_object_directory()); - output_fd = xmkstemp(tmpfile); + output_fd = odb_mkstemp(tmpfile, sizeof(tmpfile), + "pack/tmp_pack_XXXXXX"); pack_name = xstrdup(tmpfile); } else output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600); @@ -275,10 +274,10 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size) stream.avail_out = size; stream.next_in = fill(1); stream.avail_in = input_len; - inflateInit(&stream); + git_inflate_init(&stream); for (;;) { - int ret = inflate(&stream, 0); + int ret = git_inflate(&stream, 0); use(input_len - stream.avail_in); if (stream.total_out == size && ret == Z_STREAM_END) break; @@ -287,7 +286,7 @@ static void *unpack_entry_data(unsigned long offset, unsigned long size) stream.next_in = fill(1); stream.avail_in = input_len; } - inflateEnd(&stream); + git_inflate_end(&stream); return buf; } @@ -382,9 +381,9 @@ static void *get_data_from_pack(struct object_entry *obj) stream.avail_out = obj->size; stream.next_in = src; stream.avail_in = len; - inflateInit(&stream); - while ((st = inflate(&stream, Z_FINISH)) == Z_OK); - inflateEnd(&stream); + git_inflate_init(&stream); + while ((st = git_inflate(&stream, Z_FINISH)) == Z_OK); + git_inflate_end(&stream); if (st != Z_STREAM_END || stream.total_out != obj->size) die("serious inflate inconsistency"); free(src); @@ -793,22 +792,24 @@ static void final(const char *final_pack_name, const char *curr_pack_name, if (keep_msg) { int keep_fd, keep_msg_len = strlen(keep_msg); - if (!keep_name) { - snprintf(name, sizeof(name), "%s/pack/pack-%s.keep", - get_object_directory(), sha1_to_hex(sha1)); - keep_name = name; - } - keep_fd = open(keep_name, O_RDWR|O_CREAT|O_EXCL, 0600); + + if (!keep_name) + keep_fd = odb_pack_keep(name, sizeof(name), sha1); + else + keep_fd = open(keep_name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (keep_fd < 0) { if (errno != EEXIST) - die("cannot write keep file"); + die("cannot write keep file '%s' (%s)", + keep_name, strerror(errno)); } else { if (keep_msg_len > 0) { write_or_die(keep_fd, keep_msg, keep_msg_len); write_or_die(keep_fd, "\n", 1); } if (close(keep_fd) != 0) - die("cannot write keep file"); + die("cannot close written keep file '%s' (%s)", + keep_name, strerror(errno)); report = "keep"; } } diff --git a/lockfile.c b/lockfile.c index 6d75608693..8e556ff8c9 100644 --- a/lockfile.c +++ b/lockfile.c @@ -140,6 +140,7 @@ static int lock_file(struct lock_file *lk, const char *path, int flags) signal(SIGHUP, remove_lock_file_on_signal); signal(SIGTERM, remove_lock_file_on_signal); signal(SIGQUIT, remove_lock_file_on_signal); + signal(SIGPIPE, remove_lock_file_on_signal); atexit(remove_lock_file); } lk->owner = getpid(); @@ -157,11 +158,25 @@ static int lock_file(struct lock_file *lk, const char *path, int flags) return lk->fd; } + +NORETURN void unable_to_lock_index_die(const char *path, int err) +{ + if (errno == EEXIST) { + die("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.", + path, strerror(err)); + } else { + die("Unable to create '%s.lock': %s", path, strerror(err)); + } +} + int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags) { int fd = lock_file(lk, path, flags); if (fd < 0 && (flags & LOCK_DIE_ON_ERROR)) - die("unable to create '%s.lock': %s", path, strerror(errno)); + unable_to_lock_index_die(path, errno); return fd; } diff --git a/merge-recursive.c b/merge-recursive.c index a0c804c817..b97026bd5c 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -447,6 +447,30 @@ static void flush_buffer(int fd, const char *buf, unsigned long size) } } +static int would_lose_untracked(const char *path) +{ + int pos = cache_name_pos(path, strlen(path)); + + if (pos < 0) + pos = -1 - pos; + while (pos < active_nr && + !strcmp(path, active_cache[pos]->name)) { + /* + * If stage #0, it is definitely tracked. + * If it has stage #2 then it was tracked + * before this merge started. All other + * cases the path was not tracked. + */ + switch (ce_stage(active_cache[pos])) { + case 0: + case 2: + return 0; + } + pos++; + } + return file_exists(path); +} + static int make_room_for_path(const char *path) { int status; @@ -462,6 +486,14 @@ static int make_room_for_path(const char *path) die(msg, path, ""); } + /* + * Do not unlink a file in the work tree if we are not + * tracking it. + */ + if (would_lose_untracked(path)) + return error("refusing to lose untracked file at '%s'", + path); + /* Successful unlink is good.. */ if (!unlink(path)) return 0; @@ -902,6 +934,11 @@ static int process_renames(struct merge_options *o, ren1_src, ren1_dst, branch1, branch2); update_file(o, 0, ren1->pair->two->sha1, ren1->pair->two->mode, ren1_dst); + update_stages(ren1_dst, NULL, + branch1 == o->branch1 ? + ren1->pair->two : NULL, + branch1 == o->branch1 ? + NULL : ren1->pair->two, 1); } else if (!sha_eq(dst_other.sha1, null_sha1)) { const char *new_path; clean_merge = 0; @@ -268,3 +268,22 @@ void add_object_array_with_mode(struct object *obj, const char *name, struct obj objects[nr].mode = mode; array->nr = ++nr; } + +void object_array_remove_duplicates(struct object_array *array) +{ + int ref, src, dst; + struct object_array_entry *objects = array->objects; + + for (ref = 0; ref < array->nr - 1; ref++) { + for (src = ref + 1, dst = src; + src < array->nr; + src++) { + if (!strcmp(objects[ref].name, objects[src].name)) + continue; + if (src != dst) + objects[dst] = objects[src]; + dst++; + } + array->nr = dst; + } +} @@ -82,5 +82,6 @@ int object_list_contains(struct object_list *list, struct object *obj); /* Object array handling .. */ void add_object_array(struct object *obj, const char *name, struct object_array *array); void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode); +void object_array_remove_duplicates(struct object_array *); #endif /* OBJECT_H */ diff --git a/pack-write.c b/pack-write.c index b426006c58..7053538f4c 100644 --- a/pack-write.c +++ b/pack-write.c @@ -44,9 +44,7 @@ char *write_idx_file(char *index_name, struct pack_idx_entry **objects, if (!index_name) { static char tmpfile[PATH_MAX]; - snprintf(tmpfile, sizeof(tmpfile), - "%s/pack/tmp_idx_XXXXXX", get_object_directory()); - fd = xmkstemp(tmpfile); + fd = odb_mkstemp(tmpfile, sizeof(tmpfile), "pack/tmp_idx_XXXXXX"); index_name = xstrdup(tmpfile); } else { unlink(index_name); @@ -239,7 +237,7 @@ char *index_pack_lockfile(int ip_out) char packname[46]; /* - * The first thing we expects from index-pack's output + * The first thing we expect from index-pack's output * is "pack\t%40s\n" or "keep\t%40s\n" (46 bytes) where * %40s is the newly created pack SHA1 name. In the "keep" * case, we need it to remove the corresponding .keep file @@ -70,7 +70,8 @@ void setup_pager(void) /* original process continues, but writes to the pipe */ dup2(pager_process.in, 1); - dup2(pager_process.in, 2); + if (isatty(2)) + dup2(pager_process.in, 2); close(pager_process.in); /* this makes sure that the parent terminates after the pager */ @@ -363,56 +363,97 @@ const char *make_relative_path(const char *abs, const char *base) } /* - * path = absolute path - * buf = buffer of at least max(2, strlen(path)+1) bytes - * It is okay if buf == path, but they should not overlap otherwise. + * It is okay if dst == src, but they should not overlap otherwise. * - * Performs the following normalizations on path, storing the result in buf: - * - Removes trailing slashes. - * - Removes empty components. + * Performs the following normalizations on src, storing the result in dst: + * - Ensures that components are separated by '/' (Windows only) + * - Squashes sequences of '/'. * - Removes "." components. * - Removes ".." components, and the components the precede them. - * "" and paths that contain only slashes are normalized to "/". - * Returns the length of the output. + * Returns failure (non-zero) if a ".." component appears as first path + * component anytime during the normalization. Otherwise, returns success (0). * * Note that this function is purely textual. It does not follow symlinks, * verify the existence of the path, or make any system calls. */ -int normalize_absolute_path(char *buf, const char *path) +int normalize_path_copy(char *dst, const char *src) { - const char *comp_start = path, *comp_end = path; - char *dst = buf; - int comp_len; - assert(buf); - assert(path); - - while (*comp_start) { - assert(*comp_start == '/'); - while (*++comp_end && *comp_end != '/') - ; /* nothing */ - comp_len = comp_end - comp_start; - - if (!strncmp("/", comp_start, comp_len) || - !strncmp("/.", comp_start, comp_len)) - goto next; - - if (!strncmp("/..", comp_start, comp_len)) { - while (dst > buf && *--dst != '/') - ; /* nothing */ - goto next; - } + char *dst0; - memmove(dst, comp_start, comp_len); - dst += comp_len; - next: - comp_start = comp_end; + if (has_dos_drive_prefix(src)) { + *dst++ = *src++; + *dst++ = *src++; } + dst0 = dst; - if (dst == buf) + if (is_dir_sep(*src)) { *dst++ = '/'; + while (is_dir_sep(*src)) + src++; + } + + for (;;) { + char c = *src; + + /* + * A path component that begins with . could be + * special: + * (1) "." and ends -- ignore and terminate. + * (2) "./" -- ignore them, eat slash and continue. + * (3) ".." and ends -- strip one and terminate. + * (4) "../" -- strip one, eat slash and continue. + */ + if (c == '.') { + if (!src[1]) { + /* (1) */ + src++; + } else if (is_dir_sep(src[1])) { + /* (2) */ + src += 2; + while (is_dir_sep(*src)) + src++; + continue; + } else if (src[1] == '.') { + if (!src[2]) { + /* (3) */ + src += 2; + goto up_one; + } else if (is_dir_sep(src[2])) { + /* (4) */ + src += 3; + while (is_dir_sep(*src)) + src++; + goto up_one; + } + } + } + /* copy up to the next '/', and eat all '/' */ + while ((c = *src++) != '\0' && !is_dir_sep(c)) + *dst++ = c; + if (is_dir_sep(c)) { + *dst++ = '/'; + while (is_dir_sep(c)) + c = *src++; + src--; + } else if (!c) + break; + continue; + + up_one: + /* + * dst0..dst is prefix portion, and dst[-1] is '/'; + * go up one level. + */ + dst--; /* go to trailing '/' */ + if (dst <= dst0) + return -1; + /* Windows: dst[-1] cannot be backslash anymore */ + while (dst0 < dst && dst[-1] != '/') + dst--; + } *dst = '\0'; - return dst - buf; + return 0; } /* @@ -438,15 +479,16 @@ int longest_ancestor_length(const char *path, const char *prefix_list) return -1; for (colon = ceil = prefix_list; *colon; ceil = colon+1) { - for (colon = ceil; *colon && *colon != ':'; colon++); + for (colon = ceil; *colon && *colon != PATH_SEP; colon++); len = colon - ceil; if (len == 0 || len > PATH_MAX || !is_absolute_path(ceil)) continue; strlcpy(buf, ceil, len+1); - len = normalize_absolute_path(buf, buf); - /* Strip "trailing slashes" from "/". */ - if (len == 1) - len = 0; + if (normalize_path_copy(buf, buf) < 0) + continue; + len = strlen(buf); + if (len > 0 && buf[len-1] == '/') + buf[--len] = '\0'; if (!strncmp(path, buf, len) && path[len] == '/' && diff --git a/perl/Git.pm b/perl/Git.pm index dde9105df8..7d7f2b1d36 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -166,11 +166,12 @@ sub repository { } } - if (not defined $opts{Repository} and not defined $opts{WorkingCopy}) { - $opts{Directory} ||= '.'; + if (not defined $opts{Repository} and not defined $opts{WorkingCopy} + and not defined $opts{Directory}) { + $opts{Directory} = '.'; } - if ($opts{Directory}) { + if (defined $opts{Directory}) { -d $opts{Directory} or throw Error::Simple("Directory not found: $!"); my $search = Git->repository(WorkingCopy => $opts{Directory}); @@ -204,14 +205,14 @@ sub repository { unless (-d "$dir/refs" and -d "$dir/objects" and -e "$dir/HEAD") { # Mimick git-rev-parse --git-dir error message: - throw Error::Simple('fatal: Not a git repository'); + throw Error::Simple("fatal: Not a git repository: $dir"); } my $search = Git->repository(Repository => $dir); try { $search->command('symbolic-ref', 'HEAD'); } catch Git::Error::Command with { # Mimick git-rev-parse --git-dir error message: - throw Error::Simple('fatal: Not a git repository'); + throw Error::Simple("fatal: Not a git repository: $dir"); } $opts{Repository} = abs_path($dir); @@ -1010,8 +1011,8 @@ sub _temp_cache { my $temp_fd = \$TEMP_FILEMAP{$name}; if (defined $$temp_fd and $$temp_fd->opened) { if ($TEMP_FILES{$$temp_fd}{locked}) { - throw Error::Simple("Temp file with moniker '", - $name, "' already in use"); + throw Error::Simple("Temp file with moniker '" . + $name . "' already in use"); } } else { if (defined $$temp_fd) { @@ -181,6 +181,20 @@ static int is_empty_line(const char *line, int *len_p) return !len; } +static const char *skip_empty_lines(const char *msg) +{ + for (;;) { + int linelen = get_one_line(msg); + int ll = linelen; + if (!linelen) + break; + if (!is_empty_line(msg, &ll)) + break; + msg += linelen; + } + return msg; +} + static void add_merge_info(enum cmit_fmt fmt, struct strbuf *sb, const struct commit *commit, int abbrev) { @@ -410,13 +424,15 @@ struct chunk { struct format_commit_context { const struct commit *commit; enum date_mode dmode; + unsigned commit_header_parsed:1; + unsigned commit_message_parsed:1; /* These offsets are relative to the start of the commit message. */ - int commit_header_parsed; - struct chunk subject; struct chunk author; struct chunk committer; struct chunk encoding; + size_t message_off; + size_t subject_off; size_t body_off; /* The following ones are relative to the result struct strbuf. */ @@ -446,23 +462,14 @@ static void parse_commit_header(struct format_commit_context *context) { const char *msg = context->commit->buffer; int i; - enum { HEADER, SUBJECT, BODY } state; - for (i = 0, state = HEADER; msg[i] && state < BODY; i++) { + for (i = 0; msg[i]; i++) { int eol; for (eol = i; msg[eol] && msg[eol] != '\n'; eol++) ; /* do nothing */ - if (state == SUBJECT) { - context->subject.off = i; - context->subject.len = eol - i; - i = eol; - } if (i == eol) { - state++; - /* strip empty lines */ - while (msg[eol] == '\n' && msg[eol + 1] == '\n') - eol++; + break; } else if (!prefixcmp(msg + i, "author ")) { context->author.off = i + 7; context->author.len = eol - i - 7; @@ -474,13 +481,50 @@ static void parse_commit_header(struct format_commit_context *context) context->encoding.len = eol - i - 9; } i = eol; - if (!msg[i]) - break; } - context->body_off = i; + context->message_off = i; context->commit_header_parsed = 1; } +const char *format_subject(struct strbuf *sb, const char *msg, + const char *line_separator) +{ + int first = 1; + + for (;;) { + const char *line = msg; + int linelen = get_one_line(line); + + msg += linelen; + if (!linelen || is_empty_line(line, &linelen)) + break; + + if (!sb) + continue; + strbuf_grow(sb, linelen + 2); + if (!first) + strbuf_addstr(sb, line_separator); + strbuf_add(sb, line, linelen); + first = 0; + } + return msg; +} + +static void parse_commit_message(struct format_commit_context *c) +{ + const char *msg = c->commit->buffer + c->message_off; + const char *start = c->commit->buffer; + + msg = skip_empty_lines(msg); + c->subject_off = msg - start; + + msg = format_subject(NULL, msg, NULL); + msg = skip_empty_lines(msg); + c->body_off = msg - start; + + c->commit_message_parsed = 1; +} + static void format_decoration(struct strbuf *sb, const struct commit *commit) { struct name_decoration *d; @@ -600,9 +644,6 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder, parse_commit_header(c); switch (placeholder[0]) { - case 's': /* subject */ - strbuf_add(sb, msg + c->subject.off, c->subject.len); - return 1; case 'a': /* author ... */ return format_person_part(sb, placeholder[1], msg + c->author.off, c->author.len, @@ -614,6 +655,16 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder, case 'e': /* encoding */ strbuf_add(sb, msg + c->encoding.off, c->encoding.len); return 1; + } + + /* Now we need to parse the commit message. */ + if (!c->commit_message_parsed) + parse_commit_message(c); + + switch (placeholder[0]) { + case 's': /* subject */ + format_subject(sb, msg + c->subject_off, " "); + return 1; case 'b': /* body */ strbuf_addstr(sb, msg + c->body_off); return 1; @@ -704,27 +755,11 @@ void pp_title_line(enum cmit_fmt fmt, const char *encoding, int need_8bit_cte) { + const char *line_separator = (fmt == CMIT_FMT_EMAIL) ? "\n " : " "; struct strbuf title; strbuf_init(&title, 80); - - for (;;) { - const char *line = *msg_p; - int linelen = get_one_line(line); - - *msg_p += linelen; - if (!linelen || is_empty_line(line, &linelen)) - break; - - strbuf_grow(&title, linelen + 2); - if (title.len) { - if (fmt == CMIT_FMT_EMAIL) { - strbuf_addch(&title, '\n'); - } - strbuf_addch(&title, ' '); - } - strbuf_add(&title, line, linelen); - } + *msg_p = format_subject(&title, *msg_p, line_separator); strbuf_grow(sb, title.len + 1024); if (subject) { @@ -850,15 +885,7 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, } /* Skip excess blank lines at the beginning of body, if any... */ - for (;;) { - int linelen = get_one_line(msg); - int ll = linelen; - if (!linelen) - break; - if (!is_empty_line(msg, &ll)) - break; - msg += linelen; - } + msg = skip_empty_lines(msg); /* These formats treat the title line specially. */ if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL) diff --git a/read-cache.c b/read-cache.c index c14b562313..940ec76fdf 100644 --- a/read-cache.c +++ b/read-cache.c @@ -99,27 +99,21 @@ static int ce_compare_data(struct cache_entry *ce, struct stat *st) static int ce_compare_link(struct cache_entry *ce, size_t expected_size) { int match = -1; - char *target; void *buffer; unsigned long size; enum object_type type; - int len; + struct strbuf sb = STRBUF_INIT; - target = xmalloc(expected_size); - len = readlink(ce->name, target, expected_size); - if (len != expected_size) { - free(target); + if (strbuf_readlink(&sb, ce->name, expected_size)) return -1; - } + buffer = read_sha1_file(ce->sha1, &type, &size); - if (!buffer) { - free(target); - return -1; + if (buffer) { + if (size == sb.len) + match = memcmp(buffer, sb.buf, size); + free(buffer); } - if (size == expected_size) - match = memcmp(buffer, target, size); - free(buffer); - free(target); + strbuf_release(&sb); return match; } @@ -1580,6 +1574,26 @@ static void update_callback(struct diff_queue_struct *q, default: die("unexpected diff status %c", p->status); case DIFF_STATUS_UNMERGED: + /* + * ADD_CACHE_IGNORE_REMOVAL is unset if "git + * add -u" is calling us, In such a case, a + * missing work tree file needs to be removed + * if there is an unmerged entry at stage #2, + * but such a diff record is followed by + * another with DIFF_STATUS_DELETED (and if + * there is no stage #2, we won't see DELETED + * nor MODIFIED). We can simply continue + * either way. + */ + if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL)) + continue; + /* + * Otherwise, it is "git add path" is asking + * to explicitly add it; we fall through. A + * missing work tree file is an error and is + * caught by add_file_to_index() in such a + * case. + */ case DIFF_STATUS_MODIFIED: case DIFF_STATUS_TYPE_CHANGED: if (add_file_to_index(&the_index, path, data->flags)) { diff --git a/revision.c b/revision.c index db60f06c98..286e416b75 100644 --- a/revision.c +++ b/revision.c @@ -183,8 +183,11 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object if (!tag->tagged) die("bad tag"); object = parse_object(tag->tagged->sha1); - if (!object) + if (!object) { + if (flags & UNINTERESTING) + return NULL; die("bad object %s", sha1_to_hex(tag->tagged->sha1)); + } } /* @@ -479,9 +482,10 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit, while (parent) { struct commit *p = parent->item; parent = parent->next; + if (p) + p->object.flags |= UNINTERESTING; if (parse_commit(p) < 0) - return -1; - p->object.flags |= UNINTERESTING; + continue; if (p->parents) mark_parents_uninteresting(p); if (p->object.flags & SEEN) @@ -1263,6 +1267,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch if (!strcmp(arg, "--all")) { handle_refs(revs, flags, for_each_ref); + handle_refs(revs, flags, head_ref); continue; } if (!strcmp(arg, "--branches")) { @@ -1733,14 +1738,16 @@ static struct commit *get_revision_1(struct rev_info *revs) (commit->date < revs->max_age)) continue; if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0) - return NULL; + die("Failed to traverse parents of commit %s", + sha1_to_hex(commit->object.sha1)); } switch (simplify_commit(revs, commit)) { case commit_ignore: continue; case commit_error: - return NULL; + die("Failed to simplify parents of commit %s", + sha1_to_hex(commit->object.sha1)); default: return commit; } diff --git a/run-command.c b/run-command.c index c90cdc50e3..44fccc9d5e 100644 --- a/run-command.c +++ b/run-command.c @@ -118,7 +118,9 @@ int start_command(struct child_process *cmd) } else { execvp(cmd->argv[0], (char *const*) cmd->argv); } - die("exec %s failed.", cmd->argv[0]); + trace_printf("trace: exec '%s' failed: %s\n", cmd->argv[0], + strerror(errno)); + exit(127); } #else int s0 = -1, s1 = -1, s2 = -1; /* backups of stdin, stdout, stderr */ @@ -187,6 +189,7 @@ int start_command(struct child_process *cmd) #endif if (cmd->pid < 0) { + int err = errno; if (need_in) close_pair(fdin); else if (cmd->in) @@ -197,7 +200,9 @@ int start_command(struct child_process *cmd) close(cmd->out); if (need_err) close_pair(fderr); - return -ERR_RUN_COMMAND_FORK; + return err == ENOENT ? + -ERR_RUN_COMMAND_EXEC : + -ERR_RUN_COMMAND_FORK; } if (need_in) @@ -236,9 +241,14 @@ static int wait_or_whine(pid_t pid) if (!WIFEXITED(status)) return -ERR_RUN_COMMAND_WAITPID_NOEXIT; code = WEXITSTATUS(status); - if (code) + switch (code) { + case 127: + return -ERR_RUN_COMMAND_EXEC; + case 0: + return 0; + default: return -code; - return 0; + } } } diff --git a/run-command.h b/run-command.h index a8b0c209e9..e90d9282ff 100644 --- a/run-command.h +++ b/run-command.h @@ -10,6 +10,7 @@ enum { ERR_RUN_COMMAND_WAITPID_SIGNAL, ERR_RUN_COMMAND_WAITPID_NOEXIT, }; +#define IS_RUN_COMMAND_ERR(x) ((x) <= -ERR_RUN_COMMAND_FORK) struct child_process { const char **argv; @@ -4,92 +4,6 @@ static int inside_git_dir = -1; static int inside_work_tree = -1; -static int sanitary_path_copy(char *dst, const char *src) -{ - char *dst0; - - if (has_dos_drive_prefix(src)) { - *dst++ = *src++; - *dst++ = *src++; - } - dst0 = dst; - - if (is_dir_sep(*src)) { - *dst++ = '/'; - while (is_dir_sep(*src)) - src++; - } - - for (;;) { - char c = *src; - - /* - * A path component that begins with . could be - * special: - * (1) "." and ends -- ignore and terminate. - * (2) "./" -- ignore them, eat slash and continue. - * (3) ".." and ends -- strip one and terminate. - * (4) "../" -- strip one, eat slash and continue. - */ - if (c == '.') { - if (!src[1]) { - /* (1) */ - src++; - } else if (is_dir_sep(src[1])) { - /* (2) */ - src += 2; - while (is_dir_sep(*src)) - src++; - continue; - } else if (src[1] == '.') { - if (!src[2]) { - /* (3) */ - src += 2; - goto up_one; - } else if (is_dir_sep(src[2])) { - /* (4) */ - src += 3; - while (is_dir_sep(*src)) - src++; - goto up_one; - } - } - } - - /* copy up to the next '/', and eat all '/' */ - while ((c = *src++) != '\0' && !is_dir_sep(c)) - *dst++ = c; - if (is_dir_sep(c)) { - *dst++ = '/'; - while (is_dir_sep(c)) - c = *src++; - src--; - } else if (!c) - break; - continue; - - up_one: - /* - * dst0..dst is prefix portion, and dst[-1] is '/'; - * go up one level. - */ - dst -= 2; /* go past trailing '/' if any */ - if (dst < dst0) - return -1; - while (1) { - if (dst <= dst0) - break; - c = *dst--; - if (c == '/') { /* MinGW: cannot be '\\' anymore */ - dst += 2; - break; - } - } - } - *dst = '\0'; - return 0; -} - const char *prefix_path(const char *prefix, int len, const char *path) { const char *orig = path; @@ -101,7 +15,7 @@ const char *prefix_path(const char *prefix, int len, const char *path) memcpy(sanitized, prefix, len); strcpy(sanitized + len, path); } - if (sanitary_path_copy(sanitized, sanitized)) + if (normalize_path_copy(sanitized, sanitized)) goto error_out; if (is_absolute_path(orig)) { const char *work_tree = get_git_work_tree(); @@ -456,7 +370,11 @@ const char *setup_git_directory_gently(int *nongit_ok) inside_git_dir = 1; if (!work_tree_env) inside_work_tree = 0; - setenv(GIT_DIR_ENVIRONMENT, ".", 1); + if (offset != len) { + cwd[offset] = '\0'; + setenv(GIT_DIR_ENVIRONMENT, cwd, 1); + } else + setenv(GIT_DIR_ENVIRONMENT, ".", 1); check_repository_format_gently(nongit_ok); return NULL; } @@ -468,7 +386,7 @@ const char *setup_git_directory_gently(int *nongit_ok) *nongit_ok = 1; return NULL; } - die("Not a git repository"); + die("Not a git repository (or any of the parent directories): %s", DEFAULT_GIT_DIR_ENVIRONMENT); } if (chdir("..")) die("Cannot change to %s/..: %s", cwd, strerror(errno)); diff --git a/sha1_file.c b/sha1_file.c index 0e021c5eca..3d93d936e4 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -689,6 +689,7 @@ void free_pack_by_name(const char *pack_name) while (*pp) { p = *pp; if (strcmp(pack_name, p->pack_name) == 0) { + clear_delta_base_cache(); close_pack_windows(p); if (p->pack_fd != -1) close(p->pack_fd); @@ -1196,8 +1197,8 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon stream->avail_out = bufsiz; if (legacy_loose_object(map)) { - inflateInit(stream); - return inflate(stream, 0); + git_inflate_init(stream); + return git_inflate(stream, 0); } @@ -1217,7 +1218,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon /* Set up the stream for the rest.. */ stream->next_in = map; stream->avail_in = mapsize; - inflateInit(stream); + git_inflate_init(stream); /* And generate the fake traditional header */ stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu", @@ -1254,11 +1255,11 @@ static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size stream->next_out = buf + bytes; stream->avail_out = size - bytes; while (status == Z_OK) - status = inflate(stream, Z_FINISH); + status = git_inflate(stream, Z_FINISH); } buf[size] = 0; if (status == Z_STREAM_END && !stream->avail_in) { - inflateEnd(stream); + git_inflate_end(stream); return buf; } @@ -1348,15 +1349,15 @@ unsigned long get_size_from_delta(struct packed_git *p, stream.next_out = delta_head; stream.avail_out = sizeof(delta_head); - inflateInit(&stream); + git_inflate_init(&stream); do { in = use_pack(p, w_curs, curpos, &stream.avail_in); stream.next_in = in; - st = inflate(&stream, Z_FINISH); + st = git_inflate(&stream, Z_FINISH); curpos += stream.next_in - in; } while ((st == Z_OK || st == Z_BUF_ERROR) && stream.total_out < sizeof(delta_head)); - inflateEnd(&stream); + git_inflate_end(&stream); if ((st != Z_STREAM_END) && stream.total_out != sizeof(delta_head)) { error("delta data unpack-initial failed"); return 0; @@ -1585,14 +1586,14 @@ static void *unpack_compressed_entry(struct packed_git *p, stream.next_out = buffer; stream.avail_out = size; - inflateInit(&stream); + git_inflate_init(&stream); do { in = use_pack(p, w_curs, curpos, &stream.avail_in); stream.next_in = in; - st = inflate(&stream, Z_FINISH); + st = git_inflate(&stream, Z_FINISH); curpos += stream.next_in - in; } while (st == Z_OK || st == Z_BUF_ERROR); - inflateEnd(&stream); + git_inflate_end(&stream); if ((st != Z_STREAM_END) || stream.total_out != size) { free(buffer); return NULL; @@ -1663,6 +1664,13 @@ static inline void release_delta_base_cache(struct delta_base_cache_entry *ent) } } +void clear_delta_base_cache(void) +{ + unsigned long p; + for (p = 0; p < MAX_DELTA_CACHE; p++) + release_delta_base_cache(&delta_base_cache[p]); +} + static void add_delta_base_cache(struct packed_git *p, off_t base_offset, void *base, unsigned long base_size, enum object_type type) { @@ -2017,7 +2025,7 @@ static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *size status = error("unable to parse %s header", sha1_to_hex(sha1)); else if (sizep) *sizep = size; - inflateEnd(&stream); + git_inflate_end(&stream); munmap(map, mapsize); return status; } @@ -2290,7 +2298,7 @@ static void close_sha1_file(int fd) fsync_or_die(fd, "sha1 file"); fchmod(fd, 0444); if (close(fd) != 0) - die("unable to write sha1 file"); + die("error when closing sha1 file (%s)", strerror(errno)); } /* Size of directory component, including the ending '/' */ @@ -2337,7 +2345,8 @@ static int create_tmpfile(char *buffer, size_t bufsiz, const char *filename) static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen, void *buf, unsigned long len, time_t mtime) { - int fd, size, ret; + int fd, ret; + size_t size; unsigned char *compressed; z_stream stream; char *filename; @@ -2523,8 +2532,7 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object) { int fd; - char *target; - size_t len; + struct strbuf sb = STRBUF_INIT; switch (st->st_mode & S_IFMT) { case S_IFREG: @@ -2537,20 +2545,17 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, int write path); break; case S_IFLNK: - len = xsize_t(st->st_size); - target = xmalloc(len + 1); - if (readlink(path, target, len + 1) != st->st_size) { + if (strbuf_readlink(&sb, path, st->st_size)) { char *errstr = strerror(errno); - free(target); return error("readlink(\"%s\"): %s", path, errstr); } if (!write_object) - hash_sha1_file(target, len, blob_type, sha1); - else if (write_sha1_file(target, len, blob_type, sha1)) + hash_sha1_file(sb.buf, sb.len, blob_type, sha1); + else if (write_sha1_file(sb.buf, sb.len, blob_type, sha1)) return error("%s: failed to insert into database", path); - free(target); + strbuf_release(&sb); break; case S_IFDIR: return resolve_gitlink_ref(path, "HEAD", sha1); diff --git a/sha1_name.c b/sha1_name.c index 159c2ab84f..722fc35a6d 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -309,7 +309,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) /* basic@{time or number} format to query ref-log */ reflog_len = at = 0; - if (str[len-1] == '}') { + if (len && str[len-1] == '}') { for (at = 0; at < len - 1; at++) { if (str[at] == '@' && str[at+1] == '{') { reflog_len = (len-1) - (at+2); @@ -288,6 +288,33 @@ ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint) return sb->len - oldlen; } +#define STRBUF_MAXLINK (2*PATH_MAX) + +int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint) +{ + if (hint < 32) + hint = 32; + + while (hint < STRBUF_MAXLINK) { + int len; + + strbuf_grow(sb, hint); + len = readlink(path, sb->buf, hint); + if (len < 0) { + if (errno != ERANGE) + break; + } else if (len < hint) { + strbuf_setlen(sb, len); + return 0; + } + + /* .. the buffer was too small - try again */ + hint *= 2; + } + strbuf_release(sb); + return -1; +} + int strbuf_getline(struct strbuf *sb, FILE *fp, int term) { int ch; @@ -124,6 +124,7 @@ extern size_t strbuf_fread(struct strbuf *, size_t, FILE *); /* XXX: if read fails, any partial read is undone */ extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint); extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint); +extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint); extern int strbuf_getline(struct strbuf *, FILE *, int); diff --git a/t/Makefile b/t/Makefile index ed49c20b16..9149373032 100644 --- a/t/Makefile +++ b/t/Makefile @@ -24,7 +24,7 @@ pre-clean: $(RM) -r test-results clean: - $(RM) -r 'trash directory' test-results + $(RM) -r 'trash directory'.* test-results aggregate-results-and-cleanup: $(T) $(MAKE) aggregate-results diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 4717c2d33b..fdb19a50f1 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -1,6 +1,8 @@ ServerName dummy PidFile httpd.pid DocumentRoot www +LogFormat "%h %l %u %t \"%r\" %>s %b" common +CustomLog access.log common ErrorLog error.log <IfDefine SSL> diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index 6e7501f352..4ed1f0b4dd 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -8,36 +8,37 @@ test_description='Test various path utilities' . ./test-lib.sh norm_abs() { - test_expect_success "normalize absolute" \ - "test \$(test-path-utils normalize_absolute_path '$1') = '$2'" + test_expect_success "normalize absolute: $1 => $2" \ + "test \"\$(test-path-utils normalize_path_copy '$1')\" = '$2'" } ancestor() { - test_expect_success "longest ancestor" \ - "test \$(test-path-utils longest_ancestor_length '$1' '$2') = '$3'" + test_expect_success "longest ancestor: $1 $2 => $3" \ + "test \"\$(test-path-utils longest_ancestor_length '$1' '$2')\" = '$3'" } -norm_abs "" / +norm_abs "" "" norm_abs / / norm_abs // / norm_abs /// / norm_abs /. / norm_abs /./ / -norm_abs /./.. / -norm_abs /../. / -norm_abs /./../.// / +norm_abs /./.. ++failed++ +norm_abs /../. ++failed++ +norm_abs /./../.// ++failed++ norm_abs /dir/.. / norm_abs /dir/sub/../.. / +norm_abs /dir/sub/../../.. ++failed++ norm_abs /dir /dir -norm_abs /dir// /dir +norm_abs /dir// /dir/ norm_abs /./dir /dir -norm_abs /dir/. /dir -norm_abs /dir///./ /dir -norm_abs /dir//sub/.. /dir -norm_abs /dir/sub/../ /dir -norm_abs //dir/sub/../. /dir -norm_abs /dir/s1/../s2/ /dir/s2 -norm_abs /d1/s1///s2/..//../s3/ /d1/s3 +norm_abs /dir/. /dir/ +norm_abs /dir///./ /dir/ +norm_abs /dir//sub/.. /dir/ +norm_abs /dir/sub/../ /dir/ +norm_abs //dir/sub/../. /dir/ +norm_abs /dir/s1/../s2/ /dir/s2/ +norm_abs /d1/s1///s2/..//../s3/ /d1/s3/ norm_abs /d1/s1//../s2/../../d2 /d2 norm_abs /d1/.../d2 /d1/.../d2 norm_abs /d1/..././../d2 /d1/d2 diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh index 4b44e131b2..271bc4e17f 100755 --- a/t/t1001-read-tree-m-2way.sh +++ b/t/t1001-read-tree-m-2way.sh @@ -341,4 +341,55 @@ test_expect_success \ check_cache_at DF/DF dirty && :' +test_expect_success \ + 'a/b (untracked) vs a case setup.' \ + 'rm -f .git/index && + : >a && + git update-index --add a && + treeM=`git write-tree` && + echo treeM $treeM && + git ls-tree $treeM && + git ls-files --stage >treeM.out && + + rm -f a && + git update-index --remove a && + mkdir a && + : >a/b && + treeH=`git write-tree` && + echo treeH $treeH && + git ls-tree $treeH' + +test_expect_success \ + 'a/b (untracked) vs a, plus c/d case test.' \ + '! git read-tree -u -m "$treeH" "$treeM" && + git ls-files --stage && + test -f a/b' + +test_expect_success \ + 'a/b vs a, plus c/d case setup.' \ + 'rm -f .git/index && + rm -fr a && + : >a && + mkdir c && + : >c/d && + git update-index --add a c/d && + treeM=`git write-tree` && + echo treeM $treeM && + git ls-tree $treeM && + git ls-files --stage >treeM.out && + + rm -f a && + mkdir a + : >a/b && + git update-index --add --remove a a/b && + treeH=`git write-tree` && + echo treeH $treeH && + git ls-tree $treeH' + +test_expect_success \ + 'a/b vs a, plus c/d case test.' \ + 'git read-tree -u -m "$treeH" "$treeM" && + git ls-files --stage | tee >treeMcheck.out && + test_cmp treeM.out treeMcheck.out' + test_done diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh index f6a6f839a1..27dc6c55d5 100755 --- a/t/t1501-worktree.sh +++ b/t/t1501-worktree.sh @@ -92,6 +92,13 @@ cd sub/dir || exit 1 test_rev_parse 'in repo.git/sub/dir' false true true sub/dir/ cd ../../../.. || exit 1 +test_expect_success 'detecting gitdir when cwd is in a subdir of gitdir' ' + (expected=$(pwd)/repo.git && + cd repo.git/refs && + unset GIT_DIR && + test "$expected" = "$(git rev-parse --git-dir)") +' + test_expect_success 'repo finds its work tree' ' (cd repo.git && : > work/sub/dir/untracked && diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh index 91b704a3a4..e377d48902 100755 --- a/t/t1504-ceiling-dirs.sh +++ b/t/t1504-ceiling-dirs.sh @@ -93,13 +93,13 @@ GIT_CEILING_DIRECTORIES="$TRASH_ROOT/subdi" test_prefix subdir_ceil_at_subdi_slash "sub/dir/" -GIT_CEILING_DIRECTORIES="foo:$TRASH_ROOT/sub" +GIT_CEILING_DIRECTORIES="/foo:$TRASH_ROOT/sub" test_fail second_of_two -GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub:bar" +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub:/bar" test_fail first_of_two -GIT_CEILING_DIRECTORIES="foo:$TRASH_ROOT/sub:bar" +GIT_CEILING_DIRECTORIES="/foo:$TRASH_ROOT/sub:/bar" test_fail second_of_three diff --git a/t/t2011-checkout-invalid-head.sh b/t/t2011-checkout-invalid-head.sh index 764bb0a6bc..15ebdc26eb 100755 --- a/t/t2011-checkout-invalid-head.sh +++ b/t/t2011-checkout-invalid-head.sh @@ -10,6 +10,10 @@ test_expect_success 'setup' ' git commit -m initial ' +test_expect_success 'checkout should not start branch from a tree' ' + test_must_fail git checkout -b newbranch master^{tree} +' + test_expect_success 'checkout master from invalid HEAD' ' echo 0000000000000000000000000000000000000000 >.git/HEAD && git checkout master -- diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index cd9231cf61..b2ddf5ace3 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -12,7 +12,7 @@ and issues a git add -u with path limiting on "dir" to add only the updates to dir/sub. Also tested are "git add -u" without limiting, and "git add -u" -without contents changes.' +without contents changes, and other conditions' . ./test-lib.sh @@ -128,4 +128,52 @@ test_expect_success 'add -n -u should not add but just report' ' ' +test_expect_success 'add -u resolves unmerged paths' ' + git reset --hard && + one=$(echo 1 | git hash-object -w --stdin) && + two=$(echo 2 | git hash-object -w --stdin) && + three=$(echo 3 | git hash-object -w --stdin) && + { + for path in path1 path2 + do + echo "100644 $one 1 $path" + echo "100644 $two 2 $path" + echo "100644 $three 3 $path" + done + echo "100644 $one 1 path3" + echo "100644 $one 1 path4" + echo "100644 $one 3 path5" + echo "100644 $one 3 path6" + } | + git update-index --index-info && + echo 3 >path1 && + echo 2 >path3 && + echo 2 >path5 && + git add -u && + git ls-files -s "path?" >actual && + { + echo "100644 $three 0 path1" + echo "100644 $one 1 path3" + echo "100644 $one 1 path4" + echo "100644 $one 3 path5" + echo "100644 $one 3 path6" + } >expect && + test_cmp expect actual && + + # Bonus tests. Explicit resolving + git add path3 path5 && + test_must_fail git add path4 && + test_must_fail git add path6 && + git rm path4 && + git rm path6 && + + git ls-files -s "path?" >actual && + { + echo "100644 $three 0 path1" + echo "100644 $two 0 path3" + echo "100644 $two 0 path5" + } >expect + +' + test_done diff --git a/t/t2300-cd-to-toplevel.sh b/t/t2300-cd-to-toplevel.sh new file mode 100755 index 0000000000..e42cbfe6c6 --- /dev/null +++ b/t/t2300-cd-to-toplevel.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +test_description='cd_to_toplevel' + +. ./test-lib.sh + +test_cd_to_toplevel () { + test_expect_success "$2" ' + ( + cd '"'$1'"' && + . git-sh-setup && + cd_to_toplevel && + [ "$(unset PWD; /bin/pwd)" = "$TOPLEVEL" ] + ) + ' +} + +TOPLEVEL="$(unset PWD; /bin/pwd)/repo" +mkdir -p repo/sub/dir +mv .git repo/ +SUBDIRECTORY_OK=1 + +test_cd_to_toplevel repo 'at physical root' + +test_cd_to_toplevel repo/sub/dir 'at physical subdir' + +ln -s repo symrepo +test_cd_to_toplevel symrepo 'at symbolic root' + +ln -s repo/sub/dir subdir-link +test_cd_to_toplevel subdir-link 'at symbolic subdir' + +cd repo +ln -s sub/dir internal-link +test_cd_to_toplevel internal-link 'at internal symbolic subdir' + +test_done diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh index 8666946b02..c65bca8388 100755 --- a/t/t3001-ls-files-others-exclude.sh +++ b/t/t3001-ls-files-others-exclude.sh @@ -19,6 +19,9 @@ do >$dir/a.$i done done +>"#ignore1" +>"#ignore2" +>"#hidden" cat >expect <<EOF a.2 @@ -42,6 +45,9 @@ three/a.8 EOF echo '.gitignore +\#ignore1 +\#ignore2* +\#hid*n output expect .gitignore @@ -79,9 +85,10 @@ test_expect_success \ >output && test_cmp expect output' -cat > excludes-file << EOF +cat > excludes-file <<\EOF *.[1-8] e* +\#* EOF git config core.excludesFile excludes-file @@ -140,4 +147,10 @@ test_expect_success 'trailing slash in exclude forces directory match (2)' ' ' +test_expect_success 'negated exclude matches can override previous ones' ' + + git ls-files --others --exclude="a.*" --exclude="!a.1" >output && + grep "^a.1" output +' + test_done diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 7d10a27f1d..4becc5513d 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -373,6 +373,38 @@ test_expect_success '--continue tries to commit, even for "edit"' ' test $parent = $(git rev-parse HEAD^) ' +test_expect_success 'aborted --continue does not squash commits after "edit"' ' + old=$(git rev-parse HEAD) && + test_tick && + FAKE_LINES="edit 1" git rebase -i HEAD^ && + echo "edited again" > file7 && + git add file7 && + ( + FAKE_COMMIT_MESSAGE=" " && + export FAKE_COMMIT_MESSAGE && + test_must_fail git rebase --continue + ) && + test $old = $(git rev-parse HEAD) && + git rebase --abort +' + +test_expect_success 'auto-amend only edited commits after "edit"' ' + test_tick && + FAKE_LINES="edit 1" git rebase -i HEAD^ && + echo "edited again" > file7 && + git add file7 && + FAKE_COMMIT_MESSAGE="edited file7 again" git commit && + echo "and again" > file7 && + git add file7 && + test_tick && + ( + FAKE_COMMIT_MESSAGE="and again" && + export FAKE_COMMIT_MESSAGE && + test_must_fail git rebase --continue + ) && + git rebase --abort +' + test_expect_success 'rebase a detached HEAD' ' grandparent=$(git rev-parse HEAD~2) && git checkout $(git rev-parse HEAD) && @@ -430,4 +462,30 @@ test_expect_success 'do "noop" when there is nothing to cherry-pick' ' ' +test_expect_success 'submodule rebase setup' ' + git checkout A && + mkdir sub && + ( + cd sub && git init && >elif && + git add elif && git commit -m "submodule initial" + ) && + echo 1 >file1 && + git add file1 sub + test_tick && + git commit -m "One" && + echo 2 >file1 && + test_tick && + git commit -a -m "Two" && + ( + cd sub && echo 3 >elif && + git commit -a -m "submodule second" + ) && + test_tick && + git commit -a -m "Three changes submodule" +' + +test_expect_success 'submodule rebase -i' ' + FAKE_LINES="1 squash 2 3" git rebase -i A +' + test_done diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh index 8cde40f8e8..e6c832780f 100755 --- a/t/t3409-rebase-preserve-merges.sh +++ b/t/t3409-rebase-preserve-merges.sh @@ -11,15 +11,23 @@ Run "git rebase -p" and check that merges are properly carried along GIT_AUTHOR_EMAIL=bogus_email_address export GIT_AUTHOR_EMAIL -#echo 'Setting up: +# Clone 1 (trivial merge): # -#A1--A2 <-- origin/master -# \ \ -# B1--M <-- topic -# \ -# B2 <-- origin/topic +# A1--A2 <-- origin/master +# \ \ +# B1--M <-- topic +# \ +# B2 <-- origin/topic # -#' +# Clone 2 (conflicting merge): +# +# A1--A2--B3 <-- origin/master +# \ \ +# B1------M <-- topic +# \ +# B2 <-- origin/topic +# +# In both cases, 'topic' is rebased onto 'origin/topic'. test_expect_success 'setup for merge-preserving rebase' \ 'echo First > A && @@ -37,12 +45,19 @@ test_expect_success 'setup for merge-preserving rebase' \ cd clone1 && git checkout -b topic origin/topic && git merge origin/master && - cd .. + cd .. && + + echo Fifth > B && + git add B && + git commit -m "Add different B" && - git clone ./. clone2 + git clone ./. clone2 && cd clone2 && git checkout -b topic origin/topic && - git merge origin/master && + test_must_fail git merge origin/master && + echo Resolved > B && + git add B && + git commit -m "Merge origin/master into topic" && cd .. && git checkout topic && @@ -51,11 +66,30 @@ test_expect_success 'setup for merge-preserving rebase' \ ' test_expect_success 'rebase -p fakes interactive rebase' ' - cd clone2 && + ( + cd clone1 && git fetch && git rebase -p origin/topic && test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) && test 1 = $(git rev-list --all --pretty=oneline | grep "Merge commit" | wc -l) + ) +' + +test_expect_success '--continue works after a conflict' ' + ( + cd clone2 && + git fetch && + test_must_fail git rebase -p origin/topic && + test 2 = $(git ls-files B | wc -l) && + echo Resolved again > B && + test_must_fail git rebase --continue && + grep "^@@@ " .git/rebase-merge/patch && + git add B && + git rebase --continue && + test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) && + test 1 = $(git rev-list --all --pretty=oneline | grep "Add different" | wc -l) && + test 1 = $(git rev-list --all --pretty=oneline | grep "Merge origin" | wc -l) + ) ' test_done diff --git a/t/t3411-rebase-preserve-around-merges.sh b/t/t3411-rebase-preserve-around-merges.sh index aacfaae843..aacfaae843 100644..100755 --- a/t/t3411-rebase-preserve-around-merges.sh +++ b/t/t3411-rebase-preserve-around-merges.sh diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index 6da212825a..bb4cf00d78 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -45,6 +45,7 @@ test_expect_success 'cherry-pick after renaming branch' ' git checkout rename2 && git cherry-pick added && + test $(git rev-parse HEAD^) = $(git rev-parse rename2) && test -f opos && grep "Add extra line at the end" opos @@ -54,6 +55,7 @@ test_expect_success 'revert after renaming branch' ' git checkout rename1 && git revert added && + test $(git rev-parse HEAD^) = $(git rev-parse rename1) && test -f spoo && ! grep "Add extra line at the end" spoo diff --git a/t/t3505-cherry-pick-empty.sh b/t/t3505-cherry-pick-empty.sh new file mode 100755 index 0000000000..9aaeabd972 --- /dev/null +++ b/t/t3505-cherry-pick-empty.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +test_description='test cherry-picking an empty commit' + +. ./test-lib.sh + +test_expect_success setup ' + + echo first > file1 && + git add file1 && + test_tick && + git commit -m "first" && + + git checkout -b empty-branch && + test_tick && + git commit --allow-empty -m "empty" + +' + +test_expect_code 1 'cherry-pick an empty commit' ' + + git checkout master && + git cherry-pick empty-branch + +' + +test_expect_success 'index lockfile was removed' ' + + test ! -f .git/index.lock + +' + +test_done diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index b7d46e50a8..95542e9cfe 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -251,4 +251,21 @@ test_expect_success 'refresh index before checking if it is up-to-date' ' ' +test_expect_success 'choking "git rm" should not let it die with cruft' ' + git reset -q --hard && + H=0000000000000000000000000000000000000000 && + i=0 && + while test $i -lt 12000 + do + echo "100644 $H 0 some-file-$i" + i=$(( $i + 1 )) + done | git update-index --index-info && + git rm -n "some-file-*" | :; + test -f .git/index.lock + status=$? + rm -f .git/index.lock + git reset -q --hard + test "$status" != 0 +' + test_done diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index aeb5405cfe..9c709022ef 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -74,6 +74,10 @@ test_expect_success setup ' for i in 1 2; do echo $i; done >>dir/sub && git update-index file0 dir/sub && + mkdir dir3 && + cp dir/sub dir3/sub && + test-chmtime +1 dir3/sub && + git config log.showroot false && git commit --amend && git show-branch @@ -261,6 +265,8 @@ diff --patch-with-stat -r initial..side diff --patch-with-raw -r initial..side diff --name-status dir2 dir diff --no-index --name-status dir2 dir +diff --no-index --name-status -- dir2 dir +diff --no-index dir dir3 diff master master^ side EOF diff --git a/t/t4013/diff.diff_--no-index_--name-status_--_dir2_dir b/t/t4013/diff.diff_--no-index_--name-status_--_dir2_dir new file mode 100644 index 0000000000..6756f8de67 --- /dev/null +++ b/t/t4013/diff.diff_--no-index_--name-status_--_dir2_dir @@ -0,0 +1,3 @@ +$ git diff --no-index --name-status -- dir2 dir +A dir/sub +$ diff --git a/t/t4013/diff.diff_--no-index_dir_dir3 b/t/t4013/diff.diff_--no-index_dir_dir3 new file mode 100644 index 0000000000..2142c2b9ad --- /dev/null +++ b/t/t4013/diff.diff_--no-index_dir_dir3 @@ -0,0 +1,2 @@ +$ git diff --no-index dir dir3 +$ diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 9d99dc2887..f045898fe3 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Junio C Hamano # -test_description='Format-patch skipping already incorporated patches' +test_description='various format-patch tests' . ./test-lib.sh @@ -255,4 +255,54 @@ test_expect_success 'format-patch respects -U' ' ' +test_expect_success 'format-patch from a subdirectory (1)' ' + filename=$( + rm -rf sub && + mkdir -p sub/dir && + cd sub/dir && + git format-patch -1 + ) && + case "$filename" in + 0*) + ;; # ok + *) + echo "Oops? $filename" + false + ;; + esac && + test -f "$filename" +' + +test_expect_success 'format-patch from a subdirectory (2)' ' + filename=$( + rm -rf sub && + mkdir -p sub/dir && + cd sub/dir && + git format-patch -1 -o .. + ) && + case "$filename" in + ../0*) + ;; # ok + *) + echo "Oops? $filename" + false + ;; + esac && + basename=$(expr "$filename" : ".*/\(.*\)") && + test -f "sub/$basename" +' + +test_expect_success 'format-patch from a subdirectory (3)' ' + here="$TEST_DIRECTORY/$test" && + rm -f 0* && + filename=$( + rm -rf sub && + mkdir -p sub/dir && + cd sub/dir && + git format-patch -1 -o "$here" + ) && + basename=$(expr "$filename" : ".*/\(.*\)") && + test -f "$basename" +' + test_done diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index fc2307eaa3..6d13da30da 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -98,6 +98,12 @@ index d99af23..8b32fb5 100644 EOF git diff -w > out test_expect_success 'another test, with -w' 'test_cmp expect out' +git diff -w -b > out +test_expect_success 'another test, with -w -b' 'test_cmp expect out' +git diff -w --ignore-space-at-eol > out +test_expect_success 'another test, with -w --ignore-space-at-eol' 'test_cmp expect out' +git diff -w -b --ignore-space-at-eol > out +test_expect_success 'another test, with -w -b --ignore-space-at-eol' 'test_cmp expect out' tr 'Q' '\015' << EOF > expect diff --git a/x b/x @@ -116,6 +122,27 @@ index d99af23..8b32fb5 100644 EOF git diff -b > out test_expect_success 'another test, with -b' 'test_cmp expect out' +git diff -b --ignore-space-at-eol > out +test_expect_success 'another test, with -b --ignore-space-at-eol' 'test_cmp expect out' + +tr 'Q' '\015' << EOF > expect +diff --git a/x b/x +index d99af23..8b32fb5 100644 +--- a/x ++++ b/x +@@ -1,6 +1,6 @@ +-whitespace at beginning +-whitespace change +-whitespace in the middle ++ whitespace at beginning ++whitespace change ++white space in the middle + whitespace at end + unchanged line + CR at endQ +EOF +git diff --ignore-space-at-eol > out +test_expect_success 'another test, with --ignore-space-at-eol' 'test_cmp expect out' test_expect_success 'check mixed spaces and tabs in indent' ' diff --git a/t/t4029-diff-trailing-space.sh b/t/t4029-diff-trailing-space.sh index 4ca65e0332..9ddbbcde57 100755 --- a/t/t4029-diff-trailing-space.sh +++ b/t/t4029-diff-trailing-space.sh @@ -2,7 +2,7 @@ # # Copyright (c) Jim Meyering # -test_description='diff honors config option, diff.suppress-blank-empty' +test_description='diff honors config option, diff.suppressBlankEmpty' . ./test-lib.sh @@ -24,14 +24,14 @@ test_expect_success \ git add f && git commit -q -m. f && printf "\ny\n" > f && - git config --bool diff.suppress-blank-empty true && + git config --bool diff.suppressBlankEmpty true && git diff f > actual && test_cmp exp actual && perl -i.bak -p -e "s/^\$/ /" exp && - git config --bool diff.suppress-blank-empty false && + git config --bool diff.suppressBlankEmpty false && git diff f > actual && test_cmp exp actual && - git config --bool --unset diff.suppress-blank-empty && + git config --bool --unset diff.suppressBlankEmpty && git diff f > actual && test_cmp exp actual ' diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh index 2f27a0ba9e..a3f0897a52 100755 --- a/t/t4030-diff-textconv.sh +++ b/t/t4030-diff-textconv.sh @@ -104,7 +104,7 @@ cat >expect.typechange <<'EOF' -1 diff --git a/file b/file new file mode 120000 -index ad8b3d2..67be421 +index 0000000..67be421 --- /dev/null +++ b/file @@ -0,0 +1 @@ diff --git a/t/t4114-apply-typechange.sh b/t/t4114-apply-typechange.sh index 55334927ab..0f185caa44 100755 --- a/t/t4114-apply-typechange.sh +++ b/t/t4114-apply-typechange.sh @@ -25,6 +25,10 @@ test_expect_success 'setup repository and commits' ' git update-index foo && git commit -m "foo back to file" && git branch foo-back-to-file && + printf "\0" > foo && + git update-index foo && + git commit -m "foo becomes binary" && + git branch foo-becomes-binary && rm -f foo && git update-index --remove foo && mkdir foo && @@ -85,6 +89,20 @@ test_expect_success 'symlink becomes file' ' ' test_debug 'cat patch' +test_expect_success 'binary file becomes symlink' ' + git checkout -f foo-becomes-binary && + git diff-tree -p --binary HEAD foo-symlinked-to-bar > patch && + git apply --index < patch + ' +test_debug 'cat patch' + +test_expect_success 'symlink becomes binary file' ' + git checkout -f foo-symlinked-to-bar && + git diff-tree -p --binary HEAD foo-becomes-binary > patch && + git apply --index < patch + ' +test_debug 'cat patch' + test_expect_success 'symlink becomes directory' ' git checkout -f foo-symlinked-to-bar && diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh new file mode 100755 index 0000000000..adfcbb5a3b --- /dev/null +++ b/t/t4129-apply-samemode.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +test_description='applying patch with mode bits' + +. ./test-lib.sh + +test_expect_success setup ' + echo original >file && + git add file && + test_tick && + git commit -m initial && + git tag initial && + echo modified >file && + git diff --stat -p >patch-0.txt && + chmod +x file && + git diff --stat -p >patch-1.txt +' + +test_expect_success 'same mode (no index)' ' + git reset --hard && + chmod +x file && + git apply patch-0.txt && + test -x file +' + +test_expect_success 'same mode (with index)' ' + git reset --hard && + chmod +x file && + git add file && + git apply --index patch-0.txt && + test -x file && + git diff --exit-code +' + +test_expect_success 'same mode (index only)' ' + git reset --hard && + chmod +x file && + git add file && + git apply --cached patch-0.txt && + git ls-files -s file | grep "^100755" +' + +test_expect_success 'mode update (no index)' ' + git reset --hard && + git apply patch-1.txt && + test -x file +' + +test_expect_success 'mode update (with index)' ' + git reset --hard && + git apply --index patch-1.txt && + test -x file && + git diff --exit-code +' + +test_expect_success 'mode update (index only)' ' + git reset --hard && + git apply --cached patch-1.txt && + git ls-files -s file | grep "^100755" +' + +test_done diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh index fe14589427..e70ea94a13 100755 --- a/t/t5100-mailinfo.sh +++ b/t/t5100-mailinfo.sh @@ -11,7 +11,7 @@ test_expect_success 'split sample box' \ 'git mailsplit -o. "$TEST_DIRECTORY"/t5100/sample.mbox >last && last=`cat last` && echo total is $last && - test `cat last` = 11' + test `cat last` = 13' for mail in `echo 00*` do @@ -26,6 +26,28 @@ do ' done + +test_expect_success 'split box with rfc2047 samples' \ + 'mkdir rfc2047 && + git mailsplit -orfc2047 "$TEST_DIRECTORY"/t5100/rfc2047-samples.mbox \ + >rfc2047/last && + last=`cat rfc2047/last` && + echo total is $last && + test `cat rfc2047/last` = 11' + +for mail in `echo rfc2047/00*` +do + test_expect_success "mailinfo $mail" ' + git mailinfo -u $mail-msg $mail-patch <$mail >$mail-info && + echo msg && + test_cmp "$TEST_DIRECTORY"/t5100/empty $mail-msg && + echo patch && + test_cmp "$TEST_DIRECTORY"/t5100/empty $mail-patch && + echo info && + test_cmp "$TEST_DIRECTORY"/t5100/rfc2047-info-$(basename $mail) $mail-info + ' +done + test_expect_success 'respect NULs' ' git mailsplit -d3 -o. "$TEST_DIRECTORY"/t5100/nul-plain && diff --git a/t/t5100/empty b/t/t5100/empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/t/t5100/empty diff --git a/t/t5100/info0012 b/t/t5100/info0012 new file mode 100644 index 0000000000..ac1216ff75 --- /dev/null +++ b/t/t5100/info0012 @@ -0,0 +1,5 @@ +Author: Dmitriy Blinov +Email: bda@mnsspb.ru +Subject: Изменён список пакетов необходимых для сборки +Date: Wed, 12 Nov 2008 17:54:41 +0300 + diff --git a/t/t5100/info0013 b/t/t5100/info0013 new file mode 100644 index 0000000000..bbe049e20e --- /dev/null +++ b/t/t5100/info0013 @@ -0,0 +1,5 @@ +Author: A U Thor +Email: a.u.thor@example.com +Subject: a patch +Date: Fri, 9 Jun 2006 00:44:16 -0700 + diff --git a/t/t5100/msg0012 b/t/t5100/msg0012 new file mode 100644 index 0000000000..1dc2bf7f7f --- /dev/null +++ b/t/t5100/msg0012 @@ -0,0 +1,7 @@ +textlive-* исправлены на texlive-* +docutils заменён на python-docutils + +Действительно, оказалось, что rest2web вытягивает за собой +python-docutils. В то время как сам rest2web не нужен. + +Signed-off-by: Dmitriy Blinov <bda@mnsspb.ru> diff --git a/t/t5100/msg0013 b/t/t5100/msg0013 new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/t/t5100/msg0013 diff --git a/t/t5100/patch0012 b/t/t5100/patch0012 new file mode 100644 index 0000000000..36a0b68161 --- /dev/null +++ b/t/t5100/patch0012 @@ -0,0 +1,30 @@ +--- + howto/build_navy.txt | 6 +++--- + 1 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/howto/build_navy.txt b/howto/build_navy.txt +index 3fd3afb..0ee807e 100644 +--- a/howto/build_navy.txt ++++ b/howto/build_navy.txt +@@ -119,8 +119,8 @@ + - libxv-dev + - libusplash-dev + - latex-make +- - textlive-lang-cyrillic +- - textlive-latex-extra ++ - texlive-lang-cyrillic ++ - texlive-latex-extra + - dia + - python-pyrex + - libtool +@@ -128,7 +128,7 @@ + - sox + - cython + - imagemagick +- - docutils ++ - python-docutils + + #. на машине dinar: добавить свой открытый ssh-ключ в authorized_keys2 пользователя ddev + #. на своей машине: отредактировать /etc/sudoers (команда ``visudo``) примерно следующим образом:: +-- +1.5.6.5 diff --git a/t/t5100/patch0013 b/t/t5100/patch0013 new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/t/t5100/patch0013 diff --git a/t/t5100/rfc2047-info-0001 b/t/t5100/rfc2047-info-0001 new file mode 100644 index 0000000000..0a383b07e3 --- /dev/null +++ b/t/t5100/rfc2047-info-0001 @@ -0,0 +1,4 @@ +Author: Keith Moore +Email: moore@cs.utk.edu +Subject: If you can read this you understand the example. + diff --git a/t/t5100/rfc2047-info-0002 b/t/t5100/rfc2047-info-0002 new file mode 100644 index 0000000000..881be75d6f --- /dev/null +++ b/t/t5100/rfc2047-info-0002 @@ -0,0 +1,4 @@ +Author: Olle Järnefors +Email: ojarnef@admin.kth.se +Subject: Time for ISO 10646? + diff --git a/t/t5100/rfc2047-info-0003 b/t/t5100/rfc2047-info-0003 new file mode 100644 index 0000000000..d0f789177c --- /dev/null +++ b/t/t5100/rfc2047-info-0003 @@ -0,0 +1,4 @@ +Author: Patrik Fältström +Email: paf@nada.kth.se +Subject: RFC-HDR care and feeding + diff --git a/t/t5100/rfc2047-info-0004 b/t/t5100/rfc2047-info-0004 new file mode 100644 index 0000000000..0ca7ff0529 --- /dev/null +++ b/t/t5100/rfc2047-info-0004 @@ -0,0 +1,4 @@ +Author: Nathaniel Borenstein (םולש ןב ילטפנ) +Email: nsb@thumper.bellcore.com +Subject: Test of new header generator + diff --git a/t/t5100/rfc2047-info-0005 b/t/t5100/rfc2047-info-0005 new file mode 100644 index 0000000000..c27be3bf24 --- /dev/null +++ b/t/t5100/rfc2047-info-0005 @@ -0,0 +1,2 @@ +Subject: (a) + diff --git a/t/t5100/rfc2047-info-0006 b/t/t5100/rfc2047-info-0006 new file mode 100644 index 0000000000..9dad474456 --- /dev/null +++ b/t/t5100/rfc2047-info-0006 @@ -0,0 +1,2 @@ +Subject: (a b) + diff --git a/t/t5100/rfc2047-info-0007 b/t/t5100/rfc2047-info-0007 new file mode 100644 index 0000000000..294f195a57 --- /dev/null +++ b/t/t5100/rfc2047-info-0007 @@ -0,0 +1,2 @@ +Subject: (ab) + diff --git a/t/t5100/rfc2047-info-0008 b/t/t5100/rfc2047-info-0008 new file mode 100644 index 0000000000..294f195a57 --- /dev/null +++ b/t/t5100/rfc2047-info-0008 @@ -0,0 +1,2 @@ +Subject: (ab) + diff --git a/t/t5100/rfc2047-info-0009 b/t/t5100/rfc2047-info-0009 new file mode 100644 index 0000000000..294f195a57 --- /dev/null +++ b/t/t5100/rfc2047-info-0009 @@ -0,0 +1,2 @@ +Subject: (ab) + diff --git a/t/t5100/rfc2047-info-0010 b/t/t5100/rfc2047-info-0010 new file mode 100644 index 0000000000..9dad474456 --- /dev/null +++ b/t/t5100/rfc2047-info-0010 @@ -0,0 +1,2 @@ +Subject: (a b) + diff --git a/t/t5100/rfc2047-info-0011 b/t/t5100/rfc2047-info-0011 new file mode 100644 index 0000000000..9dad474456 --- /dev/null +++ b/t/t5100/rfc2047-info-0011 @@ -0,0 +1,2 @@ +Subject: (a b) + diff --git a/t/t5100/rfc2047-samples.mbox b/t/t5100/rfc2047-samples.mbox new file mode 100644 index 0000000000..3ca2470da2 --- /dev/null +++ b/t/t5100/rfc2047-samples.mbox @@ -0,0 +1,48 @@ +From nobody Mon Sep 17 00:00:00 2001 +From: =?US-ASCII?Q?Keith_Moore?= <moore@cs.utk.edu> +To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld@dkuug.dk> +CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be> +Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?= + =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?= + +From nobody Mon Sep 17 00:00:00 2001 +From: =?ISO-8859-1?Q?Olle_J=E4rnefors?= <ojarnef@admin.kth.se> +To: ietf-822@dimacs.rutgers.edu, ojarnef@admin.kth.se +Subject: Time for ISO 10646? + +From nobody Mon Sep 17 00:00:00 2001 +To: Dave Crocker <dcrocker@mordor.stanford.edu> +Cc: ietf-822@dimacs.rutgers.edu, paf@comsol.se +From: =?ISO-8859-1?Q?Patrik_F=E4ltstr=F6m?= <paf@nada.kth.se> +Subject: Re: RFC-HDR care and feeding + +From nobody Mon Sep 17 00:00:00 2001 +From: Nathaniel Borenstein <nsb@thumper.bellcore.com> + (=?iso-8859-8?b?7eXs+SDv4SDp7Oj08A==?=) +To: Greg Vaudreuil <gvaudre@NRI.Reston.VA.US>, Ned Freed + <ned@innosoft.com>, Keith Moore <moore@cs.utk.edu> +Subject: Test of new header generator +MIME-Version: 1.0 +Content-type: text/plain; charset=ISO-8859-1 + +From nobody Mon Sep 17 00:00:00 2001 +Subject: (=?ISO-8859-1?Q?a?=) + +From nobody Mon Sep 17 00:00:00 2001 +Subject: (=?ISO-8859-1?Q?a?= b) + +From nobody Mon Sep 17 00:00:00 2001 +Subject: (=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=) + +From nobody Mon Sep 17 00:00:00 2001 +Subject: (=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=) + +From nobody Mon Sep 17 00:00:00 2001 +Subject: (=?ISO-8859-1?Q?a?= + =?ISO-8859-1?Q?b?=) + +From nobody Mon Sep 17 00:00:00 2001 +Subject: (=?ISO-8859-1?Q?a_b?=) + +From nobody Mon Sep 17 00:00:00 2001 +Subject: (=?ISO-8859-1?Q?a?= =?ISO-8859-2?Q?_b?=) diff --git a/t/t5100/sample.mbox b/t/t5100/sample.mbox index 4bf7947b41..85df55f2c4 100644 --- a/t/t5100/sample.mbox +++ b/t/t5100/sample.mbox @@ -2,7 +2,10 @@ From nobody Mon Sep 17 00:00:00 2001 -From: A U Thor <a.u.thor@example.com> +From: A + U + Thor + <a.u.thor@example.com> Date: Fri, 9 Jun 2006 00:44:16 -0700 Subject: [PATCH] a commit. @@ -501,3 +504,60 @@ index 3e5fe51..aabfe5c 100644 --=-=-=-- +From bda@mnsspb.ru Wed Nov 12 17:54:41 2008 +From: Dmitriy Blinov <bda@mnsspb.ru> +To: navy-patches@dinar.mns.mnsspb.ru +Date: Wed, 12 Nov 2008 17:54:41 +0300 +Message-Id: <1226501681-24923-1-git-send-email-bda@mnsspb.ru> +X-Mailer: git-send-email 1.5.6.5 +MIME-Version: 1.0 +Content-Type: text/plain; + charset=utf-8 +Content-Transfer-Encoding: 8bit +Subject: [Navy-patches] [PATCH] + =?utf-8?b?0JjQt9C80LXQvdGR0L0g0YHQv9C40YHQvtC6INC/0LA=?= + =?utf-8?b?0LrQtdGC0L7QsiDQvdC10L7QsdGF0L7QtNC40LzRi9GFINC00LvRjyA=?= + =?utf-8?b?0YHQsdC+0YDQutC4?= + +textlive-* исправлены на texlive-* +docutils заменён на python-docutils + +Действительно, оказалось, что rest2web вытягивает за собой +python-docutils. В то время как сам rest2web не нужен. + +Signed-off-by: Dmitriy Blinov <bda@mnsspb.ru> +--- + howto/build_navy.txt | 6 +++--- + 1 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/howto/build_navy.txt b/howto/build_navy.txt +index 3fd3afb..0ee807e 100644 +--- a/howto/build_navy.txt ++++ b/howto/build_navy.txt +@@ -119,8 +119,8 @@ + - libxv-dev + - libusplash-dev + - latex-make +- - textlive-lang-cyrillic +- - textlive-latex-extra ++ - texlive-lang-cyrillic ++ - texlive-latex-extra + - dia + - python-pyrex + - libtool +@@ -128,7 +128,7 @@ + - sox + - cython + - imagemagick +- - docutils ++ - python-docutils + + #. на машине dinar: добавить свой открытый ssh-ключ в authorized_keys2 пользователя ddev + #. на своей машине: отредактировать /etc/sudoers (команда ``visudo``) примерно следующим образом:: +-- +1.5.6.5 +From nobody Mon Sep 17 00:00:00 2001 +From: <a.u.thor@example.com> (A U Thor) +Date: Fri, 9 Jun 2006 00:44:16 -0700 +Subject: [PATCH] a patch + diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 04522857ab..ccfc64c6ee 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -180,6 +180,23 @@ test_expect_success \ unset GIT_OBJECT_DIRECTORY +test_expect_success 'survive missing objects/pack directory' ' + ( + rm -fr missing-pack && + mkdir missing-pack && + cd missing-pack && + git init && + GOP=.git/objects/pack + rm -fr $GOP && + git index-pack --stdin --keep=test <../test-3-${packname_3}.pack && + test -f $GOP/pack-${packname_3}.pack && + test_cmp $GOP/pack-${packname_3}.pack ../test-3-${packname_3}.pack && + test -f $GOP/pack-${packname_3}.idx && + test_cmp $GOP/pack-${packname_3}.idx ../test-3-${packname_3}.idx && + test -f $GOP/pack-${packname_3}.keep + ) +' + test_expect_success \ 'verify pack' \ 'git verify-pack test-1-${packname_1}.idx \ diff --git a/t/t5307-pack-missing-commit.sh b/t/t5307-pack-missing-commit.sh new file mode 100755 index 0000000000..ae52a1882d --- /dev/null +++ b/t/t5307-pack-missing-commit.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +test_description='pack should notice missing commit objects' + +. ./test-lib.sh + +test_expect_success setup ' + for i in 1 2 3 4 5 + do + echo "$i" >"file$i" && + git add "file$i" && + test_tick && + git commit -m "$i" && + git tag "tag$i" + done && + obj=$(git rev-parse --verify tag3) && + fanout=$(expr "$obj" : "\(..\)") && + remainder=$(expr "$obj" : "..\(.*\)") && + rm -f ".git/objects/$fanout/$remainder" +' + +test_expect_success 'check corruption' ' + test_must_fail git fsck +' + +test_expect_success 'rev-list notices corruption (1)' ' + test_must_fail git rev-list HEAD +' + +test_expect_success 'rev-list notices corruption (2)' ' + test_must_fail git rev-list --objects HEAD +' + +test_expect_success 'pack-objects notices corruption' ' + echo HEAD | + test_must_fail git pack-objects --revs pack +' + +test_done diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh index da69f087b4..b21317d685 100755 --- a/t/t5400-send-pack.sh +++ b/t/t5400-send-pack.sh @@ -99,7 +99,7 @@ test_expect_success \ ! test -f victim/.git/refs/heads/extra ' -unset GIT_CONFIG GIT_CONFIG_LOCAL +unset GIT_CONFIG HOME=`pwd`/no-such-directory export HOME ;# this way we force the victim/.git/config to be used. diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 1f59960d90..bc5b7ce4a6 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -107,6 +107,32 @@ test_expect_success 'remove remote' ' ) ' +test_expect_success 'remove remote protects non-remote branches' ' +( + cd test && + (cat >expect1 <<EOF +Note: A non-remote branch was not removed; to delete it, use: + git branch -d master +EOF + cat >expect2 <<EOF +Note: Non-remote branches were not removed; to delete them, use: + git branch -d foobranch + git branch -d master +EOF +) && + git tag footag + git config --add remote.oops.fetch "+refs/*:refs/*" && + git remote rm oops 2>actual1 && + git branch foobranch && + git config --add remote.oops.fetch "+refs/*:refs/*" && + git remote rm oops 2>actual2 && + git branch -d foobranch && + git tag -d footag && + test_cmp expect1 actual1 && + test_cmp expect2 actual2 +) +' + cat > test/expect << EOF * remote origin URL: $(pwd)/one diff --git a/t/t5519-push-alternates.sh b/t/t5519-push-alternates.sh new file mode 100755 index 0000000000..96be5236a2 --- /dev/null +++ b/t/t5519-push-alternates.sh @@ -0,0 +1,143 @@ +#!/bin/sh + +test_description='push to a repository that borrows from elsewhere' + +. ./test-lib.sh + +test_expect_success setup ' + mkdir alice-pub && + ( + cd alice-pub && + GIT_DIR=. git init + ) && + mkdir alice-work && + ( + cd alice-work && + git init && + >file && + git add . && + git commit -m initial && + git push ../alice-pub master + ) && + + # Project Bob is a fork of project Alice + mkdir bob-pub && + ( + cd bob-pub && + GIT_DIR=. git init && + mkdir -p objects/info && + echo ../../alice-pub/objects >objects/info/alternates + ) && + git clone alice-pub bob-work && + ( + cd bob-work && + git push ../bob-pub master + ) +' + +test_expect_success 'alice works and pushes' ' + ( + cd alice-work && + echo more >file && + git commit -a -m second && + git push ../alice-pub + ) +' + +test_expect_success 'bob fetches from alice, works and pushes' ' + ( + # Bob acquires what Alice did in his work tree first. + # Even though these objects are not directly in + # the public repository of Bob, this push does not + # need to send the commit Bob received from Alice + # to his public repository, as all the object Alice + # has at her public repository are available to it + # via its alternates. + cd bob-work && + git pull ../alice-pub master && + echo more bob >file && + git commit -a -m third && + git push ../bob-pub + ) && + + # Check that the second commit by Alice is not sent + # to ../bob-pub + ( + cd bob-pub && + second=$(git rev-parse HEAD^) && + rm -f objects/info/alternates && + test_must_fail git cat-file -t $second && + echo ../../alice-pub/objects >objects/info/alternates + ) +' + +test_expect_success 'clean-up in case the previous failed' ' + ( + cd bob-pub && + echo ../../alice-pub/objects >objects/info/alternates + ) +' + +test_expect_success 'alice works and pushes again' ' + ( + # Alice does not care what Bob does. She does not + # even have to be aware of his existence. She just + # keeps working and pushing + cd alice-work && + echo more alice >file && + git commit -a -m fourth && + git push ../alice-pub + ) +' + +test_expect_success 'bob works and pushes' ' + ( + # This time Bob does not pull from Alice, and + # the master branch at her public repository points + # at a commit Bob does not know about. This should + # not prevent the push by Bob from succeeding. + cd bob-work && + echo yet more bob >file && + git commit -a -m fifth && + git push ../bob-pub + ) +' + +test_expect_success 'alice works and pushes yet again' ' + ( + # Alice does not care what Bob does. She does not + # even have to be aware of his existence. She just + # keeps working and pushing + cd alice-work && + echo more and more alice >file && + git commit -a -m sixth.1 && + echo more and more alice >>file && + git commit -a -m sixth.2 && + echo more and more alice >>file && + git commit -a -m sixth.3 && + git push ../alice-pub + ) +' + +test_expect_success 'bob works and pushes again' ' + ( + cd alice-pub && + git cat-file commit master >../bob-work/commit + ) + ( + # This time Bob does not pull from Alice, and + # the master branch at her public repository points + # at a commit Bob does not fully know about, but + # he happens to have the commit object (but not the + # necessary tree) in his repository from Alice. + # This should not prevent the push by Bob from + # succeeding. + cd bob-work && + git hash-object -t commit -w commit && + echo even more bob >file && + git commit -a -m seventh && + git push ../bob-pub + ) +' + +test_done diff --git a/t/t5521-pull-symlink.sh b/t/t5521-pull-symlink.sh new file mode 100755 index 0000000000..5672b51e2e --- /dev/null +++ b/t/t5521-pull-symlink.sh @@ -0,0 +1,78 @@ +#!/bin/sh + +test_description='pulling from symlinked subdir' + +. ./test-lib.sh + +# The scenario we are building: +# +# trash\ directory/ +# clone-repo/ +# subdir/ +# bar +# subdir-link -> clone-repo/subdir/ +# +# The working directory is subdir-link. + +mkdir subdir +echo file >subdir/file +git add subdir/file +git commit -q -m file +git clone -q . clone-repo +ln -s clone-repo/subdir/ subdir-link + + +# Demonstrate that things work if we just avoid the symlink +# +test_expect_success 'pulling from real subdir' ' + ( + echo real >subdir/file && + git commit -m real subdir/file && + cd clone-repo/subdir/ && + git pull && + test real = $(cat file) + ) +' + +# From subdir-link, pulling should work as it does from +# clone-repo/subdir/. +# +# Instead, the error pull gave was: +# +# fatal: 'origin': unable to chdir or not a git archive +# fatal: The remote end hung up unexpectedly +# +# because git would find the .git/config for the "trash directory" +# repo, not for the clone-repo repo. The "trash directory" repo +# had no entry for origin. Git found the wrong .git because +# git rev-parse --show-cdup printed a path relative to +# clone-repo/subdir/, not subdir-link/. Git rev-parse --show-cdup +# used the correct .git, but when the git pull shell script did +# "cd `git rev-parse --show-cdup`", it ended up in the wrong +# directory. A POSIX shell's "cd" works a little differently +# than chdir() in C; "cd -P" is much closer to chdir(). +# +test_expect_success 'pulling from symlinked subdir' ' + ( + echo link >subdir/file && + git commit -m link subdir/file && + cd subdir-link/ && + git pull && + test link = $(cat file) + ) +' + +# Prove that the remote end really is a repo, and other commands +# work fine in this context. It's just that "git pull" breaks. +# +test_expect_success 'pushing from symlinked subdir' ' + ( + cd subdir-link/ && + echo push >file && + git commit -m push ./file && + git push + ) && + test push = $(git show HEAD:subdir/file) +' + +test_done diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh index da9588645c..c236b5e83b 100755 --- a/t/t5540-http-push.sh +++ b/t/t5540-http-push.sh @@ -51,17 +51,29 @@ test_expect_success 'clone remote repository' ' git clone $HTTPD_URL/test_repo.git test_repo_clone ' -test_expect_failure 'push to remote repository' ' +test_expect_failure 'push to remote repository with packed refs' ' cd "$ROOT_PATH"/test_repo_clone && : >path2 && git add path2 && test_tick && git commit -m path2 && + HEAD=$(git rev-parse --verify HEAD) && git push && - [ -f "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/refs/heads/master" ] + (cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git && + test $HEAD = $(git rev-parse --verify HEAD)) ' -test_expect_failure 'create and delete remote branch' ' +test_expect_success ' push to remote repository with unpacked refs' ' + (cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git && + rm packed-refs && + git update-ref refs/heads/master \ + 0c973ae9bd51902a28466f3850b543fa66a6aaf4) && + git push && + (cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git && + test $HEAD = $(git rev-parse --verify HEAD)) +' + +test_expect_success 'create and delete remote branch' ' cd "$ROOT_PATH"/test_repo_clone && git checkout -b dev && : >path3 && @@ -76,6 +88,12 @@ test_expect_failure 'create and delete remote branch' ' test_must_fail git show-ref --verify refs/remotes/origin/dev ' +test_expect_success 'MKCOL sends directory names with trailing slashes' ' + + ! grep "\"MKCOL.*[^/] HTTP/[^ ]*\"" < "$HTTPD_ROOT_PATH"/access.log + +' + stop_httpd test_done diff --git a/t/t5701-clone-local.sh b/t/t5701-clone-local.sh index 8dfaaa456e..fe0fda282c 100755 --- a/t/t5701-clone-local.sh +++ b/t/t5701-clone-local.sh @@ -11,8 +11,8 @@ test_expect_success 'preparing origin repository' ' git clone --bare . x && test "$(GIT_CONFIG=a.git/config git config --bool core.bare)" = true && test "$(GIT_CONFIG=x/config git config --bool core.bare)" = true - git bundle create b1.bundle --all HEAD && - git bundle create b2.bundle --all && + git bundle create b1.bundle --all && + git bundle create b2.bundle master && mkdir dir && cp b1.bundle dir/b3 cp b1.bundle b4 diff --git a/t/t6014-rev-list-all.sh b/t/t6014-rev-list-all.sh new file mode 100755 index 0000000000..991ab4a65b --- /dev/null +++ b/t/t6014-rev-list-all.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +test_description='--all includes detached HEADs' + +. ./test-lib.sh + + +commit () { + test_tick && + echo $1 > foo && + git add foo && + git commit -m "$1" +} + +test_expect_success 'setup' ' + + commit one && + commit two && + git checkout HEAD^ && + commit detached + +' + +test_expect_success 'rev-list --all lists detached HEAD' ' + + test 3 = $(git rev-list --all | wc -l) + +' + +test_expect_success 'repack does not lose detached HEAD' ' + + git gc && + git prune --expire=now && + git show HEAD + +' + +test_done diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh index 802d0d06eb..129fa3000c 100755 --- a/t/t6024-recursive-merge.sh +++ b/t/t6024-recursive-merge.sh @@ -97,4 +97,27 @@ test_expect_success 'refuse to merge binary files' ' merge.err ' +test_expect_success 'mark rename/delete as unmerged' ' + + git reset --hard && + git checkout -b delete && + git rm a1 && + test_tick && + git commit -m delete && + git checkout -b rename HEAD^ && + git mv a1 a2 + test_tick && + git commit -m rename && + test_must_fail git merge delete && + test 1 = $(git ls-files --unmerged | wc -l) && + git rev-parse --verify :2:a2 && + test_must_fail git rev-parse --verify :3:a2 && + git checkout -f delete && + test_must_fail git merge rename && + test 1 = $(git ls-files --unmerged | wc -l) && + test_must_fail git rev-parse --verify :2:a2 && + git rev-parse --verify :3:a2 + +' + test_done diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index dd7eac84ea..052a6c90f5 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -224,6 +224,31 @@ test_expect_success 'bisect skip: cannot tell between 2 commits' ' fi ' +# $HASH1 is good, $HASH4 is both skipped and bad, we skip $HASH3 +# and $HASH2 is good, +# so we should not be able to tell the first bad commit +# among $HASH3 and $HASH4 +test_expect_success 'bisect skip: with commit both bad and skipped' ' + git bisect start && + git bisect skip && + git bisect bad && + git bisect good $HASH1 && + git bisect skip && + if git bisect good > my_bisect_log.txt + then + echo Oops, should have failed. + false + else + test $? -eq 2 && + grep "first bad commit could be any of" my_bisect_log.txt && + ! grep $HASH1 my_bisect_log.txt && + ! grep $HASH2 my_bisect_log.txt && + grep $HASH3 my_bisect_log.txt && + grep $HASH4 my_bisect_log.txt && + git bisect reset + fi +' + # We want to automatically find the commit that # introduced "Another" into hello. test_expect_success \ diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index e6c9e59b61..8c7e081c53 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -100,6 +100,12 @@ check_describe B --tags HEAD^^2^ check_describe B-0-* --long HEAD^^2^ check_describe A-3-* --long HEAD^^2 +: >err.expect +check_describe A --all A^0 +test_expect_success 'no warning was displayed for A' ' + test_cmp err.expect err.actual +' + test_expect_success 'rename tag A to Q locally' ' mv .git/refs/tags/A .git/refs/tags/Q ' diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 575ef5beb2..8fb3a56838 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -39,6 +39,39 @@ test_expect_success \ grep "^R100..*path1/COPYING..*path0/COPYING"' test_expect_success \ + 'checking -k on non-existing file' \ + 'git mv -k idontexist path0' + +test_expect_success \ + 'checking -k on untracked file' \ + 'touch untracked1 && + git mv -k untracked1 path0 && + test -f untracked1 && + test ! -f path0/untracked1' + +test_expect_success \ + 'checking -k on multiple untracked files' \ + 'touch untracked2 && + git mv -k untracked1 untracked2 path0 && + test -f untracked1 && + test -f untracked2 && + test ! -f path0/untracked1 && + test ! -f path0/untracked2' + +test_expect_success \ + 'checking -f on untracked file with existing target' \ + 'touch path0/untracked1 && + git mv -f untracked1 path0 + test ! -f .git/index.lock && + test -f untracked1 && + test -f path0/untracked1' + +# clean up the mess in case bad things happen +rm -f idontexist untracked1 untracked2 \ + path0/idontexist path0/untracked1 path0/untracked2 \ + .git/index.lock + +test_expect_success \ 'adding another file' \ 'cp "$TEST_DIRECTORY"/../README path0/README && git add path0/README && diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh index 18fe6f2d57..c4938544d4 100755 --- a/t/t7002-grep.sh +++ b/t/t7002-grep.sh @@ -161,7 +161,14 @@ test_expect_success 'log grep (6)' ' git log --author=-0700 --pretty=tformat:%s >actual && >expect && test_cmp expect actual +' +test_expect_success 'grep with CE_VALID file' ' + git update-index --assume-unchanged t/t && + rm t/t && + test "$(git grep --no-ext-grep t)" = "t/t:test" && + git update-index --no-assume-unchanged t/t && + git checkout t/t ' test_done diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index b0a9d7d536..6a9936e5c4 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -39,7 +39,9 @@ test_expect_success 'result is really identical' ' ' test_expect_success 'rewrite bare repository identically' ' - (git config core.bare true && cd .git && git filter-branch branch) + (git config core.bare true && cd .git && + git filter-branch branch > filter-output 2>&1 && + ! fgrep fatal filter-output) ' git config core.bare false test_expect_success 'result is really identical' ' diff --git a/t/t7007-show.sh b/t/t7007-show.sh new file mode 100755 index 0000000000..cce222f052 --- /dev/null +++ b/t/t7007-show.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +test_description='git show' + +. ./test-lib.sh + +test_expect_success setup ' + echo hello world >foo && + H=$(git hash-object -w foo) && + git tag -a foo-tag -m "Tags $H" $H && + HH=$(expr "$H" : "\(..\)") && + H38=$(expr "$H" : "..\(.*\)") && + rm -f .git/objects/$HH/$H38 +' + +test_expect_success 'showing a tag that point at a missing object' ' + test_must_fail git --no-pager show foo-tag +' + +test_done diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index be73f7b60a..2ec7ac6a51 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -209,4 +209,29 @@ test_expect_success 'update --init' ' ' +test_expect_success 'do not add files from a submodule' ' + + git reset --hard && + test_must_fail git add init/a + +' + +test_expect_success 'gracefully add submodule with a trailing slash' ' + + git reset --hard && + git commit -m "commit subproject" init && + (cd init && + echo b > a) && + git add init/ && + git diff --exit-code --cached init && + commit=$(cd init && + git commit -m update a >/dev/null && + git rev-parse HEAD) && + git add init/ && + test_must_fail git diff --exit-code --cached init && + test $commit = $(git ls-files --stage | + sed -n "s/^160000 \([^ ]*\).*/\1/p") + +' + test_done diff --git a/t/t7607-merge-overwrite.sh b/t/t7607-merge-overwrite.sh new file mode 100755 index 0000000000..49f4e1599a --- /dev/null +++ b/t/t7607-merge-overwrite.sh @@ -0,0 +1,87 @@ +#!/bin/sh + +test_description='git-merge + +Do not overwrite changes.' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo c0 > c0.c && + git add c0.c && + git commit -m c0 && + git tag c0 && + echo c1 > c1.c && + git add c1.c && + git commit -m c1 && + git tag c1 && + git reset --hard c0 && + echo c2 > c2.c && + git add c2.c && + git commit -m c2 && + git tag c2 && + git reset --hard c1 && + echo "c1 a" > c1.c && + git add c1.c && + git commit -m "c1 a" && + git tag c1a && + echo "VERY IMPORTANT CHANGES" > important +' + +test_expect_success 'will not overwrite untracked file' ' + git reset --hard c1 && + cat important > c2.c && + ! git merge c2 && + test_cmp important c2.c +' + +test_expect_success 'will not overwrite new file' ' + git reset --hard c1 && + cat important > c2.c && + git add c2.c && + ! git merge c2 && + test_cmp important c2.c +' + +test_expect_success 'will not overwrite staged changes' ' + git reset --hard c1 && + cat important > c2.c && + git add c2.c && + rm c2.c && + ! git merge c2 && + git checkout c2.c && + test_cmp important c2.c +' + +test_expect_success 'will not overwrite removed file' ' + git reset --hard c1 && + git rm c1.c && + git commit -m "rm c1.c" && + cat important > c1.c && + ! git merge c1a && + test_cmp important c1.c +' + +test_expect_success 'will not overwrite re-added file' ' + git reset --hard c1 && + git rm c1.c && + git commit -m "rm c1.c" && + cat important > c1.c && + git add c1.c && + ! git merge c1a && + test_cmp important c1.c +' + +test_expect_success 'will not overwrite removed file with staged changes' ' + git reset --hard c1 && + git rm c1.c && + git commit -m "rm c1.c" && + cat important > c1.c && + git add c1.c && + rm c1.c && + ! git merge c1a && + git checkout c1.c && + test_cmp important c1.c +' + +test_done diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh index 938b7fe4b4..8a9dde44d5 100755 --- a/t/t9129-git-svn-i18n-commitencoding.sh +++ b/t/t9129-git-svn-i18n-commitencoding.sh @@ -60,21 +60,25 @@ do ' done -test_expect_success 'ISO-8859-1 should match UTF-8 in svn' ' -( - cd ISO-8859-1 && - compare_svn_head_with "$TEST_DIRECTORY"/t3900/1-UTF-8.txt -) -' - -for H in EUCJP ISO-2022-JP -do - test_expect_success '$H should match UTF-8 in svn' ' +if locale -a |grep -q en_US.utf8; then + test_expect_success 'ISO-8859-1 should match UTF-8 in svn' ' ( - cd $H && - compare_svn_head_with "$TEST_DIRECTORY"/t3900/2-UTF-8.txt + cd ISO-8859-1 && + compare_svn_head_with "$TEST_DIRECTORY"/t3900/1-UTF-8.txt ) ' -done + + for H in EUCJP ISO-2022-JP + do + test_expect_success '$H should match UTF-8 in svn' ' + ( + cd $H && + compare_svn_head_with "$TEST_DIRECTORY"/t3900/2-UTF-8.txt + ) + ' + done +else + say "UTF-8 locale not available, test skipped" +fi test_done diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 91b5aced1b..821be7ce8d 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -56,6 +56,12 @@ M 644 :2 file2 M 644 :3 file3 M 755 :4 file4 +tag series-A +from :5 +data <<EOF +An annotated tag without a tagger +EOF + INPUT_END test_expect_success \ 'A: create pack from stdin' \ @@ -102,6 +108,18 @@ test_expect_success \ 'git cat-file blob master:file4 >actual && test_cmp expect actual' cat >expect <<EOF +object $(git rev-parse refs/heads/master) +type commit +tag series-A + +An annotated tag without a tagger +EOF +test_expect_success 'A: verify tag/series-A' ' + git cat-file tag tags/series-A >actual && + test_cmp expect actual +' + +cat >expect <<EOF :2 `git rev-parse --verify master:file2` :3 `git rev-parse --verify master:file3` :4 `git rev-parse --verify master:file4` diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh index 2057435462..86c376088c 100755 --- a/t/t9301-fast-export.sh +++ b/t/t9301-fast-export.sh @@ -185,8 +185,8 @@ test_expect_success 'submodule fast-export | fast-import' ' ' -export GIT_AUTHOR_NAME='A U Thor' -export GIT_COMMITTER_NAME='C O Mitter' +GIT_AUTHOR_NAME='A U Thor'; export GIT_AUTHOR_NAME +GIT_COMMITTER_NAME='C O Mitter'; export GIT_COMMITTER_NAME test_expect_success 'setup copies' ' @@ -239,4 +239,24 @@ test_expect_success 'fast-export | fast-import when master is tagged' ' ' +cat > tag-content << EOF +object $(git rev-parse HEAD) +type commit +tag rosten +EOF + +test_expect_success 'cope with tagger-less tags' ' + + TAG=$(git hash-object -t tag -w tag-content) && + git update-ref refs/tags/sonnenschein $TAG && + git fast-export -C -C --signed-tags=strip --all > output && + test $(grep -c "^tag " output) = 4 && + ! grep "Unspecified Tagger" output && + git fast-export -C -C --signed-tags=strip --all \ + --fake-missing-tagger > output && + test $(grep -c "^tag " output) = 4 && + grep "Unspecified Tagger" output + +' + test_done diff --git a/t/test-lib.sh b/t/test-lib.sh index 8936173ee2..1b4f216385 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -82,7 +82,7 @@ do -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate) immediate=t; shift ;; -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests) - export GIT_TEST_LONG=t; shift ;; + GIT_TEST_LONG=t; export GIT_TEST_LONG; shift ;; -h|--h|--he|--hel|--help) help=t; shift ;; -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) @@ -441,14 +441,6 @@ test_done () { fi case "$test_failure" in 0) - # We could: - # cd .. && rm -fr 'trash directory' - # but that means we forbid any tests that use their own - # subdirectory from calling test_done without coming back - # to where they started from. - # The Makefile provided will clean this test area so - # we will leave things as they are. - say_color pass "passed all $msg" test -d "$remove_trash" && @@ -471,7 +463,6 @@ PATH=$TEST_DIRECTORY/..:$PATH GIT_EXEC_PATH=$(pwd)/.. GIT_TEMPLATE_DIR=$(pwd)/../templates/blt unset GIT_CONFIG -unset GIT_CONFIG_LOCAL GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_NOGLOBAL=1 export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL diff --git a/dump-cache-tree.c b/test-dump-cache-tree.c index 1f73f1ea7d..1f73f1ea7d 100644 --- a/dump-cache-tree.c +++ b/test-dump-cache-tree.c diff --git a/test-path-utils.c b/test-path-utils.c index a0bcb0e210..5168a8e3df 100644 --- a/test-path-utils.c +++ b/test-path-utils.c @@ -2,11 +2,13 @@ int main(int argc, char **argv) { - if (argc == 3 && !strcmp(argv[1], "normalize_absolute_path")) { - char *buf = xmalloc(strlen(argv[2])+1); - int rv = normalize_absolute_path(buf, argv[2]); - assert(strlen(buf) == rv); + if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) { + char *buf = xmalloc(PATH_MAX + 1); + int rv = normalize_path_copy(buf, argv[2]); + if (rv) + buf = "++failed++"; puts(buf); + return 0; } if (argc >= 2 && !strcmp(argv[1], "make_absolute_path")) { @@ -15,12 +17,16 @@ int main(int argc, char **argv) argc--; argv++; } + return 0; } if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) { int len = longest_ancestor_length(argv[2], argv[3]); printf("%d\n", len); + return 0; } - return 0; + fprintf(stderr, "%s: unknown function name: %s\n", argv[0], + argv[1] ? argv[1] : "(there was none)"); + return 1; } diff --git a/unpack-trees.c b/unpack-trees.c index 54f301da67..3a4e181af4 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -240,8 +240,11 @@ static struct cache_entry *create_ce_entry(const struct traverse_info *info, con return ce; } -static int unpack_nondirectories(int n, unsigned long mask, unsigned long dirmask, struct cache_entry *src[5], - const struct name_entry *names, const struct traverse_info *info) +static int unpack_nondirectories(int n, unsigned long mask, + unsigned long dirmask, + struct cache_entry **src, + const struct name_entry *names, + const struct traverse_info *info) { int i; struct unpack_trees_options *o = info->data; @@ -291,7 +294,7 @@ static int unpack_nondirectories(int n, unsigned long mask, unsigned long dirmas static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, struct name_entry *names, struct traverse_info *info) { - struct cache_entry *src[5] = { NULL, }; + struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, }; struct unpack_trees_options *o = info->data; const struct name_entry *p = names; @@ -494,7 +497,7 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, * anything in the existing directory there. */ int namelen; - int pos, i; + int i; struct dir_struct d; char *pathbuf; int cnt = 0; @@ -515,24 +518,20 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, * in that directory. */ namelen = strlen(ce->name); - pos = index_name_pos(o->src_index, ce->name, namelen); - if (0 <= pos) - return cnt; /* we have it as nondirectory */ - pos = -pos - 1; - for (i = pos; i < o->src_index->cache_nr; i++) { - struct cache_entry *ce = o->src_index->cache[i]; - int len = ce_namelen(ce); + for (i = o->pos; i < o->src_index->cache_nr; i++) { + struct cache_entry *ce2 = o->src_index->cache[i]; + int len = ce_namelen(ce2); if (len < namelen || - strncmp(ce->name, ce->name, namelen) || - ce->name[namelen] != '/') + strncmp(ce->name, ce2->name, namelen) || + ce2->name[namelen] != '/') break; /* - * ce->name is an entry in the subdirectory. + * ce2->name is an entry in the subdirectory. */ - if (!ce_stage(ce)) { - if (verify_uptodate(ce, o)) + if (!ce_stage(ce2)) { + if (verify_uptodate(ce2, o)) return -1; - add_entry(o, ce, CE_REMOVE, 0); + add_entry(o, ce2, CE_REMOVE, 0); } cnt++; } @@ -588,7 +587,7 @@ static int verify_absent(struct cache_entry *ce, const char *action, return 0; if (!lstat(ce->name, &st)) { - int cnt; + int ret; int dtype = ce_to_dtype(ce); struct cache_entry *result; @@ -616,13 +615,15 @@ static int verify_absent(struct cache_entry *ce, const char *action, * files that are in "foo/" we would lose * it. */ - cnt = verify_clean_subdirectory(ce, action, o); + ret = verify_clean_subdirectory(ce, action, o); + if (ret < 0) + return ret; /* * If this removed entries from the index, * what that means is: * - * (1) the caller unpack_trees_rec() saw path/foo + * (1) the caller unpack_callback() saw path/foo * in the index, and it has not removed it because * it thinks it is handling 'path' as blob with * D/F conflict; @@ -635,7 +636,7 @@ static int verify_absent(struct cache_entry *ce, const char *action, * We need to increment it by the number of * deleted entries here. */ - o->pos += cnt; + o->pos += ret; return 0; } @@ -246,6 +246,25 @@ int utf8_width(const char **start, size_t *remainder_p) return git_wcwidth(ch); } +/* + * Returns the total number of columns required by a null-terminated + * string, assuming that the string is utf8. Returns strlen() instead + * if the string does not look like a valid utf8 string. + */ +int utf8_strwidth(const char *string) +{ + int width = 0; + const char *orig = string; + + while (1) { + if (!string) + return strlen(orig); + if (!*string) + return width; + width += utf8_width(&string, NULL); + } +} + int is_utf8(const char *text) { while (*text) { @@ -5,6 +5,7 @@ typedef unsigned int ucs_char_t; /* assuming 32bit int */ ucs_char_t pick_one_utf8_char(const char **start, size_t *remainder_p); int utf8_width(const char **start, size_t *remainder_p); +int utf8_strwidth(const char *string); int is_utf8(const char *text); int is_encoding_utf8(const char *name); @@ -196,3 +196,96 @@ int xmkstemp(char *template) die("Unable to create temporary file: %s", strerror(errno)); return fd; } + +/* + * zlib wrappers to make sure we don't silently miss errors + * at init time. + */ +void git_inflate_init(z_streamp strm) +{ + const char *err; + + switch (inflateInit(strm)) { + case Z_OK: + return; + + case Z_MEM_ERROR: + err = "out of memory"; + break; + case Z_VERSION_ERROR: + err = "wrong version"; + break; + default: + err = "error"; + } + die("inflateInit: %s (%s)", err, strm->msg ? strm->msg : "no message"); +} + +void git_inflate_end(z_streamp strm) +{ + if (inflateEnd(strm) != Z_OK) + error("inflateEnd: %s", strm->msg ? strm->msg : "failed"); +} + +int git_inflate(z_streamp strm, int flush) +{ + int ret = inflate(strm, flush); + const char *err; + + switch (ret) { + /* Out of memory is fatal. */ + case Z_MEM_ERROR: + die("inflate: out of memory"); + + /* Data corruption errors: we may want to recover from them (fsck) */ + case Z_NEED_DICT: + err = "needs dictionary"; break; + case Z_DATA_ERROR: + err = "data stream error"; break; + case Z_STREAM_ERROR: + err = "stream consistency error"; break; + default: + err = "unknown error"; break; + + /* Z_BUF_ERROR: normal, needs more space in the output buffer */ + case Z_BUF_ERROR: + case Z_OK: + case Z_STREAM_END: + return ret; + } + error("inflate: %s (%s)", err, strm->msg ? strm->msg : "no message"); + return ret; +} + +int odb_mkstemp(char *template, size_t limit, const char *pattern) +{ + int fd; + + snprintf(template, limit, "%s/%s", + get_object_directory(), pattern); + fd = mkstemp(template); + if (0 <= fd) + return fd; + + /* slow path */ + /* some mkstemp implementations erase template on failure */ + snprintf(template, limit, "%s/%s", + get_object_directory(), pattern); + safe_create_leading_directories(template); + return xmkstemp(template); +} + +int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1) +{ + int fd; + + snprintf(name, namesz, "%s/pack/pack-%s.keep", + get_object_directory(), sha1_to_hex(sha1)); + fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (0 <= fd) + return fd; + + /* slow path */ + safe_create_leading_directories(name); + return open(name, O_RDWR|O_CREAT|O_EXCL, 0600); +} diff --git a/xdiff/xutils.c b/xdiff/xutils.c index d7974d1a3e..04ad468702 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -245,12 +245,14 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data, while (ptr + 1 < top && isspace(ptr[1]) && ptr[1] != '\n') ptr++; - if (flags & XDF_IGNORE_WHITESPACE_CHANGE + if (flags & XDF_IGNORE_WHITESPACE) + ; /* already handled */ + else if (flags & XDF_IGNORE_WHITESPACE_CHANGE && ptr[1] != '\n') { ha += (ha << 5); ha ^= (unsigned long) ' '; } - if (flags & XDF_IGNORE_WHITESPACE_AT_EOL + else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL && ptr[1] != '\n') { while (ptr2 != ptr + 1) { ha += (ha << 5); |