diff options
278 files changed, 6388 insertions, 2368 deletions
diff --git a/Documentation/Makefile b/Documentation/Makefile index 62269e39c4..ded0e40b97 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -44,6 +44,7 @@ MANPAGE_XSL = callouts.xsl INSTALL?=install RM ?= rm -f DOC_REF = origin/man +HTML_REF = origin/html infodir?=$(prefix)/share/info MAKEINFO=makeinfo @@ -222,4 +223,7 @@ install-webdoc : html quick-install: sh ./install-doc-quick.sh $(DOC_REF) $(DESTDIR)$(mandir) +quick-install-html: + sh ./install-doc-quick.sh $(HTML_REF) $(DESTDIR)$(htmldir) + .PHONY: .FORCE-GIT-VERSION-FILE diff --git a/Documentation/RelNotes-1.6.0.2.txt b/Documentation/RelNotes-1.6.0.2.txt new file mode 100644 index 0000000000..7a9646fc4f --- /dev/null +++ b/Documentation/RelNotes-1.6.0.2.txt @@ -0,0 +1,87 @@ +GIT v1.6.0.2 Release Notes +========================== + +Fixes since v1.6.0.1 +-------------------- + +* Installation on platforms that needs .exe suffix to git-* programs were + broken in 1.6.0.1. + +* Installation on filesystems without symbolic links support did nto + work well. + +* In-tree documentations and test scripts now use "git foo" form to set a + better example, instead of the "git-foo" form (which is an acceptable + form if you have "PATH=$(git --exec-path):$PATH" in your script) + +* Many commands did not use the correct working tree location when used + with GIT_WORK_TREE environment settings. + +* Some systems needs to use compatibility fnmach and regex libraries + independent from each other; the compat/ area has been reorganized to + allow this. + + +* "git apply --unidiff-zero" incorrectly applied a -U0 patch that inserts + a new line before the second line. + +* "git blame -c" did not exactly work like "git annotate" when range + boundaries are involved. + +* "git checkout file" when file is still unmerged checked out contents from + a random high order stage, which was confusing. + +* "git clone $there $here/" with extra trailing slashes after explicit + local directory name $here did not work as expected. + +* "git diff" on tracked contents with CRLF line endings did not drive "less" + intelligently when showing added or removed lines. + +* "git diff --dirstat -M" did not add changes in subdirectories up + correctly for renamed paths. + +* "git diff --cumulative" did not imply "--dirstat". + +* "git for-each-ref refs/heads/" did not work as expected. + +* "git gui" allowed users to feed patch without any context to be applied. + +* "git gui" botched parsing "diff" output when a line that begins with two + dashes and a space gets removed or a line that begins with two pluses + and a space gets added. + +* "git gui" translation updates and i18n fixes. + +* "git index-pack" is more careful against disk corruption while completing + a thin pack. + +* "git log -i --grep=pattern" did not ignore case; neither "git log -E + --grep=pattern" triggered extended regexp. + +* "git log --pretty="%ad" --date=short" did not use short format when + showing the timestamp. + +* "git log --author=author" match incorrectly matched with the + timestamp part of "author " line in commit objects. + +* "git log -F --author=author" did not work at all. + +* Build procedure for "git shell" that used stub versions of some + functions and globals was not understood by linkers on some platforms. + +* "git stash" was fooled by a stat-dirty but otherwise unmodified paths + and refused to work until the user refreshed the index. + +* "git svn" was broken on Perl before 5.8 with recent fixes to reduce + use of temporary files. + +* "git verify-pack -v" did not work correctly when given more than one + packfile. + +Also contains many documentation updates. + +-- +exec >/var/tmp/1 +O=v1.6.0.1-78-g3632cfc +echo O=$(git describe maint) +git shortlog --no-merges $O..maint diff --git a/Documentation/RelNotes-1.6.0.3.txt b/Documentation/RelNotes-1.6.0.3.txt new file mode 100644 index 0000000000..46e13a450a --- /dev/null +++ b/Documentation/RelNotes-1.6.0.3.txt @@ -0,0 +1,45 @@ +GIT v1.6.0.3 Release Notes +========================== + +Fixes since v1.6.0.2 +-------------------- + +* "git archive --format=zip" did not honor core.autocrlf while + --format=tar did. + +* Continuing "git rebase -i" was very confused when the user left modified + files in the working tree while resolving conflicts. + +* Continuing "git rebase -i" was also very confused when the user left + some staged changes in the index after "edit". + +* Behaviour of "git diff --quiet" was inconsistent with "diff --exit-code" + with the output redirected to /dev/null. + +* "git stash apply sash@{1}" was fixed to error out. Prior versions + would have applied stash@{0} incorrectly. + +* "git for-each-ref --format=%(subject)" fixed for commits with no + no newline in the message body. + +* "git remote" fixed to protect printf from user input. + +* "git checkout -q" once again suppresses the locally modified file list. + +* Cross-directory renames are no longer used when creating packs. This + allows more graceful behavior on filesystems like sshfs. + +* Stale temporary files under $GIT_DIR/objects/pack are now cleaned up + automatically by "git prune". + +* "Git.pm" tests relied on unnecessarily more recent version of Perl. + +* "gitweb" triggered undef warning on commits without log messages. + +Many other documentation updates. + +-- +exec >/var/tmp/1 +O=v1.6.0.2-41-g7fe4a72 +echo O=$(git describe maint) +git shortlog --no-merges $O..maint diff --git a/Documentation/RelNotes-1.6.1.txt b/Documentation/RelNotes-1.6.1.txt index d37da039f6..421e569ea0 100644 --- a/Documentation/RelNotes-1.6.1.txt +++ b/Documentation/RelNotes-1.6.1.txt @@ -13,7 +13,8 @@ on. (subsystems) -* ... +* gitk can call out to git-gui to view "git blame" output; git-gui in turn + can run gitk from its blame view. (portability) @@ -28,17 +29,80 @@ on. * The underlying diff machinery to produce textual output has been optimized, which would result in faster "git blame" processing. +* Most of the test scripts (but not the ones that try to run servers) + can be run in parallel. + +* Bash completion of refnames in a repository with massive number of + refs has been optimized. + (usability, bells and whistles) +* When you mistype a command name, git helpfully suggests what it guesses + you might have meant to say. help.autocorrect configuration can be set + to a non-zero value to accept the suggestion when git can uniquely + guess. + +* "git bisect" is careful about a user mistake and suggests testing of + merge base first when good is not a strict ancestor of bad. + * "git checkout --track origin/hack" used to be a syntax error. It now DWIMs to create a corresponding local branch "hack", i.e. acts as if you said "git checkout --track -b hack origin/hack". +* "git cherry-pick" can also utilize rerere for conflict resolution. + +* "git commit --author=$name" can look up author name from existing + commits. + +* "git count-objects" reports the on-disk footprint for packfiles and + their corresponding idx files. + +* "git daemon" learned --max-connections=<count> option. + * "git diff" learned to mimick --suppress-blank-empty from GNU diff via a configuration option. +* "git diff" learned to put more sensible hunk headers for Python and + HTML contents. + +* "git diff" learned to vary the a/ vs b/ prefix depending on what are + being compared, controlled by diff.mnemonicprefix configuration. + +* "git for-each-ref" learned "refname:short" token that gives an + unambiguously abbreviated refname. + +* "git help" learned to use GIT_MAN_VIEWER environment variable before + using "man" program. + * "git imap-send" can optionally talk SSL. +* "git index-pack" is more careful against disk corruption while + completing a thin pack. + +* "git log --check" and "git log --exit-code" passes their underlying diff + status with their exit status code. + +* "git log" learned --simplify-merges, a milder variant of --full-history; + "gitk --simplify-merges" is easier to view than with --full-history. + +* "git log --pretty=format:" learned "%d" format element that inserts + names of tags that point at the commit. + +* "git merge --squash" and "git merge --no-ff" into an unborn branch are + noticed as user errors. + +* "git merge -s $strategy" can use a custom built strategy if you have a + command "git-merge-$strategy" on your $PATH. + +* "git reflog expire branch" can be used in place of "git reflog expire + refs/heads/branch". + +* "git submodule foreach" subcommand allows you to iterate over checked + out submodules. + +* "git submodule sync" subcommands allows you to update the origin URL + recorded in submodule directories from the toplevel .gitmodules file. + (internal) * "git hash-object" learned to lie about the path being hashed, so that @@ -51,8 +115,26 @@ Fixes since v1.6.0 All of the fixes in v1.6.0.X maintenance series are included in this release, unless otherwise noted. +* "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 + is a path in it). + +* "git diff --stdin" used to take two trees on a line and compared them, + but we droppped support for such a use case long time ago. This has + been resurrected. + +* "git filter-branch" failed to rewrite a tag name with slashes in it. + +* "git push --tags --all $there" failed with generic usage message without + telling saying these two options are incompatible. + +* "git log --author/--committer" match used to potentially match the + timestamp part, exposing internal implementation detail. Also these did + not work with --fixed-strings match at all. + -- exec >/var/tmp/1 -O=v1.6.0-48-ge28a867 +O=v1.6.0.2-295-g34a5d35 echo O=$(git describe master) git shortlog --no-merges $O..master ^maint diff --git a/Documentation/config.txt b/Documentation/config.txt index af57d94304..bea867df60 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -585,6 +585,22 @@ diff.external:: you want to use an external diff program only on a subset of your files, you might want to use linkgit:gitattributes[5] instead. +diff.mnemonicprefix:: + If set, 'git-diff' uses a prefix pair that is different from the + standard "a/" and "b/" depending on what is being compared. When + this configuration is in effect, reverse diff output also swaps + the order of the prefixes: +'git-diff';; + compares the (i)ndex and the (w)ork tree; +'git-diff HEAD';; + compares a (c)ommit and the (w)ork tree; +'git diff --cached';; + compares a (c)ommit and the (i)ndex; +'git-diff HEAD:file1 file2';; + compares an (o)bject and a (w)ork tree entity; +'git diff --no-index a b';; + compares two non-git things (1) and (2). + diff.renameLimit:: The number of files to consider when performing the copy/rename detection; equivalent to the 'git-diff' option '-l'. @@ -697,7 +713,7 @@ gitcvs.logfile:: Path to a log file where the CVS server interface well... logs various stuff. See linkgit:git-cvsserver[1]. -gitcvs.usecrlfattr +gitcvs.usecrlfattr:: If true, the server will look up the `crlf` attribute for files to determine the '-k' modes to use. If `crlf` is set, the '-k' mode will be left blank, so cvs clients will @@ -790,6 +806,15 @@ help.format:: Values 'man', 'info', 'web' and 'html' are supported. 'man' is the default. 'web' and 'html' are the same. +help.autocorrect:: + Automatically correct and execute mistyped commands after + waiting for the given number of deciseconds (0.1 sec). If more + than one command can be deduced from the entered text, nothing + will be executed. If the value of this option is negative, + the corrected command will be executed immediately. If the + value is 0 - the command will be just shown but not executed. + This is the default. + http.proxy:: Override the HTTP proxy, normally configured using the 'http_proxy' environment variable (see linkgit:curl[1]). This can be overridden diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 1759386404..7788d4fa4a 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -59,12 +59,14 @@ endif::git-format-patch[] lines. --dirstat[=limit]:: - Output only the sub-directories that are impacted by a diff, - and to what degree they are impacted. You can override the - default cut-off in percent (3) by "--dirstat=limit". If you - want to enable "cumulative" directory statistics, you can use - the "--cumulative" flag, which adds up percentages recursively - even when they have been already reported for a sub-directory. + Output the distribution of relative amount of changes (number of lines added or + removed) for each sub-directory. Directories with changes below + a cut-off percent (3% by default) are not shown. The cut-off percent + can be set with "--dirstat=limit". Changes in a child directory is not + counted for the parent directory, unless "--cumulative" is used. + +--dirstat-by-file[=limit]:: + Same as --dirstat, but counts changed files instead of lines. --summary:: Output a condensed summary of extended header information diff --git a/Documentation/git-annotate.txt b/Documentation/git-annotate.txt index 8b6b56a544..0aba022ba6 100644 --- a/Documentation/git-annotate.txt +++ b/Documentation/git-annotate.txt @@ -14,6 +14,11 @@ DESCRIPTION Annotates each line in the given file with information from the commit which introduced the line. Optionally annotate from a given revision. +The only difference between this command and linkgit:git-blame[1] is that +they use slightly different output formats, and this command exists only +for backward compatibility to support existing scripts, and provide more +familiar command name for people coming from other SCM systems. + OPTIONS ------- include::blame-options.txt[] diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index feb51f124a..e726510ab1 100644 --- a/Documentation/git-apply.txt +++ b/Documentation/git-apply.txt @@ -14,7 +14,8 @@ SYNOPSIS [--allow-binary-replacement | --binary] [--reject] [-z] [-pNUM] [-CNUM] [--inaccurate-eof] [--recount] [--cached] [--whitespace=<nowarn|warn|fix|error|error-all>] - [--exclude=PATH] [--directory=<root>] [--verbose] [<patch>...] + [--exclude=PATH] [--include=PATH] [--directory=<root>] + [--verbose] [<patch>...] DESCRIPTION ----------- @@ -137,6 +138,17 @@ discouraged. be useful when importing patchsets, where you want to exclude certain files or directories. +--include=<path-pattern>:: + Apply changes to files matching the given path pattern. This can + be useful when importing patchsets, where you want to include certain + files or directories. ++ +When --exclude and --include patterns are used, they are examined in the +order they appear on the command line, and the first match determines if a +patch to each path is used. A patch to a path that does not match any +include/exclude pattern is used by default if there is no include pattern +on the command line, and ignored if there is any include pattern. + --whitespace=<action>:: When applying a patch, detect a new or modified line that has whitespace errors. What are considered whitespace errors is diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt index 92ab3ab4a8..b8834baced 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.txt @@ -79,9 +79,9 @@ Diagnostics You don't exist. Go away!:: The passwd(5) gecos field couldn't be read Your parents must have hated you!:: - The password(5) gecos field is longer than a giant static buffer. + The passwd(5) gecos field is longer than a giant static buffer. Your sysadmin must hate you!:: - The password(5) name field is longer than a giant static buffer. + The passwd(5) name field is longer than a giant static buffer. Discussion ---------- diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 0e25bb8627..eb05b0f49b 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -75,8 +75,10 @@ OPTIONS read the message from the standard input. --author=<author>:: - Override the author name used in the commit. Use - `A U Thor <author@example.com>` format. + Override the author name used in the commit. You can use the + standard `A U Thor <author@example.com>` format. Otherwise, + an existing commit that matches the given string and its author + name is used. -m <msg>:: --message=<msg>:: diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index eae6c0e7bc..5061d3e4e7 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -16,7 +16,7 @@ DESCRIPTION Iterate over all refs that match `<pattern>` and show them according to the given `<format>`, after sorting them according -to the given set of `<key>`. If `<max>` is given, stop after +to the given set of `<key>`. If `<count>` is given, stop after showing that many refs. The interpolated values in `<format>` can optionally be quoted as string literals in the specified host language allowing their direct evaluation in that language. @@ -74,6 +74,7 @@ For all objects, the following names can be used: refname:: The name of the ref (the part after $GIT_DIR/). + For a non-ambiguous short name of the ref append `:short`. objecttype:: The type of the object (`blob`, `tree`, `commit`, `tag`). diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt index f414583fc4..d9b9c34b3a 100644 --- a/Documentation/git-help.txt +++ b/Documentation/git-help.txt @@ -112,7 +112,9 @@ For example, this configuration: will try to use konqueror first. But this may fail (for example if DISPLAY is not set) and in that case emacs' woman mode will be tried. -If everything fails the 'man' program will be tried anyway. +If everything fails, or if no viewer is configured, the viewer specified +in the GIT_MAN_VIEWER environment variable will be tried. If that +fails too, the 'man' program will be tried anyway. man.<tool>.path ~~~~~~~~~~~~~~~ diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index 6f4b9b017f..309deac23b 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -160,7 +160,10 @@ Here are the "carry forward" rules: 0 nothing nothing nothing (does not happen) 1 nothing nothing exists use M 2 nothing exists nothing remove path from index - 3 nothing exists exists use M + 3 nothing exists exists, use M if "initial checkout" + H == M keep index otherwise + exists fail + H != M clean I==H I==M ------------------ @@ -207,6 +210,12 @@ you picked it up via e-mail in a patch form), `git diff-index merge, but it would not show in `git diff-index --cached $M` output after two-tree merge. +Case #3 is slightly tricky and needs explanation. The result from this +rule logically should be to remove the path if the user staged the removal +of the path and then swiching to a new branch. That however will prevent +the initial checkout from happening, so the rule is modified to use M (new +tree) only when the contents of the index is empty. Otherwise the removal +of the path is kept as long as $H and $M are the same. 3-Way Merge ~~~~~~~~~~~ diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 59c1b021a6..32f0f122e9 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -92,7 +92,7 @@ branch to another, to pretend that you forked the topic branch from the latter branch, using `rebase --onto`. First let's assume your 'topic' is based on branch 'next'. -For example feature developed in 'topic' depends on some +For example, a feature developed in 'topic' depends on some functionality which is found in 'next'. ------------ @@ -103,9 +103,9 @@ functionality which is found in 'next'. o---o---o topic ------------ -We would want to make 'topic' forked from branch 'master', -for example because the functionality 'topic' branch depend on -got merged into more stable 'master' branch, like this: +We want to make 'topic' forked from branch 'master'; for example, +because the functionality on which 'topic' depends was merged into the +more stable 'master' branch. We want our tree to look like this: ------------ o---o---o---o---o master diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt index 38ac60947b..bbe1485a97 100644 --- a/Documentation/git-repack.txt +++ b/Documentation/git-repack.txt @@ -60,7 +60,7 @@ OPTIONS linkgit:git-pack-objects[1]. -f:: - Pass the `--no-reuse-delta` option to 'git-pack-objects'. See + Pass the `--no-reuse-object` option to `git-pack-objects`, see linkgit:git-pack-objects[1]. -q:: diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index e2437f30ca..3c3e1b0e77 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -179,6 +179,9 @@ user is prompted for a password while the input is masked for privacy. This is useful if your default address is not the address that is subscribed to a list. If you use the sendmail binary, you must have suitable privileges for the -f parameter. + Default is the value of the 'sendemail.envelopesender' configuration + variable; if that is unspecified, choosing the envelope sender is left + to your MTA. --to:: Specify the primary recipient of the emails generated. diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 49e2296a24..051f94d26f 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -159,7 +159,7 @@ perform a pull, and then unstash, like this: + ---------------------------------------------------------------- $ git pull -... + ... file foobar not up to date, cannot merge. $ git stash $ git pull @@ -174,7 +174,7 @@ make a commit to a temporary branch to store your changes away, and return to your original branch to make the emergency fix, like this: + ---------------------------------------------------------------- -... hack hack hack ... +# ... hack hack hack ... $ git checkout -b my_wip $ git commit -a -m "WIP" $ git checkout master @@ -182,18 +182,18 @@ $ edit emergency fix $ git commit -a -m "Fix in a hurry" $ git checkout my_wip $ git reset --soft HEAD^ -... continue hacking ... +# ... continue hacking ... ---------------------------------------------------------------- + You can use 'git-stash' to simplify the above, like this: + ---------------------------------------------------------------- -... hack hack hack ... +# ... hack hack hack ... $ git stash $ edit emergency fix $ git commit -a -m "Fix in a hurry" $ git stash apply -... continue hacking ... +# ... continue hacking ... ---------------------------------------------------------------- Testing partial commits:: @@ -203,13 +203,13 @@ more commits out of the changes in the work tree, and you want to test each change before committing: + ---------------------------------------------------------------- -... hack hack hack ... +# ... hack hack hack ... $ git add --patch foo # add just first part to the index $ git stash save --keep-index # save all other changes to the stash $ edit/build/test first part -$ git commit foo -m 'First part' # commit fully tested change +$ git commit -m 'First part' # commit fully tested change $ git stash pop # prepare to work on all other changes -... repeat above five steps until one commit remains ... +# ... repeat above five steps until one commit remains ... $ edit/build/test remaining parts $ git commit foo -m 'Remaining parts' ---------------------------------------------------------------- diff --git a/Documentation/git-var.txt b/Documentation/git-var.txt index 3647dd6c8f..e2f4c0901b 100644 --- a/Documentation/git-var.txt +++ b/Documentation/git-var.txt @@ -20,7 +20,7 @@ OPTIONS Cause the logical variables to be listed. In addition, all the variables of the git configuration file .git/config are listed as well. (However, the configuration variables listing functionality - is deprecated in favor of 'git-config -l'.) + is deprecated in favor of 'git config -l'.) EXAMPLE -------- @@ -41,9 +41,9 @@ Diagnostics You don't exist. Go away!:: The passwd(5) gecos field couldn't be read Your parents must have hated you!:: - The password(5) gecos field is longer than a giant static buffer. + The passwd(5) gecos field is longer than a giant static buffer. Your sysadmin must hate you!:: - The password(5) name field is longer than a giant static buffer. + The passwd(5) name field is longer than a giant static buffer. SEE ALSO -------- diff --git a/Documentation/git-web--browse.txt b/Documentation/git-web--browse.txt index 36afad8d4e..278cf73527 100644 --- a/Documentation/git-web--browse.txt +++ b/Documentation/git-web--browse.txt @@ -26,6 +26,7 @@ The following browsers (or commands) are currently supported: * lynx * dillo * open (this is the default under Mac OS X GUI) +* start (this is the default under MinGW) Custom commands may also be specified. @@ -77,7 +78,7 @@ the URLs passed as arguments. Note about konqueror -------------------- -When 'konqueror' is specified by the a command line option or a +When 'konqueror' is specified by a command line option or a configuration variable, we launch 'kfmclient' to try to open the HTML man page on an already opened konqueror in a new tab if possible. diff --git a/Documentation/git.txt b/Documentation/git.txt index e178fb5813..df420aeb33 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,10 +43,11 @@ 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.1/git.html[documentation for release 1.6.1] +* link:v1.6.0.2/git.html[documentation for release 1.6.0.2] * release notes for - link:RelNotes-1.6.1.txt[1.6.1], + link:RelNotes-1.6.0.2.txt[1.6.0.2], + 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] diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 1f23d27a61..e848c94397 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -7,7 +7,7 @@ gitattributes - defining attributes per path SYNOPSIS -------- -$GIT_DIR/info/attributes, gitattributes +$GIT_DIR/info/attributes, .gitattributes DESCRIPTION @@ -270,27 +270,27 @@ See linkgit:git[1] for details. Defining a custom hunk-header ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Each group of changes (called "hunk") in the textual diff output +Each group of changes (called a "hunk") in the textual diff output is prefixed with a line of the form: @@ -k,l +n,m @@ TEXT -The text is called 'hunk header', and by default a line that -begins with an alphabet, an underscore or a dollar sign is used, -which matches what GNU 'diff -p' output uses. This default -selection however is not suited for some contents, and you can -use customized pattern to make a selection. +This is called a 'hunk header'. The "TEXT" portion is by default a line +that begins with an alphabet, an underscore or a dollar sign; this +matches what GNU 'diff -p' output uses. This default selection however +is not suited for some contents, and you can use a customized pattern +to make a selection. -First in .gitattributes, you would assign the `diff` attribute +First, in .gitattributes, you would assign the `diff` attribute for paths. ------------------------ *.tex diff=tex ------------------------ -Then, you would define "diff.tex.funcname" configuration to +Then, you would define a "diff.tex.funcname" configuration to specify a regular expression that matches a line that you would -want to appear as the hunk header, like this: +want to appear as the hunk header "TEXT", like this: ------------------------ [diff "tex"] @@ -311,18 +311,20 @@ patterns are available: - `bibtex` suitable for files with BibTeX coded references. -- `java` suitable for source code in the Java lanugage. +- `html` suitable for HTML/XHTML documents. + +- `java` suitable for source code in the Java language. - `pascal` suitable for source code in the Pascal/Delphi language. +- `php` suitable for source code in the PHP language. + - `python` suitable for source code in the Python language. - `ruby` suitable for source code in the Ruby language. - `tex` suitable for source code for LaTeX documents. -- `html` suitable for HTML/XHTML documents. - Performing a three-way merge ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Documentation/gitdiffcore.txt b/Documentation/gitdiffcore.txt index 2bdbc3d4f6..e8041bc08f 100644 --- a/Documentation/gitdiffcore.txt +++ b/Documentation/gitdiffcore.txt @@ -36,11 +36,25 @@ files: - 'git-diff-tree' compares contents of two "tree" objects; -In all of these cases, the commands themselves compare -corresponding paths in the two sets of files. The result of -comparison is passed from these commands to what is internally -called "diffcore", in a format similar to what is output when -the -p option is not used. E.g. +In all of these cases, the commands themselves first optionally limit +the two sets of files by any pathspecs given on their command-lines, +and compare corresponding paths in the two resulting sets of files. + +The pathspecs are used to limit the world diff operates in. They remove +the filepairs outside the specified sets of pathnames. E.g. If the +input set of filepairs included: + +------------------------------------------------ +:100644 100644 bcd1234... 0123456... M junkfile +------------------------------------------------ + +but the command invocation was `git diff-files myfile`, then the +junkfile entry would be removed from the list because only "myfile" +is under consideration. + +The result of comparison is passed from these commands to what is +internally called "diffcore", in a format similar to what is output +when the -p option is not used. E.g. ------------------------------------------------ in-place edit :100644 100644 bcd1234... 0123456... M file0 @@ -52,9 +66,8 @@ unmerged :000000 000000 0000000... 0000000... U file6 The diffcore mechanism is fed a list of such comparison results (each of which is called "filepair", although at this point each of them talks about a single file), and transforms such a list -into another list. There are currently 6 such transformations: +into another list. There are currently 5 such transformations: -- diffcore-pathspec - diffcore-break - diffcore-rename - diffcore-merge-broken @@ -62,38 +75,14 @@ into another list. There are currently 6 such transformations: - diffcore-order These are applied in sequence. The set of filepairs 'git-diff-{asterisk}' -commands find are used as the input to diffcore-pathspec, and -the output from diffcore-pathspec is used as the input to the +commands find are used as the input to diffcore-break, and +the output from diffcore-break is used as the input to the next transformation. The final result is then passed to the output routine and generates either diff-raw format (see Output format sections of the manual for 'git-diff-{asterisk}' commands) or diff-patch format. -diffcore-pathspec: For Ignoring Files Outside Our Consideration ---------------------------------------------------------------- - -The first transformation in the chain is diffcore-pathspec, and -is controlled by giving the pathname parameters to the -'git-diff-{asterisk}' commands on the command line. The pathspec is used -to limit the world diff operates in. It removes the filepairs -outside the specified set of pathnames. E.g. If the input set -of filepairs included: - ------------------------------------------------- -:100644 100644 bcd1234... 0123456... M junkfile ------------------------------------------------- - -but the command invocation was `git diff-files myfile`, then the -junkfile entry would be removed from the list because only "myfile" -is under consideration. - -Implementation note. For performance reasons, 'git-diff-tree' -uses the pathname parameters on the command line to cull set of -filepairs it feeds the diffcore mechanism itself, and does not -use diffcore-pathspec, but the end result is the same. - - diffcore-break: For Splitting Up "Complete Rewrites" ---------------------------------------------------- diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt index f8d122a8b9..d1a17e2625 100644 --- a/Documentation/gitmodules.txt +++ b/Documentation/gitmodules.txt @@ -7,7 +7,7 @@ gitmodules - defining submodule properties SYNOPSIS -------- -gitmodules +$GIT_WORK_DIR/.gitmodules DESCRIPTION diff --git a/Documentation/i18n.txt b/Documentation/i18n.txt index fb0d7da56b..d2970f8357 100644 --- a/Documentation/i18n.txt +++ b/Documentation/i18n.txt @@ -21,7 +21,7 @@ project find it more convenient to use legacy encodings, git does not forbid it. However, there are a few things to keep in mind. -. 'git-commit-tree' (hence, 'git-commit' which uses it) issues +. 'git-commit' and 'git-commit-tree' issues a warning if the commit log message given to it does not look like a valid UTF-8 string, unless you explicitly say your project uses a legacy encoding. The way to say this is to diff --git a/Documentation/merge-config.txt b/Documentation/merge-config.txt index 00277e0613..c735788b0f 100644 --- a/Documentation/merge-config.txt +++ b/Documentation/merge-config.txt @@ -1,5 +1,5 @@ merge.stat:: - Whether to print the diffstat between ORIG_HEAD and merge result + Whether to print the diffstat between ORIG_HEAD and the merge result at the end of the merge. True by default. merge.log:: diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index 388d4925e6..f18d33e00b 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -116,6 +116,7 @@ The placeholders are: - '%cr': committer date, relative - '%ct': committer date, UNIX timestamp - '%ci': committer date, ISO 8601 format +- '%d': ref names, like the --decorate option of linkgit:git-log[1] - '%e': encoding - '%s': subject - '%b': body diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 735cf07b20..0ce916a188 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -409,6 +409,48 @@ Note that without '\--full-history', this still simplifies merges: if one of the parents is TREESAME, we follow only that one, so the other sides of the merge are never walked. +Finally, there is a fourth simplification mode available: + +--simplify-merges:: + + First, build a history graph in the same way that + '\--full-history' with parent rewriting does (see above). ++ +Then simplify each commit `C` to its replacement `C'` in the final +history according to the following rules: ++ +-- +* Set `C'` to `C`. ++ +* Replace each parent `P` of `C'` with its simplification `P'`. In + the process, drop parents that are ancestors of other parents, and + remove duplicates. ++ +* If after this parent rewriting, `C'` is a root or merge commit (has + zero or >1 parents), a boundary commit, or !TREESAME, it remains. + Otherwise, it is replaced with its only parent. +-- ++ +The effect of this is best shown by way of comparing to +'\--full-history' with parent rewriting. The example turns into: ++ +----------------------------------------------------------------------- + .-A---M---N---O + / / / + I B D + \ / / + `---------' +----------------------------------------------------------------------- ++ +Note the major differences in `N` and `P` over '\--full-history': ++ +-- +* `N`'s parent list had `I` removed, because it is an ancestor of the + other parent `M`. Still, `N` remained because it is !TREESAME. ++ +* `P`'s parent list similarly had `I` removed. `P` was then + removed completely, because it had one parent and is TREESAME. +-- ifdef::git-rev-list[] Bisection Helpers diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 156dc13733..6c7465c758 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.6.0.GIT +DEF_VER=v1.6.0.2.GIT LF=' ' @@ -6,7 +6,7 @@ will install the git programs in your own ~/bin/ directory. If you want to do a global install, you can do $ make prefix=/usr all doc info ;# as yourself - # make prefix=/usr install install-doc install-info ;# as root + # make prefix=/usr install install-doc install-html install-info ;# as root (or prefix=/usr/local, of course). Just like any program suite that uses $prefix, the built results have some paths encoded, @@ -19,7 +19,7 @@ set up install paths (via config.mak.autogen), so you can write instead $ make configure ;# as yourself $ ./configure --prefix=/usr ;# as yourself $ make all doc ;# as yourself - # make install install-doc ;# as root + # make install install-doc install-html;# as root Issues of note: @@ -89,13 +89,22 @@ Issues of note: inclined to install the tools, the default build target ("make all") does _not_ build them. + "make doc" builds documentation in man and html formats; there are + also "make man", "make html" and "make info". Note that "make html" + requires asciidoc, but not xmlto. "make man" (and thus make doc) + requires both. + + "make install-doc" installs documentation in man format only; there + are also "make install-man", "make install-html" and "make + install-info". + Building and installing the info file additionally requires makeinfo and docbook2X. Version 0.8.3 is known to work. The documentation is written for AsciiDoc 7, but "make ASCIIDOC8=YesPlease doc" will let you format with AsciiDoc 8. - Alternatively, pre-formatted documentation are available in + Alternatively, pre-formatted documentation is available in "html" and "man" branches of the git repository itself. For example, you could: @@ -117,6 +126,12 @@ Issues of note: http://www.kernel.org/pub/software/scm/git/docs/ + There are also "make quick-install-doc" and "make quick-install-html" + which install preformatted man pages and html documentation. + This does not require asciidoc/xmlto, but it only works from within + a cloned checkout of git.git with these two extra branches, and will + not work for the maintainer for obvious chicken-and-egg reasons. + It has been reported that docbook-xsl version 1.72 and 1.73 are buggy; 1.72 misformats manual pages for callouts, and 1.73 needs the patch in contrib/patches/docbook-xsl-manpages-charmap.patch @@ -294,8 +294,8 @@ PROGRAMS += git-mktag$X PROGRAMS += git-mktree$X PROGRAMS += git-pack-redundant$X PROGRAMS += git-patch-id$X -PROGRAMS += git-receive-pack$X PROGRAMS += git-send-pack$X +PROGRAMS += git-shell$X PROGRAMS += git-show-index$X PROGRAMS += git-unpack-file$X PROGRAMS += git-update-server-info$X @@ -358,10 +358,12 @@ LIB_H += graph.h LIB_H += grep.h LIB_H += hash.h LIB_H += help.h +LIB_H += levenshtein.h LIB_H += list-objects.h LIB_H += ll-merge.h LIB_H += log-tree.h LIB_H += mailmap.h +LIB_H += merge-recursive.h LIB_H += object.h LIB_H += pack.h LIB_H += pack-refs.h @@ -433,6 +435,7 @@ LIB_OBJS += hash.o LIB_OBJS += help.o LIB_OBJS += ident.o LIB_OBJS += interpolate.o +LIB_OBJS += levenshtein.o LIB_OBJS += list-objects.o LIB_OBJS += ll-merge.o LIB_OBJS += lockfile.o @@ -543,6 +546,7 @@ BUILTIN_OBJS += builtin-prune-packed.o BUILTIN_OBJS += builtin-prune.o BUILTIN_OBJS += builtin-push.o BUILTIN_OBJS += builtin-read-tree.o +BUILTIN_OBJS += builtin-receive-pack.o BUILTIN_OBJS += builtin-reflog.o BUILTIN_OBJS += builtin-remote.o BUILTIN_OBJS += builtin-rerere.o @@ -633,6 +637,8 @@ ifeq ($(uname_S),Darwin) endif NO_STRLCPY = YesPlease NO_MEMMEM = YesPlease + COMPAT_CFLAGS += -Icompat/regex + COMPAT_OBJS += compat/regex/regex.o endif ifeq ($(uname_S),SunOS) NEEDS_SOCKET = YesPlease @@ -683,6 +689,8 @@ ifeq ($(uname_S),FreeBSD) BASIC_LDFLAGS += -L/usr/local/lib DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease THREADED_DELTA_SEARCH = YesPlease + COMPAT_CFLAGS += -Icompat/regex + COMPAT_OBJS += compat/regex/regex.o endif ifeq ($(uname_S),OpenBSD) NO_STRCASESTR = YesPlease @@ -697,8 +705,7 @@ ifeq ($(uname_S),NetBSD) NEEDS_LIBICONV = YesPlease endif BASIC_CFLAGS += -I/usr/pkg/include - BASIC_LDFLAGS += -L/usr/pkg/lib - ALL_LDFLAGS += -Wl,-rpath,/usr/pkg/lib + BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib THREADED_DELTA_SEARCH = YesPlease endif ifeq ($(uname_S),AIX) @@ -710,6 +717,8 @@ ifeq ($(uname_S),AIX) INTERNAL_QSORT = UnfortunatelyYes NEEDS_LIBICONV=YesPlease BASIC_CFLAGS += -D_LARGE_FILES + COMPAT_CFLAGS += -Icompat/regex + COMPAT_OBJS += compat/regex/regex.o endif ifeq ($(uname_S),GNU) # GNU/Hurd @@ -761,10 +770,10 @@ ifneq (,$(findstring MINGW,$(uname_S))) NO_PERL_MAKEMAKER = YesPlease NO_POSIX_ONLY_PROGRAMS = YesPlease NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease - COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat + COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1 COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" - COMPAT_OBJS += compat/mingw.o compat/fnmatch.o compat/regex.o compat/winansi.o + COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/regex/regex.o compat/winansi.o EXTLIBS += -lws2_32 X = .exe gitexecdir = ../libexec/git-core @@ -793,12 +802,14 @@ ifeq ($(uname_S),Darwin) endif endif -ifdef NO_R_TO_GCC_LINKER - # Some gcc does not accept and pass -R to the linker to specify - # the runtime dynamic library path. - CC_LD_DYNPATH = -Wl,-rpath= -else - CC_LD_DYNPATH = -R +ifndef CC_LD_DYNPATH + ifdef NO_R_TO_GCC_LINKER + # Some gcc does not accept and pass -R to the linker to specify + # the runtime dynamic library path. + CC_LD_DYNPATH = -Wl,-rpath, + else + CC_LD_DYNPATH = -R + endif endif ifdef NO_CURL @@ -834,7 +845,6 @@ EXTLIBS += -lz ifndef NO_POSIX_ONLY_PROGRAMS PROGRAMS += git-daemon$X PROGRAMS += git-imap-send$X - PROGRAMS += git-shell$X endif ifndef NO_OPENSSL OPENSSL_LIBSSL = -lssl @@ -1262,6 +1272,12 @@ $(XDIFF_LIB): $(XDIFF_OBJS) doc: $(MAKE) -C Documentation all +man: + $(MAKE) -C Documentation man + +html: + $(MAKE) -C Documentation html + info: $(MAKE) -C Documentation info @@ -1365,7 +1381,7 @@ install: all $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' - $(INSTALL) git$X git-upload-pack$X git-receive-pack$X git-upload-archive$X git-shell$X '$(DESTDIR_SQ)$(bindir_SQ)' + $(INSTALL) git$X git-upload-pack$X git-receive-pack$X git-upload-archive$X git-shell$X git-cvsserver '$(DESTDIR_SQ)$(bindir_SQ)' $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install $(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install ifndef NO_TCLTK @@ -1398,6 +1414,9 @@ install-info: quick-install-doc: $(MAKE) -C Documentation quick-install +quick-install-html: + $(MAKE) -C Documentation quick-install-html + ### Maintainer's dist rules @@ -1,5 +1,16 @@ #include "cache.h" +/* + * Do not use this for inspecting *tracked* content. When path is a + * symlink to a directory, we do not want to say it is a directory when + * dealing with tracked content in the working tree. + */ +int is_directory(const char *path) +{ + struct stat st; + return (!stat(path, &st) && S_ISDIR(st.st_mode)); +} + /* We allow "recursive" symbolic links. Only within reason, though. */ #define MAXDEPTH 5 @@ -17,7 +28,7 @@ const char *make_absolute_path(const char *path) die ("Too long path: %.*s", 60, path); while (depth--) { - if (stat(buf, &st) || !S_ISDIR(st.st_mode)) { + if (!is_directory(buf)) { char *last_slash = strrchr(buf, '/'); if (last_slash) { *last_slash = '\0'; diff --git a/builtin-apply.c b/builtin-apply.c index 47261e10fb..2ab4aba5a0 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -274,7 +274,7 @@ static void say_patch_name(FILE *output, const char *pre, static void read_patch_file(struct strbuf *sb, int fd) { if (strbuf_read(sb, fd, 0) < 0) - die("git-apply: read returned %s", strerror(errno)); + die("git apply: read returned %s", strerror(errno)); /* * Make sure that we have some slop in the buffer @@ -506,17 +506,17 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, name = orig_name; len = strlen(name); if (isnull) - die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr); + die("git apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr); another = find_name(line, NULL, p_value, TERM_TAB); if (!another || memcmp(another, name, len)) - die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr); + die("git apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr); free(another); return orig_name; } else { /* expect "/dev/null" */ if (memcmp("/dev/null", line, 9) || line[9] != '\n') - die("git-apply: bad git-diff - expected /dev/null on line %d", linenr); + die("git apply: bad git-diff - expected /dev/null on line %d", linenr); return NULL; } } @@ -2994,29 +2994,45 @@ static int write_out_results(struct patch *list, int skipped_patch) static struct lock_file lock_file; -static struct excludes { - struct excludes *next; - const char *path; -} *excludes; +static struct string_list limit_by_name; +static int has_include; +static void add_name_limit(const char *name, int exclude) +{ + struct string_list_item *it; + + it = string_list_append(name, &limit_by_name); + it->util = exclude ? NULL : (void *) 1; +} static int use_patch(struct patch *p) { const char *pathname = p->new_name ? p->new_name : p->old_name; - struct excludes *x = excludes; - while (x) { - if (fnmatch(x->path, pathname, 0) == 0) - return 0; - x = x->next; - } + int i; + + /* Paths outside are not touched regardless of "--include" */ if (0 < prefix_length) { int pathlen = strlen(pathname); if (pathlen <= prefix_length || memcmp(prefix, pathname, prefix_length)) return 0; } - return 1; + + /* See if it matches any of exclude/include rule */ + for (i = 0; i < limit_by_name.nr; i++) { + struct string_list_item *it = &limit_by_name.items[i]; + if (!fnmatch(it->string, pathname, 0)) + return (it->util != NULL); + } + + /* + * If we had any include, a path that does not match any rule is + * not used. Otherwise, we saw bunch of exclude rules (or none) + * and such a path is used. + */ + return !has_include; } + static void prefix_one(char **name) { char *old_name = *name; @@ -3157,10 +3173,12 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) continue; } if (!prefixcmp(arg, "--exclude=")) { - struct excludes *x = xmalloc(sizeof(*x)); - x->path = arg + 10; - x->next = excludes; - excludes = x; + add_name_limit(arg + 10, 1); + continue; + } + if (!prefixcmp(arg, "--include=")) { + add_name_limit(arg + 10, 0); + has_include = 1; continue; } if (!prefixcmp(arg, "-p")) { diff --git a/builtin-archive.c b/builtin-archive.c index 22445acbfc..432ce2acc6 100644 --- a/builtin-archive.c +++ b/builtin-archive.c @@ -47,18 +47,18 @@ static int run_remote_archiver(const char *remote, int argc, len = packet_read_line(fd[0], buf, sizeof(buf)); if (!len) - die("git-archive: expected ACK/NAK, got EOF"); + die("git archive: expected ACK/NAK, got EOF"); if (buf[len-1] == '\n') buf[--len] = 0; if (strcmp(buf, "ACK")) { if (len > 5 && !prefixcmp(buf, "NACK ")) - die("git-archive: NACK %s", buf + 5); - die("git-archive: protocol error"); + die("git archive: NACK %s", buf + 5); + die("git archive: protocol error"); } len = packet_read_line(fd[0], buf, sizeof(buf)); if (len) - die("git-archive: expected a flush"); + die("git archive: expected a flush"); /* Now, start reading from fd[0] and spit it out to stdout */ rv = recv_sideband("archive", fd[0], 1, 2); @@ -111,6 +111,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix) { const char *remote = NULL; + git_config(git_default_config, NULL); + remote = extract_remote_arg(&argc, argv); if (remote) return run_remote_archiver(remote, argc, argv); diff --git a/builtin-blame.c b/builtin-blame.c index e4d12de8a9..6b7b9f4466 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -38,7 +38,6 @@ static int show_root; static int reverse; static int blank_boundary; static int incremental; -static int cmd_is_annotate; static int xdl_opts = XDF_NEED_MINIMAL; static struct string_list mailmap; @@ -1682,7 +1681,7 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt) if (suspect->commit->object.flags & UNINTERESTING) { if (blank_boundary) memset(hex, ' ', length); - else if (!cmd_is_annotate) { + else if (!(opt & OUTPUT_ANNOTATE_COMPAT)) { length--; putchar('^'); } @@ -1787,7 +1786,7 @@ static int prepare_lines(struct scoreboard *sb) /* * Add phony grafts for use with -S; this is primarily to - * support git-cvsserver that wants to give a linear history + * support git's cvsserver that wants to give a linear history * to its clients. */ static int read_ancestry(const char *graft_file) @@ -2313,8 +2312,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) }; struct parse_opt_ctx_t ctx; - - cmd_is_annotate = !strcmp(argv[0], "annotate"); + int cmd_is_annotate = !strcmp(argv[0], "annotate"); git_config(git_blame_config, NULL); init_revisions(&revs, NULL); @@ -2342,6 +2340,9 @@ int cmd_blame(int argc, const char **argv, const char *prefix) parse_done: argc = parse_options_end(&ctx); + if (cmd_is_annotate) + output_option |= OUTPUT_ANNOTATE_COMPAT; + if (DIFF_OPT_TST(&revs.diffopt, FIND_COPIES_HARDER)) opt |= (PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE | PICKAXE_BLAME_COPY_HARDER); diff --git a/builtin-bundle.c b/builtin-bundle.c index ac476e7a4b..9b58152047 100644 --- a/builtin-bundle.c +++ b/builtin-bundle.c @@ -6,10 +6,10 @@ * Basic handler for bundle files to connect repositories via sneakernet. * Invocation must include action. * This function can create a bundle or provide information on an existing - * bundle supporting git-fetch, git-pull, and git-ls-remote + * bundle supporting "fetch", "pull", and "ls-remote". */ -static const char *bundle_usage="git-bundle (create <bundle> <git-rev-list args> | verify <bundle> | list-heads <bundle> [refname]... | unbundle <bundle> [refname]... )"; +static const char *bundle_usage="git bundle (create <bundle> <git rev-list args> | verify <bundle> | list-heads <bundle> [refname]... | unbundle <bundle> [refname]... )"; int cmd_bundle(int argc, const char **argv, const char *prefix) { diff --git a/builtin-cat-file.c b/builtin-cat-file.c index 7441a56acd..3fba6b9e74 100644 --- a/builtin-cat-file.c +++ b/builtin-cat-file.c @@ -137,11 +137,11 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name) break; default: - die("git-cat-file: unknown option: %s\n", exp_type); + die("git cat-file: unknown option: %s\n", exp_type); } if (!buf) - die("git-cat-file %s: bad file", obj_name); + die("git cat-file %s: bad file", obj_name); write_or_die(1, buf, size); return 0; diff --git a/builtin-check-ref-format.c b/builtin-check-ref-format.c index fe04be77a9..701de439ae 100644 --- a/builtin-check-ref-format.c +++ b/builtin-check-ref-format.c @@ -9,6 +9,6 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix) { if (argc != 2) - usage("git-check-ref-format refname"); + usage("git check-ref-format refname"); return !!check_ref_format(argv[1]); } diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c index 71ebabf990..55b7aafe06 100644 --- a/builtin-checkout-index.c +++ b/builtin-checkout-index.c @@ -5,26 +5,26 @@ * * Careful: order of argument flags does matter. For example, * - * git-checkout-index -a -f file.c + * git checkout-index -a -f file.c * * Will first check out all files listed in the cache (but not * overwrite any old ones), and then force-checkout "file.c" a * second time (ie that one _will_ overwrite any old contents * with the same filename). * - * Also, just doing "git-checkout-index" does nothing. You probably - * meant "git-checkout-index -a". And if you want to force it, you - * want "git-checkout-index -f -a". + * Also, just doing "git checkout-index" does nothing. You probably + * meant "git checkout-index -a". And if you want to force it, you + * want "git checkout-index -f -a". * * Intuitiveness is not the goal here. Repeatability is. The * reason for the "no arguments means no work" thing is that * from scripts you are supposed to be able to do things like * - * find . -name '*.h' -print0 | xargs -0 git-checkout-index -f -- + * find . -name '*.h' -print0 | xargs -0 git checkout-index -f -- * * or: * - * find . -name '*.h' -print0 | git-checkout-index -f -z --stdin + * find . -name '*.h' -print0 | git checkout-index -f -z --stdin * * which will force all existing *.h files to be replaced with * their cached copies. If an empty command line implied "all", @@ -107,7 +107,7 @@ static int checkout_file(const char *name, int prefix_length) } if (!state.quiet) { - fprintf(stderr, "git-checkout-index: %s ", name); + fprintf(stderr, "git checkout-index: %s ", name); if (!has_same_name) fprintf(stderr, "is not in the cache"); else if (checkout_stage) @@ -258,9 +258,9 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) const char *p; if (all) - die("git-checkout-index: don't mix '--all' and explicit filenames"); + die("git checkout-index: don't mix '--all' and explicit filenames"); if (read_from_stdin) - die("git-checkout-index: don't mix '--stdin' and explicit filenames"); + die("git checkout-index: don't mix '--stdin' and explicit filenames"); p = prefix_path(prefix, prefix_length, arg); checkout_file(p, prefix_length); if (p < arg || p > arg + strlen(arg)) @@ -271,7 +271,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) struct strbuf buf, nbuf; if (all) - die("git-checkout-index: don't mix '--all' and '--stdin'"); + die("git checkout-index: don't mix '--all' and '--stdin'"); strbuf_init(&buf, 0); strbuf_init(&nbuf, 0); diff --git a/builtin-checkout.c b/builtin-checkout.c index f3c6b0fad2..075667c9cc 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -76,6 +76,15 @@ static int read_tree_some(struct tree *tree, const char **pathspec) return 0; } +static int skip_same_name(struct cache_entry *ce, int pos) +{ + while (++pos < active_nr && + !strcmp(active_cache[pos]->name, ce->name)) + ; /* skip */ + return pos; +} + + static int checkout_paths(struct tree *source_tree, const char **pathspec) { int pos; @@ -107,6 +116,20 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec) if (report_path_error(ps_matched, pathspec, 0)) return 1; + /* Any unmerged paths? */ + for (pos = 0; pos < active_nr; pos++) { + struct cache_entry *ce = active_cache[pos]; + if (pathspec_match(pathspec, NULL, ce->name, 0)) { + if (!ce_stage(ce)) + continue; + errs = 1; + error("path '%s' is unmerged", ce->name); + pos = skip_same_name(ce, pos) - 1; + } + } + if (errs) + return 1; + /* Now we are committed to check them out */ memset(&state, 0, sizeof(state)); state.force = 1; @@ -114,7 +137,11 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec) for (pos = 0; pos < active_nr; pos++) { struct cache_entry *ce = active_cache[pos]; if (pathspec_match(pathspec, NULL, ce->name, 0)) { - errs |= checkout_entry(ce, &state, NULL); + if (!ce_stage(ce)) { + errs |= checkout_entry(ce, &state, NULL); + continue; + } + pos = skip_same_name(ce, pos) - 1; } } @@ -242,6 +269,8 @@ static int merge_working_tree(struct checkout_opts *opts, } /* 2-way merge to the new branch */ + topts.initial_checkout = (!active_nr && + (old->commit == new->commit)); topts.update = 1; topts.merge = 1; topts.gently = opts->merge; @@ -304,7 +333,7 @@ static int merge_working_tree(struct checkout_opts *opts, commit_locked_index(lock_file)) die("unable to write new index file"); - if (!opts->force) + if (!opts->force && !opts->quiet) show_local_changes(&new->commit->object); return 0; @@ -391,13 +420,11 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new) } /* - * If the new thing isn't a branch and isn't HEAD and we're - * not starting a new branch, and we want messages, and we - * weren't on a branch, and we're moving to a new commit, - * describe the old commit. + * If we were on a detached HEAD, but we are now moving to + * a new commit, we want to mention the old commit once more + * to remind the user that it might be lost. */ - if (!new->path && strcmp(new->name, "HEAD") && !opts->new_branch && - !opts->quiet && !old.path && new->commit != old.commit) + if (!opts->quiet && !old.path && new->commit != old.commit) describe_detached_head("Previous HEAD position was", old.commit); if (!old.commit) { @@ -558,6 +585,18 @@ no_reference: return checkout_paths(source_tree, pathspec); } + if (opts.new_branch) { + struct strbuf buf; + strbuf_init(&buf, 0); + strbuf_addstr(&buf, "refs/heads/"); + strbuf_addstr(&buf, opts.new_branch); + if (!get_sha1(buf.buf, rev)) + die("git checkout: branch %s already exists", opts.new_branch); + if (check_ref_format(buf.buf)) + die("git checkout: we do not like '%s' as a branch name.", opts.new_branch); + strbuf_release(&buf); + } + if (new.name && !new.commit) { die("Cannot switch branch to a non-commit."); } diff --git a/builtin-clone.c b/builtin-clone.c index c0e3086437..49d2eb9c2b 100644 --- a/builtin-clone.c +++ b/builtin-clone.c @@ -58,7 +58,7 @@ static struct option builtin_clone_options[] = { OPT_STRING(0, "reference", &option_reference, "repo", "reference repository"), OPT_STRING('o', "origin", &option_origin, "branch", - "use <branch> instead or 'origin' to track upstream"), + "use <branch> instead of 'origin' to track upstream"), OPT_STRING('u', "upload-pack", &option_upload_pack, "path", "path to git-upload-pack on the remote"), OPT_STRING(0, "depth", &option_depth, "depth", @@ -77,7 +77,7 @@ static char *get_repo_path(const char *repo, int *is_bundle) for (i = 0; i < ARRAY_SIZE(suffix); i++) { const char *path; path = mkpath("%s%s", repo, suffix[i]); - if (!stat(path, &st) && S_ISDIR(st.st_mode)) { + if (is_directory(path)) { *is_bundle = 0; return xstrdup(make_nonrelative_path(path)); } @@ -140,11 +140,13 @@ static char *guess_dir_name(const char *repo, int is_bundle, int is_bare) return xstrndup(start, end - start); } -static int is_directory(const char *path) +static void strip_trailing_slashes(char *dir) { - struct stat buf; + char *end = dir + strlen(dir); - return !stat(path, &buf) && S_ISDIR(buf.st_mode); + while (dir < end - 1 && is_dir_sep(end[-1])) + end--; + *end = '\0'; } static void setup_reference(const char *repo) @@ -387,7 +389,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) path = get_repo_path(repo_name, &is_bundle); if (path) - repo = path; + repo = xstrdup(make_nonrelative_path(repo_name)); else if (!strchr(repo_name, ':')) repo = xstrdup(make_absolute_path(repo_name)); else @@ -397,6 +399,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) dir = xstrdup(argv[1]); else dir = guess_dir_name(repo_name, is_bundle, option_bare); + strip_trailing_slashes(dir); if (!stat(dir, &buf)) die("destination directory '%s' already exists.", dir); @@ -422,10 +425,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (!option_bare) { junk_work_tree = work_tree; if (safe_create_leading_directories_const(work_tree) < 0) - die("could not create leading directories of '%s'", - work_tree); + die("could not create leading directories of '%s': %s", + work_tree, strerror(errno)); if (mkdir(work_tree, 0755)) - die("could not create work tree dir '%s'.", work_tree); + die("could not create work tree dir '%s': %s.", + work_tree, strerror(errno)); set_git_work_tree(work_tree); } junk_git_dir = git_dir; diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c index f773db596c..0453425c47 100644 --- a/builtin-commit-tree.c +++ b/builtin-commit-tree.c @@ -24,7 +24,7 @@ static void check_valid(unsigned char *sha1, enum object_type expect) typename(expect)); } -static const char commit_tree_usage[] = "git-commit-tree <sha1> [-p <sha1>]* < changelog"; +static const char commit_tree_usage[] = "git commit-tree <sha1> [-p <sha1>]* < changelog"; static void new_parent(struct commit *parent, struct commit_list **parents_p) { @@ -46,7 +46,8 @@ static const char commit_utf8_warn[] = "variable i18n.commitencoding to the encoding your project uses.\n"; int commit_tree(const char *msg, unsigned char *tree, - struct commit_list *parents, unsigned char *ret) + struct commit_list *parents, unsigned char *ret, + const char *author) { int result; int encoding_is_utf8; @@ -74,7 +75,9 @@ int commit_tree(const char *msg, unsigned char *tree, } /* Person/date information */ - strbuf_addf(&buffer, "author %s\n", git_author_info(IDENT_ERROR_ON_NO_NAME)); + if (!author) + author = git_author_info(IDENT_ERROR_ON_NO_NAME); + strbuf_addf(&buffer, "author %s\n", author); strbuf_addf(&buffer, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME)); if (!encoding_is_utf8) strbuf_addf(&buffer, "encoding %s\n", git_commit_encoding); @@ -121,9 +124,9 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) } if (strbuf_read(&buffer, 0, 0) < 0) - die("git-commit-tree: read returned %s", strerror(errno)); + die("git commit-tree: read returned %s", strerror(errno)); - if (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1)) { + if (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) { printf("%s\n", sha1_to_hex(commit_sha1)); return 0; } diff --git a/builtin-commit.c b/builtin-commit.c index c870037b07..55e1087d27 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -320,7 +320,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix) die("unable to write new_index file"); fd = hold_lock_file_for_update(&false_lock, - git_path("next-index-%d", getpid()), 1); + git_path("next-index-%"PRIuMAX, (uintmax_t) getpid()), 1); create_base_index(); add_remove_files(&partial); @@ -667,14 +667,14 @@ static int prepare_to_commit(const char *index_file, const char *prefix) } /* - * Find out if the message starting at position 'start' in the strbuf - * contains only whitespace and Signed-off-by lines. + * Find out if the message in the strbuf contains only whitespace and + * Signed-off-by lines. */ -static int message_is_empty(struct strbuf *sb, int start) +static int message_is_empty(struct strbuf *sb) { struct strbuf tmpl; const char *nl; - int eol, i; + int eol, i, start = 0; if (cleanup_mode == CLEANUP_NONE && sb->len) return 0; @@ -710,6 +710,31 @@ static int message_is_empty(struct strbuf *sb, int start) return 1; } +static const char *find_author_by_nickname(const char *name) +{ + struct rev_info revs; + struct commit *commit; + struct strbuf buf = STRBUF_INIT; + const char *av[20]; + int ac = 0; + + init_revisions(&revs, NULL); + strbuf_addf(&buf, "--author=%s", name); + av[++ac] = "--all"; + av[++ac] = "-i"; + av[++ac] = buf.buf; + av[++ac] = NULL; + setup_revisions(ac, av, &revs, NULL); + prepare_revision_walk(&revs); + commit = get_revision(&revs); + if (commit) { + strbuf_release(&buf); + format_commit_message(commit, "%an <%ae>", &buf, DATE_NORMAL); + return strbuf_detach(&buf, NULL); + } + die("No existing author found with '%s'", name); +} + static int parse_and_validate_options(int argc, const char *argv[], const char * const usage[], const char *prefix) @@ -720,6 +745,9 @@ static int parse_and_validate_options(int argc, const char *argv[], logfile = parse_options_fix_filename(prefix, logfile); template_file = parse_options_fix_filename(prefix, template_file); + if (force_author && !strchr(force_author, '>')) + force_author = find_author_by_nickname(force_author); + if (logfile || message.len || use_message) use_editor = 0; if (edit_flag) @@ -901,34 +929,14 @@ static const char commit_utf8_warn[] = "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"; -static void add_parent(struct strbuf *sb, const unsigned char *sha1) -{ - struct object *obj = parse_object(sha1); - const char *parent = sha1_to_hex(sha1); - const char *cp; - - if (!obj) - die("Unable to find commit parent %s", parent); - if (obj->type != OBJ_COMMIT) - die("Parent %s isn't a proper commit", parent); - - for (cp = sb->buf; cp && (cp = strstr(cp, "\nparent ")); cp += 8) { - if (!memcmp(cp + 8, parent, 40) && cp[48] == '\n') { - error("duplicate parent %s ignored", parent); - return; - } - } - strbuf_addf(sb, "parent %s\n", parent); -} - int cmd_commit(int argc, const char **argv, const char *prefix) { - int header_len; struct strbuf sb; const char *index_file, *reflog_msg; char *nl, *p; unsigned char commit_sha1[20]; struct ref_lock *ref_lock; + struct commit_list *parents = NULL, **pptr = &parents; git_config(git_commit_config, NULL); @@ -943,13 +951,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix) return 1; } - /* - * The commit object - */ - strbuf_init(&sb, 0); - strbuf_addf(&sb, "tree %s\n", - sha1_to_hex(active_cache_tree->sha1)); - /* Determine parents */ if (initial_commit) { reflog_msg = "commit (initial)"; @@ -963,13 +964,13 @@ int cmd_commit(int argc, const char **argv, const char *prefix) die("could not parse HEAD commit"); for (c = commit->parents; c; c = c->next) - add_parent(&sb, c->item->object.sha1); + pptr = &commit_list_insert(c->item, pptr)->next; } else if (in_merge) { struct strbuf m; FILE *fp; reflog_msg = "commit (merge)"; - add_parent(&sb, head_sha1); + pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next; strbuf_init(&m, 0); fp = fopen(git_path("MERGE_HEAD"), "r"); if (fp == NULL) @@ -979,24 +980,18 @@ int cmd_commit(int argc, const char **argv, const char *prefix) unsigned char sha1[20]; if (get_sha1_hex(m.buf, sha1) < 0) die("Corrupt MERGE_HEAD file (%s)", m.buf); - add_parent(&sb, sha1); + pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next; } fclose(fp); strbuf_release(&m); } else { reflog_msg = "commit"; - strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1)); + pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next; } - - strbuf_addf(&sb, "author %s\n", - fmt_ident(author_name, author_email, author_date, IDENT_ERROR_ON_NO_NAME)); - strbuf_addf(&sb, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME)); - if (!is_encoding_utf8(git_commit_encoding)) - strbuf_addf(&sb, "encoding %s\n", git_commit_encoding); - strbuf_addch(&sb, '\n'); + parents = reduce_heads(parents); /* Finally, get the commit message */ - header_len = sb.len; + strbuf_init(&sb, 0); if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) { rollback_index_files(); die("could not read commit message"); @@ -1009,16 +1004,15 @@ int cmd_commit(int argc, const char **argv, const char *prefix) if (cleanup_mode != CLEANUP_NONE) stripspace(&sb, cleanup_mode == CLEANUP_ALL); - if (sb.len < header_len || message_is_empty(&sb, header_len)) { + if (message_is_empty(&sb)) { rollback_index_files(); fprintf(stderr, "Aborting commit due to empty commit message.\n"); exit(1); } - strbuf_addch(&sb, '\0'); - if (is_encoding_utf8(git_commit_encoding) && !is_utf8(sb.buf)) - fprintf(stderr, commit_utf8_warn); - if (write_sha1_file(sb.buf, sb.len - 1, commit_type, commit_sha1)) { + if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1, + fmt_ident(author_name, author_email, author_date, + IDENT_ERROR_ON_NO_NAME))) { rollback_index_files(); die("failed to write commit object"); } @@ -1027,12 +1021,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix) initial_commit ? NULL : head_sha1, 0); - nl = strchr(sb.buf + header_len, '\n'); + nl = strchr(sb.buf, '\n'); if (nl) strbuf_setlen(&sb, nl + 1 - sb.buf); else strbuf_addch(&sb, '\n'); - strbuf_remove(&sb, 0, header_len); strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg)); strbuf_insert(&sb, strlen(reflog_msg), ": ", 2); diff --git a/builtin-count-objects.c b/builtin-count-objects.c index 6e80fe7c01..ab35b65b07 100644 --- a/builtin-count-objects.c +++ b/builtin-count-objects.c @@ -126,6 +126,6 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) } else printf("%lu objects, %lu kilobytes\n", - loose, loose_size / 2); + loose, loose_size / 1024); return 0; } diff --git a/builtin-diff-files.c b/builtin-diff-files.c index 9bf10bb37e..2b578c714d 100644 --- a/builtin-diff-files.c +++ b/builtin-diff-files.c @@ -50,7 +50,12 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) 3 < rev.max_count) usage(diff_files_usage); - if (rev.max_count == -1 && + /* + * "diff-files --base -p" should not combine merges because it + * was not asked to. "diff-files -c -p" should not densify + * (the user should ask with "diff-files --cc" explicitly). + */ + if (rev.max_count == -1 && !rev.combine_merges && (rev.diffopt.output_format & DIFF_FORMAT_PATCH)) rev.combine_merges = rev.dense_combined_merges = 1; diff --git a/builtin-diff-index.c b/builtin-diff-index.c index 17d851b29e..04837494fe 100644 --- a/builtin-diff-index.c +++ b/builtin-diff-index.c @@ -39,6 +39,8 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) if (rev.pending.nr != 1 || rev.max_count != -1 || rev.min_age != -1 || rev.max_age != -1) usage(diff_cache_usage); + if (!cached) + setup_work_tree(); if (read_cache() < 0) { perror("read_cache"); return -1; diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c index 1138c2da73..8ecefd4f0f 100644 --- a/builtin-diff-tree.c +++ b/builtin-diff-tree.c @@ -71,8 +71,9 @@ static int diff_tree_stdin(char *line) line[len-1] = 0; if (get_sha1_hex(line, sha1)) return -1; - obj = lookup_object(sha1); - obj = obj ? obj : parse_object(sha1); + obj = lookup_unknown_object(sha1); + if (!obj || !obj->parsed) + obj = parse_object(sha1); if (!obj) return -1; if (obj->type == OBJ_COMMIT) diff --git a/builtin-diff.c b/builtin-diff.c index 7ffea97505..35da366f46 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -74,6 +74,8 @@ static int builtin_diff_b_f(struct rev_info *revs, if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))) die("'%s': not a regular file or symlink", path); + diff_set_mnemonic_prefix(&revs->diffopt, "o/", "w/"); + if (blob[0].mode == S_IFINVALID) blob[0].mode = canon_mode(st.st_mode); @@ -122,6 +124,8 @@ static int builtin_diff_index(struct rev_info *revs, usage(builtin_diff_usage); argv++; argc--; } + if (!cached) + setup_work_tree(); /* * Make sure there is one revision (i.e. pending object), * and there is no revision filtering parameters. @@ -221,10 +225,17 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv argv++; argc--; } - if (revs->max_count == -1 && + /* + * "diff --base" should not combine merges because it was not + * asked to. "diff -c" should not densify (if the user wants + * dense one, --cc can be explicitly asked for, or just rely + * on the default). + */ + if (revs->max_count == -1 && !revs->combine_merges && (revs->diffopt.output_format & DIFF_FORMAT_PATCH)) revs->combine_merges = revs->dense_combined_merges = 1; + setup_work_tree(); if (read_cache() < 0) { perror("read_cache"); return -1; diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c index 273239af3b..fa3c936493 100644 --- a/builtin-fetch-pack.c +++ b/builtin-fetch-pack.c @@ -540,7 +540,7 @@ static int get_pack(int xd[2], char **pack_lockfile) *av++ = "--fix-thin"; if (args.lock_pack || unpack_limit) { int s = sprintf(keep_arg, - "--keep=fetch-pack %d on ", getpid()); + "--keep=fetch-pack %"PRIuMAX " on ", (uintmax_t) getpid()); if (gethostname(keep_arg + s, sizeof(keep_arg) - s)) strcpy(keep_arg + s, "localhost"); *av++ = keep_arg; @@ -609,7 +609,7 @@ static struct ref *do_fetch_pack(int fd[2], fprintf(stderr, "warning: no common commits\n"); if (get_pack(fd, pack_lockfile)) - die("git-fetch-pack: fetch failed."); + die("git fetch-pack: fetch failed."); all_done: return ref; @@ -735,7 +735,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) conn = git_connect(fd, (char *)dest, args.uploadpack, args.verbose ? CONNECT_VERBOSE : 0); if (conn) { - get_remote_heads(fd[0], &ref, 0, NULL, 0); + get_remote_heads(fd[0], &ref, 0, NULL, 0, NULL); ref = fetch_pack(&args, fd, conn, ref, dest, nr_heads, heads, NULL); close(fd[0]); @@ -750,7 +750,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) if (!ret && nr_heads) { /* If the heads to pull were given, we should have * consumed all of them by matching the remote. - * Otherwise, 'git-fetch remote no-such-ref' would + * Otherwise, 'git fetch remote no-such-ref' would * silently succeed without issuing an error. */ for (i = 0; i < nr_heads; i++) diff --git a/builtin-fetch.c b/builtin-fetch.c index 7eec4a0e43..ee93d3a93d 100644 --- a/builtin-fetch.c +++ b/builtin-fetch.c @@ -86,10 +86,10 @@ static void add_merge_config(struct ref **head, /* * Not fetched to a tracking branch? We need to fetch * it anyway to allow this branch's "branch.$name.merge" - * to be honored by git-pull, but we do not have to + * to be honored by 'git pull', but we do not have to * fail if branch.$name.merge is misconfigured to point * at a nonexisting branch. If we were indeed called by - * git-pull, it will notice the misconfiguration because + * 'git pull', it will notice the misconfiguration because * there is no entry in the resulting FETCH_HEAD marked * for merging. */ @@ -396,7 +396,7 @@ static int store_updated_refs(const char *url, const char *remote_name, * The refs we are going to fetch are in to_fetch (nr_heads in * total). If running * - * $ git-rev-list --objects to_fetch[0] to_fetch[1] ... --not --all + * $ git rev-list --objects to_fetch[0] to_fetch[1] ... --not --all * * does not error out, that means everything reachable from the * refs we are going to fetch exists and is connected to some of diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c index 21e92bbcb5..e59bd8075e 100644 --- a/builtin-for-each-ref.c +++ b/builtin-for-each-ref.c @@ -321,8 +321,8 @@ static const char *find_wholine(const char *who, int wholen, const char *buf, un static const char *copy_line(const char *buf) { const char *eol = strchr(buf, '\n'); - if (!eol) - return ""; + if (!eol) // simulate strchrnul() + eol = buf + strlen(buf); return xmemdupz(buf, eol - buf); } @@ -546,6 +546,107 @@ static void grab_values(struct atom_value *val, int deref, struct object *obj, v } /* + * generate a format suitable for scanf from a ref_rev_parse_rules + * rule, that is replace the "%.*s" spec with a "%s" spec + */ +static void gen_scanf_fmt(char *scanf_fmt, const char *rule) +{ + char *spec; + + spec = strstr(rule, "%.*s"); + if (!spec || strstr(spec + 4, "%.*s")) + die("invalid rule in ref_rev_parse_rules: %s", rule); + + /* copy all until spec */ + strncpy(scanf_fmt, rule, spec - rule); + scanf_fmt[spec - rule] = '\0'; + /* copy new spec */ + strcat(scanf_fmt, "%s"); + /* copy remaining rule */ + strcat(scanf_fmt, spec + 4); + + return; +} + +/* + * Shorten the refname to an non-ambiguous form + */ +static char *get_short_ref(struct refinfo *ref) +{ + int i; + static char **scanf_fmts; + static int nr_rules; + char *short_name; + + /* pre generate scanf formats from ref_rev_parse_rules[] */ + if (!nr_rules) { + size_t total_len = 0; + + /* the rule list is NULL terminated, count them first */ + for (; ref_rev_parse_rules[nr_rules]; nr_rules++) + /* no +1 because strlen("%s") < strlen("%.*s") */ + total_len += strlen(ref_rev_parse_rules[nr_rules]); + + scanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len); + + total_len = 0; + for (i = 0; i < nr_rules; i++) { + scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + + total_len; + gen_scanf_fmt(scanf_fmts[i], ref_rev_parse_rules[i]); + total_len += strlen(ref_rev_parse_rules[i]); + } + } + + /* bail out if there are no rules */ + if (!nr_rules) + return ref->refname; + + /* buffer for scanf result, at most ref->refname must fit */ + short_name = xstrdup(ref->refname); + + /* skip first rule, it will always match */ + for (i = nr_rules - 1; i > 0 ; --i) { + int j; + int short_name_len; + + if (1 != sscanf(ref->refname, scanf_fmts[i], short_name)) + continue; + + short_name_len = strlen(short_name); + + /* + * check if the short name resolves to a valid ref, + * but use only rules prior to the matched one + */ + for (j = 0; j < i; j++) { + const char *rule = ref_rev_parse_rules[j]; + unsigned char short_objectname[20]; + + /* + * the short name is ambiguous, if it resolves + * (with this previous rule) to a valid ref + * read_ref() returns 0 on success + */ + if (!read_ref(mkpath(rule, short_name_len, short_name), + short_objectname)) + break; + } + + /* + * short name is non-ambiguous if all previous rules + * haven't resolved to a valid ref + */ + if (j == i) + return short_name; + } + + free(short_name); + return ref->refname; +} + + +/* * Parse the object referred by ref, and grab needed value. */ static void populate_value(struct refinfo *ref) @@ -570,13 +671,33 @@ static void populate_value(struct refinfo *ref) for (i = 0; i < used_atom_cnt; i++) { const char *name = used_atom[i]; struct atom_value *v = &ref->value[i]; - if (!strcmp(name, "refname")) - v->s = ref->refname; - else if (!strcmp(name, "*refname")) { - int len = strlen(ref->refname); - char *s = xmalloc(len + 4); - sprintf(s, "%s^{}", ref->refname); - v->s = s; + int deref = 0; + if (*name == '*') { + deref = 1; + name++; + } + if (!prefixcmp(name, "refname")) { + const char *formatp = strchr(name, ':'); + const char *refname = ref->refname; + + /* look for "short" refname format */ + if (formatp) { + formatp++; + if (!strcmp(formatp, "short")) + refname = get_short_ref(ref); + else + die("unknown refname format %s", + formatp); + } + + if (!deref) + v->s = refname; + else { + int len = strlen(refname); + char *s = xmalloc(len + 4); + sprintf(s, "%s^{}", refname); + v->s = s; + } } } diff --git a/builtin-grep.c b/builtin-grep.c index 631129ddfd..3a51662a35 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -774,7 +774,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) /* Make sure we do not get outside of paths */ for (i = 0; paths[i]; i++) if (strncmp(prefix, paths[i], opt.prefix_length)) - die("git-grep: cannot generate relative filenames containing '..'"); + die("git grep: cannot generate relative filenames containing '..'"); } } else if (prefix) { @@ -783,8 +783,11 @@ int cmd_grep(int argc, const char **argv, const char *prefix) paths[1] = NULL; } - if (!list.nr) + if (!list.nr) { + if (!cached) + setup_work_tree(); return !grep_cache(&opt, paths, cached); + } if (cached) die("both --cached and trees are given."); diff --git a/builtin-help.c b/builtin-help.c index 721038e4f5..64207cbfe9 100644 --- a/builtin-help.c +++ b/builtin-help.c @@ -361,12 +361,15 @@ static void show_man_page(const char *git_cmd) { struct man_viewer_list *viewer; const char *page = cmd_to_page(git_cmd); + const char *fallback = getenv("GIT_MAN_VIEWER"); setup_man_path(); for (viewer = man_viewer_list; viewer; viewer = viewer->next) { exec_viewer(viewer->name, page); /* will return when unable */ } + if (fallback) + exec_viewer(fallback, page); exec_viewer("man", page); die("no man viewer handled the request"); } diff --git a/builtin-http-fetch.c b/builtin-http-fetch.c index 3a062487a7..f3e63d7206 100644 --- a/builtin-http-fetch.c +++ b/builtin-http-fetch.c @@ -42,7 +42,7 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix) arg++; } if (argc < arg + 2 - commits_on_stdin) { - usage("git-http-fetch [-c] [-t] [-a] [-v] [--recover] [-w ref] [--stdin] commit-id url"); + usage("git http-fetch [-c] [-t] [-a] [-v] [--recover] [-w ref] [--stdin] commit-id url"); return 1; } if (commits_on_stdin) { @@ -53,7 +53,7 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix) } url = argv[arg]; if (url && url[strlen(url)-1] != '/') { - rewritten_url = malloc(strlen(url)+2); + rewritten_url = xmalloc(strlen(url)+2); strcpy(rewritten_url, url); strcat(rewritten_url, "/"); url = rewritten_url; @@ -75,7 +75,7 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix) fprintf(stderr, "Some loose object were found to be corrupt, but they might be just\n" "a false '404 Not Found' error message sent with incorrect HTTP\n" -"status code. Suggest running git-fsck.\n"); +"status code. Suggest running 'git fsck'.\n"); } walker_free(walker); diff --git a/builtin-init-db.c b/builtin-init-db.c index baf0d09ac4..8140c1299a 100644 --- a/builtin-init-db.c +++ b/builtin-init-db.c @@ -37,7 +37,7 @@ static void copy_templates_1(char *path, int baselen, /* Note: if ".git/hooks" file exists in the repository being * re-initialized, /etc/core-git/templates/hooks/update would - * cause git-init to fail here. I think this is sane but + * cause "git init" to fail here. I think this is sane but * it means that the set of templates we ship by default, along * with the way the namespace under .git/ is organized, should * be really carefully chosen. diff --git a/builtin-log.c b/builtin-log.c index 1d3c5cbf58..fc5e4da822 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -14,7 +14,6 @@ #include "tag.h" #include "reflog-walk.h" #include "patch-ids.h" -#include "refs.h" #include "run-command.h" #include "shortlog.h" @@ -25,31 +24,6 @@ static int default_show_root = 1; static const char *fmt_patch_subject_prefix = "PATCH"; static const char *fmt_pretty; -static void add_name_decoration(const char *prefix, const char *name, struct object *obj) -{ - int plen = strlen(prefix); - int nlen = strlen(name); - struct name_decoration *res = xmalloc(sizeof(struct name_decoration) + plen + nlen); - memcpy(res->name, prefix, plen); - memcpy(res->name + plen, name, nlen + 1); - res->next = add_decoration(&name_decoration, obj, res); -} - -static int add_ref_decoration(const char *refname, const unsigned char *sha1, int flags, void *cb_data) -{ - struct object *obj = parse_object(sha1); - if (!obj) - return 0; - add_name_decoration("", refname, obj); - while (obj->type == OBJ_TAG) { - obj = ((struct tag *)obj)->tagged; - if (!obj) - break; - add_name_decoration("tag: ", refname, obj); - } - return 0; -} - static void cmd_log_init(int argc, const char **argv, const char *prefix, struct rev_info *rev) { @@ -80,8 +54,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix, for (i = 1; i < argc; i++) { const char *arg = argv[i]; if (!strcmp(arg, "--decorate")) { - if (!decorate) - for_each_ref(add_ref_decoration, NULL); + load_ref_decorations(); decorate = 1; } else die("unrecognized argument: %s", arg); @@ -844,7 +817,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) committer = git_committer_info(IDENT_ERROR_ON_NO_NAME); endpos = strchr(committer, '>'); if (!endpos) - die("bogos committer info %s\n", committer); + die("bogus committer info %s\n", committer); add_signoff = xmemdupz(committer, endpos - committer + 1); } else if (!strcmp(argv[i], "--attach")) { diff --git a/builtin-ls-files.c b/builtin-ls-files.c index e8d568eed7..068f424696 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -78,7 +78,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent) int offset = prefix_offset; if (len >= ent->len) - die("git-ls-files: internal error - directory entry not superset of prefix"); + die("git ls-files: internal error - directory entry not superset of prefix"); if (pathspec && !pathspec_match(pathspec, ps_matched, ent->name, len)) return; @@ -183,7 +183,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce) int offset = prefix_offset; if (len >= ce_namelen(ce)) - die("git-ls-files: internal error - cache entry not superset of prefix"); + die("git ls-files: internal error - cache entry not superset of prefix"); if (pathspec && !pathspec_match(pathspec, ps_matched, ce->name, len)) return; @@ -319,7 +319,7 @@ static const char *verify_pathspec(const char *prefix) } if (prefix_offset > max || memcmp(prev, prefix, prefix_offset)) - die("git-ls-files: cannot generate relative filenames containing '..'"); + die("git ls-files: cannot generate relative filenames containing '..'"); prefix_len = max; return max ? xmemdupz(prev, max) : NULL; diff --git a/builtin-merge.c b/builtin-merge.c index bb09e6fb34..5c65a58699 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -477,6 +477,8 @@ static int git_merge_config(const char *k, const char *v, void *cb) buf = xstrdup(v); argc = split_cmdline(buf, &argv); + if (argc < 0) + die("Bad branch.%s.mergeoptions string", branch); argv = xrealloc(argv, sizeof(*argv) * (argc + 2)); memmove(argv + 1, argv, sizeof(*argv) * (argc + 1)); argc++; @@ -729,7 +731,7 @@ static int merge_trivial(void) parent->next = xmalloc(sizeof(struct commit_list *)); parent->next->item = remoteheads->item; parent->next->next = NULL; - commit_tree(merge_msg.buf, result_tree, parent, result_commit); + commit_tree(merge_msg.buf, result_tree, parent, result_commit, NULL); finish(result_commit, "In-index merge"); drop_save(); return 0; @@ -758,7 +760,7 @@ static int finish_automerge(struct commit_list *common, } free_commit_list(remoteheads); strbuf_addch(&merge_msg, '\n'); - commit_tree(merge_msg.buf, result_tree, parents, result_commit); + commit_tree(merge_msg.buf, result_tree, parents, result_commit, NULL); strbuf_addf(&buf, "Merge made by %s.", wt_strategy); finish(result_commit, buf.buf); strbuf_release(&buf); diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index ef3befe57b..1158e42cba 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -23,7 +23,7 @@ #endif static const char pack_usage[] = "\ -git-pack-objects [{ -q | --progress | --all-progress }] \n\ +git pack-objects [{ -q | --progress | --all-progress }] \n\ [--max-pack-size=N] [--local] [--incremental] \n\ [--window=N] [--window-memory=N] [--depth=N] \n\ [--no-reuse-delta] [--no-reuse-object] [--delta-base-offset] \n\ @@ -410,25 +410,22 @@ static unsigned long write_object(struct sha1file *f, return hdrlen + datalen; } -static off_t write_one(struct sha1file *f, +static int write_one(struct sha1file *f, struct object_entry *e, - off_t offset) + off_t *offset) { unsigned long size; /* offset is non zero if object is written already. */ if (e->idx.offset || e->preferred_base) - return offset; + return 1; /* if we are deltified, write out base object first. */ - if (e->delta) { - offset = write_one(f, e->delta, offset); - if (!offset) - return 0; - } + if (e->delta && !write_one(f, e->delta, offset)) + return 0; - e->idx.offset = offset; - size = write_object(f, e, offset); + e->idx.offset = *offset; + size = write_object(f, e, *offset); if (!size) { e->idx.offset = 0; return 0; @@ -436,9 +433,10 @@ static off_t write_one(struct sha1file *f, written_list[nr_written++] = &e->idx; /* make sure off_t is sufficiently large not to wrap */ - if (offset > offset + size) + if (*offset > *offset + size) die("pack too large for current definition of off_t"); - return offset + size; + *offset += size; + return 1; } /* forward declaration for write_pack_file */ @@ -448,7 +446,7 @@ static void write_pack_file(void) { uint32_t i = 0, j; struct sha1file *f; - off_t offset, offset_one, last_obj_offset = 0; + off_t offset; struct pack_header hdr; uint32_t nr_remaining = nr_result; time_t last_mtime = 0; @@ -467,7 +465,7 @@ static void write_pack_file(void) char tmpname[PATH_MAX]; int fd; snprintf(tmpname, sizeof(tmpname), - "%s/tmp_pack_XXXXXX", get_object_directory()); + "%s/pack/tmp_pack_XXXXXX", get_object_directory()); fd = xmkstemp(tmpname); pack_tmp_name = xstrdup(tmpname); f = sha1fd(fd, pack_tmp_name); @@ -480,11 +478,8 @@ static void write_pack_file(void) offset = sizeof(hdr); nr_written = 0; for (; i < nr_objects; i++) { - last_obj_offset = offset; - offset_one = write_one(f, objects + i, offset); - if (!offset_one) + if (!write_one(f, objects + i, &offset)) break; - offset = offset_one; display_progress(progress_state, written); } @@ -497,8 +492,9 @@ static void write_pack_file(void) } else if (nr_written == nr_remaining) { sha1close(f, sha1, CSUM_FSYNC); } else { - int fd = sha1close(f, NULL, 0); - fixup_pack_header_footer(fd, sha1, pack_tmp_name, nr_written); + int fd = sha1close(f, sha1, 0); + fixup_pack_header_footer(fd, sha1, pack_tmp_name, + nr_written, sha1, offset); close(fd); } @@ -1729,6 +1725,14 @@ static void prepare_pack(int window, int depth) if (entry->type < 0) die("unable to get type of object %s", sha1_to_hex(entry->idx.sha1)); + } else { + if (entry->type < 0) { + /* + * This object is not found, but we + * don't have to include it anyway. + */ + continue; + } } delta_list[n++] = entry; @@ -1876,7 +1880,7 @@ static void mark_in_pack_object(struct object *object, struct packed_git *p, str /* * Compare the objects in the offset order, in order to emulate the - * "git-rev-list --objects" output that produced the pack originally. + * "git rev-list --objects" output that produced the pack originally. */ static int ofscmp(const void *a_, const void *b_) { diff --git a/builtin-prune.c b/builtin-prune.c index c767a0ac89..1663f8bdb1 100644 --- a/builtin-prune.c +++ b/builtin-prune.c @@ -13,7 +13,7 @@ static const char * const prune_usage[] = { static int show_only; static unsigned long expire; -static int prune_tmp_object(char *path, const char *filename) +static int prune_tmp_object(const char *path, const char *filename) { const char *fullpath = mkpath("%s/%s", path, filename); if (expire) { @@ -110,24 +110,22 @@ static void prune_object_dir(const char *path) /* * Write errors (particularly out of space) can result in * failed temporary packs (and more rarely indexes and other - * files begining with "tmp_") accumulating in the - * object directory. + * files begining with "tmp_") accumulating in the object + * and the pack directories. */ -static void remove_temporary_files(void) +static void remove_temporary_files(const char *path) { DIR *dir; struct dirent *de; - char* dirname=get_object_directory(); - dir = opendir(dirname); + dir = opendir(path); if (!dir) { - fprintf(stderr, "Unable to open object directory %s\n", - dirname); + fprintf(stderr, "Unable to open directory %s\n", path); return; } while ((de = readdir(dir)) != NULL) if (!prefixcmp(de->d_name, "tmp_")) - prune_tmp_object(dirname, de->d_name); + prune_tmp_object(path, de->d_name); closedir(dir); } @@ -141,6 +139,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix) "expire objects older than <time>"), OPT_END() }; + char *s; save_commit_buffer = 0; init_revisions(&revs, prefix); @@ -163,6 +162,9 @@ int cmd_prune(int argc, const char **argv, const char *prefix) prune_object_dir(get_object_directory()); prune_packed_objects(show_only); - remove_temporary_files(); + remove_temporary_files(get_object_directory()); + s = xstrdup(mkpath("%s/pack", get_object_directory())); + remove_temporary_files(s); + free(s); return 0; } diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 72a6de302f..0706c95818 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -64,7 +64,7 @@ static void prime_cache_tree(void) } -static const char read_tree_usage[] = "git-read-tree (<sha> | [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <sha1> [<sha2> [<sha3>]])"; +static const char read_tree_usage[] = "git read-tree (<sha> | [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <sha1> [<sha2> [<sha3>]])"; static struct lock_file lock_file; @@ -194,6 +194,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) usage(read_tree_usage); if ((opts.dir && !opts.update)) die("--exclude-per-directory is meaningless unless -u"); + if (opts.merge && !opts.index_only) + setup_work_tree(); if (opts.merge) { if (stage < 2) @@ -204,6 +206,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) break; case 2: opts.fn = twoway_merge; + opts.initial_checkout = !active_nr; break; case 3: default: diff --git a/receive-pack.c b/builtin-receive-pack.c index d44c19e6b5..45e3cd90fd 100644 --- a/receive-pack.c +++ b/builtin-receive-pack.c @@ -6,6 +6,8 @@ #include "exec_cmd.h" #include "commit.h" #include "object.h" +#include "remote.h" +#include "transport.h" static const char receive_pack_usage[] = "git-receive-pack <git-dir>"; @@ -407,7 +409,7 @@ static const char *unpack(void) char keep_arg[256]; struct child_process ip; - s = sprintf(keep_arg, "--keep=receive-pack %i on ", getpid()); + s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid()); if (gethostname(keep_arg + s, sizeof(keep_arg) - s)) strcpy(keep_arg + s, "localhost"); @@ -462,14 +464,48 @@ static int delete_only(struct command *cmd) return 1; } -int main(int argc, char **argv) +static int add_refs_from_alternate(struct alternate_object_database *e, void *unused) +{ + char *other = xstrdup(make_absolute_path(e->base)); + size_t len = strlen(other); + struct remote *remote; + struct transport *transport; + const struct ref *extra; + + while (other[len-1] == '/') + other[--len] = '\0'; + if (len < 8 || memcmp(other + len - 8, "/objects", 8)) + return 0; + /* Is this a git repository with refs? */ + memcpy(other + len - 8, "/refs", 6); + if (!is_directory(other)) + return 0; + other[len - 8] = '\0'; + remote = remote_get(other); + transport = transport_get(remote, other); + for (extra = transport_get_remote_refs(transport); + extra; + extra = extra->next) { + add_extra_ref(".have", extra->old_sha1, 0); + } + transport_disconnect(transport); + free(other); + return 0; +} + +static void add_alternate_refs(void) +{ + foreach_alt_odb(add_refs_from_alternate, NULL); +} + +int cmd_receive_pack(int argc, const char **argv, const char *prefix) { int i; char *dir = NULL; argv++; for (i = 1; i < argc; i++) { - char *arg = *argv++; + const char *arg = *argv++; if (*arg == '-') { /* Do flag handling here */ @@ -477,7 +513,7 @@ int main(int argc, char **argv) } if (dir) usage(receive_pack_usage); - dir = arg; + dir = xstrdup(arg); } if (!dir) usage(receive_pack_usage); @@ -497,7 +533,9 @@ int main(int argc, char **argv) else if (0 <= receive_unpack_limit) unpack_limit = receive_unpack_limit; + add_alternate_refs(); write_head_info(); + clear_extra_refs(); /* EOF */ packet_flush(1); diff --git a/builtin-remote.c b/builtin-remote.c index 01945a8651..4cb763f989 100644 --- a/builtin-remote.c +++ b/builtin-remote.c @@ -407,14 +407,15 @@ static int rm(int argc, const char **argv) return i; } -static void show_list(const char *title, struct string_list *list) +static void show_list(const char *title, struct string_list *list, + const char *extra_arg) { int i; if (!list->nr) return; - printf(title, list->nr > 1 ? "es" : ""); + printf(title, list->nr > 1 ? "es" : "", extra_arg); printf("\n "); for (i = 0; i < list->nr; i++) printf("%s%s", i ? " " : "", list->items[i].string); @@ -477,7 +478,6 @@ static int show(int argc, const char **argv) memset(&states, 0, sizeof(states)); for (; argc; argc--, argv++) { - struct strbuf buf; int i; get_remote_ref_states(*argv, &states, !no_query); @@ -503,18 +503,16 @@ static int show(int argc, const char **argv) } if (!no_query) { - strbuf_init(&buf, 0); - strbuf_addf(&buf, " New remote branch%%s (next fetch " - "will store in remotes/%s)", states.remote->name); - show_list(buf.buf, &states.new); - strbuf_release(&buf); + show_list(" New remote branch%s (next fetch " + "will store in remotes/%s)", + &states.new, states.remote->name); show_list(" Stale tracking branch%s (use 'git remote " - "prune')", &states.stale); + "prune')", &states.stale, ""); } if (no_query) for_each_ref(append_ref_to_tracked_list, &states); - show_list(" Tracked remote branch%s", &states.tracked); + show_list(" Tracked remote branch%s", &states.tracked, ""); if (states.remote->push_refspec_nr) { printf(" Local branch%s pushed with 'git push'\n ", diff --git a/builtin-rev-list.c b/builtin-rev-list.c index c023003b2b..facaff288d 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -178,7 +178,7 @@ static void finish_object(struct object_array_entry *p) static void show_object(struct object_array_entry *p) { /* An object with name "foo\n0000000..." can be used to - * confuse downstream git-pack-objects very badly. + * confuse downstream "git pack-objects" very badly. */ const char *ep = strchr(p->name, '\n'); diff --git a/builtin-rm.c b/builtin-rm.c index 0ed26bb8f1..fdac34f242 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -104,7 +104,7 @@ static int check_local_mod(unsigned char *head, int index_only) "from both the file and the HEAD\n" "(use -f to force removal)", name); else if (!index_only) { - /* It's not dangerous to git-rm --cached a + /* It's not dangerous to "git rm --cached" a * file if the index matches the file or the * HEAD, since it means the deleted content is * still available somewhere. @@ -221,7 +221,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) printf("rm '%s'\n", path); if (remove_file_from_cache(path)) - die("git-rm: unable to remove %s", path); + die("git rm: unable to remove %s", path); } if (show_only) @@ -244,7 +244,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) continue; } if (!removed) - die("git-rm: %s: %s", path, strerror(errno)); + die("git rm: %s: %s", path, strerror(errno)); } } diff --git a/builtin-send-pack.c b/builtin-send-pack.c index 7588d22885..910db92b62 100644 --- a/builtin-send-pack.c +++ b/builtin-send-pack.c @@ -18,7 +18,7 @@ static struct send_pack_args args = { /* * Make a pack stream and spit it out into file descriptor fd */ -static int pack_objects(int fd, struct ref *refs) +static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra) { /* * The child becomes pack-objects --revs; we feed @@ -34,6 +34,8 @@ static int pack_objects(int fd, struct ref *refs) NULL, }; struct child_process po; + int i; + char buf[42]; if (args.use_thin_pack) argv[4] = "--thin"; @@ -43,15 +45,21 @@ static int pack_objects(int fd, struct ref *refs) po.out = fd; po.git_cmd = 1; if (start_command(&po)) - die("git-pack-objects failed (%s)", strerror(errno)); + die("git pack-objects failed (%s)", strerror(errno)); /* * We feed the pack-objects we just spawned with revision * parameters by writing to the pipe. */ - while (refs) { - char buf[42]; + 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")) + 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); @@ -381,14 +389,17 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest int expect_status_report = 0; int flags = MATCH_REFS_NONE; int ret; + struct extra_have_objects extra_have; + memset(&extra_have, 0, sizeof(extra_have)); if (args.send_all) flags |= MATCH_REFS_ALL; if (args.send_mirror) flags |= MATCH_REFS_MIRROR; /* No funny business with the matcher */ - remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL); + remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL, + &extra_have); get_local_heads(); /* Does the other end support the reporting? */ @@ -496,7 +507,7 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest packet_flush(out); if (new_refs && !args.dry_run) { - if (pack_objects(out, remote_refs) < 0) + if (pack_objects(out, remote_refs, &extra_have) < 0) return -1; } else diff --git a/builtin-show-ref.c b/builtin-show-ref.c index add16004f1..572b114119 100644 --- a/builtin-show-ref.c +++ b/builtin-show-ref.c @@ -62,7 +62,7 @@ match: * ref points at a nonexistent object. */ if (!has_sha1_file(sha1)) - die("git-show-ref: bad ref %s (%s)", refname, + die("git show-ref: bad ref %s (%s)", refname, sha1_to_hex(sha1)); if (quiet) @@ -82,12 +82,12 @@ match: else { obj = parse_object(sha1); if (!obj) - die("git-show-ref: bad ref %s (%s)", refname, + die("git show-ref: bad ref %s (%s)", refname, sha1_to_hex(sha1)); if (obj->type == OBJ_TAG) { obj = deref_tag(obj, refname, 0); if (!obj) - die("git-show-ref: bad tag at ref %s (%s)", refname, + die("git show-ref: bad tag at ref %s (%s)", refname, sha1_to_hex(sha1)); hex = find_unique_abbrev(obj->sha1, abbrev); printf("%s %s^{}\n", hex, refname); diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c index f4bea4a322..0713bca778 100644 --- a/builtin-tar-tree.c +++ b/builtin-tar-tree.c @@ -9,26 +9,26 @@ static const char tar_tree_usage[] = "git tar-tree [--remote=<repo>] <tree-ish> [basedir]\n" -"*** Note that this command is now deprecated; use git-archive instead."; +"*** Note that this command is now deprecated; use \"git archive\" instead."; int cmd_tar_tree(int argc, const char **argv, const char *prefix) { /* - * git-tar-tree is now a wrapper around git-archive --format=tar + * "git tar-tree" is now a wrapper around "git archive --format=tar" * * $0 --remote=<repo> arg... ==> - * git-archive --format=tar --remote=<repo> arg... + * git archive --format=tar --remote=<repo> arg... * $0 tree-ish ==> - * git-archive --format=tar tree-ish + * git archive --format=tar tree-ish * $0 tree-ish basedir ==> - * git-archive --format-tar --prefix=basedir tree-ish + * git archive --format-tar --prefix=basedir tree-ish */ int i; const char **nargv = xcalloc(sizeof(*nargv), argc + 2); char *basedir_arg; int nargc = 0; - nargv[nargc++] = "git-archive"; + nargv[nargc++] = "archive"; nargv[nargc++] = "--format=tar"; if (2 <= argc && !prefixcmp(argv[1], "--remote=")) { @@ -53,8 +53,8 @@ int cmd_tar_tree(int argc, const char **argv, const char *prefix) nargv[nargc] = NULL; fprintf(stderr, - "*** git-tar-tree is now deprecated.\n" - "*** Running git-archive instead.\n***"); + "*** \"git tar-tree\" is now deprecated.\n" + "*** Running \"git archive\" instead.\n***"); for (i = 0; i < nargc; i++) { fputc(' ', stderr); sq_quote_print(stderr, nargv[i]); @@ -76,7 +76,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix) n = read_in_full(0, buffer, HEADERSIZE); if (n < HEADERSIZE) - die("git-get-tar-commit-id: read error"); + die("git get-tar-commit-id: read error"); if (header->typeflag[0] != 'g') return 1; if (memcmp(content, "52 comment=", 11)) @@ -84,7 +84,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix) n = write_in_full(1, content + 11, 41); if (n < 41) - die("git-get-tar-commit-id: write error"); + die("git get-tar-commit-id: write error"); return 0; } diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c index a891866665..40b20f26e8 100644 --- a/builtin-unpack-objects.c +++ b/builtin-unpack-objects.c @@ -13,7 +13,7 @@ #include "fsck.h" static int dry_run, quiet, recover, has_errors, strict; -static const char unpack_usage[] = "git-unpack-objects [-n] [-q] [-r] [--strict] < pack-file"; +static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict] < pack-file"; /* We always read in 4kB chunks. */ static unsigned char buffer[4096]; diff --git a/builtin-update-index.c b/builtin-update-index.c index 434cb8e4a0..417f9724ab 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -14,7 +14,7 @@ * Default to not allowing changes to the list of files. The * tool doesn't actually care, but this makes it harder to add * files to the revision control by mistake by doing something - * like "git-update-index *" and suddenly having all the object + * like "git update-index *" and suddenly having all the object * files be revision controlled. */ static int allow_add; @@ -265,7 +265,7 @@ static void chmod_path(int flip, const char *path) report("chmod %cx '%s'", flip, path); return; fail: - die("git-update-index: cannot chmod %cx '%s'", flip, path); + die("git update-index: cannot chmod %cx '%s'", flip, path); } static void update_one(const char *path, const char *prefix, int prefix_length) @@ -283,7 +283,7 @@ static void update_one(const char *path, const char *prefix, int prefix_length) if (force_remove) { if (remove_file_from_cache(p)) - die("git-update-index: unable to remove %s", path); + die("git update-index: unable to remove %s", path); report("remove '%s'", path); goto free_return; } @@ -313,18 +313,18 @@ static void read_index_info(int line_termination) /* This reads lines formatted in one of three formats: * * (1) mode SP sha1 TAB path - * The first format is what "git-apply --index-info" + * The first format is what "git apply --index-info" * reports, and used to reconstruct a partial tree * that is used for phony merge base tree when falling * back on 3-way merge. * * (2) mode SP type SP sha1 TAB path - * The second format is to stuff git-ls-tree output + * The second format is to stuff "git ls-tree" output * into the index file. * * (3) mode SP sha1 SP stage TAB path * This format is to put higher order stages into the - * index file and matches git-ls-files --stage output. + * index file and matches "git ls-files --stage" output. */ errno = 0; ul = strtoul(buf.buf, &ptr, 8); @@ -354,7 +354,7 @@ static void read_index_info(int line_termination) if (line_termination && path_name[0] == '"') { strbuf_reset(&uq); if (unquote_c_style(&uq, path_name, NULL)) { - die("git-update-index: bad quoting of path name"); + die("git update-index: bad quoting of path name"); } path_name = uq.buf; } @@ -367,7 +367,7 @@ static void read_index_info(int line_termination) if (!mode) { /* mode == 0 means there is no such path -- remove */ if (remove_file_from_cache(path_name)) - die("git-update-index: unable to remove %s", + die("git update-index: unable to remove %s", ptr); } else { @@ -377,7 +377,7 @@ static void read_index_info(int line_termination) */ ptr[-42] = ptr[-1] = 0; if (add_cacheinfo(mode, sha1, path_name, stage)) - die("git-update-index: unable to update %s", + die("git update-index: unable to update %s", path_name); } continue; @@ -617,10 +617,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) continue; } if (!strcmp(path, "--refresh")) { + setup_work_tree(); has_errors |= refresh_cache(refresh_flags); continue; } if (!strcmp(path, "--really-refresh")) { + setup_work_tree(); has_errors |= refresh_cache(REFRESH_REALLY | refresh_flags); continue; } @@ -629,12 +631,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) unsigned int mode; if (i+3 >= argc) - die("git-update-index: --cacheinfo <mode> <sha1> <path>"); + die("git update-index: --cacheinfo <mode> <sha1> <path>"); if (strtoul_ui(argv[i+1], 8, &mode) || get_sha1_hex(argv[i+2], sha1) || add_cacheinfo(mode, sha1, argv[i+3], 0)) - die("git-update-index: --cacheinfo" + die("git update-index: --cacheinfo" " cannot add %s", argv[i+3]); i += 3; continue; @@ -642,7 +644,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) if (!strcmp(path, "--chmod=-x") || !strcmp(path, "--chmod=+x")) { if (argc <= i+1) - die("git-update-index: %s <path>", path); + die("git update-index: %s <path>", path); set_executable_bit = path[8]; continue; } @@ -687,6 +689,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) goto finish; } if (!strcmp(path, "--again") || !strcmp(path, "-g")) { + setup_work_tree(); has_errors = do_reupdate(argc - i, argv + i, prefix, prefix_length); if (has_errors) @@ -705,6 +708,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) usage(update_index_usage); die("unknown option %s", path); } + setup_work_tree(); p = prefix_path(prefix, prefix_length, path); update_one(p, NULL, 0); if (set_executable_bit) @@ -717,6 +721,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) strbuf_init(&buf, 0); strbuf_init(&nbuf, 0); + setup_work_tree(); while (strbuf_getline(&buf, stdin, line_termination) != EOF) { const char *p; if (line_termination && buf.buf[0] == '"') { @@ -11,13 +11,14 @@ extern const char git_usage_string[]; extern const char git_more_info_string[]; extern void list_common_cmds_help(void); -extern void help_unknown_cmd(const char *cmd); +extern const char *help_unknown_cmd(const char *cmd); extern void prune_packed_objects(int); extern int read_line_with_nul(char *buf, int size, FILE *file); extern int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out); extern int commit_tree(const char *msg, unsigned char *tree, - struct commit_list *parents, unsigned char *ret); + struct commit_list *parents, unsigned char *ret, + const char *author); extern int check_pager_config(const char *cmd); extern int cmd_add(int argc, const char **argv, const char *prefix); @@ -78,6 +79,7 @@ extern int cmd_prune(int argc, const char **argv, const char *prefix); extern int cmd_prune_packed(int argc, const char **argv, const char *prefix); extern int cmd_push(int argc, const char **argv, const char *prefix); extern int cmd_read_tree(int argc, const char **argv, const char *prefix); +extern int cmd_receive_pack(int argc, const char **argv, const char *prefix); extern int cmd_reflog(int argc, const char **argv, const char *prefix); extern int cmd_remote(int argc, const char **argv, const char *prefix); extern int cmd_config(int argc, const char **argv, const char *prefix); @@ -533,6 +533,7 @@ static inline int is_absolute_path(const char *path) { return path[0] == '/' || has_dos_drive_prefix(path); } +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); @@ -640,6 +641,8 @@ extern struct alternate_object_database { } *alt_odb_list; extern void prepare_alt_odb(void); extern void add_to_alternates_file(const char *reference); +typedef int alt_odb_fn(struct alternate_object_database *, void *); +extern void foreach_alt_odb(alt_odb_fn, void*); struct pack_window { struct pack_window *next; @@ -708,7 +711,11 @@ extern struct child_process *git_connect(int fd[2], const char *url, const char extern int finish_connect(struct child_process *conn); extern int path_match(const char *path, int nr, char **match); extern int get_ack(int fd, unsigned char *result_sha1); -extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags); +struct extra_have_objects { + int nr, alloc; + unsigned char (*array)[20]; +}; +extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags, struct extra_have_objects *); extern int server_supports(const char *feature); extern struct packed_git *parse_pack_index(unsigned char *sha1); diff --git a/combine-diff.c b/combine-diff.c index 0cf2a830b5..de83c6972e 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -496,6 +496,18 @@ static int hunk_comment_line(const char *bol) return (isalpha(ch) || ch == '_' || ch == '$'); } +static void show_line_to_eol(const char *line, int len, const char *reset) +{ + int saw_cr_at_eol = 0; + if (len < 0) + len = strlen(line); + saw_cr_at_eol = (len && line[len-1] == '\r'); + + printf("%.*s%s%s\n", len - saw_cr_at_eol, line, + reset, + saw_cr_at_eol ? "\r" : ""); +} + static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent, int use_color) { @@ -589,7 +601,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent, else putchar(' '); } - printf("%s%s\n", ll->line, c_reset); + show_line_to_eol(ll->line, -1, c_reset); ll = ll->next; } if (cnt < lno) @@ -613,7 +625,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent, putchar(' '); p_mask <<= 1; } - printf("%.*s%s\n", sl->len, sl->bol, c_reset); + show_line_to_eol(sl->bol, sl->len, c_reset); } } } @@ -671,9 +683,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, int i, show_hunks; int working_tree_file = is_null_sha1(elem->sha1); int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV; + const char *a_prefix, *b_prefix; mmfile_t result_file; context = opt->context; + a_prefix = opt->a_prefix ? opt->a_prefix : "a/"; + b_prefix = opt->b_prefix ? opt->b_prefix : "b/"; + /* Read the result of merge first */ if (!working_tree_file) result = grab_blob(elem->sha1, &result_size); @@ -849,13 +865,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, dump_quoted_path("--- ", "", "/dev/null", c_meta, c_reset); else - dump_quoted_path("--- ", opt->a_prefix, elem->path, + dump_quoted_path("--- ", a_prefix, elem->path, c_meta, c_reset); if (deleted) dump_quoted_path("+++ ", "", "/dev/null", c_meta, c_reset); else - dump_quoted_path("+++ ", opt->b_prefix, elem->path, + dump_quoted_path("+++ ", b_prefix, elem->path, c_meta, c_reset); dump_sline(sline, cnt, num_parent, DIFF_OPT_TST(opt, COLOR_DIFF)); diff --git a/compat/fnmatch.c b/compat/fnmatch/fnmatch.c index 1f4ead5f98..1f4ead5f98 100644 --- a/compat/fnmatch.c +++ b/compat/fnmatch/fnmatch.c diff --git a/compat/fnmatch.h b/compat/fnmatch/fnmatch.h index cc3ec37940..cc3ec37940 100644 --- a/compat/fnmatch.h +++ b/compat/fnmatch/fnmatch.h diff --git a/compat/regex.c b/compat/regex/regex.c index 87b33e4669..87b33e4669 100644 --- a/compat/regex.c +++ b/compat/regex/regex.c diff --git a/compat/regex.h b/compat/regex/regex.h index 6eb64f1402..6eb64f1402 100644 --- a/compat/regex.h +++ b/compat/regex/regex.h diff --git a/config.mak.in b/config.mak.in index f67d673d01..17e9861c06 100644 --- a/config.mak.in +++ b/config.mak.in @@ -4,6 +4,7 @@ CC = @CC@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ +CC_LD_DYNPATH = @CC_LD_DYNPATH@ AR = @AR@ TAR = @TAR@ #INSTALL = @INSTALL@ # needs install-sh or install.sh in sources diff --git a/configure.ac b/configure.ac index 7c2856efc9..27bab00a45 100644 --- a/configure.ac +++ b/configure.ac @@ -103,6 +103,38 @@ GIT_PARSE_WITH(tcltk)) AC_MSG_NOTICE([CHECKS for programs]) # AC_PROG_CC([cc gcc]) +# which switch to pass runtime path to dynamic libraries to the linker +AC_CACHE_CHECK([if linker supports -R], ld_dashr, [ + SAVE_LDFLAGS="${LDFLAGS}" + LDFLAGS="${SAVE_LDFLAGS} -R /" + AC_LINK_IFELSE(AC_LANG_PROGRAM([], []), [ld_dashr=yes], [ld_dashr=no]) + LDFLAGS="${SAVE_LDFLAGS}" +]) +if test "$ld_dashr" = "yes"; then + AC_SUBST(CC_LD_DYNPATH, [-R]) +else + AC_CACHE_CHECK([if linker supports -Wl,-rpath,], ld_wl_rpath, [ + 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}" + ]) + if test "$ld_wl_rpath" = "yes"; then + AC_SUBST(CC_LD_DYNPATH, [-Wl,-rpath,]) + else + AC_CACHE_CHECK([if linker supports -rpath], ld_rpath, [ + SAVE_LDFLAGS="${LDFLAGS}" + LDFLAGS="${SAVE_LDFLAGS} -rpath /" + AC_LINK_IFELSE(AC_LANG_PROGRAM([], []), [ld_rpath=yes], [ld_rpath=no]) + LDFLAGS="${SAVE_LD_FLAGS}" + ]) + if test "$ld_rpath" = "yes"; then + AC_SUBST(CC_LD_DYNPATH, [-rpath]) + else + AC_MSG_WARN([linker does not support runtime path to dynamic libraries]) + fi + fi +fi #AC_PROG_INSTALL # needs install-sh or install.sh in sources AC_CHECK_TOOLS(AR, [gar ar], :) AC_CHECK_PROGS(TAR, [gtar tar]) @@ -41,12 +41,20 @@ int check_ref_type(const struct ref *ref, int flags) return check_ref(ref->name, strlen(ref->name), flags); } +static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1) +{ + ALLOC_GROW(extra->array, extra->nr + 1, extra->alloc); + hashcpy(&(extra->array[extra->nr][0]), sha1); + extra->nr++; +} + /* * Read all the refs from the other end */ struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, - unsigned int flags) + unsigned int flags, + struct extra_have_objects *extra_have) { *list = NULL; for (;;) { @@ -72,6 +80,12 @@ struct ref **get_remote_heads(int in, struct ref **list, server_capabilities = xstrdup(name + name_len + 1); } + if (extra_have && + name_len == 5 && !memcmp(".have", name, 5)) { + add_extra_have(extra_have, old_sha1); + continue; + } + if (!check_ref(name, name_len, flags)) continue; if (nr_match && !path_match(name, nr_match, match)) @@ -97,7 +111,7 @@ int get_ack(int fd, unsigned char *result_sha1) int len = packet_read_line(fd, line, sizeof(line)); if (!len) - die("git-fetch-pack: expected ACK/NAK, got EOF"); + die("git fetch-pack: expected ACK/NAK, got EOF"); if (line[len-1] == '\n') line[--len] = 0; if (!strcmp(line, "NAK")) @@ -109,7 +123,7 @@ int get_ack(int fd, unsigned char *result_sha1) return 1; } } - die("git-fetch_pack: expected ACK/NAK, got '%s'", line); + die("git fetch_pack: expected ACK/NAK, got '%s'", line); } int path_match(const char *path, int nr, char **match) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 4f64f8ab7d..93f088189e 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -154,11 +154,8 @@ __git_heads () { local cmd i is_hash=y dir="$(__gitdir "$1")" if [ -d "$dir" ]; then - for i in $(git --git-dir="$dir" \ - for-each-ref --format='%(refname)' \ - refs/heads ); do - echo "${i#refs/heads/}" - done + git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ + refs/heads return fi for i in $(git ls-remote "$1" 2>/dev/null); do @@ -175,11 +172,8 @@ __git_tags () { local cmd i is_hash=y dir="$(__gitdir "$1")" if [ -d "$dir" ]; then - for i in $(git --git-dir="$dir" \ - for-each-ref --format='%(refname)' \ - refs/tags ); do - echo "${i#refs/tags/}" - done + git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ + refs/tags return fi for i in $(git ls-remote "$1" 2>/dev/null); do @@ -197,16 +191,8 @@ __git_refs () local cmd i is_hash=y dir="$(__gitdir "$1")" if [ -d "$dir" ]; then if [ -e "$dir/HEAD" ]; then echo HEAD; fi - for i in $(git --git-dir="$dir" \ - for-each-ref --format='%(refname)' \ - refs/tags refs/heads refs/remotes); do - case "$i" in - refs/tags/*) echo "${i#refs/tags/}" ;; - refs/heads/*) echo "${i#refs/heads/}" ;; - refs/remotes/*) echo "${i#refs/remotes/}" ;; - *) echo "$i" ;; - esac - done + git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ + refs/tags refs/heads refs/remotes return fi for i in $(git ls-remote "$dir" 2>/dev/null); do @@ -386,7 +372,9 @@ __git_porcelain_commands () cat-file) : plumbing;; check-attr) : plumbing;; check-ref-format) : plumbing;; + checkout-index) : plumbing;; commit-tree) : plumbing;; + count-objects) : infrequent;; cvsexportcommit) : export;; cvsimport) : import;; cvsserver) : daemon;; @@ -395,6 +383,7 @@ __git_porcelain_commands () diff-index) : plumbing;; diff-tree) : plumbing;; fast-import) : import;; + fast-export) : export;; fsck-objects) : plumbing;; fetch-pack) : plumbing;; fmt-merge-msg) : plumbing;; @@ -404,6 +393,10 @@ __git_porcelain_commands () index-pack) : plumbing;; init-db) : deprecated;; local-fetch) : plumbing;; + lost-found) : infrequent;; + ls-files) : plumbing;; + ls-remote) : plumbing;; + ls-tree) : plumbing;; mailinfo) : plumbing;; mailsplit) : plumbing;; merge-*) : plumbing;; @@ -428,6 +421,7 @@ __git_porcelain_commands () runstatus) : plumbing;; sh-setup) : internal;; shell) : daemon;; + show-ref) : plumbing;; send-pack) : plumbing;; show-index) : plumbing;; ssh-*) : transport;; @@ -442,6 +436,8 @@ __git_porcelain_commands () upload-archive) : plumbing;; upload-pack) : plumbing;; write-tree) : plumbing;; + var) : infrequent;; + verify-pack) : infrequent;; verify-tag) : plumbing;; *) echo $i;; esac @@ -740,7 +736,7 @@ _git_commit () --*) __gitcomp " --all --author= --signoff --verify --no-verify - --edit --amend --include --only + --edit --amend --include --only --interactive " return esac diff --git a/contrib/hooks/setgitperms.perl b/contrib/hooks/setgitperms.perl index dab7c8e3a1..a577ad095f 100644 --- a/contrib/hooks/setgitperms.perl +++ b/contrib/hooks/setgitperms.perl @@ -50,7 +50,7 @@ if ((@ARGV < 0) || !GetOptions( )) { die $usage; } die $usage unless ($read_mode xor $write_mode); -my $topdir = `git-rev-parse --show-cdup` or die "\n"; chomp $topdir; +my $topdir = `git rev-parse --show-cdup` or die "\n"; chomp $topdir; my $gitdir = $topdir . '.git'; my $gitmeta = $topdir . '.gitmeta'; @@ -155,7 +155,7 @@ elsif ($read_mode) { open (OUT, ">$gitmeta.tmp") or die "Could not open $gitmeta.tmp for writing: $!\n"; } - my @files = `git-ls-files`; + my @files = `git ls-files`; my %dirs; foreach my $path (@files) { diff --git a/csum-file.c b/csum-file.c index ace64f165e..bb70c75ee1 100644 --- a/csum-file.c +++ b/csum-file.c @@ -11,10 +11,8 @@ #include "progress.h" #include "csum-file.h" -static void sha1flush(struct sha1file *f, unsigned int count) +static void sha1flush(struct sha1file *f, void *buf, unsigned int count) { - void *buf = f->buffer; - for (;;) { int ret = xwrite(f->fd, buf, count); if (ret > 0) { @@ -39,15 +37,15 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags) if (offset) { SHA1_Update(&f->ctx, f->buffer, offset); - sha1flush(f, offset); + sha1flush(f, f->buffer, offset); f->offset = 0; } + SHA1_Final(f->buffer, &f->ctx); + if (result) + hashcpy(result, f->buffer); if (flags & (CSUM_CLOSE | CSUM_FSYNC)) { /* write checksum and close fd */ - SHA1_Final(f->buffer, &f->ctx); - if (result) - hashcpy(result, f->buffer); - sha1flush(f, 20); + sha1flush(f, f->buffer, 20); if (flags & CSUM_FSYNC) fsync_or_die(f->fd, f->name); if (close(f->fd)) @@ -62,21 +60,30 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags) int sha1write(struct sha1file *f, void *buf, unsigned int count) { - if (f->do_crc) - f->crc32 = crc32(f->crc32, buf, count); while (count) { unsigned offset = f->offset; unsigned left = sizeof(f->buffer) - offset; unsigned nr = count > left ? left : count; + void *data; + + if (f->do_crc) + f->crc32 = crc32(f->crc32, buf, nr); + + if (nr == sizeof(f->buffer)) { + /* process full buffer directly without copy */ + data = buf; + } else { + memcpy(f->buffer + offset, buf, nr); + data = f->buffer; + } - memcpy(f->buffer + offset, buf, nr); count -= nr; offset += nr; buf = (char *) buf + nr; left -= nr; if (!left) { - SHA1_Update(&f->ctx, f->buffer, offset); - sha1flush(f, offset); + SHA1_Update(&f->ctx, data, offset); + sha1flush(f, data, offset); offset = 0; } f->offset = offset; @@ -86,7 +86,7 @@ static void logreport(int priority, const char *err, va_list params) * Since stderr is set to linebuffered mode, the * logging of different processes will not overlap */ - fprintf(stderr, "[%d] ", (int)getpid()); + fprintf(stderr, "[%"PRIuMAX"] ", (uintmax_t)getpid()); vfprintf(stderr, err, params); fputc('\n', stderr); } @@ -658,7 +658,7 @@ static void check_dead_children(void) remove_child(pid); if (!WIFEXITED(status) || (WEXITSTATUS(status) > 0)) dead = " (with error)"; - loginfo("[%d] Disconnected%s", (int)pid, dead); + loginfo("[%"PRIuMAX"] Disconnected%s", (uintmax_t)pid, dead); } } @@ -923,7 +923,7 @@ static void store_pid(const char *path) FILE *f = fopen(path, "w"); if (!f) die("cannot open pid file %s: %s", path, strerror(errno)); - if (fprintf(f, "%d\n", getpid()) < 0 || fclose(f) != 0) + if (fprintf(f, "%"PRIuMAX"\n", (uintmax_t) getpid()) < 0 || fclose(f) != 0) die("failed to write pid file %s: %s", path, strerror(errno)); } @@ -1083,7 +1083,8 @@ int main(int argc, char **argv) openlog("git-daemon", LOG_PID, LOG_DAEMON); set_die_routine(daemon_die); } else - setlinebuf(stderr); /* avoid splitting a message in the middle */ + /* avoid splitting a message in the middle */ + setvbuf(stderr, NULL, _IOLBF, 0); if (inetd_mode && (group_name || user_name)) die("--user and --group are incompatible with --inetd"); @@ -1115,13 +1116,9 @@ int main(int argc, char **argv) if (strict_paths && (!ok_paths || !*ok_paths)) die("option --strict-paths requires a whitelist"); - if (base_path) { - struct stat st; - - if (stat(base_path, &st) || !S_ISDIR(st.st_mode)) - die("base-path '%s' does not exist or " - "is not a directory", base_path); - } + if (base_path && !is_directory(base_path)) + die("base-path '%s' does not exist or is not a directory", + base_path); if (inetd_mode) { struct sockaddr_storage ss; diff --git a/diff-lib.c b/diff-lib.c index e7eaff9a68..ae96c64ca2 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -63,6 +63,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option) ? CE_MATCH_RACY_IS_DIRTY : 0); char symcache[PATH_MAX]; + diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/"); + if (diff_unmerged_stage < 0) diff_unmerged_stage = 2; entries = active_nr; @@ -469,6 +471,7 @@ int run_diff_index(struct rev_info *revs, int cached) if (unpack_trees(1, &t, &opts)) exit(128); + diff_set_mnemonic_prefix(&revs->diffopt, "c/", cached ? "i/" : "w/"); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); return 0; diff --git a/diff-no-index.c b/diff-no-index.c index 7d68b7f1be..b60d3455da 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -252,6 +252,7 @@ void diff_no_index(struct rev_info *revs, if (queue_diff(&revs->diffopt, revs->diffopt.paths[0], revs->diffopt.paths[1])) exit(1); + diff_set_mnemonic_prefix(&revs->diffopt, "1/", "2/"); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); @@ -24,6 +24,7 @@ static int diff_suppress_blank_empty; int diff_use_color_default = -1; static const char *external_diff_cmd_cfg; int diff_auto_refresh_index = 1; +static int diff_mnemonic_prefix; static char diff_colors[][COLOR_MAXLEN] = { "\033[m", /* reset */ @@ -150,6 +151,10 @@ int git_diff_ui_config(const char *var, const char *value, void *cb) diff_auto_refresh_index = git_config_bool(var, value); return 0; } + if (!strcmp(var, "diff.mnemonicprefix")) { + diff_mnemonic_prefix = git_config_bool(var, value); + return 0; + } if (!strcmp(var, "diff.external")) return git_config_string(&external_diff_cmd_cfg, var, value); if (!prefixcmp(var, "diff.")) { @@ -312,6 +317,15 @@ static void emit_rewrite_diff(const char *name_a, const char *new = diff_get_color(color_diff, DIFF_FILE_NEW); const char *reset = diff_get_color(color_diff, DIFF_RESET); static struct strbuf a_name = STRBUF_INIT, b_name = STRBUF_INIT; + const char *a_prefix, *b_prefix; + + if (diff_mnemonic_prefix && DIFF_OPT_TST(o, REVERSE_DIFF)) { + a_prefix = o->b_prefix; + b_prefix = o->a_prefix; + } else { + a_prefix = o->a_prefix; + b_prefix = o->b_prefix; + } name_a += (*name_a == '/'); name_b += (*name_b == '/'); @@ -320,8 +334,8 @@ static void emit_rewrite_diff(const char *name_a, strbuf_reset(&a_name); strbuf_reset(&b_name); - quote_two_c_style(&a_name, o->a_prefix, name_a, 0); - quote_two_c_style(&b_name, o->b_prefix, name_b, 0); + quote_two_c_style(&a_name, a_prefix, name_a, 0); + quote_two_c_style(&b_name, b_prefix, name_b, 0); diff_populate_filespec(one, 0); diff_populate_filespec(two, 0); @@ -513,13 +527,20 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix) static void emit_line(FILE *file, const char *set, const char *reset, const char *line, int len) { - int has_trailing_newline = (len > 0 && line[len-1] == '\n'); + int has_trailing_newline, has_trailing_carriage_return; + + has_trailing_newline = (len > 0 && line[len-1] == '\n'); if (has_trailing_newline) len--; + has_trailing_carriage_return = (len > 0 && line[len-1] == '\r'); + if (has_trailing_carriage_return) + len--; fputs(set, file); fwrite(line, len, 1, file); fputs(reset, file); + if (has_trailing_carriage_return) + fputc('\r', file); if (has_trailing_newline) fputc('\n', file); } @@ -1078,7 +1099,7 @@ static void show_dirstat(struct diff_options *options) dir.alloc = 0; dir.nr = 0; dir.percent = options->dirstat_percent; - dir.cumulative = options->output_format & DIFF_FORMAT_CUMULATIVE; + dir.cumulative = DIFF_OPT_TST(options, DIRSTAT_CUMULATIVE); changed = 0; for (i = 0; i < q->nr; i++) { @@ -1110,9 +1131,13 @@ static void show_dirstat(struct diff_options *options) /* * Original minus copied is the removed material, * added is the new material. They are both damages - * made to the preimage. + * made to the preimage. In --dirstat-by-file mode, count + * damaged files, not damaged lines. This is done by + * counting only a single damaged line per file. */ damage = (p->one->size - copied) + added; + if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE) && damage > 0) + damage = 1; ALLOC_GROW(dir.files, dir.nr + 1, dir.alloc); dir.files[dir.nr].name = name; @@ -1402,6 +1427,7 @@ static struct builtin_funcname_pattern { "\\|" "^\\(.*=[ \t]*\\(class\\|record\\).*\\)$" }, + { "php", "^[\t ]*\\(\\(function\\|class\\).*\\)" }, { "python", "^\\s*\\(\\(class\\|def\\)\\s.*\\)$" }, { "ruby", "^\\s*\\(\\(class\\|module\\|def\\)\\s.*\\)$" }, { "tex", "^\\(\\\\\\(\\(sub\\)*section\\|chapter\\|part\\)\\*\\{0,1\\}{.*\\)$" }, @@ -1439,6 +1465,14 @@ static const char *diff_funcname_pattern(struct diff_filespec *one) return NULL; } +void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b) +{ + if (!options->a_prefix) + options->a_prefix = a; + if (!options->b_prefix) + options->b_prefix = b; +} + static void builtin_diff(const char *name_a, const char *name_b, struct diff_filespec *one, @@ -1452,9 +1486,19 @@ static void builtin_diff(const char *name_a, char *a_one, *b_two; const char *set = diff_get_color_opt(o, DIFF_METAINFO); const char *reset = diff_get_color_opt(o, DIFF_RESET); + const char *a_prefix, *b_prefix; + + diff_set_mnemonic_prefix(o, "a/", "b/"); + if (DIFF_OPT_TST(o, REVERSE_DIFF)) { + a_prefix = o->b_prefix; + b_prefix = o->a_prefix; + } else { + a_prefix = o->a_prefix; + b_prefix = o->b_prefix; + } - a_one = quote_two(o->a_prefix, name_a + (*name_a == '/')); - b_two = quote_two(o->b_prefix, name_b + (*name_b == '/')); + a_one = quote_two(a_prefix, name_a + (*name_a == '/')); + b_two = quote_two(b_prefix, name_b + (*name_b == '/')); lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null"; lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null"; fprintf(o->file, "%sdiff --git %s %s%s\n", set, a_one, b_two, reset); @@ -2300,6 +2344,7 @@ void diff_setup(struct diff_options *options) options->break_opt = -1; options->rename_limit = -1; options->dirstat_percent = 3; + DIFF_OPT_CLR(options, DIRSTAT_CUMULATIVE); options->context = 3; options->change = diff_change; @@ -2310,8 +2355,10 @@ void diff_setup(struct diff_options *options) DIFF_OPT_CLR(options, COLOR_DIFF); options->detect_rename = diff_detect_rename_default; - options->a_prefix = "a/"; - options->b_prefix = "b/"; + if (!diff_mnemonic_prefix) { + options->a_prefix = "a/"; + options->b_prefix = "b/"; + } } int diff_setup_done(struct diff_options *options) @@ -2394,13 +2441,6 @@ int diff_setup_done(struct diff_options *options) DIFF_OPT_SET(options, EXIT_WITH_STATUS); } - /* - * If we postprocess in diffcore, we cannot simply return - * upon the first hit. We need to run diff as usual. - */ - if (options->pickaxe || options->filter) - DIFF_OPT_CLR(options, QUIET); - return 0; } @@ -2472,8 +2512,14 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) options->output_format |= DIFF_FORMAT_SHORTSTAT; else if (opt_arg(arg, 'X', "dirstat", &options->dirstat_percent)) options->output_format |= DIFF_FORMAT_DIRSTAT; - else if (!strcmp(arg, "--cumulative")) - options->output_format |= DIFF_FORMAT_CUMULATIVE; + else if (!strcmp(arg, "--cumulative")) { + options->output_format |= DIFF_FORMAT_DIRSTAT; + DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE); + } else if (opt_arg(arg, 0, "dirstat-by-file", + &options->dirstat_percent)) { + options->output_format |= DIFF_FORMAT_DIRSTAT; + DIFF_OPT_SET(options, DIRSTAT_BY_FILE); + } else if (!strcmp(arg, "--check")) options->output_format |= DIFF_FORMAT_CHECKDIFF; else if (!strcmp(arg, "--summary")) @@ -3386,10 +3432,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) void diffcore_std(struct diff_options *options) { - if (DIFF_OPT_TST(options, QUIET)) - return; - - if (options->skip_stat_unmatch && !DIFF_OPT_TST(options, FIND_COPIES_HARDER)) + if (options->skip_stat_unmatch) diffcore_skip_stat_unmatch(options); if (options->break_opt != -1) diffcore_break(options->break_opt); @@ -31,7 +31,6 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q, #define DIFF_FORMAT_PATCH 0x0010 #define DIFF_FORMAT_SHORTSTAT 0x0020 #define DIFF_FORMAT_DIRSTAT 0x0040 -#define DIFF_FORMAT_CUMULATIVE 0x0080 /* These override all above */ #define DIFF_FORMAT_NAME 0x0100 @@ -64,6 +63,8 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q, #define DIFF_OPT_CHECK_FAILED (1 << 16) #define DIFF_OPT_RELATIVE_NAME (1 << 17) #define DIFF_OPT_IGNORE_SUBMODULES (1 << 18) +#define DIFF_OPT_DIRSTAT_CUMULATIVE (1 << 19) +#define DIFF_OPT_DIRSTAT_BY_FILE (1 << 20) #define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag) #define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag) #define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag) @@ -160,6 +161,8 @@ extern void diff_tree_combined(const unsigned char *sha1, const unsigned char pa extern void diff_tree_combined_merge(const unsigned char *sha1, int, struct rev_info *); +void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b); + extern void diff_addremove(struct diff_options *, int addremove, unsigned mode, diff --git a/diffcore.h b/diffcore.h index cc96c20734..8ae35785fd 100644 --- a/diffcore.h +++ b/diffcore.h @@ -92,7 +92,6 @@ extern struct diff_filepair *diff_queue(struct diff_queue_struct *, struct diff_filespec *); extern void diff_q(struct diff_queue_struct *, struct diff_filepair *); -extern void diffcore_pathspec(const char **pathspec); extern void diffcore_break(int); extern void diffcore_rename(struct diff_options *); extern void diffcore_merge_broken(void); @@ -111,7 +111,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout case S_IFREG: new = read_blob_entry(ce, path, &size); if (!new) - return error("git-checkout-index: unable to read sha1 file of %s (%s)", + return error("git checkout-index: unable to read sha1 file of %s (%s)", path, sha1_to_hex(ce->sha1)); /* @@ -132,7 +132,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout fd = create_file(path, ce->ce_mode); if (fd < 0) { free(new); - return error("git-checkout-index: unable to create file %s (%s)", + return error("git checkout-index: unable to create file %s (%s)", path, strerror(errno)); } @@ -140,12 +140,12 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout close(fd); free(new); if (wrote != size) - return error("git-checkout-index: unable to write file %s", path); + return error("git checkout-index: unable to write file %s", path); break; case S_IFLNK: new = read_blob_entry(ce, path, &size); if (!new) - return error("git-checkout-index: unable to read sha1 file of %s (%s)", + return error("git checkout-index: unable to read sha1 file of %s (%s)", path, sha1_to_hex(ce->sha1)); if (to_tempfile || !has_symlinks) { if (to_tempfile) { @@ -155,31 +155,31 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout fd = create_file(path, 0666); if (fd < 0) { free(new); - return error("git-checkout-index: unable to create " + return error("git checkout-index: unable to create " "file %s (%s)", path, strerror(errno)); } wrote = write_in_full(fd, new, size); close(fd); free(new); if (wrote != size) - return error("git-checkout-index: unable to write file %s", + return error("git checkout-index: unable to write file %s", path); } else { wrote = symlink(new, path); free(new); if (wrote) - return error("git-checkout-index: unable to create " + return error("git checkout-index: unable to create " "symlink %s (%s)", path, strerror(errno)); } break; case S_IFGITLINK: if (to_tempfile) - return error("git-checkout-index: cannot create temporary subproject %s", path); + return error("git checkout-index: cannot create temporary subproject %s", path); if (mkdir(path, 0777) < 0) - return error("git-checkout-index: cannot create subproject directory %s", path); + return error("git checkout-index: cannot create subproject directory %s", path); break; default: - return error("git-checkout-index: unknown file mode for %s", path); + return error("git checkout-index: unknown file mode for %s", path); } if (state->refresh_cache) { diff --git a/fast-import.c b/fast-import.c index 7089e6f9e6..ab6689a64d 100644 --- a/fast-import.c +++ b/fast-import.c @@ -376,7 +376,7 @@ static void dump_marks_helper(FILE *, uintmax_t, struct mark_set *); static void write_crash_report(const char *err) { - char *loc = git_path("fast_import_crash_%d", getpid()); + char *loc = git_path("fast_import_crash_%"PRIuMAX, (uintmax_t) getpid()); FILE *rpt = fopen(loc, "w"); struct branch *b; unsigned long lu; @@ -390,8 +390,8 @@ static void write_crash_report(const char *err) fprintf(stderr, "fast-import: dumping crash report to %s\n", loc); fprintf(rpt, "fast-import crash report:\n"); - fprintf(rpt, " fast-import process: %d\n", getpid()); - fprintf(rpt, " parent process : %d\n", getppid()); + fprintf(rpt, " fast-import process: %"PRIuMAX"\n", (uintmax_t) getpid()); + fprintf(rpt, " parent process : %"PRIuMAX"\n", (uintmax_t) getppid()); fprintf(rpt, " at %s\n", show_date(time(NULL), 0, DATE_LOCAL)); fputc('\n', rpt); @@ -816,7 +816,7 @@ static void start_packfile(void) int pack_fd; snprintf(tmpfile, sizeof(tmpfile), - "%s/tmp_pack_XXXXXX", get_object_directory()); + "%s/pack/tmp_pack_XXXXXX", get_object_directory()); pack_fd = xmkstemp(tmpfile); p = xcalloc(1, sizeof(*p) + strlen(tmpfile) + 2); strcpy(p->pack_name, tmpfile); @@ -878,7 +878,7 @@ static char *create_index(void) } snprintf(tmpfile, sizeof(tmpfile), - "%s/tmp_idx_XXXXXX", get_object_directory()); + "%s/pack/tmp_idx_XXXXXX", get_object_directory()); idx_fd = xmkstemp(tmpfile); f = sha1fd(idx_fd, tmpfile); sha1write(f, array, 256 * sizeof(int)); @@ -951,7 +951,8 @@ static void end_packfile(void) close_pack_windows(pack_data); fixup_pack_header_footer(pack_data->pack_fd, pack_data->sha1, - pack_data->pack_name, object_count); + pack_data->pack_name, object_count, + NULL, 0); close(pack_data->pack_fd); idx_name = keep_pack(create_index()); diff --git a/git-bisect.sh b/git-bisect.sh index 97ac600873..79de7017e8 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -172,6 +172,25 @@ bisect_write() { test -n "$nolog" || echo "git bisect $state $rev" >>"$GIT_DIR/BISECT_LOG" } +is_expected_rev() { + test -f "$GIT_DIR/BISECT_EXPECTED_REV" && + test "$1" = $(cat "$GIT_DIR/BISECT_EXPECTED_REV") +} + +mark_expected_rev() { + echo "$1" > "$GIT_DIR/BISECT_EXPECTED_REV" +} + +check_expected_revs() { + for _rev in "$@"; do + if ! is_expected_rev "$_rev"; then + rm -f "$GIT_DIR/BISECT_ANCESTORS_OK" + rm -f "$GIT_DIR/BISECT_EXPECTED_REV" + return + fi + done +} + bisect_state() { bisect_autostart state=$1 @@ -181,7 +200,8 @@ bisect_state() { 1,bad|1,good|1,skip) rev=$(git rev-parse --verify HEAD) || die "Bad rev input: HEAD" - bisect_write "$state" "$rev" ;; + bisect_write "$state" "$rev" + check_expected_revs "$rev" ;; 2,bad|*,good|*,skip) shift eval='' @@ -191,7 +211,8 @@ bisect_state() { die "Bad rev input: $rev" eval="$eval bisect_write '$state' '$sha'; " done - eval "$eval" ;; + eval "$eval" + check_expected_revs "$@" ;; *,bad) die "'git bisect bad' can take only one argument." ;; *) @@ -243,33 +264,18 @@ bisect_auto_next() { bisect_next_check && bisect_next || : } -eval_rev_list() { - _eval="$1" - - eval $_eval - res=$? - - if [ $res -ne 0 ]; then - echo >&2 "'git rev-list --bisect-vars' failed:" - echo >&2 "maybe you mistake good and bad revs?" - exit $res - fi - - return $res -} - filter_skipped() { _eval="$1" _skip="$2" if [ -z "$_skip" ]; then - eval_rev_list "$_eval" + eval "$_eval" return fi # Let's parse the output of: # "git rev-list --bisect-vars --bisect-all ..." - eval_rev_list "$_eval" | while read hash line + eval "$_eval" | while read hash line do case "$VARS,$FOUND,$TRIED,$hash" in # We display some vars. @@ -332,20 +338,133 @@ exit_if_skipped_commits () { fi } +bisect_checkout() { + _rev="$1" + _msg="$2" + echo "Bisecting: $_msg" + mark_expected_rev "$_rev" + git checkout -q "$_rev" || exit + git show-branch "$_rev" +} + +is_among() { + _rev="$1" + _list="$2" + case "$_list" in *$_rev*) return 0 ;; esac + return 1 +} + +handle_bad_merge_base() { + _badmb="$1" + _good="$2" + if is_expected_rev "$_badmb"; then + cat >&2 <<EOF +The merge base $_badmb is bad. +This means the bug has been fixed between $_badmb and [$_good]. +EOF + exit 3 + else + cat >&2 <<EOF +Some good revs are not ancestor of the bad rev. +git bisect cannot work properly in this case. +Maybe you mistake good and bad revs? +EOF + exit 1 + fi +} + +handle_skipped_merge_base() { + _mb="$1" + _bad="$2" + _good="$3" + cat >&2 <<EOF +Warning: the merge base between $_bad and [$_good] must be skipped. +So we cannot be sure the first bad commit is between $_mb and $_bad. +We continue anyway. +EOF +} + +# +# "check_merge_bases" checks that merge bases are not "bad". +# +# - If one is "good", that's good, we have nothing to do. +# - If one is "bad", it means the user assumed something wrong +# and we must exit. +# - If one is "skipped", we can't know but we should warn. +# - If we don't know, we should check it out and ask the user to test. +# +# In the last case we will return 1, and otherwise 0. +# +check_merge_bases() { + _bad="$1" + _good="$2" + _skip="$3" + for _mb in $(git merge-base --all $_bad $_good) + do + if is_among "$_mb" "$_good"; then + continue + elif test "$_mb" = "$_bad"; then + handle_bad_merge_base "$_bad" "$_good" + elif is_among "$_mb" "$_skip"; then + handle_skipped_merge_base "$_mb" "$_bad" "$_good" + else + bisect_checkout "$_mb" "a merge base must be tested" + return 1 + fi + done + return 0 +} + +# +# "check_good_are_ancestors_of_bad" checks that all "good" revs are +# ancestor of the "bad" rev. +# +# If that's not the case, we need to check the merge bases. +# If a merge base must be tested by the user we return 1 and +# otherwise 0. +# +check_good_are_ancestors_of_bad() { + test -f "$GIT_DIR/BISECT_ANCESTORS_OK" && + return + + _bad="$1" + _good=$(echo $2 | sed -e 's/\^//g') + _skip="$3" + + # Bisecting with no good rev is ok + test -z "$_good" && return + + _side=$(git rev-list $_good ^$_bad) + if test -n "$_side"; then + # Return if a checkout was done + check_merge_bases "$_bad" "$_good" "$_skip" || return + fi + + : > "$GIT_DIR/BISECT_ANCESTORS_OK" + + return 0 +} + bisect_next() { case "$#" in 0) ;; *) usage ;; esac bisect_autostart bisect_next_check good + # Get bad, good and skipped revs + bad=$(git rev-parse --verify refs/bisect/bad) && + good=$(git for-each-ref --format='^%(objectname)' \ + "refs/bisect/good-*" | tr '\012' ' ') && skip=$(git for-each-ref --format='%(objectname)' \ - "refs/bisect/skip-*" | tr '\012' ' ') || exit + "refs/bisect/skip-*" | tr '\012' ' ') && + + # Maybe some merge bases must be tested first + check_good_are_ancestors_of_bad "$bad" "$good" "$skip" + # Return now if a checkout has already been done + test "$?" -eq "1" && return + # Get bisection information BISECT_OPT='' test -n "$skip" && BISECT_OPT='--bisect-all' - - bad=$(git rev-parse --verify refs/bisect/bad) && - good=$(git for-each-ref --format='^%(objectname)' \ - "refs/bisect/good-*" | tr '\012' ' ') && eval="git rev-list --bisect-vars $BISECT_OPT $good $bad --" && eval="$eval $(cat "$GIT_DIR/BISECT_NAMES")" && eval=$(filter_skipped "$eval" "$skip") && @@ -366,9 +485,7 @@ bisect_next() { # commit is also a "skip" commit (see above). exit_if_skipped_commits "$bisect_rev" - echo "Bisecting: $bisect_nr revisions left to test after this" - git checkout -q "$bisect_rev" || exit - git show-branch "$bisect_rev" + bisect_checkout "$bisect_rev" "$bisect_nr revisions left to test after this" } bisect_visualize() { @@ -415,6 +532,8 @@ bisect_clean_state() { do git update-ref -d $ref $hash || exit done + rm -f "$GIT_DIR/BISECT_EXPECTED_REV" && + rm -f "$GIT_DIR/BISECT_ANCESTORS_OK" && rm -f "$GIT_DIR/BISECT_LOG" && rm -f "$GIT_DIR/BISECT_NAMES" && rm -f "$GIT_DIR/BISECT_RUN" && diff --git a/git-filter-branch.sh b/git-filter-branch.sh index 2871a59e32..81392add0b 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -232,11 +232,11 @@ mkdir ../map || die "Could not create map/ directory" case "$filter_subdir" in "") git rev-list --reverse --topo-order --default HEAD \ - --parents "$@" + --parents --simplify-merges "$@" ;; *) git rev-list --reverse --topo-order --default HEAD \ - --parents "$@" -- "$filter_subdir" + --parents --simplify-merges "$@" -- "$filter_subdir" esac > ../revs || die "Could not get the commits" commits=$(wc -l <../revs | tr -d " ") @@ -317,24 +317,20 @@ done <../revs # In case of a subdirectory filter, it is possible that a specified head # is not in the set of rewritten commits, because it was pruned by the -# revision walker. Fix it by mapping these heads to the next rewritten -# ancestor(s), i.e. the boundaries in the set of rewritten commits. +# revision walker. Fix it by mapping these heads to the unique nearest +# ancestor that survived the pruning. -# NEEDSWORK: we should sort the unmapped refs topologically first -while read ref -do - sha1=$(git rev-parse "$ref"^0) - test -f "$workdir"/../map/$sha1 && continue - # Assign the boundarie(s) in the set of rewritten commits - # as the replacement commit(s). - # (This would look a bit nicer if --not --stdin worked.) - for p in $( (cd "$workdir"/../map; ls | sed "s/^/^/") | - git rev-list $ref --boundary --stdin | - sed -n "s/^-//p") +if test "$filter_subdir" +then + while read ref do - map $p >> "$workdir"/../map/$sha1 - done -done < "$tempdir"/heads + sha1=$(git rev-parse "$ref"^0) + test -f "$workdir"/../map/$sha1 && continue + ancestor=$(git rev-list --simplify-merges -1 \ + $ref -- "$filter_subdir") + test "$ancestor" && echo $(map $ancestor) >> "$workdir"/../map/$sha1 + done < "$tempdir"/heads +fi # Finally update the refs diff --git a/git-gui/.gitattributes b/git-gui/.gitattributes new file mode 100644 index 0000000000..f96112d47f --- /dev/null +++ b/git-gui/.gitattributes @@ -0,0 +1,3 @@ +* encoding=US-ASCII +git-gui.sh encoding=UTF-8 +/po/*.po encoding=UTF-8 diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index ad65aaad5a..4085e8fea5 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -521,6 +521,19 @@ proc kill_file_process {fd} { } } +proc gitattr {path attr default} { + if {[catch {set r [git check-attr $attr -- $path]}]} { + set r unspecified + } else { + set r [join [lrange [split $r :] 2 end] :] + regsub {^ } $r {} r + } + if {$r eq {unspecified}} { + return $default + } + return $r +} + proc sq {value} { regsub -all ' $value "'\\''" value return "'$value'" @@ -657,17 +670,21 @@ proc apply_config {} { } set default_config(branch.autosetupmerge) true +set default_config(merge.tool) {} +set default_config(merge.keepbackup) true set default_config(merge.diffstat) true set default_config(merge.summary) false set default_config(merge.verbosity) 2 set default_config(user.name) {} set default_config(user.email) {} +set default_config(gui.encoding) [encoding system] set default_config(gui.matchtrackingbranch) false set default_config(gui.pruneduringfetch) false set default_config(gui.trustmtime) false set default_config(gui.fastcopyblame) false set default_config(gui.copyblamethreshold) 40 +set default_config(gui.blamehistoryctx) 7 set default_config(gui.diffcontext) 5 set default_config(gui.commitmsgwidth) 75 set default_config(gui.newbranchtemplate) {} @@ -945,10 +962,32 @@ blame { } citool { enable_option singlecommit + enable_option retcode disable_option multicommit disable_option branch disable_option transport + + while {[llength $argv] > 0} { + set a [lindex $argv 0] + switch -- $a { + --amend { + enable_option initialamend + } + --nocommit { + enable_option nocommit + enable_option nocommitmsg + } + --commitmsg { + disable_option nocommitmsg + } + default { + break + } + } + + set argv [lrange $argv 1 end] + } } } @@ -1020,8 +1059,12 @@ set current_branch {} set is_detached 0 set current_diff_path {} set is_3way_diff 0 +set is_conflict_diff 0 set selected_commit_type new +set nullid "0000000000000000000000000000000000000000" +set nullid2 "0000000000000000000000000000000000000001" + ###################################################################### ## ## task management @@ -1102,6 +1145,20 @@ proc PARENT {} { return $empty_tree } +proc force_amend {} { + global selected_commit_type + global HEAD PARENT MERGE_HEAD commit_type + + repository_state newType newHEAD newMERGE_HEAD + set HEAD $newHEAD + set PARENT $newHEAD + set MERGE_HEAD $newMERGE_HEAD + set commit_type $newType + + set selected_commit_type amend + do_select_commit_type +} + proc rescan {after {honor_trustmtime 1}} { global HEAD PARENT MERGE_HEAD commit_type global ui_index ui_workdir ui_comm @@ -1128,6 +1185,7 @@ proc rescan {after {honor_trustmtime 1}} { || [string trim [$ui_comm get 0.0 end]] eq {})} { if {[string match amend* $commit_type]} { } elseif {[load_message GITGUI_MSG]} { + } elseif {[run_prepare_commit_msg_hook]} { } elseif {[load_message MERGE_MSG]} { } elseif {[load_message SQUASH_MSG]} { } @@ -1227,6 +1285,70 @@ proc load_message {file} { return 0 } +proc run_prepare_commit_msg_hook {} { + global pch_error + + # prepare-commit-msg requires PREPARE_COMMIT_MSG exist. From git-gui + # it will be .git/MERGE_MSG (merge), .git/SQUASH_MSG (squash), or an + # empty file but existant file. + + set fd_pcm [open [gitdir PREPARE_COMMIT_MSG] a] + + if {[file isfile [gitdir MERGE_MSG]]} { + set pcm_source "merge" + set fd_mm [open [gitdir MERGE_MSG] r] + puts -nonewline $fd_pcm [read $fd_mm] + close $fd_mm + } elseif {[file isfile [gitdir SQUASH_MSG]]} { + set pcm_source "squash" + set fd_sm [open [gitdir SQUASH_MSG] r] + puts -nonewline $fd_pcm [read $fd_sm] + close $fd_sm + } else { + set pcm_source "" + } + + close $fd_pcm + + set fd_ph [githook_read prepare-commit-msg \ + [gitdir PREPARE_COMMIT_MSG] $pcm_source] + if {$fd_ph eq {}} { + catch {file delete [gitdir PREPARE_COMMIT_MSG]} + return 0; + } + + ui_status [mc "Calling prepare-commit-msg hook..."] + set pch_error {} + + fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fileevent $fd_ph readable \ + [list prepare_commit_msg_hook_wait $fd_ph] + + return 1; +} + +proc prepare_commit_msg_hook_wait {fd_ph} { + global pch_error + + append pch_error [read $fd_ph] + fconfigure $fd_ph -blocking 1 + if {[eof $fd_ph]} { + if {[catch {close $fd_ph}]} { + ui_status [mc "Commit declined by prepare-commit-msg hook."] + hook_failed_popup prepare-commit-msg $pch_error + catch {file delete [gitdir PREPARE_COMMIT_MSG]} + exit 1 + } else { + load_message PREPARE_COMMIT_MSG + } + set pch_error {} + catch {file delete [gitdir PREPARE_COMMIT_MSG]} + return + } + fconfigure $fd_ph -blocking 0 + catch {file delete [gitdir PREPARE_COMMIT_MSG]} +} + proc read_diff_index {fd after} { global buf_rdi @@ -1323,6 +1445,8 @@ proc rescan_done {fd buf after} { unlock_index display_all_files if {$current_diff_path ne {}} reshow_diff + if {$current_diff_path eq {}} select_first_diff + uplevel #0 $after } @@ -1619,6 +1743,15 @@ static unsigned char file_merge_bits[] = { 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f}; } -maskdata $filemask +image create bitmap file_statechange -background white -foreground green -data { +#define file_merge_width 14 +#define file_merge_height 15 +static unsigned char file_statechange_bits[] = { + 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x62, 0x10, + 0x62, 0x10, 0xba, 0x11, 0xba, 0x11, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10, + 0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f}; +} -maskdata $filemask + set ui_index .vpane.files.index.list set ui_workdir .vpane.files.workdir.list @@ -1627,12 +1760,14 @@ set all_icons(A$ui_index) file_fulltick set all_icons(M$ui_index) file_fulltick set all_icons(D$ui_index) file_removed set all_icons(U$ui_index) file_merge +set all_icons(T$ui_index) file_statechange set all_icons(_$ui_workdir) file_plain set all_icons(M$ui_workdir) file_mod set all_icons(D$ui_workdir) file_question set all_icons(U$ui_workdir) file_merge set all_icons(O$ui_workdir) file_plain +set all_icons(T$ui_workdir) file_statechange set max_status_desc 0 foreach i { @@ -1643,6 +1778,9 @@ foreach i { {MM {mc "Portions staged for commit"}} {MD {mc "Staged for commit, missing"}} + {_T {mc "File type changed, not staged"}} + {T_ {mc "File type changed, staged"}} + {_O {mc "Untracked, not staged"}} {A_ {mc "Staged for commit"}} {AM {mc "Portions staged for commit"}} @@ -1652,10 +1790,12 @@ foreach i { {D_ {mc "Staged for removal"}} {DO {mc "Staged for removal, still present"}} + {_U {mc "Requires merge resolution"}} {U_ {mc "Requires merge resolution"}} {UU {mc "Requires merge resolution"}} {UM {mc "Requires merge resolution"}} {UD {mc "Requires merge resolution"}} + {UT {mc "Requires merge resolution"}} } { set text [eval [lindex $i 1]] if {$max_status_desc < [string length $text]} { @@ -1730,11 +1870,19 @@ proc do_gitk {revs} { } set is_quitting 0 +set ret_code 1 + +proc terminate_me {win} { + global ret_code + if {$win ne {.}} return + exit $ret_code +} -proc do_quit {} { +proc do_quit {{rc {1}}} { global ui_comm is_quitting repo_config commit_type global GITGUI_BCK_exists GITGUI_BCK_i global ui_comm_spell + global ret_code if {$is_quitting} return set is_quitting 1 @@ -1789,6 +1937,7 @@ proc do_quit {} { } } + set ret_code $rc destroy . } @@ -1796,13 +1945,120 @@ proc do_rescan {} { rescan ui_ready } +proc ui_do_rescan {} { + rescan {force_first_diff; ui_ready} +} + proc do_commit {} { commit_tree } proc next_diff {} { global next_diff_p next_diff_w next_diff_i - show_diff $next_diff_p $next_diff_w $next_diff_i + show_diff $next_diff_p $next_diff_w {} +} + +proc find_anchor_pos {lst name} { + set lid [lsearch -sorted -exact $lst $name] + + if {$lid == -1} { + set lid 0 + foreach lname $lst { + if {$lname >= $name} break + incr lid + } + } + + return $lid +} + +proc find_file_from {flist idx delta path mmask} { + global file_states + + set len [llength $flist] + while {$idx >= 0 && $idx < $len} { + set name [lindex $flist $idx] + + if {$name ne $path && [info exists file_states($name)]} { + set state [lindex $file_states($name) 0] + + if {$mmask eq {} || [regexp $mmask $state]} { + return $idx + } + } + + incr idx $delta + } + + return {} +} + +proc find_next_diff {w path {lno {}} {mmask {}}} { + global next_diff_p next_diff_w next_diff_i + global file_lists ui_index ui_workdir + + set flist $file_lists($w) + if {$lno eq {}} { + set lno [find_anchor_pos $flist $path] + } else { + incr lno -1 + } + + if {$mmask ne {} && ![regexp {(^\^)|(\$$)} $mmask]} { + if {$w eq $ui_index} { + set mmask "^$mmask" + } else { + set mmask "$mmask\$" + } + } + + set idx [find_file_from $flist $lno 1 $path $mmask] + if {$idx eq {}} { + incr lno -1 + set idx [find_file_from $flist $lno -1 $path $mmask] + } + + if {$idx ne {}} { + set next_diff_w $w + set next_diff_p [lindex $flist $idx] + set next_diff_i [expr {$idx+1}] + return 1 + } else { + return 0 + } +} + +proc next_diff_after_action {w path {lno {}} {mmask {}}} { + global current_diff_path + + if {$path ne $current_diff_path} { + return {} + } elseif {[find_next_diff $w $path $lno $mmask]} { + return {next_diff;} + } else { + return {reshow_diff;} + } +} + +proc select_first_diff {} { + global ui_workdir + + if {[find_next_diff $ui_workdir {} 1 {^_?U}] || + [find_next_diff $ui_workdir {} 1 {[^O]$}]} { + next_diff + } +} + +proc force_first_diff {} { + global current_diff_path + + if {[info exists file_states($current_diff_path)]} { + set state [lindex $file_states($current_diff_path) 0] + + if {[string index $state 1] ne {O}} return + } + + select_first_diff } proc toggle_or_diff {w x y} { @@ -1823,34 +2079,29 @@ proc toggle_or_diff {w x y} { $ui_index tag remove in_sel 0.0 end $ui_workdir tag remove in_sel 0.0 end + # Determine the state of the file + if {[info exists file_states($path)]} { + set state [lindex $file_states($path) 0] + } else { + set state {__} + } + + # Restage the file, or simply show the diff if {$col == 0 && $y > 1} { - set i [expr {$lno-1}] - set ll [expr {[llength $file_lists($w)]-1}] + # Conflicts need special handling + if {[string first {U} $state] >= 0} { + merge_stage_workdir $path $w $lno + return + } - if {$i == $ll && $i == 0} { - set after {reshow_diff;} + if {[string index $state 1] eq {O}} { + set mmask {} } else { - global next_diff_p next_diff_w next_diff_i - - set next_diff_w $w - - if {$i < $ll} { - set i [expr {$i + 1}] - set next_diff_i $i - } else { - set next_diff_i $i - set i [expr {$i - 1}] - } - - set next_diff_p [lindex $file_lists($w) $i] - - if {$next_diff_p ne {} && $current_diff_path ne {}} { - set after {next_diff;} - } else { - set after {} - } + set mmask {[^O]} } + set after [next_diff_after_action $w $path $lno $mmask] + if {$w eq $ui_index} { update_indexinfo \ "Unstaging [short_path $path] from commit" \ @@ -1932,7 +2183,7 @@ proc show_more_context {} { proc show_less_context {} { global repo_config - if {$repo_config(gui.diffcontext) >= 1} { + if {$repo_config(gui.diffcontext) > 1} { incr repo_config(gui.diffcontext) -1 reshow_diff } @@ -2091,29 +2342,39 @@ if {[is_enabled branch]} { # -- Commit Menu # +proc commit_btn_caption {} { + if {[is_enabled nocommit]} { + return [mc "Done"] + } else { + return [mc Commit@@verb] + } +} + if {[is_enabled multicommit] || [is_enabled singlecommit]} { menu .mbar.commit - .mbar.commit add radiobutton \ - -label [mc "New Commit"] \ - -command do_select_commit_type \ - -variable selected_commit_type \ - -value new - lappend disable_on_lock \ - [list .mbar.commit entryconf [.mbar.commit index last] -state] + if {![is_enabled nocommit]} { + .mbar.commit add radiobutton \ + -label [mc "New Commit"] \ + -command do_select_commit_type \ + -variable selected_commit_type \ + -value new + lappend disable_on_lock \ + [list .mbar.commit entryconf [.mbar.commit index last] -state] - .mbar.commit add radiobutton \ - -label [mc "Amend Last Commit"] \ - -command do_select_commit_type \ - -variable selected_commit_type \ - -value amend - lappend disable_on_lock \ - [list .mbar.commit entryconf [.mbar.commit index last] -state] + .mbar.commit add radiobutton \ + -label [mc "Amend Last Commit"] \ + -command do_select_commit_type \ + -variable selected_commit_type \ + -value amend + lappend disable_on_lock \ + [list .mbar.commit entryconf [.mbar.commit index last] -state] - .mbar.commit add separator + .mbar.commit add separator + } .mbar.commit add command -label [mc Rescan] \ - -command do_rescan \ + -command ui_do_rescan \ -accelerator F5 lappend disable_on_lock \ [list .mbar.commit entryconf [.mbar.commit index last] -state] @@ -2152,11 +2413,13 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} { .mbar.commit add separator - .mbar.commit add command -label [mc "Sign Off"] \ - -command do_signoff \ - -accelerator $M1T-S + if {![is_enabled nocommit]} { + .mbar.commit add command -label [mc "Sign Off"] \ + -command do_signoff \ + -accelerator $M1T-S + } - .mbar.commit add command -label [mc Commit@@verb] \ + .mbar.commit add command -label [commit_btn_caption] \ -command do_commit \ -accelerator $M1T-Return lappend disable_on_lock \ @@ -2281,10 +2544,15 @@ proc usage {} { switch -- $subcommand { browser - blame { - set subcommand_args {rev? path} + if {$subcommand eq "blame"} { + set subcommand_args {[--line=<num>] rev? path} + } else { + set subcommand_args {rev? path} + } if {$argv eq {}} usage set head {} set path {} + set jump_spec {} set is_path 0 foreach a $argv { if {$is_path || [file exists $_prefix$a]} { @@ -2298,6 +2566,9 @@ blame { set path {} } set is_path 1 + } elseif {[regexp {^--line=(\d+)$} $a a lnum]} { + if {$jump_spec ne {} || $head ne {}} usage + set jump_spec [list $lnum] } elseif {$head eq {}} { if {$head ne {}} usage set head $a @@ -2329,6 +2600,7 @@ blame { switch -- $subcommand { browser { + if {$jump_spec ne {}} usage if {$head eq {}} { if {$path ne {} && [file isdirectory $path]} { set head $current_branch @@ -2344,7 +2616,7 @@ blame { puts stderr [mc "fatal: cannot stat path %s: No such file or directory" $path] exit 1 } - blame::new $head $path + blame::new $head $path $jump_spec } } return @@ -2460,7 +2732,7 @@ pack .vpane.lower.commarea.buttons.l -side top -fill x pack .vpane.lower.commarea.buttons -side left -fill y button .vpane.lower.commarea.buttons.rescan -text [mc Rescan] \ - -command do_rescan + -command ui_do_rescan pack .vpane.lower.commarea.buttons.rescan -side top -fill x lappend disable_on_lock \ {.vpane.lower.commarea.buttons.rescan conf -state} @@ -2471,19 +2743,23 @@ pack .vpane.lower.commarea.buttons.incall -side top -fill x lappend disable_on_lock \ {.vpane.lower.commarea.buttons.incall conf -state} -button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \ - -command do_signoff -pack .vpane.lower.commarea.buttons.signoff -side top -fill x +if {![is_enabled nocommit]} { + button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \ + -command do_signoff + pack .vpane.lower.commarea.buttons.signoff -side top -fill x +} -button .vpane.lower.commarea.buttons.commit -text [mc Commit@@verb] \ +button .vpane.lower.commarea.buttons.commit -text [commit_btn_caption] \ -command do_commit pack .vpane.lower.commarea.buttons.commit -side top -fill x lappend disable_on_lock \ {.vpane.lower.commarea.buttons.commit conf -state} -button .vpane.lower.commarea.buttons.push -text [mc Push] \ - -command do_push_anywhere -pack .vpane.lower.commarea.buttons.push -side top -fill x +if {![is_enabled nocommit]} { + button .vpane.lower.commarea.buttons.push -text [mc Push] \ + -command do_push_anywhere + pack .vpane.lower.commarea.buttons.push -side top -fill x +} # -- Commit Message Buffer # @@ -2491,20 +2767,24 @@ frame .vpane.lower.commarea.buffer frame .vpane.lower.commarea.buffer.header set ui_comm .vpane.lower.commarea.buffer.t set ui_coml .vpane.lower.commarea.buffer.header.l -radiobutton .vpane.lower.commarea.buffer.header.new \ - -text [mc "New Commit"] \ - -command do_select_commit_type \ - -variable selected_commit_type \ - -value new -lappend disable_on_lock \ - [list .vpane.lower.commarea.buffer.header.new conf -state] -radiobutton .vpane.lower.commarea.buffer.header.amend \ - -text [mc "Amend Last Commit"] \ - -command do_select_commit_type \ - -variable selected_commit_type \ - -value amend -lappend disable_on_lock \ - [list .vpane.lower.commarea.buffer.header.amend conf -state] + +if {![is_enabled nocommit]} { + radiobutton .vpane.lower.commarea.buffer.header.new \ + -text [mc "New Commit"] \ + -command do_select_commit_type \ + -variable selected_commit_type \ + -value new + lappend disable_on_lock \ + [list .vpane.lower.commarea.buffer.header.new conf -state] + radiobutton .vpane.lower.commarea.buffer.header.amend \ + -text [mc "Amend Last Commit"] \ + -command do_select_commit_type \ + -variable selected_commit_type \ + -value amend + lappend disable_on_lock \ + [list .vpane.lower.commarea.buffer.header.amend conf -state] +} + label $ui_coml \ -anchor w \ -justify left @@ -2522,8 +2802,11 @@ proc trace_commit_type {varname args} { } trace add variable commit_type write trace_commit_type pack $ui_coml -side left -fill x -pack .vpane.lower.commarea.buffer.header.amend -side right -pack .vpane.lower.commarea.buffer.header.new -side right + +if {![is_enabled nocommit]} { + pack .vpane.lower.commarea.buffer.header.amend -side right + pack .vpane.lower.commarea.buffer.header.new -side right +} text $ui_comm -background white -foreground black \ -borderwidth 1 \ @@ -2689,6 +2972,59 @@ $ui_diff tag raise sel # -- Diff Body Context Menu # + +proc create_common_diff_popup {ctxm} { + $ctxm add command \ + -label [mc "Show Less Context"] \ + -command show_less_context + lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] + $ctxm add command \ + -label [mc "Show More Context"] \ + -command show_more_context + lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] + $ctxm add separator + $ctxm add command \ + -label [mc Refresh] \ + -command reshow_diff + lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] + $ctxm add command \ + -label [mc Copy] \ + -command {tk_textCopy $ui_diff} + lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] + $ctxm add command \ + -label [mc "Select All"] \ + -command {focus $ui_diff;$ui_diff tag add sel 0.0 end} + lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] + $ctxm add command \ + -label [mc "Copy All"] \ + -command { + $ui_diff tag add sel 0.0 end + tk_textCopy $ui_diff + $ui_diff tag remove sel 0.0 end + } + lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] + $ctxm add separator + $ctxm add command \ + -label [mc "Decrease Font Size"] \ + -command {incr_font_size font_diff -1} + lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] + $ctxm add command \ + -label [mc "Increase Font Size"] \ + -command {incr_font_size font_diff 1} + lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] + $ctxm add separator + set emenu $ctxm.enc + menu $emenu + build_encoding_menu $emenu [list force_diff_encoding] + $ctxm add cascade \ + -label [mc "Encoding"] \ + -menu $emenu + lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] + $ctxm add separator + $ctxm add command -label [mc "Options..."] \ + -command do_options +} + set ctxm .vpane.lower.diff.body.ctxm menu $ctxm -tearoff 0 $ctxm add command \ @@ -2702,71 +3038,65 @@ $ctxm add command \ set ui_diff_applyline [$ctxm index last] lappend diff_actions [list $ctxm entryconf $ui_diff_applyline -state] $ctxm add separator -$ctxm add command \ - -label [mc "Show Less Context"] \ - -command show_less_context -lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] -$ctxm add command \ - -label [mc "Show More Context"] \ - -command show_more_context -lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] -$ctxm add separator -$ctxm add command \ - -label [mc Refresh] \ - -command reshow_diff -lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] -$ctxm add command \ - -label [mc Copy] \ - -command {tk_textCopy $ui_diff} -lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] -$ctxm add command \ - -label [mc "Select All"] \ - -command {focus $ui_diff;$ui_diff tag add sel 0.0 end} -lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] -$ctxm add command \ - -label [mc "Copy All"] \ - -command { - $ui_diff tag add sel 0.0 end - tk_textCopy $ui_diff - $ui_diff tag remove sel 0.0 end - } -lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] -$ctxm add separator -$ctxm add command \ - -label [mc "Decrease Font Size"] \ - -command {incr_font_size font_diff -1} -lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] -$ctxm add command \ - -label [mc "Increase Font Size"] \ - -command {incr_font_size font_diff 1} -lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] -$ctxm add separator -$ctxm add command -label [mc "Options..."] \ - -command do_options -proc popup_diff_menu {ctxm x y X Y} { +create_common_diff_popup $ctxm + +set ctxmmg .vpane.lower.diff.body.ctxmmg +menu $ctxmmg -tearoff 0 +$ctxmmg add command \ + -label [mc "Run Merge Tool"] \ + -command {merge_resolve_tool} +lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state] +$ctxmmg add separator +$ctxmmg add command \ + -label [mc "Use Remote Version"] \ + -command {merge_resolve_one 3} +lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state] +$ctxmmg add command \ + -label [mc "Use Local Version"] \ + -command {merge_resolve_one 2} +lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state] +$ctxmmg add command \ + -label [mc "Revert To Base"] \ + -command {merge_resolve_one 1} +lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state] +$ctxmmg add separator +create_common_diff_popup $ctxmmg + +proc popup_diff_menu {ctxm ctxmmg x y X Y} { global current_diff_path file_states set ::cursorX $x set ::cursorY $y - if {$::ui_index eq $::current_diff_side} { - set l [mc "Unstage Hunk From Commit"] - set t [mc "Unstage Line From Commit"] + if {[info exists file_states($current_diff_path)]} { + set state [lindex $file_states($current_diff_path) 0] } else { - set l [mc "Stage Hunk For Commit"] - set t [mc "Stage Line For Commit"] - } - if {$::is_3way_diff - || $current_diff_path eq {} - || ![info exists file_states($current_diff_path)] - || {_O} eq [lindex $file_states($current_diff_path) 0]} { - set s disabled + set state {__} + } + if {[string first {U} $state] >= 0} { + tk_popup $ctxmmg $X $Y } else { - set s normal + if {$::ui_index eq $::current_diff_side} { + set l [mc "Unstage Hunk From Commit"] + set t [mc "Unstage Line From Commit"] + } else { + set l [mc "Stage Hunk For Commit"] + set t [mc "Stage Line For Commit"] + } + if {$::is_3way_diff + || $current_diff_path eq {} + || {__} eq $state + || {_O} eq $state + || {_T} eq $state + || {T_} eq $state} { + set s disabled + } else { + set s normal + } + $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l + $ctxm entryconf $::ui_diff_applyline -state $s -label $t + tk_popup $ctxm $X $Y } - $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l - $ctxm entryconf $::ui_diff_applyline -state $s -label $t - tk_popup $ctxm $X $Y } -bind_button3 $ui_diff [list popup_diff_menu $ctxm %x %y %X %Y] +bind_button3 $ui_diff [list popup_diff_menu $ctxm $ctxmmg %x %y %X %Y] # -- Status Bar # @@ -2842,9 +3172,9 @@ if {[is_enabled transport]} { bind . <$M1B-Key-P> do_push_anywhere } -bind . <Key-F5> do_rescan -bind . <$M1B-Key-r> do_rescan -bind . <$M1B-Key-R> do_rescan +bind . <Key-F5> ui_do_rescan +bind . <$M1B-Key-r> ui_do_rescan +bind . <$M1B-Key-R> ui_do_rescan bind . <$M1B-Key-s> do_signoff bind . <$M1B-Key-S> do_signoff bind . <$M1B-Key-t> do_add_selection @@ -3022,7 +3352,20 @@ lock_index begin-read if {![winfo ismapped .]} { wm deiconify . } -after 1 do_rescan +after 1 { + if {[is_enabled initialamend]} { + force_amend + } else { + do_rescan + } + + if {[is_enabled nocommitmsg]} { + $ui_comm configure -state disabled -background gray + } +} if {[is_enabled multicommit]} { after 1000 hint_gc } +if {[is_enabled retcode]} { + bind . <Destroy> {+terminate_me %W} +} diff --git a/git-gui/lib/blame.tcl b/git-gui/lib/blame.tcl index b6e42cbc8f..eb61374d2d 100644 --- a/git-gui/lib/blame.tcl +++ b/git-gui/lib/blame.tcl @@ -58,7 +58,7 @@ field tooltip_t {} ; # Text widget in $tooltip_wm field tooltip_timer {} ; # Current timer event for our tooltip field tooltip_commit {} ; # Commit(s) in tooltip -constructor new {i_commit i_path} { +constructor new {i_commit i_path i_jump} { global cursor_ptr variable active_color variable group_colors @@ -256,9 +256,22 @@ constructor new {i_commit i_path} { $w.ctxm add command \ -label [mc "Copy Commit"] \ -command [cb _copycommit] + $w.ctxm add separator + menu $w.ctxm.enc + build_encoding_menu $w.ctxm.enc [cb _setencoding] + $w.ctxm add cascade \ + -label [mc "Encoding"] \ + -menu $w.ctxm.enc $w.ctxm add command \ -label [mc "Do Full Copy Detection"] \ -command [cb _fullcopyblame] + $w.ctxm add separator + $w.ctxm add command \ + -label [mc "Show History Context"] \ + -command [cb _gitkcommit] + $w.ctxm add command \ + -label [mc "Blame Parent Commit"] \ + -command [cb _blameparent] foreach i $w_columns { for {set g 0} {$g < [llength $group_colors]} {incr g} { @@ -332,7 +345,7 @@ constructor new {i_commit i_path} { wm protocol $top WM_DELETE_WINDOW "destroy $top" bind $top <Destroy> [cb _kill] - _load $this {} + _load $this $i_jump } method _kill {} { @@ -393,7 +406,10 @@ method _load {jump} { } else { set fd [git_read cat-file blob "$commit:$path"] } - fconfigure $fd -blocking 0 -translation lf -encoding binary + fconfigure $fd \ + -blocking 0 \ + -translation lf \ + -encoding [get_path_encoding $path] fileevent $fd readable [cb _read_file $fd $jump] set current_fd $fd } @@ -502,7 +518,7 @@ method _exec_blame {cur_w cur_d options cur_s} { } lappend options -- $path set fd [eval git_read --nice blame $options] - fconfigure $fd -blocking 0 -translation lf -encoding binary + fconfigure $fd -blocking 0 -translation lf -encoding utf-8 fileevent $fd readable [cb _read_blame $fd $cur_w $cur_d] set current_fd $fd set blame_lines 0 @@ -782,24 +798,42 @@ method _click {cur_w pos} { _showcommit $this $cur_w $lno } +method _setencoding {enc} { + force_path_encoding $path $enc + _load $this [list \ + $highlight_column \ + $highlight_line \ + [lindex [$w_file xview] 0] \ + [lindex [$w_file yview] 0] \ + ] +} + method _load_commit {cur_w cur_d pos} { upvar #0 $cur_d line_data set lno [lindex [split [$cur_w index $pos] .] 0] set dat [lindex $line_data $lno] if {$dat ne {}} { - lappend history [list \ - $commit $path \ - $highlight_column \ - $highlight_line \ - [lindex [$w_file xview] 0] \ - [lindex [$w_file yview] 0] \ - ] - set commit [lindex $dat 0] - set path [lindex $dat 1] - _load $this [list [lindex $dat 2]] + _load_new_commit $this \ + [lindex $dat 0] \ + [lindex $dat 1] \ + [list [lindex $dat 2]] } } +method _load_new_commit {new_commit new_path jump} { + lappend history [list \ + $commit $path \ + $highlight_column \ + $highlight_line \ + [lindex [$w_file xview] 0] \ + [lindex [$w_file yview] 0] \ + ] + + set commit $new_commit + set path $new_path + _load $this $jump +} + method _showcommit {cur_w lno} { global repo_config variable active_color @@ -867,12 +901,6 @@ method _showcommit {cur_w lno} { set enc [tcl_encoding $enc] if {$enc ne {}} { set msg [encoding convertfrom $enc $msg] - set author_name [encoding convertfrom $enc $author_name] - set committer_name [encoding convertfrom $enc $committer_name] - set header($cmit,author) $author_name - set header($cmit,committer) $committer_name - set header($cmit,summary) \ - [encoding convertfrom $enc $header($cmit,summary)] } set msg [string trim $msg] } @@ -905,10 +933,14 @@ method _showcommit {cur_w lno} { } } -method _copycommit {} { +method _get_click_amov_info {} { set pos @$::cursorX,$::cursorY set lno [lindex [split [$::cursorW index $pos] .] 0] - set dat [lindex $amov_data $lno] + return [lindex $amov_data $lno] +} + +method _copycommit {} { + set dat [_get_click_amov_info $this] if {$dat ne {}} { clipboard clear clipboard append \ @@ -918,6 +950,147 @@ method _copycommit {} { } } +method _format_offset_date {base offset} { + set exval [expr {$base + $offset*24*60*60}] + return [clock format $exval -format {%Y-%m-%d}] +} + +method _gitkcommit {} { + global nullid + + set dat [_get_click_amov_info $this] + if {$dat ne {}} { + set cmit [lindex $dat 0] + + # If the line belongs to the working copy, use HEAD instead + if {$cmit eq $nullid} { + if {[catch {set cmit [git rev-parse --verify HEAD]} err]} { + error_popup [strcat [mc "Cannot find HEAD commit:"] "\n\n$err"] + return; + } + } + + set radius [get_config gui.blamehistoryctx] + set cmdline [list --select-commit=$cmit] + + if {$radius > 0} { + set author_time {} + set committer_time {} + + catch {set author_time $header($cmit,author-time)} + catch {set committer_time $header($cmit,committer-time)} + + if {$committer_time eq {}} { + set committer_time $author_time + } + + set after_time [_format_offset_date $this $committer_time [expr {-$radius}]] + set before_time [_format_offset_date $this $committer_time $radius] + + lappend cmdline --after=$after_time --before=$before_time + } + + lappend cmdline $cmit + + set base_rev "HEAD" + if {$commit ne {}} { + set base_rev $commit + } + + if {$base_rev ne $cmit} { + lappend cmdline $base_rev + } + + do_gitk $cmdline + } +} + +method _blameparent {} { + global nullid + + set dat [_get_click_amov_info $this] + if {$dat ne {}} { + set cmit [lindex $dat 0] + set new_path [lindex $dat 1] + + # Allow using Blame Parent on lines modified in the working copy + if {$cmit eq $nullid} { + set parent_ref "HEAD" + } else { + set parent_ref "$cmit^" + } + if {[catch {set cparent [git rev-parse --verify $parent_ref]} err]} { + error_popup [strcat [mc "Cannot find parent commit:"] "\n\n$err"] + return; + } + + _kill $this + + # Generate a diff between the commit and its parent, + # and use the hunks to update the line number. + # Request zero context to simplify calculations. + if {$cmit eq $nullid} { + set diffcmd [list diff-index --unified=0 $cparent -- $new_path] + } else { + set diffcmd [list diff-tree --unified=0 $cparent $cmit -- $new_path] + } + if {[catch {set fd [eval git_read $diffcmd]} err]} { + $status stop [mc "Unable to display parent"] + error_popup [strcat [mc "Error loading diff:"] "\n\n$err"] + return + } + + set r_orig_line [lindex $dat 2] + + fconfigure $fd \ + -blocking 0 \ + -encoding binary \ + -translation binary + fileevent $fd readable [cb _read_diff_load_commit \ + $fd $cparent $new_path $r_orig_line] + set current_fd $fd + } +} + +method _read_diff_load_commit {fd cparent new_path tline} { + if {$fd ne $current_fd} { + catch {close $fd} + return + } + + while {[gets $fd line] >= 0} { + if {[regexp {^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@} $line line \ + old_line osz old_size new_line nsz new_size]} { + + if {$osz eq {}} { set old_size 1 } + if {$nsz eq {}} { set new_size 1 } + + if {$new_line <= $tline} { + if {[expr {$new_line + $new_size}] > $tline} { + # Target line within the hunk + set line_shift [expr { + ($new_size-$old_size)*($tline-$new_line)/$new_size + }] + } else { + set line_shift [expr {$new_size-$old_size}] + } + + set r_orig_line [expr {$r_orig_line - $line_shift}] + } + } + } + + if {[eof $fd]} { + close $fd; + set current_fd {} + + _load_new_commit $this \ + $cparent \ + $new_path \ + [list $r_orig_line] + } +} ifdeleted { catch {close $fd} } + method _show_tooltip {cur_w pos} { if {$tooltip_wm ne {}} { _open_tooltip $this $cur_w diff --git a/git-gui/lib/browser.tcl b/git-gui/lib/browser.tcl index ab470d1264..0410cc68df 100644 --- a/git-gui/lib/browser.tcl +++ b/git-gui/lib/browser.tcl @@ -151,7 +151,7 @@ method _enter {} { append p [lindex $n 1] } append p $name - blame::new $browser_commit $p + blame::new $browser_commit $p {} } } } diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl index 40a7103557..334514996a 100644 --- a/git-gui/lib/commit.tcl +++ b/git-gui/lib/commit.tcl @@ -149,7 +149,9 @@ The rescan will be automatically started now. _? {continue} A? - D? - + T_ - M? {set files_ready 1} + _U - U? { error_popup [mc "Unmerged files cannot be committed. @@ -166,7 +168,7 @@ File %s cannot be committed by this program. } } } - if {!$files_ready && ![string match *merge $curType]} { + if {!$files_ready && ![string match *merge $curType] && ![is_enabled nocommit]} { info_popup [mc "No changes to commit. You must stage at least 1 file before you can commit. @@ -175,6 +177,8 @@ You must stage at least 1 file before you can commit. return } + if {[is_enabled nocommitmsg]} { do_quit 0 } + # -- A message is required. # set msg [string trim [$ui_comm get 1.0 end]] @@ -210,6 +214,8 @@ A good commit message has the following format: puts $msg_wt $msg close $msg_wt + if {[is_enabled nocommit]} { do_quit 0 } + # -- Run the pre-commit hook. # set fd_ph [githook_read pre-commit] @@ -408,7 +414,7 @@ A rescan will be automatically started now. set ::GITGUI_BCK_exists 0 } - if {[is_enabled singlecommit]} do_quit + if {[is_enabled singlecommit]} { do_quit 0 } # -- Update in memory status # @@ -428,6 +434,7 @@ A rescan will be automatically started now. __ - A_ - M_ - + T_ - D_ { unset file_states($path) catch {unset selected_paths($path)} diff --git a/git-gui/lib/diff.tcl b/git-gui/lib/diff.tcl index 52b79e4a1f..abe502d971 100644 --- a/git-gui/lib/diff.tcl +++ b/git-gui/lib/diff.tcl @@ -24,16 +24,31 @@ proc reshow_diff {} { set p $current_diff_path if {$p eq {}} { # No diff is being shown. - } elseif {$current_diff_side eq {} - || [catch {set s $file_states($p)}] - || [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} { + } elseif {$current_diff_side eq {}} { clear_diff + } elseif {[catch {set s $file_states($p)}] + || [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} { + + if {[find_next_diff $current_diff_side $p {} {[^O]}]} { + next_diff + } else { + clear_diff + } } else { set save_pos [lindex [$ui_diff yview] 0] show_diff $p $current_diff_side {} $save_pos } } +proc force_diff_encoding {enc} { + global current_diff_path + + if {$current_diff_path ne {}} { + force_path_encoding $current_diff_path $enc + reshow_diff + } +} + proc handle_empty_diff {} { global current_diff_path file_states file_lists @@ -54,11 +69,12 @@ A rescan will be automatically started to find other files which may have the sa rescan ui_ready 0 } -proc show_diff {path w {lno {}} {scroll_pos {}}} { +proc show_diff {path w {lno {}} {scroll_pos {}} {callback {}}} { global file_states file_lists - global is_3way_diff diff_active repo_config + global is_3way_diff is_conflict_diff diff_active repo_config global ui_diff ui_index ui_workdir global current_diff_path current_diff_side current_diff_header + global current_diff_queue if {$diff_active || ![lock_index read]} return @@ -71,17 +87,80 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} { } if {$lno >= 1} { $w tag add in_diff $lno.0 [expr {$lno + 1}].0 + $w see $lno.0 } set s $file_states($path) set m [lindex $s 0] - set is_3way_diff 0 - set diff_active 1 + set is_conflict_diff 0 set current_diff_path $path set current_diff_side $w - set current_diff_header {} + set current_diff_queue {} ui_status [mc "Loading diff of %s..." [escape_path $path]] + set cont_info [list $scroll_pos $callback] + + if {[string first {U} $m] >= 0} { + merge_load_stages $path [list show_unmerged_diff $cont_info] + } elseif {$m eq {_O}} { + show_other_diff $path $w $m $cont_info + } else { + start_show_diff $cont_info + } +} + +proc show_unmerged_diff {cont_info} { + global current_diff_path current_diff_side + global merge_stages ui_diff is_conflict_diff + global current_diff_queue + + if {$merge_stages(2) eq {}} { + set is_conflict_diff 1 + lappend current_diff_queue \ + [list "LOCAL: deleted\nREMOTE:\n" d======= \ + [list ":1:$current_diff_path" ":3:$current_diff_path"]] + } elseif {$merge_stages(3) eq {}} { + set is_conflict_diff 1 + lappend current_diff_queue \ + [list "REMOTE: deleted\nLOCAL:\n" d======= \ + [list ":1:$current_diff_path" ":2:$current_diff_path"]] + } elseif {[lindex $merge_stages(1) 0] eq {120000} + || [lindex $merge_stages(2) 0] eq {120000} + || [lindex $merge_stages(3) 0] eq {120000}} { + set is_conflict_diff 1 + lappend current_diff_queue \ + [list "LOCAL:\n" d======= \ + [list ":1:$current_diff_path" ":2:$current_diff_path"]] + lappend current_diff_queue \ + [list "REMOTE:\n" d======= \ + [list ":1:$current_diff_path" ":3:$current_diff_path"]] + } else { + start_show_diff $cont_info + return + } + + advance_diff_queue $cont_info +} + +proc advance_diff_queue {cont_info} { + global current_diff_queue ui_diff + + set item [lindex $current_diff_queue 0] + set current_diff_queue [lrange $current_diff_queue 1 end] + + $ui_diff conf -state normal + $ui_diff insert end [lindex $item 0] [lindex $item 1] + $ui_diff conf -state disabled + + start_show_diff $cont_info [lindex $item 2] +} + +proc show_other_diff {path w m cont_info} { + global file_states file_lists + global is_3way_diff diff_active repo_config + global ui_diff ui_index ui_workdir + global current_diff_path current_diff_side current_diff_header + # - Git won't give us the diff, there's nothing to compare to! # if {$m eq {_O}} { @@ -101,7 +180,9 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} { } file { set fd [open $path r] - fconfigure $fd -eofchar {} + fconfigure $fd \ + -eofchar {} \ + -encoding [get_path_encoding $path] set content [read $fd $max_sz] close $fd set sz [file size $path] @@ -153,20 +234,41 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} { $ui_diff conf -state disabled set diff_active 0 unlock_index + set scroll_pos [lindex $cont_info 0] if {$scroll_pos ne {}} { update $ui_diff yview moveto $scroll_pos } ui_ready + set callback [lindex $cont_info 1] + if {$callback ne {}} { + eval $callback + } return } +} + +proc start_show_diff {cont_info {add_opts {}}} { + global file_states file_lists + global is_3way_diff diff_active repo_config + global ui_diff ui_index ui_workdir + global current_diff_path current_diff_side current_diff_header + + set path $current_diff_path + set w $current_diff_side + + set s $file_states($path) + set m [lindex $s 0] + set is_3way_diff 0 + set diff_active 1 + set current_diff_header {} set cmd [list] if {$w eq $ui_index} { lappend cmd diff-index lappend cmd --cached } elseif {$w eq $ui_workdir} { - if {[string index $m 0] eq {U}} { + if {[string first {U} $m] >= 0} { lappend cmd diff } else { lappend cmd diff-files @@ -175,14 +277,18 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} { lappend cmd -p lappend cmd --no-color - if {$repo_config(gui.diffcontext) >= 0} { + if {$repo_config(gui.diffcontext) >= 1} { lappend cmd "-U$repo_config(gui.diffcontext)" } if {$w eq $ui_index} { lappend cmd [PARENT] } - lappend cmd -- - lappend cmd $path + if {$add_opts ne {}} { + eval lappend cmd $add_opts + } else { + lappend cmd -- + lappend cmd $path + } if {[catch {set fd [eval git_read --nice $cmd]} err]} { set diff_active 0 @@ -192,33 +298,38 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} { return } + set ::current_diff_inheader 1 fconfigure $fd \ -blocking 0 \ - -encoding binary \ - -translation binary - fileevent $fd readable [list read_diff $fd $scroll_pos] + -encoding [get_path_encoding $path] \ + -translation lf + fileevent $fd readable [list read_diff $fd $cont_info] } -proc read_diff {fd scroll_pos} { +proc read_diff {fd cont_info} { global ui_diff diff_active - global is_3way_diff current_diff_header + global is_3way_diff is_conflict_diff current_diff_header + global current_diff_queue $ui_diff conf -state normal while {[gets $fd line] >= 0} { # -- Cleanup uninteresting diff header lines. # - if { [string match {diff --git *} $line] - || [string match {diff --cc *} $line] - || [string match {diff --combined *} $line] - || [string match {--- *} $line] - || [string match {+++ *} $line]} { - append current_diff_header $line "\n" - continue + if {$::current_diff_inheader} { + if { [string match {diff --git *} $line] + || [string match {diff --cc *} $line] + || [string match {diff --combined *} $line] + || [string match {--- *} $line] + || [string match {+++ *} $line]} { + append current_diff_header $line "\n" + continue + } } if {[string match {index *} $line]} continue if {$line eq {deleted file mode 120000}} { set line "deleted symlink" } + set ::current_diff_inheader 0 # -- Automatically detect if this is a 3 way diff. # @@ -245,6 +356,7 @@ proc read_diff {fd scroll_pos} { {--} {set tags d_--} {++} { if {[regexp {^\+\+([<>]{7} |={7})} $line _g op]} { + set is_conflict_diff 1 set line [string replace $line 0 1 { }] set tags d$op } else { @@ -264,6 +376,7 @@ proc read_diff {fd scroll_pos} { {-} {set tags d_-} {+} { if {[regexp {^\+([<>]{7} |={7})} $line _g op]} { + set is_conflict_diff 1 set line [string replace $line 0 0 { }] set tags d$op } else { @@ -286,8 +399,15 @@ proc read_diff {fd scroll_pos} { if {[eof $fd]} { close $fd + + if {$current_diff_queue ne {}} { + advance_diff_queue $cont_info + return + } + set diff_active 0 unlock_index + set scroll_pos [lindex $cont_info 0] if {$scroll_pos ne {}} { update $ui_diff yview moveto $scroll_pos @@ -297,6 +417,10 @@ proc read_diff {fd scroll_pos} { if {[$ui_diff index end] eq {2.0}} { handle_empty_diff } + set callback [lindex $cont_info 1] + if {$callback ne {}} { + eval $callback + } } } @@ -337,8 +461,9 @@ proc apply_hunk {x y} { } if {[catch { + set enc [get_path_encoding $current_diff_path] set p [eval git_write $apply_cmd] - fconfigure $p -translation binary -encoding binary + fconfigure $p -translation binary -encoding $enc puts -nonewline $p $current_diff_header puts -nonewline $p [$ui_diff get $s_lno $e_lno] close $p} err]} { @@ -366,10 +491,9 @@ proc apply_hunk {x y} { } unlock_index display_file $current_diff_path $mi + # This should trigger shift to the next changed file if {$o eq {_}} { - clear_diff - } else { - set current_diff_path $current_diff_path + reshow_diff } } @@ -507,8 +631,9 @@ proc apply_line {x y} { set patch "@@ -$hln,$n +$hln,[eval expr $n $sign 1] @@\n$patch" if {[catch { + set enc [get_path_encoding $current_diff_path] set p [eval git_write $apply_cmd] - fconfigure $p -translation binary -encoding binary + fconfigure $p -translation binary -encoding $enc puts -nonewline $p $current_diff_header puts -nonewline $p $patch close $p} err]} { diff --git a/git-gui/lib/encoding.tcl b/git-gui/lib/encoding.tcl index 7f06b0d47f..32668fc9c6 100644 --- a/git-gui/lib/encoding.tcl +++ b/git-gui/lib/encoding.tcl @@ -206,7 +206,7 @@ set encoding_aliases { { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 } { GBK CP936 MS936 windows-936 } { JIS_Encoding csJISEncoding } - { Shift_JIS MS_Kanji csShiftJIS } + { Shift_JIS MS_Kanji csShiftJIS ShiftJIS Shift-JIS } { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese EUC-JP } { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese } @@ -240,37 +240,227 @@ set encoding_aliases { { Big5 csBig5 } } +set encoding_groups { + {"" "" + {"Unicode" UTF-8} + {"Western" ISO-8859-1}} + {we "West European" + {"Western" ISO-8859-15 CP-437 CP-850 MacRoman CP-1252 Windows-1252} + {"Celtic" ISO-8859-14} + {"Greek" ISO-8859-14 ISO-8859-7 CP-737 CP-869 MacGreek CP-1253 Windows-1253} + {"Icelandic" MacIceland MacIcelandic CP-861} + {"Nordic" ISO-8859-10 CP-865} + {"Portuguese" CP-860} + {"South European" ISO-8859-3}} + {ee "East European" + {"Baltic" CP-775 ISO-8859-4 ISO-8859-13 CP-1257 Windows-1257} + {"Central European" CP-852 ISO-8859-2 MacCE CP-1250 Windows-1250} + {"Croatian" MacCroatian} + {"Cyrillic" CP-855 ISO-8859-5 ISO-IR-111 KOI8-R MacCyrillic CP-1251 Windows-1251} + {"Russian" CP-866} + {"Ukrainian" KOI8-U MacUkraine MacUkrainian} + {"Romanian" ISO-8859-16 MacRomania MacRomanian}} + {ea "East Asian" + {"Generic" ISO-2022} + {"Chinese Simplified" GB2312 GB1988 GB12345 GB2312-RAW GBK EUC-CN GB18030 HZ ISO-2022-CN} + {"Chinese Traditional" Big5 Big5-HKSCS EUC-TW CP-950} + {"Japanese" EUC-JP ISO-2022-JP Shift-JIS JIS-0212 JIS-0208 JIS-0201 CP-932 MacJapan} + {"Korean" EUC-KR UHC JOHAB ISO-2022-KR CP-949 KSC5601}} + {sa "SE & SW Asian" + {"Armenian" ARMSCII-8} + {"Georgian" GEOSTD8} + {"Thai" TIS-620 ISO-8859-11 CP-874 Windows-874 MacThai} + {"Turkish" CP-857 CP857 ISO-8859-9 MacTurkish CP-1254 Windows-1254} + {"Vietnamese" TCVN VISCII VPS CP-1258 Windows-1258} + {"Hindi" MacDevanagari} + {"Gujarati" MacGujarati} + {"Gurmukhi" MacGurmukhi}} + {me "Middle Eastern" + {"Arabic" ISO-8859-6 Windows-1256 CP-1256 CP-864 MacArabic} + {"Farsi" MacFarsi} + {"Hebrew" ISO-8859-8-I Windows-1255 CP-1255 ISO-8859-8 CP-862 MacHebrew}} + {mi "Misc" + {"7-bit" ASCII} + {"16-bit" Unicode} + {"Legacy" CP-863 EBCDIC} + {"Symbol" Symbol Dingbats MacDingbats MacCentEuro}} +} + +proc build_encoding_table {} { + global encoding_aliases encoding_lookup_table + + # Prepare the lookup list; cannot use lsort -nocase because + # of compatibility issues with older Tcl (e.g. in msysgit) + set names [list] + foreach item [encoding names] { + lappend names [list [string tolower $item] $item] + } + set names [lsort -ascii -index 0 $names] + # neither can we use lsearch -index + set lnames [list] + foreach item $names { + lappend lnames [lindex $item 0] + } + + foreach grp $encoding_aliases { + set target {} + foreach item $grp { + set i [lsearch -sorted -ascii $lnames \ + [string tolower $item]] + if {$i >= 0} { + set target [lindex $names $i 1] + break + } + } + if {$target eq {}} continue + foreach item $grp { + set encoding_lookup_table([string tolower $item]) $target + } + } + + foreach item $names { + set encoding_lookup_table([lindex $item 0]) [lindex $item 1] + } +} + proc tcl_encoding {enc} { - global encoding_aliases - set names [encoding names] - set lcnames [string tolower $names] - set enc [string tolower $enc] - set i [lsearch -exact $lcnames $enc] - if {$i < 0} { - # look for "isonnn" instead of "iso-nnn" or "iso_nnn" - if {[regsub {^iso[-_]} $enc iso encx]} { - set i [lsearch -exact $lcnames $encx] + global encoding_lookup_table + if {$enc eq {}} { + return {} + } + if {![info exists encoding_lookup_table]} { + build_encoding_table + } + set enc [string tolower $enc] + if {![info exists encoding_lookup_table($enc)]} { + # look for "isonnn" instead of "iso-nnn" or "iso_nnn" + if {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\1} encx]} { + set enc $encx + } + } + if {[info exists encoding_lookup_table($enc)]} { + return $encoding_lookup_table($enc) + } else { + return {} + } +} + +proc force_path_encoding {path enc} { + global path_encoding_overrides last_encoding_override + + set enc [tcl_encoding $enc] + if {$enc eq {}} { + catch { unset last_encoding_override } + catch { unset path_encoding_overrides($path) } + } else { + set last_encoding_override $enc + if {$path ne {}} { + set path_encoding_overrides($path) $enc + } + } +} + +proc get_path_encoding {path} { + global path_encoding_overrides last_encoding_override + + if {[info exists last_encoding_override]} { + set tcl_enc $last_encoding_override + } else { + set tcl_enc [tcl_encoding [get_config gui.encoding]] } - } - if {$i < 0} { - foreach l $encoding_aliases { - set ll [string tolower $l] - if {[lsearch -exact $ll $enc] < 0} continue - # look through the aliases for one that tcl knows about - foreach e $ll { - set i [lsearch -exact $lcnames $e] - if {$i < 0} { - if {[regsub {^iso[-_]} $e iso ex]} { - set i [lsearch -exact $lcnames $ex] - } + if {$tcl_enc eq {}} { + set tcl_enc [encoding system] + } + if {$path ne {}} { + if {[info exists path_encoding_overrides($path)]} { + set enc2 $path_encoding_overrides($path) + } else { + set enc2 [tcl_encoding [gitattr $path encoding $tcl_enc]] + } + if {$enc2 ne {}} { + set tcl_enc $enc2 + } + } + return $tcl_enc +} + +proc build_encoding_submenu {parent grp cmd} { + global used_encodings + + set mid [lindex $grp 0] + set gname [mc [lindex $grp 1]] + + set smenu {} + foreach subset [lrange $grp 2 end] { + set name [mc [lindex $subset 0]] + + foreach enc [lrange $subset 1 end] { + set tcl_enc [tcl_encoding $enc] + if {$tcl_enc eq {}} continue + + if {$smenu eq {}} { + if {$mid eq {}} { + set smenu $parent + } else { + set smenu "$parent.$mid" + menu $smenu + $parent add cascade \ + -label $gname \ + -menu $smenu + } + } + + if {$name ne {}} { + set lbl "$name ($enc)" + } else { + set lbl $enc + } + $smenu add command \ + -label $lbl \ + -command [concat $cmd [list $tcl_enc]] + + lappend used_encodings $tcl_enc + } + } +} + +proc popup_btn_menu {m b} { + tk_popup $m [winfo pointerx $b] [winfo pointery $b] +} + +proc build_encoding_menu {emenu cmd {nodef 0}} { + $emenu configure -postcommand \ + [list do_build_encoding_menu $emenu $cmd $nodef] +} + +proc do_build_encoding_menu {emenu cmd {nodef 0}} { + global used_encodings encoding_groups + + $emenu configure -postcommand {} + + if {!$nodef} { + $emenu add command \ + -label [mc "Default"] \ + -command [concat $cmd [list {}]] + } + set sysenc [encoding system] + $emenu add command \ + -label [mc "System (%s)" $sysenc] \ + -command [concat $cmd [list $sysenc]] + + # Main encoding tree + set used_encodings [list identity] + $emenu add separator + foreach grp $encoding_groups { + build_encoding_submenu $emenu $grp $cmd + } + + # Add unclassified encodings + set unused_grp [list [mc Other]] + foreach enc [encoding names] { + if {[lsearch -exact $used_encodings $enc] < 0} { + lappend unused_grp $enc } - if {$i >= 0} break - } - break } - } - if {$i >= 0} { - return [lindex $names $i] - } - return {} + build_encoding_submenu $emenu [list other [mc Other] $unused_grp] $cmd } diff --git a/git-gui/lib/index.tcl b/git-gui/lib/index.tcl index 3c1fce7475..b045219a1c 100644 --- a/git-gui/lib/index.tcl +++ b/git-gui/lib/index.tcl @@ -99,6 +99,7 @@ proc write_update_indexinfo {fd pathList totalCnt batch after} { switch -glob -- [lindex $s 0] { A? {set new _O} M? {set new _M} + T_ {set new _T} D_ {set new _D} D? {set new _?} ?? {continue} @@ -162,6 +163,8 @@ proc write_update_index {fd pathList totalCnt batch after} { ?D {set new D_} _O - AM {set new A_} + _T {set new T_} + _U - U? { if {[file exists $path]} { set new M_ @@ -231,6 +234,7 @@ proc write_checkout_index {fd pathList totalCnt batch after} { switch -glob -- [lindex $file_states($path) 0] { U? {continue} ?M - + ?T - ?D { puts -nonewline $fd "[encoding convertto $path]\0" display_file $path ?_ @@ -252,6 +256,7 @@ proc unstage_helper {txt paths} { switch -glob -- [lindex $file_states($path) 0] { A? - M? - + T_ - D? { lappend pathList $path if {$path eq $current_diff_path} { @@ -296,6 +301,7 @@ proc add_helper {txt paths} { _O - ?M - ?D - + ?T - U? { lappend pathList $path if {$path eq $current_diff_path} { @@ -336,6 +342,7 @@ proc do_add_all {} { switch -glob -- [lindex $file_states($path) 0] { U? {continue} ?M - + ?T - ?D {lappend paths $path} } } @@ -353,6 +360,7 @@ proc revert_helper {txt paths} { switch -glob -- [lindex $file_states($path) 0] { U? {continue} ?M - + ?T - ?D { lappend pathList $path if {$path eq $current_diff_path} { @@ -409,11 +417,11 @@ proc do_revert_selection {} { if {[array size selected_paths] > 0} { revert_helper \ - {Reverting selected files} \ + [mc "Reverting selected files"] \ [array names selected_paths] } elseif {$current_diff_path ne {}} { revert_helper \ - "Reverting [short_path $current_diff_path]" \ + [mc "Reverting %s" [short_path $current_diff_path]] \ [list $current_diff_path] } } diff --git a/git-gui/lib/mergetool.tcl b/git-gui/lib/mergetool.tcl new file mode 100644 index 0000000000..6ab5701d93 --- /dev/null +++ b/git-gui/lib/mergetool.tcl @@ -0,0 +1,400 @@ +# git-gui merge conflict resolution +# parts based on git-mergetool (c) 2006 Theodore Y. Ts'o + +proc merge_resolve_one {stage} { + global current_diff_path + + switch -- $stage { + 1 { set targetquestion [mc "Force resolution to the base version?"] } + 2 { set targetquestion [mc "Force resolution to this branch?"] } + 3 { set targetquestion [mc "Force resolution to the other branch?"] } + } + + set op_question [strcat $targetquestion "\n" \ +[mc "Note that the diff shows only conflicting changes. + +%s will be overwritten. + +This operation can be undone only by restarting the merge." \ + [short_path $current_diff_path]]] + + if {[ask_popup $op_question] eq {yes}} { + merge_load_stages $current_diff_path [list merge_force_stage $stage] + } +} + +proc merge_stage_workdir {path w lno} { + global current_diff_path diff_active + + if {$diff_active} return + + if {$path ne $current_diff_path} { + show_diff $path $w $lno {} [list do_merge_stage_workdir $path] + } else { + do_merge_stage_workdir $path + } +} + +proc do_merge_stage_workdir {path} { + global current_diff_path is_conflict_diff + + if {$path ne $current_diff_path} return; + + if {$is_conflict_diff} { + if {[ask_popup [mc "File %s seems to have unresolved conflicts, still stage?" \ + [short_path $path]]] ne {yes}} { + return + } + } + + merge_add_resolution $path +} + +proc merge_add_resolution {path} { + global current_diff_path ui_workdir + + set after [next_diff_after_action $ui_workdir $path {} {^_?U}] + + update_index \ + [mc "Adding resolution for %s" [short_path $path]] \ + [list $path] \ + [concat $after [list ui_ready]] +} + +proc merge_force_stage {stage} { + global current_diff_path merge_stages + + if {$merge_stages($stage) ne {}} { + git checkout-index -f --stage=$stage -- $current_diff_path + } else { + file delete -- $current_diff_path + } + + merge_add_resolution $current_diff_path +} + +proc merge_load_stages {path cont} { + global merge_stages_fd merge_stages merge_stages_buf + + if {[info exists merge_stages_fd]} { + catch { kill_file_process $merge_stages_fd } + catch { close $merge_stages_fd } + } + + set merge_stages(0) {} + set merge_stages(1) {} + set merge_stages(2) {} + set merge_stages(3) {} + set merge_stages_buf {} + + set merge_stages_fd [eval git_read ls-files -u -z -- $path] + + fconfigure $merge_stages_fd -blocking 0 -translation binary -encoding binary + fileevent $merge_stages_fd readable [list read_merge_stages $merge_stages_fd $cont] +} + +proc read_merge_stages {fd cont} { + global merge_stages_buf merge_stages_fd merge_stages + + append merge_stages_buf [read $fd] + set pck [split $merge_stages_buf "\0"] + set merge_stages_buf [lindex $pck end] + + if {[eof $fd] && $merge_stages_buf ne {}} { + lappend pck {} + set merge_stages_buf {} + } + + foreach p [lrange $pck 0 end-1] { + set fcols [split $p "\t"] + set cols [split [lindex $fcols 0] " "] + set stage [lindex $cols 2] + + set merge_stages($stage) [lrange $cols 0 1] + } + + if {[eof $fd]} { + close $fd + unset merge_stages_fd + eval $cont + } +} + +proc merge_resolve_tool {} { + global current_diff_path + + merge_load_stages $current_diff_path [list merge_resolve_tool2] +} + +proc merge_resolve_tool2 {} { + global current_diff_path merge_stages + + # Validate the stages + if {$merge_stages(2) eq {} || + [lindex $merge_stages(2) 0] eq {120000} || + [lindex $merge_stages(2) 0] eq {160000} || + $merge_stages(3) eq {} || + [lindex $merge_stages(3) 0] eq {120000} || + [lindex $merge_stages(3) 0] eq {160000} + } { + error_popup [mc "Cannot resolve deletion or link conflicts using a tool"] + return + } + + if {![file exists $current_diff_path]} { + error_popup [mc "Conflict file does not exist"] + return + } + + # Determine the tool to use + set tool [get_config merge.tool] + if {$tool eq {}} { set tool meld } + + set merge_tool_path [get_config "mergetool.$tool.path"] + if {$merge_tool_path eq {}} { + switch -- $tool { + emerge { set merge_tool_path "emacs" } + araxis { set merge_tool_path "compare" } + default { set merge_tool_path $tool } + } + } + + # Make file names + set filebase [file rootname $current_diff_path] + set fileext [file extension $current_diff_path] + set basename [lindex [file split $current_diff_path] end] + + set MERGED $current_diff_path + set BASE "./$MERGED.BASE$fileext" + set LOCAL "./$MERGED.LOCAL$fileext" + set REMOTE "./$MERGED.REMOTE$fileext" + set BACKUP "./$MERGED.BACKUP$fileext" + + set base_stage $merge_stages(1) + + # Build the command line + switch -- $tool { + kdiff3 { + if {$base_stage ne {}} { + set cmdline [list "$merge_tool_path" --auto --L1 "$MERGED (Base)" \ + --L2 "$MERGED (Local)" --L3 "$MERGED (Remote)" -o "$MERGED" "$BASE" "$LOCAL" "$REMOTE"] + } else { + set cmdline [list "$merge_tool_path" --auto --L1 "$MERGED (Local)" \ + --L2 "$MERGED (Remote)" -o "$MERGED" "$LOCAL" "$REMOTE"] + } + } + tkdiff { + if {$base_stage ne {}} { + set cmdline [list "$merge_tool_path" -a "$BASE" -o "$MERGED" "$LOCAL" "$REMOTE"] + } else { + set cmdline [list "$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"] + } + } + meld { + set cmdline [list "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"] + } + gvimdiff { + set cmdline [list "$merge_tool_path" -f "$LOCAL" "$MERGED" "$REMOTE"] + } + xxdiff { + if {$base_stage ne {}} { + set cmdline [list "$merge_tool_path" -X --show-merged-pane \ + -R {Accel.SaveAsMerged: "Ctrl-S"} \ + -R {Accel.Search: "Ctrl+F"} \ + -R {Accel.SearchForward: "Ctrl-G"} \ + --merged-file "$MERGED" "$LOCAL" "$BASE" "$REMOTE"] + } else { + set cmdline [list "$merge_tool_path" -X --show-merged-pane \ + -R {Accel.SaveAsMerged: "Ctrl-S"} \ + -R {Accel.Search: "Ctrl+F"} \ + -R {Accel.SearchForward: "Ctrl-G"} \ + --merged-file "$MERGED" "$LOCAL" "$REMOTE"] + } + } + opendiff { + if {$base_stage ne {}} { + set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$MERGED"] + } else { + set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" -merge "$MERGED"] + } + } + ecmerge { + if {$base_stage ne {}} { + set cmdline [list "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" --default --mode=merge3 --to="$MERGED"] + } else { + set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" --default --mode=merge2 --to="$MERGED"] + } + } + emerge { + if {$base_stage ne {}} { + set cmdline [list "$merge_tool_path" -f emerge-files-with-ancestor-command \ + "$LOCAL" "$REMOTE" "$BASE" "$basename"] + } else { + set cmdline [list "$merge_tool_path" -f emerge-files-command \ + "$LOCAL" "$REMOTE" "$basename"] + } + } + winmerge { + if {$base_stage ne {}} { + # This tool does not support 3-way merges. + # Use the 'conflict file' resolution feature instead. + set cmdline [list "$merge_tool_path" -e -ub "$MERGED"] + } else { + set cmdline [list "$merge_tool_path" -e -ub -wl \ + -dl "Theirs File" -dr "Mine File" "$REMOTE" "$LOCAL" "$MERGED"] + } + } + araxis { + if {$base_stage ne {}} { + set cmdline [list "$merge_tool_path" -wait -merge -3 -a1 \ + -title1:"'$MERGED (Base)'" -title2:"'$MERGED (Local)'" \ + -title3:"'$MERGED (Remote)'" \ + "$BASE" "$LOCAL" "$REMOTE" "$MERGED"] + } else { + set cmdline [list "$merge_tool_path" -wait -2 \ + -title1:"'$MERGED (Local)'" -title2:"'$MERGED (Remote)'" \ + "$LOCAL" "$REMOTE" "$MERGED"] + } + } + p4merge { + set cmdline [list "$merge_tool_path" "$BASE" "$REMOTE" "$LOCAL" "$MERGED"] + } + vimdiff { + error_popup [mc "Not a GUI merge tool: '%s'" $tool] + return + } + default { + error_popup [mc "Unsupported merge tool '%s'" $tool] + return + } + } + + merge_tool_start $cmdline $MERGED $BACKUP [list $BASE $LOCAL $REMOTE] +} + +proc delete_temp_files {files} { + foreach fname $files { + file delete $fname + } +} + +proc merge_tool_get_stages {target stages} { + global merge_stages + + set i 1 + foreach fname $stages { + if {$merge_stages($i) eq {}} { + file delete $fname + catch { close [open $fname w] } + } else { + # A hack to support autocrlf properly + git checkout-index -f --stage=$i -- $target + file rename -force -- $target $fname + } + incr i + } +} + +proc merge_tool_start {cmdline target backup stages} { + global merge_stages mtool_target mtool_tmpfiles mtool_fd mtool_mtime + + if {[info exists mtool_fd]} { + if {[ask_popup [mc "Merge tool is already running, terminate it?"]] eq {yes}} { + catch { kill_file_process $mtool_fd } + catch { close $mtool_fd } + unset mtool_fd + + set old_backup [lindex $mtool_tmpfiles end] + file rename -force -- $old_backup $mtool_target + delete_temp_files $mtool_tmpfiles + } else { + return + } + } + + # Save the original file + file rename -force -- $target $backup + + # Get the blobs; it destroys $target + if {[catch {merge_tool_get_stages $target $stages} err]} { + file rename -force -- $backup $target + delete_temp_files $stages + error_popup [mc "Error retrieving versions:\n%s" $err] + return + } + + # Restore the conflict file + file copy -force -- $backup $target + + # Initialize global state + set mtool_target $target + set mtool_mtime [file mtime $target] + set mtool_tmpfiles $stages + + lappend mtool_tmpfiles $backup + + # Force redirection to avoid interpreting output on stderr + # as an error, and launch the tool + lappend cmdline {2>@1} + + if {[catch { set mtool_fd [_open_stdout_stderr $cmdline] } err]} { + delete_temp_files $mtool_tmpfiles + error_popup [mc "Could not start the merge tool:\n\n%s" $err] + return + } + + ui_status [mc "Running merge tool..."] + + fconfigure $mtool_fd -blocking 0 -translation binary -encoding binary + fileevent $mtool_fd readable [list read_mtool_output $mtool_fd] +} + +proc read_mtool_output {fd} { + global mtool_fd mtool_tmpfiles + + read $fd + if {[eof $fd]} { + unset mtool_fd + + fconfigure $fd -blocking 1 + merge_tool_finish $fd + } +} + +proc merge_tool_finish {fd} { + global mtool_tmpfiles mtool_target mtool_mtime + + set backup [lindex $mtool_tmpfiles end] + set failed 0 + + # Check the return code + if {[catch {close $fd} err]} { + set failed 1 + if {$err ne {child process exited abnormally}} { + error_popup [strcat [mc "Merge tool failed."] "\n\n$err"] + } + } + + # Check the modification time of the target file + if {!$failed && [file mtime $mtool_target] eq $mtool_mtime} { + if {[ask_popup [mc "File %s unchanged, still accept as resolved?" \ + [short_path $mtool_target]]] ne {yes}} { + set failed 1 + } + } + + # Finish + if {$failed} { + file rename -force -- $backup $mtool_target + delete_temp_files $mtool_tmpfiles + ui_status [mc "Merge tool failed."] + } else { + if {[is_config_true merge.keepbackup]} { + file rename -force -- $backup "$mtool_target.orig" + } + + delete_temp_files $mtool_tmpfiles + + merge_add_resolution $mtool_target + } +} diff --git a/git-gui/lib/option.tcl b/git-gui/lib/option.tcl index ffb3f00ff0..c80c939878 100644 --- a/git-gui/lib/option.tcl +++ b/git-gui/lib/option.tcl @@ -1,6 +1,28 @@ # git-gui options editor # Copyright (C) 2006, 2007 Shawn Pearce +proc config_check_encodings {} { + global repo_config_new global_config_new + + set enc $global_config_new(gui.encoding) + if {$enc eq {}} { + set global_config_new(gui.encoding) [encoding system] + } elseif {[tcl_encoding $enc] eq {}} { + error_popup [mc "Invalid global encoding '%s'" $enc] + return 0 + } + + set enc $repo_config_new(gui.encoding) + if {$enc eq {}} { + set repo_config_new(gui.encoding) [encoding system] + } elseif {[tcl_encoding $enc] eq {}} { + error_popup [mc "Invalid repo encoding '%s'" $enc] + return 0 + } + + return 1 +} + proc save_config {} { global default_config font_descs global repo_config global_config @@ -119,15 +141,18 @@ proc do_options {} { {b merge.summary {mc "Summarize Merge Commits"}} {i-1..5 merge.verbosity {mc "Merge Verbosity"}} {b merge.diffstat {mc "Show Diffstat After Merge"}} + {t merge.tool {mc "Use Merge Tool"}} {b gui.trustmtime {mc "Trust File Modification Timestamps"}} {b gui.pruneduringfetch {mc "Prune Tracking Branches During Fetch"}} {b gui.matchtrackingbranch {mc "Match Tracking Branches"}} {b gui.fastcopyblame {mc "Blame Copy Only On Changed Files"}} {i-20..200 gui.copyblamethreshold {mc "Minimum Letters To Blame Copy On"}} - {i-0..99 gui.diffcontext {mc "Number of Diff Context Lines"}} + {i-0..300 gui.blamehistoryctx {mc "Blame History Context Radius (days)"}} + {i-1..99 gui.diffcontext {mc "Number of Diff Context Lines"}} {i-0..99 gui.commitmsgwidth {mc "Commit Message Text Width"}} {t gui.newbranchtemplate {mc "New Branch Name Template"}} + {c gui.encoding {mc "Default File Contents Encoding"}} } { set type [lindex $option 0] set name [lindex $option 1] @@ -157,6 +182,7 @@ proc do_options {} { pack $w.$f.$optid.v -side right -anchor e -padx 5 pack $w.$f.$optid -side top -anchor w -fill x } + c - t { frame $w.$f.$optid label $w.$f.$optid.l -text "$text:" @@ -169,6 +195,16 @@ proc do_options {} { pack $w.$f.$optid.v -side left -anchor w \ -fill x -expand 1 \ -padx 5 + if {$type eq {c}} { + menu $w.$f.$optid.m + build_encoding_menu $w.$f.$optid.m \ + [list set ${f}_config_new($name)] 1 + button $w.$f.$optid.b \ + -text [mc "Change"] \ + -command [list popup_btn_menu \ + $w.$f.$optid.m $w.$f.$optid.b] + pack $w.$f.$optid.b -side left -anchor w + } pack $w.$f.$optid -side top -anchor w -fill x } } @@ -273,6 +309,7 @@ proc do_restore_defaults {} { } proc do_save_config {w} { + if {![config_check_encodings]} return if {[catch {save_config} err]} { error_popup [strcat [mc "Failed to completely save options:"] "\n\n$err"] } diff --git a/git-gui/po/de.po b/git-gui/po/de.po index fa43947ad0..793cca1e79 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-08-02 08:58+0200\n" -"PO-Revision-Date: 2008-08-02 09:09+0200\n" +"POT-Creation-Date: 2008-09-13 10:20+0200\n" +"PO-Revision-Date: 2008-09-13 10:24+0200\n" "Last-Translator: Christian Stimming <stimming@tuhh.de>\n" "Language-Team: German\n" "MIME-Version: 1.0\n" @@ -110,7 +110,15 @@ msgstr "Teilweise bereitgestellt zum Eintragen" msgid "Staged for commit, missing" msgstr "Bereitgestellt zum Eintragen, fehlend" -#: git-gui.sh:1597 +#: git-gui.sh:1658 +msgid "File type changed, not staged" +msgstr "Dateityp geändert, nicht bereitgestellt" + +#: git-gui.sh:1659 +msgid "File type changed, staged" +msgstr "Dateityp geändert, bereitgestellt" + +#: git-gui.sh:1661 msgid "Untracked, not staged" msgstr "Nicht unter Versionskontrolle, nicht bereitgestellt" @@ -396,15 +404,7 @@ msgstr "Alle kopieren" msgid "File:" msgstr "Datei:" -#: git-gui.sh:2589 -msgid "Apply/Reverse Hunk" -msgstr "Kontext anwenden/umkehren" - -#: git-gui.sh:2696 -msgid "Apply/Reverse Line" -msgstr "Zeile anwenden/umkehren" - -#: git-gui.sh:2711 +#: git-gui.sh:2834 msgid "Refresh" msgstr "Aktualisieren" @@ -416,7 +416,35 @@ msgstr "Schriftgröße verkleinern" msgid "Increase Font Size" msgstr "Schriftgröße vergrößern" -#: git-gui.sh:2646 +#: git-gui.sh:2870 +msgid "Apply/Reverse Hunk" +msgstr "Kontext anwenden/umkehren" + +#: git-gui.sh:2875 +msgid "Apply/Reverse Line" +msgstr "Zeile anwenden/umkehren" + +#: git-gui.sh:2885 +msgid "Run Merge Tool" +msgstr "Zusammenführungswerkzeug" + +#: git-gui.sh:2890 +msgid "Use Remote Version" +msgstr "Entfernte Version benutzen" + +#: git-gui.sh:2894 +msgid "Use Local Version" +msgstr "Lokale Version benutzen" + +#: git-gui.sh:2898 +msgid "Revert To Base" +msgstr "Ursprüngliche Version benutzen" + +#: git-gui.sh:2906 +msgid "Stage Working Copy" +msgstr "Arbeitskopie bereitstellen" + +#: git-gui.sh:2925 msgid "Unstage Hunk From Commit" msgstr "Kontext aus Bereitstellung herausnehmen" @@ -498,7 +526,15 @@ msgstr "Version kopieren" msgid "Do Full Copy Detection" msgstr "Volle Kopie-Erkennung" -#: lib/blame.tcl:388 +#: lib/blame.tcl:263 +msgid "Show History Context" +msgstr "Historien-Kontext anzeigen" + +#: lib/blame.tcl:266 +msgid "Blame Parent Commit" +msgstr "Elternversion annotieren" + +#: lib/blame.tcl:394 #, tcl-format msgid "Reading %s..." msgstr "%s lesen..." @@ -547,7 +583,19 @@ msgstr "Eintragender:" msgid "Original File:" msgstr "Ursprüngliche Datei:" -#: lib/blame.tcl:925 +#: lib/blame.tcl:990 +msgid "Cannot find parent commit:" +msgstr "Elternversion kann nicht gefunden werden:" + +#: lib/blame.tcl:1001 +msgid "Unable to display parent" +msgstr "Elternversion kann nicht angezeigt werden" + +#: lib/blame.tcl:1002 lib/diff.tcl:191 +msgid "Error loading diff:" +msgstr "Fehler beim Laden des Vergleichs:" + +#: lib/blame.tcl:1142 msgid "Originally By:" msgstr "Ursprünglich von:" @@ -1494,11 +1542,7 @@ msgstr "Git-Projektarchiv (Unterprojekt)" msgid "* Binary file (not showing content)." msgstr "* Binärdatei (Inhalt wird nicht angezeigt)" -#: lib/diff.tcl:185 -msgid "Error loading diff:" -msgstr "Fehler beim Laden des Vergleichs:" - -#: lib/diff.tcl:303 +#: lib/diff.tcl:313 msgid "Failed to unstage selected hunk." msgstr "" "Fehler beim Herausnehmen des gewählten Kontexts aus der Bereitstellung." @@ -1586,6 +1630,15 @@ msgstr "" msgid "Do Nothing" msgstr "Nichts tun" +#: lib/index.tcl:419 +msgid "Reverting selected files" +msgstr "Änderungen in gewählten Dateien verwerfen" + +#: lib/index.tcl:423 +#, tcl-format +msgid "Reverting %s" +msgstr "Änderungen in %s verwerfen" + #: lib/merge.tcl:13 msgid "" "Cannot merge while amending.\n" @@ -1730,6 +1783,96 @@ msgstr "Abbruch fehlgeschlagen." msgid "Abort completed. Ready." msgstr "Abbruch durchgeführt. Bereit." +#: lib/mergetool.tcl:14 +msgid "Force resolution to the base version?" +msgstr "Konflikt durch Basisversion ersetzen?" + +#: lib/mergetool.tcl:15 +msgid "Force resolution to this branch?" +msgstr "Konflikt durch diesen Zweig ersetzen?" + +#: lib/mergetool.tcl:16 +msgid "Force resolution to the other branch?" +msgstr "Konflikt durch anderen Zweig ersetzen?" + +#: lib/mergetool.tcl:20 +#, 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 "" +"Hinweis: Der Vergleich zeigt nur konfliktverursachende Änderungen an.\n" +"\n" +"»%s« wird überschrieben.\n" +"\n" +"Diese Operation kann nur rückgängig gemacht werden, wenn die\n" +"Zusammenführung erneut gestartet wird." + +#: lib/mergetool.tcl:32 +#, tcl-format +msgid "Adding resolution for %s" +msgstr "Auflösung hinzugefügt für %s" + +#: lib/mergetool.tcl:119 +msgid "Cannot resolve deletion or link conflicts using a tool" +msgstr "" +"Konflikte durch gelöschte Dateien oder symbolische Links können nicht durch " +"das Zusamenführungswerkzeug gelöst werden." + +#: lib/mergetool.tcl:124 +msgid "Conflict file does not exist" +msgstr "Konflikt-Datei existiert nicht" + +#: lib/mergetool.tcl:236 +#, tcl-format +msgid "Not a GUI merge tool: '%s'" +msgstr "Kein GUI Zusammenführungswerkzeug: »%s«" + +#: lib/mergetool.tcl:240 +#, tcl-format +msgid "Unsupported merge tool '%s'" +msgstr "Unbekanntes Zusammenführungswerkzeug: »%s«" + +#: lib/mergetool.tcl:275 +msgid "Merge tool is already running, terminate it?" +msgstr "Zusammenführungswerkzeug läuft bereits. Soll es abgebrochen werden?" + +#: lib/mergetool.tcl:295 +#, tcl-format +msgid "" +"Error retrieving versions:\n" +"%s" +msgstr "" +"Fehler beim Abrufen der Dateiversionen:\n" +"%s" + +#: lib/mergetool.tcl:315 +#, tcl-format +msgid "" +"Could not start the merge tool:\n" +"\n" +"%s" +msgstr "" +"Zusammenführungswerkzeug konnte nicht gestartet werden:\n" +"\n" +"%s" + +#: lib/mergetool.tcl:319 +msgid "Running merge tool..." +msgstr "Zusammenführungswerkzeug starten..." + +#: lib/mergetool.tcl:347 lib/mergetool.tcl:363 +msgid "Merge tool failed." +msgstr "Zusammenführungswerkzeug fehlgeschlagen." + +#: lib/mergetool.tcl:353 +#, tcl-format +msgid "File %s unchanged, still accept as resolved?" +msgstr "Datei »%s« unverändert. Trotzdem Konflikt als gelöst akzeptieren?" + #: lib/option.tcl:95 msgid "Restore Defaults" msgstr "Voreinstellungen wiederherstellen" @@ -1767,7 +1910,11 @@ msgstr "Ausführlichkeit der Zusammenführen-Meldungen" msgid "Show Diffstat After Merge" msgstr "Vergleichsstatistik nach Zusammenführen anzeigen" -#: lib/option.tcl:123 +#: lib/option.tcl:122 +msgid "Use Merge Tool" +msgstr "Zusammenführungswerkzeug" + +#: lib/option.tcl:124 msgid "Trust File Modification Timestamps" msgstr "Auf Dateiänderungsdatum verlassen" @@ -1788,6 +1935,10 @@ msgid "Minimum Letters To Blame Copy On" msgstr "Mindestzahl Zeichen für Kopie-Annotieren" #: lib/option.tcl:128 +msgid "Blame History Context Radius (days)" +msgstr "Anzahl Tage für Historien-Kontext" + +#: lib/option.tcl:129 msgid "Number of Diff Context Lines" msgstr "Anzahl der Kontextzeilen beim Vergleich" diff --git a/git-gui/po/fr.po b/git-gui/po/fr.po index 89b6d51ea0..26b866f551 100644 --- a/git-gui/po/fr.po +++ b/git-gui/po/fr.po @@ -1,50 +1,51 @@ -# translation of fr.po to French +# translation of fr.po to Français # Translation of git-gui to French. # Copyright (C) 2008 Shawn Pearce, et al. # This file is distributed under the same license as the git package. # # Christian Couder <chriscool@tuxfamily.org>, 2008. +# Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>, 2008. msgid "" msgstr "" "Project-Id-Version: fr\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-03-14 07:18+0100\n" -"PO-Revision-Date: 2008-04-04 22:05+0200\n" -"Last-Translator: Christian Couder <chriscool@tuxfamily.org>\n" -"Language-Team: French\n" +"POT-Creation-Date: 2008-08-02 14:45-0700\n" +"PO-Revision-Date: 2008-08-11 17:12-0400\n" +"Last-Translator: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>\n" +"Language-Team: Français <fr@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: git-gui.sh:41 git-gui.sh:634 git-gui.sh:648 git-gui.sh:661 git-gui.sh:744 -#: git-gui.sh:763 +#: git-gui.sh:41 git-gui.sh:688 git-gui.sh:702 git-gui.sh:715 git-gui.sh:798 +#: git-gui.sh:817 msgid "git-gui: fatal error" msgstr "git-gui: erreur fatale" -#: git-gui.sh:593 +#: git-gui.sh:644 #, tcl-format msgid "Invalid font specified in %s:" -msgstr "Invalide fonte spécifiée dans %s :" +msgstr "Police invalide spécifiée dans %s :" -#: git-gui.sh:620 +#: git-gui.sh:674 msgid "Main Font" -msgstr "Fonte principale" +msgstr "Police principale" -#: git-gui.sh:621 +#: git-gui.sh:675 msgid "Diff/Console Font" -msgstr "Fonte diff/console" +msgstr "Police diff/console" -#: git-gui.sh:635 +#: git-gui.sh:689 msgid "Cannot find git in PATH." msgstr "Impossible de trouver git dans PATH." -#: git-gui.sh:662 +#: git-gui.sh:716 msgid "Cannot parse Git version string:" msgstr "Impossible de parser la version de Git :" -#: git-gui.sh:680 +#: git-gui.sh:734 #, tcl-format msgid "" "Git version cannot be determined.\n" @@ -63,378 +64,381 @@ msgstr "" "\n" "Peut'on considérer que '%s' est en version 1.5.0 ?\n" -#: git-gui.sh:918 +#: git-gui.sh:972 msgid "Git directory not found:" -msgstr "Impossible de trouver le répertoire de Git :" +msgstr "Impossible de trouver le répertoire git :" -#: git-gui.sh:925 +#: git-gui.sh:979 msgid "Cannot move to top of working directory:" msgstr "Impossible d'aller à la racine du répertoire de travail :" -#: git-gui.sh:932 +#: git-gui.sh:986 msgid "Cannot use funny .git directory:" -msgstr "Impossible d'utiliser un drôle de répertoire git :" +msgstr "Impossible d'utiliser le répertoire .git:" -#: git-gui.sh:937 +#: git-gui.sh:991 msgid "No working directory" -msgstr "Pas de répertoire de travail" +msgstr "Aucun répertoire de travail" -#: git-gui.sh:1084 lib/checkout_op.tcl:283 +#: git-gui.sh:1138 lib/checkout_op.tcl:305 msgid "Refreshing file status..." msgstr "Rafraichissement du status des fichiers..." -#: git-gui.sh:1149 +#: git-gui.sh:1194 msgid "Scanning for modified files ..." msgstr "Recherche de fichiers modifiés..." -#: git-gui.sh:1324 lib/browser.tcl:246 +#: git-gui.sh:1369 lib/browser.tcl:246 msgid "Ready." msgstr "Prêt." -#: git-gui.sh:1590 +#: git-gui.sh:1635 msgid "Unmodified" msgstr "Non modifié" -#: git-gui.sh:1592 +#: git-gui.sh:1637 msgid "Modified, not staged" -msgstr "Modifié, non pré-commité" +msgstr "Modifié, pas indexé" -#: git-gui.sh:1593 git-gui.sh:1598 +#: git-gui.sh:1638 git-gui.sh:1643 msgid "Staged for commit" -msgstr "Pré-commité" +msgstr "Indexé" -#: git-gui.sh:1594 git-gui.sh:1599 +#: git-gui.sh:1639 git-gui.sh:1644 msgid "Portions staged for commit" -msgstr "En partie pré-commité" +msgstr "Portions indexées" -#: git-gui.sh:1595 git-gui.sh:1600 +#: git-gui.sh:1640 git-gui.sh:1645 msgid "Staged for commit, missing" -msgstr "Pré-commité, manquant" +msgstr "Indexés, manquant" -#: git-gui.sh:1597 +#: git-gui.sh:1642 msgid "Untracked, not staged" -msgstr "Non suivi, non pré-commité" +msgstr "Non versionné, non indexé" -#: git-gui.sh:1602 +#: git-gui.sh:1647 msgid "Missing" msgstr "Manquant" -#: git-gui.sh:1603 +#: git-gui.sh:1648 msgid "Staged for removal" -msgstr "Pré-commité pour suppression" +msgstr "Indexé pour suppression" -#: git-gui.sh:1604 +#: git-gui.sh:1649 msgid "Staged for removal, still present" -msgstr "Pré-commité pour suppression, toujours présent" +msgstr "Indexé pour suppression, toujours présent" -#: git-gui.sh:1606 git-gui.sh:1607 git-gui.sh:1608 git-gui.sh:1609 +#: git-gui.sh:1651 git-gui.sh:1652 git-gui.sh:1653 git-gui.sh:1654 msgid "Requires merge resolution" msgstr "Nécessite la résolution d'une fusion" -#: git-gui.sh:1644 +#: git-gui.sh:1689 msgid "Starting gitk... please wait..." -msgstr "Lancement de gitk... merci de patienter..." +msgstr "Lancement de gitk... un instant..." -#: git-gui.sh:1653 -#, tcl-format -msgid "" -"Unable to start gitk:\n" -"\n" -"%s does not exist" -msgstr "" -"Impossible de lancer gitk :\n" -"\n" -"%s inexistant" +#: git-gui.sh:1698 +msgid "Couldn't find gitk in PATH" +msgstr "Impossible de trouver gitk dans PATH." -#: git-gui.sh:1860 lib/choose_repository.tcl:36 +#: git-gui.sh:1948 lib/choose_repository.tcl:36 msgid "Repository" -msgstr "Référentiel" +msgstr "Dépôt" -#: git-gui.sh:1861 +#: git-gui.sh:1949 msgid "Edit" -msgstr "Editer" +msgstr "Edition" -#: git-gui.sh:1863 lib/choose_rev.tcl:561 +#: git-gui.sh:1951 lib/choose_rev.tcl:561 msgid "Branch" msgstr "Branche" -#: git-gui.sh:1866 lib/choose_rev.tcl:548 +#: git-gui.sh:1954 lib/choose_rev.tcl:548 msgid "Commit@@noun" msgstr "Commit" -#: git-gui.sh:1869 lib/merge.tcl:120 lib/merge.tcl:149 lib/merge.tcl:167 +#: git-gui.sh:1957 lib/merge.tcl:120 lib/merge.tcl:149 lib/merge.tcl:167 msgid "Merge" msgstr "Fusionner" -#: git-gui.sh:1870 lib/choose_rev.tcl:557 +#: git-gui.sh:1958 lib/choose_rev.tcl:557 msgid "Remote" -msgstr "Référentiel distant" +msgstr "Dépôt distant" -#: git-gui.sh:1879 +#: git-gui.sh:1967 msgid "Browse Current Branch's Files" -msgstr "Visionner fichiers dans branche courante" +msgstr "Naviguer dans la branche courante" -#: git-gui.sh:1883 +#: git-gui.sh:1971 msgid "Browse Branch Files..." -msgstr "Visionner fichiers de branche" +msgstr "Naviguer dans la branche..." -#: git-gui.sh:1888 +#: git-gui.sh:1976 msgid "Visualize Current Branch's History" msgstr "Visualiser historique branche courante" -#: git-gui.sh:1892 +#: git-gui.sh:1980 msgid "Visualize All Branch History" -msgstr "Visualiser historique toutes branches" +msgstr "Voir l'historique de toutes les branches" -#: git-gui.sh:1899 +#: git-gui.sh:1987 #, tcl-format msgid "Browse %s's Files" -msgstr "Visionner fichiers de %s" +msgstr "Naviguer l'arborescence de %s" -#: git-gui.sh:1901 +#: git-gui.sh:1989 #, tcl-format msgid "Visualize %s's History" -msgstr "Visualiser historique de %s" +msgstr "Voir l'historique de la branche: %s" -#: git-gui.sh:1906 lib/database.tcl:27 lib/database.tcl:67 +#: git-gui.sh:1994 lib/database.tcl:27 lib/database.tcl:67 msgid "Database Statistics" -msgstr "Statistiques base de donnée" +msgstr "Statistiques du dépôt" -#: git-gui.sh:1909 lib/database.tcl:34 +#: git-gui.sh:1997 lib/database.tcl:34 msgid "Compress Database" -msgstr "Comprimer base de donnée" +msgstr "Comprimer le dépôt" -#: git-gui.sh:1912 +#: git-gui.sh:2000 msgid "Verify Database" -msgstr "Vérifier base de donnée" +msgstr "Vérifier le dépôt" -#: git-gui.sh:1919 git-gui.sh:1923 git-gui.sh:1927 lib/shortcut.tcl:7 +#: git-gui.sh:2007 git-gui.sh:2011 git-gui.sh:2015 lib/shortcut.tcl:7 #: lib/shortcut.tcl:39 lib/shortcut.tcl:71 msgid "Create Desktop Icon" msgstr "Créer icône sur bureau" -#: git-gui.sh:1932 lib/choose_repository.tcl:177 lib/choose_repository.tcl:185 +#: git-gui.sh:2023 lib/choose_repository.tcl:177 lib/choose_repository.tcl:185 msgid "Quit" msgstr "Quitter" -#: git-gui.sh:1939 +#: git-gui.sh:2031 msgid "Undo" msgstr "Défaire" -#: git-gui.sh:1942 +#: git-gui.sh:2034 msgid "Redo" msgstr "Refaire" -#: git-gui.sh:1946 git-gui.sh:2443 +#: git-gui.sh:2038 git-gui.sh:2545 msgid "Cut" msgstr "Couper" -#: git-gui.sh:1949 git-gui.sh:2446 git-gui.sh:2520 git-gui.sh:2614 +#: git-gui.sh:2041 git-gui.sh:2548 git-gui.sh:2622 git-gui.sh:2715 #: lib/console.tcl:69 msgid "Copy" msgstr "Copier" -#: git-gui.sh:1952 git-gui.sh:2449 +#: git-gui.sh:2044 git-gui.sh:2551 msgid "Paste" msgstr "Coller" -#: git-gui.sh:1955 git-gui.sh:2452 lib/branch_delete.tcl:26 +#: git-gui.sh:2047 git-gui.sh:2554 lib/branch_delete.tcl:26 #: lib/remote_branch_delete.tcl:38 msgid "Delete" msgstr "Supprimer" -#: git-gui.sh:1959 git-gui.sh:2456 git-gui.sh:2618 lib/console.tcl:71 +#: git-gui.sh:2051 git-gui.sh:2558 git-gui.sh:2719 lib/console.tcl:71 msgid "Select All" msgstr "Tout sélectionner" -#: git-gui.sh:1968 +#: git-gui.sh:2060 msgid "Create..." msgstr "Créer..." -#: git-gui.sh:1974 +#: git-gui.sh:2066 msgid "Checkout..." -msgstr "Emprunter... " +msgstr "Charger (checkout)..." -#: git-gui.sh:1980 +#: git-gui.sh:2072 msgid "Rename..." msgstr "Renommer..." -#: git-gui.sh:1985 git-gui.sh:2085 +#: git-gui.sh:2077 git-gui.sh:2187 msgid "Delete..." msgstr "Supprimer..." -#: git-gui.sh:1990 +#: git-gui.sh:2082 msgid "Reset..." msgstr "Réinitialiser..." -#: git-gui.sh:2002 git-gui.sh:2389 +#: git-gui.sh:2094 git-gui.sh:2491 msgid "New Commit" msgstr "Nouveau commit" -#: git-gui.sh:2010 git-gui.sh:2396 +#: git-gui.sh:2102 git-gui.sh:2498 msgid "Amend Last Commit" msgstr "Corriger dernier commit" -#: git-gui.sh:2019 git-gui.sh:2356 lib/remote_branch_delete.tcl:99 +#: git-gui.sh:2111 git-gui.sh:2458 lib/remote_branch_delete.tcl:99 msgid "Rescan" -msgstr "Resynchroniser" +msgstr "Recharger modifs." -#: git-gui.sh:2025 +#: git-gui.sh:2117 msgid "Stage To Commit" -msgstr "Commiter un pré-commit" +msgstr "Indexer" -#: git-gui.sh:2031 +#: git-gui.sh:2123 msgid "Stage Changed Files To Commit" -msgstr "Commiter fichiers modifiés dans pré-commit" +msgstr "Indexer toutes modifications" -#: git-gui.sh:2037 +#: git-gui.sh:2129 msgid "Unstage From Commit" -msgstr "Commit vers pré-commit" +msgstr "Désindexer" -#: git-gui.sh:2042 lib/index.tcl:395 +#: git-gui.sh:2134 lib/index.tcl:395 msgid "Revert Changes" -msgstr "Inverser modification" +msgstr "Annuler les modifications (revert)" -#: git-gui.sh:2049 git-gui.sh:2368 git-gui.sh:2467 +#: git-gui.sh:2141 git-gui.sh:2702 +msgid "Show Less Context" +msgstr "Montrer moins de contexte" + +#: git-gui.sh:2145 git-gui.sh:2706 +msgid "Show More Context" +msgstr "Montrer plus de contexte" + +#: git-gui.sh:2151 git-gui.sh:2470 git-gui.sh:2569 msgid "Sign Off" -msgstr "Se désinscrire" +msgstr "Signer" -#: git-gui.sh:2053 git-gui.sh:2372 +#: git-gui.sh:2155 git-gui.sh:2474 msgid "Commit@@verb" msgstr "Commiter" -#: git-gui.sh:2064 +#: git-gui.sh:2166 msgid "Local Merge..." msgstr "Fusion locale..." -#: git-gui.sh:2069 +#: git-gui.sh:2171 msgid "Abort Merge..." msgstr "Abandonner fusion..." -#: git-gui.sh:2081 +#: git-gui.sh:2183 msgid "Push..." msgstr "Pousser..." -#: git-gui.sh:2092 lib/choose_repository.tcl:41 -msgid "Apple" -msgstr "Pomme" - -#: git-gui.sh:2095 git-gui.sh:2117 lib/about.tcl:14 +#: git-gui.sh:2197 git-gui.sh:2219 lib/about.tcl:14 #: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50 #, tcl-format msgid "About %s" -msgstr "A propos de %s" +msgstr "À propos de %s" -#: git-gui.sh:2099 +#: git-gui.sh:2201 msgid "Preferences..." msgstr "Préférences..." -#: git-gui.sh:2107 git-gui.sh:2639 +#: git-gui.sh:2209 git-gui.sh:2740 msgid "Options..." msgstr "Options..." -#: git-gui.sh:2113 lib/choose_repository.tcl:47 +#: git-gui.sh:2215 lib/choose_repository.tcl:47 msgid "Help" msgstr "Aide" -#: git-gui.sh:2154 +#: git-gui.sh:2256 msgid "Online Documentation" msgstr "Documentation en ligne" -#: git-gui.sh:2238 +#: git-gui.sh:2340 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" -msgstr "erreur fatale : pas d'infos sur le chemin %s : Fichier ou répertoire inexistant" +msgstr "" +"erreur fatale : pas d'infos sur le chemin %s : Fichier ou répertoire " +"inexistant" -#: git-gui.sh:2271 +#: git-gui.sh:2373 msgid "Current Branch:" msgstr "Branche courante :" -#: git-gui.sh:2292 +#: git-gui.sh:2394 msgid "Staged Changes (Will Commit)" -msgstr "Modifications pré-commitées" +msgstr "Modifs. indexées (pour commit)" -#: git-gui.sh:2312 +#: git-gui.sh:2414 msgid "Unstaged Changes" -msgstr "Modifications non pré-commitées" +msgstr "Modifs. non indexées" -#: git-gui.sh:2362 +#: git-gui.sh:2464 msgid "Stage Changed" -msgstr "Pré-commit modifié" +msgstr "Indexer modifs." -#: git-gui.sh:2378 lib/transport.tcl:93 lib/transport.tcl:182 +#: git-gui.sh:2480 lib/transport.tcl:93 lib/transport.tcl:182 msgid "Push" msgstr "Pousser" -#: git-gui.sh:2408 +#: git-gui.sh:2510 msgid "Initial Commit Message:" msgstr "Message de commit initial :" -#: git-gui.sh:2409 +#: git-gui.sh:2511 msgid "Amended Commit Message:" msgstr "Message de commit corrigé :" -#: git-gui.sh:2410 +#: git-gui.sh:2512 msgid "Amended Initial Commit Message:" msgstr "Message de commit initial corrigé :" -#: git-gui.sh:2411 +#: git-gui.sh:2513 msgid "Amended Merge Commit Message:" msgstr "Message de commit de fusion corrigé :" -#: git-gui.sh:2412 +#: git-gui.sh:2514 msgid "Merge Commit Message:" msgstr "Message de commit de fusion :" -#: git-gui.sh:2413 +#: git-gui.sh:2515 msgid "Commit Message:" msgstr "Message de commit :" -#: git-gui.sh:2459 git-gui.sh:2622 lib/console.tcl:73 +#: git-gui.sh:2561 git-gui.sh:2723 lib/console.tcl:73 msgid "Copy All" msgstr "Copier tout" -#: git-gui.sh:2483 lib/blame.tcl:107 +#: git-gui.sh:2585 lib/blame.tcl:100 msgid "File:" msgstr "Fichier :" -#: git-gui.sh:2589 +#: git-gui.sh:2691 msgid "Apply/Reverse Hunk" msgstr "Appliquer/Inverser section" -#: git-gui.sh:2595 -msgid "Show Less Context" -msgstr "Montrer moins de contexte" - -#: git-gui.sh:2602 -msgid "Show More Context" -msgstr "Montrer plus de contexte" +#: git-gui.sh:2696 +msgid "Apply/Reverse Line" +msgstr "Appliquer/Inverser la ligne" -#: git-gui.sh:2610 +#: git-gui.sh:2711 msgid "Refresh" msgstr "Rafraichir" -#: git-gui.sh:2631 +#: git-gui.sh:2732 msgid "Decrease Font Size" -msgstr "Réduire fonte" +msgstr "Diminuer la police" -#: git-gui.sh:2635 +#: git-gui.sh:2736 msgid "Increase Font Size" -msgstr "Agrandir fonte" +msgstr "Agrandir la police" -#: git-gui.sh:2646 +#: git-gui.sh:2747 msgid "Unstage Hunk From Commit" -msgstr "Enlever section pré-commitée" +msgstr "Désindexer la section" + +#: git-gui.sh:2748 +msgid "Unstage Line From Commit" +msgstr "Désindexer la ligne" -#: git-gui.sh:2648 +#: git-gui.sh:2750 msgid "Stage Hunk For Commit" -msgstr "Pré-commiter section" +msgstr "Indexer la section" -#: git-gui.sh:2667 +#: git-gui.sh:2751 +msgid "Stage Line For Commit" +msgstr "Indexer la ligne" + +#: git-gui.sh:2771 msgid "Initializing..." msgstr "Initialisation..." -#: git-gui.sh:2762 +#: git-gui.sh:2876 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -451,7 +455,7 @@ msgstr "" "sous-processus de Git lancés par %s\n" "\n" -#: git-gui.sh:2792 +#: git-gui.sh:2906 msgid "" "\n" "This is due to a known issue with the\n" @@ -461,7 +465,7 @@ msgstr "" "Ceci est du à un problème connu avec\n" "le binaire Tcl distribué par Cygwin." -#: git-gui.sh:2797 +#: git-gui.sh:2911 #, tcl-format msgid "" "\n" @@ -482,78 +486,94 @@ msgstr "" msgid "git-gui - a graphical user interface for Git." msgstr "git-gui - une interface graphique utilisateur pour Git" -#: lib/blame.tcl:77 +#: lib/blame.tcl:70 msgid "File Viewer" msgstr "Visionneur de fichier" -#: lib/blame.tcl:81 +#: lib/blame.tcl:74 msgid "Commit:" msgstr "Commit :" -#: lib/blame.tcl:264 +#: lib/blame.tcl:257 msgid "Copy Commit" msgstr "Copier commit" -#: lib/blame.tcl:384 +#: lib/blame.tcl:260 +msgid "Do Full Copy Detection" +msgstr "Lancer la détection approfondie des copies" + +#: lib/blame.tcl:388 #, tcl-format msgid "Reading %s..." msgstr "Lecture de %s..." -#: lib/blame.tcl:488 +#: lib/blame.tcl:492 msgid "Loading copy/move tracking annotations..." msgstr "Chargement des annotations de suivi des copies/déplacements..." -#: lib/blame.tcl:508 +#: lib/blame.tcl:512 msgid "lines annotated" msgstr "lignes annotées" -#: lib/blame.tcl:689 +#: lib/blame.tcl:704 msgid "Loading original location annotations..." msgstr "Chargement des annotations d'emplacement original" -#: lib/blame.tcl:692 +#: lib/blame.tcl:707 msgid "Annotation complete." msgstr "Annotation terminée." -#: lib/blame.tcl:746 +#: lib/blame.tcl:737 +msgid "Busy" +msgstr "Occupé" + +#: lib/blame.tcl:738 +msgid "Annotation process is already running." +msgstr "Annotation en cours d'exécution." + +#: lib/blame.tcl:777 +msgid "Running thorough copy detection..." +msgstr "Recherche de copie approfondie en cours..." + +#: lib/blame.tcl:827 msgid "Loading annotation..." msgstr "Chargement des annotations..." -#: lib/blame.tcl:802 +#: lib/blame.tcl:883 msgid "Author:" msgstr "Auteur :" -#: lib/blame.tcl:806 +#: lib/blame.tcl:887 msgid "Committer:" msgstr "Commiteur :" -#: lib/blame.tcl:811 +#: lib/blame.tcl:892 msgid "Original File:" msgstr "Fichier original :" -#: lib/blame.tcl:925 +#: lib/blame.tcl:1006 msgid "Originally By:" msgstr "A l'origine par :" -#: lib/blame.tcl:931 +#: lib/blame.tcl:1012 msgid "In File:" msgstr "Dans le fichier :" -#: lib/blame.tcl:936 +#: lib/blame.tcl:1017 msgid "Copied Or Moved Here By:" msgstr "Copié ou déplacé ici par :" #: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19 msgid "Checkout Branch" -msgstr "Emprunter branche" +msgstr "Charger la branche (checkout)" #: lib/branch_checkout.tcl:23 msgid "Checkout" -msgstr "Emprunter" +msgstr "Charger (checkout)" #: 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:522 lib/choose_font.tcl:43 lib/merge.tcl:171 +#: lib/checkout_op.tcl:544 lib/choose_font.tcl:43 lib/merge.tcl:171 #: lib/option.tcl:103 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97 msgid "Cancel" msgstr "Annuler" @@ -562,17 +582,17 @@ msgstr "Annuler" msgid "Revision" msgstr "Révision" -#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:242 +#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:244 msgid "Options" msgstr "Options" #: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92 msgid "Fetch Tracking Branch" -msgstr "Branche suivant récupération" +msgstr "Récupérer la branche de suivi" #: lib/branch_checkout.tcl:44 msgid "Detach From Local Branch" -msgstr "Détacher de branche locale" +msgstr "Détacher de la branche locale" #: lib/branch_create.tcl:22 msgid "Create Branch" @@ -600,7 +620,7 @@ msgstr "Trouver nom de branche de suivi" #: lib/branch_create.tcl:66 msgid "Starting Revision" -msgstr "Début de révision" +msgstr "Révision initiale" #: lib/branch_create.tcl:72 msgid "Update Existing Branch:" @@ -612,28 +632,28 @@ msgstr "Non" #: lib/branch_create.tcl:80 msgid "Fast Forward Only" -msgstr "Avance rapide seulement" +msgstr "Mise-à-jour rectiligne seulement (fast-forward)" -#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514 +#: lib/branch_create.tcl:85 lib/checkout_op.tcl:536 msgid "Reset" msgstr "Réinitialiser" #: lib/branch_create.tcl:97 msgid "Checkout After Creation" -msgstr "Emprunt après création" +msgstr "Charger (checkout) après création" #: lib/branch_create.tcl:131 msgid "Please select a tracking branch." -msgstr "Merci de choisir une branche de suivi" +msgstr "Choisissez une branche de suivi" #: lib/branch_create.tcl:140 #, tcl-format msgid "Tracking branch %s is not a branch in the remote repository." -msgstr "La branche de suivi %s n'est pas une branche dans le référentiel distant." +msgstr "La branche de suivi %s n'est pas une branche dans le dépôt distant." #: lib/branch_create.tcl:153 lib/branch_rename.tcl:86 msgid "Please supply a branch name." -msgstr "Merci de fournir un nom de branche." +msgstr "Fournissez un nom de branche." #: lib/branch_create.tcl:164 lib/branch_rename.tcl:106 #, tcl-format @@ -654,7 +674,7 @@ msgstr "Branches locales" #: lib/branch_delete.tcl:52 msgid "Delete Only If Merged Into" -msgstr "Supprimer ssi fusion dedans" +msgstr "Supprimer seulement si fusionnée dans:" #: lib/branch_delete.tcl:54 msgid "Always (Do not perform merge test.)" @@ -704,7 +724,7 @@ msgstr "Nouveau nom :" msgid "Please select a branch to rename." msgstr "Merci de sélectionner une branche à renommer." -#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179 +#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:201 #, tcl-format msgid "Branch '%s' already exists." msgstr "La branche '%s' existe déjà." @@ -712,7 +732,7 @@ msgstr "La branche '%s' existe déjà." #: lib/branch_rename.tcl:117 #, tcl-format msgid "Failed to rename '%s'." -msgstr "Le renommage de '%s' a échoué." +msgstr "Échec pour renommer '%s'." #: lib/browser.tcl:17 msgid "Starting..." @@ -733,34 +753,39 @@ msgstr "[Jusqu'au parent]" #: lib/browser.tcl:267 lib/browser.tcl:273 msgid "Browse Branch Files" -msgstr "Visionner fichiers de branches" +msgstr "Naviguer dans les fichiers de le branche" #: lib/browser.tcl:278 lib/choose_repository.tcl:387 -#: lib/choose_repository.tcl:474 lib/choose_repository.tcl:484 -#: lib/choose_repository.tcl:987 +#: lib/choose_repository.tcl:472 lib/choose_repository.tcl:482 +#: lib/choose_repository.tcl:985 msgid "Browse" -msgstr "Visionner" +msgstr "Naviguer" -#: lib/checkout_op.tcl:79 +#: lib/checkout_op.tcl:84 #, tcl-format msgid "Fetching %s from %s" msgstr "Récupération de %s à partir de %s" -#: lib/checkout_op.tcl:127 +#: lib/checkout_op.tcl:132 #, tcl-format msgid "fatal: Cannot resolve %s" msgstr "erreur fatale : Impossible de résoudre %s" -#: lib/checkout_op.tcl:140 lib/console.tcl:81 lib/database.tcl:31 +#: lib/checkout_op.tcl:145 lib/console.tcl:81 lib/database.tcl:31 msgid "Close" msgstr "Fermer" -#: lib/checkout_op.tcl:169 +#: lib/checkout_op.tcl:174 #, tcl-format msgid "Branch '%s' does not exist." msgstr "La branche '%s' n'existe pas." -#: lib/checkout_op.tcl:206 +#: lib/checkout_op.tcl:193 +#, tcl-format +msgid "Failed to configure simplified git-pull for '%s'." +msgstr "Échec de la configuration simplifiée de git-pull pour '%s'." + +#: lib/checkout_op.tcl:228 #, tcl-format msgid "" "Branch '%s' already exists.\n" @@ -770,24 +795,24 @@ msgid "" msgstr "" "La branche '%s' existe déjà.\n" "\n" -"Impossible d'avancer rapidement à %s.\n" +"Impossible de faire une avance rapide (fast forward) vers %s.\n" "Une fusion est nécessaire." -#: lib/checkout_op.tcl:220 +#: lib/checkout_op.tcl:242 #, tcl-format msgid "Merge strategy '%s' not supported." msgstr "La stratégie de fusion '%s' n'est pas supportée." -#: lib/checkout_op.tcl:239 +#: lib/checkout_op.tcl:261 #, tcl-format msgid "Failed to update '%s'." msgstr "La mise à jour de '%s' a échouée." -#: lib/checkout_op.tcl:251 +#: lib/checkout_op.tcl:273 msgid "Staging area (index) is already locked." -msgstr "L'espace de pré-commit ('index' ou 'staging') est déjà vérouillé." +msgstr "L'index (staging area) est déjà vérouillé" -#: lib/checkout_op.tcl:266 +#: lib/checkout_op.tcl:288 msgid "" "Last scanned state does not match repository state.\n" "\n" @@ -796,36 +821,39 @@ msgid "" "\n" "The rescan will be automatically started now.\n" msgstr "" -"L'état lors de la dernière synchronisation ne correspond plus à l'état du référentiel.\n" +"L'état lors de la dernière synchronisation ne correspond plus à l'état du " +"dépôt\n" "\n" -"Un autre programme Git a modifié ce référentiel depuis la dernière synchronisation. Une resynchronisation doit être effectuée avant de pouvoir modifier la branche courante.\n" +"Un autre programme Git a modifié ce dépôt depuis la dernière " +"synchronisation. Une resynchronisation doit être effectuée avant de pouvoir " +"modifier la branche courante.\n" "\n" "Cela va être fait tout de suite automatiquement.\n" -#: lib/checkout_op.tcl:322 +#: lib/checkout_op.tcl:344 #, tcl-format msgid "Updating working directory to '%s'..." msgstr "Mise à jour du répertoire courant avec '%s'..." -#: lib/checkout_op.tcl:323 +#: lib/checkout_op.tcl:345 msgid "files checked out" -msgstr "fichiers empruntés" +msgstr "fichiers chargés" -#: lib/checkout_op.tcl:353 +#: lib/checkout_op.tcl:375 #, tcl-format msgid "Aborted checkout of '%s' (file level merging is required)." -msgstr "Emprunt de '%s' abandonné. (Il est nécessaire de fusionner des fichiers.)" +msgstr "Chargement de '%s' abandonné (il est nécessaire de fusionner des fichiers)." -#: lib/checkout_op.tcl:354 +#: lib/checkout_op.tcl:376 msgid "File level merge required." msgstr "Il est nécessaire de fusionner des fichiers." -#: lib/checkout_op.tcl:358 +#: lib/checkout_op.tcl:380 #, tcl-format msgid "Staying on branch '%s'." msgstr "Le répertoire de travail reste sur la branche '%s'." -#: lib/checkout_op.tcl:429 +#: lib/checkout_op.tcl:451 msgid "" "You are no longer on a local branch.\n" "\n" @@ -837,30 +865,30 @@ msgstr "" "Si vous vouliez être sur une branche, créez en une maintenant en partant de " "'Cet emprunt détaché'." -#: lib/checkout_op.tcl:446 lib/checkout_op.tcl:450 +#: lib/checkout_op.tcl:468 lib/checkout_op.tcl:472 #, tcl-format msgid "Checked out '%s'." -msgstr "'%s' emprunté." +msgstr "'%s' chargé." -#: lib/checkout_op.tcl:478 +#: lib/checkout_op.tcl:500 #, tcl-format msgid "Resetting '%s' to '%s' will lose the following commits:" msgstr "Réinitialiser '%s' à '%s' va faire perdre les commits suivants :" -#: lib/checkout_op.tcl:500 +#: lib/checkout_op.tcl:522 msgid "Recovering lost commits may not be easy." msgstr "Récupérer les commits perdus ne sera peut être pas facile." -#: lib/checkout_op.tcl:505 +#: lib/checkout_op.tcl:527 #, tcl-format msgid "Reset '%s'?" msgstr "Réinitialiser '%s' ?" -#: lib/checkout_op.tcl:510 lib/merge.tcl:163 +#: lib/checkout_op.tcl:532 lib/merge.tcl:163 msgid "Visualize" msgstr "Visualiser" -#: lib/checkout_op.tcl:578 +#: lib/checkout_op.tcl:600 #, tcl-format msgid "" "Failed to set current branch.\n" @@ -884,15 +912,15 @@ msgstr "Sélectionner" #: lib/choose_font.tcl:53 msgid "Font Family" -msgstr "Famille de fonte" +msgstr "Familles de polices" #: lib/choose_font.tcl:74 msgid "Font Size" -msgstr "Taille de fonte" +msgstr "Taille de police" #: lib/choose_font.tcl:91 msgid "Font Example" -msgstr "Exemple de fonte" +msgstr "Exemple de police" #: lib/choose_font.tcl:103 msgid "" @@ -900,7 +928,7 @@ msgid "" "If you like this text, it can be your font." msgstr "" "C'est un texte d'exemple.\n" -"Si vous aimez ce texte, vous pouvez choisir cette fonte." +"Si vous aimez ce texte, vous pouvez choisir cette police" #: lib/choose_repository.tcl:28 msgid "Git Gui" @@ -908,23 +936,23 @@ msgstr "Git Gui" #: lib/choose_repository.tcl:81 lib/choose_repository.tcl:376 msgid "Create New Repository" -msgstr "Créer nouveau référentiel" +msgstr "Créer nouveau dépôt" #: lib/choose_repository.tcl:87 msgid "New..." msgstr "Nouveau..." -#: lib/choose_repository.tcl:94 lib/choose_repository.tcl:460 +#: lib/choose_repository.tcl:94 lib/choose_repository.tcl:458 msgid "Clone Existing Repository" -msgstr "Cloner référentiel existant" +msgstr "Cloner dépôt existant" #: lib/choose_repository.tcl:100 msgid "Clone..." msgstr "Cloner..." -#: lib/choose_repository.tcl:107 lib/choose_repository.tcl:976 +#: lib/choose_repository.tcl:107 lib/choose_repository.tcl:974 msgid "Open Existing Repository" -msgstr "Ouvrir référentiel existant" +msgstr "Ouvrir dépôt existant" #: lib/choose_repository.tcl:113 msgid "Open..." @@ -932,202 +960,202 @@ msgstr "Ouvrir..." #: lib/choose_repository.tcl:126 msgid "Recent Repositories" -msgstr "Référentiels récents" +msgstr "Dépôt récemment utilisés" #: lib/choose_repository.tcl:132 msgid "Open Recent Repository:" -msgstr "Ouvrir référentiel récent :" +msgstr "Ouvrir dépôt récent :" #: lib/choose_repository.tcl:296 lib/choose_repository.tcl:303 #: lib/choose_repository.tcl:310 #, tcl-format msgid "Failed to create repository %s:" -msgstr "La création du référentiel %s a échouée :" +msgstr "La création du dépôt %s a échouée :" -#: lib/choose_repository.tcl:381 lib/choose_repository.tcl:478 +#: lib/choose_repository.tcl:381 lib/choose_repository.tcl:476 msgid "Directory:" msgstr "Répertoire :" -#: lib/choose_repository.tcl:412 lib/choose_repository.tcl:537 -#: lib/choose_repository.tcl:1011 +#: lib/choose_repository.tcl:410 lib/choose_repository.tcl:535 +#: lib/choose_repository.tcl:1007 msgid "Git Repository" -msgstr "Référentiel Git" +msgstr "Dépôt Git" -#: lib/choose_repository.tcl:437 +#: lib/choose_repository.tcl:435 #, tcl-format msgid "Directory %s already exists." msgstr "Le répertoire %s existe déjà." -#: lib/choose_repository.tcl:441 +#: lib/choose_repository.tcl:439 #, tcl-format msgid "File %s already exists." msgstr "Le fichier %s existe déjà." -#: lib/choose_repository.tcl:455 +#: lib/choose_repository.tcl:453 msgid "Clone" msgstr "Cloner" -#: lib/choose_repository.tcl:468 +#: lib/choose_repository.tcl:466 msgid "URL:" msgstr "URL :" -#: lib/choose_repository.tcl:489 +#: lib/choose_repository.tcl:487 msgid "Clone Type:" msgstr "Type de clonage :" -#: lib/choose_repository.tcl:495 +#: lib/choose_repository.tcl:493 msgid "Standard (Fast, Semi-Redundant, Hardlinks)" msgstr "Standard (rapide, semi-redondant, liens durs)" -#: lib/choose_repository.tcl:501 +#: lib/choose_repository.tcl:499 msgid "Full Copy (Slower, Redundant Backup)" msgstr "Copy complète (plus lent, sauvegarde redondante)" -#: lib/choose_repository.tcl:507 +#: lib/choose_repository.tcl:505 msgid "Shared (Fastest, Not Recommended, No Backup)" msgstr "Partagé (le plus rapide, non recommandé, pas de sauvegarde)" -#: lib/choose_repository.tcl:543 lib/choose_repository.tcl:590 -#: lib/choose_repository.tcl:736 lib/choose_repository.tcl:806 -#: lib/choose_repository.tcl:1017 lib/choose_repository.tcl:1025 +#: lib/choose_repository.tcl:541 lib/choose_repository.tcl:588 +#: lib/choose_repository.tcl:734 lib/choose_repository.tcl:804 +#: lib/choose_repository.tcl:1013 lib/choose_repository.tcl:1021 #, tcl-format msgid "Not a Git repository: %s" -msgstr "'%s' n'est pas un référentiel Git." +msgstr "'%s' n'est pas un dépôt Git." -#: lib/choose_repository.tcl:579 +#: lib/choose_repository.tcl:577 msgid "Standard only available for local repository." -msgstr "Standard n'est disponible que pour un référentiel local." +msgstr "Standard n'est disponible que pour un dépôt local." -#: lib/choose_repository.tcl:583 +#: lib/choose_repository.tcl:581 msgid "Shared only available for local repository." -msgstr "Partagé n'est disponible que pour un référentiel local." +msgstr "Partagé n'est disponible que pour un dépôt local." -#: lib/choose_repository.tcl:604 +#: lib/choose_repository.tcl:602 #, tcl-format msgid "Location %s already exists." msgstr "L'emplacement %s existe déjà." -#: lib/choose_repository.tcl:615 +#: lib/choose_repository.tcl:613 msgid "Failed to configure origin" msgstr "La configuration de l'origine a échouée." -#: lib/choose_repository.tcl:627 +#: lib/choose_repository.tcl:625 msgid "Counting objects" -msgstr "Comptage des objets" +msgstr "Décompte des objets" -#: lib/choose_repository.tcl:628 +#: lib/choose_repository.tcl:626 msgid "buckets" msgstr "paniers" -#: lib/choose_repository.tcl:652 +#: lib/choose_repository.tcl:650 #, tcl-format msgid "Unable to copy objects/info/alternates: %s" msgstr "Impossible de copier 'objects/info/alternates' : %s" -#: lib/choose_repository.tcl:688 +#: lib/choose_repository.tcl:686 #, tcl-format msgid "Nothing to clone from %s." msgstr "Il n'y a rien à cloner depuis %s." -#: lib/choose_repository.tcl:690 lib/choose_repository.tcl:904 -#: lib/choose_repository.tcl:916 +#: lib/choose_repository.tcl:688 lib/choose_repository.tcl:902 +#: lib/choose_repository.tcl:914 msgid "The 'master' branch has not been initialized." -msgstr "Cette branche 'master' n'a pas été initialisée." +msgstr "La branche 'master' n'a pas été initialisée." -#: lib/choose_repository.tcl:703 +#: lib/choose_repository.tcl:701 msgid "Hardlinks are unavailable. Falling back to copying." -msgstr "Les liens durs ne sont pas disponibles. On se résoud à copier." +msgstr "Les liens durs ne sont pas supportés. Une copie sera effectuée à la place." -#: lib/choose_repository.tcl:715 +#: lib/choose_repository.tcl:713 #, tcl-format msgid "Cloning from %s" msgstr "Clonage depuis %s" -#: lib/choose_repository.tcl:746 +#: lib/choose_repository.tcl:744 msgid "Copying objects" msgstr "Copie des objets" -#: lib/choose_repository.tcl:747 +#: lib/choose_repository.tcl:745 msgid "KiB" msgstr "KiB" -#: lib/choose_repository.tcl:771 +#: lib/choose_repository.tcl:769 #, tcl-format msgid "Unable to copy object: %s" msgstr "Impossible de copier l'objet : %s" -#: lib/choose_repository.tcl:781 +#: lib/choose_repository.tcl:779 msgid "Linking objects" msgstr "Liaison des objets" -#: lib/choose_repository.tcl:782 +#: lib/choose_repository.tcl:780 msgid "objects" msgstr "objets" -#: lib/choose_repository.tcl:790 +#: lib/choose_repository.tcl:788 #, tcl-format msgid "Unable to hardlink object: %s" msgstr "Impossible créer un lien dur pour l'objet : %s" -#: lib/choose_repository.tcl:845 +#: lib/choose_repository.tcl:843 msgid "Cannot fetch branches and objects. See console output for details." msgstr "" "Impossible de récupérer les branches et objets. Voir la sortie console pour " "plus de détails." -#: lib/choose_repository.tcl:856 +#: lib/choose_repository.tcl:854 msgid "Cannot fetch tags. See console output for details." msgstr "" -"Impossible de récupérer les marques. Voir la sortie console pour plus de " -"détails." +"Impossible de récupérer les marques (tags). Voir la sortie console pour plus " +"de détails." -#: lib/choose_repository.tcl:880 +#: lib/choose_repository.tcl:878 msgid "Cannot determine HEAD. See console output for details." msgstr "Impossible de déterminer HEAD. Voir la sortie console pour plus de détails." -#: lib/choose_repository.tcl:889 +#: lib/choose_repository.tcl:887 #, tcl-format msgid "Unable to cleanup %s" msgstr "Impossible de nettoyer %s" -#: lib/choose_repository.tcl:895 +#: lib/choose_repository.tcl:893 msgid "Clone failed." msgstr "Le clonage a échoué." -#: lib/choose_repository.tcl:902 +#: lib/choose_repository.tcl:900 msgid "No default branch obtained." msgstr "Aucune branche par défaut n'a été obtenue." -#: lib/choose_repository.tcl:913 +#: lib/choose_repository.tcl:911 #, tcl-format msgid "Cannot resolve %s as a commit." msgstr "Impossible de résoudre %s comme commit." -#: lib/choose_repository.tcl:925 +#: lib/choose_repository.tcl:923 msgid "Creating working directory" msgstr "Création du répertoire de travail" -#: lib/choose_repository.tcl:926 lib/index.tcl:65 lib/index.tcl:127 +#: lib/choose_repository.tcl:924 lib/index.tcl:65 lib/index.tcl:127 #: lib/index.tcl:193 msgid "files" msgstr "fichiers" -#: lib/choose_repository.tcl:955 +#: lib/choose_repository.tcl:953 msgid "Initial file checkout failed." -msgstr "L'emprunt initial de fichier a échoué." +msgstr "Chargement initial du fichier échoué." -#: lib/choose_repository.tcl:971 +#: lib/choose_repository.tcl:969 msgid "Open" msgstr "Ouvrir" -#: lib/choose_repository.tcl:981 +#: lib/choose_repository.tcl:979 msgid "Repository:" -msgstr "Référentiel :" +msgstr "Dépôt :" -#: lib/choose_repository.tcl:1031 +#: lib/choose_repository.tcl:1027 #, tcl-format msgid "Failed to open repository %s:" -msgstr "Impossible d'ouvrir le référentiel %s :" +msgstr "Impossible d'ouvrir le dépôt %s :" #: lib/choose_rev.tcl:53 msgid "This Detached Checkout" @@ -1143,11 +1171,11 @@ msgstr "Branche locale" #: lib/choose_rev.tcl:79 msgid "Tracking Branch" -msgstr "Suivi de branche" +msgstr "Branche de suivi" #: lib/choose_rev.tcl:84 lib/choose_rev.tcl:538 msgid "Tag" -msgstr "Marque" +msgstr "Marque (tag)" #: lib/choose_rev.tcl:317 #, tcl-format @@ -1164,7 +1192,7 @@ msgstr "L'expression de révision est vide." #: lib/choose_rev.tcl:531 msgid "Updated" -msgstr "Misa à jour" +msgstr "Mise-à-jour:" #: lib/choose_rev.tcl:559 msgid "URL" @@ -1218,9 +1246,9 @@ msgid "" "The rescan will be automatically started now.\n" msgstr "" "L'état lors de la dernière synchronisation ne correspond plus à l'état du " -"référentiel.\n" +"dépôt.\n" "\n" -"Un autre programme Git a modifié ce référentiel depuis la dernière " +"Un autre programme Git a modifié ce dépôt depuis la dernière " "synchronisation. Une resynshronisation doit être effectuée avant de pouvoir " "créer un nouveau commit.\n" "\n" @@ -1258,7 +1286,7 @@ msgid "" msgstr "" "Pas de modification à commiter.\n" "\n" -"Vous devez pré-commiter au moins 1 fichier avant de pouvoir commiter.\n" +"Vous devez indexer au moins 1 fichier avant de pouvoir commiter.\n" #: lib/commit.tcl:183 msgid "" @@ -1285,19 +1313,19 @@ msgstr "attention : Tcl ne supporte pas l'encodage '%s'." #: lib/commit.tcl:221 msgid "Calling pre-commit hook..." -msgstr "Appel du programme externe d'avant commit..." +msgstr "Lancement de l'action d'avant-commit..." #: lib/commit.tcl:236 msgid "Commit declined by pre-commit hook." -msgstr "Commit refusé par le programme externe d'avant commit." +msgstr "Commit refusé par l'action d'avant-commit." #: lib/commit.tcl:259 msgid "Calling commit-msg hook..." -msgstr "Appel du programme externe de message de commit..." +msgstr "Lancement de l'action \"message de commit\"..." #: lib/commit.tcl:274 msgid "Commit declined by commit-msg hook." -msgstr "Commit refusé par le programme externe de message de commit." +msgstr "Commit refusé par l'action \"message de commit\"." #: lib/commit.tcl:287 msgid "Committing changes..." @@ -1406,7 +1434,7 @@ msgid "" "\n" "Compress the database now?" msgstr "" -"Ce référentiel comprend actuellement environ %i objets ayant leur fichier " +"Ce dépôt comprend actuellement environ %i objets ayant leur fichier " "particulier.\n" "\n" "Pour conserver une performance optimale, il est fortement recommandé de " @@ -1420,7 +1448,7 @@ msgstr "" msgid "Invalid date from Git: %s" msgstr "Date invalide de Git : %s" -#: lib/diff.tcl:42 +#: lib/diff.tcl:44 #, tcl-format msgid "" "No differences detected.\n" @@ -1443,39 +1471,47 @@ msgstr "" "Une resynchronisation va être lancée automatiquement pour trouver d'autres " "fichiers qui pourraient se trouver dans le même état." -#: lib/diff.tcl:81 +#: lib/diff.tcl:83 #, tcl-format msgid "Loading diff of %s..." msgstr "Chargement des différences de %s..." -#: lib/diff.tcl:114 lib/diff.tcl:184 +#: lib/diff.tcl:116 lib/diff.tcl:190 #, tcl-format msgid "Unable to display %s" msgstr "Impossible d'afficher %s" -#: lib/diff.tcl:115 +#: lib/diff.tcl:117 msgid "Error loading file:" msgstr "Erreur lors du chargement du fichier :" -#: lib/diff.tcl:122 +#: lib/diff.tcl:124 msgid "Git Repository (subproject)" -msgstr "Référentiel Git (sous projet)" +msgstr "Dépôt Git (sous projet)" -#: lib/diff.tcl:134 +#: lib/diff.tcl:136 msgid "* Binary file (not showing content)." msgstr "* Fichier binaire (pas d'apperçu du contenu)." -#: lib/diff.tcl:185 +#: lib/diff.tcl:191 msgid "Error loading diff:" msgstr "Erreur lors du chargement des différences :" -#: lib/diff.tcl:303 +#: lib/diff.tcl:313 msgid "Failed to unstage selected hunk." -msgstr "La suppression dans le pré-commit de la section sélectionnée a échouée." +msgstr "Échec lors de la désindexation de la section sélectionnée." -#: lib/diff.tcl:310 +#: lib/diff.tcl:320 msgid "Failed to stage selected hunk." -msgstr "Le pré-commit de la section sélectionnée a échoué." +msgstr "Échec lors de l'indexation de la section." + +#: lib/diff.tcl:386 +msgid "Failed to unstage selected line." +msgstr "Échec lors de la désindexation de la ligne sélectionnée." + +#: lib/diff.tcl:394 +msgid "Failed to stage selected line." +msgstr "Échec lors de l'indexation de la ligne." #: lib/error.tcl:20 lib/error.tcl:114 msgid "error" @@ -1491,17 +1527,19 @@ msgstr "Vous devez corriger les erreurs suivantes avant de pouvoir commiter." #: lib/index.tcl:6 msgid "Unable to unlock the index." -msgstr "Impossible de dévérouiller le pré-commit." +msgstr "Impossible de dévérouiller l'index." #: lib/index.tcl:15 msgid "Index Error" -msgstr "Erreur de pré-commit" +msgstr "Erreur de l'index" #: lib/index.tcl:21 msgid "" "Updating the Git index failed. A rescan will be automatically started to " "resynchronize git-gui." -msgstr "Le pré-commit a échoué. Une resynchronisation va être lancée automatiquement." +msgstr "" +"Échec de la mise à jour de l'index. Une resynchronisation va être lancée " +"automatiquement." #: lib/index.tcl:27 msgid "Continue" @@ -1509,12 +1547,12 @@ msgstr "Continuer" #: lib/index.tcl:31 msgid "Unlock Index" -msgstr "Dévérouiller le pré-commit" +msgstr "Déverouiller l'index" #: lib/index.tcl:282 #, tcl-format msgid "Unstaging %s from commit" -msgstr "Supprimer %s du commit" +msgstr "Désindexation de: %s" #: lib/index.tcl:313 msgid "Ready to commit." @@ -1523,23 +1561,23 @@ msgstr "Prêt à être commité." #: lib/index.tcl:326 #, tcl-format msgid "Adding %s" -msgstr "Ajouter %s" +msgstr "Ajout de %s" #: lib/index.tcl:381 #, tcl-format msgid "Revert changes in file %s?" -msgstr "Inverser les modifications dans le fichier %s ? " +msgstr "Annuler les modifications dans le fichier %s ? " #: lib/index.tcl:383 #, tcl-format msgid "Revert changes in these %i files?" -msgstr "Inverser les modifications dans ces %i fichiers ?" +msgstr "Annuler les modifications dans ces %i fichiers ?" #: lib/index.tcl:391 msgid "Any unstaged changes will be permanently lost by the revert." msgstr "" -"Toutes les modifications non pré-commitées seront définitivement perdues " -"lors de l'inversion." +"Toutes les modifications non-indexées seront définitivement perdues par " +"l'annulation." #: lib/index.tcl:394 msgid "Do Nothing" @@ -1551,7 +1589,7 @@ msgid "" "\n" "You must finish amending this commit before starting any type of merge.\n" msgstr "" -"Impossible de fucionner pendant une correction.\n" +"Impossible de fusionner pendant une correction.\n" "\n" "Vous devez finir de corriger ce commit avant de lancer une quelconque " "fusion.\n" @@ -1566,9 +1604,9 @@ msgid "" "The rescan will be automatically started now.\n" msgstr "" "L'état lors de la dernière synchronisation ne correspond plus à l'état du " -"référentiel.\n" +"dépôt.\n" "\n" -"Un autre programme Git a modifié ce référentiel depuis la dernière " +"Un autre programme Git a modifié ce dépôt depuis la dernière " "synchronisation. Une resynchronisation doit être effectuée avant de pouvoir " "fusionner de nouveau.\n" "\n" @@ -1588,8 +1626,8 @@ msgstr "" "\n" "Le fichier %s a des conflicts de fusion.\n" "\n" -"Vous devez les résoudre, puis pré-commiter le fichier, et enfin commiter " -"pour terminer la fusion courante. Seulementà ce moment là, il sera possible " +"Vous devez les résoudre, puis indexer le fichier, et enfin commiter pour " +"terminer la fusion courante. Seulement à ce moment là sera-t-il possible " "d'effectuer une nouvelle fusion.\n" #: lib/merge.tcl:54 @@ -1685,11 +1723,11 @@ msgstr "Abandon" msgid "files reset" msgstr "fichiers réinitialisés" -#: lib/merge.tcl:265 +#: lib/merge.tcl:266 msgid "Abort failed." msgstr "L'abandon a échoué." -#: lib/merge.tcl:267 +#: lib/merge.tcl:268 msgid "Abort completed. Ready." msgstr "Abandon teminé. Prêt." @@ -1704,11 +1742,11 @@ msgstr "Sauvegarder" #: lib/option.tcl:109 #, tcl-format msgid "%s Repository" -msgstr "Référentiel de %s" +msgstr "Dépôt: %s" #: lib/option.tcl:110 msgid "Global (All Repositories)" -msgstr "Globales (tous les référentiels)" +msgstr "Globales (tous les dépôts)" #: lib/option.tcl:116 msgid "User Name" @@ -1736,56 +1774,76 @@ msgstr "Faire confiance aux dates de modification de fichiers " #: lib/option.tcl:124 msgid "Prune Tracking Branches During Fetch" -msgstr "Nettoyer les branches de suivi pendant la récupération" +msgstr "Purger les branches de suivi pendant la récupération" #: lib/option.tcl:125 msgid "Match Tracking Branches" msgstr "Faire correspondre les branches de suivi" #: lib/option.tcl:126 +msgid "Blame Copy Only On Changed Files" +msgstr "Annoter les copies seulement sur fichiers modifiés" + +#: lib/option.tcl:127 +msgid "Minimum Letters To Blame Copy On" +msgstr "Minimum de caratères pour annoter une copie" + +#: lib/option.tcl:128 msgid "Number of Diff Context Lines" msgstr "Nombre de lignes de contexte dans les diffs" -#: lib/option.tcl:127 +#: lib/option.tcl:129 msgid "Commit Message Text Width" msgstr "Largeur du texte de message de commit" -#: lib/option.tcl:128 +#: lib/option.tcl:130 msgid "New Branch Name Template" msgstr "Nouveau modèle de nom de branche" -#: lib/option.tcl:192 +#: lib/option.tcl:194 msgid "Spelling Dictionary:" msgstr "Dictionnaire d'orthographe :" -#: lib/option.tcl:216 +#: lib/option.tcl:218 msgid "Change Font" -msgstr "Modifier les fontes" +msgstr "Modifier les polices" -#: lib/option.tcl:220 +#: lib/option.tcl:222 #, tcl-format msgid "Choose %s" msgstr "Choisir %s" -#: lib/option.tcl:226 +#: lib/option.tcl:228 msgid "pt." msgstr "pt." -#: lib/option.tcl:240 +#: lib/option.tcl:242 msgid "Preferences" msgstr "Préférences" -#: lib/option.tcl:275 +#: lib/option.tcl:277 msgid "Failed to completely save options:" msgstr "La sauvegarde complète des options a échouée :" +#: lib/remote.tcl:165 +msgid "Prune from" +msgstr "Purger de" + +#: lib/remote.tcl:170 +msgid "Fetch from" +msgstr "Récupérer de" + +#: lib/remote.tcl:213 +msgid "Push to" +msgstr "Pousser vers" + #: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34 msgid "Delete Remote Branch" msgstr "Supprimer branche distante" #: lib/remote_branch_delete.tcl:47 msgid "From Repository" -msgstr "Référentiel" +msgstr "Dépôt source" #: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123 msgid "Remote:" @@ -1856,25 +1914,13 @@ msgstr "Supprimer les branches de %s" #: lib/remote_branch_delete.tcl:286 msgid "No repository selected." -msgstr "Aucun référentiel n'est sélectionné." +msgstr "Aucun dépôt n'est sélectionné." #: lib/remote_branch_delete.tcl:291 #, tcl-format msgid "Scanning %s..." msgstr "Synchronisation de %s..." -#: lib/remote.tcl:165 -msgid "Prune from" -msgstr "Nettoyer de" - -#: lib/remote.tcl:170 -msgid "Fetch from" -msgstr "Récupérer de" - -#: lib/remote.tcl:213 -msgid "Push to" -msgstr "Pousser vers" - #: lib/shortcut.tcl:20 lib/shortcut.tcl:61 msgid "Cannot write shortcut:" msgstr "Impossible d'écrire le raccourcis :" @@ -1908,15 +1954,15 @@ msgstr "La vérification d'orthographe a échouée silentieusement au démarrage msgid "Unrecognized spell checker" msgstr "Vérificateur d'orthographe non reconnu" -#: lib/spellcheck.tcl:180 +#: lib/spellcheck.tcl:186 msgid "No Suggestions" msgstr "Aucune suggestion" -#: lib/spellcheck.tcl:381 +#: lib/spellcheck.tcl:387 msgid "Unexpected EOF from spell checker" -msgstr "Fin de fichier innatendue envoyée par le vérificateur d'orthographe" +msgstr "EOF inattendue envoyée par le vérificateur d'orthographe" -#: lib/spellcheck.tcl:385 +#: lib/spellcheck.tcl:391 msgid "Spell Checker Failed" msgstr "Le vérificateur d'orthographe a échoué" @@ -1938,7 +1984,7 @@ msgstr "Récupération des dernières modifications de %s" #: lib/transport.tcl:18 #, tcl-format msgid "remote prune %s" -msgstr "nettoyer à distance %s" +msgstr "purger à distance %s" #: lib/transport.tcl:19 #, tcl-format @@ -1970,11 +2016,11 @@ msgstr "Branches source" #: lib/transport.tcl:120 msgid "Destination Repository" -msgstr "Référentiel de destination" +msgstr "Dépôt de destination" #: lib/transport.tcl:158 msgid "Transfer Options" -msgstr "Transférer options" +msgstr "Options de transfert" #: lib/transport.tcl:160 msgid "Force overwrite existing branch (may discard changes)" @@ -1988,5 +2034,5 @@ msgstr "Utiliser des petits paquets (pour les connexions lentes)" #: lib/transport.tcl:168 msgid "Include tags" -msgstr "Inclure les marques" +msgstr "Inclure les marques (tags)" diff --git a/git-gui/po/po2msg.sh b/git-gui/po/po2msg.sh index b7c4bf3fdf..1e9f992528 100644 --- a/git-gui/po/po2msg.sh +++ b/git-gui/po/po2msg.sh @@ -11,8 +11,8 @@ proc u2a {s} { foreach i [split $s ""] { scan $i %c c if {$c<128} { - # escape '[', '\' and ']' - if {$c == 0x5b || $c == 0x5d} { + # escape '[', '\', '$' and ']' + if {$c == 0x5b || $c == 0x5d || $c == 0x24} { append res "\\" } append res $i diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 929d681c47..edb6ec6ed0 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -284,7 +284,7 @@ do_next () { pick_one $sha1 || die_with_patch $sha1 "Could not apply $sha1... $rest" make_patch $sha1 - : > "$DOTEST"/amend + git rev-parse --verify HEAD > "$DOTEST"/amend warn "Stopped at $sha1... $rest" warn "You can amend the commit now, with" warn @@ -427,14 +427,22 @@ do else . "$DOTEST"/author-script || die "Cannot find the author identity" + amend= if test -f "$DOTEST"/amend then + amend=$(git rev-parse --verify HEAD) + test "$amend" = $(cat "$DOTEST"/amend) || + die "\ +You have uncommitted changes in your working tree. Please, commit them +first and then run 'git rebase --continue' again." git reset --soft HEAD^ || die "Cannot rewind the HEAD" fi export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE && - git commit --no-verify -F "$DOTEST"/message -e || - die "Could not commit staged changes." + git commit --no-verify -F "$DOTEST"/message -e || { + test -n "$amend" && git reset --soft $amend + die "Could not commit staged changes." + } fi require_clean_work_tree diff --git a/git-repack.sh b/git-repack.sh index 683960b04d..d39eb6cea6 100755 --- a/git-repack.sh +++ b/git-repack.sh @@ -10,7 +10,7 @@ git repack [options] a pack everything in a single pack A same as -a, and turn unreachable objects loose d remove redundant packs, and run git-prune-packed -f pass --no-reuse-delta to git-pack-objects +f pass --no-reuse-object to git-pack-objects n do not run git-update-server-info q,quiet be quiet l pass --local to git-pack-objects diff --git a/git-stash.sh b/git-stash.sh index e15c12abc3..6bd2572f77 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -39,6 +39,7 @@ clear_stash () { create_stash () { stash_msg="$1" + git update-index -q --refresh if no_changes then exit 0 @@ -101,6 +102,7 @@ save_stash () { stash_msg="$*" + git update-index -q --refresh if no_changes then echo 'No local changes to save' @@ -142,7 +144,14 @@ show_stash () { then flags=--stat fi - s=$(git rev-parse --revs-only --no-flags --default $ref_stash "$@") + + if test $# = 0 + then + set x "$ref_stash@{0}" + shift + fi + + s=$(git rev-parse --revs-only --no-flags "$@") w_commit=$(git rev-parse --verify "$s") && b_commit=$(git rev-parse --verify "$s^") && @@ -150,6 +159,7 @@ show_stash () { } apply_stash () { + git update-index -q --refresh && git diff-files --quiet --ignore-submodules || die 'Cannot restore on top of a dirty state' @@ -160,13 +170,19 @@ apply_stash () { shift esac + if test $# = 0 + then + set x "$ref_stash@{0}" + shift + fi + # current index state c_tree=$(git write-tree) || die 'Cannot apply a stash in the middle of a merge' # stash records the work tree, and is a merge between the # base commit (first parent) and the index tree (second parent). - s=$(git rev-parse --revs-only --no-flags --default $ref_stash "$@") && + s=$(git rev-parse --revs-only --no-flags "$@") && w_tree=$(git rev-parse --verify "$s:") && b_tree=$(git rev-parse --verify "$s^1:") && i_tree=$(git rev-parse --verify "$s^2:") || diff --git a/git-submodule.sh b/git-submodule.sh index 1c39b593a6..92be0feb58 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -634,6 +634,14 @@ cmd_sync() do name=$(module_name "$path") url=$(git config -f .gitmodules --get submodule."$name".url) + + # Possibly a url relative to parent + case "$url" in + ./*|../*) + url=$(resolve_relative_url "$url") || exit + ;; + esac + if test -e "$path"/.git then ( diff --git a/git-svn.perl b/git-svn.perl index 7a1d26db8b..80a5728371 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -421,15 +421,15 @@ sub cmd_dcommit { $head ||= 'HEAD'; my @refs; my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs); + unless ($gs) { + die "Unable to determine upstream SVN information from ", + "$head history.\nPerhaps the repository is empty."; + } $url = defined $_commit_url ? $_commit_url : $gs->full_url; my $last_rev = $_revision if defined $_revision; if ($url) { print "Committing to $url ...\n"; } - unless ($gs) { - die "Unable to determine upstream SVN information from ", - "$head history.\nPerhaps the repository is empty."; - } my ($linear_refs, $parents) = linearize_history($gs, \@refs); if ($_no_rebase && scalar(@$linear_refs) > 1) { warn "Attempting to commit more than one change while ", @@ -803,8 +803,28 @@ sub cmd_commit_diff { } } +sub escape_uri_only { + my ($uri) = @_; + my @tmp; + foreach (split m{/}, $uri) { + s/([^\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg; + push @tmp, $_; + } + join('/', @tmp); +} + +sub escape_url { + my ($url) = @_; + if ($url =~ m#^([^:]+)://([^/]*)(.*)$#) { + my ($scheme, $domain, $uri) = ($1, $2, escape_uri_only($3)); + $url = "$scheme://$domain$uri"; + } + $url; +} + sub cmd_info { my $path = canonicalize_path(defined($_[0]) ? $_[0] : "."); + my $fullpath = canonicalize_path($cmd_dir_prefix . $path); if (exists $_[1]) { die "Too many arguments specified\n"; } @@ -812,8 +832,8 @@ sub cmd_info { my ($file_type, $diff_status) = find_file_type_and_diff_status($path); if (!$file_type && !$diff_status) { - print STDERR "$path: (Not a versioned resource)\n\n"; - return; + print STDERR "svn: '$path' is not under version control\n"; + exit 1; } my ($url, $rev, $uuid, $gs) = working_head_info('HEAD'); @@ -825,21 +845,21 @@ sub cmd_info { # canonicalize_path() will return "" to make libsvn 1.5.x happy, $path = "." if $path eq ""; - my $full_url = $url . ($path eq "." ? "" : "/$path"); + my $full_url = $url . ($fullpath eq "" ? "" : "/$fullpath"); if ($_url) { - print $full_url, "\n"; + print escape_url($full_url), "\n"; return; } my $result = "Path: $path\n"; $result .= "Name: " . basename($path) . "\n" if $file_type ne "dir"; - $result .= "URL: " . $full_url . "\n"; + $result .= "URL: " . escape_url($full_url) . "\n"; eval { my $repos_root = $gs->repos_root; Git::SVN::remove_username($repos_root); - $result .= "Repository Root: $repos_root\n"; + $result .= "Repository Root: " . escape_url($repos_root) . "\n"; }; if ($@) { $result .= "Repository Root: (offline)\n"; @@ -861,7 +881,7 @@ sub cmd_info { } my ($lc_author, $lc_rev, $lc_date_utc); - my @args = Git::SVN::Log::git_svn_log_cmd($rev, $rev, "--", $path); + my @args = Git::SVN::Log::git_svn_log_cmd($rev, $rev, "--", $fullpath); my $log = command_output_pipe(@args); my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/; while (<$log>) { @@ -2606,9 +2626,9 @@ sub rebuild_from_rev_db { sub rebuild { my ($self) = @_; my $map_path = $self->map_path; - return if (-e $map_path && ! -z $map_path); + my $partial = (-e $map_path && ! -z $map_path); return unless ::verify_ref($self->refname.'^0'); - if ($self->use_svm_props || $self->no_metadata) { + if (!$partial && ($self->use_svm_props || $self->no_metadata)) { my $rev_db = $self->rev_db_path; $self->rebuild_from_rev_db($rev_db); if ($self->use_svm_props) { @@ -2618,10 +2638,13 @@ sub rebuild { $self->unlink_rev_db_symlink; return; } - print "Rebuilding $map_path ...\n"; + print "Rebuilding $map_path ...\n" if (!$partial); + my ($base_rev, $head) = ($partial ? $self->rev_map_max_norebuild(1) : + (undef, undef)); my ($log, $ctx) = command_output_pipe(qw/rev-list --pretty=raw --no-color --reverse/, - $self->refname, '--'); + ($head ? "$head.." : "") . $self->refname, + '--'); my $metadata_url = $self->metadata_url; remove_username($metadata_url); my $svn_uuid = $self->ra_uuid; @@ -2644,12 +2667,17 @@ sub rebuild { ($metadata_url && $url && ($url ne $metadata_url))) { next; } + if ($partial && $head) { + print "Partial-rebuilding $map_path ...\n"; + print "Currently at $base_rev = $head\n"; + $head = undef; + } $self->rev_map_set($rev, $c); print "r$rev = $c\n"; } command_close_pipe($log, $ctx); - print "Done rebuilding $map_path\n"; + print "Done rebuilding $map_path\n" if (!$partial || !$head); my $rev_db_path = $self->rev_db_path; if (-f $self->rev_db_path) { unlink $self->rev_db_path or croak "unlink: $!"; @@ -2789,6 +2817,12 @@ sub rev_map_set { sub rev_map_max { my ($self, $want_commit) = @_; $self->rebuild; + my ($r, $c) = $self->rev_map_max_norebuild($want_commit); + $want_commit ? ($r, $c) : $r; +} + +sub rev_map_max_norebuild { + my ($self, $want_commit) = @_; my $map_path = $self->map_path; stat $map_path or return $want_commit ? (0, undef) : 0; sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!"; @@ -3284,7 +3318,7 @@ sub close_file { my $out = syswrite($tmp_fh, $str, $res); defined($out) && $out == $res or croak("write ", - $tmp_fh->filename, + Git::temp_path($tmp_fh), ": $!\n"); } defined $res or croak $!; @@ -3295,7 +3329,7 @@ sub close_file { } $hash = $::_repository->hash_and_insert_object( - $fh->filename); + Git::temp_path($fh)); $hash =~ /^[a-f\d]{40}$/ or die "not a sha1: $hash\n"; Git::temp_release($fb->{base}, 1); @@ -3380,11 +3414,12 @@ sub generate_diff { while (<$diff_fh>) { chomp $_; # this gets rid of the trailing "\0" if ($state eq 'meta' && /^:(\d{6})\s(\d{6})\s - $::sha1\s($::sha1)\s + ($::sha1)\s($::sha1)\s ([MTCRAD])\d*$/xo) { push @mods, { mode_a => $1, mode_b => $2, - sha1_b => $3, chg => $4 }; - if ($4 =~ /^(?:C|R)$/) { + sha1_a => $3, sha1_b => $4, + chg => $5 }; + if ($5 =~ /^(?:C|R)$/) { $state = 'file_a'; } else { $state = 'file_b'; @@ -3636,6 +3671,7 @@ sub R { my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat, $self->url_path($m->{file_a}), $self->{r}); print "\tR\t$m->{file_a} => $m->{file_b}\n" unless $::_q; + $self->apply_autoprops($file, $fbat); $self->chg_file($fbat, $m); $self->close_file($fbat,undef,$self->{pool}); @@ -3662,33 +3698,52 @@ sub change_file_prop { $self->SUPER::change_file_prop($fbat, $pname, $pval, $self->{pool}); } -sub chg_file { - my ($self, $fbat, $m) = @_; - if ($m->{mode_b} =~ /755$/ && $m->{mode_a} !~ /755$/) { - $self->change_file_prop($fbat,'svn:executable','*'); - } elsif ($m->{mode_b} !~ /755$/ && $m->{mode_a} =~ /755$/) { - $self->change_file_prop($fbat,'svn:executable',undef); - } - my $fh = Git::temp_acquire('git_blob'); - if ($m->{mode_b} =~ /^120/) { +sub _chg_file_get_blob ($$$$) { + my ($self, $fbat, $m, $which) = @_; + my $fh = Git::temp_acquire("git_blob_$which"); + if ($m->{"mode_$which"} =~ /^120/) { print $fh 'link ' or croak $!; $self->change_file_prop($fbat,'svn:special','*'); - } elsif ($m->{mode_a} =~ /^120/ && $m->{mode_b} !~ /^120/) { + } elsif ($m->{mode_a} =~ /^120/ && $m->{"mode_$which"} !~ /^120/) { $self->change_file_prop($fbat,'svn:special',undef); } - my $size = $::_repository->cat_blob($m->{sha1_b}, $fh); - croak "Failed to read object $m->{sha1_b}" if ($size < 0); + my $blob = $m->{"sha1_$which"}; + return ($fh,) if ($blob =~ /^0{40}$/); + my $size = $::_repository->cat_blob($blob, $fh); + croak "Failed to read object $blob" if ($size < 0); $fh->flush == 0 or croak $!; seek $fh, 0, 0 or croak $!; my $exp = ::md5sum($fh); seek $fh, 0, 0 or croak $!; + return ($fh, $exp); +} +sub chg_file { + my ($self, $fbat, $m) = @_; + if ($m->{mode_b} =~ /755$/ && $m->{mode_a} !~ /755$/) { + $self->change_file_prop($fbat,'svn:executable','*'); + } elsif ($m->{mode_b} !~ /755$/ && $m->{mode_a} =~ /755$/) { + $self->change_file_prop($fbat,'svn:executable',undef); + } + my ($fh_a, $exp_a) = _chg_file_get_blob $self, $fbat, $m, 'a'; + my ($fh_b, $exp_b) = _chg_file_get_blob $self, $fbat, $m, 'b'; my $pool = SVN::Pool->new; - my $atd = $self->apply_textdelta($fbat, undef, $pool); - my $got = SVN::TxDelta::send_stream($fh, @$atd, $pool); - die "Checksum mismatch\nexpected: $exp\ngot: $got\n" if ($got ne $exp); - Git::temp_release($fh, 1); + my $atd = $self->apply_textdelta($fbat, $exp_a, $pool); + if (-s $fh_a) { + my $txstream = SVN::TxDelta::new ($fh_a, $fh_b, $pool); + my $res = SVN::TxDelta::send_txstream($txstream, @$atd, $pool); + if (defined $res) { + die "Unexpected result from send_txstream: $res\n", + "(SVN::Core::VERSION: $SVN::Core::VERSION)\n"; + } + } else { + my $got = SVN::TxDelta::send_stream($fh_b, @$atd, $pool); + die "Checksum mismatch\nexpected: $exp_b\ngot: $got\n" + if ($got ne $exp_b); + } + Git::temp_release($fh_b, 1); + Git::temp_release($fh_a, 1); $pool->clear; } @@ -3969,21 +4024,21 @@ sub gs_do_switch { my $old_url = $full_url; $full_url .= '/' . escape_uri_only($path) if length $path; my ($ra, $reparented); - if ($old_url ne $full_url) { - if ($old_url !~ m#^svn(\+ssh)?://#) { - SVN::_Ra::svn_ra_reparent($self->{session}, $full_url, - $pool); - $self->{url} = $full_url; - $reparented = 1; - } else { - $_[0] = undef; - $self = undef; - $RA = undef; - $ra = Git::SVN::Ra->new($full_url); - $ra_invalid = 1; - } + + if ($old_url =~ m#^svn(\+ssh)?://#) { + $_[0] = undef; + $self = undef; + $RA = undef; + $ra = Git::SVN::Ra->new($full_url); + $ra_invalid = 1; + } elsif ($old_url ne $full_url) { + SVN::_Ra::svn_ra_reparent($self->{session}, $full_url, $pool); + $self->{url} = $full_url; + $reparented = 1; } + $ra ||= $self; + $url_b = escape_url($url_b); my $reporter = $ra->do_switch($rev_b, '', 1, $url_b, $editor, $pool); my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : (); $reporter->set_path('', $rev_a, 0, @lock, $pool); @@ -4383,7 +4438,7 @@ sub config_pager { sub run_pager { return unless -t *STDOUT && defined $pager; - pipe my $rfd, my $wfd or return; + pipe my ($rfd, $wfd) or return; defined(my $pid = fork) or ::fatal "Can't fork: $!"; if (!$pid) { open STDOUT, '>&', $wfd or diff --git a/git-web--browse.sh b/git-web--browse.sh index 384148a59f..78d236b77f 100755 --- a/git-web--browse.sh +++ b/git-web--browse.sh @@ -31,7 +31,7 @@ valid_custom_tool() valid_tool() { case "$1" in - firefox | iceweasel | konqueror | w3m | links | lynx | dillo | open) + firefox | iceweasel | konqueror | w3m | links | lynx | dillo | open | start) ;; # happy *) valid_custom_tool "$1" || return 1 @@ -114,6 +114,10 @@ if test -z "$browser" ; then if test -n "$SECURITYSESSIONID"; then browser_candidates="open $browser_candidates" fi + # /bin/start indicates MinGW + if test -n /bin/start; then + browser_candidates="start $browser_candidates" + fi for i in $browser_candidates; do init_browser_path $i @@ -157,7 +161,7 @@ case "$browser" in ;; esac ;; - w3m|links|lynx|open) + w3m|links|lynx|open|start) eval "$browser_path" "$@" ;; dillo) @@ -162,6 +162,8 @@ static int handle_alias(int *argcp, const char ***argv) alias_string + 1, alias_command); } count = split_cmdline(alias_string, &new_argv); + if (count < 0) + die("Bad alias.%s string", alias_command); option_count = handle_options(&new_argv, &count, &envchanged); if (envchanged) die("alias '%s' changes environment variables\n" @@ -286,7 +288,7 @@ static void handle_internal_command(int argc, const char **argv) { "count-objects", cmd_count_objects, RUN_SETUP }, { "describe", cmd_describe, RUN_SETUP }, { "diff", cmd_diff }, - { "diff-files", cmd_diff_files, RUN_SETUP }, + { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE }, { "diff-index", cmd_diff_index, RUN_SETUP }, { "diff-tree", cmd_diff_tree, RUN_SETUP }, { "fast-export", cmd_fast_export, RUN_SETUP }, @@ -328,6 +330,7 @@ static void handle_internal_command(int argc, const char **argv) { "prune-packed", cmd_prune_packed, RUN_SETUP }, { "push", cmd_push, RUN_SETUP }, { "read-tree", cmd_read_tree, RUN_SETUP }, + { "receive-pack", cmd_receive_pack }, { "reflog", cmd_reflog, RUN_SETUP }, { "remote", cmd_remote, RUN_SETUP }, { "repo-config", cmd_config }, @@ -364,7 +367,7 @@ static void handle_internal_command(int argc, const char **argv) if (sizeof(ext) > 1) { i = strlen(argv[0]) - strlen(ext); if (i > 0 && !strcmp(argv[0] + i, ext)) { - char *argv0 = strdup(argv[0]); + char *argv0 = xstrdup(argv[0]); argv[0] = cmd = argv0; argv0[i] = '\0'; } @@ -499,7 +502,9 @@ int main(int argc, const char **argv) cmd, argv[0]); exit(1); } - help_unknown_cmd(cmd); + argv[0] = help_unknown_cmd(cmd); + handle_internal_command(argc, argv); + execv_dashed_external(argv); } fprintf(stderr, "Failed to run command '%s': %s\n", diff --git a/git.spec.in b/git.spec.in index c6492e5be2..6733b6f555 100644 --- a/git.spec.in +++ b/git.spec.in @@ -145,6 +145,7 @@ rm -rf $RPM_BUILD_ROOT %files cvs %defattr(-,root,root) %doc Documentation/*git-cvs*.txt +%{_bindir}/git-cvsserver %{_libexecdir}/git-core/*cvs* %{!?_without_docs: %{_mandir}/man1/*cvs*.1*} %{!?_without_docs: %doc Documentation/*git-cvs*.html } @@ -188,6 +189,9 @@ rm -rf $RPM_BUILD_ROOT # No files for you! %changelog +* Fri Sep 12 2008 Quy Tonthat <qtonthat@gmail.com> +- move git-cvsserver to bindir. + * Sun Jun 15 2008 Junio C Hamano <gitster@pobox.com> - Remove curl from Requires list. diff --git a/gitk-git/gitk b/gitk-git/gitk index 087c4ac733..2eaa2ae7d6 100644 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -418,10 +418,12 @@ proc stop_rev_list {view} { } proc reset_pending_select {selid} { - global pending_select mainheadid + global pending_select mainheadid selectheadid if {$selid ne {}} { set pending_select $selid + } elseif {$selectheadid ne {}} { + set pending_select $selectheadid } else { set pending_select $mainheadid } @@ -1609,6 +1611,7 @@ proc getcommit {id} { proc readrefs {} { global tagids idtags headids idheads tagobjid global otherrefids idotherrefs mainhead mainheadid + global selecthead selectheadid foreach v {tagids idtags headids idheads otherrefids idotherrefs} { catch {unset $v} @@ -1655,6 +1658,12 @@ proc readrefs {} { set mainhead [string range $thehead 11 end] } } + set selectheadid {} + if {$selecthead ne {}} { + catch { + set selectheadid [exec git rev-parse --verify $selecthead] + } + } } # skip over fake commits @@ -2205,6 +2214,8 @@ proc makewindow {} { -command {flist_hl 1} $flist_menu add command -label [mc "External diff"] \ -command {external_diff} + $flist_menu add command -label [mc "Blame parent commit"] \ + -command {external_blame 1} } # Windows sends all mouse wheel events to the current focused window, not @@ -3012,6 +3023,27 @@ proc external_diff {} { } } +proc external_blame {parent_idx} { + global flist_menu_file + global nullid nullid2 + global parentlist selectedline currentid + + if {$parent_idx > 0} { + set base_commit [lindex $parentlist $selectedline [expr {$parent_idx-1}]] + } else { + set base_commit $currentid + } + + if {$base_commit eq {} || $base_commit eq $nullid || $base_commit eq $nullid2} { + error_popup [mc "No such commit"] + return + } + + if {[catch {exec git gui blame $base_commit $flist_menu_file &} err]} { + error_popup [mc "git gui blame: command failed: $err"] + } +} + # delete $dir when we see eof on $f (presumably because the child has exited) proc delete_at_eof {f dir} { while {[gets $f line] >= 0} {} @@ -9865,6 +9897,9 @@ if {![file isdirectory $gitdir]} { exit 1 } +set selecthead {} +set selectheadid {} + set revtreeargs {} set cmdline_files {} set i 0 @@ -9876,6 +9911,9 @@ foreach arg $argv { set cmdline_files [lrange $argv [expr {$i + 1}] end] break } + "--select-commit=*" { + set selecthead [string range $arg 16 end] + } "--argscmd=*" { set revtreeargscmd [string range $arg 10 end] } @@ -9886,6 +9924,10 @@ foreach arg $argv { incr i } +if {$selecthead eq "HEAD"} { + set selecthead {} +} + if {$i >= [llength $argv] && $revtreeargs ne {}} { # no -- on command line, but some arguments (other than --argscmd) if {[catch { diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index aa0eeca247..07f5b53788 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -481,6 +481,19 @@ span.refs span { border-color: #ffccff #ff00ee #ff00ee #ffccff; } +span.refs span a { + text-decoration: none; + color: inherit; +} + +span.refs span a:hover { + text-decoration: underline; +} + +span.refs span.indirect { + font-style: italic; +} + span.refs span.ref { background-color: #aaaaff; border-color: #ccccff #0033cc #0033cc #ccccff; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 90cd99bf91..18e70a3663 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1090,13 +1090,23 @@ sub format_log_line_html { } # format marker of refs pointing to given object + +# the destination action is chosen based on object type and current context: +# - for annotated tags, we choose the tag view unless it's the current view +# already, in which case we go to shortlog view +# - for other refs, we keep the current view if we're in history, shortlog or +# log view, and select shortlog otherwise sub format_ref_marker { my ($refs, $id) = @_; my $markers = ''; if (defined $refs->{$id}) { foreach my $ref (@{$refs->{$id}}) { + # this code exploits the fact that non-lightweight tags are the + # only indirect objects, and that they are the only objects for which + # we want to use tag instead of shortlog as action my ($type, $name) = qw(); + my $indirect = ($ref =~ s/\^\{\}$//); # e.g. tags/v2.6.11 or heads/next if ($ref =~ m!^(.*?)s?/(.*)$!) { $type = $1; @@ -1106,8 +1116,29 @@ sub format_ref_marker { $name = $ref; } - $markers .= " <span class=\"$type\" title=\"$ref\">" . - esc_html($name) . "</span>"; + my $class = $type; + $class .= " indirect" if $indirect; + + my $dest_action = "shortlog"; + + if ($indirect) { + $dest_action = "tag" unless $action eq "tag"; + } elsif ($action =~ /^(history|(short)?log)$/) { + $dest_action = $action; + } + + my $dest = ""; + $dest .= "refs/" unless $ref =~ m!^refs/!; + $dest .= $ref; + + my $link = $cgi->a({ + -href => href( + action=>$dest_action, + hash=>$dest + )}, $name); + + $markers .= " <span class=\"$class\" title=\"$ref\">" . + $link . "</span>"; } } @@ -1918,7 +1949,7 @@ sub git_get_references { while (my $line = <$fd>) { chomp $line; - if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?[^^]+)!) { + if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type.*)$!) { if (defined $refs{$1}) { push @{$refs{$1}}, $2; } else { @@ -2092,7 +2123,7 @@ sub parse_commit_text { last; } } - if ($co{'title'} eq "") { + if (! defined $co{'title'} || $co{'title'} eq "") { $co{'title'} = $co{'title_short'} = '(no commit message)'; } # remove added spaces @@ -5467,7 +5498,11 @@ sub git_shortlog { } my $refs = git_get_references(); - my @commitlist = parse_commits($hash, 101, (100 * $page)); + my $commit_hash = $hash; + if (defined $hash_parent) { + $commit_hash = "$hash_parent..$hash"; + } + my @commitlist = parse_commits($commit_hash, 101, (100 * $page)); my $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, $#commitlist >= 100); my $next_link = ''; @@ -4,6 +4,43 @@ #include "diff.h" #include "revision.h" +/* Internal API */ + +/* + * Output the next line for a graph. + * This formats the next graph line into the specified strbuf. It is not + * terminated with a newline. + * + * Returns 1 if the line includes the current commit, and 0 otherwise. + * graph_next_line() will return 1 exactly once for each time + * graph_update() is called. + */ +static int graph_next_line(struct git_graph *graph, struct strbuf *sb); + +/* + * Output a padding line in the graph. + * This is similar to graph_next_line(). However, it is guaranteed to + * never print the current commit line. Instead, if the commit line is + * next, it will simply output a line of vertical padding, extending the + * branch lines downwards, but leaving them otherwise unchanged. + */ +static void graph_padding_line(struct git_graph *graph, struct strbuf *sb); + +/* + * Print a strbuf to stdout. If the graph is non-NULL, all lines but the + * first will be prefixed with the graph output. + * + * If the strbuf ends with a newline, the output will end after this + * newline. A new graph line will not be printed after the final newline. + * If the strbuf is empty, no output will be printed. + * + * Since the first line will not include the graph ouput, the caller is + * responsible for printing this line's graph (perhaps via + * graph_show_commit() or graph_show_oneline()) before calling + * graph_show_strbuf(). + */ +static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb); + /* * TODO: * - Add colors to the graph. @@ -180,14 +217,6 @@ struct git_graph *graph_init(struct rev_info *opt) return graph; } -void graph_release(struct git_graph *graph) -{ - free(graph->columns); - free(graph->new_columns); - free(graph->mapping); - free(graph); -} - static void graph_update_state(struct git_graph *graph, enum graph_state s) { graph->prev_state = graph->state; @@ -685,7 +714,7 @@ static void graph_output_commit_char(struct git_graph *graph, struct strbuf *sb) strbuf_addch(sb, '*'); } -void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb) +static void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb) { int seen_this = 0; int i, j; @@ -760,7 +789,7 @@ void graph_output_commit_line(struct git_graph *graph, struct strbuf *sb) graph_update_state(graph, GRAPH_COLLAPSING); } -void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb) +static void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb) { int seen_this = 0; int i, j; @@ -801,7 +830,7 @@ void graph_output_post_merge_line(struct git_graph *graph, struct strbuf *sb) graph_update_state(graph, GRAPH_COLLAPSING); } -void graph_output_collapsing_line(struct git_graph *graph, struct strbuf *sb) +static void graph_output_collapsing_line(struct git_graph *graph, struct strbuf *sb) { int i; int *tmp_mapping; @@ -906,7 +935,7 @@ void graph_output_collapsing_line(struct git_graph *graph, struct strbuf *sb) graph_update_state(graph, GRAPH_PADDING); } -int graph_next_line(struct git_graph *graph, struct strbuf *sb) +static int graph_next_line(struct git_graph *graph, struct strbuf *sb) { switch (graph->state) { case GRAPH_PADDING: @@ -933,7 +962,7 @@ int graph_next_line(struct git_graph *graph, struct strbuf *sb) return 0; } -void graph_padding_line(struct git_graph *graph, struct strbuf *sb) +static void graph_padding_line(struct git_graph *graph, struct strbuf *sb) { int i, j; @@ -1055,7 +1084,7 @@ int graph_show_remainder(struct git_graph *graph) } -void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb) +static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb) { char *p; @@ -11,11 +11,6 @@ struct git_graph; struct git_graph *graph_init(struct rev_info *opt); /* - * Destroy a struct git_graph and free associated memory. - */ -void graph_release(struct git_graph *graph); - -/* * Update a git_graph with a new commit. * This will cause the graph to begin outputting lines for the new commit * the next time graph_next_line() is called. @@ -27,26 +22,6 @@ void graph_release(struct git_graph *graph); void graph_update(struct git_graph *graph, struct commit *commit); /* - * Output the next line for a graph. - * This formats the next graph line into the specified strbuf. It is not - * terminated with a newline. - * - * Returns 1 if the line includes the current commit, and 0 otherwise. - * graph_next_line() will return 1 exactly once for each time - * graph_update() is called. - */ -int graph_next_line(struct git_graph *graph, struct strbuf *sb); - -/* - * Output a padding line in the graph. - * This is similar to graph_next_line(). However, it is guaranteed to - * never print the current commit line. Instead, if the commit line is - * next, it will simply output a line of vertical padding, extending the - * branch lines downwards, but leaving them otherwise unchanged. - */ -void graph_padding_line(struct git_graph *graph, struct strbuf *sb); - -/* * Determine if a graph has finished outputting lines for the current * commit. * @@ -90,21 +65,6 @@ void graph_show_padding(struct git_graph *graph); int graph_show_remainder(struct git_graph *graph); /* - * Print a strbuf to stdout. If the graph is non-NULL, all lines but the - * first will be prefixed with the graph output. - * - * If the strbuf ends with a newline, the output will end after this - * newline. A new graph line will not be printed after the final newline. - * If the strbuf is empty, no output will be printed. - * - * Since the first line will not include the graph ouput, the caller is - * responsible for printing this line's graph (perhaps via - * graph_show_commit() or graph_show_oneline()) before calling - * graph_show_strbuf(). - */ -void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb); - -/* * Print a commit message strbuf and the remainder of the graph to stdout. * * This is similar to graph_show_strbuf(), but it always prints the @@ -2,6 +2,19 @@ #include "grep.h" #include "xdiff-interface.h" +void append_header_grep_pattern(struct grep_opt *opt, enum grep_header_field field, const char *pat) +{ + struct grep_pat *p = xcalloc(1, sizeof(*p)); + p->pattern = pat; + p->origin = "header"; + p->no = 0; + p->token = GREP_PATTERN_HEAD; + p->field = field; + *opt->pattern_tail = p; + opt->pattern_tail = &p->next; + p->next = NULL; +} + void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t) { @@ -247,16 +260,53 @@ static int fixmatch(const char *pattern, char *line, regmatch_t *match) } } +static int strip_timestamp(char *bol, char **eol_p) +{ + char *eol = *eol_p; + int ch; + + while (bol < --eol) { + if (*eol != '>') + continue; + *eol_p = ++eol; + ch = *eol; + *eol = '\0'; + return ch; + } + return 0; +} + +static struct { + const char *field; + size_t len; +} header_field[] = { + { "author ", 7 }, + { "committer ", 10 }, +}; + static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol, enum grep_context ctx) { int hit = 0; int at_true_bol = 1; + int saved_ch = 0; regmatch_t pmatch[10]; if ((p->token != GREP_PATTERN) && ((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD))) return 0; + if (p->token == GREP_PATTERN_HEAD) { + const char *field; + size_t len; + assert(p->field < ARRAY_SIZE(header_field)); + field = header_field[p->field].field; + len = header_field[p->field].len; + if (strncmp(bol, field, len)) + return 0; + bol += len; + saved_ch = strip_timestamp(bol, &eol); + } + again: if (!opt->fixed) { regex_t *exp = &p->regexp; @@ -298,6 +348,8 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol goto again; } } + if (p->token == GREP_PATTERN_HEAD && saved_ch) + *eol = saved_ch; return hit; } @@ -17,12 +17,18 @@ enum grep_context { GREP_CONTEXT_BODY, }; +enum grep_header_field { + GREP_HEADER_AUTHOR = 0, + GREP_HEADER_COMMITTER, +}; + struct grep_pat { struct grep_pat *next; const char *origin; int no; enum grep_pat_token token; const char *pattern; + enum grep_header_field field; regex_t regexp; }; @@ -74,6 +80,7 @@ struct grep_opt { }; extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t); +extern void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *); extern void compile_grep_patterns(struct grep_opt *opt); extern void free_grep_patterns(struct grep_opt *opt); extern int grep_buffer(struct grep_opt *opt, const char *name, char *buf, unsigned long size); @@ -1,6 +1,7 @@ #include "cache.h" #include "builtin.h" #include "exec_cmd.h" +#include "levenshtein.h" #include "help.h" /* most GUI terminals set COLUMNS (although some don't export it) */ @@ -37,6 +38,16 @@ void add_cmdname(struct cmdnames *cmds, const char *name, int len) cmds->names[cmds->cnt++] = ent; } +static void clean_cmdnames(struct cmdnames *cmds) +{ + int i; + for (i = 0; i < cmds->cnt; ++i) + free(cmds->names[i]); + free(cmds->names); + cmds->cnt = 0; + cmds->alloc = 0; +} + static int cmdname_compare(const void *a_, const void *b_) { struct cmdname *a = *(struct cmdname **)a_; @@ -193,8 +204,8 @@ void load_command_list(const char *prefix, while (1) { if ((colon = strchr(path, PATH_SEP))) *colon = 0; - - list_commands_in_dir(other_cmds, path, prefix); + if (!exec_path || strcmp(path, exec_path)) + list_commands_in_dir(other_cmds, path, prefix); if (!colon) break; @@ -250,9 +261,101 @@ int is_in_cmdlist(struct cmdnames *c, const char *s) return 0; } -void help_unknown_cmd(const char *cmd) +static int autocorrect; +static struct cmdnames aliases; + +static int git_unknown_cmd_config(const char *var, const char *value, void *cb) +{ + if (!strcmp(var, "help.autocorrect")) + autocorrect = git_config_int(var,value); + /* Also use aliases for command lookup */ + if (!prefixcmp(var, "alias.")) + add_cmdname(&aliases, var + 6, strlen(var + 6)); + + return git_default_config(var, value, cb); +} + +static int levenshtein_compare(const void *p1, const void *p2) +{ + const struct cmdname *const *c1 = p1, *const *c2 = p2; + const char *s1 = (*c1)->name, *s2 = (*c2)->name; + int l1 = (*c1)->len; + int l2 = (*c2)->len; + return l1 != l2 ? l1 - l2 : strcmp(s1, s2); +} + +static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) { + int i; + ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc); + + for (i = 0; i < old->cnt; i++) + cmds->names[cmds->cnt++] = old->names[i]; + free(old->names); + old->cnt = 0; + old->names = NULL; +} + +const char *help_unknown_cmd(const char *cmd) +{ + int i, n, best_similarity = 0; + struct cmdnames main_cmds, other_cmds; + + memset(&main_cmds, 0, sizeof(main_cmds)); + memset(&other_cmds, 0, sizeof(main_cmds)); + memset(&aliases, 0, sizeof(aliases)); + + git_config(git_unknown_cmd_config, NULL); + + load_command_list("git-", &main_cmds, &other_cmds); + + add_cmd_list(&main_cmds, &aliases); + add_cmd_list(&main_cmds, &other_cmds); + qsort(main_cmds.names, main_cmds.cnt, + sizeof(main_cmds.names), cmdname_compare); + uniq(&main_cmds); + + /* This reuses cmdname->len for similarity index */ + for (i = 0; i < main_cmds.cnt; ++i) + main_cmds.names[i]->len = + levenshtein(cmd, main_cmds.names[i]->name, 0, 2, 1, 4); + + qsort(main_cmds.names, main_cmds.cnt, + sizeof(*main_cmds.names), levenshtein_compare); + + if (!main_cmds.cnt) + die ("Uh oh. Your system reports no Git commands at all."); + + best_similarity = main_cmds.names[0]->len; + n = 1; + while (n < main_cmds.cnt && best_similarity == main_cmds.names[n]->len) + ++n; + if (autocorrect && n == 1) { + const char *assumed = main_cmds.names[0]->name; + main_cmds.names[0] = NULL; + clean_cmdnames(&main_cmds); + fprintf(stderr, "WARNING: You called a Git program named '%s', " + "which does not exist.\n" + "Continuing under the assumption that you meant '%s'\n", + cmd, assumed); + if (autocorrect > 0) { + fprintf(stderr, "in %0.1f seconds automatically...\n", + (float)autocorrect/10.0); + poll(NULL, 0, autocorrect * 100); + } + return assumed; + } + fprintf(stderr, "git: '%s' is not a git-command. See 'git --help'.\n", cmd); + + if (best_similarity < 6) { + fprintf(stderr, "\nDid you mean %s?\n", + n < 2 ? "this": "one of these"); + + for (i = 0; i < n; i++) + fprintf(stderr, "\t%s\n", main_cmds.names[i]->name); + } + exit(1); } @@ -5,7 +5,7 @@ struct cmdnames { int alloc; int cnt; struct cmdname { - size_t len; + size_t len; /* also used for similarity index in help.c */ char name[FLEX_ARRAY]; } **names; }; diff --git a/http-push.c b/http-push.c index 6805288857..c9dd9a1f64 100644 --- a/http-push.c +++ b/http-push.c @@ -2237,7 +2237,7 @@ int main(int argc, char **argv) no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:"); if (remote->url && remote->url[strlen(remote->url)-1] != '/') { - rewritten_url = malloc(strlen(remote->url)+2); + rewritten_url = xmalloc(strlen(remote->url)+2); strcpy(rewritten_url, remote->url); strcat(rewritten_url, "/"); remote->url = rewritten_url; @@ -165,7 +165,16 @@ static CURL* get_curl_handle(void) { CURL* result = curl_easy_init(); - curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, curl_ssl_verify); + if (!curl_ssl_verify) { + curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 0); + } else { + /* Verify authenticity of the peer's certificate */ + curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, 1); + /* The name in the cert must match whom we tried to connect */ + curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2); + } + #if LIBCURL_VERSION_NUM >= 0x070907 curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); #endif @@ -402,7 +411,7 @@ static struct fill_chain *fill_cfg = NULL; void add_fill_function(void *data, int (*fill)(void *)) { - struct fill_chain *new = malloc(sizeof(*new)); + struct fill_chain *new = xmalloc(sizeof(*new)); struct fill_chain **linkp = &fill_cfg; new->data = data; new->fill = fill; diff --git a/index-pack.c b/index-pack.c index 728af7da9c..530d820370 100644 --- a/index-pack.c +++ b/index-pack.c @@ -172,7 +172,7 @@ static char *open_pack_file(char *pack_name) if (!pack_name) { static char tmpfile[PATH_MAX]; snprintf(tmpfile, sizeof(tmpfile), - "%s/tmp_pack_XXXXXX", get_object_directory()); + "%s/pack/tmp_pack_XXXXXX", get_object_directory()); output_fd = xmkstemp(tmpfile); pack_name = xstrdup(tmpfile); } else @@ -654,7 +654,7 @@ static void parse_pack_objects(unsigned char *sha1) } } -static int write_compressed(int fd, void *in, unsigned int size, uint32_t *obj_crc) +static int write_compressed(struct sha1file *f, void *in, unsigned int size) { z_stream stream; unsigned long maxsize; @@ -674,13 +674,12 @@ static int write_compressed(int fd, void *in, unsigned int size, uint32_t *obj_c deflateEnd(&stream); size = stream.total_out; - write_or_die(fd, out, size); - *obj_crc = crc32(*obj_crc, out, size); + sha1write(f, out, size); free(out); return size; } -static struct object_entry *append_obj_to_pack( +static struct object_entry *append_obj_to_pack(struct sha1file *f, const unsigned char *sha1, void *buf, unsigned long size, enum object_type type) { @@ -696,15 +695,15 @@ static struct object_entry *append_obj_to_pack( s >>= 7; } header[n++] = c; - write_or_die(output_fd, header, n); - obj[0].idx.crc32 = crc32(0, Z_NULL, 0); - obj[0].idx.crc32 = crc32(obj[0].idx.crc32, header, n); + crc32_begin(f); + sha1write(f, header, n); obj[0].size = size; obj[0].hdr_size = n; obj[0].type = type; obj[0].real_type = type; obj[1].idx.offset = obj[0].idx.offset + n; - obj[1].idx.offset += write_compressed(output_fd, buf, size, &obj[0].idx.crc32); + obj[1].idx.offset += write_compressed(f, buf, size); + obj[0].idx.crc32 = crc32_end(f); hashcpy(obj->idx.sha1, sha1); return obj; } @@ -716,7 +715,7 @@ static int delta_pos_compare(const void *_a, const void *_b) return a->obj_no - b->obj_no; } -static void fix_unresolved_deltas(int nr_unresolved) +static void fix_unresolved_deltas(struct sha1file *f, int nr_unresolved) { struct delta_entry **sorted_by_pos; int i, n = 0; @@ -754,8 +753,8 @@ static void fix_unresolved_deltas(int nr_unresolved) if (check_sha1_signature(d->base.sha1, base_obj.data, base_obj.size, typename(type))) die("local object %s is corrupt", sha1_to_hex(d->base.sha1)); - base_obj.obj = append_obj_to_pack(d->base.sha1, base_obj.data, - base_obj.size, type); + base_obj.obj = append_obj_to_pack(f, d->base.sha1, + base_obj.data, base_obj.size, type); link_base_data(NULL, &base_obj); find_delta_children(&d->base, &first, &last); @@ -875,7 +874,7 @@ int main(int argc, char **argv) const char *keep_name = NULL, *keep_msg = NULL; char *index_name_buf = NULL, *keep_name_buf = NULL; struct pack_idx_entry **idx_objects; - unsigned char sha1[20]; + unsigned char pack_sha1[20]; int nongit = 0; setup_git_directory_gently(&nongit); @@ -962,13 +961,15 @@ int main(int argc, char **argv) parse_pack_header(); objects = xmalloc((nr_objects + 1) * sizeof(struct object_entry)); deltas = xmalloc(nr_objects * sizeof(struct delta_entry)); - parse_pack_objects(sha1); + parse_pack_objects(pack_sha1); if (nr_deltas == nr_resolved_deltas) { stop_progress(&progress); /* Flush remaining pack final 20-byte SHA1. */ flush(); } else { if (fix_thin_pack) { + struct sha1file *f; + unsigned char read_sha1[20], tail_sha1[20]; char msg[48]; int nr_unresolved = nr_deltas - nr_resolved_deltas; int nr_objects_initial = nr_objects; @@ -977,12 +978,19 @@ int main(int argc, char **argv) objects = xrealloc(objects, (nr_objects + nr_unresolved + 1) * sizeof(*objects)); - fix_unresolved_deltas(nr_unresolved); + f = sha1fd(output_fd, curr_pack); + fix_unresolved_deltas(f, nr_unresolved); sprintf(msg, "completed with %d local objects", nr_objects - nr_objects_initial); stop_progress_msg(&progress, msg); - fixup_pack_header_footer(output_fd, sha1, - curr_pack, nr_objects); + sha1close(f, tail_sha1, 0); + hashcpy(read_sha1, pack_sha1); + fixup_pack_header_footer(output_fd, pack_sha1, + curr_pack, nr_objects, + read_sha1, consumed_bytes-20); + if (hashcmp(read_sha1, tail_sha1) != 0) + die("Unexpected tail checksum for %s " + "(disk corruption?)", curr_pack); } if (nr_deltas != nr_resolved_deltas) die("pack has %d unresolved deltas", @@ -995,13 +1003,13 @@ int main(int argc, char **argv) idx_objects = xmalloc((nr_objects) * sizeof(struct pack_idx_entry *)); for (i = 0; i < nr_objects; i++) idx_objects[i] = &objects[i].idx; - curr_index = write_idx_file(index_name, idx_objects, nr_objects, sha1); + curr_index = write_idx_file(index_name, idx_objects, nr_objects, pack_sha1); free(idx_objects); final(pack_name, curr_pack, index_name, curr_index, keep_name, keep_msg, - sha1); + pack_sha1); free(objects); free(index_name_buf); free(keep_name_buf); diff --git a/levenshtein.c b/levenshtein.c new file mode 100644 index 0000000000..db52f2c205 --- /dev/null +++ b/levenshtein.c @@ -0,0 +1,47 @@ +#include "cache.h" +#include "levenshtein.h" + +int levenshtein(const char *string1, const char *string2, + int w, int s, int a, int d) +{ + int len1 = strlen(string1), len2 = strlen(string2); + int *row0 = xmalloc(sizeof(int) * (len2 + 1)); + int *row1 = xmalloc(sizeof(int) * (len2 + 1)); + int *row2 = xmalloc(sizeof(int) * (len2 + 1)); + int i, j; + + for (j = 0; j <= len2; j++) + row1[j] = j * a; + for (i = 0; i < len1; i++) { + int *dummy; + + row2[0] = (i + 1) * d; + for (j = 0; j < len2; j++) { + /* substitution */ + row2[j + 1] = row1[j] + s * (string1[i] != string2[j]); + /* swap */ + if (i > 0 && j > 0 && string1[i - 1] == string2[j] && + string1[i] == string2[j - 1] && + row2[j + 1] > row0[j - 1] + w) + row2[j + 1] = row0[j - 1] + w; + /* deletion */ + if (j + 1 < len2 && row2[j + 1] > row1[j + 1] + d) + row2[j + 1] = row1[j + 1] + d; + /* insertion */ + if (row2[j + 1] > row2[j] + a) + row2[j + 1] = row2[j] + a; + } + + dummy = row0; + row0 = row1; + row1 = row2; + row2 = dummy; + } + + i = row1[len2]; + free(row0); + free(row1); + free(row2); + + return i; +} diff --git a/levenshtein.h b/levenshtein.h new file mode 100644 index 0000000000..0173abeef5 --- /dev/null +++ b/levenshtein.h @@ -0,0 +1,8 @@ +#ifndef LEVENSHTEIN_H +#define LEVENSHTEIN_H + +int levenshtein(const char *string1, const char *string2, + int swap_penalty, int substition_penalty, + int insertion_penalty, int deletion_penalty); + +#endif diff --git a/log-tree.c b/log-tree.c index 30cd5bb228..2c1f3e673a 100644 --- a/log-tree.c +++ b/log-tree.c @@ -1,12 +1,48 @@ #include "cache.h" #include "diff.h" #include "commit.h" +#include "tag.h" #include "graph.h" #include "log-tree.h" #include "reflog-walk.h" +#include "refs.h" struct decoration name_decoration = { "object names" }; +static void add_name_decoration(const char *prefix, const char *name, struct object *obj) +{ + int plen = strlen(prefix); + int nlen = strlen(name); + struct name_decoration *res = xmalloc(sizeof(struct name_decoration) + plen + nlen); + memcpy(res->name, prefix, plen); + memcpy(res->name + plen, name, nlen + 1); + res->next = add_decoration(&name_decoration, obj, res); +} + +static int add_ref_decoration(const char *refname, const unsigned char *sha1, int flags, void *cb_data) +{ + struct object *obj = parse_object(sha1); + if (!obj) + return 0; + add_name_decoration("", refname, obj); + while (obj->type == OBJ_TAG) { + obj = ((struct tag *)obj)->tagged; + if (!obj) + break; + add_name_decoration("tag: ", refname, obj); + } + return 0; +} + +void load_ref_decorations(void) +{ + static int loaded; + if (!loaded) { + loaded = 1; + for_each_ref(add_ref_decoration, NULL); + } +} + static void show_parents(struct commit *commit, int abbrev) { struct commit_list *p; diff --git a/log-tree.h b/log-tree.h index 59ba4c48b7..3c8127bb7c 100644 --- a/log-tree.h +++ b/log-tree.h @@ -17,5 +17,6 @@ void log_write_email_headers(struct rev_info *opt, const char *name, const char **subject_p, const char **extra_headers_p, int *need_8bit_cte_p); +void load_ref_decorations(void); #endif diff --git a/merge-index.c b/merge-index.c index 7491c56ad2..7827e87a92 100644 --- a/merge-index.c +++ b/merge-index.c @@ -27,7 +27,7 @@ static int merge_entry(int pos, const char *path) int found; if (pos >= active_nr) - die("git-merge-index: %s not in the cache", path); + die("git merge-index: %s not in the cache", path); arguments[0] = pgm; arguments[1] = ""; arguments[2] = ""; @@ -53,7 +53,7 @@ static int merge_entry(int pos, const char *path) arguments[stage + 4] = ownbuf[stage]; } while (++pos < active_nr); if (!found) - die("git-merge-index: %s not in the cache", path); + die("git merge-index: %s not in the cache", path); run_program(); return found; } @@ -117,7 +117,7 @@ int main(int argc, char **argv) merge_all(); continue; } - die("git-merge-index: unknown option %s", arg); + die("git merge-index: unknown option %s", arg); } merge_file(arg); } @@ -41,7 +41,18 @@ extern int type_from_string(const char *str); extern unsigned int get_max_object_index(void); extern struct object *get_indexed_object(unsigned int); -/** Internal only **/ +/* + * This can be used to see if we have heard of the object before, but + * it can return "yes we have, and here is a half-initialised object" + * for an object that we haven't loaded/parsed yet. + * + * When parsing a commit to create an in-core commit object, its + * parents list holds commit objects that represent its parents, but + * they are expected to be lazily initialized and do not know what + * their trees or parents are yet. When this function returns such a + * half-initialised objects, the caller is expected to initialize them + * by calling parse_object() on them. + */ struct object *lookup_object(const unsigned char *sha1); extern void *create_object(const unsigned char *sha1, int type, void *obj); diff --git a/pack-write.c b/pack-write.c index ddcfd37af2..3621f1dd32 100644 --- a/pack-write.c +++ b/pack-write.c @@ -45,7 +45,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/tmp_idx_XXXXXX", get_object_directory()); + "%s/pack/tmp_idx_XXXXXX", get_object_directory()); fd = xmkstemp(tmpfile); index_name = xstrdup(tmpfile); } else { @@ -144,41 +144,93 @@ char *write_idx_file(char *index_name, struct pack_idx_entry **objects, return index_name; } +/* + * Update pack header with object_count and compute new SHA1 for pack data + * associated to pack_fd, and write that SHA1 at the end. That new SHA1 + * is also returned in new_pack_sha1. + * + * If partial_pack_sha1 is non null, then the SHA1 of the existing pack + * (without the header update) is computed and validated against the + * one provided in partial_pack_sha1. The validation is performed at + * partial_pack_offset bytes in the pack file. The SHA1 of the remaining + * data (i.e. from partial_pack_offset to the end) is then computed and + * returned in partial_pack_sha1. + * + * Note that new_pack_sha1 is updated last, so both new_pack_sha1 and + * partial_pack_sha1 can refer to the same buffer if the caller is not + * interested in the resulting SHA1 of pack data above partial_pack_offset. + */ void fixup_pack_header_footer(int pack_fd, - unsigned char *pack_file_sha1, + unsigned char *new_pack_sha1, const char *pack_name, - uint32_t object_count) + uint32_t object_count, + unsigned char *partial_pack_sha1, + off_t partial_pack_offset) { - static const int buf_sz = 128 * 1024; - SHA_CTX c; + int aligned_sz, buf_sz = 8 * 1024; + SHA_CTX old_sha1_ctx, new_sha1_ctx; struct pack_header hdr; char *buf; + SHA1_Init(&old_sha1_ctx); + SHA1_Init(&new_sha1_ctx); + if (lseek(pack_fd, 0, SEEK_SET) != 0) - die("Failed seeking to start: %s", strerror(errno)); + die("Failed seeking to start of %s: %s", pack_name, strerror(errno)); if (read_in_full(pack_fd, &hdr, sizeof(hdr)) != sizeof(hdr)) die("Unable to reread header of %s: %s", pack_name, strerror(errno)); if (lseek(pack_fd, 0, SEEK_SET) != 0) - die("Failed seeking to start: %s", strerror(errno)); + die("Failed seeking to start of %s: %s", pack_name, strerror(errno)); + SHA1_Update(&old_sha1_ctx, &hdr, sizeof(hdr)); hdr.hdr_entries = htonl(object_count); + SHA1_Update(&new_sha1_ctx, &hdr, sizeof(hdr)); write_or_die(pack_fd, &hdr, sizeof(hdr)); - - SHA1_Init(&c); - SHA1_Update(&c, &hdr, sizeof(hdr)); + partial_pack_offset -= sizeof(hdr); buf = xmalloc(buf_sz); + aligned_sz = buf_sz - sizeof(hdr); for (;;) { - ssize_t n = xread(pack_fd, buf, buf_sz); + ssize_t m, n; + m = (partial_pack_sha1 && partial_pack_offset < aligned_sz) ? + partial_pack_offset : aligned_sz; + n = xread(pack_fd, buf, m); if (!n) break; if (n < 0) die("Failed to checksum %s: %s", pack_name, strerror(errno)); - SHA1_Update(&c, buf, n); + SHA1_Update(&new_sha1_ctx, buf, n); + + aligned_sz -= n; + if (!aligned_sz) + aligned_sz = buf_sz; + + if (!partial_pack_sha1) + continue; + + SHA1_Update(&old_sha1_ctx, buf, n); + partial_pack_offset -= n; + if (partial_pack_offset == 0) { + unsigned char sha1[20]; + SHA1_Final(sha1, &old_sha1_ctx); + if (hashcmp(sha1, partial_pack_sha1) != 0) + die("Unexpected checksum for %s " + "(disk corruption?)", pack_name); + /* + * Now let's compute the SHA1 of the remainder of the + * pack, which also means making partial_pack_offset + * big enough not to matter anymore. + */ + SHA1_Init(&old_sha1_ctx); + partial_pack_offset = ~partial_pack_offset; + partial_pack_offset -= MSB(partial_pack_offset, 1); + } } free(buf); - SHA1_Final(pack_file_sha1, &c); - write_or_die(pack_fd, pack_file_sha1, 20); + if (partial_pack_sha1) + SHA1_Final(partial_pack_sha1, &old_sha1_ctx); + SHA1_Final(new_pack_sha1, &new_sha1_ctx); + write_or_die(pack_fd, new_pack_sha1, 20); fsync_or_die(pack_fd, pack_name); } @@ -58,7 +58,7 @@ struct pack_idx_entry { extern char *write_idx_file(char *index_name, struct pack_idx_entry **objects, int nr_objects, unsigned char *sha1); extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr); extern int verify_pack(struct packed_git *); -extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t); +extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t, unsigned char *, off_t); extern char *index_pack_lockfile(int fd); #define PH_ERROR_EOF (-1) diff --git a/perl/Git.pm b/perl/Git.pm index 102e6a4ce3..6aab712e6a 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -58,7 +58,7 @@ require Exporter; command_bidi_pipe command_close_bidi_pipe version exec_path hash_object git_cmd_try remote_refs - temp_acquire temp_release temp_reset); + temp_acquire temp_release temp_reset temp_path); =head1 DESCRIPTION @@ -937,7 +937,7 @@ sub _close_cat_blob { { # %TEMP_* Lexical Context -my (%TEMP_LOCKS, %TEMP_FILES); +my (%TEMP_FILEMAP, %TEMP_FILES); =item temp_acquire ( NAME ) @@ -965,7 +965,7 @@ sub temp_acquire { my $temp_fd = _temp_cache($name); - $TEMP_LOCKS{$temp_fd} = 1; + $TEMP_FILES{$temp_fd}{locked} = 1; $temp_fd; } @@ -991,16 +991,16 @@ the same string. sub temp_release { my ($self, $temp_fd, $trunc) = _maybe_self(@_); - if (ref($temp_fd) ne 'File::Temp') { + if (exists $TEMP_FILEMAP{$temp_fd}) { $temp_fd = $TEMP_FILES{$temp_fd}; } - unless ($TEMP_LOCKS{$temp_fd}) { + unless ($TEMP_FILES{$temp_fd}{locked}) { carp "Attempt to release temp file '", $temp_fd, "' that has not been locked"; } temp_reset($temp_fd) if $trunc and $temp_fd->opened; - $TEMP_LOCKS{$temp_fd} = 0; + $TEMP_FILES{$temp_fd}{locked} = 0; undef; } @@ -1009,9 +1009,9 @@ sub _temp_cache { _verify_require(); - my $temp_fd = \$TEMP_FILES{$name}; + my $temp_fd = \$TEMP_FILEMAP{$name}; if (defined $$temp_fd and $$temp_fd->opened) { - if ($TEMP_LOCKS{$$temp_fd}) { + if ($TEMP_FILES{$$temp_fd}{locked}) { throw Error::Simple("Temp file with moniker '", $name, "' already in use"); } @@ -1021,12 +1021,13 @@ sub _temp_cache { carp "Temp file '", $name, "' was closed. Opening replacement."; } - $$temp_fd = File::Temp->new( - TEMPLATE => 'Git_XXXXXX', - DIR => File::Spec->tmpdir + my $fname; + ($$temp_fd, $fname) = File::Temp->tempfile( + 'Git_XXXXXX', UNLINK => 1 ) or throw Error::Simple("couldn't open new temp file"); $$temp_fd->autoflush; binmode $$temp_fd; + $TEMP_FILES{$$temp_fd}{fname} = $fname; } $$temp_fd; } @@ -1053,8 +1054,25 @@ sub temp_reset { or throw Error::Simple("expected file position to be reset"); } +=item temp_path ( NAME ) + +=item temp_path ( FILEHANDLE ) + +Returns the filename associated with the given tempfile. + +=cut + +sub temp_path { + my ($self, $temp_fd) = _maybe_self(@_); + + if (exists $TEMP_FILEMAP{$temp_fd}) { + $temp_fd = $TEMP_FILEMAP{$temp_fd}; + } + $TEMP_FILES{$temp_fd}{fname}; +} + sub END { - unlink values %TEMP_FILES if %TEMP_FILES; + unlink values %TEMP_FILEMAP if %TEMP_FILEMAP; } } # %TEMP_* Lexical Context @@ -5,6 +5,7 @@ #include "revision.h" #include "string-list.h" #include "mailmap.h" +#include "log-tree.h" static char *user_format; @@ -481,6 +482,23 @@ static void parse_commit_header(struct format_commit_context *context) context->commit_header_parsed = 1; } +static void format_decoration(struct strbuf *sb, const struct commit *commit) +{ + struct name_decoration *d; + const char *prefix = " ("; + + load_ref_decorations(); + d = lookup_decoration(&name_decoration, &commit->object); + while (d) { + strbuf_addstr(sb, prefix); + prefix = ", "; + strbuf_addstr(sb, d->name); + d = d->next; + } + if (prefix[0] == ',') + strbuf_addch(sb, ')'); +} + static size_t format_commit_item(struct strbuf *sb, const char *placeholder, void *context) { @@ -573,6 +591,9 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder, ? '<' : '>'); return 1; + case 'd': + format_decoration(sb, commit); + return 1; } /* For the rest we have to parse the commit header. */ diff --git a/read-cache.c b/read-cache.c index 5150c1e14b..5b1b3ad03b 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1253,6 +1253,7 @@ int discard_index(struct index_state *istate) istate->cache_nr = 0; istate->cache_changed = 0; istate->timestamp = 0; + istate->name_hash_initialized = 0; free_hash(&istate->name_hash); cache_tree_free(&(istate->cache_tree)); free(istate->alloc); @@ -390,6 +390,18 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *re return retval; } +/* + * If the "reading" argument is set, this function finds out what _object_ + * the ref points at by "reading" the ref. The ref, if it is not symbolic, + * has to exist, and if it is symbolic, it has to point at an existing ref, + * because the "read" goes through the symref to the ref it points at. + * + * The access that is not "reading" may often be "writing", but does not + * have to; it can be merely checking _where it leads to_. If it is a + * prelude to "writing" to the ref, a write to a symref that points at + * yet-to-be-born ref will create the real ref pointed by the symref. + * reading=0 allows the caller to check where such a symref leads to. + */ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *flag) { int depth = MAXDEPTH; @@ -409,13 +421,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int * if (--depth < 0) return NULL; - /* Special case: non-existing file. - * Not having the refs/heads/new-branch is OK - * if we are writing into it, so is .git/HEAD - * that points at refs/heads/master still to be - * born. It is NOT OK if we are resolving for - * reading. - */ + /* Special case: non-existing file. */ if (lstat(path, &st) < 0) { struct ref_list *list = get_packed_refs(); while (list) { @@ -69,7 +69,7 @@ static const char *alias_url(const char *url) if (!longest) return url; - ret = malloc(rewrite[longest_i]->baselen + + ret = xmalloc(rewrite[longest_i]->baselen + (strlen(url) - longest->len) + 1); strcpy(ret, rewrite[longest_i]->base); strcpy(ret + rewrite[longest_i]->baselen, url + longest->len); @@ -152,7 +152,7 @@ static struct branch *make_branch(const char *name, int len) ret->name = xstrndup(name, len); else ret->name = xstrdup(name); - refname = malloc(strlen(name) + strlen("refs/heads/") + 1); + refname = xmalloc(strlen(name) + strlen("refs/heads/") + 1); strcpy(refname, "refs/heads/"); strcpy(refname + strlen("refs/heads/"), ret->name); ret->refname = refname; @@ -455,7 +455,7 @@ static int verify_refname(char *name, int is_glob) * and dst pointers are always freeable pointers as well * as the refspec pointer itself. */ -void free_refspecs(struct refspec *refspec, int nr_refspec) +static void free_refspecs(struct refspec *refspec, int nr_refspec) { int i; @@ -613,7 +613,7 @@ struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec) return parse_refspec_internal(nr_refspec, refspec, 1, 0); } -struct refspec *parse_push_refspec(int nr_refspec, const char **refspec) +static struct refspec *parse_push_refspec(int nr_refspec, const char **refspec) { return parse_refspec_internal(nr_refspec, refspec, 0, 0); } @@ -783,7 +783,7 @@ struct ref *copy_ref_list(const struct ref *ref) return ret; } -void free_ref(struct ref *ref) +static void free_ref(struct ref *ref) { if (!ref) return; @@ -77,8 +77,6 @@ void ref_remove_duplicates(struct ref *ref_map); int valid_fetch_refspec(const char *refspec); struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec); -struct refspec *parse_push_refspec(int nr_refspec, const char **refspec); -void free_refspecs(struct refspec *refspec, int nr_refspec); int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail, int nr_refspec, const char **refspec, int all); @@ -319,7 +319,6 @@ static int git_rerere_config(const char *var, const char *value, void *cb) static int is_rerere_enabled(void) { - struct stat st; const char *rr_cache; int rr_cache_exists; @@ -327,7 +326,7 @@ static int is_rerere_enabled(void) return 0; rr_cache = git_path("rr-cache"); - rr_cache_exists = !stat(rr_cache, &st) && S_ISDIR(st.st_mode); + rr_cache_exists = is_directory(rr_cache); if (rerere_enabled < 0) return rr_cache_exists; diff --git a/revision.c b/revision.c index 36291b6b86..2f646deab0 100644 --- a/revision.c +++ b/revision.c @@ -489,7 +489,7 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit, p->object.flags |= SEEN; insert_by_date_cached(p, list, cached_base, cache_ptr); } - if(revs->first_parent_only) + if (revs->first_parent_only) break; } return 0; @@ -953,22 +953,9 @@ static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token append_grep_pattern(&revs->grep_filter, ptn, "command line", 0, what); } -static void add_header_grep(struct rev_info *revs, const char *field, const char *pattern) +static void add_header_grep(struct rev_info *revs, enum grep_header_field field, const char *pattern) { - char *pat; - const char *prefix; - int patlen, fldlen; - - fldlen = strlen(field); - patlen = strlen(pattern); - pat = xmalloc(patlen + fldlen + 10); - prefix = ".*"; - if (*pattern == '^') { - prefix = ""; - pattern++; - } - sprintf(pat, "^%s %s%s", field, prefix, pattern); - add_grep(revs, pat, GREP_PATTERN_HEAD); + append_header_grep_pattern(&revs->grep_filter, field, pattern); } static void add_message_grep(struct rev_info *revs, const char *pattern) @@ -1041,6 +1028,11 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if (!strcmp(arg, "--topo-order")) { revs->lifo = 1; revs->topo_order = 1; + } else if (!strcmp(arg, "--simplify-merges")) { + revs->simplify_merges = 1; + revs->rewrite_parents = 1; + revs->simplify_history = 0; + revs->limited = 1; } else if (!strcmp(arg, "--date-order")) { revs->lifo = 0; revs->topo_order = 1; @@ -1154,9 +1146,9 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg * Grepping the commit log */ else if (!prefixcmp(arg, "--author=")) { - add_header_grep(revs, "author", arg+9); + add_header_grep(revs, GREP_HEADER_AUTHOR, arg+9); } else if (!prefixcmp(arg, "--committer=")) { - add_header_grep(revs, "committer", arg+12); + add_header_grep(revs, GREP_HEADER_COMMITTER, arg+12); } else if (!prefixcmp(arg, "--grep=")) { add_message_grep(revs, arg+7); } else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) { @@ -1368,6 +1360,179 @@ static void add_child(struct rev_info *revs, struct commit *parent, struct commi l->next = add_decoration(&revs->children, &parent->object, l); } +static int remove_duplicate_parents(struct commit *commit) +{ + struct commit_list **pp, *p; + int surviving_parents; + + /* Examine existing parents while marking ones we have seen... */ + pp = &commit->parents; + while ((p = *pp) != NULL) { + struct commit *parent = p->item; + if (parent->object.flags & TMP_MARK) { + *pp = p->next; + continue; + } + parent->object.flags |= TMP_MARK; + pp = &p->next; + } + /* count them while clearing the temporary mark */ + surviving_parents = 0; + for (p = commit->parents; p; p = p->next) { + p->item->object.flags &= ~TMP_MARK; + surviving_parents++; + } + return surviving_parents; +} + +struct merge_simplify_state { + struct commit *simplified; +}; + +static struct merge_simplify_state *locate_simplify_state(struct rev_info *revs, struct commit *commit) +{ + struct merge_simplify_state *st; + + st = lookup_decoration(&revs->merge_simplification, &commit->object); + if (!st) { + st = xcalloc(1, sizeof(*st)); + add_decoration(&revs->merge_simplification, &commit->object, st); + } + return st; +} + +static struct commit_list **simplify_one(struct rev_info *revs, struct commit *commit, struct commit_list **tail) +{ + struct commit_list *p; + struct merge_simplify_state *st, *pst; + int cnt; + + st = locate_simplify_state(revs, commit); + + /* + * Have we handled this one? + */ + if (st->simplified) + return tail; + + /* + * An UNINTERESTING commit simplifies to itself, so does a + * root commit. We do not rewrite parents of such commit + * anyway. + */ + if ((commit->object.flags & UNINTERESTING) || !commit->parents) { + st->simplified = commit; + return tail; + } + + /* + * Do we know what commit all of our parents should be rewritten to? + * Otherwise we are not ready to rewrite this one yet. + */ + for (cnt = 0, p = commit->parents; p; p = p->next) { + pst = locate_simplify_state(revs, p->item); + if (!pst->simplified) { + tail = &commit_list_insert(p->item, tail)->next; + cnt++; + } + } + if (cnt) { + tail = &commit_list_insert(commit, tail)->next; + return tail; + } + + /* + * Rewrite our list of parents. + */ + for (p = commit->parents; p; p = p->next) { + pst = locate_simplify_state(revs, p->item); + p->item = pst->simplified; + } + cnt = remove_duplicate_parents(commit); + + /* + * It is possible that we are a merge and one side branch + * does not have any commit that touches the given paths; + * in such a case, the immediate parents will be rewritten + * to different commits. + * + * o----X X: the commit we are looking at; + * / / o: a commit that touches the paths; + * ---o----' + * + * Further reduce the parents by removing redundant parents. + */ + if (1 < cnt) { + struct commit_list *h = reduce_heads(commit->parents); + cnt = commit_list_count(h); + free_commit_list(commit->parents); + commit->parents = h; + } + + /* + * A commit simplifies to itself if it is a root, if it is + * UNINTERESTING, if it touches the given paths, or if it is a + * merge and its parents simplifies to more than one commits + * (the first two cases are already handled at the beginning of + * this function). + * + * Otherwise, it simplifies to what its sole parent simplifies to. + */ + if (!cnt || + (commit->object.flags & UNINTERESTING) || + !(commit->object.flags & TREESAME) || + (1 < cnt)) + st->simplified = commit; + else { + pst = locate_simplify_state(revs, commit->parents->item); + st->simplified = pst->simplified; + } + return tail; +} + +static void simplify_merges(struct rev_info *revs) +{ + struct commit_list *list; + struct commit_list *yet_to_do, **tail; + + if (!revs->topo_order) + sort_in_topological_order(&revs->commits, revs->lifo); + if (!revs->prune) + return; + + /* feed the list reversed */ + yet_to_do = NULL; + for (list = revs->commits; list; list = list->next) + commit_list_insert(list->item, &yet_to_do); + while (yet_to_do) { + list = yet_to_do; + yet_to_do = NULL; + tail = &yet_to_do; + while (list) { + struct commit *commit = list->item; + struct commit_list *next = list->next; + free(list); + list = next; + tail = simplify_one(revs, commit, tail); + } + } + + /* clean up the result, removing the simplified ones */ + list = revs->commits; + revs->commits = NULL; + tail = &revs->commits; + while (list) { + struct commit *commit = list->item; + struct commit_list *next = list->next; + struct merge_simplify_state *st; + free(list); + list = next; + st = locate_simplify_state(revs, commit); + if (st->simplified == commit) + tail = &commit_list_insert(commit, tail)->next; + } +} + static void set_children(struct rev_info *revs) { struct commit_list *l; @@ -1408,6 +1573,8 @@ int prepare_revision_walk(struct rev_info *revs) return -1; if (revs->topo_order) sort_in_topological_order(&revs->commits, revs->lifo); + if (revs->simplify_merges) + simplify_merges(revs); if (revs->children.name) set_children(revs); return 0; @@ -1440,26 +1607,6 @@ static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp } } -static void remove_duplicate_parents(struct commit *commit) -{ - struct commit_list **pp, *p; - - /* Examine existing parents while marking ones we have seen... */ - pp = &commit->parents; - while ((p = *pp) != NULL) { - struct commit *parent = p->item; - if (parent->object.flags & TMP_MARK) { - *pp = p->next; - continue; - } - parent->object.flags |= TMP_MARK; - pp = &p->next; - } - /* ... and clear the temporary mark */ - for (p = commit->parents; p; p = p->next) - p->item->object.flags &= ~TMP_MARK; -} - static int rewrite_parents(struct rev_info *revs, struct commit *commit) { struct commit_list **pp = &commit->parents; @@ -1646,26 +1793,6 @@ static struct commit *get_revision_internal(struct rev_info *revs) return c; } - if (revs->reverse) { - int limit = -1; - - if (0 <= revs->max_count) { - limit = revs->max_count; - if (0 < revs->skip_count) - limit += revs->skip_count; - } - l = NULL; - while ((c = get_revision_1(revs))) { - commit_list_insert(c, &l); - if ((0 < limit) && !--limit) - break; - } - revs->commits = l; - revs->reverse = 0; - revs->max_count = -1; - c = NULL; - } - /* * Now pick up what they want to give us */ @@ -1738,7 +1865,23 @@ static struct commit *get_revision_internal(struct rev_info *revs) struct commit *get_revision(struct rev_info *revs) { - struct commit *c = get_revision_internal(revs); + struct commit *c; + struct commit_list *reversed; + + if (revs->reverse) { + reversed = NULL; + while ((c = get_revision_internal(revs))) { + commit_list_insert(c, &reversed); + } + revs->commits = reversed; + revs->reverse = 0; + revs->reverse_output_stage = 1; + } + + if (revs->reverse_output_stage) + return pop_commit(&revs->commits); + + c = get_revision_internal(revs); if (c && revs->graph) graph_update(revs->graph, c); return c; diff --git a/revision.h b/revision.h index 91f194478b..2fdb2dd0ff 100644 --- a/revision.h +++ b/revision.h @@ -42,6 +42,7 @@ struct rev_info { simplify_history:1, lifo:1, topo_order:1, + simplify_merges:1, tag_objects:1, tree_objects:1, blob_objects:1, @@ -53,6 +54,7 @@ struct rev_info { rewrite_parents:1, print_parents:1, reverse:1, + reverse_output_stage:1, cherry_pick:1, first_parent_only:1; @@ -110,6 +112,7 @@ struct rev_info { struct reflog_walk_info *reflog_info; struct decoration children; + struct decoration merge_simplification; }; #define REV_TREE_SAME 0 @@ -581,6 +581,8 @@ const char *setup_git_directory(void) if (retval && chdir(retval)) die ("Could not jump back into original cwd"); rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree()); + if (rel && *rel && chdir(get_git_work_tree())) + die ("Could not jump to working directory"); return rel && *rel ? strcat(rel, "/") : NULL; } diff --git a/sha1_file.c b/sha1_file.c index 9ee1ed16ad..70ff904717 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -99,7 +99,11 @@ int safe_create_leading_directories(char *path) pos = strchr(pos, '/'); if (!pos) break; - *pos = 0; + while (*++pos == '/') + ; + if (!*pos) + break; + *--pos = '\0'; if (!stat(path, &st)) { /* path exists */ if (!S_ISDIR(st.st_mode)) { @@ -250,7 +254,6 @@ static void read_info_alternates(const char * alternates, int depth); */ static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth) { - struct stat st; const char *objdir = get_object_directory(); struct alternate_object_database *ent; struct alternate_object_database *alt; @@ -281,7 +284,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative ent->base[pfxlen] = ent->base[entlen-1] = 0; /* Detect cases where alternate disappeared */ - if (stat(ent->base, &st) || !S_ISDIR(st.st_mode)) { + if (!is_directory(ent->base)) { error("object directory %s does not exist; " "check .git/objects/info/alternates.", ent->base); @@ -394,6 +397,16 @@ void add_to_alternates_file(const char *reference) link_alt_odb_entries(alt, alt + strlen(alt), '\n', NULL, 0); } +void foreach_alt_odb(alt_odb_fn fn, void *cb) +{ + struct alternate_object_database *ent; + + prepare_alt_odb(); + for (ent = alt_odb_list; ent; ent = ent->next) + if (fn(ent, cb)) + return; +} + void prepare_alt_odb(void) { const char *alt; @@ -2136,7 +2149,9 @@ static void write_sha1_file_prepare(const void *buf, unsigned long len, */ int move_temp_to_file(const char *tmpfile, const char *filename) { - int ret = link(tmpfile, filename); + int ret = 0; + if (link(tmpfile, filename)) + ret = errno; /* * Coda hack - coda doesn't like cross-directory links, diff --git a/sideband.c b/sideband.c index b6777812cb..cca3360546 100644 --- a/sideband.c +++ b/sideband.c @@ -25,6 +25,7 @@ int recv_sideband(const char *me, int in_stream, int out, int err) unsigned sf; char buf[LARGE_PACKET_MAX + 2*FIX_SIZE]; char *suffix, *term; + int skip_pf = 0; memcpy(buf, PREFIX, pf); term = getenv("TERM"); @@ -54,39 +55,58 @@ int recv_sideband(const char *me, int in_stream, int out, int err) return SIDEBAND_REMOTE_ERROR; case 2: buf[pf] = ' '; - len += pf+1; - while (1) { - int brk = pf+1; + do { + char *b = buf; + int brk = 0; - /* Break the buffer into separate lines. */ - while (brk < len) { + /* + * If the last buffer didn't end with a line + * break then we should not print a prefix + * this time around. + */ + if (skip_pf) { + b += pf+1; + } else { + len += pf+1; + brk += pf+1; + } + + /* Look for a line break. */ + for (;;) { brk++; - if (buf[brk-1] == '\n' || - buf[brk-1] == '\r') + if (brk > len) { + brk = 0; + break; + } + if (b[brk-1] == '\n' || + b[brk-1] == '\r') break; } /* * Let's insert a suffix to clear the end - * of the screen line, but only if current - * line data actually contains something. + * of the screen line if a line break was + * found. Also, if we don't skip the + * prefix, then a non-empty string must be + * present too. */ - if (brk > pf+1 + 1) { + if (brk > (skip_pf ? 0 : (pf+1 + 1))) { char save[FIX_SIZE]; - memcpy(save, buf + brk, sf); - buf[brk + sf - 1] = buf[brk - 1]; - memcpy(buf + brk - 1, suffix, sf); - safe_write(err, buf, brk + sf); - memcpy(buf + brk, save, sf); - } else - safe_write(err, buf, brk); + memcpy(save, b + brk, sf); + b[brk + sf - 1] = b[brk - 1]; + memcpy(b + brk - 1, suffix, sf); + safe_write(err, b, brk + sf); + memcpy(b + brk, save, sf); + len -= brk; + } else { + int l = brk ? brk : len; + safe_write(err, b, l); + len -= l; + } - if (brk < len) { - memmove(buf + pf+1, buf + brk, len - brk); - len = len - brk + pf+1; - } else - break; - } + skip_pf = !brk; + memmove(buf + pf+1, b + brk, len); + } while (len); continue; case 1: safe_write(out, buf + pf+1, len); diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh index a841df2a9e..67c431d4eb 100644 --- a/t/lib-git-svn.sh +++ b/t/lib-git-svn.sh @@ -1,8 +1,11 @@ . ./test-lib.sh +remotes_git_svn=remotes/git""-svn +git_svn_id=git""-svn-id + if test -n "$NO_SVN_TESTS" then - test_expect_success 'skipping git-svn tests, NO_SVN_TESTS defined' : + test_expect_success 'skipping git svn tests, NO_SVN_TESTS defined' : test_done exit fi @@ -14,7 +17,7 @@ SVN_TREE=$GIT_SVN_DIR/svn-tree svn >/dev/null 2>&1 if test $? -ne 1 then - test_expect_success 'skipping git-svn tests, svn not found' : + test_expect_success 'skipping git svn tests, svn not found' : test_done exit fi @@ -88,7 +91,7 @@ start_httpd () { mkdir "$GIT_DIR"/logs cat > "$GIT_DIR/httpd.conf" <<EOF -ServerName "git-svn test" +ServerName "git svn test" ServerRoot "$GIT_DIR" DocumentRoot "$GIT_DIR" PidFile "$GIT_DIR/httpd.pid" @@ -135,3 +138,20 @@ close $wr or die $!; close $rd or die $!; EOF } + +require_svnserve () { + if test -z "$SVNSERVE_PORT" + then + say 'skipping svnserve test. (set $SVNSERVE_PORT to enable)' + test_done + exit + fi +} + +start_svnserve () { + svnserve --listen-port $SVNSERVE_PORT \ + --root "$rawsvnrepo" \ + --listen-once \ + --listen-host 127.0.0.1 & +} + diff --git a/t/t0024-crlf-archive.sh b/t/t0024-crlf-archive.sh new file mode 100644 index 0000000000..e5330395fc --- /dev/null +++ b/t/t0024-crlf-archive.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +test_description='respect crlf in git archive' + +. ./test-lib.sh +UNZIP=${UNZIP:-unzip} + +test_expect_success setup ' + + git config core.autocrlf true + + printf "CRLF line ending\r\nAnd another\r\n" > sample && + git add sample && + + test_tick && + git commit -m Initial + +' + +test_expect_success 'tar archive' ' + + git archive --format=tar HEAD | + ( mkdir untarred && cd untarred && "$TAR" -xf - ) + + test_cmp sample untarred/sample + +' + +"$UNZIP" -v >/dev/null 2>&1 +if [ $? -eq 127 ]; then + echo "Skipping ZIP test, because unzip was not found" + test_done + exit +fi + +test_expect_success 'zip archive' ' + + git archive --format=zip HEAD >test.zip && + + ( mkdir unzipped && cd unzipped && unzip ../test.zip ) && + + test_cmp sample unzipped/sample + +' + +test_done diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh index b177174ef5..7edf49db3c 100755 --- a/t/t0050-filesystem.sh +++ b/t/t0050-filesystem.sh @@ -85,7 +85,7 @@ $test_case 'add (with different case)' ' rm camelcase && echo 1 >CamelCase && git add CamelCase && - test $(git-ls-files | grep -i camelcase | wc -l) = 1 + test $(git ls-files | grep -i camelcase | wc -l) = 1 ' diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh index fcdd15a358..fd98e445bf 100755 --- a/t/t1007-hash-object.sh +++ b/t/t1007-hash-object.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description="git-hash-object" +test_description="git hash-object" . ./test-lib.sh diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh index 09a8199335..67e637b781 100755 --- a/t/t1200-tutorial.sh +++ b/t/t1200-tutorial.sh @@ -78,7 +78,7 @@ test_expect_success 'git whatchanged -p --root' 'cmp whatchanged.expect whatchan git tag my-first-tag test_expect_success 'git tag my-first-tag' 'cmp .git/refs/heads/master .git/refs/tags/my-first-tag' -# TODO: test git-clone +# TODO: test git clone git checkout -b mybranch test_expect_success 'git checkout -b mybranch' 'cmp .git/refs/heads/master .git/refs/heads/mybranch' diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 64567fb94d..11b82f43dd 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -741,4 +741,14 @@ test_expect_success 'symlinked configuration' ' ' +test_expect_success 'check split_cmdline return' " + git config alias.split-cmdline-fix 'echo \"' && + test_must_fail git split-cmdline-fix && + echo foo > foo && + git add foo && + git commit -m 'initial commit' && + git config branch.master.mergeoptions 'echo \"' && + test_must_fail git merge master + " + test_done diff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh index f98f4c5179..1983076c75 100755 --- a/t/t1303-wacky-config.sh +++ b/t/t1303-wacky-config.sh @@ -35,7 +35,7 @@ test_expect_success 'add key in different section' ' ' SECTION="test.q\"s\\sq'sp e.key" -test_expect_success 'make sure git-config escapes section names properly' ' +test_expect_success 'make sure git config escapes section names properly' ' git config "$SECTION" bar && check "$SECTION" bar ' diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index b31e4b1ac6..04c2b164bc 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -228,21 +228,21 @@ test_expect_success \ 'echo TEST >F && git add F && GIT_AUTHOR_DATE="2005-05-26 23:30" \ - GIT_COMMITTER_DATE="2005-05-26 23:30" git-commit -m add -a && + GIT_COMMITTER_DATE="2005-05-26 23:30" git commit -m add -a && h_TEST=$(git rev-parse --verify HEAD) echo The other day this did not work. >M && echo And then Bob told me how to fix it. >>M && echo OTHER >F && GIT_AUTHOR_DATE="2005-05-26 23:41" \ - GIT_COMMITTER_DATE="2005-05-26 23:41" git-commit -F M -a && + GIT_COMMITTER_DATE="2005-05-26 23:41" git commit -F M -a && h_OTHER=$(git rev-parse --verify HEAD) && GIT_AUTHOR_DATE="2005-05-26 23:44" \ - GIT_COMMITTER_DATE="2005-05-26 23:44" git-commit --amend && + GIT_COMMITTER_DATE="2005-05-26 23:44" git commit --amend && h_FIXED=$(git rev-parse --verify HEAD) && echo Merged initial commit and a later commit. >M && echo $h_TEST >.git/MERGE_HEAD && GIT_AUTHOR_DATE="2005-05-26 23:45" \ - GIT_COMMITTER_DATE="2005-05-26 23:45" git-commit -F M && + GIT_COMMITTER_DATE="2005-05-26 23:45" git commit -F M && h_MERGED=$(git rev-parse --verify HEAD) && rm -f M' @@ -253,7 +253,7 @@ $h_OTHER $h_FIXED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151040 +0000 co $h_FIXED $h_MERGED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151100 +0000 commit (merge): Merged initial commit and a later commit. EOF test_expect_success \ - 'git-commit logged updates' \ + 'git commit logged updates' \ "diff expect .git/logs/$m" unset h_TEST h_OTHER h_FIXED h_MERGED diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh index 2ee88d8a06..c039ee3fd8 100755 --- a/t/t1501-worktree.sh +++ b/t/t1501-worktree.sh @@ -28,6 +28,7 @@ test_rev_parse() { [ $# -eq 0 ] && return } +EMPTY_TREE=$(git write-tree) mkdir -p work/sub/dir || exit 1 mv .git repo.git || exit 1 @@ -106,12 +107,71 @@ test_expect_success 'repo finds its work tree from work tree, too' ' ' test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' ' - cd repo.git/work/sub/dir && + (cd repo.git/work/sub/dir && GIT_DIR=../../.. GIT_WORK_TREE=../.. GIT_PAGER= \ git diff --exit-code tracked && echo changed > tracked && ! GIT_DIR=../../.. GIT_WORK_TREE=../.. GIT_PAGER= \ - git diff --exit-code tracked + git diff --exit-code tracked) +' +cat > diff-index-cached.expected <<\EOF +:000000 100644 0000000000000000000000000000000000000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 A sub/dir/tracked +EOF +cat > diff-index.expected <<\EOF +:000000 100644 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 A sub/dir/tracked +EOF + + +test_expect_success 'git diff-index' ' + GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff-index $EMPTY_TREE > result && + test_cmp diff-index.expected result && + GIT_DIR=repo.git git diff-index --cached $EMPTY_TREE > result && + test_cmp diff-index-cached.expected result +' +cat >diff-files.expected <<\EOF +:100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 M sub/dir/tracked +EOF + +test_expect_success 'git diff-files' ' + GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff-files > result && + test_cmp diff-files.expected result +' + +cat >diff-TREE.expected <<\EOF +diff --git a/sub/dir/tracked b/sub/dir/tracked +new file mode 100644 +index 0000000..5ea2ed4 +--- /dev/null ++++ b/sub/dir/tracked +@@ -0,0 +1 @@ ++changed +EOF +cat >diff-TREE-cached.expected <<\EOF +diff --git a/sub/dir/tracked b/sub/dir/tracked +new file mode 100644 +index 0000000..e69de29 +EOF +cat >diff-FILES.expected <<\EOF +diff --git a/sub/dir/tracked b/sub/dir/tracked +index e69de29..5ea2ed4 100644 +--- a/sub/dir/tracked ++++ b/sub/dir/tracked +@@ -0,0 +1 @@ ++changed +EOF + +test_expect_success 'git diff' ' + GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff $EMPTY_TREE > result && + test_cmp diff-TREE.expected result && + GIT_DIR=repo.git git diff --cached $EMPTY_TREE > result && + test_cmp diff-TREE-cached.expected result && + GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff > result && + test_cmp diff-FILES.expected result +' + +test_expect_success 'git grep' ' + (cd repo.git/work/sub && + GIT_DIR=../.. GIT_WORK_TREE=.. git grep -l changed | grep -q dir/tracked) ' test_done diff --git a/t/t1503-rev-parse-verify.sh b/t/t1503-rev-parse-verify.sh index 95244c9bcf..cc65394947 100755 --- a/t/t1503-rev-parse-verify.sh +++ b/t/t1503-rev-parse-verify.sh @@ -23,7 +23,7 @@ add_line_into_file() fi test_tick - git-commit --quiet -m "$MSG" $_file + git commit --quiet -m "$MSG" $_file } HASH1= diff --git a/t/t2005-checkout-index-symlinks.sh b/t/t2005-checkout-index-symlinks.sh index a84c5a6af9..ed12c4d782 100755 --- a/t/t2005-checkout-index-symlinks.sh +++ b/t/t2005-checkout-index-symlinks.sh @@ -13,7 +13,7 @@ file if core.symlinks is false.' test_expect_success \ 'preparation' ' git config core.symlinks false && -l=$(echo -n file | git-hash-object -t blob -w --stdin) && +l=$(echo -n file | git hash-object -t blob -w --stdin) && echo "120000 $l symlink" | git update-index --index-info' test_expect_success \ @@ -23,6 +23,6 @@ test -f symlink' test_expect_success \ 'the file must be the blob we added during the setup' ' -test "$(git-hash-object -t blob symlink)" = $l' +test "$(git hash-object -t blob symlink)" = $l' test_done diff --git a/t/t2050-git-dir-relative.sh b/t/t2050-git-dir-relative.sh index 88f268b9d7..b7131d8c08 100755 --- a/t/t2050-git-dir-relative.sh +++ b/t/t2050-git-dir-relative.sh @@ -26,8 +26,8 @@ chmod +x .git/hooks/post-commit' test_expect_success 'post-commit hook used ordinarily' ' echo initial >top && -git-add top -git-commit -m initial && +git add top +git commit -m initial && test -r "${COMMIT_FILE}" ' diff --git a/t/t2101-update-index-reupdate.sh b/t/t2101-update-index-reupdate.sh index 59b560bfdf..648184fd98 100755 --- a/t/t2101-update-index-reupdate.sh +++ b/t/t2101-update-index-reupdate.sh @@ -40,7 +40,7 @@ test_expect_success 'update-index --remove --again' \ git ls-files -s >current && cmp current expected' -test_expect_success 'first commit' 'git-commit -m initial' +test_expect_success 'first commit' 'git commit -m initial' cat > expected <<\EOF 100644 53ab446c3f4e42ce9bb728a0ccb283a101be4979 0 dir1/file3 diff --git a/t/t2102-update-index-symlinks.sh b/t/t2102-update-index-symlinks.sh index 19d0894d26..f195aefe3a 100755 --- a/t/t2102-update-index-symlinks.sh +++ b/t/t2102-update-index-symlinks.sh @@ -13,7 +13,7 @@ even if a plain file is in the working tree if core.symlinks is false.' test_expect_success \ 'preparation' ' git config core.symlinks false && -l=$(echo -n file | git-hash-object -t blob -w --stdin) && +l=$(echo -n file | git hash-object -t blob -w --stdin) && echo "120000 $l symlink" | git update-index --index-info' test_expect_success \ diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index f57a6e077c..cd9231cf61 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -26,7 +26,7 @@ test_expect_success setup ' echo initial >dir2/sub3 && git add check dir1 dir2 top foo && test_tick - git-commit -m initial && + git commit -m initial && echo changed >check && echo changed >top && @@ -40,20 +40,20 @@ test_expect_success update ' ' test_expect_success 'update noticed a removal' ' - test "$(git-ls-files dir1/sub1)" = "" + test "$(git ls-files dir1/sub1)" = "" ' test_expect_success 'update touched correct path' ' - test "$(git-diff-files --name-status dir2/sub3)" = "" + test "$(git diff-files --name-status dir2/sub3)" = "" ' test_expect_success 'update did not touch other tracked files' ' - test "$(git-diff-files --name-status check)" = "M check" && - test "$(git-diff-files --name-status top)" = "M top" + test "$(git diff-files --name-status check)" = "M check" && + test "$(git diff-files --name-status top)" = "M top" ' test_expect_success 'update did not touch untracked files' ' - test "$(git-ls-files dir2/other)" = "" + test "$(git ls-files dir2/other)" = "" ' test_expect_success 'cache tree has not been corrupted' ' diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh index 1caeacafa7..8666946b02 100755 --- a/t/t3001-ls-files-others-exclude.sh +++ b/t/t3001-ls-files-others-exclude.sh @@ -96,7 +96,7 @@ cat > expect << EOF # three/ EOF -test_expect_success 'git-status honours core.excludesfile' \ +test_expect_success 'git status honors core.excludesfile' \ 'test_cmp expect output' test_expect_success 'trailing slash in exclude allows directory match(1)' ' diff --git a/t/t3020-ls-files-error-unmatch.sh b/t/t3020-ls-files-error-unmatch.sh index af8c4121ab..f4066cbc09 100755 --- a/t/t3020-ls-files-error-unmatch.sh +++ b/t/t3020-ls-files-error-unmatch.sh @@ -13,7 +13,7 @@ line. touch foo bar git update-index --add foo bar -git-commit -m "add foo bar" +git commit -m "add foo bar" test_expect_success \ 'git ls-files --error-unmatch should fail with unmatched path.' \ diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index f2880152b0..de0cdb1cf4 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -241,7 +241,7 @@ test_expect_success 'merge-recursive simple' ' rm -fr [abcd] && git checkout -f "$c2" && - git-merge-recursive "$c0" -- "$c2" "$c1" + git merge-recursive "$c0" -- "$c2" "$c1" status=$? case "$status" in 1) @@ -285,7 +285,7 @@ test_expect_success 'merge-recursive remove conflict' ' rm -fr [abcd] && git checkout -f "$c1" && - git-merge-recursive "$c0" -- "$c1" "$c5" + git merge-recursive "$c0" -- "$c1" "$c5" status=$? case "$status" in 1) @@ -317,7 +317,7 @@ test_expect_success 'merge-recursive d/f simple' ' git reset --hard && git checkout -f "$c1" && - git-merge-recursive "$c0" -- "$c1" "$c3" + git merge-recursive "$c0" -- "$c1" "$c3" ' test_expect_success 'merge-recursive result' ' @@ -339,7 +339,7 @@ test_expect_success 'merge-recursive d/f conflict' ' git reset --hard && git checkout -f "$c1" && - git-merge-recursive "$c0" -- "$c1" "$c4" + git merge-recursive "$c0" -- "$c1" "$c4" status=$? case "$status" in 1) @@ -373,7 +373,7 @@ test_expect_success 'merge-recursive d/f conflict the other way' ' git reset --hard && git checkout -f "$c4" && - git-merge-recursive "$c0" -- "$c4" "$c1" + git merge-recursive "$c0" -- "$c4" "$c1" status=$? case "$status" in 1) @@ -407,7 +407,7 @@ test_expect_success 'merge-recursive d/f conflict' ' git reset --hard && git checkout -f "$c1" && - git-merge-recursive "$c0" -- "$c1" "$c6" + git merge-recursive "$c0" -- "$c1" "$c6" status=$? case "$status" in 1) @@ -441,7 +441,7 @@ test_expect_success 'merge-recursive d/f conflict' ' git reset --hard && git checkout -f "$c6" && - git-merge-recursive "$c0" -- "$c6" "$c1" + git merge-recursive "$c0" -- "$c6" "$c1" status=$? case "$status" in 1) diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 7a83fbfe4f..2147eacc50 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -14,10 +14,10 @@ test_expect_success \ 'prepare a trivial repository' \ 'echo Hello > A && git update-index --add A && - git-commit -m "Initial commit." && + git commit -m "Initial commit." && echo World >> A && git update-index --add A && - git-commit -m "Second commit." && + git commit -m "Second commit." && HEAD=$(git rev-parse --verify HEAD)' test_expect_success \ @@ -123,7 +123,7 @@ test_expect_success \ test_expect_success 'test tracking setup via --track' \ 'git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --track my1 local/master && test $(git config branch.my1.remote) = local && test $(git config branch.my1.merge) = refs/heads/master' @@ -131,7 +131,7 @@ test_expect_success 'test tracking setup via --track' \ test_expect_success 'test tracking setup (non-wildcard, matching)' \ 'git config remote.local.url . && git config remote.local.fetch refs/heads/master:refs/remotes/local/master && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --track my4 local/master && test $(git config branch.my4.remote) = local && test $(git config branch.my4.merge) = refs/heads/master' @@ -139,7 +139,7 @@ test_expect_success 'test tracking setup (non-wildcard, matching)' \ test_expect_success 'test tracking setup (non-wildcard, not matching)' \ 'git config remote.local.url . && git config remote.local.fetch refs/heads/s:refs/remotes/local/s && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --track my5 local/master && ! test "$(git config branch.my5.remote)" = local && ! test "$(git config branch.my5.merge)" = refs/heads/master' @@ -148,7 +148,7 @@ test_expect_success 'test tracking setup via config' \ 'git config branch.autosetupmerge true && git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch my3 local/master && test $(git config branch.my3.remote) = local && test $(git config branch.my3.merge) = refs/heads/master' @@ -157,7 +157,7 @@ test_expect_success 'test overriding tracking setup via --no-track' \ 'git config branch.autosetupmerge true && git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --no-track my2 local/master && git config branch.autosetupmerge false && ! test "$(git config branch.my2.remote)" = local && @@ -173,7 +173,7 @@ test_expect_success 'no tracking without .fetch entries' \ test_expect_success 'test tracking setup via --track but deeper' \ 'git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/o/o || git-fetch local) && + (git show-ref -q refs/remotes/local/o/o || git fetch local) && git branch --track my7 local/o/o && test "$(git config branch.my7.remote)" = local && test "$(git config branch.my7.merge)" = refs/heads/o/o' @@ -209,7 +209,7 @@ EOF test_expect_success \ 'git checkout -b g/h/i -l should create a branch and a log' \ 'GIT_COMMITTER_DATE="2005-05-26 23:30" \ - git-checkout -b g/h/i -l master && + git checkout -b g/h/i -l master && test -f .git/refs/heads/g/h/i && test -f .git/logs/refs/heads/g/h/i && diff expect .git/logs/refs/heads/g/h/i' @@ -228,7 +228,7 @@ test_expect_success 'autosetuprebase local on a tracked local branch' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && git config branch.autosetuprebase local && - (git show-ref -q refs/remotes/local/o || git-fetch local) && + (git show-ref -q refs/remotes/local/o || git fetch local) && git branch mybase && git branch --track myr1 mybase && test "$(git config branch.myr1.remote)" = . && @@ -240,7 +240,7 @@ test_expect_success 'autosetuprebase always on a tracked local branch' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && git config branch.autosetuprebase always && - (git show-ref -q refs/remotes/local/o || git-fetch local) && + (git show-ref -q refs/remotes/local/o || git fetch local) && git branch mybase2 && git branch --track myr2 mybase && test "$(git config branch.myr2.remote)" = . && @@ -252,7 +252,7 @@ test_expect_success 'autosetuprebase remote on a tracked local branch' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && git config branch.autosetuprebase remote && - (git show-ref -q refs/remotes/local/o || git-fetch local) && + (git show-ref -q refs/remotes/local/o || git fetch local) && git branch mybase3 && git branch --track myr3 mybase2 && test "$(git config branch.myr3.remote)" = . && @@ -264,7 +264,7 @@ test_expect_success 'autosetuprebase never on a tracked local branch' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && git config branch.autosetuprebase never && - (git show-ref -q refs/remotes/local/o || git-fetch local) && + (git show-ref -q refs/remotes/local/o || git fetch local) && git branch mybase4 && git branch --track myr4 mybase2 && test "$(git config branch.myr4.remote)" = . && @@ -276,7 +276,7 @@ test_expect_success 'autosetuprebase local on a tracked remote branch' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && git config branch.autosetuprebase local && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --track myr5 local/master && test "$(git config branch.myr5.remote)" = local && test "$(git config branch.myr5.merge)" = refs/heads/master && @@ -287,7 +287,7 @@ test_expect_success 'autosetuprebase never on a tracked remote branch' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && git config branch.autosetuprebase never && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --track myr6 local/master && test "$(git config branch.myr6.remote)" = local && test "$(git config branch.myr6.merge)" = refs/heads/master && @@ -298,7 +298,7 @@ test_expect_success 'autosetuprebase remote on a tracked remote branch' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && git config branch.autosetuprebase remote && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --track myr7 local/master && test "$(git config branch.myr7.remote)" = local && test "$(git config branch.myr7.merge)" = refs/heads/master && @@ -309,7 +309,7 @@ test_expect_success 'autosetuprebase always on a tracked remote branch' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && git config branch.autosetuprebase remote && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --track myr8 local/master && test "$(git config branch.myr8.remote)" = local && test "$(git config branch.myr8.merge)" = refs/heads/master && @@ -320,7 +320,7 @@ test_expect_success 'autosetuprebase unconfigured on a tracked remote branch' ' git config --unset branch.autosetuprebase && git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --track myr9 local/master && test "$(git config branch.myr9.remote)" = local && test "$(git config branch.myr9.merge)" = refs/heads/master && @@ -330,7 +330,7 @@ test_expect_success 'autosetuprebase unconfigured on a tracked remote branch' ' test_expect_success 'autosetuprebase unconfigured on a tracked local branch' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/o || git-fetch local) && + (git show-ref -q refs/remotes/local/o || git fetch local) && git branch mybase10 && git branch --track myr10 mybase2 && test "$(git config branch.myr10.remote)" = . && @@ -341,7 +341,7 @@ test_expect_success 'autosetuprebase unconfigured on a tracked local branch' ' test_expect_success 'autosetuprebase unconfigured on untracked local branch' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --no-track myr11 mybase2 && test "z$(git config branch.myr11.remote)" = z && test "z$(git config branch.myr11.merge)" = z && @@ -351,7 +351,7 @@ test_expect_success 'autosetuprebase unconfigured on untracked local branch' ' test_expect_success 'autosetuprebase unconfigured on untracked remote branch' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --no-track myr12 local/master && test "z$(git config branch.myr12.remote)" = z && test "z$(git config branch.myr12.merge)" = z && @@ -362,7 +362,7 @@ test_expect_success 'autosetuprebase never on an untracked local branch' ' git config branch.autosetuprebase never && git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --no-track myr13 mybase2 && test "z$(git config branch.myr13.remote)" = z && test "z$(git config branch.myr13.merge)" = z && @@ -373,7 +373,7 @@ test_expect_success 'autosetuprebase local on an untracked local branch' ' git config branch.autosetuprebase local && git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --no-track myr14 mybase2 && test "z$(git config branch.myr14.remote)" = z && test "z$(git config branch.myr14.merge)" = z && @@ -384,7 +384,7 @@ test_expect_success 'autosetuprebase remote on an untracked local branch' ' git config branch.autosetuprebase remote && git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --no-track myr15 mybase2 && test "z$(git config branch.myr15.remote)" = z && test "z$(git config branch.myr15.merge)" = z && @@ -395,7 +395,7 @@ test_expect_success 'autosetuprebase always on an untracked local branch' ' git config branch.autosetuprebase always && git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --no-track myr16 mybase2 && test "z$(git config branch.myr16.remote)" = z && test "z$(git config branch.myr16.merge)" = z && @@ -406,7 +406,7 @@ test_expect_success 'autosetuprebase never on an untracked remote branch' ' git config branch.autosetuprebase never && git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --no-track myr17 local/master && test "z$(git config branch.myr17.remote)" = z && test "z$(git config branch.myr17.merge)" = z && @@ -417,7 +417,7 @@ test_expect_success 'autosetuprebase local on an untracked remote branch' ' git config branch.autosetuprebase local && git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --no-track myr18 local/master && test "z$(git config branch.myr18.remote)" = z && test "z$(git config branch.myr18.merge)" = z && @@ -428,7 +428,7 @@ test_expect_success 'autosetuprebase remote on an untracked remote branch' ' git config branch.autosetuprebase remote && git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --no-track myr19 local/master && test "z$(git config branch.myr19.remote)" = z && test "z$(git config branch.myr19.merge)" = z && @@ -439,7 +439,7 @@ test_expect_success 'autosetuprebase always on an untracked remote branch' ' git config branch.autosetuprebase always && git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && - (git show-ref -q refs/remotes/local/master || git-fetch local) && + (git show-ref -q refs/remotes/local/master || git fetch local) && git branch --no-track myr20 local/master && test "z$(git config branch.myr20.remote)" = z && test "z$(git config branch.myr20.merge)" = z && diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index c2dec1c632..087ef75061 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -17,7 +17,7 @@ test_expect_success \ 'prepare a trivial repository' \ 'echo Hello > A && git update-index --add A && - git-commit -m "Initial commit." && + git commit -m "Initial commit." && HEAD=$(git rev-parse --verify HEAD)' SHA1= @@ -97,7 +97,7 @@ test_expect_success \ git branch n' test_expect_success 'pack, prune and repack' ' - git-tag foo && + git tag foo && git pack-refs --all --prune && git show-ref >all-of-them && git pack-refs && diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 91bb5e1d9e..b7a670ef40 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -16,15 +16,15 @@ test_expect_success \ 'prepare repository with topic branches' \ 'echo First > A && git update-index --add A && - git-commit -m "Add A." && + git commit -m "Add A." && git checkout -b my-topic-branch && echo Second > B && git update-index --add B && - git-commit -m "Add B." && + git commit -m "Add B." && git checkout -f master && echo Third >> A && git update-index A && - git-commit -m "Modify A." && + git commit -m "Modify A." && git checkout -b side my-topic-branch && echo Side >> C && git add C && diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh index 166ddb1447..aea6685984 100755 --- a/t/t3401-rebase-partial.sh +++ b/t/t3401-rebase-partial.sh @@ -15,29 +15,29 @@ test_expect_success \ 'prepare repository with topic branch' \ 'echo First > A && git update-index --add A && - git-commit -m "Add A." && + git commit -m "Add A." && - git-checkout -b my-topic-branch && + git checkout -b my-topic-branch && echo Second > B && git update-index --add B && - git-commit -m "Add B." && + git commit -m "Add B." && echo AnotherSecond > C && git update-index --add C && - git-commit -m "Add C." && + git commit -m "Add C." && - git-checkout -f master && + git checkout -f master && echo Third >> A && git update-index A && - git-commit -m "Modify A." + git commit -m "Modify A." ' test_expect_success \ 'pick top patch from topic branch into master' \ 'git cherry-pick my-topic-branch^0 && - git-checkout -f my-topic-branch && + git checkout -f my-topic-branch && git branch master-merge master && git branch my-topic-branch-merge my-topic-branch ' @@ -49,13 +49,13 @@ test_debug \ ' test_expect_success \ - 'rebase topic branch against new master and check git-am did not get halted' \ - 'git-rebase master && test ! -d .git/rebase-apply' + 'rebase topic branch against new master and check git am did not get halted' \ + 'git rebase master && test ! -d .git/rebase-apply' test_expect_success \ 'rebase --merge topic branch that was partially merged upstream' \ - 'git-checkout -f my-topic-branch-merge && - git-rebase --merge master-merge && + 'git checkout -f my-topic-branch-merge && + git rebase --merge master-merge && test ! -d .git/rebase-merge' test_done diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh index 0d33c71daa..64446e3db3 100755 --- a/t/t3403-rebase-skip.sh +++ b/t/t3403-rebase-skip.sh @@ -7,7 +7,7 @@ test_description='git rebase --merge --skip tests' . ./test-lib.sh -# we assume the default git-am -3 --skip strategy is tested independently +# we assume the default git am -3 --skip strategy is tested independently # and always works :) test_expect_success setup ' diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 5aa487ac02..e0ded197ec 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -161,7 +161,7 @@ test_expect_success 'stop on conflicting pick' ' test "$(git rev-parse HEAD~3)" = "$(git rev-parse master)" && test_cmp expect .git/rebase-merge/patch && test_cmp expect2 file1 && - test "$(git-diff --name-status | + test "$(git diff --name-status | sed -n -e "/^U/s/^U[^a-z]*//p")" = file1 && test 4 = $(grep -v "^#" < .git/rebase-merge/done | wc -l) && test 0 = $(grep -c "^[^#]" < .git/rebase-merge/git-rebase-todo) diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh index 4de550a632..2999e78937 100755 --- a/t/t3407-rebase-abort.sh +++ b/t/t3407-rebase-abort.sh @@ -52,7 +52,7 @@ testrebase() { test -d "$dotest" && test_must_fail git rebase --skip && test $(git rev-parse HEAD) = $(git rev-parse master) && - git-rebase --abort && + git rebase --abort && test $(git rev-parse to-rebase) = $(git rev-parse pre-rebase) && test ! -d "$dotest" ' diff --git a/t/t3500-cherry.sh b/t/t3500-cherry.sh index 4911c48378..dadbbc2a9f 100755 --- a/t/t3500-cherry.sh +++ b/t/t3500-cherry.sh @@ -17,25 +17,25 @@ test_expect_success \ 'prepare repository with topic branch, and check cherry finds the 2 patches from there' \ 'echo First > A && git update-index --add A && - git-commit -m "Add A." && + git commit -m "Add A." && - git-checkout -b my-topic-branch && + git checkout -b my-topic-branch && echo Second > B && git update-index --add B && - git-commit -m "Add B." && + git commit -m "Add B." && sleep 2 && echo AnotherSecond > C && git update-index --add C && - git-commit -m "Add C." && + git commit -m "Add C." && - git-checkout -f master && + git checkout -f master && rm -f B C && echo Third >> A && git update-index A && - git-commit -m "Modify A." && + git commit -m "Modify A." && expr "$(echo $(git cherry master my-topic-branch) )" : "+ [^ ]* + .*" ' diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 79c06adf1f..558c80edbf 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -12,14 +12,14 @@ test_expect_success \ 'Initialize test directory' \ "touch -- foo bar baz 'space embedded' -q && git add -- foo bar baz 'space embedded' -q && - git-commit -m 'add normal files' && + git commit -m 'add normal files' && test_tabs=y && if touch -- 'tab embedded' 'newline embedded' then git add -- 'tab embedded' 'newline embedded' && - git-commit -m 'add files with tabs and newlines' + git commit -m 'add files with tabs and newlines' else say 'Your filesystem does not allow tabs in filenames.' test_tabs=n diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh index c851db8ca9..6fb027ba57 100755 --- a/t/t3800-mktag.sh +++ b/t/t3800-mktag.sh @@ -2,7 +2,7 @@ # # -test_description='git-mktag: tag object verify test' +test_description='git mktag: tag object verify test' . ./test-lib.sh @@ -14,7 +14,7 @@ test_description='git-mktag: tag object verify test' check_verify_failure () { expect="$2" test_expect_success "$1" ' - ( test_must_fail git-mktag <tag.sig 2>message ) && + ( test_must_fail git mktag <tag.sig 2>message ) && grep "$expect" message ' } @@ -24,7 +24,7 @@ check_verify_failure () { # for the tag. echo Hello >A git update-index --add A -git-commit -m "Initial commit" +git commit -m "Initial commit" head=$(git rev-parse --verify HEAD) ############################################################ @@ -222,7 +222,7 @@ EOF test_expect_success \ 'allow empty tag email' \ - 'git-mktag <tag.sig >.git/refs/tags/mytag 2>message' + 'git mktag <tag.sig >.git/refs/tags/mytag 2>message' ############################################################ # 16. disallow spaces in tag email @@ -350,14 +350,14 @@ EOF test_expect_success \ 'create valid tag' \ - 'git-mktag <tag.sig >.git/refs/tags/mytag 2>message' + 'git mktag <tag.sig >.git/refs/tags/mytag 2>message' ############################################################ # 25. check mytag test_expect_success \ 'check mytag' \ - 'git-tag -l | grep mytag' + 'git tag -l | grep mytag' test_done diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh index f4f41847f3..784c31aec9 100755 --- a/t/t3900-i18n-commit.sh +++ b/t/t3900-i18n-commit.sh @@ -18,7 +18,7 @@ test_expect_success setup ' T=$(git write-tree) && C=$(git commit-tree $T <"$TEST_DIRECTORY"/t3900/1-UTF-8.txt) && git update-ref HEAD $C && - git-tag C0 + git tag C0 ' test_expect_success 'no encoding header for base case' ' @@ -30,9 +30,9 @@ for H in ISO-8859-1 EUCJP ISO-2022-JP do test_expect_success "$H setup" ' git config i18n.commitencoding $H && - git-checkout -b $H C0 && + git checkout -b $H C0 && echo $H >F && - git-commit -a -F "$TEST_DIRECTORY"/t3900/$H.txt + git commit -a -F "$TEST_DIRECTORY"/t3900/$H.txt ' done diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh index f68ff53051..7655da3f8d 100755 --- a/t/t3901-i18n-patch.sh +++ b/t/t3901-i18n-patch.sh @@ -103,7 +103,7 @@ test_expect_success 'rebase (U/U)' ' # we want UTF-8 encoded name. . "$TEST_DIRECTORY"/t3901-utf8.txt && git checkout -b test && - git-rebase master && + git rebase master && check_encoding 2 ' @@ -114,7 +114,7 @@ test_expect_success 'rebase (U/L)' ' . "$TEST_DIRECTORY"/t3901-utf8.txt && git reset --hard side && - git-rebase master && + git rebase master && check_encoding 2 ' @@ -126,7 +126,7 @@ test_expect_success 'rebase (L/L)' ' . "$TEST_DIRECTORY"/t3901-8859-1.txt && git reset --hard side && - git-rebase master && + git rebase master && check_encoding 2 8859 ' @@ -139,7 +139,7 @@ test_expect_success 'rebase (L/U)' ' . "$TEST_DIRECTORY"/t3901-8859-1.txt && git reset --hard side && - git-rebase master && + git rebase master && check_encoding 2 8859 ' @@ -211,7 +211,7 @@ test_expect_success 'rebase --merge (U/U)' ' . "$TEST_DIRECTORY"/t3901-utf8.txt && git reset --hard side && - git-rebase --merge master && + git rebase --merge master && check_encoding 2 ' @@ -222,7 +222,7 @@ test_expect_success 'rebase --merge (U/L)' ' . "$TEST_DIRECTORY"/t3901-utf8.txt && git reset --hard side && - git-rebase --merge master && + git rebase --merge master && check_encoding 2 ' @@ -234,7 +234,7 @@ test_expect_success 'rebase --merge (L/L)' ' . "$TEST_DIRECTORY"/t3901-8859-1.txt && git reset --hard side && - git-rebase --merge master && + git rebase --merge master && check_encoding 2 8859 ' @@ -247,7 +247,7 @@ test_expect_success 'rebase --merge (L/U)' ' . "$TEST_DIRECTORY"/t3901-8859-1.txt && git reset --hard side && - git-rebase --merge master && + git rebase --merge master && check_encoding 2 8859 ' diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 8d4804b658..7484cbede6 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Johannes E Schindelin # -test_description='Test git-stash' +test_description='Test git stash' . ./test-lib.sh diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh index 69934991cb..b8ec6e90af 100755 --- a/t/t4012-diff-binary.sh +++ b/t/t4012-diff-binary.sh @@ -61,7 +61,7 @@ test_expect_success 'apply detecting corrupt patch correctly' \ detected=`sed -ne "${detected}p" broken` && test "$detected" = xCIT' -test_expect_success 'initial commit' 'git-commit -a -m initial' +test_expect_success 'initial commit' 'git commit -a -m initial' # Try removal (b), modification (d), and creation (e). test_expect_success 'diff-index with --binary' \ @@ -72,7 +72,7 @@ test_expect_success 'diff-index with --binary' \ git apply --stat --summary current' test_expect_success 'apply binary patch' \ - 'git-reset --hard && + 'git reset --hard && git apply --binary --index <current && tree1=`git write-tree` && test "$tree1" = "$tree0"' diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index 833d6cbcfc..18bcd9713d 100755 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@ -57,4 +57,10 @@ test_expect_success 'last regexp must not be negated' ' test_must_fail git diff --no-index Beer.java Beer-correct.java ' +test_expect_success 'alternation in pattern' ' + git config diff.java.funcname "^[ ]*\\(\\(public\\|static\\).*\\)$" + git diff --no-index Beer.java Beer-correct.java | + grep "^@@.*@@ public static void main(" +' + test_done diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh index 7eae1f4500..84a1fe3115 100755 --- a/t/t4019-diff-wserror.sh +++ b/t/t4019-diff-wserror.sh @@ -178,4 +178,16 @@ test_expect_success 'trailing empty lines (2)' ' ' +test_expect_success 'do not color trailing cr in context' ' + git config --unset core.whitespace + rm -f .gitattributes && + echo AAAQ | tr Q "\015" >G && + git add G && + echo BBBQ | tr Q "\015" >>G + git diff --color G | tr "\015" Q >output && + grep "BBB.*${blue_grep}Q" output && + grep "AAA.*\[mQ" output + +' + test_done diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh index 7da0b4bb8b..ad4cc1a757 100755 --- a/t/t4103-apply-binary.sh +++ b/t/t4103-apply-binary.sh @@ -21,16 +21,16 @@ cat file1 >file2 cat file1 >file4 git update-index --add --remove file1 file2 file4 -git-commit -m 'Initial Version' 2>/dev/null +git commit -m 'Initial Version' 2>/dev/null -git-checkout -b binary +git checkout -b binary perl -pe 'y/x/\000/' <file1 >file3 cat file3 >file4 git add file2 perl -pe 'y/\000/v/' <file3 >file1 rm -f file2 git update-index --add --remove file1 file2 file3 file4 -git-commit -m 'Second Version' +git commit -m 'Second Version' git diff-tree -p master binary >B.diff git diff-tree -p -C master binary >C.diff @@ -39,47 +39,47 @@ git diff-tree -p --binary master binary >BF.diff git diff-tree -p --binary -C master binary >CF.diff test_expect_success 'stat binary diff -- should not fail.' \ - 'git-checkout master + 'git checkout master git apply --stat --summary B.diff' test_expect_success 'stat binary diff (copy) -- should not fail.' \ - 'git-checkout master + 'git checkout master git apply --stat --summary C.diff' test_expect_success 'check binary diff -- should fail.' \ - 'git-checkout master && + 'git checkout master && test_must_fail git apply --check B.diff' test_expect_success 'check binary diff (copy) -- should fail.' \ - 'git-checkout master && + 'git checkout master && test_must_fail git apply --check C.diff' test_expect_success \ 'check incomplete binary diff with replacement -- should fail.' ' - git-checkout master && + git checkout master && test_must_fail git apply --check --allow-binary-replacement B.diff ' test_expect_success \ 'check incomplete binary diff with replacement (copy) -- should fail.' ' - git-checkout master && + git checkout master && test_must_fail git apply --check --allow-binary-replacement C.diff ' test_expect_success 'check binary diff with replacement.' \ - 'git-checkout master + 'git checkout master git apply --check --allow-binary-replacement BF.diff' test_expect_success 'check binary diff with replacement (copy).' \ - 'git-checkout master + 'git checkout master git apply --check --allow-binary-replacement CF.diff' # Now we start applying them. do_reset () { rm -f file? && - git-reset --hard && - git-checkout -f master + git reset --hard && + git checkout -f master } test_expect_success 'apply binary diff -- should fail.' \ diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh index 85f3da2b98..f83322e513 100755 --- a/t/t4124-apply-ws-rule.sh +++ b/t/t4124-apply-ws-rule.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='core.whitespace rules and git-apply' +test_description='core.whitespace rules and git apply' . ./test-lib.sh diff --git a/t/t4127-apply-same-fn.sh b/t/t4127-apply-same-fn.sh index 1f859dd908..3a8202ea93 100755 --- a/t/t4127-apply-same-fn.sh +++ b/t/t4127-apply-same-fn.sh @@ -26,7 +26,7 @@ test_expect_success 'apply same filename with independent changes' ' git diff >> patch0 && cp same_fn same_fn2 && git reset --hard && - git-apply patch0 && + git apply patch0 && diff same_fn same_fn2 ' @@ -39,7 +39,7 @@ test_expect_success 'apply same filename with overlapping changes' ' git diff >> patch0 && cp same_fn same_fn2 && git reset --hard && - git-apply patch0 && + git apply patch0 && diff same_fn same_fn2 ' diff --git a/t/t4150-am.sh b/t/t4150-am.sh index 6e6aaf5936..1be5fb3f9d 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -164,7 +164,7 @@ test_expect_success 'am --keep really keeps the subject' ' git checkout HEAD^ && git am --keep patch4 && ! test -d .git/rebase-apply && - git-cat-file commit HEAD | + git cat-file commit HEAD | grep -q -F "Re: Re: Re: [PATCH 1/5 v2] third" ' diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh index 7d86cdff64..4448aba7e0 100755 --- a/t/t4151-am-abort.sh +++ b/t/t4151-am-abort.sh @@ -44,14 +44,14 @@ do ' test_expect_success "am$with3 --skip continue after failed am$with3" ' - test_must_fail git-am$with3 --skip >output && + test_must_fail git am$with3 --skip >output && test "$(grep "^Applying" output)" = "Applying: 6" && test_cmp file-2-expect file-2 && test ! -f .git/rr-cache/MERGE_RR ' test_expect_success "am --abort goes back after failed am$with3" ' - git-am --abort && + git am --abort && git rev-parse HEAD >actual && git rev-parse initial >expect && test_cmp expect actual && diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 83abe5f25e..b335c6b42d 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='git-pack-object +test_description='git pack-object ' . ./test-lib.sh @@ -242,24 +242,24 @@ test_expect_success \ test_expect_success \ 'build pack index for an existing pack' \ 'cat test-1-${packname_1}.pack >test-3.pack && - git-index-pack -o tmp.idx test-3.pack && + git index-pack -o tmp.idx test-3.pack && cmp tmp.idx test-1-${packname_1}.idx && - git-index-pack test-3.pack && + git index-pack test-3.pack && cmp test-3.idx test-1-${packname_1}.idx && cat test-2-${packname_2}.pack >test-3.pack && - git-index-pack -o tmp.idx test-2-${packname_2}.pack && + git index-pack -o tmp.idx test-2-${packname_2}.pack && cmp tmp.idx test-2-${packname_2}.idx && - git-index-pack test-3.pack && + git index-pack test-3.pack && cmp test-3.idx test-2-${packname_2}.idx && cat test-3-${packname_3}.pack >test-3.pack && - git-index-pack -o tmp.idx test-3-${packname_3}.pack && + git index-pack -o tmp.idx test-3-${packname_3}.pack && cmp tmp.idx test-3-${packname_3}.idx && - git-index-pack test-3.pack && + git index-pack test-3.pack && cmp test-3.idx test-3-${packname_3}.idx && :' @@ -272,7 +272,8 @@ test_expect_success \ test_expect_success \ 'make sure index-pack detects the SHA1 collision' \ - 'test_must_fail git-index-pack -o bad.idx test-3.pack' + 'test_must_fail git index-pack -o bad.idx test-3.pack 2>msg && + grep "SHA1 COLLISION FOUND" msg' test_expect_success \ 'honor pack.packSizeLimit' \ diff --git a/t/t5301-sliding-window.sh b/t/t5301-sliding-window.sh index 073ac0c6f9..0a24e61ff9 100755 --- a/t/t5301-sliding-window.sh +++ b/t/t5301-sliding-window.sh @@ -19,7 +19,7 @@ test_expect_success \ tree=`git write-tree` && commit1=`git commit-tree $tree </dev/null` && git update-ref HEAD $commit1 && - git-repack -a -d && + git repack -a -d && test "`git count-objects`" = "0 objects, 0 kilobytes" && pack1=`ls .git/objects/pack/*.pack` && test -f "$pack1"' @@ -45,7 +45,7 @@ test_expect_success \ git config core.packedGitLimit 512 && commit2=`git commit-tree $tree -p $commit1 </dev/null` && git update-ref HEAD $commit2 && - git-repack -a -d && + git repack -a -d && test "`git count-objects`" = "0 objects, 0 kilobytes" && pack2=`ls .git/objects/pack/*.pack` && test -f "$pack2" diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index 0639772ac4..6424db1f28 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -48,11 +48,11 @@ test_expect_success \ test_expect_success \ 'index-pack with index version 1' \ - 'git-index-pack --index-version=1 -o 1.idx "test-1-${pack1}.pack"' + 'git index-pack --index-version=1 -o 1.idx "test-1-${pack1}.pack"' test_expect_success \ 'index-pack with index version 2' \ - 'git-index-pack --index-version=2 -o 2.idx "test-1-${pack1}.pack"' + 'git index-pack --index-version=2 -o 2.idx "test-1-${pack1}.pack"' test_expect_success \ 'index-pack results should match pack-objects ones' \ @@ -85,7 +85,7 @@ test_expect_success \ test "$have_64bits" && test_expect_success \ 'index v2: force some 64-bit offsets with index-pack' \ - 'git-index-pack --index-version=2,0x40000 -o 3.idx "test-1-${pack1}.pack"' + 'git index-pack --index-version=2,0x40000 -o 3.idx "test-1-${pack1}.pack"' test "$have_64bits" && test_expect_success \ @@ -94,7 +94,7 @@ test_expect_success \ test_expect_success \ '[index v1] 1) stream pack to repository' \ - 'git-index-pack --index-version=1 --stdin < "test-1-${pack1}.pack" && + 'git index-pack --index-version=1 --stdin < "test-1-${pack1}.pack" && git prune-packed && git count-objects | ( read nr rest && test "$nr" -eq 1 ) && cmp "test-1-${pack1}.pack" ".git/objects/pack/pack-${pack1}.pack" && @@ -132,7 +132,7 @@ test_expect_success \ test_expect_success \ '[index v2] 1) stream pack to repository' \ 'rm -f .git/objects/pack/* && - git-index-pack --index-version=2 --stdin < "test-1-${pack1}.pack" && + git index-pack --index-version=2 --stdin < "test-1-${pack1}.pack" && git prune-packed && git count-objects | ( read nr rest && test "$nr" -eq 1 ) && cmp "test-1-${pack1}.pack" ".git/objects/pack/pack-${pack1}.pack" && @@ -165,7 +165,7 @@ test_expect_success \ test_expect_success \ '[index v2] 6) verify-pack detects CRC mismatch' \ 'rm -f .git/objects/pack/* && - git-index-pack --index-version=2 --stdin < "test-1-${pack1}.pack" && + git index-pack --index-version=2 --stdin < "test-1-${pack1}.pack" && git verify-pack ".git/objects/pack/pack-${pack1}.pack" && chmod +w ".git/objects/pack/pack-${pack1}.idx" && dd if=/dev/zero of=".git/objects/pack/pack-${pack1}.idx" conv=notrunc \ diff --git a/t/t5305-include-tag.sh b/t/t5305-include-tag.sh index fb471a08c6..b061864a87 100755 --- a/t/t5305-include-tag.sh +++ b/t/t5305-include-tag.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-pack-object --include-tag' +test_description='git pack-object --include-tag' . ./test-lib.sh TRASH=`pwd` diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh index 68c2ae688c..544771d8fa 100755 --- a/t/t5400-send-pack.sh +++ b/t/t5400-send-pack.sh @@ -31,7 +31,7 @@ test_expect_success setup ' parent=$commit || return 1 done && git update-ref HEAD "$commit" && - git-clone ./. victim && + git clone ./. victim && cd victim && git log && cd .. && @@ -68,7 +68,7 @@ test_expect_success 'pack the destination repository' ' test_expect_success \ 'pushing rewound head should not barf but require --force' ' # should not fail but refuse to update. - if git-send-pack ./victim/.git/ master + if git send-pack ./victim/.git/ master then # now it should fail with Pasky patch echo >&2 Gaah, it should have failed. @@ -85,7 +85,7 @@ test_expect_success \ true fi && # this should update - git-send-pack --force ./victim/.git/ master && + git send-pack --force ./victim/.git/ master && cmp victim/.git/refs/heads/master .git/refs/heads/master ' @@ -95,7 +95,7 @@ test_expect_success \ git branch extra master && cd .. && test -f victim/.git/refs/heads/extra && - git-send-pack ./victim/.git/ :extra master && + git send-pack ./victim/.git/ :extra master && ! test -f victim/.git/refs/heads/extra ' @@ -109,27 +109,27 @@ test_expect_success \ git config receive.denyNonFastforwards true && cd .. && git update-ref refs/heads/master master^ || return 1 - git-send-pack --force ./victim/.git/ master && return 1 + git send-pack --force ./victim/.git/ master && return 1 ! test_cmp .git/refs/heads/master victim/.git/refs/heads/master ' test_expect_success \ 'pushing does not include non-head refs' ' mkdir parent && cd parent && - git-init && touch file && git-add file && git-commit -m add && + git init && touch file && git add file && git commit -m add && cd .. && - git-clone parent child && cd child && git-push --all && + git clone parent child && cd child && git push --all && cd ../parent && - git-branch -a >branches && ! grep origin/master branches + git branch -a >branches && ! grep origin/master branches ' rewound_push_setup() { rm -rf parent child && mkdir parent && cd parent && - git-init && echo one >file && git-add file && git-commit -m one && - echo two >file && git-commit -a -m two && + git init && echo one >file && git add file && git commit -m one && + echo two >file && git commit -a -m two && cd .. && - git-clone parent child && cd child && git-reset --hard HEAD^ + git clone parent child && cd child && git reset --hard HEAD^ } rewound_push_succeeded() { @@ -148,26 +148,26 @@ rewound_push_failed() { test_expect_success \ 'pushing explicit refspecs respects forcing' ' rewound_push_setup && - if git-send-pack ../parent/.git refs/heads/master:refs/heads/master + if git send-pack ../parent/.git refs/heads/master:refs/heads/master then false else true fi && rewound_push_failed && - git-send-pack ../parent/.git +refs/heads/master:refs/heads/master && + git send-pack ../parent/.git +refs/heads/master:refs/heads/master && rewound_push_succeeded ' test_expect_success \ 'pushing wildcard refspecs respects forcing' ' rewound_push_setup && - if git-send-pack ../parent/.git refs/heads/*:refs/heads/* + if git send-pack ../parent/.git refs/heads/*:refs/heads/* then false else true fi && rewound_push_failed && - git-send-pack ../parent/.git +refs/heads/*:refs/heads/* && + git send-pack ../parent/.git +refs/heads/*:refs/heads/* && rewound_push_succeeded ' diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh index ee769d6695..64f66c94f3 100755 --- a/t/t5401-update-hooks.sh +++ b/t/t5401-update-hooks.sh @@ -17,7 +17,7 @@ test_expect_success setup ' commit1=$(echo modify | git commit-tree $tree1 -p $commit0) && git update-ref refs/heads/master $commit0 && git update-ref refs/heads/tofail $commit1 && - git-clone ./. victim && + git clone ./. victim && GIT_DIR=victim/.git git update-ref refs/heads/tofail $commit1 && git update-ref refs/heads/master $commit1 && git update-ref refs/heads/tofail $commit0 @@ -61,7 +61,7 @@ EOF chmod u+x victim/.git/hooks/post-update test_expect_success push ' - test_must_fail git-send-pack --force ./victim/.git \ + test_must_fail git send-pack --force ./victim/.git \ master tofail >send.out 2>send.err ' diff --git a/t/t5402-post-merge-hook.sh b/t/t5402-post-merge-hook.sh index 1394047a8d..6eb2ffd6ec 100755 --- a/t/t5402-post-merge-hook.sh +++ b/t/t5402-post-merge-hook.sh @@ -16,9 +16,9 @@ test_expect_success setup ' tree1=$(git write-tree) && commit1=$(echo modify | git commit-tree $tree1 -p $commit0) && git update-ref refs/heads/master $commit0 && - git-clone ./. clone1 && + git clone ./. clone1 && GIT_DIR=clone1/.git git update-index --add a && - git-clone ./. clone2 && + git clone ./. clone2 && GIT_DIR=clone2/.git git update-index --add a ' diff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh index 823239a251..9b2e1a94c5 100755 --- a/t/t5403-post-checkout-hook.sh +++ b/t/t5403-post-checkout-hook.sh @@ -14,8 +14,8 @@ test_expect_success setup ' tree0=$(git write-tree) && commit0=$(echo setup | git commit-tree $tree0) && git update-ref refs/heads/master $commit0 && - git-clone ./. clone1 && - git-clone ./. clone2 && + git clone ./. clone1 && + git clone ./. clone2 && GIT_DIR=clone2/.git git branch -a new2 && echo Data for commit1. >clone2/b && GIT_DIR=clone2/.git git add clone2/b && diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 7125baebb8..c450f33f33 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -58,7 +58,7 @@ pull_to_client () { cd client test_expect_success "$number pull" \ - "git-fetch-pack -k -v .. $heads" + "git fetch-pack -k -v .. $heads" case "$heads" in *A*) echo $ATIP > .git/refs/heads/A;; esac case "$heads" in *B*) echo $BTIP > .git/refs/heads/B;; esac git symbolic-ref HEAD refs/heads/`echo $heads | sed -e 's/^\(.\).*$/\1/'` @@ -129,7 +129,7 @@ pull_to_client 2nd "B" $((64*3)) pull_to_client 3rd "A" $((1*3)) # old fails -test_expect_success "clone shallow" 'git-clone --depth 2 "file://$(pwd)/." shallow' +test_expect_success "clone shallow" 'git clone --depth 2 "file://$(pwd)/." shallow' (cd shallow; git count-objects -v) > count.shallow diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index be9ee9326f..c4496635df 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -109,7 +109,7 @@ test_expect_success 'remove remote' ' cat > test/expect << EOF * remote origin - URL: $(pwd)/one/.git + URL: $(pwd)/one Remote branch merged with 'git pull' while on branch master master New remote branch (next fetch will store in remotes/origin) @@ -140,7 +140,7 @@ test_expect_success 'show' ' cat > test/expect << EOF * remote origin - URL: $(pwd)/one/.git + URL: $(pwd)/one Remote branch merged with 'git pull' while on branch master master Tracked remote branches @@ -169,7 +169,7 @@ test_expect_success 'prune' ' cat > test/expect << EOF Pruning origin -URL: $(pwd)/one/.git +URL: $(pwd)/one * [would prune] origin/side2 EOF diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 13d1d826c2..9aae4965da 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -111,7 +111,7 @@ test_expect_success 'fetch must not resolve short tag name' ' test_expect_success 'fetch must not resolve short remote name' ' cd "$D" && - git-update-ref refs/remotes/six/HEAD HEAD + git update-ref refs/remotes/six/HEAD HEAD mkdir six && cd six && @@ -303,4 +303,24 @@ test_expect_success 'pushing nonexistent branch by mistake should not segv' ' ' +test_expect_success 'auto tag following fetches minimum' ' + + cd "$D" && + git clone .git follow && + git checkout HEAD^0 && + ( + for i in 1 2 3 4 5 6 7 + do + echo $i >>file && + git commit -m $i -a && + git tag -a -m $i excess-$i || exit 1 + done + ) && + git checkout master && + ( + cd follow && + git fetch + ) +' + test_done diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh index 1a15817cd5..f5102b902a 100755 --- a/t/t5530-upload-pack-error.sh +++ b/t/t5530-upload-pack-error.sh @@ -34,7 +34,7 @@ test_expect_success 'upload-pack fails due to error in pack-objects' ' ! echo "0032want $(git rev-parse HEAD) 00000009done -0000" | git-upload-pack . > /dev/null 2> output.err && +0000" | git upload-pack . > /dev/null 2> output.err && grep "pack-objects died" output.err ' @@ -52,7 +52,7 @@ test_expect_success 'upload-pack fails due to error in rev-list' ' ! echo "0032want $(git rev-parse HEAD) 00000009done -0000" | git-upload-pack . > /dev/null 2> output.err && +0000" | git upload-pack . > /dev/null 2> output.err && grep "waitpid (async) failed" output.err ' diff --git a/t/t5600-clone-fail-cleanup.sh b/t/t5600-clone-fail-cleanup.sh index 3c013e2b6a..ee06d28649 100755 --- a/t/t5600-clone-fail-cleanup.sh +++ b/t/t5600-clone-fail-cleanup.sh @@ -3,9 +3,9 @@ # Copyright (C) 2006 Carl D. Worth <cworth@cworth.org> # -test_description='test git-clone to cleanup after failure +test_description='test git clone to cleanup after failure -This test covers the fact that if git-clone fails, it should remove +This test covers the fact that if git clone fails, it should remove the directory it created, to avoid the user having to manually remove the directory before attempting a clone again.' @@ -13,7 +13,7 @@ remove the directory before attempting a clone again.' test_expect_success \ 'clone of non-existent source should fail' \ - 'test_must_fail git-clone foo bar' + 'test_must_fail git clone foo bar' test_expect_success \ 'failed clone should not leave a directory' \ @@ -25,15 +25,15 @@ test_create_repo foo # clone doesn't like it if there is no HEAD. Is that a bug? (cd foo && touch file && git add file && git commit -m 'add file' >/dev/null 2>&1) -# source repository given to git-clone should be relative to the +# source repository given to git clone should be relative to the # current path not to the target dir test_expect_success \ 'clone of non-existent (relative to $PWD) source should fail' \ - 'test_must_fail git-clone ../foo baz' + 'test_must_fail git clone ../foo baz' test_expect_success \ 'clone should work now that source exists' \ - 'git-clone foo bar' + 'git clone foo bar' test_expect_success \ 'successful clone must leave the directory' \ diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 59c65fef28..78a3fa639c 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -107,4 +107,22 @@ test_expect_success 'clone --mirror does not repeat tags' ' ' +test_expect_success 'clone to destination with trailing /' ' + + git clone src target-1/ && + T=$( cd target-1 && git rev-parse HEAD ) && + S=$( cd src && git rev-parse HEAD ) && + test "$T" = "$S" + +' + +test_expect_success 'clone to destination with extra trailing /' ' + + git clone src target-2/// && + T=$( cd target-2 && git rev-parse HEAD ) && + S=$( cd src && git rev-parse HEAD ) && + test "$T" = "$S" + +' + test_done diff --git a/t/t5602-clone-remote-exec.sh b/t/t5602-clone-remote-exec.sh index 8367a6845f..82b1d1e2b3 100755 --- a/t/t5602-clone-remote-exec.sh +++ b/t/t5602-clone-remote-exec.sh @@ -11,13 +11,13 @@ test_expect_success setup ' chmod +x not_ssh ' -test_expect_success 'clone calls git-upload-pack unqualified with no -u option' ' +test_expect_success 'clone calls git upload-pack unqualified with no -u option' ' GIT_SSH=./not_ssh git clone localhost:/path/to/repo junk echo "localhost git-upload-pack '\''/path/to/repo'\''" >expected test_cmp expected not_ssh_output ' -test_expect_success 'clone calls specified git-upload-pack with -u option' ' +test_expect_success 'clone calls specified git upload-pack with -u option' ' GIT_SSH=./not_ssh git clone -u /something/bin/git-upload-pack localhost:/path/to/repo junk echo "localhost /something/bin/git-upload-pack '\''/path/to/repo'\''" >expected test_cmp expected not_ssh_output diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index 485ad4d44a..86bf7e14ba 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -6,8 +6,8 @@ test_description='git rev-list --pretty=format test' test_tick test_expect_success 'setup' ' -touch foo && git add foo && git-commit -m "added foo" && - echo changed >foo && git-commit -a -m "changed foo" +touch foo && git add foo && git commit -m "added foo" && + echo changed >foo && git commit -a -m "changed foo" ' # usage: test_format name format_string <expected_output @@ -110,7 +110,7 @@ include an iso8859 character: ¡bueno! EOF test_expect_success 'setup complex body' ' git config i18n.commitencoding iso8859-1 && - echo change2 >foo && git-commit -a -F commit-msg + echo change2 >foo && git commit -a -F commit-msg ' test_format complex-encoding %e <<'EOF' diff --git a/t/t6012-rev-list-simplify.sh b/t/t6012-rev-list-simplify.sh new file mode 100755 index 0000000000..510bb9679f --- /dev/null +++ b/t/t6012-rev-list-simplify.sh @@ -0,0 +1,93 @@ +#!/bin/sh + +test_description='merge simplification' + +. ./test-lib.sh + +note () { + git tag "$1" +} + +_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' +_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" + +unnote () { + git name-rev --tags --stdin | sed -e "s|$_x40 (tags/\([^)]*\)) |\1 |g" +} + +test_expect_success setup ' + echo "Hi there" >file && + git add file && + test_tick && git commit -m "Initial file" && + note A && + + git branch other-branch && + + echo "Hello" >file && + git add file && + test_tick && git commit -m "Modified file" && + note B && + + git checkout other-branch && + + echo "Hello" >file && + git add file && + test_tick && git commit -m "Modified the file identically" && + note C && + + echo "This is a stupid example" >another-file && + git add another-file && + test_tick && git commit -m "Add another file" && + note D && + + test_tick && git merge -m "merge" master && + note E && + + echo "Yet another" >elif && + git add elif && + test_tick && git commit -m "Irrelevant change" && + note F && + + git checkout master && + echo "Yet another" >elif && + git add elif && + test_tick && git commit -m "Another irrelevant change" && + note G && + + test_tick && git merge -m "merge" other-branch && + note H && + + echo "Final change" >file && + test_tick && git commit -a -m "Final change" && + note I +' + +FMT='tformat:%P %H | %s' + +check_result () { + for c in $1 + do + echo "$c" + done >expect && + shift && + param="$*" && + test_expect_success "log $param" ' + git log --pretty="$FMT" --parents $param | + unnote >actual && + sed -e "s/^.* \([^ ]*\) .*/\1/" >check <actual && + test_cmp expect check || { + cat actual + false + } + ' +} + +check_result 'I H G F E D C B A' --full-history +check_result 'I H E C B A' --full-history -- file +check_result 'I H E C B A' --full-history --topo-order -- file +check_result 'I H E C B A' --full-history --date-order -- file +check_result 'I E C B A' --simplify-merges -- file +check_result 'I B A' -- file +check_result 'I B A' --topo-order -- file + +test_done diff --git a/t/t6013-rev-list-reverse-parents.sh b/t/t6013-rev-list-reverse-parents.sh new file mode 100755 index 0000000000..59fc2f06e0 --- /dev/null +++ b/t/t6013-rev-list-reverse-parents.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +test_description='--reverse combines with --parents' + +. ./test-lib.sh + + +commit () { + test_tick && + echo $1 > foo && + git add foo && + git commit -m "$1" +} + +test_expect_success 'set up --reverse example' ' + commit one && + git tag root && + commit two && + git checkout -b side HEAD^ && + commit three && + git checkout master && + git merge -s ours side && + commit five + ' + +test_expect_success '--reverse --parents --full-history combines correctly' ' + git rev-list --parents --full-history master -- foo | + perl -e "print reverse <>" > expected && + git rev-list --reverse --parents --full-history master -- foo \ + > actual && + test_cmp actual expected + ' + +test_expect_success '--boundary does too' ' + git rev-list --boundary --parents --full-history master ^root -- foo | + perl -e "print reverse <>" > expected && + git rev-list --boundary --reverse --parents --full-history \ + master ^root -- foo > actual && + test_cmp actual expected + ' + +test_done diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh index 42620e0732..5e18d68c97 100755 --- a/t/t6023-merge-file.sh +++ b/t/t6023-merge-file.sh @@ -150,8 +150,8 @@ test_expect_success 'MERGE_ZEALOUS simplifies non-conflicts' ' ' -sed -e 's/deerit./&\n\n\n\n/' -e "s/locavit,/locavit;/" < new6.txt > new8.txt -sed -e 's/deerit./&\n\n\n\n/' -e "s/locavit,/locavit --/" < new7.txt > new9.txt +sed -e 's/deerit./&%%%%/' -e "s/locavit,/locavit;/"< new6.txt | tr '%' '\012' > new8.txt +sed -e 's/deerit./&%%%%/' -e "s/locavit,/locavit --/" < new7.txt | tr '%' '\012' > new9.txt test_expect_success 'ZEALOUS_ALNUM' ' diff --git a/t/t6025-merge-symlinks.sh b/t/t6025-merge-symlinks.sh index fc58456a11..53892a555c 100755 --- a/t/t6025-merge-symlinks.sh +++ b/t/t6025-merge-symlinks.sh @@ -5,7 +5,7 @@ test_description='merging symlinks on filesystem w/o symlink support. -This tests that git-merge-recursive writes merge results as plain files +This tests that git merge-recursive writes merge results as plain files if core.symlinks is false.' . ./test-lib.sh @@ -15,25 +15,25 @@ test_expect_success \ git config core.symlinks false && > file && git add file && -git-commit -m initial && +git commit -m initial && git branch b-symlink && git branch b-file && -l=$(echo -n file | git-hash-object -t blob -w --stdin) && +l=$(echo -n file | git hash-object -t blob -w --stdin) && echo "120000 $l symlink" | git update-index --index-info && -git-commit -m master && -git-checkout b-symlink && -l=$(echo -n file-different | git-hash-object -t blob -w --stdin) && +git commit -m master && +git checkout b-symlink && +l=$(echo -n file-different | git hash-object -t blob -w --stdin) && echo "120000 $l symlink" | git update-index --index-info && -git-commit -m b-symlink && -git-checkout b-file && +git commit -m b-symlink && +git checkout b-file && echo plain-file > symlink && git add symlink && -git-commit -m b-file' +git commit -m b-file' test_expect_success \ 'merge master into b-symlink, which has a different symbolic link' ' -git-checkout b-symlink && -test_must_fail git-merge master' +git checkout b-symlink && +test_must_fail git merge master' test_expect_success \ 'the merge result must be a file' ' @@ -41,8 +41,8 @@ test -f symlink' test_expect_success \ 'merge master into b-file, which has a file instead of a symbolic link' ' -git-reset --hard && git-checkout b-file && -test_must_fail git-merge master' +git reset --hard && git checkout b-file && +test_must_fail git merge master' test_expect_success \ 'the merge result must be a file' ' @@ -50,9 +50,9 @@ test -f symlink' test_expect_success \ 'merge b-file, which has a file instead of a symbolic link, into master' ' -git-reset --hard && -git-checkout master && -test_must_fail git-merge b-file' +git reset --hard && +git checkout master && +test_must_fail git merge b-file' test_expect_success \ 'the merge result must be a file' ' diff --git a/t/t6026-merge-attr.sh b/t/t6026-merge-attr.sh index 86f47ca595..1ba0a25223 100755 --- a/t/t6026-merge-attr.sh +++ b/t/t6026-merge-attr.sh @@ -106,9 +106,9 @@ test_expect_success 'custom merge backend' ' cmp binary union && sed -e 1,3d text >check-1 && - o=$(git-unpack-file master^:text) && - a=$(git-unpack-file side^:text) && - b=$(git-unpack-file master:text) && + o=$(git unpack-file master^:text) && + a=$(git unpack-file side^:text) && + b=$(git unpack-file master:text) && sh -c "./custom-merge $o $a $b 0" && sed -e 1,3d $a >check-2 && cmp check-1 check-2 && @@ -133,9 +133,9 @@ test_expect_success 'custom merge backend' ' cmp binary union && sed -e 1,3d text >check-1 && - o=$(git-unpack-file master^:text) && - a=$(git-unpack-file anchor:text) && - b=$(git-unpack-file master:text) && + o=$(git unpack-file master^:text) && + a=$(git unpack-file anchor:text) && + b=$(git unpack-file master:text) && sh -c "./custom-merge $o $a $b 0" && sed -e 1,3d $a >check-2 && cmp check-1 check-2 && diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 244fda62a5..85fa39cf0b 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -2,7 +2,7 @@ # # Copyright (c) 2007 Christian Couder # -test_description='Tests git-bisect functionality' +test_description='Tests git bisect functionality' exec </dev/null @@ -23,7 +23,7 @@ add_line_into_file() fi test_tick - git-commit --quiet -m "$MSG" $_file + git commit --quiet -m "$MSG" $_file } HASH1= @@ -350,6 +350,120 @@ test_expect_success 'bisect does not create a "bisect" branch' ' git branch -D bisect ' +# This creates a "side" branch to test "siblings" cases. +# +# H1-H2-H3-H4-H5-H6-H7 <--other +# \ +# S5-S6-S7 <--side +# +test_expect_success 'side branch creation' ' + git bisect reset && + git checkout -b side $HASH4 && + add_line_into_file "5(side): first line on a side branch" hello2 && + SIDE_HASH5=$(git rev-parse --verify HEAD) && + add_line_into_file "6(side): second line on a side branch" hello2 && + SIDE_HASH6=$(git rev-parse --verify HEAD) && + add_line_into_file "7(side): third line on a side branch" hello2 && + SIDE_HASH7=$(git rev-parse --verify HEAD) +' + +test_expect_success 'good merge base when good and bad are siblings' ' + git bisect start "$HASH7" "$SIDE_HASH7" > my_bisect_log.txt && + grep "merge base must be tested" my_bisect_log.txt && + grep $HASH4 my_bisect_log.txt && + git bisect good > my_bisect_log.txt && + test_must_fail grep "merge base must be tested" my_bisect_log.txt && + grep $HASH6 my_bisect_log.txt && + git bisect reset +' +test_expect_success 'skipped merge base when good and bad are siblings' ' + git bisect start "$SIDE_HASH7" "$HASH7" > my_bisect_log.txt && + grep "merge base must be tested" my_bisect_log.txt && + grep $HASH4 my_bisect_log.txt && + git bisect skip > my_bisect_log.txt 2>&1 && + grep "Warning" my_bisect_log.txt && + grep $SIDE_HASH6 my_bisect_log.txt && + git bisect reset +' + +test_expect_success 'bad merge base when good and bad are siblings' ' + git bisect start "$HASH7" HEAD > my_bisect_log.txt && + grep "merge base must be tested" my_bisect_log.txt && + grep $HASH4 my_bisect_log.txt && + test_must_fail git bisect bad > my_bisect_log.txt 2>&1 && + grep "merge base $HASH4 is bad" my_bisect_log.txt && + grep "fixed between $HASH4 and \[$SIDE_HASH7\]" my_bisect_log.txt && + git bisect reset +' + +# This creates a few more commits (A and B) to test "siblings" cases +# when a good and a bad rev have many merge bases. +# +# We should have the following: +# +# H1-H2-H3-H4-H5-H6-H7 +# \ \ \ +# S5-A \ +# \ \ +# S6-S7----B +# +# And there A and B have 2 merge bases (S5 and H5) that should be +# reported by "git merge-base --all A B". +# +test_expect_success 'many merge bases creation' ' + git checkout "$SIDE_HASH5" && + git merge -m "merge HASH5 and SIDE_HASH5" "$HASH5" && + A_HASH=$(git rev-parse --verify HEAD) && + git checkout side && + git merge -m "merge HASH7 and SIDE_HASH7" "$HASH7" && + B_HASH=$(git rev-parse --verify HEAD) && + git merge-base --all "$A_HASH" "$B_HASH" > merge_bases.txt && + test $(wc -l < merge_bases.txt) = "2" && + grep "$HASH5" merge_bases.txt && + grep "$SIDE_HASH5" merge_bases.txt +' + +test_expect_success 'good merge bases when good and bad are siblings' ' + git bisect start "$B_HASH" "$A_HASH" > my_bisect_log.txt && + grep "merge base must be tested" my_bisect_log.txt && + git bisect good > my_bisect_log2.txt && + grep "merge base must be tested" my_bisect_log2.txt && + { + { + grep "$SIDE_HASH5" my_bisect_log.txt && + grep "$HASH5" my_bisect_log2.txt + } || { + grep "$SIDE_HASH5" my_bisect_log2.txt && + grep "$HASH5" my_bisect_log.txt + } + } && + git bisect reset +' + +check_trace() { + grep "$1" "$GIT_TRACE" | grep "\^$2" | grep "$3" >/dev/null +} + +test_expect_success 'optimized merge base checks' ' + GIT_TRACE="$(pwd)/trace.log" && + export GIT_TRACE && + git bisect start "$HASH7" "$SIDE_HASH7" > my_bisect_log.txt && + grep "merge base must be tested" my_bisect_log.txt && + grep "$HASH4" my_bisect_log.txt && + check_trace "rev-list" "$HASH7" "$SIDE_HASH7" && + git bisect good > my_bisect_log2.txt && + test -f ".git/BISECT_ANCESTORS_OK" && + test "$HASH6" = $(git rev-parse --verify HEAD) && + : > "$GIT_TRACE" && + git bisect bad > my_bisect_log3.txt && + test_must_fail check_trace "rev-list" "$HASH6" "$SIDE_HASH7" && + git bisect good "$A_HASH" > my_bisect_log4.txt && + grep "merge base must be tested" my_bisect_log4.txt && + test_must_fail test -f ".git/BISECT_ANCESTORS_OK" && + check_trace "rev-list" "$HASH6" "$A_HASH" && + unset GIT_TRACE +' + # # test_done diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index 2fb672c3b4..16cc635813 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -31,57 +31,57 @@ check_describe () { test_expect_success setup ' test_tick && - echo one >file && git add file && git-commit -m initial && + echo one >file && git add file && git commit -m initial && one=$(git rev-parse HEAD) && test_tick && - echo two >file && git add file && git-commit -m second && + echo two >file && git add file && git commit -m second && two=$(git rev-parse HEAD) && test_tick && - echo three >file && git add file && git-commit -m third && + echo three >file && git add file && git commit -m third && test_tick && - echo A >file && git add file && git-commit -m A && + echo A >file && git add file && git commit -m A && test_tick && - git-tag -a -m A A && + git tag -a -m A A && test_tick && - echo c >file && git add file && git-commit -m c && + echo c >file && git add file && git commit -m c && test_tick && - git-tag c && + git tag c && git reset --hard $two && test_tick && - echo B >side && git add side && git-commit -m B && + echo B >side && git add side && git commit -m B && test_tick && - git-tag -a -m B B && + git tag -a -m B B && test_tick && - git-merge -m Merged c && + git merge -m Merged c && merged=$(git rev-parse HEAD) && git reset --hard $two && test_tick && - echo D >another && git add another && git-commit -m D && + echo D >another && git add another && git commit -m D && test_tick && - git-tag -a -m D D && + git tag -a -m D D && test_tick && echo DD >another && git commit -a -m another && test_tick && - git-tag e && + git tag e && test_tick && echo DDD >another && git commit -a -m "yet another" && test_tick && - git-merge -m Merged $merged && + git merge -m Merged $merged && test_tick && echo X >file && echo X >side && git add file side && - git-commit -m x + git commit -m x ' diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 8ced59321e..8bfae44a83 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -97,27 +97,27 @@ test_atom tag contents 'Tagging at 1151939927 ' test_expect_success 'Check invalid atoms names are errors' ' - test_must_fail git-for-each-ref --format="%(INVALID)" refs/heads + test_must_fail git for-each-ref --format="%(INVALID)" refs/heads ' test_expect_success 'Check format specifiers are ignored in naming date atoms' ' - git-for-each-ref --format="%(authordate)" refs/heads && - git-for-each-ref --format="%(authordate:default) %(authordate)" refs/heads && - git-for-each-ref --format="%(authordate) %(authordate:default)" refs/heads && - git-for-each-ref --format="%(authordate:default) %(authordate:default)" refs/heads + git for-each-ref --format="%(authordate)" refs/heads && + git for-each-ref --format="%(authordate:default) %(authordate)" refs/heads && + git for-each-ref --format="%(authordate) %(authordate:default)" refs/heads && + git for-each-ref --format="%(authordate:default) %(authordate:default)" refs/heads ' test_expect_success 'Check valid format specifiers for date fields' ' - git-for-each-ref --format="%(authordate:default)" refs/heads && - git-for-each-ref --format="%(authordate:relative)" refs/heads && - git-for-each-ref --format="%(authordate:short)" refs/heads && - git-for-each-ref --format="%(authordate:local)" refs/heads && - git-for-each-ref --format="%(authordate:iso8601)" refs/heads && - git-for-each-ref --format="%(authordate:rfc2822)" refs/heads + git for-each-ref --format="%(authordate:default)" refs/heads && + git for-each-ref --format="%(authordate:relative)" refs/heads && + git for-each-ref --format="%(authordate:short)" refs/heads && + git for-each-ref --format="%(authordate:local)" refs/heads && + git for-each-ref --format="%(authordate:iso8601)" refs/heads && + git for-each-ref --format="%(authordate:rfc2822)" refs/heads ' test_expect_success 'Check invalid format specifiers are errors' ' - test_must_fail git-for-each-ref --format="%(authordate:INVALID)" refs/heads + test_must_fail git for-each-ref --format="%(authordate:INVALID)" refs/heads ' cat >expected <<\EOF @@ -207,7 +207,7 @@ refs/tags/testtag EOF test_expect_success 'Verify ascending sort' ' - git-for-each-ref --format="%(refname)" --sort=refname >actual && + git for-each-ref --format="%(refname)" --sort=refname >actual && test_cmp expected actual ' @@ -218,7 +218,7 @@ refs/heads/master EOF test_expect_success 'Verify descending sort' ' - git-for-each-ref --format="%(refname)" --sort=-refname >actual && + git for-each-ref --format="%(refname)" --sort=-refname >actual && test_cmp expected actual ' @@ -262,6 +262,50 @@ for i in "--perl --shell" "-s --python" "--python --tcl" "--tcl --perl"; do " done +cat >expected <<\EOF +master +testtag +EOF + +test_expect_success 'Check short refname format' ' + (git for-each-ref --format="%(refname:short)" refs/heads && + git for-each-ref --format="%(refname:short)" refs/tags) >actual && + test_cmp expected actual +' + +test_expect_success 'Check for invalid refname format' ' + test_must_fail git for-each-ref --format="%(refname:INVALID)" +' + +cat >expected <<\EOF +heads/master +master +EOF + +test_expect_success 'Check ambiguous head and tag refs' ' + git checkout -b newtag && + echo "Using $datestamp" > one && + git add one && + git commit -m "Branch" && + setdate_and_increment && + git tag -m "Tagging at $datestamp" master && + git for-each-ref --format "%(refname:short)" refs/heads/master refs/tags/master >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +heads/ambiguous +ambiguous +EOF + +test_expect_success 'Check ambiguous head and tag refs II' ' + git checkout master && + git tag ambiguous testtag^0 && + git branch ambiguous testtag^0 && + git for-each-ref --format "%(refname:short)" refs/heads/ambiguous refs/tags/ambiguous >actual && + test_cmp expected actual +' + test_expect_success 'an unusual tag with an incomplete line' ' git tag -m "bogo" bogo && diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 78167980b3..575ef5beb2 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -8,7 +8,7 @@ test_expect_success \ 'mkdir path0 path1 && cp "$TEST_DIRECTORY"/../COPYING path0/COPYING && git add path0/COPYING && - git-commit -m add -a' + git commit -m add -a' test_expect_success \ 'moving the file out of subdirectory' \ @@ -17,7 +17,7 @@ test_expect_success \ # in path0 currently test_expect_success \ 'commiting the change' \ - 'cd .. && git-commit -m move-out -a' + 'cd .. && git commit -m move-out -a' test_expect_success \ 'checking the commit' \ @@ -31,7 +31,7 @@ test_expect_success \ # in path0 currently test_expect_success \ 'commiting the change' \ - 'cd .. && git-commit -m move-in -a' + 'cd .. && git commit -m move-in -a' test_expect_success \ 'checking the commit' \ @@ -42,7 +42,7 @@ test_expect_success \ 'adding another file' \ 'cp "$TEST_DIRECTORY"/../README path0/README && git add path0/README && - git-commit -m add2 -a' + git commit -m add2 -a' test_expect_success \ 'moving whole subdirectory' \ @@ -50,7 +50,7 @@ test_expect_success \ test_expect_success \ 'commiting the change' \ - 'git-commit -m dir-move -a' + 'git commit -m dir-move -a' test_expect_success \ 'checking the commit' \ @@ -69,7 +69,7 @@ test_expect_success \ test_expect_success \ 'commiting the change' \ - 'git-commit -m dir-move -a' + 'git commit -m dir-move -a' test_expect_success \ 'checking the commit' \ diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh index c8b4f65f38..5e359cb561 100755 --- a/t/t7002-grep.sh +++ b/t/t7002-grep.sh @@ -22,6 +22,7 @@ test_expect_success setup ' mkdir t && echo test >t/t && git add file x y z t/t && + test_tick && git commit -m initial ' @@ -113,4 +114,54 @@ do done +test_expect_success 'log grep setup' ' + echo a >>file && + test_tick && + GIT_AUTHOR_NAME="With * Asterisk" \ + GIT_AUTHOR_EMAIL="xyzzy@frotz.com" \ + git commit -a -m "second" && + + echo a >>file && + test_tick && + git commit -a -m "third" + +' + +test_expect_success 'log grep (1)' ' + git log --author=author --pretty=tformat:%s >actual && + ( echo third ; echo initial ) >expect && + test_cmp expect actual +' + +test_expect_success 'log grep (2)' ' + git log --author=" * " -F --pretty=tformat:%s >actual && + ( echo second ) >expect && + test_cmp expect actual +' + +test_expect_success 'log grep (3)' ' + git log --author="^A U" --pretty=tformat:%s >actual && + ( echo third ; echo initial ) >expect && + test_cmp expect actual +' + +test_expect_success 'log grep (4)' ' + git log --author="frotz\.com>$" --pretty=tformat:%s >actual && + ( echo second ) >expect && + test_cmp expect actual +' + +test_expect_success 'log grep (5)' ' + git log --author=Thor -F --grep=Thu --pretty=tformat:%s >actual && + ( echo third ; echo initial ) >expect && + test_cmp expect actual +' + +test_expect_success 'log grep (6)' ' + git log --author=-0700 --pretty=tformat:%s >actual && + >expect && + test_cmp expect actual + +' + test_done diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index f92d414e63..b0a9d7d536 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-filter-branch' +test_description='git filter-branch' . ./test-lib.sh make_commit () { @@ -32,14 +32,14 @@ test_expect_success 'setup' ' H=$(git rev-parse H) test_expect_success 'rewrite identically' ' - git-filter-branch branch + git filter-branch branch ' test_expect_success 'result is really identical' ' test $H = $(git rev-parse HEAD) ' 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) ' git config core.bare false test_expect_success 'result is really identical' ' @@ -47,7 +47,7 @@ test_expect_success 'result is really identical' ' ' test_expect_success 'rewrite, renaming a specific file' ' - git-filter-branch -f --tree-filter "mv d doh || :" HEAD + git filter-branch -f --tree-filter "mv d doh || :" HEAD ' test_expect_success 'test that the file was renamed' ' @@ -58,7 +58,7 @@ test_expect_success 'test that the file was renamed' ' ' test_expect_success 'rewrite, renaming a specific directory' ' - git-filter-branch -f --tree-filter "mv dir diroh || :" HEAD + git filter-branch -f --tree-filter "mv dir diroh || :" HEAD ' test_expect_success 'test that the directory was renamed' ' @@ -73,7 +73,7 @@ test_expect_success 'test that the directory was renamed' ' git tag oldD HEAD~4 test_expect_success 'rewrite one branch, keeping a side branch' ' git branch modD oldD && - git-filter-branch -f --tree-filter "mv b boh || :" D..modD + git filter-branch -f --tree-filter "mv b boh || :" D..modD ' test_expect_success 'common ancestor is still common (unchanged)' ' @@ -96,13 +96,17 @@ test_expect_success 'filter subdirectory only' ' test_tick && git commit -m "again not subdir" && git branch sub && - git-filter-branch -f --subdirectory-filter subdir refs/heads/sub + git branch sub-earlier HEAD~2 && + git filter-branch -f --subdirectory-filter subdir \ + refs/heads/sub refs/heads/sub-earlier ' test_expect_success 'subdirectory filter result looks okay' ' test 2 = $(git rev-list sub | wc -l) && git show sub:new && - test_must_fail git show sub:subdir + test_must_fail git show sub:subdir && + git show sub-earlier:new && + test_must_fail git show sub-earlier:subdir ' test_expect_success 'more setup' ' @@ -120,7 +124,7 @@ test_expect_success 'more setup' ' test_expect_success 'use index-filter to move into a subdirectory' ' git branch directorymoved && - git-filter-branch -f --index-filter \ + git filter-branch -f --index-filter \ "git ls-files -s | sed \"s-\\t-&newsubdir/-\" | GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \ git update-index --index-info && @@ -129,7 +133,7 @@ test_expect_success 'use index-filter to move into a subdirectory' ' test_expect_success 'stops when msg filter fails' ' old=$(git rev-parse HEAD) && - test_must_fail git-filter-branch -f --msg-filter false HEAD && + test_must_fail git filter-branch -f --msg-filter false HEAD && test $old = $(git rev-parse HEAD) && rm -rf .git-rewrite ' @@ -140,7 +144,7 @@ test_expect_success 'author information is preserved' ' test_tick && GIT_AUTHOR_NAME="B V Uips" git commit -m bvuips && git branch preserved-author && - git-filter-branch -f --msg-filter "cat; \ + git filter-branch -f --msg-filter "cat; \ test \$GIT_COMMIT != $(git rev-parse master) || \ echo Hallo" \ preserved-author && @@ -152,7 +156,7 @@ test_expect_success "remove a certain author's commits" ' test_tick && git commit -m i i && git branch removed-author && - git-filter-branch -f --commit-filter "\ + git filter-branch -f --commit-filter "\ if [ \"\$GIT_AUTHOR_NAME\" = \"B V Uips\" ];\ then\ skip_commit \"\$@\"; diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 198244c57d..f0edbf1a76 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Carlos Rica # -test_description='git-tag +test_description='git tag Tests for operations with tags.' @@ -22,25 +22,25 @@ test_expect_success 'listing all tags in an empty tree should succeed' ' ' test_expect_success 'listing all tags in an empty tree should output nothing' ' - test `git-tag -l | wc -l` -eq 0 && - test `git-tag | wc -l` -eq 0 + test `git tag -l | wc -l` -eq 0 && + test `git tag | wc -l` -eq 0 ' test_expect_success 'looking for a tag in an empty tree should fail' \ '! (tag_exists mytag)' test_expect_success 'creating a tag in an empty tree should fail' ' - test_must_fail git-tag mynotag && + test_must_fail git tag mynotag && ! tag_exists mynotag ' test_expect_success 'creating a tag for HEAD in an empty tree should fail' ' - test_must_fail git-tag mytaghead HEAD && + test_must_fail git tag mytaghead HEAD && ! tag_exists mytaghead ' test_expect_success 'creating a tag for an unknown revision should fail' ' - test_must_fail git-tag mytagnorev aaaaaaaaaaa && + test_must_fail git tag mytagnorev aaaaaaaaaaa && ! tag_exists mytagnorev ' @@ -54,32 +54,32 @@ test_expect_success 'creating a tag using default HEAD should succeed' ' ' test_expect_success 'listing all tags if one exists should succeed' ' - git-tag -l && - git-tag + git tag -l && + git tag ' test_expect_success 'listing all tags if one exists should output that tag' ' - test `git-tag -l` = mytag && - test `git-tag` = mytag + test `git tag -l` = mytag && + test `git tag` = mytag ' # pattern matching: test_expect_success 'listing a tag using a matching pattern should succeed' \ - 'git-tag -l mytag' + 'git tag -l mytag' test_expect_success \ 'listing a tag using a matching pattern should output that tag' \ - 'test `git-tag -l mytag` = mytag' + 'test `git tag -l mytag` = mytag' # todo: git tag -l now returns always zero, when fixed, change this test test_expect_success \ 'listing tags using a non-matching pattern should suceed' \ - 'git-tag -l xxx' + 'git tag -l xxx' test_expect_success \ 'listing tags using a non-matching pattern should output nothing' \ - 'test `git-tag -l xxx | wc -l` -eq 0' + 'test `git tag -l xxx | wc -l` -eq 0' # special cases for creating tags: @@ -89,13 +89,13 @@ test_expect_success \ test_expect_success \ 'trying to create a tag with a non-valid name should fail' ' - test `git-tag -l | wc -l` -eq 1 && + test `git tag -l | wc -l` -eq 1 && test_must_fail git tag "" && test_must_fail git tag .othertag && test_must_fail git tag "other tag" && test_must_fail git tag "othertag^" && test_must_fail git tag "other~tag" && - test `git-tag -l | wc -l` -eq 1 + test `git tag -l | wc -l` -eq 1 ' test_expect_success 'creating a tag using HEAD directly should succeed' ' @@ -107,7 +107,7 @@ test_expect_success 'creating a tag using HEAD directly should succeed' ' test_expect_success 'trying to delete an unknown tag should fail' ' ! tag_exists unknown-tag && - test_must_fail git-tag -d unknown-tag + test_must_fail git tag -d unknown-tag ' cat >expect <<EOF @@ -117,7 +117,7 @@ EOF test_expect_success \ 'trying to delete tags without params should succeed and do nothing' ' git tag -l > actual && test_cmp expect actual && - git-tag -d && + git tag -d && git tag -l > actual && test_cmp expect actual ' @@ -125,7 +125,7 @@ test_expect_success \ 'deleting two existing tags in one command should succeed' ' tag_exists mytag && tag_exists myhead && - git-tag -d mytag myhead && + git tag -d mytag myhead && ! tag_exists mytag && ! tag_exists myhead ' @@ -133,7 +133,7 @@ test_expect_success \ test_expect_success \ 'creating a tag with the name of another deleted one should succeed' ' ! tag_exists mytag && - git-tag mytag && + git tag mytag && tag_exists mytag ' @@ -141,13 +141,13 @@ test_expect_success \ 'trying to delete two tags, existing and not, should fail in the 2nd' ' tag_exists mytag && ! tag_exists myhead && - test_must_fail git-tag -d mytag anothertag && + test_must_fail git tag -d mytag anothertag && ! tag_exists mytag && ! tag_exists myhead ' test_expect_success 'trying to delete an already deleted tag should fail' \ - 'test_must_fail git-tag -d mytag' + 'test_must_fail git tag -d mytag' # listing various tags with pattern matching: @@ -185,7 +185,7 @@ cba EOF test_expect_success \ 'listing tags with substring as pattern must print those matching' ' - git-tag -l "*a*" > actual && + git tag -l "*a*" > actual && test_cmp expect actual ' @@ -195,7 +195,7 @@ v1.0.1 EOF test_expect_success \ 'listing tags with a suffix as pattern must print those matching' ' - git-tag -l "*.1" > actual && + git tag -l "*.1" > actual && test_cmp expect actual ' @@ -205,7 +205,7 @@ t211 EOF test_expect_success \ 'listing tags with a prefix as pattern must print those matching' ' - git-tag -l "t21*" > actual && + git tag -l "t21*" > actual && test_cmp expect actual ' @@ -214,7 +214,7 @@ a1 EOF test_expect_success \ 'listing tags using a name as pattern must print that one matching' ' - git-tag -l a1 > actual && + git tag -l a1 > actual && test_cmp expect actual ' @@ -223,7 +223,7 @@ v1.0 EOF test_expect_success \ 'listing tags using a name as pattern must print that one matching' ' - git-tag -l v1.0 > actual && + git tag -l v1.0 > actual && test_cmp expect actual ' @@ -233,14 +233,14 @@ v1.1.3 EOF test_expect_success \ 'listing tags with ? in the pattern should print those matching' ' - git-tag -l "v1.?.?" > actual && + git tag -l "v1.?.?" > actual && test_cmp expect actual ' >expect test_expect_success \ 'listing tags using v.* should print nothing because none have v.' ' - git-tag -l "v.*" > actual && + git tag -l "v.*" > actual && test_cmp expect actual ' @@ -252,7 +252,7 @@ v1.1.3 EOF test_expect_success \ 'listing tags using v* should print only those having v' ' - git-tag -l "v*" > actual && + git tag -l "v*" > actual && test_cmp expect actual ' @@ -260,21 +260,21 @@ test_expect_success \ test_expect_success \ 'a non-annotated tag created without parameters should point to HEAD' ' - git-tag non-annotated-tag && + git tag non-annotated-tag && test $(git cat-file -t non-annotated-tag) = commit && test $(git rev-parse non-annotated-tag) = $(git rev-parse HEAD) ' test_expect_success 'trying to verify an unknown tag should fail' \ - 'test_must_fail git-tag -v unknown-tag' + 'test_must_fail git tag -v unknown-tag' test_expect_success \ 'trying to verify a non-annotated and non-signed tag should fail' \ - 'test_must_fail git-tag -v non-annotated-tag' + 'test_must_fail git tag -v non-annotated-tag' test_expect_success \ 'trying to verify many non-annotated or unknown tags, should fail' \ - 'test_must_fail git-tag -v unknown-tag1 non-annotated-tag unknown-tag2' + 'test_must_fail git tag -v unknown-tag1 non-annotated-tag unknown-tag2' # creating annotated tags: @@ -300,7 +300,7 @@ get_tag_header annotated-tag $commit commit $time >expect echo "A message" >>expect test_expect_success \ 'creating an annotated tag with -m message should succeed' ' - git-tag -m "A message" annotated-tag && + git tag -m "A message" annotated-tag && get_tag_msg annotated-tag >actual && test_cmp expect actual ' @@ -313,7 +313,7 @@ get_tag_header file-annotated-tag $commit commit $time >expect cat msgfile >>expect test_expect_success \ 'creating an annotated tag with -F messagefile should succeed' ' - git-tag -F msgfile file-annotated-tag && + git tag -F msgfile file-annotated-tag && get_tag_msg file-annotated-tag >actual && test_cmp expect actual ' @@ -325,7 +325,7 @@ EOF get_tag_header stdin-annotated-tag $commit commit $time >expect cat inputmsg >>expect test_expect_success 'creating an annotated tag with -F - should succeed' ' - git-tag -F - stdin-annotated-tag <inputmsg && + git tag -F - stdin-annotated-tag <inputmsg && get_tag_msg stdin-annotated-tag >actual && test_cmp expect actual ' @@ -334,7 +334,7 @@ test_expect_success \ 'trying to create a tag with a non-existing -F file should fail' ' ! test -f nonexistingfile && ! tag_exists notag && - test_must_fail git-tag -F nonexistingfile notag && + test_must_fail git tag -F nonexistingfile notag && ! tag_exists notag ' @@ -343,11 +343,11 @@ test_expect_success \ echo "message file 1" >msgfile1 && echo "message file 2" >msgfile2 && ! tag_exists msgtag && - test_must_fail git-tag -m "message 1" -F msgfile1 msgtag && + test_must_fail git tag -m "message 1" -F msgfile1 msgtag && ! tag_exists msgtag && - test_must_fail git-tag -F msgfile1 -m "message 1" msgtag && + test_must_fail git tag -F msgfile1 -m "message 1" msgtag && ! tag_exists msgtag && - test_must_fail git-tag -m "message 1" -F msgfile1 \ + test_must_fail git tag -m "message 1" -F msgfile1 \ -m "message 2" msgtag && ! tag_exists msgtag ' @@ -357,7 +357,7 @@ test_expect_success \ get_tag_header empty-annotated-tag $commit commit $time >expect test_expect_success \ 'creating a tag with an empty -m message should succeed' ' - git-tag -m "" empty-annotated-tag && + git tag -m "" empty-annotated-tag && get_tag_msg empty-annotated-tag >actual && test_cmp expect actual ' @@ -366,7 +366,7 @@ test_expect_success \ get_tag_header emptyfile-annotated-tag $commit commit $time >expect test_expect_success \ 'creating a tag with an empty -F messagefile should succeed' ' - git-tag -F emptyfile emptyfile-annotated-tag && + git tag -F emptyfile emptyfile-annotated-tag && get_tag_msg emptyfile-annotated-tag >actual && test_cmp expect actual ' @@ -387,7 +387,7 @@ Trailing blank lines EOF test_expect_success \ 'extra blanks in the message for an annotated tag should be removed' ' - git-tag -F blanksfile blanks-annotated-tag && + git tag -F blanksfile blanks-annotated-tag && get_tag_msg blanks-annotated-tag >actual && test_cmp expect actual ' @@ -395,7 +395,7 @@ test_expect_success \ get_tag_header blank-annotated-tag $commit commit $time >expect test_expect_success \ 'creating a tag with blank -m message with spaces should succeed' ' - git-tag -m " " blank-annotated-tag && + git tag -m " " blank-annotated-tag && get_tag_msg blank-annotated-tag >actual && test_cmp expect actual ' @@ -406,7 +406,7 @@ echo ' ' >>blankfile get_tag_header blankfile-annotated-tag $commit commit $time >expect test_expect_success \ 'creating a tag with blank -F messagefile with spaces should succeed' ' - git-tag -F blankfile blankfile-annotated-tag && + git tag -F blankfile blankfile-annotated-tag && get_tag_msg blankfile-annotated-tag >actual && test_cmp expect actual ' @@ -415,7 +415,7 @@ printf ' ' >blanknonlfile get_tag_header blanknonlfile-annotated-tag $commit commit $time >expect test_expect_success \ 'creating a tag with -F file of spaces and no newline should succeed' ' - git-tag -F blanknonlfile blanknonlfile-annotated-tag && + git tag -F blanknonlfile blanknonlfile-annotated-tag && get_tag_msg blanknonlfile-annotated-tag >actual && test_cmp expect actual ' @@ -450,7 +450,7 @@ Last line. EOF test_expect_success \ 'creating a tag using a -F messagefile with #comments should succeed' ' - git-tag -F commentsfile comments-annotated-tag && + git tag -F commentsfile comments-annotated-tag && get_tag_msg comments-annotated-tag >actual && test_cmp expect actual ' @@ -458,7 +458,7 @@ test_expect_success \ get_tag_header comment-annotated-tag $commit commit $time >expect test_expect_success \ 'creating a tag with a #comment in the -m message should succeed' ' - git-tag -m "#comment" comment-annotated-tag && + git tag -m "#comment" comment-annotated-tag && get_tag_msg comment-annotated-tag >actual && test_cmp expect actual ' @@ -469,7 +469,7 @@ echo '####' >>commentfile get_tag_header commentfile-annotated-tag $commit commit $time >expect test_expect_success \ 'creating a tag with #comments in the -F messagefile should succeed' ' - git-tag -F commentfile commentfile-annotated-tag && + git tag -F commentfile commentfile-annotated-tag && get_tag_msg commentfile-annotated-tag >actual && test_cmp expect actual ' @@ -478,7 +478,7 @@ printf '#comment' >commentnonlfile get_tag_header commentnonlfile-annotated-tag $commit commit $time >expect test_expect_success \ 'creating a tag with a file of #comment and no newline should succeed' ' - git-tag -F commentnonlfile commentnonlfile-annotated-tag && + git tag -F commentnonlfile commentnonlfile-annotated-tag && get_tag_msg commentnonlfile-annotated-tag >actual && test_cmp expect actual ' @@ -487,51 +487,51 @@ test_expect_success \ test_expect_success \ 'listing the one-line message of a non-signed tag should succeed' ' - git-tag -m "A msg" tag-one-line && + git tag -m "A msg" tag-one-line && echo "tag-one-line" >expect && - git-tag -l | grep "^tag-one-line" >actual && + git tag -l | grep "^tag-one-line" >actual && test_cmp expect actual && - git-tag -n0 -l | grep "^tag-one-line" >actual && + git tag -n0 -l | grep "^tag-one-line" >actual && test_cmp expect actual && - git-tag -n0 -l tag-one-line >actual && + git tag -n0 -l tag-one-line >actual && test_cmp expect actual && echo "tag-one-line A msg" >expect && - git-tag -n1 -l | grep "^tag-one-line" >actual && + git tag -n1 -l | grep "^tag-one-line" >actual && test_cmp expect actual && - git-tag -n -l | grep "^tag-one-line" >actual && + git tag -n -l | grep "^tag-one-line" >actual && test_cmp expect actual && - git-tag -n1 -l tag-one-line >actual && + git tag -n1 -l tag-one-line >actual && test_cmp expect actual && - git-tag -n2 -l tag-one-line >actual && + git tag -n2 -l tag-one-line >actual && test_cmp expect actual && - git-tag -n999 -l tag-one-line >actual && + git tag -n999 -l tag-one-line >actual && test_cmp expect actual ' test_expect_success \ 'listing the zero-lines message of a non-signed tag should succeed' ' - git-tag -m "" tag-zero-lines && + git tag -m "" tag-zero-lines && echo "tag-zero-lines" >expect && - git-tag -l | grep "^tag-zero-lines" >actual && + git tag -l | grep "^tag-zero-lines" >actual && test_cmp expect actual && - git-tag -n0 -l | grep "^tag-zero-lines" >actual && + git tag -n0 -l | grep "^tag-zero-lines" >actual && test_cmp expect actual && - git-tag -n0 -l tag-zero-lines >actual && + git tag -n0 -l tag-zero-lines >actual && test_cmp expect actual && echo "tag-zero-lines " >expect && - git-tag -n1 -l | grep "^tag-zero-lines" >actual && + git tag -n1 -l | grep "^tag-zero-lines" >actual && test_cmp expect actual && - git-tag -n -l | grep "^tag-zero-lines" >actual && + git tag -n -l | grep "^tag-zero-lines" >actual && test_cmp expect actual && - git-tag -n1 -l tag-zero-lines >actual && + git tag -n1 -l tag-zero-lines >actual && test_cmp expect actual && - git-tag -n2 -l tag-zero-lines >actual && + git tag -n2 -l tag-zero-lines >actual && test_cmp expect actual && - git-tag -n999 -l tag-zero-lines >actual && + git tag -n999 -l tag-zero-lines >actual && test_cmp expect actual ' @@ -540,42 +540,42 @@ echo 'tag line two' >>annotagmsg echo 'tag line three' >>annotagmsg test_expect_success \ 'listing many message lines of a non-signed tag should succeed' ' - git-tag -F annotagmsg tag-lines && + git tag -F annotagmsg tag-lines && echo "tag-lines" >expect && - git-tag -l | grep "^tag-lines" >actual && + git tag -l | grep "^tag-lines" >actual && test_cmp expect actual && - git-tag -n0 -l | grep "^tag-lines" >actual && + git tag -n0 -l | grep "^tag-lines" >actual && test_cmp expect actual && - git-tag -n0 -l tag-lines >actual && + git tag -n0 -l tag-lines >actual && test_cmp expect actual && echo "tag-lines tag line one" >expect && - git-tag -n1 -l | grep "^tag-lines" >actual && + git tag -n1 -l | grep "^tag-lines" >actual && test_cmp expect actual && - git-tag -n -l | grep "^tag-lines" >actual && + git tag -n -l | grep "^tag-lines" >actual && test_cmp expect actual && - git-tag -n1 -l tag-lines >actual && + git tag -n1 -l tag-lines >actual && test_cmp expect actual && echo " tag line two" >>expect && - git-tag -n2 -l | grep "^ *tag.line" >actual && + git tag -n2 -l | grep "^ *tag.line" >actual && test_cmp expect actual && - git-tag -n2 -l tag-lines >actual && + git tag -n2 -l tag-lines >actual && test_cmp expect actual && echo " tag line three" >>expect && - git-tag -n3 -l | grep "^ *tag.line" >actual && + git tag -n3 -l | grep "^ *tag.line" >actual && test_cmp expect actual && - git-tag -n3 -l tag-lines >actual && + git tag -n3 -l tag-lines >actual && test_cmp expect actual && - git-tag -n4 -l | grep "^ *tag.line" >actual && + git tag -n4 -l | grep "^ *tag.line" >actual && test_cmp expect actual && - git-tag -n4 -l tag-lines >actual && + git tag -n4 -l tag-lines >actual && test_cmp expect actual && - git-tag -n99 -l | grep "^ *tag.line" >actual && + git tag -n99 -l | grep "^ *tag.line" >actual && test_cmp expect actual && - git-tag -n99 -l tag-lines >actual && + git tag -n99 -l tag-lines >actual && test_cmp expect actual ' @@ -592,19 +592,19 @@ fi test_expect_success \ 'trying to verify an annotated non-signed tag should fail' ' tag_exists annotated-tag && - test_must_fail git-tag -v annotated-tag + test_must_fail git tag -v annotated-tag ' test_expect_success \ 'trying to verify a file-annotated non-signed tag should fail' ' tag_exists file-annotated-tag && - test_must_fail git-tag -v file-annotated-tag + test_must_fail git tag -v file-annotated-tag ' test_expect_success \ 'trying to verify two annotated non-signed tags should fail' ' tag_exists annotated-tag file-annotated-tag && - test_must_fail git-tag -v annotated-tag file-annotated-tag + test_must_fail git tag -v annotated-tag file-annotated-tag ' # creating and verifying signed tags: @@ -634,7 +634,7 @@ get_tag_header signed-tag $commit commit $time >expect echo 'A signed tag message' >>expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success 'creating a signed tag with -m message should succeed' ' - git-tag -s -m "A signed tag message" signed-tag && + git tag -s -m "A signed tag message" signed-tag && get_tag_msg signed-tag >actual && test_cmp expect actual ' @@ -675,7 +675,7 @@ get_tag_header implied-sign $commit commit $time >expect ./fakeeditor >>expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success '-u implies signed tag' ' - GIT_EDITOR=./fakeeditor git-tag -u CDDE430D implied-sign && + GIT_EDITOR=./fakeeditor git tag -u CDDE430D implied-sign && get_tag_msg implied-sign >actual && test_cmp expect actual ' @@ -689,7 +689,7 @@ cat sigmsgfile >>expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag with -F messagefile should succeed' ' - git-tag -s -F sigmsgfile file-signed-tag && + git tag -s -F sigmsgfile file-signed-tag && get_tag_msg file-signed-tag >actual && test_cmp expect actual ' @@ -702,7 +702,7 @@ get_tag_header stdin-signed-tag $commit commit $time >expect cat siginputmsg >>expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success 'creating a signed tag with -F - should succeed' ' - git-tag -s -F - stdin-signed-tag <siginputmsg && + git tag -s -F - stdin-signed-tag <siginputmsg && get_tag_msg stdin-signed-tag >actual && test_cmp expect actual ' @@ -711,7 +711,7 @@ get_tag_header implied-annotate $commit commit $time >expect ./fakeeditor >>expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success '-s implies annotated tag' ' - GIT_EDITOR=./fakeeditor git-tag -s implied-annotate && + GIT_EDITOR=./fakeeditor git tag -s implied-annotate && get_tag_msg implied-annotate >actual && test_cmp expect actual ' @@ -720,23 +720,23 @@ test_expect_success \ 'trying to create a signed tag with non-existing -F file should fail' ' ! test -f nonexistingfile && ! tag_exists nosigtag && - test_must_fail git-tag -s -F nonexistingfile nosigtag && + test_must_fail git tag -s -F nonexistingfile nosigtag && ! tag_exists nosigtag ' test_expect_success 'verifying a signed tag should succeed' \ - 'git-tag -v signed-tag' + 'git tag -v signed-tag' test_expect_success 'verifying two signed tags in one command should succeed' \ - 'git-tag -v signed-tag file-signed-tag' + 'git tag -v signed-tag file-signed-tag' test_expect_success \ 'verifying many signed and non-signed tags should fail' ' - test_must_fail git-tag -v signed-tag annotated-tag && - test_must_fail git-tag -v file-annotated-tag file-signed-tag && - test_must_fail git-tag -v annotated-tag \ + test_must_fail git tag -v signed-tag annotated-tag && + test_must_fail git tag -v file-annotated-tag file-signed-tag && + test_must_fail git tag -v annotated-tag \ file-signed-tag file-annotated-tag && - test_must_fail git-tag -v signed-tag annotated-tag file-signed-tag + test_must_fail git tag -v signed-tag annotated-tag file-signed-tag ' test_expect_success 'verifying a forged tag should fail' ' @@ -744,7 +744,7 @@ test_expect_success 'verifying a forged tag should fail' ' sed -e "s/signed-tag/forged-tag/" | git mktag) && git tag forged-tag $forged && - test_must_fail git-tag -v forged-tag + test_must_fail git tag -v forged-tag ' # blank and empty messages for signed tags: @@ -753,10 +753,10 @@ get_tag_header empty-signed-tag $commit commit $time >expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag with an empty -m message should succeed' ' - git-tag -s -m "" empty-signed-tag && + git tag -s -m "" empty-signed-tag && get_tag_msg empty-signed-tag >actual && test_cmp expect actual && - git-tag -v empty-signed-tag + git tag -v empty-signed-tag ' >sigemptyfile @@ -764,10 +764,10 @@ get_tag_header emptyfile-signed-tag $commit commit $time >expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag with an empty -F messagefile should succeed' ' - git-tag -s -F sigemptyfile emptyfile-signed-tag && + git tag -s -F sigemptyfile emptyfile-signed-tag && get_tag_msg emptyfile-signed-tag >actual && test_cmp expect actual && - git-tag -v emptyfile-signed-tag + git tag -v emptyfile-signed-tag ' printf '\n\n \n\t\nLeading blank lines\n' > sigblanksfile @@ -787,20 +787,20 @@ EOF echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'extra blanks in the message for a signed tag should be removed' ' - git-tag -s -F sigblanksfile blanks-signed-tag && + git tag -s -F sigblanksfile blanks-signed-tag && get_tag_msg blanks-signed-tag >actual && test_cmp expect actual && - git-tag -v blanks-signed-tag + git tag -v blanks-signed-tag ' get_tag_header blank-signed-tag $commit commit $time >expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag with a blank -m message should succeed' ' - git-tag -s -m " " blank-signed-tag && + git tag -s -m " " blank-signed-tag && get_tag_msg blank-signed-tag >actual && test_cmp expect actual && - git-tag -v blank-signed-tag + git tag -v blank-signed-tag ' echo ' ' >sigblankfile @@ -810,10 +810,10 @@ get_tag_header blankfile-signed-tag $commit commit $time >expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag with blank -F file with spaces should succeed' ' - git-tag -s -F sigblankfile blankfile-signed-tag && + git tag -s -F sigblankfile blankfile-signed-tag && get_tag_msg blankfile-signed-tag >actual && test_cmp expect actual && - git-tag -v blankfile-signed-tag + git tag -v blankfile-signed-tag ' printf ' ' >sigblanknonlfile @@ -821,10 +821,10 @@ get_tag_header blanknonlfile-signed-tag $commit commit $time >expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag with spaces and no newline should succeed' ' - git-tag -s -F sigblanknonlfile blanknonlfile-signed-tag && + git tag -s -F sigblanknonlfile blanknonlfile-signed-tag && get_tag_msg blanknonlfile-signed-tag >actual && test_cmp expect actual && - git-tag -v signed-tag + git tag -v signed-tag ' # messages with commented lines for signed tags: @@ -858,20 +858,20 @@ EOF echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag with a -F file with #comments should succeed' ' - git-tag -s -F sigcommentsfile comments-signed-tag && + git tag -s -F sigcommentsfile comments-signed-tag && get_tag_msg comments-signed-tag >actual && test_cmp expect actual && - git-tag -v comments-signed-tag + git tag -v comments-signed-tag ' get_tag_header comment-signed-tag $commit commit $time >expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag with #commented -m message should succeed' ' - git-tag -s -m "#comment" comment-signed-tag && + git tag -s -m "#comment" comment-signed-tag && get_tag_msg comment-signed-tag >actual && test_cmp expect actual && - git-tag -v comment-signed-tag + git tag -v comment-signed-tag ' echo '#comment' >sigcommentfile @@ -881,10 +881,10 @@ get_tag_header commentfile-signed-tag $commit commit $time >expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag with #commented -F messagefile should succeed' ' - git-tag -s -F sigcommentfile commentfile-signed-tag && + git tag -s -F sigcommentfile commentfile-signed-tag && get_tag_msg commentfile-signed-tag >actual && test_cmp expect actual && - git-tag -v commentfile-signed-tag + git tag -v commentfile-signed-tag ' printf '#comment' >sigcommentnonlfile @@ -892,61 +892,61 @@ get_tag_header commentnonlfile-signed-tag $commit commit $time >expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag with a #comment and no newline should succeed' ' - git-tag -s -F sigcommentnonlfile commentnonlfile-signed-tag && + git tag -s -F sigcommentnonlfile commentnonlfile-signed-tag && get_tag_msg commentnonlfile-signed-tag >actual && test_cmp expect actual && - git-tag -v commentnonlfile-signed-tag + git tag -v commentnonlfile-signed-tag ' # listing messages for signed tags: test_expect_success \ 'listing the one-line message of a signed tag should succeed' ' - git-tag -s -m "A message line signed" stag-one-line && + git tag -s -m "A message line signed" stag-one-line && echo "stag-one-line" >expect && - git-tag -l | grep "^stag-one-line" >actual && + git tag -l | grep "^stag-one-line" >actual && test_cmp expect actual && - git-tag -n0 -l | grep "^stag-one-line" >actual && + git tag -n0 -l | grep "^stag-one-line" >actual && test_cmp expect actual && - git-tag -n0 -l stag-one-line >actual && + git tag -n0 -l stag-one-line >actual && test_cmp expect actual && echo "stag-one-line A message line signed" >expect && - git-tag -n1 -l | grep "^stag-one-line" >actual && + git tag -n1 -l | grep "^stag-one-line" >actual && test_cmp expect actual && - git-tag -n -l | grep "^stag-one-line" >actual && + git tag -n -l | grep "^stag-one-line" >actual && test_cmp expect actual && - git-tag -n1 -l stag-one-line >actual && + git tag -n1 -l stag-one-line >actual && test_cmp expect actual && - git-tag -n2 -l stag-one-line >actual && + git tag -n2 -l stag-one-line >actual && test_cmp expect actual && - git-tag -n999 -l stag-one-line >actual && + git tag -n999 -l stag-one-line >actual && test_cmp expect actual ' test_expect_success \ 'listing the zero-lines message of a signed tag should succeed' ' - git-tag -s -m "" stag-zero-lines && + git tag -s -m "" stag-zero-lines && echo "stag-zero-lines" >expect && - git-tag -l | grep "^stag-zero-lines" >actual && + git tag -l | grep "^stag-zero-lines" >actual && test_cmp expect actual && - git-tag -n0 -l | grep "^stag-zero-lines" >actual && + git tag -n0 -l | grep "^stag-zero-lines" >actual && test_cmp expect actual && - git-tag -n0 -l stag-zero-lines >actual && + git tag -n0 -l stag-zero-lines >actual && test_cmp expect actual && echo "stag-zero-lines " >expect && - git-tag -n1 -l | grep "^stag-zero-lines" >actual && + git tag -n1 -l | grep "^stag-zero-lines" >actual && test_cmp expect actual && - git-tag -n -l | grep "^stag-zero-lines" >actual && + git tag -n -l | grep "^stag-zero-lines" >actual && test_cmp expect actual && - git-tag -n1 -l stag-zero-lines >actual && + git tag -n1 -l stag-zero-lines >actual && test_cmp expect actual && - git-tag -n2 -l stag-zero-lines >actual && + git tag -n2 -l stag-zero-lines >actual && test_cmp expect actual && - git-tag -n999 -l stag-zero-lines >actual && + git tag -n999 -l stag-zero-lines >actual && test_cmp expect actual ' @@ -955,42 +955,42 @@ echo 'stag line two' >>sigtagmsg echo 'stag line three' >>sigtagmsg test_expect_success \ 'listing many message lines of a signed tag should succeed' ' - git-tag -s -F sigtagmsg stag-lines && + git tag -s -F sigtagmsg stag-lines && echo "stag-lines" >expect && - git-tag -l | grep "^stag-lines" >actual && + git tag -l | grep "^stag-lines" >actual && test_cmp expect actual && - git-tag -n0 -l | grep "^stag-lines" >actual && + git tag -n0 -l | grep "^stag-lines" >actual && test_cmp expect actual && - git-tag -n0 -l stag-lines >actual && + git tag -n0 -l stag-lines >actual && test_cmp expect actual && echo "stag-lines stag line one" >expect && - git-tag -n1 -l | grep "^stag-lines" >actual && + git tag -n1 -l | grep "^stag-lines" >actual && test_cmp expect actual && - git-tag -n -l | grep "^stag-lines" >actual && + git tag -n -l | grep "^stag-lines" >actual && test_cmp expect actual && - git-tag -n1 -l stag-lines >actual && + git tag -n1 -l stag-lines >actual && test_cmp expect actual && echo " stag line two" >>expect && - git-tag -n2 -l | grep "^ *stag.line" >actual && + git tag -n2 -l | grep "^ *stag.line" >actual && test_cmp expect actual && - git-tag -n2 -l stag-lines >actual && + git tag -n2 -l stag-lines >actual && test_cmp expect actual && echo " stag line three" >>expect && - git-tag -n3 -l | grep "^ *stag.line" >actual && + git tag -n3 -l | grep "^ *stag.line" >actual && test_cmp expect actual && - git-tag -n3 -l stag-lines >actual && + git tag -n3 -l stag-lines >actual && test_cmp expect actual && - git-tag -n4 -l | grep "^ *stag.line" >actual && + git tag -n4 -l | grep "^ *stag.line" >actual && test_cmp expect actual && - git-tag -n4 -l stag-lines >actual && + git tag -n4 -l stag-lines >actual && test_cmp expect actual && - git-tag -n99 -l | grep "^ *stag.line" >actual && + git tag -n99 -l | grep "^ *stag.line" >actual && test_cmp expect actual && - git-tag -n99 -l stag-lines >actual && + git tag -n99 -l stag-lines >actual && test_cmp expect actual ' @@ -1005,7 +1005,7 @@ echo "A message for a tree" >>expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag pointing to a tree should succeed' ' - git-tag -s -m "A message for a tree" tree-signed-tag HEAD^{tree} && + git tag -s -m "A message for a tree" tree-signed-tag HEAD^{tree} && get_tag_msg tree-signed-tag >actual && test_cmp expect actual ' @@ -1015,7 +1015,7 @@ echo "A message for a blob" >>expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag pointing to a blob should succeed' ' - git-tag -s -m "A message for a blob" blob-signed-tag HEAD:foo && + git tag -s -m "A message for a blob" blob-signed-tag HEAD:foo && get_tag_msg blob-signed-tag >actual && test_cmp expect actual ' @@ -1025,7 +1025,7 @@ echo "A message for another tag" >>expect echo '-----BEGIN PGP SIGNATURE-----' >>expect test_expect_success \ 'creating a signed tag pointing to another tag should succeed' ' - git-tag -s -m "A message for another tag" tag-signed-tag signed-tag && + git tag -s -m "A message for another tag" tag-signed-tag signed-tag && get_tag_msg tag-signed-tag >actual && test_cmp expect actual ' @@ -1033,7 +1033,7 @@ test_expect_success \ # try to sign with bad user.signingkey git config user.signingkey BobTheMouse test_expect_success \ - 'git-tag -s fails if gpg is misconfigured' \ + 'git tag -s fails if gpg is misconfigured' \ 'test_must_fail git tag -s -m tail tag-gpg-failure' git config --unset user.signingkey @@ -1042,10 +1042,10 @@ git config --unset user.signingkey rm -rf gpghome test_expect_success \ 'verify signed tag fails when public key is not present' \ - 'test_must_fail git-tag -v signed-tag' + 'test_must_fail git tag -v signed-tag' test_expect_success \ - 'git-tag -a fails if tag annotation is empty' ' + 'git tag -a fails if tag annotation is empty' ' ! (GIT_EDITOR=cat git tag -a initial-comment) ' diff --git a/t/t7101-reset.sh b/t/t7101-reset.sh index ffaeb3983a..96e163f084 100755 --- a/t/t7101-reset.sh +++ b/t/t7101-reset.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Shawn Pearce # -test_description='git-reset should cull empty subdirs' +test_description='git reset should cull empty subdirs' . ./test-lib.sh test_expect_success \ @@ -11,7 +11,7 @@ test_expect_success \ 'mkdir path0 && cp "$TEST_DIRECTORY"/../COPYING path0/COPYING && git add path0/COPYING && - git-commit -m add -a' + git commit -m add -a' test_expect_success \ 'creating second files' \ @@ -25,11 +25,11 @@ test_expect_success \ git add path1/COPYING && git add COPYING && git add path0/COPYING-TOO && - git-commit -m change -a' + git commit -m change -a' test_expect_success \ 'resetting tree HEAD^' \ - 'git-reset --hard HEAD^' + 'git reset --hard HEAD^' test_expect_success \ 'checking initial files exist after rewind' \ diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index 29f5678b4c..e637c7d4db 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -3,9 +3,9 @@ # Copyright (c) 2007 Carlos Rica # -test_description='git-reset +test_description='git reset -Documented tests for git-reset' +Documented tests for git reset' . ./test-lib.sh diff --git a/t/t7103-reset-bare.sh b/t/t7103-reset-bare.sh index cdecebe456..42bf518c68 100755 --- a/t/t7103-reset-bare.sh +++ b/t/t7103-reset-bare.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-reset in a bare repository' +test_description='git reset in a bare repository' . ./test-lib.sh test_expect_success 'setup non-bare' ' diff --git a/t/t7201-co.sh b/t/t7201-co.sh index 1dff84d2fd..62d73f934a 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Junio C Hamano # -test_description='git-checkout tests. +test_description='git checkout tests. Creates master, forks renamer and side branches from it. Test switching across them. @@ -369,4 +369,36 @@ test_expect_success \ 'checkout with --track, but without -b, fails with too short tracked name' ' test_must_fail git checkout --track renamer' +test_expect_success 'checkout an unmerged path should fail' ' + rm -f .git/index && + O=$(echo original | git hash-object -w --stdin) && + A=$(echo ourside | git hash-object -w --stdin) && + B=$(echo theirside | git hash-object -w --stdin) && + ( + echo "100644 $A 0 fild" && + echo "100644 $O 1 file" && + echo "100644 $A 2 file" && + echo "100644 $B 3 file" && + echo "100644 $A 0 filf" + ) | git update-index --index-info && + echo "none of the above" >sample && + cat sample >fild && + cat sample >file && + cat sample >filf && + test_must_fail git checkout fild file filf && + test_cmp sample fild && + test_cmp sample filf && + test_cmp sample file +' + +test_expect_success 'failing checkout -b should not break working tree' ' + git reset --hard master && + git symbolic-ref HEAD refs/heads/master && + test_must_fail git checkout -b renamer side^ && + test $(git symbolic-ref HEAD) = refs/heads/master && + git diff --exit-code && + git diff --cached --exit-code + +' + test_done diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 2b51c0d7d8..1636fac2a4 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Michael Spang # -test_description='git-clean basic tests' +test_description='git clean basic tests' . ./test-lib.sh @@ -16,17 +16,17 @@ test_expect_success 'setup' ' echo build >.gitignore && echo \*.o >>.gitignore && git add . && - git-commit -m setup && + git commit -m setup && touch src/part2.c README && git add . ' -test_expect_success 'git-clean' ' +test_expect_success 'git clean' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && - git-clean && + git clean && test -f Makefile && test -f README && test -f src/part1.c && @@ -39,11 +39,11 @@ test_expect_success 'git-clean' ' ' -test_expect_success 'git-clean src/' ' +test_expect_success 'git clean src/' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && - git-clean src/ && + git clean src/ && test -f Makefile && test -f README && test -f src/part1.c && @@ -56,11 +56,11 @@ test_expect_success 'git-clean src/' ' ' -test_expect_success 'git-clean src/ src/' ' +test_expect_success 'git clean src/ src/' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && - git-clean src/ src/ && + git clean src/ src/ && test -f Makefile && test -f README && test -f src/part1.c && @@ -73,11 +73,11 @@ test_expect_success 'git-clean src/ src/' ' ' -test_expect_success 'git-clean with prefix' ' +test_expect_success 'git clean with prefix' ' mkdir -p build docs src/test && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so src/test/1.c && - (cd src/ && git-clean) && + (cd src/ && git clean) && test -f Makefile && test -f README && test -f src/part1.c && @@ -91,7 +91,7 @@ test_expect_success 'git-clean with prefix' ' ' -test_expect_success 'git-clean with relative prefix' ' +test_expect_success 'git clean with relative prefix' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && @@ -106,7 +106,7 @@ test_expect_success 'git-clean with relative prefix' ' } ' -test_expect_success 'git-clean with absolute path' ' +test_expect_success 'git clean with absolute path' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && @@ -121,7 +121,7 @@ test_expect_success 'git-clean with absolute path' ' } ' -test_expect_success 'git-clean with out of work tree relative path' ' +test_expect_success 'git clean with out of work tree relative path' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && @@ -131,7 +131,7 @@ test_expect_success 'git-clean with out of work tree relative path' ' ) ' -test_expect_success 'git-clean with out of work tree absolute path' ' +test_expect_success 'git clean with out of work tree absolute path' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && @@ -142,11 +142,11 @@ test_expect_success 'git-clean with out of work tree absolute path' ' ) ' -test_expect_success 'git-clean -d with prefix and path' ' +test_expect_success 'git clean -d with prefix and path' ' mkdir -p build docs src/feature && touch a.out src/part3.c src/feature/file.c docs/manual.txt obj.o build/lib.so && - (cd src/ && git-clean -d feature/) && + (cd src/ && git clean -d feature/) && test -f Makefile && test -f README && test -f src/part1.c && @@ -160,12 +160,12 @@ test_expect_success 'git-clean -d with prefix and path' ' ' -test_expect_success 'git-clean symbolic link' ' +test_expect_success 'git clean symbolic link' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && ln -s docs/manual.txt src/part4.c - git-clean && + git clean && test -f Makefile && test -f README && test -f src/part1.c && @@ -179,10 +179,10 @@ test_expect_success 'git-clean symbolic link' ' ' -test_expect_success 'git-clean with wildcard' ' +test_expect_success 'git clean with wildcard' ' touch a.clean b.clean other.c && - git-clean "*.clean" && + git clean "*.clean" && test -f Makefile && test -f README && test -f src/part1.c && @@ -193,11 +193,11 @@ test_expect_success 'git-clean with wildcard' ' ' -test_expect_success 'git-clean -n' ' +test_expect_success 'git clean -n' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && - git-clean -n && + git clean -n && test -f Makefile && test -f README && test -f src/part1.c && @@ -210,11 +210,11 @@ test_expect_success 'git-clean -n' ' ' -test_expect_success 'git-clean -d' ' +test_expect_success 'git clean -d' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && - git-clean -d && + git clean -d && test -f Makefile && test -f README && test -f src/part1.c && @@ -227,11 +227,11 @@ test_expect_success 'git-clean -d' ' ' -test_expect_success 'git-clean -d src/ examples/' ' +test_expect_success 'git clean -d src/ examples/' ' mkdir -p build docs examples && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so examples/1.c && - git-clean -d src/ examples/ && + git clean -d src/ examples/ && test -f Makefile && test -f README && test -f src/part1.c && @@ -245,11 +245,11 @@ test_expect_success 'git-clean -d src/ examples/' ' ' -test_expect_success 'git-clean -x' ' +test_expect_success 'git clean -x' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && - git-clean -x && + git clean -x && test -f Makefile && test -f README && test -f src/part1.c && @@ -262,11 +262,11 @@ test_expect_success 'git-clean -x' ' ' -test_expect_success 'git-clean -d -x' ' +test_expect_success 'git clean -d -x' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && - git-clean -d -x && + git clean -d -x && test -f Makefile && test -f README && test -f src/part1.c && @@ -279,11 +279,11 @@ test_expect_success 'git-clean -d -x' ' ' -test_expect_success 'git-clean -X' ' +test_expect_success 'git clean -X' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && - git-clean -X && + git clean -X && test -f Makefile && test -f README && test -f src/part1.c && @@ -296,11 +296,11 @@ test_expect_success 'git-clean -X' ' ' -test_expect_success 'git-clean -d -X' ' +test_expect_success 'git clean -d -X' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && - git-clean -d -X && + git clean -d -X && test -f Makefile && test -f README && test -f src/part1.c && @@ -331,7 +331,7 @@ test_expect_success 'clean.requireForce and -n' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && - git-clean -n && + git clean -n && test -f Makefile && test -f README && test -f src/part1.c && @@ -346,7 +346,7 @@ test_expect_success 'clean.requireForce and -n' ' test_expect_success 'clean.requireForce and -f' ' - git-clean -f && + git clean -f && test -f README && test -f src/part1.c && test -f src/part2.c && diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index cbc0c34ce2..be73f7b60a 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -6,7 +6,7 @@ test_description='Basic porcelain support for submodules This test tries to verify basic sanity of the init, update and status -subcommands of git-submodule. +subcommands of git submodule. ' . ./test-lib.sh @@ -22,16 +22,16 @@ subcommands of git-submodule. # test_expect_success 'Prepare submodule testing' ' : > t && - git-add t && - git-commit -m "initial commit" && + git add t && + git commit -m "initial commit" && git branch initial HEAD && mkdir init && cd init && git init && echo a >a && git add a && - git-commit -m "submodule commit 1" && - git-tag -a -m "rev-1" rev-1 && + git commit -m "submodule commit 1" && + git tag -a -m "rev-1" rev-1 && rev1=$(git rev-parse HEAD) && if test -z "$rev1" then @@ -42,13 +42,13 @@ test_expect_success 'Prepare submodule testing' ' echo a >a && echo z >z && git add a init z && - git-commit -m "super commit 1" && + git commit -m "super commit 1" && mv init .subrepo && GIT_CONFIG=.gitmodules git config submodule.example.url git://example.com/init.git ' test_expect_success 'status should fail for unmapped paths' ' - if git-submodule status + if git submodule status then echo "[OOPS] submodule status succeeded" false @@ -60,16 +60,16 @@ test_expect_success 'status should fail for unmapped paths' ' ' test_expect_success 'status should only print one line' ' - lines=$(git-submodule status | wc -l) && + lines=$(git submodule status | wc -l) && test $lines = 1 ' test_expect_success 'status should initially be "missing"' ' - git-submodule status | grep "^-$rev1" + git submodule status | grep "^-$rev1" ' test_expect_success 'init should register submodule url in .git/config' ' - git-submodule init && + git submodule init && url=$(git config submodule.example.url) && if test "$url" != "git://example.com/init.git" then @@ -84,7 +84,7 @@ test_expect_success 'init should register submodule url in .git/config' ' test_expect_success 'update should fail when path is used by a file' ' echo "hello" >init && - if git-submodule update + if git submodule update then echo "[OOPS] update should have failed" false @@ -100,7 +100,7 @@ test_expect_success 'update should fail when path is used by a file' ' test_expect_success 'update should fail when path is used by a nonempty directory' ' mkdir init && echo "hello" >init/a && - if git-submodule update + if git submodule update then echo "[OOPS] update should have failed" false @@ -116,7 +116,7 @@ test_expect_success 'update should fail when path is used by a nonempty director test_expect_success 'update should work when path is an empty dir' ' rm -rf init && mkdir init && - git-submodule update && + git submodule update && head=$(cd init && git rev-parse HEAD) && if test -z "$head" then @@ -130,14 +130,14 @@ test_expect_success 'update should work when path is an empty dir' ' ' test_expect_success 'status should be "up-to-date" after update' ' - git-submodule status | grep "^ $rev1" + git submodule status | grep "^ $rev1" ' test_expect_success 'status should be "modified" after submodule commit' ' cd init && echo b >b && git add b && - git-commit -m "submodule commit 2" && + git commit -m "submodule commit 2" && rev2=$(git rev-parse HEAD) && cd .. && if test -z "$rev2" @@ -145,19 +145,19 @@ test_expect_success 'status should be "modified" after submodule commit' ' echo "[OOPS] submodule git rev-parse returned nothing" false fi && - git-submodule status | grep "^+$rev2" + git submodule status | grep "^+$rev2" ' test_expect_success 'the --cached sha1 should be rev1' ' - git-submodule --cached status | grep "^+$rev1" + git submodule --cached status | grep "^+$rev1" ' test_expect_success 'git diff should report the SHA1 of the new submodule commit' ' - git-diff | grep "^+Subproject commit $rev2" + git diff | grep "^+Subproject commit $rev2" ' test_expect_success 'update should checkout rev1' ' - git-submodule update init && + git submodule update init && head=$(cd init && git rev-parse HEAD) && if test -z "$head" then @@ -171,12 +171,12 @@ test_expect_success 'update should checkout rev1' ' ' test_expect_success 'status should be "up-to-date" after update' ' - git-submodule status | grep "^ $rev1" + git submodule status | grep "^ $rev1" ' test_expect_success 'checkout superproject with subproject already present' ' - git-checkout initial && - git-checkout master + git checkout initial && + git checkout master ' test_expect_success 'apply submodule diff' ' @@ -188,8 +188,8 @@ test_expect_success 'apply submodule diff' ' git commit -m "change subproject" ) && git update-index --add init && - git-commit -m "change init" && - git-format-patch -1 --stdout >P.diff && + git commit -m "change init" && + git format-patch -1 --stdout >P.diff && git checkout second && git apply --index P.diff && D=$(git diff --cached master) && diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh index bf12dbdeef..61498293b9 100755 --- a/t/t7401-submodule-summary.sh +++ b/t/t7401-submodule-summary.sh @@ -5,7 +5,7 @@ test_description='Summary support for submodules -This test tries to verify the sanity of summary subcommand of git-submodule. +This test tries to verify the sanity of summary subcommand of git submodule. ' . ./test-lib.sh diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh index 7ae0bd0e31..6e18a96319 100755 --- a/t/t7500-commit.sh +++ b/t/t7500-commit.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Steven Grimm # -test_description='git-commit +test_description='git commit Tests for selected commit options.' diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh index 0edd9ddf73..63bfc6d8b3 100755 --- a/t/t7501-commit.sh +++ b/t/t7501-commit.sh @@ -6,7 +6,7 @@ # FIXME: Test the various index usages, -i and -o, test reflog, # signoff -test_description='git-commit' +test_description='git commit' . ./test-lib.sh test_tick @@ -14,52 +14,52 @@ test_tick test_expect_success \ "initial status" \ "echo 'bongo bongo' >file && - git-add file && \ - git-status | grep 'Initial commit'" + git add file && \ + git status | grep 'Initial commit'" test_expect_success \ "fail initial amend" \ - "test_must_fail git-commit --amend" + "test_must_fail git commit --amend" test_expect_success \ "initial commit" \ - "git-commit -m initial" + "git commit -m initial" test_expect_success \ "invalid options 1" \ - "test_must_fail git-commit -m foo -m bar -F file" + "test_must_fail git commit -m foo -m bar -F file" test_expect_success \ "invalid options 2" \ - "test_must_fail git-commit -C HEAD -m illegal" + "test_must_fail git commit -C HEAD -m illegal" test_expect_success \ "using paths with -a" \ "echo King of the bongo >file && - test_must_fail git-commit -m foo -a file" + test_must_fail git commit -m foo -a file" test_expect_success \ "using paths with --interactive" \ "echo bong-o-bong >file && - ! (echo 7 | git-commit -m foo --interactive file)" + ! (echo 7 | git commit -m foo --interactive file)" test_expect_success \ "using invalid commit with -C" \ - "test_must_fail git-commit -C bogus" + "test_must_fail git commit -C bogus" test_expect_success \ "testing nothing to commit" \ - "test_must_fail git-commit -m initial" + "test_must_fail git commit -m initial" test_expect_success \ "next commit" \ "echo 'bongo bongo bongo' >file \ - git-commit -m next -a" + git commit -m next -a" test_expect_success \ "commit message from non-existing file" \ "echo 'more bongo: bongo bongo bongo bongo' >file && \ - test_must_fail git-commit -F gah -a" + test_must_fail git commit -F gah -a" # Empty except stray tabs and spaces on a few lines. sed -e 's/@$//' >msg <<EOF @@ -70,12 +70,12 @@ Signed-off-by: hula EOF test_expect_success \ "empty commit message" \ - "test_must_fail git-commit -F msg -a" + "test_must_fail git commit -F msg -a" test_expect_success \ "commit message from file" \ "echo 'this is the commit message, coming from a file' >msg && \ - git-commit -F msg -a" + git commit -F msg -a" cat >editor <<\EOF #!/bin/sh @@ -86,16 +86,16 @@ chmod 755 editor test_expect_success \ "amend commit" \ - "VISUAL=./editor git-commit --amend" + "VISUAL=./editor git commit --amend" test_expect_success \ "passing -m and -F" \ "echo 'enough with the bongos' >file && \ - test_must_fail git-commit -F msg -m amending ." + test_must_fail git commit -F msg -m amending ." test_expect_success \ "using message from other commit" \ - "git-commit -C HEAD^ ." + "git commit -C HEAD^ ." cat >editor <<\EOF #!/bin/sh @@ -107,25 +107,25 @@ chmod 755 editor test_expect_success \ "editing message from other commit" \ "echo 'hula hula' >file && \ - VISUAL=./editor git-commit -c HEAD^ -a" + VISUAL=./editor git commit -c HEAD^ -a" test_expect_success \ "message from stdin" \ "echo 'silly new contents' >file && \ - echo commit message from stdin | git-commit -F - -a" + echo commit message from stdin | git commit -F - -a" test_expect_success \ "overriding author from command line" \ "echo 'gak' >file && \ - git-commit -m 'author' --author 'Rubber Duck <rduck@convoy.org>' -a" + git commit -m 'author' --author 'Rubber Duck <rduck@convoy.org>' -a" test_expect_success \ "interactive add" \ - "echo 7 | git-commit --interactive | grep 'What now'" + "echo 7 | git commit --interactive | grep 'What now'" test_expect_success \ "showing committed revisions" \ - "git-rev-list HEAD >current" + "git rev-list HEAD >current" # We could just check the head sha1, but checking each commit makes it # easier to isolate bugs. @@ -140,8 +140,8 @@ d381ac431806e53f3dd7ac2f1ae0534f36d738b9 EOF test_expect_success \ - 'validate git-rev-list output.' \ - 'diff current expected' + 'validate git rev-list output.' \ + 'test_cmp expected current' test_expect_success 'partial commit that involves removal (1)' ' @@ -151,7 +151,7 @@ test_expect_success 'partial commit that involves removal (1)' ' git commit -m "Partial: add elif" elif && git diff-tree --name-status HEAD^ HEAD >current && echo "A elif" >expected && - diff expected current + test_cmp expected current ' @@ -160,7 +160,7 @@ test_expect_success 'partial commit that involves removal (2)' ' git commit -m "Partial: remove file" file && git diff-tree --name-status HEAD^ HEAD >current && echo "D file" >expected && - diff expected current + test_cmp expected current ' @@ -171,7 +171,7 @@ test_expect_success 'partial commit that involves removal (3)' ' git commit -m "Partial: modify elif" elif && git diff-tree --name-status HEAD^ HEAD >current && echo "M elif" >expected && - diff expected current + test_cmp expected current ' @@ -187,7 +187,7 @@ test_expect_success 'amend commit to fix author' ' expected && git commit --amend --author="$author" && git cat-file -p HEAD > current && - diff expected current + test_cmp expected current ' @@ -256,7 +256,7 @@ test_expect_success 'amend commit to fix author' ' expected && git commit --amend --author="$author" && git cat-file -p HEAD > current && - diff expected current + test_cmp expected current ' diff --git a/t/t7502-status.sh b/t/t7502-status.sh index 38a48b57c7..1905fb34cd 100755 --- a/t/t7502-status.sh +++ b/t/t7502-status.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Johannes E. Schindelin # -test_description='git-status' +test_description='git status' . ./test-lib.sh @@ -46,6 +46,7 @@ cat > expect << \EOF # # Changed but not updated: # (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) # # modified: dir1/modified # @@ -76,6 +77,7 @@ cat >expect <<EOF # # Changed but not updated: # (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) # # modified: dir1/modified # @@ -104,6 +106,7 @@ cat >expect <<EOF # # Changed but not updated: # (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) # # modified: dir1/modified # @@ -138,6 +141,7 @@ cat >expect <<EOF # # Changed but not updated: # (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) # # modified: dir1/modified # @@ -174,6 +178,7 @@ cat > expect << \EOF # # Changed but not updated: # (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) # # modified: modified # @@ -204,6 +209,7 @@ cat > expect << \EOF # # Changed but not updated: # (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) # # modified: dir1/modified # @@ -267,6 +273,7 @@ cat >expect <<EOF # # Changed but not updated: # (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) # # modified: dir1/modified # @@ -297,6 +304,7 @@ cat >expect <<EOF # # Changed but not updated: # (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) # # modified: dir1/modified # @@ -326,6 +334,7 @@ cat >expect <<EOF # On branch master # Changed but not updated: # (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) # # modified: dir1/modified # @@ -357,6 +366,7 @@ cat >expect <<EOF # # Changed but not updated: # (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) # # modified: dir1/modified # diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh index cd6c7c8342..ff189624d4 100755 --- a/t/t7505-prepare-commit-msg-hook.sh +++ b/t/t7505-prepare-commit-msg-hook.sh @@ -32,7 +32,7 @@ echo "#!$SHELL_PATH" > "$HOOK" cat >> "$HOOK" <<'EOF' if test "$2" = commit; then - source=$(git-rev-parse "$3") + source=$(git rev-parse "$3") else source=${2-default} fi diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh index a75130cdbb..d9a08aac56 100755 --- a/t/t7506-status-submodule.sh +++ b/t/t7506-status-submodule.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-status for submodule' +test_description='git status for submodule' . ./test-lib.sh diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 6a2b12558a..9516f541e9 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Lars Hjemli # -test_description='git-merge +test_description='git merge Testing basic merge operations/option parsing.' diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index 55aa6b5f27..7ba94ea99b 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-merge +test_description='git merge Testing pull.* configuration parsing.' diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh index fcb8285746..01e5415e94 100755 --- a/t/t7602-merge-octopus-many.sh +++ b/t/t7602-merge-octopus-many.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-merge +test_description='git merge Testing octopus merge with more than 25 refs.' diff --git a/t/t7603-merge-reduce-heads.sh b/t/t7603-merge-reduce-heads.sh index 17b19dc11f..7e17eb490d 100755 --- a/t/t7603-merge-reduce-heads.sh +++ b/t/t7603-merge-reduce-heads.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-merge +test_description='git merge Testing octopus merge when reducing parents to independent branches.' @@ -60,4 +60,57 @@ test_expect_success 'merge c1 with c2, c3, c4, c5' ' test -f c5.c ' +test_expect_success 'setup' ' + for i in A B C D E + do + echo $i > $i.c && + git add $i.c && + git commit -m $i && + git tag $i + done && + git reset --hard A && + for i in F G H I + do + echo $i > $i.c && + git add $i.c && + git commit -m $i && + git tag $i + done +' + +test_expect_success 'merge E and I' ' + git reset --hard A && + git merge E I +' + +test_expect_success 'verify merge result' ' + test $(git rev-parse HEAD^1) = $(git rev-parse E) && + test $(git rev-parse HEAD^2) = $(git rev-parse I) +' + +test_expect_success 'add conflicts' ' + git reset --hard E && + echo foo > file.c && + git add file.c && + git commit -m E2 && + git tag E2 && + git reset --hard I && + echo bar >file.c && + git add file.c && + git commit -m I2 && + git tag I2 +' + +test_expect_success 'merge E2 and I2, causing a conflict and resolve it' ' + git reset --hard A && + test_must_fail git merge E2 I2 && + echo baz > file.c && + git add file.c && + git commit -m "resolve conflict" +' + +test_expect_success 'verify merge result' ' + test $(git rev-parse HEAD^1) = $(git rev-parse E2) && + test $(git rev-parse HEAD^2) = $(git rev-parse I2) +' test_done diff --git a/t/t7604-merge-custom-message.sh b/t/t7604-merge-custom-message.sh index 6081677d23..de977c5e2f 100755 --- a/t/t7604-merge-custom-message.sh +++ b/t/t7604-merge-custom-message.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-merge +test_description='git merge Testing merge when using a custom message for the merge commit.' diff --git a/t/t7605-merge-resolve.sh b/t/t7605-merge-resolve.sh index f1f86ddb23..0cb9d11f21 100755 --- a/t/t7605-merge-resolve.sh +++ b/t/t7605-merge-resolve.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-merge +test_description='git merge Testing the resolve strategy.' diff --git a/t/t7606-merge-custom.sh b/t/t7606-merge-custom.sh index de9b6ed5ba..52a451dd57 100755 --- a/t/t7606-merge-custom.sh +++ b/t/t7606-merge-custom.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-merge +test_description='git merge Testing a custom strategy.' diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh index 9285071c47..09fa5f115c 100755 --- a/t/t7610-mergetool.sh +++ b/t/t7610-mergetool.sh @@ -3,7 +3,7 @@ # Copyright (c) 2008 Charles Bailey # -test_description='git-mergetool +test_description='git mergetool Testing basic merge tool invocation' diff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh index 31c340fd38..531dac060a 100755 --- a/t/t7701-repack-unpack-unreachable.sh +++ b/t/t7701-repack-unpack-unreachable.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-repack works correctly' +test_description='git repack works correctly' . ./test-lib.sh diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 1c857cf4ab..d098a01ba3 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-send-email' +test_description='git send-email' . ./test-lib.sh PROG='git send-email' diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index 843a5013b9..9b238c329b 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Eric Wong # -test_description='git-svn basic tests' +test_description='git svn basic tests' GIT_SVN_LC_ALL=${LC_ALL:-$LANG} case "$GIT_SVN_LC_ALL" in @@ -17,10 +17,10 @@ esac . ./lib-git-svn.sh -say 'define NO_SVN_TESTS to skip git-svn tests' +say 'define NO_SVN_TESTS to skip git svn tests' test_expect_success \ - 'initialize git-svn' ' + 'initialize git svn' ' mkdir import && cd import && echo foo > foo && @@ -31,26 +31,26 @@ test_expect_success \ echo "zzz" > bar/zzz && echo "#!/bin/sh" > exec.sh && chmod +x exec.sh && - svn import -m "import for git-svn" . "$svnrepo" >/dev/null && + svn import -m "import for git svn" . "$svnrepo" >/dev/null && cd .. && rm -rf import && - git-svn init "$svnrepo"' + git svn init "$svnrepo"' test_expect_success \ 'import an SVN revision into git' \ - 'git-svn fetch' + 'git svn fetch' test_expect_success "checkout from svn" 'svn co "$svnrepo" "$SVN_TREE"' name='try a deep --rmdir with a commit' test_expect_success "$name" ' - git checkout -f -b mybranch remotes/git-svn && + git checkout -f -b mybranch ${remotes_git_svn} && mv dir/a/b/c/d/e/file dir/file && cp dir/file file && git update-index --add --remove dir/a/b/c/d/e/file dir/file file && git commit -m "$name" && - git-svn set-tree --find-copies-harder --rmdir \ - remotes/git-svn..mybranch && + git svn set-tree --find-copies-harder --rmdir \ + ${remotes_git_svn}..mybranch && svn up "$SVN_TREE" && test -d "$SVN_TREE"/dir && test ! -d "$SVN_TREE"/dir/a' @@ -63,61 +63,61 @@ test_expect_success "$name" " git update-index --remove dir/file && git update-index --add dir/file/file && git commit -m '$name' && - test_must_fail git-svn set-tree --find-copies-harder --rmdir \ - remotes/git-svn..mybranch" || true + test_must_fail git svn set-tree --find-copies-harder --rmdir \ + ${remotes_git_svn}..mybranch" || true name='detect node change from directory to file #1' test_expect_success "$name" ' rm -rf dir "$GIT_DIR"/index && - git checkout -f -b mybranch2 remotes/git-svn && + git checkout -f -b mybranch2 ${remotes_git_svn} && mv bar/zzz zzz && rm -rf bar && mv zzz bar && git update-index --remove -- bar/zzz && git update-index --add -- bar && git commit -m "$name" && - test_must_fail git-svn set-tree --find-copies-harder --rmdir \ - remotes/git-svn..mybranch2' || true + test_must_fail git svn set-tree --find-copies-harder --rmdir \ + ${remotes_git_svn}..mybranch2' || true name='detect node change from file to directory #2' test_expect_success "$name" ' rm -f "$GIT_DIR"/index && - git checkout -f -b mybranch3 remotes/git-svn && + git checkout -f -b mybranch3 ${remotes_git_svn} && rm bar/zzz && git update-index --remove bar/zzz && mkdir bar/zzz && echo yyy > bar/zzz/yyy && git update-index --add bar/zzz/yyy && git commit -m "$name" && - test_must_fail git-svn set-tree --find-copies-harder --rmdir \ - remotes/git-svn..mybranch3' || true + test_must_fail git svn set-tree --find-copies-harder --rmdir \ + ${remotes_git_svn}..mybranch3' || true name='detect node change from directory to file #2' test_expect_success "$name" ' rm -f "$GIT_DIR"/index && - git checkout -f -b mybranch4 remotes/git-svn && + git checkout -f -b mybranch4 ${remotes_git_svn} && rm -rf dir && git update-index --remove -- dir/file && touch dir && echo asdf > dir && git update-index --add -- dir && git commit -m "$name" && - test_must_fail git-svn set-tree --find-copies-harder --rmdir \ - remotes/git-svn..mybranch4' || true + test_must_fail git svn set-tree --find-copies-harder --rmdir \ + ${remotes_git_svn}..mybranch4' || true name='remove executable bit from a file' test_expect_success "$name" ' rm -f "$GIT_DIR"/index && - git checkout -f -b mybranch5 remotes/git-svn && + git checkout -f -b mybranch5 ${remotes_git_svn} && chmod -x exec.sh && git update-index exec.sh && git commit -m "$name" && - git-svn set-tree --find-copies-harder --rmdir \ - remotes/git-svn..mybranch5 && + git svn set-tree --find-copies-harder --rmdir \ + ${remotes_git_svn}..mybranch5 && svn up "$SVN_TREE" && test ! -x "$SVN_TREE"/exec.sh' @@ -127,8 +127,8 @@ test_expect_success "$name" ' chmod +x exec.sh && git update-index exec.sh && git commit -m "$name" && - git-svn set-tree --find-copies-harder --rmdir \ - remotes/git-svn..mybranch5 && + git svn set-tree --find-copies-harder --rmdir \ + ${remotes_git_svn}..mybranch5 && svn up "$SVN_TREE" && test -x "$SVN_TREE"/exec.sh' @@ -139,8 +139,8 @@ test_expect_success "$name" ' ln -s bar/zzz exec.sh && git update-index exec.sh && git commit -m "$name" && - git-svn set-tree --find-copies-harder --rmdir \ - remotes/git-svn..mybranch5 && + git svn set-tree --find-copies-harder --rmdir \ + ${remotes_git_svn}..mybranch5 && svn up "$SVN_TREE" && test -L "$SVN_TREE"/exec.sh' @@ -151,8 +151,8 @@ test_expect_success "$name" ' ln -s bar/zzz exec-2.sh && git update-index --add bar/zzz exec-2.sh && git commit -m "$name" && - git-svn set-tree --find-copies-harder --rmdir \ - remotes/git-svn..mybranch5 && + git svn set-tree --find-copies-harder --rmdir \ + ${remotes_git_svn}..mybranch5 && svn up "$SVN_TREE" && test -x "$SVN_TREE"/bar/zzz && test -L "$SVN_TREE"/exec-2.sh' @@ -164,8 +164,8 @@ test_expect_success "$name" ' cp help exec-2.sh && git update-index exec-2.sh && git commit -m "$name" && - git-svn set-tree --find-copies-harder --rmdir \ - remotes/git-svn..mybranch5 && + git svn set-tree --find-copies-harder --rmdir \ + ${remotes_git_svn}..mybranch5 && svn up "$SVN_TREE" && test -f "$SVN_TREE"/exec-2.sh && test ! -L "$SVN_TREE"/exec-2.sh && @@ -180,7 +180,7 @@ then echo '# hello' >> exec-2.sh && git update-index exec-2.sh && git commit -m 'éï∏' && - git-svn set-tree HEAD" + git svn set-tree HEAD" unset LC_ALL else say "UTF-8 locale not set, test skipped ($GIT_SVN_LC_ALL)" @@ -190,8 +190,8 @@ name='test fetch functionality (svn => git) with alternate GIT_SVN_ID' GIT_SVN_ID=alt export GIT_SVN_ID test_expect_success "$name" \ - 'git-svn init "$svnrepo" && git-svn fetch && - git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a && + 'git svn init "$svnrepo" && git svn fetch && + git rev-list --pretty=raw ${remotes_git_svn} | grep ^tree | uniq > a && git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b && test_cmp a b' @@ -215,45 +215,45 @@ test_expect_success "$name" "test_cmp a expected" test_expect_success 'exit if remote refs are ambigious' " git config --add svn-remote.svn.fetch \ - bar:refs/remotes/git-svn && - test_must_fail git-svn migrate + bar:refs/${remotes_git_svn} && + test_must_fail git svn migrate " test_expect_success 'exit if init-ing a would clobber a URL' ' svnadmin create "${PWD}/svnrepo2" && svn mkdir -m "mkdir bar" "${svnrepo}2/bar" && git config --unset svn-remote.svn.fetch \ - "^bar:refs/remotes/git-svn$" && - test_must_fail git-svn init "${svnrepo}2/bar" + "^bar:refs/${remotes_git_svn}$" && + test_must_fail git svn init "${svnrepo}2/bar" ' test_expect_success \ 'init allows us to connect to another directory in the same repo' ' - git-svn init --minimize-url -i bar "$svnrepo/bar" && + git svn init --minimize-url -i bar "$svnrepo/bar" && git config --get svn-remote.svn.fetch \ "^bar:refs/remotes/bar$" && git config --get svn-remote.svn.fetch \ - "^:refs/remotes/git-svn$" + "^:refs/${remotes_git_svn}$" ' test_expect_success 'able to dcommit to a subdirectory' " - git-svn fetch -i bar && + git svn fetch -i bar && git checkout -b my-bar refs/remotes/bar && echo abc > d && git update-index --add d && git commit -m '/bar/d should be in the log' && - git-svn dcommit -i bar && + git svn dcommit -i bar && test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" && mkdir newdir && echo new > newdir/dir && git update-index --add newdir/dir && git commit -m 'add a new directory' && - git-svn dcommit -i bar && + git svn dcommit -i bar && test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" && echo foo >> newdir/dir && git update-index newdir/dir && git commit -m 'modify a file in new directory' && - git-svn dcommit -i bar && + git svn dcommit -i bar && test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" " @@ -261,7 +261,7 @@ test_expect_success 'able to set-tree to a subdirectory' " echo cba > d && git update-index d && git commit -m 'update /bar/d' && - git-svn set-tree -i bar HEAD && + git svn set-tree -i bar HEAD && test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" " diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh index f420796c31..1e31d6ea72 100755 --- a/t/t9101-git-svn-props.sh +++ b/t/t9101-git-svn-props.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Eric Wong # -test_description='git-svn property tests' +test_description='git svn property tests' . ./lib-git-svn.sh mkdir import @@ -26,29 +26,29 @@ cd import EOF printf "Hello\r\nWorld\r\n" > crlf - a_crlf=`git-hash-object -w crlf` + a_crlf=`git hash-object -w crlf` printf "Hello\rWorld\r" > cr - a_cr=`git-hash-object -w cr` + a_cr=`git hash-object -w cr` printf "Hello\nWorld\n" > lf - a_lf=`git-hash-object -w lf` + a_lf=`git hash-object -w lf` printf "Hello\r\nWorld" > ne_crlf - a_ne_crlf=`git-hash-object -w ne_crlf` + a_ne_crlf=`git hash-object -w ne_crlf` printf "Hello\nWorld" > ne_lf - a_ne_lf=`git-hash-object -w ne_lf` + a_ne_lf=`git hash-object -w ne_lf` printf "Hello\rWorld" > ne_cr - a_ne_cr=`git-hash-object -w ne_cr` + a_ne_cr=`git hash-object -w ne_cr` touch empty - a_empty=`git-hash-object -w empty` + a_empty=`git hash-object -w empty` printf "\n" > empty_lf - a_empty_lf=`git-hash-object -w empty_lf` + a_empty_lf=`git hash-object -w empty_lf` printf "\r" > empty_cr - a_empty_cr=`git-hash-object -w empty_cr` + a_empty_cr=`git hash-object -w empty_cr` printf "\r\n" > empty_crlf - a_empty_crlf=`git-hash-object -w empty_crlf` + a_empty_crlf=`git hash-object -w empty_crlf` - svn import --no-auto-props -m 'import for git-svn' . "$svnrepo" >/dev/null + svn import --no-auto-props -m 'import for git svn' . "$svnrepo" >/dev/null cd .. rm -rf import @@ -66,16 +66,16 @@ test_expect_success 'setup some commits to svn' \ svn commit -m "Propset Id" && cd ..' -test_expect_success 'initialize git-svn' 'git-svn init "$svnrepo"' -test_expect_success 'fetch revisions from svn' 'git-svn fetch' +test_expect_success 'initialize git svn' 'git svn init "$svnrepo"' +test_expect_success 'fetch revisions from svn' 'git svn fetch' name='test svn:keywords ignoring' test_expect_success "$name" \ - 'git checkout -b mybranch remotes/git-svn && + 'git checkout -b mybranch ${remotes_git_svn} && echo Hi again >> kw.c && git commit -a -m "test keywords ignoring" && - git-svn set-tree remotes/git-svn..mybranch && - git pull . remotes/git-svn' + git svn set-tree ${remotes_git_svn}..mybranch && + git pull . ${remotes_git_svn}' expect='/* $Id$ */' got="`sed -ne 2p kw.c`" @@ -90,8 +90,8 @@ test_expect_success "propset CR on crlf files" \ cd ..' test_expect_success 'fetch and pull latest from svn and checkout a new wc' \ - 'git-svn fetch && - git pull . remotes/git-svn && + 'git svn fetch && + git pull . ${remotes_git_svn} && svn co "$svnrepo" new_wc' for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf @@ -103,8 +103,8 @@ done cd test_wc printf '$Id$\rHello\rWorld\r' > cr printf '$Id$\rHello\rWorld' > ne_cr - a_cr=`printf '$Id$\r\nHello\r\nWorld\r\n' | git-hash-object --stdin` - a_ne_cr=`printf '$Id$\r\nHello\r\nWorld' | git-hash-object --stdin` + a_cr=`printf '$Id$\r\nHello\r\nWorld\r\n' | git hash-object --stdin` + a_ne_cr=`printf '$Id$\r\nHello\r\nWorld' | git hash-object --stdin` test_expect_success 'Set CRLF on cr files' \ 'svn propset svn:eol-style CRLF cr && svn propset svn:eol-style CRLF ne_cr && @@ -113,10 +113,10 @@ cd test_wc svn commit -m "propset CRLF on cr files"' cd .. test_expect_success 'fetch and pull latest from svn' \ - 'git-svn fetch && git pull . remotes/git-svn' + 'git svn fetch && git pull . ${remotes_git_svn}' -b_cr="`git-hash-object cr`" -b_ne_cr="`git-hash-object ne_cr`" +b_cr="`git hash-object cr`" +b_ne_cr="`git hash-object ne_cr`" test_expect_success 'CRLF + $Id$' "test '$a_cr' = '$b_cr'" test_expect_success 'CRLF + $Id$ (no newline)' "test '$a_ne_cr' = '$b_ne_cr'" @@ -145,7 +145,7 @@ test_expect_success 'test show-ignore' " svn propset -R svn:ignore 'no-such-file*' . svn commit -m 'propset svn:ignore' cd .. && - git-svn show-ignore > show-ignore.got && + git svn show-ignore > show-ignore.got && cmp show-ignore.expect show-ignore.got " @@ -161,8 +161,8 @@ cat >create-ignore-index.expect <<\EOF EOF test_expect_success 'test create-ignore' " - git-svn fetch && git pull . remotes/git-svn && - git-svn create-ignore && + git svn fetch && git pull . ${remotes_git_svn} && + git svn create-ignore && cmp ./.gitignore create-ignore.expect && cmp ./deeply/.gitignore create-ignore.expect && cmp ./deeply/nested/.gitignore create-ignore.expect && @@ -182,15 +182,15 @@ EOF # pattern, it can pass even though the propget did not execute on the # right directory. test_expect_success 'test propget' " - git-svn propget svn:ignore . | cmp - prop.expect && + git svn propget svn:ignore . | cmp - prop.expect && cd deeply && - git-svn propget svn:ignore . | cmp - ../prop.expect && - git-svn propget svn:entry:committed-rev nested/directory/.keep \ + git svn propget svn:ignore . | cmp - ../prop.expect && + git svn propget svn:entry:committed-rev nested/directory/.keep \ | cmp - ../prop2.expect && - git-svn propget svn:ignore .. | cmp - ../prop.expect && - git-svn propget svn:ignore nested/ | cmp - ../prop.expect && - git-svn propget svn:ignore ./nested | cmp - ../prop.expect && - git-svn propget svn:ignore .././deeply/nested | cmp - ../prop.expect + git svn propget svn:ignore .. | cmp - ../prop.expect && + git svn propget svn:ignore nested/ | cmp - ../prop.expect && + git svn propget svn:ignore ./nested | cmp - ../prop.expect && + git svn propget svn:ignore .././deeply/nested | cmp - ../prop.expect " cat >prop.expect <<\EOF @@ -210,8 +210,8 @@ Properties on 'nested/directory/.keep': EOF test_expect_success 'test proplist' " - git-svn proplist . | cmp - prop.expect && - git-svn proplist nested/directory/.keep | cmp - prop2.expect + git svn proplist . | cmp - prop.expect && + git svn proplist nested/directory/.keep | cmp - prop2.expect " test_done diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh index 0e7ce34b9b..e223218015 100755 --- a/t/t9102-git-svn-deep-rmdir.sh +++ b/t/t9102-git-svn-deep-rmdir.sh @@ -1,5 +1,5 @@ #!/bin/sh -test_description='git-svn rmdir' +test_description='git svn rmdir' . ./lib-git-svn.sh test_expect_success 'initialize repo' ' @@ -9,20 +9,20 @@ test_expect_success 'initialize repo' ' mkdir -p deeply/nested/directory/number/2 && echo foo > deeply/nested/directory/number/1/file && echo foo > deeply/nested/directory/number/2/another && - svn import -m "import for git-svn" . "$svnrepo" && + svn import -m "import for git svn" . "$svnrepo" && cd .. ' -test_expect_success 'mirror via git-svn' ' - git-svn init "$svnrepo" && - git-svn fetch && - git checkout -f -b test-rmdir remotes/git-svn +test_expect_success 'mirror via git svn' ' + git svn init "$svnrepo" && + git svn fetch && + git checkout -f -b test-rmdir ${remotes_git_svn} ' test_expect_success 'Try a commit on rmdir' ' git rm -f deeply/nested/directory/number/2/another && git commit -a -m "remove another" && - git-svn set-tree --rmdir HEAD && + git svn set-tree --rmdir HEAD && svn ls -R "$svnrepo" | grep ^deeply/nested/directory/number/1 ' diff --git a/t/t9103-git-svn-tracked-directory-removed.sh b/t/t9103-git-svn-tracked-directory-removed.sh index 9ffd8458ef..963dd95e4a 100755 --- a/t/t9103-git-svn-tracked-directory-removed.sh +++ b/t/t9103-git-svn-tracked-directory-removed.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Eric Wong # -test_description='git-svn tracking removed top-level path' +test_description='git svn tracking removed top-level path' . ./lib-git-svn.sh test_expect_success 'make history for tracking' ' diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh index 4d964e2db7..0a091e048e 100755 --- a/t/t9104-git-svn-follow-parent.sh +++ b/t/t9104-git-svn-follow-parent.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Eric Wong # -test_description='git-svn fetching' +test_description='git svn fetching' . ./lib-git-svn.sh test_expect_success 'initialize repo' ' @@ -27,8 +27,8 @@ test_expect_success 'initialize repo' ' ' test_expect_success 'init and fetch a moved directory' ' - git-svn init --minimize-url -i thunk "$svnrepo"/thunk && - git-svn fetch -i thunk && + git svn init --minimize-url -i thunk "$svnrepo"/thunk && + git svn fetch -i thunk && test "`git rev-parse --verify refs/remotes/thunk@2`" \ = "`git rev-parse --verify refs/remotes/thunk~1`" && test "`git cat-file blob refs/remotes/thunk:readme |\ @@ -43,7 +43,7 @@ test_expect_success 'init and fetch from one svn-remote' ' trunk:refs/remotes/svn/trunk && git config --add svn-remote.svn.fetch \ thunk:refs/remotes/svn/thunk && - git-svn fetch -i svn/thunk && + git svn fetch -i svn/thunk && test "`git rev-parse --verify refs/remotes/svn/trunk`" \ = "`git rev-parse --verify refs/remotes/svn/thunk~1`" && test "`git cat-file blob refs/remotes/svn/thunk:readme |\ @@ -57,8 +57,8 @@ test_expect_success 'follow deleted parent' ' -r2 "$svnrepo"/trunk "$svnrepo"/junk) && git config --add svn-remote.svn.fetch \ junk:refs/remotes/svn/junk && - git-svn fetch -i svn/thunk && - git-svn fetch -i svn/junk && + git svn fetch -i svn/thunk && + git svn fetch -i svn/junk && test -z "`git diff svn/junk svn/trunk`" && test "`git merge-base svn/junk svn/trunk`" \ = "`git rev-parse svn/trunk`" @@ -69,9 +69,9 @@ test_expect_success 'follow larger parent' ' echo hi > import/trunk/thunk/bump/thud/file && svn import -m "import a larger parent" import "$svnrepo"/larger-parent && svn cp -m "hi" "$svnrepo"/larger-parent "$svnrepo"/another-larger && - git-svn init --minimize-url -i larger \ + git svn init --minimize-url -i larger \ "$svnrepo"/another-larger/trunk/thunk/bump/thud && - git-svn fetch -i larger && + git svn fetch -i larger && git rev-parse --verify refs/remotes/larger && git rev-parse --verify \ refs/remotes/larger-parent/trunk/thunk/bump/thud && @@ -92,15 +92,15 @@ test_expect_success 'follow higher-level parent' ' cd .. svn mkdir -m "new glob at top level" "$svnrepo"/glob && svn mv -m "move blob down a level" "$svnrepo"/blob "$svnrepo"/glob/blob && - git-svn init --minimize-url -i blob "$svnrepo"/glob/blob && - git-svn fetch -i blob + git svn init --minimize-url -i blob "$svnrepo"/glob/blob && + git svn fetch -i blob ' test_expect_success 'follow deleted directory' ' svn mv -m "bye!" "$svnrepo"/glob/blob/hi "$svnrepo"/glob/blob/bye && svn rm -m "remove glob" "$svnrepo"/glob && - git-svn init --minimize-url -i glob "$svnrepo"/glob && - git-svn fetch -i glob && + git svn init --minimize-url -i glob "$svnrepo"/glob && + git svn fetch -i glob && test "`git cat-file blob refs/remotes/glob:blob/bye`" = hi && test "`git ls-tree refs/remotes/glob | wc -l `" -eq 1 ' @@ -129,9 +129,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' ' poke native/t/c.t && svn commit -m "reorg test" && cd .. && - git-svn init --minimize-url -i r9270-t \ + git svn init --minimize-url -i r9270-t \ "$svnrepo"/r9270/trunk/subversion/bindings/swig/perl/native/t && - git-svn fetch -i r9270-t && + git svn fetch -i r9270-t && test `git rev-list r9270-t | wc -l` -eq 2 && test "`git ls-tree --name-only r9270-t~1`" = \ "`git ls-tree --name-only r9270-t`" @@ -139,9 +139,9 @@ test_expect_success 'follow-parent avoids deleting relevant info' ' test_expect_success "track initial change if it was only made to parent" ' svn cp -m "wheee!" "$svnrepo"/r9270/trunk "$svnrepo"/r9270/drunk && - git-svn init --minimize-url -i r9270-d \ + git svn init --minimize-url -i r9270-d \ "$svnrepo"/r9270/drunk/subversion/bindings/swig/perl/native/t && - git-svn fetch -i r9270-d && + git svn fetch -i r9270-d && test `git rev-list r9270-d | wc -l` -eq 3 && test "`git ls-tree --name-only r9270-t`" = \ "`git ls-tree --name-only r9270-d`" && @@ -151,19 +151,19 @@ test_expect_success "track initial change if it was only made to parent" ' test_expect_success "track multi-parent paths" ' svn cp -m "resurrect /glob" "$svnrepo"/r9270 "$svnrepo"/glob && - git-svn multi-fetch && + git svn multi-fetch && test `git cat-file commit refs/remotes/glob | \ grep "^parent " | wc -l` -eq 2 ' test_expect_success "multi-fetch continues to work" " - git-svn multi-fetch + git svn multi-fetch " test_expect_success "multi-fetch works off a 'clean' repository" ' rm -r "$GIT_DIR/svn" "$GIT_DIR/refs/remotes" "$GIT_DIR/logs" && mkdir "$GIT_DIR/svn" && - git-svn multi-fetch + git svn multi-fetch ' test_debug 'gitk --all &' diff --git a/t/t9105-git-svn-commit-diff.sh b/t/t9105-git-svn-commit-diff.sh index 63230367bb..ba99abb6d9 100755 --- a/t/t9105-git-svn-commit-diff.sh +++ b/t/t9105-git-svn-commit-diff.sh @@ -1,7 +1,7 @@ #!/bin/sh # # Copyright (c) 2006 Eric Wong -test_description='git-svn commit-diff' +test_description='git svn commit-diff' . ./lib-git-svn.sh test_expect_success 'initialize repo' ' @@ -26,16 +26,16 @@ prev=`git rev-parse --verify HEAD^1` test_expect_success 'test the commit-diff command' ' test -n "$prev" && test -n "$head" && - git-svn commit-diff -r1 "$prev" "$head" "$svnrepo" && + git svn commit-diff -r1 "$prev" "$head" "$svnrepo" && svn co "$svnrepo" wc && cmp readme wc/readme ' -test_expect_success 'commit-diff to a sub-directory (with git-svn config)' ' +test_expect_success 'commit-diff to a sub-directory (with git svn config)' ' svn import -m "sub-directory" import "$svnrepo"/subdir && - git-svn init --minimize-url "$svnrepo"/subdir && - git-svn fetch && - git-svn commit-diff -r3 "$prev" "$head" && + git svn init --minimize-url "$svnrepo"/subdir && + git svn fetch && + git svn commit-diff -r3 "$prev" "$head" && svn cat "$svnrepo"/subdir/readme > readme.2 && cmp readme readme.2 ' diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh index 83896e9687..6eb0fd85c8 100755 --- a/t/t9106-git-svn-commit-diff-clobber.sh +++ b/t/t9106-git-svn-commit-diff-clobber.sh @@ -1,7 +1,7 @@ #!/bin/sh # # Copyright (c) 2006 Eric Wong -test_description='git-svn commit-diff clobber' +test_description='git svn commit-diff clobber' . ./lib-git-svn.sh test_expect_success 'initialize repo' ' @@ -27,7 +27,7 @@ test_expect_success 'commit change from svn side' ' test_expect_success 'commit conflicting change from git' ' echo second line from git >> file && git commit -a -m "second line from git" && - test_must_fail git-svn commit-diff -r1 HEAD~1 HEAD "$svnrepo" + test_must_fail git svn commit-diff -r1 HEAD~1 HEAD "$svnrepo" ' test_expect_success 'commit complementing change from git' ' @@ -36,13 +36,13 @@ test_expect_success 'commit complementing change from git' ' git commit -a -m "second line from svn" && echo third line from git >> file && git commit -a -m "third line from git" && - git-svn commit-diff -r2 HEAD~1 HEAD "$svnrepo" + git svn commit-diff -r2 HEAD~1 HEAD "$svnrepo" ' test_expect_success 'dcommit fails to commit because of conflict' ' - git-svn init "$svnrepo" && - git-svn fetch && - git reset --hard refs/remotes/git-svn && + git svn init "$svnrepo" && + git svn fetch && + git reset --hard refs/${remotes_git_svn} && svn co "$svnrepo" t.svn && cd t.svn && echo fourth line from svn >> file && @@ -52,18 +52,18 @@ test_expect_success 'dcommit fails to commit because of conflict' ' rm -rf t.svn && echo "fourth line from git" >> file && git commit -a -m "fourth line from git" && - test_must_fail git-svn dcommit + test_must_fail git svn dcommit ' test_expect_success 'dcommit does the svn equivalent of an index merge' " - git reset --hard refs/remotes/git-svn && + git reset --hard refs/${remotes_git_svn} && echo 'index merge' > file2 && git update-index --add file2 && git commit -a -m 'index merge' && echo 'more changes' >> file2 && git update-index file2 && git commit -a -m 'more changes' && - git-svn dcommit + git svn dcommit " test_expect_success 'commit another change from svn side' ' @@ -76,8 +76,8 @@ test_expect_success 'commit another change from svn side' ' rm -rf t.svn ' -test_expect_success 'multiple dcommit from git-svn will not clobber svn' " - git reset --hard refs/remotes/git-svn && +test_expect_success 'multiple dcommit from git svn will not clobber svn' " + git reset --hard refs/${remotes_git_svn} && echo new file >> new-file && git update-index --add new-file && git commit -a -m 'new file' && diff --git a/t/t9106-git-svn-dcommit-clobber-series.sh b/t/t9106-git-svn-dcommit-clobber-series.sh index bc37db9d62..fd185011b7 100755 --- a/t/t9106-git-svn-dcommit-clobber-series.sh +++ b/t/t9106-git-svn-dcommit-clobber-series.sh @@ -1,7 +1,7 @@ #!/bin/sh # # Copyright (c) 2007 Eric Wong -test_description='git-svn dcommit clobber series' +test_description='git svn dcommit clobber series' . ./lib-git-svn.sh test_expect_success 'initialize repo' ' diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh index d9b553ad55..acad16a6f0 100755 --- a/t/t9107-git-svn-migrate.sh +++ b/t/t9107-git-svn-migrate.sh @@ -1,6 +1,6 @@ #!/bin/sh # Copyright (c) 2006 Eric Wong -test_description='git-svn metadata migrations from previous versions' +test_description='git svn metadata migrations from previous versions' . ./lib-git-svn.sh test_expect_success 'setup old-looking metadata' ' @@ -14,34 +14,34 @@ test_expect_success 'setup old-looking metadata' ' done && \ svn import -m test . "$svnrepo" cd .. && - git-svn init "$svnrepo" && - git-svn fetch && + git svn init "$svnrepo" && + git svn fetch && mv "$GIT_DIR"/svn/* "$GIT_DIR"/ && mv "$GIT_DIR"/svn/.metadata "$GIT_DIR"/ && rmdir "$GIT_DIR"/svn && - git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn && - git update-ref refs/heads/svn-HEAD refs/remotes/git-svn && - git update-ref -d refs/remotes/git-svn refs/remotes/git-svn + git update-ref refs/heads/git-svn-HEAD refs/${remotes_git_svn} && + git update-ref refs/heads/svn-HEAD refs/${remotes_git_svn} && + git update-ref -d refs/${remotes_git_svn} refs/${remotes_git_svn} ' head=`git rev-parse --verify refs/heads/git-svn-HEAD^0` test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'" -test_expect_success 'initialize old-style (v0) git-svn layout' ' +test_expect_success 'initialize old-style (v0) git svn layout' ' mkdir -p "$GIT_DIR"/git-svn/info "$GIT_DIR"/svn/info && echo "$svnrepo" > "$GIT_DIR"/git-svn/info/url && echo "$svnrepo" > "$GIT_DIR"/svn/info/url && - git-svn migrate && - ! test -d "$GIT_DIR"/git-svn && - git rev-parse --verify refs/remotes/git-svn^0 && + git svn migrate && + ! test -d "$GIT_DIR"/git svn && + git rev-parse --verify refs/${remotes_git_svn}^0 && git rev-parse --verify refs/remotes/svn^0 && test "$(git config --get svn-remote.svn.url)" = "$svnrepo" && test `git config --get svn-remote.svn.fetch` = \ - ":refs/remotes/git-svn" + ":refs/${remotes_git_svn}" ' test_expect_success 'initialize a multi-repository repo' ' - git-svn init "$svnrepo" -T trunk -t tags -b branches && + git svn init "$svnrepo" -T trunk -t tags -b branches && git config --get-all svn-remote.svn.fetch > fetch.out && grep "^trunk:refs/remotes/trunk$" fetch.out && test -n "`git config --get svn-remote.svn.branches \ @@ -61,7 +61,7 @@ test_expect_success 'initialize a multi-repository repo' ' # refs should all be different, but the trees should all be the same: test_expect_success 'multi-fetch works on partial urls + paths' " - git-svn multi-fetch && + git svn multi-fetch && for i in trunk a b tags/0.1 tags/0.2 tags/0.3; do git rev-parse --verify refs/remotes/\$i^0 >> refs.out || exit 1; done && @@ -85,7 +85,7 @@ test_expect_success 'migrate --minimize on old inited layout' ' ( mkdir -p "$GIT_DIR"/svn/$ref/info/ && echo "$svnrepo"$path > "$GIT_DIR"/svn/$ref/info/url ) || exit 1; done && - git-svn migrate --minimize && + git svn migrate --minimize && test -z "`git config -l |grep -v "^svn-remote\.git-svn\."`" && git config --get-all svn-remote.svn.fetch > fetch.out && grep "^trunk:refs/remotes/trunk$" fetch.out && @@ -94,11 +94,11 @@ test_expect_success 'migrate --minimize on old inited layout' ' grep "^tags/0\.1:refs/remotes/tags/0\.1$" fetch.out && grep "^tags/0\.2:refs/remotes/tags/0\.2$" fetch.out && grep "^tags/0\.3:refs/remotes/tags/0\.3$" fetch.out - grep "^:refs/remotes/git-svn" fetch.out + grep "^:refs/${remotes_git_svn}" fetch.out ' test_expect_success ".rev_db auto-converted to .rev_map.UUID" ' - git-svn fetch -i trunk && + git svn fetch -i trunk && test -z "$(ls "$GIT_DIR"/svn/trunk/.rev_db.* 2>/dev/null)" && expect="$(ls "$GIT_DIR"/svn/trunk/.rev_map.*)" && test -n "$expect" && @@ -106,7 +106,7 @@ test_expect_success ".rev_db auto-converted to .rev_map.UUID" ' convert_to_rev_db "$expect" "$rev_db" && rm -f "$expect" && test -f "$rev_db" && - git-svn fetch -i trunk && + git svn fetch -i trunk && test -z "$(ls "$GIT_DIR"/svn/trunk/.rev_db.* 2>/dev/null)" && test ! -e "$GIT_DIR"/svn/trunk/.rev_db && test -f "$expect" diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh index 8b792a1370..d8582b1aa5 100755 --- a/t/t9108-git-svn-glob.sh +++ b/t/t9108-git-svn-glob.sh @@ -1,6 +1,6 @@ #!/bin/sh # Copyright (c) 2007 Eric Wong -test_description='git-svn globbing refspecs' +test_description='git svn globbing refspecs' . ./lib-git-svn.sh cat > expect.end <<EOF @@ -46,7 +46,7 @@ test_expect_success 'test refspec globbing' ' "branches/*/src/a:refs/remotes/branches/*" && git config --add svn-remote.svn.tags\ "tags/*/src/a:refs/remotes/tags/*" && - git-svn multi-fetch && + git svn multi-fetch && git log --pretty=oneline refs/remotes/tags/end | \ sed -e "s/^.\{41\}//" > output.end && test_cmp expect.end output.end && @@ -74,7 +74,7 @@ test_expect_success 'test left-hand-side only globbing' ' poke tags/end/src/b/readme && svn commit -m "try to try" ) && - git-svn fetch two && + git svn fetch two && test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 && test `git rev-list refs/remotes/two/branches/start | wc -l` -eq 3 && test `git rev-parse refs/remotes/two/branches/start~2` = \ @@ -104,7 +104,7 @@ test_expect_success 'test disallow multi-globs' ' poke tags/end/src/b/readme && svn commit -m "try to try" ) && - test_must_fail git-svn fetch three 2> stderr.three && + test_must_fail git svn fetch three 2> stderr.three && test_cmp expect.three stderr.three ' diff --git a/t/t9108-git-svn-multi-glob.sh b/t/t9108-git-svn-multi-glob.sh index 3583721652..8f79c3f251 100755 --- a/t/t9108-git-svn-multi-glob.sh +++ b/t/t9108-git-svn-multi-glob.sh @@ -1,6 +1,6 @@ #!/bin/sh # Copyright (c) 2007 Eric Wong -test_description='git-svn globbing refspecs' +test_description='git svn globbing refspecs' . ./lib-git-svn.sh cat > expect.end <<EOF @@ -46,7 +46,7 @@ test_expect_success 'test refspec globbing' ' "branches/*/*/src/a:refs/remotes/branches/*/*" && git config --add svn-remote.svn.tags\ "tags/*/src/a:refs/remotes/tags/*" && - git-svn multi-fetch && + git svn multi-fetch && git log --pretty=oneline refs/remotes/tags/end | \ sed -e "s/^.\{41\}//" > output.end && test_cmp expect.end output.end && @@ -74,7 +74,7 @@ test_expect_success 'test left-hand-side only globbing' ' poke tags/end/src/b/readme && svn commit -m "try to try" ) && - git-svn fetch two && + git svn fetch two && test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 && test `git rev-list refs/remotes/two/branches/v1/start | wc -l` -eq 3 && test `git rev-parse refs/remotes/two/branches/v1/start~2` = \ @@ -123,7 +123,7 @@ test_expect_success 'test another branch' ' "branches/*/*:refs/remotes/four/branches/*/*" && git config --add svn-remote.four.tags \ "tags/*:refs/remotes/four/tags/*" && - git-svn fetch four && + git svn fetch four && test `git rev-list refs/remotes/four/tags/next | wc -l` -eq 5 && test `git rev-list refs/remotes/four/branches/v2/start | wc -l` -eq 3 && test `git rev-parse refs/remotes/four/branches/v2/start~2` = \ @@ -153,7 +153,7 @@ test_expect_success 'test disallow multiple globs' ' poke tags/end/src/b/readme && svn commit -m "try to try" ) && - test_must_fail git-svn fetch three 2> stderr.three && + test_must_fail git svn fetch three 2> stderr.three && test_cmp expect.three stderr.three ' diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh index 83bd1cf17a..a06e4c5b8e 100755 --- a/t/t9110-git-svn-use-svm-props.sh +++ b/t/t9110-git-svn-use-svm-props.sh @@ -3,18 +3,18 @@ # Copyright (c) 2007 Eric Wong # -test_description='git-svn useSvmProps test' +test_description='git svn useSvmProps test' . ./lib-git-svn.sh test_expect_success 'load svm repo' ' svnadmin load -q "$rawsvnrepo" < "$TEST_DIRECTORY"/t9110/svm.dump && - git-svn init --minimize-url -R arr -i bar "$svnrepo"/mirror/arr && - git-svn init --minimize-url -R argh -i dir "$svnrepo"/mirror/argh && - git-svn init --minimize-url -R argh -i e \ + git svn init --minimize-url -R arr -i bar "$svnrepo"/mirror/arr && + git svn init --minimize-url -R argh -i dir "$svnrepo"/mirror/argh && + git svn init --minimize-url -R argh -i e \ "$svnrepo"/mirror/argh/a/b/c/d/e && git config svn.useSvmProps true && - git-svn fetch --all + git svn fetch --all ' uuid=161ce429-a9dd-4828-af4a-52023f968c89 @@ -22,40 +22,40 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89 bar_url=http://mayonaise/svnrepo/bar test_expect_success 'verify metadata for /bar' " git cat-file commit refs/remotes/bar | \ - grep '^git-svn-id: $bar_url@12 $uuid$' && + grep '^${git_svn_id}: $bar_url@12 $uuid$' && git cat-file commit refs/remotes/bar~1 | \ - grep '^git-svn-id: $bar_url@11 $uuid$' && + grep '^${git_svn_id}: $bar_url@11 $uuid$' && git cat-file commit refs/remotes/bar~2 | \ - grep '^git-svn-id: $bar_url@10 $uuid$' && + grep '^${git_svn_id}: $bar_url@10 $uuid$' && git cat-file commit refs/remotes/bar~3 | \ - grep '^git-svn-id: $bar_url@9 $uuid$' && + grep '^${git_svn_id}: $bar_url@9 $uuid$' && git cat-file commit refs/remotes/bar~4 | \ - grep '^git-svn-id: $bar_url@6 $uuid$' && + grep '^${git_svn_id}: $bar_url@6 $uuid$' && git cat-file commit refs/remotes/bar~5 | \ - grep '^git-svn-id: $bar_url@1 $uuid$' + grep '^${git_svn_id}: $bar_url@1 $uuid$' " e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e test_expect_success 'verify metadata for /dir/a/b/c/d/e' " git cat-file commit refs/remotes/e | \ - grep '^git-svn-id: $e_url@1 $uuid$' + grep '^${git_svn_id}: $e_url@1 $uuid$' " dir_url=http://mayonaise/svnrepo/dir test_expect_success 'verify metadata for /dir' " git cat-file commit refs/remotes/dir | \ - grep '^git-svn-id: $dir_url@2 $uuid$' && + grep '^${git_svn_id}: $dir_url@2 $uuid$' && git cat-file commit refs/remotes/dir~1 | \ - grep '^git-svn-id: $dir_url@1 $uuid$' + grep '^${git_svn_id}: $dir_url@1 $uuid$' " test_expect_success 'find commit based on SVN revision number' " - git-svn find-rev r12 | + git svn find-rev r12 | grep `git rev-parse HEAD` " test_expect_success 'empty rebase' " - git-svn rebase + git svn rebase " test_done diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh index c5dfd61e41..bd081c2ec3 100755 --- a/t/t9111-git-svn-use-svnsync-props.sh +++ b/t/t9111-git-svn-use-svnsync-props.sh @@ -3,17 +3,17 @@ # Copyright (c) 2007 Eric Wong # -test_description='git-svn useSvnsyncProps test' +test_description='git svn useSvnsyncProps test' . ./lib-git-svn.sh test_expect_success 'load svnsync repo' ' svnadmin load -q "$rawsvnrepo" < "$TEST_DIRECTORY"/t9111/svnsync.dump && - git-svn init --minimize-url -R arr -i bar "$svnrepo"/bar && - git-svn init --minimize-url -R argh -i dir "$svnrepo"/dir && - git-svn init --minimize-url -R argh -i e "$svnrepo"/dir/a/b/c/d/e && + git svn init --minimize-url -R arr -i bar "$svnrepo"/bar && + git svn init --minimize-url -R argh -i dir "$svnrepo"/dir && + git svn init --minimize-url -R argh -i e "$svnrepo"/dir/a/b/c/d/e && git config svn.useSvnsyncProps true && - git-svn fetch --all + git svn fetch --all ' uuid=161ce429-a9dd-4828-af4a-52023f968c89 @@ -21,31 +21,31 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89 bar_url=http://mayonaise/svnrepo/bar test_expect_success 'verify metadata for /bar' " git cat-file commit refs/remotes/bar | \ - grep '^git-svn-id: $bar_url@12 $uuid$' && + grep '^${git_svn_id}: $bar_url@12 $uuid$' && git cat-file commit refs/remotes/bar~1 | \ - grep '^git-svn-id: $bar_url@11 $uuid$' && + grep '^${git_svn_id}: $bar_url@11 $uuid$' && git cat-file commit refs/remotes/bar~2 | \ - grep '^git-svn-id: $bar_url@10 $uuid$' && + grep '^${git_svn_id}: $bar_url@10 $uuid$' && git cat-file commit refs/remotes/bar~3 | \ - grep '^git-svn-id: $bar_url@9 $uuid$' && + grep '^${git_svn_id}: $bar_url@9 $uuid$' && git cat-file commit refs/remotes/bar~4 | \ - grep '^git-svn-id: $bar_url@6 $uuid$' && + grep '^${git_svn_id}: $bar_url@6 $uuid$' && git cat-file commit refs/remotes/bar~5 | \ - grep '^git-svn-id: $bar_url@1 $uuid$' + grep '^${git_svn_id}: $bar_url@1 $uuid$' " e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e test_expect_success 'verify metadata for /dir/a/b/c/d/e' " git cat-file commit refs/remotes/e | \ - grep '^git-svn-id: $e_url@1 $uuid$' + grep '^${git_svn_id}: $e_url@1 $uuid$' " dir_url=http://mayonaise/svnrepo/dir test_expect_success 'verify metadata for /dir' " git cat-file commit refs/remotes/dir | \ - grep '^git-svn-id: $dir_url@2 $uuid$' && + grep '^${git_svn_id}: $dir_url@2 $uuid$' && git cat-file commit refs/remotes/dir~1 | \ - grep '^git-svn-id: $dir_url@1 $uuid$' + grep '^${git_svn_id}: $dir_url@1 $uuid$' " test_done diff --git a/t/t9112-git-svn-md5less-file.sh b/t/t9112-git-svn-md5less-file.sh index d470a920e4..a61d6716d2 100755 --- a/t/t9112-git-svn-md5less-file.sh +++ b/t/t9112-git-svn-md5less-file.sh @@ -42,6 +42,6 @@ EOF test_expect_success 'load svn dumpfile' 'svnadmin load "$rawsvnrepo" < dumpfile.svn' -test_expect_success 'initialize git-svn' 'git-svn init "$svnrepo"' -test_expect_success 'fetch revisions from svn' 'git-svn fetch' +test_expect_success 'initialize git svn' 'git svn init "$svnrepo"' +test_expect_success 'fetch revisions from svn' 'git svn fetch' test_done diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh index ae78e334ac..e9b6128b3f 100755 --- a/t/t9113-git-svn-dcommit-new-file.sh +++ b/t/t9113-git-svn-dcommit-new-file.sh @@ -8,23 +8,11 @@ # daemon running on a users system if the test fails. # Not all git users will need to interact with SVN. -test_description='git-svn dcommit new files over svn:// test' +test_description='git svn dcommit new files over svn:// test' . ./lib-git-svn.sh -if test -z "$SVNSERVE_PORT" -then - say 'skipping svnserve test. (set $SVNSERVE_PORT to enable)' - test_done - exit -fi - -start_svnserve () { - svnserve --listen-port $SVNSERVE_PORT \ - --root "$rawsvnrepo" \ - --listen-once \ - --listen-host 127.0.0.1 & -} +require_svnserve test_expect_success 'start tracking an empty repo' ' svn mkdir -m "empty dir" "$svnrepo"/empty-dir && diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh index 61d7781616..17b2855c4f 100755 --- a/t/t9114-git-svn-dcommit-merge.sh +++ b/t/t9114-git-svn-dcommit-merge.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Eric Wong # Based on a script by Joakim Tjernlund <joakim.tjernlund@transmode.se> -test_description='git-svn dcommit handles merges' +test_description='git svn dcommit handles merges' . ./lib-git-svn.sh diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh index b0ba1f0200..9be7aefaee 100755 --- a/t/t9115-git-svn-dcommit-funky-renames.sh +++ b/t/t9115-git-svn-dcommit-funky-renames.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Eric Wong -test_description='git-svn dcommit can commit renames of files with ugly names' +test_description='git svn dcommit can commit renames of files with ugly names' . ./lib-git-svn.sh @@ -75,7 +75,7 @@ test_expect_success 'make a commit to test rebase' ' git svn dcommit ' -test_expect_success 'git-svn rebase works inside a fresh-cloned repository' ' +test_expect_success 'git svn rebase works inside a fresh-cloned repository' ' cd test-rebase && git svn rebase && test -e test-rebase-main && diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh index 4b2cc878f6..fd6d1d2046 100755 --- a/t/t9116-git-svn-log.sh +++ b/t/t9116-git-svn-log.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Eric Wong # -test_description='git-svn log tests' +test_description='git svn log tests' . ./lib-git-svn.sh test_expect_success 'setup repository and import' ' @@ -16,8 +16,8 @@ test_expect_success 'setup repository and import' ' done && \ svn import -m test . "$svnrepo" cd .. && - git-svn init "$svnrepo" -T trunk -b branches -t tags && - git-svn fetch && + git svn init "$svnrepo" -T trunk -b branches -t tags && + git svn fetch && git reset --hard trunk && echo bye >> README && git commit -a -m bye && diff --git a/t/t9117-git-svn-init-clone.sh b/t/t9117-git-svn-init-clone.sh index 7a689bb1cd..dde46cd92f 100755 --- a/t/t9117-git-svn-init-clone.sh +++ b/t/t9117-git-svn-init-clone.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Eric Wong # -test_description='git-svn init/clone tests' +test_description='git svn init/clone tests' . ./lib-git-svn.sh diff --git a/t/t9118-git-svn-funky-branch-names.sh b/t/t9118-git-svn-funky-branch-names.sh index 3281cbd347..7a7c128687 100755 --- a/t/t9118-git-svn-funky-branch-names.sh +++ b/t/t9118-git-svn-funky-branch-names.sh @@ -3,9 +3,13 @@ # Copyright (c) 2007 Eric Wong # -test_description='git-svn funky branch names' +test_description='git svn funky branch names' . ./lib-git-svn.sh +# Abo-Uebernahme (Bug #994) +scary_uri='Abo-Uebernahme%20%28Bug%20%23994%29' +scary_ref='Abo-Uebernahme%20(Bug%20#994)' + test_expect_success 'setup svnrepo' ' mkdir project project/trunk project/branches project/tags && echo foo > project/trunk/foo && @@ -15,6 +19,8 @@ test_expect_success 'setup svnrepo' ' "$svnrepo/pr ject/branches/fun plugin" && svn cp -m "more fun!" "$svnrepo/pr ject/branches/fun plugin" \ "$svnrepo/pr ject/branches/more fun plugin!" && + svn cp -m "scary" "$svnrepo/pr ject/branches/fun plugin" \ + "$svnrepo/pr ject/branches/$scary_uri" && start_httpd ' @@ -23,6 +29,7 @@ test_expect_success 'test clone with funky branch names' ' cd project && git rev-parse "refs/remotes/fun%20plugin" && git rev-parse "refs/remotes/more%20fun%20plugin!" && + git rev-parse "refs/remotes/$scary_ref" && cd .. ' @@ -35,6 +42,15 @@ test_expect_success 'test dcommit to funky branch' " cd .. " +test_expect_success 'test dcommit to scary branch' ' + cd project && + git reset --hard "refs/remotes/$scary_ref" && + echo urls are scary >> foo && + git commit -m "eep" -- foo && + git svn dcommit && + cd .. + ' + stop_httpd test_done diff --git a/t/t9119-git-svn-info.sh b/t/t9119-git-svn-info.sh index 5fd36a1483..27dd7c273a 100755 --- a/t/t9119-git-svn-info.sh +++ b/t/t9119-git-svn-info.sh @@ -2,16 +2,14 @@ # # Copyright (c) 2007 David D. Kilzer -test_description='git-svn info' +test_description='git svn info' . ./lib-git-svn.sh -set -e - # Tested with: svn, version 1.4.4 (r25188) -v=`svn --version | sed -n -e 's/^svn, version \(1\.4\.[0-9]\).*$/\1/p'` +v=`svn --version | sed -n -e 's/^svn, version \(1\.[0-9]*\.[0-9]*\).*$/\1/p'` case $v in -1.4.*) +1.[45].*) ;; *) say "skipping svn-info test (SVN version: $v not supported)" @@ -36,6 +34,8 @@ ptouch() { ' "`svn info $2 | grep '^Text Last Updated:'`" "$1" } +quoted_svnrepo="$(echo $svnrepo | sed 's/ /%20/')" + test_expect_success 'setup repository and import' ' mkdir info && cd info && @@ -47,80 +47,92 @@ test_expect_success 'setup repository and import' ' ln -s directory symlink-directory && svn import -m "initial" . "$svnrepo" && cd .. && + svn co "$svnrepo" svnwc && + cd svnwc && + echo foo > foo && + svn add foo && + svn commit -m "change outside directory" && + svn update && + cd .. && mkdir gitwc && cd gitwc && - git-svn init "$svnrepo" && - git-svn fetch && + git svn init "$svnrepo" && + git svn fetch && cd .. && - svn co "$svnrepo" svnwc && - ptouch svnwc/file gitwc/file && - ptouch svnwc/directory gitwc/directory && - ptouch svnwc/symlink-file gitwc/symlink-file && - ptouch svnwc/symlink-directory gitwc/symlink-directory + ptouch gitwc/file svnwc/file && + ptouch gitwc/directory svnwc/directory && + ptouch gitwc/symlink-file svnwc/symlink-file && + ptouch gitwc/symlink-directory svnwc/symlink-directory ' test_expect_success 'info' " (cd svnwc; svn info) > expected.info && - (cd gitwc; git-svn info) > actual.info && - git-diff expected.info actual.info + (cd gitwc; git svn info) > actual.info && + test_cmp expected.info actual.info " test_expect_success 'info --url' ' - test "$(cd gitwc; git-svn info --url)" = "$svnrepo" + test "$(cd gitwc; git svn info --url)" = "$quoted_svnrepo" ' test_expect_success 'info .' " (cd svnwc; svn info .) > expected.info-dot && - (cd gitwc; git-svn info .) > actual.info-dot && - git-diff expected.info-dot actual.info-dot + (cd gitwc; git svn info .) > actual.info-dot && + test_cmp expected.info-dot actual.info-dot " test_expect_success 'info --url .' ' - test "$(cd gitwc; git-svn info --url .)" = "$svnrepo" + test "$(cd gitwc; git svn info --url .)" = "$quoted_svnrepo" ' test_expect_success 'info file' " (cd svnwc; svn info file) > expected.info-file && - (cd gitwc; git-svn info file) > actual.info-file && - git-diff expected.info-file actual.info-file + (cd gitwc; git svn info file) > actual.info-file && + test_cmp expected.info-file actual.info-file " test_expect_success 'info --url file' ' - test "$(cd gitwc; git-svn info --url file)" = "$svnrepo/file" + test "$(cd gitwc; git svn info --url file)" = "$quoted_svnrepo/file" ' test_expect_success 'info directory' " (cd svnwc; svn info directory) > expected.info-directory && - (cd gitwc; git-svn info directory) > actual.info-directory && - git-diff expected.info-directory actual.info-directory + (cd gitwc; git svn info directory) > actual.info-directory && + test_cmp expected.info-directory actual.info-directory + " + +test_expect_success 'info inside directory' " + (cd svnwc/directory; svn info) > expected.info-inside-directory && + (cd gitwc/directory; git svn info) > actual.info-inside-directory && + test_cmp expected.info-inside-directory actual.info-inside-directory " test_expect_success 'info --url directory' ' - test "$(cd gitwc; git-svn info --url directory)" = "$svnrepo/directory" + test "$(cd gitwc; git svn info --url directory)" = "$quoted_svnrepo/directory" ' test_expect_success 'info symlink-file' " (cd svnwc; svn info symlink-file) > expected.info-symlink-file && - (cd gitwc; git-svn info symlink-file) > actual.info-symlink-file && - git-diff expected.info-symlink-file actual.info-symlink-file + (cd gitwc; git svn info symlink-file) > actual.info-symlink-file && + test_cmp expected.info-symlink-file actual.info-symlink-file " test_expect_success 'info --url symlink-file' ' - test "$(cd gitwc; git-svn info --url symlink-file)" \ - = "$svnrepo/symlink-file" + test "$(cd gitwc; git svn info --url symlink-file)" \ + = "$quoted_svnrepo/symlink-file" ' test_expect_success 'info symlink-directory' " (cd svnwc; svn info symlink-directory) \ > expected.info-symlink-directory && - (cd gitwc; git-svn info symlink-directory) \ + (cd gitwc; git svn info symlink-directory) \ > actual.info-symlink-directory && - git-diff expected.info-symlink-directory actual.info-symlink-directory + test_cmp expected.info-symlink-directory actual.info-symlink-directory " test_expect_success 'info --url symlink-directory' ' - test "$(cd gitwc; git-svn info --url symlink-directory)" \ - = "$svnrepo/symlink-directory" + test "$(cd gitwc; git svn info --url symlink-directory)" \ + = "$quoted_svnrepo/symlink-directory" ' test_expect_success 'info added-file' " @@ -134,13 +146,13 @@ test_expect_success 'info added-file' " svn add added-file > /dev/null && cd .. && (cd svnwc; svn info added-file) > expected.info-added-file && - (cd gitwc; git-svn info added-file) > actual.info-added-file && - git-diff expected.info-added-file actual.info-added-file + (cd gitwc; git svn info added-file) > actual.info-added-file && + test_cmp expected.info-added-file actual.info-added-file " test_expect_success 'info --url added-file' ' - test "$(cd gitwc; git-svn info --url added-file)" \ - = "$svnrepo/added-file" + test "$(cd gitwc; git svn info --url added-file)" \ + = "$quoted_svnrepo/added-file" ' test_expect_success 'info added-directory' " @@ -155,14 +167,14 @@ test_expect_success 'info added-directory' " cd .. && (cd svnwc; svn info added-directory) \ > expected.info-added-directory && - (cd gitwc; git-svn info added-directory) \ + (cd gitwc; git svn info added-directory) \ > actual.info-added-directory && - git-diff expected.info-added-directory actual.info-added-directory + test_cmp expected.info-added-directory actual.info-added-directory " test_expect_success 'info --url added-directory' ' - test "$(cd gitwc; git-svn info --url added-directory)" \ - = "$svnrepo/added-directory" + test "$(cd gitwc; git svn info --url added-directory)" \ + = "$quoted_svnrepo/added-directory" ' test_expect_success 'info added-symlink-file' " @@ -177,15 +189,15 @@ test_expect_success 'info added-symlink-file' " ptouch gitwc/added-symlink-file svnwc/added-symlink-file && (cd svnwc; svn info added-symlink-file) \ > expected.info-added-symlink-file && - (cd gitwc; git-svn info added-symlink-file) \ + (cd gitwc; git svn info added-symlink-file) \ > actual.info-added-symlink-file && - git-diff expected.info-added-symlink-file \ + test_cmp expected.info-added-symlink-file \ actual.info-added-symlink-file " test_expect_success 'info --url added-symlink-file' ' - test "$(cd gitwc; git-svn info --url added-symlink-file)" \ - = "$svnrepo/added-symlink-file" + test "$(cd gitwc; git svn info --url added-symlink-file)" \ + = "$quoted_svnrepo/added-symlink-file" ' test_expect_success 'info added-symlink-directory' " @@ -200,15 +212,15 @@ test_expect_success 'info added-symlink-directory' " ptouch gitwc/added-symlink-directory svnwc/added-symlink-directory && (cd svnwc; svn info added-symlink-directory) \ > expected.info-added-symlink-directory && - (cd gitwc; git-svn info added-symlink-directory) \ + (cd gitwc; git svn info added-symlink-directory) \ > actual.info-added-symlink-directory && - git-diff expected.info-added-symlink-directory \ + test_cmp expected.info-added-symlink-directory \ actual.info-added-symlink-directory " test_expect_success 'info --url added-symlink-directory' ' - test "$(cd gitwc; git-svn info --url added-symlink-directory)" \ - = "$svnrepo/added-symlink-directory" + test "$(cd gitwc; git svn info --url added-symlink-directory)" \ + = "$quoted_svnrepo/added-symlink-directory" ' # The next few tests replace the "Text Last Updated" value with a @@ -226,15 +238,15 @@ test_expect_success 'info deleted-file' " (cd svnwc; svn info file) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > expected.info-deleted-file && - (cd gitwc; git-svn info file) | + (cd gitwc; git svn info file) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > actual.info-deleted-file && - git-diff expected.info-deleted-file actual.info-deleted-file + test_cmp expected.info-deleted-file actual.info-deleted-file " test_expect_success 'info --url file (deleted)' ' - test "$(cd gitwc; git-svn info --url file)" \ - = "$svnrepo/file" + test "$(cd gitwc; git svn info --url file)" \ + = "$quoted_svnrepo/file" ' test_expect_success 'info deleted-directory' " @@ -247,15 +259,15 @@ test_expect_success 'info deleted-directory' " (cd svnwc; svn info directory) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > expected.info-deleted-directory && - (cd gitwc; git-svn info directory) | + (cd gitwc; git svn info directory) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > actual.info-deleted-directory && - git-diff expected.info-deleted-directory actual.info-deleted-directory + test_cmp expected.info-deleted-directory actual.info-deleted-directory " test_expect_success 'info --url directory (deleted)' ' - test "$(cd gitwc; git-svn info --url directory)" \ - = "$svnrepo/directory" + test "$(cd gitwc; git svn info --url directory)" \ + = "$quoted_svnrepo/directory" ' test_expect_success 'info deleted-symlink-file' " @@ -268,16 +280,16 @@ test_expect_success 'info deleted-symlink-file' " (cd svnwc; svn info symlink-file) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > expected.info-deleted-symlink-file && - (cd gitwc; git-svn info symlink-file) | + (cd gitwc; git svn info symlink-file) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > actual.info-deleted-symlink-file && - git-diff expected.info-deleted-symlink-file \ + test_cmp expected.info-deleted-symlink-file \ actual.info-deleted-symlink-file " test_expect_success 'info --url symlink-file (deleted)' ' - test "$(cd gitwc; git-svn info --url symlink-file)" \ - = "$svnrepo/symlink-file" + test "$(cd gitwc; git svn info --url symlink-file)" \ + = "$quoted_svnrepo/symlink-file" ' test_expect_success 'info deleted-symlink-directory' " @@ -290,16 +302,16 @@ test_expect_success 'info deleted-symlink-directory' " (cd svnwc; svn info symlink-directory) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > expected.info-deleted-symlink-directory && - (cd gitwc; git-svn info symlink-directory) | + (cd gitwc; git svn info symlink-directory) | sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \ > actual.info-deleted-symlink-directory && - git-diff expected.info-deleted-symlink-directory \ + test_cmp expected.info-deleted-symlink-directory \ actual.info-deleted-symlink-directory " test_expect_success 'info --url symlink-directory (deleted)' ' - test "$(cd gitwc; git-svn info --url symlink-directory)" \ - = "$svnrepo/symlink-directory" + test "$(cd gitwc; git svn info --url symlink-directory)" \ + = "$quoted_svnrepo/symlink-directory" ' # NOTE: git does not have the concept of replaced objects, @@ -307,82 +319,59 @@ test_expect_success 'info --url symlink-directory (deleted)' ' test_expect_success 'info unknown-file' " echo two > gitwc/unknown-file && - cp gitwc/unknown-file svnwc/unknown-file && - ptouch gitwc/unknown-file svnwc/unknown-file && - (cd svnwc; svn info unknown-file) 2> expected.info-unknown-file && - (cd gitwc; git-svn info unknown-file) 2> actual.info-unknown-file && - git-diff expected.info-unknown-file actual.info-unknown-file + (cd gitwc; test_must_fail git svn info unknown-file) \ + 2> actual.info-unknown-file && + grep unknown-file actual.info-unknown-file " test_expect_success 'info --url unknown-file' ' - test -z "$(cd gitwc; git-svn info --url unknown-file \ - 2> ../actual.info--url-unknown-file)" && - git-diff expected.info-unknown-file actual.info--url-unknown-file + echo two > gitwc/unknown-file && + (cd gitwc; test_must_fail git svn info --url unknown-file) \ + 2> actual.info-url-unknown-file && + grep unknown-file actual.info-url-unknown-file ' test_expect_success 'info unknown-directory' " mkdir gitwc/unknown-directory svnwc/unknown-directory && - ptouch gitwc/unknown-directory svnwc/unknown-directory && - touch gitwc/unknown-directory/.placeholder && - (cd svnwc; svn info unknown-directory) \ - 2> expected.info-unknown-directory && - (cd gitwc; git-svn info unknown-directory) \ - 2> actual.info-unknown-directory && - git-diff expected.info-unknown-directory actual.info-unknown-directory + (cd gitwc; test_must_fail git svn info unknown-directory) \ + 2> actual.info-unknown-directory && + grep unknown-directory actual.info-unknown-directory " test_expect_success 'info --url unknown-directory' ' - test -z "$(cd gitwc; git-svn info --url unknown-directory \ - 2> ../actual.info--url-unknown-directory)" && - git-diff expected.info-unknown-directory \ - actual.info--url-unknown-directory + (cd gitwc; test_must_fail git svn info --url unknown-directory) \ + 2> actual.info-url-unknown-directory && + grep unknown-directory actual.info-url-unknown-directory ' test_expect_success 'info unknown-symlink-file' " cd gitwc && ln -s unknown-file unknown-symlink-file && cd .. && - cd svnwc && - ln -s unknown-file unknown-symlink-file && - cd .. && - ptouch gitwc/unknown-symlink-file svnwc/unknown-symlink-file && - (cd svnwc; svn info unknown-symlink-file) \ - 2> expected.info-unknown-symlink-file && - (cd gitwc; git-svn info unknown-symlink-file) \ - 2> actual.info-unknown-symlink-file && - git-diff expected.info-unknown-symlink-file \ - actual.info-unknown-symlink-file + (cd gitwc; test_must_fail git svn info unknown-symlink-file) \ + 2> actual.info-unknown-symlink-file && + grep unknown-symlink-file actual.info-unknown-symlink-file " test_expect_success 'info --url unknown-symlink-file' ' - test -z "$(cd gitwc; git-svn info --url unknown-symlink-file \ - 2> ../actual.info--url-unknown-symlink-file)" && - git-diff expected.info-unknown-symlink-file \ - actual.info--url-unknown-symlink-file + (cd gitwc; test_must_fail git svn info --url unknown-symlink-file) \ + 2> actual.info-url-unknown-symlink-file && + grep unknown-symlink-file actual.info-url-unknown-symlink-file ' test_expect_success 'info unknown-symlink-directory' " cd gitwc && ln -s unknown-directory unknown-symlink-directory && cd .. && - cd svnwc && - ln -s unknown-directory unknown-symlink-directory && - cd .. && - ptouch gitwc/unknown-symlink-directory \ - svnwc/unknown-symlink-directory && - (cd svnwc; svn info unknown-symlink-directory) \ - 2> expected.info-unknown-symlink-directory && - (cd gitwc; git-svn info unknown-symlink-directory) \ - 2> actual.info-unknown-symlink-directory && - git-diff expected.info-unknown-symlink-directory \ - actual.info-unknown-symlink-directory + (cd gitwc; test_must_fail git svn info unknown-symlink-directory) \ + 2> actual.info-unknown-symlink-directory && + grep unknown-symlink-directory actual.info-unknown-symlink-directory " test_expect_success 'info --url unknown-symlink-directory' ' - test -z "$(cd gitwc; git-svn info --url unknown-symlink-directory \ - 2> ../actual.info--url-unknown-symlink-directory)" && - git-diff expected.info-unknown-symlink-directory \ - actual.info--url-unknown-symlink-directory + (cd gitwc; test_must_fail git svn info --url unknown-symlink-directory) \ + 2> actual.info-url-unknown-symlink-directory && + grep unknown-symlink-directory actual.info-url-unknown-symlink-directory ' test_done diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh index 5979e133b9..ef2c0523cd 100755 --- a/t/t9120-git-svn-clone-with-percent-escapes.sh +++ b/t/t9120-git-svn-clone-with-percent-escapes.sh @@ -3,7 +3,7 @@ # Copyright (c) 2008 Kevin Ballard # -test_description='git-svn clone with percent escapes' +test_description='git svn clone with percent escapes' . ./lib-git-svn.sh test_expect_success 'setup svnrepo' ' @@ -21,7 +21,7 @@ else test_expect_success 'test clone with percent escapes' ' git svn clone "$svnrepo/pr%20ject" clone && cd clone && - git rev-parse refs/remotes/git-svn && + git rev-parse refs/${remotes_git_svn} && cd .. ' fi diff --git a/t/t9121-git-svn-fetch-renamed-dir.sh b/t/t9121-git-svn-fetch-renamed-dir.sh index 92e69a2a75..000cad37c6 100755 --- a/t/t9121-git-svn-fetch-renamed-dir.sh +++ b/t/t9121-git-svn-fetch-renamed-dir.sh @@ -3,7 +3,7 @@ # Copyright (c) 2008 Santhosh Kumar Mani -test_description='git-svn can fetch renamed directories' +test_description='git svn can fetch renamed directories' . ./lib-git-svn.sh diff --git a/t/t9122-git-svn-author.sh b/t/t9122-git-svn-author.sh index 1190576a65..1b1cf47281 100755 --- a/t/t9122-git-svn-author.sh +++ b/t/t9122-git-svn-author.sh @@ -13,7 +13,7 @@ test_expect_success 'setup svn repository' ' ) ' -test_expect_success 'interact with it via git-svn' ' +test_expect_success 'interact with it via git svn' ' mkdir work.git && ( cd work.git && diff --git a/t/t9123-git-svn-rebuild-with-rewriteroot.sh b/t/t9123-git-svn-rebuild-with-rewriteroot.sh index c18878fad1..cf0415274c 100755 --- a/t/t9123-git-svn-rebuild-with-rewriteroot.sh +++ b/t/t9123-git-svn-rebuild-with-rewriteroot.sh @@ -3,21 +3,21 @@ # Copyright (c) 2008 Jan Krüger # -test_description='git-svn respects rewriteRoot during rebuild' +test_description='git svn respects rewriteRoot during rebuild' . ./lib-git-svn.sh mkdir import cd import touch foo - svn import -m 'import for git-svn' . "$svnrepo" >/dev/null + svn import -m 'import for git svn' . "$svnrepo" >/dev/null cd .. rm -rf import test_expect_success 'init, fetch and checkout repository' ' git svn init --rewrite-root=http://invalid.invalid/ "$svnrepo" && git svn fetch - git checkout -b mybranch remotes/git-svn + git checkout -b mybranch ${remotes_git_svn} ' test_expect_success 'remove rev_map' ' diff --git a/t/t9124-git-svn-dcommit-auto-props.sh b/t/t9124-git-svn-dcommit-auto-props.sh index 8223c5909e..263dbf5fc2 100755 --- a/t/t9124-git-svn-dcommit-auto-props.sh +++ b/t/t9124-git-svn-dcommit-auto-props.sh @@ -2,7 +2,7 @@ # # Copyright (c) 2008 Brad King -test_description='git-svn dcommit honors auto-props' +test_description='git svn dcommit honors auto-props' . ./lib-git-svn.sh @@ -16,26 +16,24 @@ enable-auto-props=$1 EOF } -test_expect_success 'initialize git-svn' ' +test_expect_success 'initialize git svn' ' mkdir import && ( cd import && echo foo >foo && - svn import -m "import for git-svn" . "$svnrepo" + svn import -m "import for git svn" . "$svnrepo" ) && rm -rf import && - git-svn init "$svnrepo" - git-svn fetch + git svn init "$svnrepo" + git svn fetch ' test_expect_success 'enable auto-props config' ' - cd "$gittestrepo" && mkdir user && generate_auto_props yes >user/config ' test_expect_success 'add files matching auto-props' ' - cd "$gittestrepo" && echo "#!$SHELL_PATH" >exec1.sh && chmod +x exec1.sh && echo "hello" >hello.txt && @@ -46,12 +44,10 @@ test_expect_success 'add files matching auto-props' ' ' test_expect_success 'disable auto-props config' ' - cd "$gittestrepo" && generate_auto_props no >user/config ' test_expect_success 'add files matching disabled auto-props' ' - cd "$gittestrepo" && echo "#$SHELL_PATH" >exec2.sh && chmod +x exec2.sh && echo "world" >world.txt && @@ -62,6 +58,7 @@ test_expect_success 'add files matching disabled auto-props' ' ' test_expect_success 'check resulting svn repository' ' +( mkdir work && cd work && svn co "$svnrepo" && @@ -81,6 +78,24 @@ test_expect_success 'check resulting svn repository' ' test "x$(svn propget svn:mime-type world.txt)" = "x" && test "x$(svn propget svn:eol-style world.txt)" = "x" && test "x$(svn propget svn:mime-type zot)" = "x" +) +' + +test_expect_success 'check renamed file' ' + test -d user && + generate_auto_props yes > user/config && + git mv foo foo.sh && + git commit -m "foo => foo.sh" && + git svn dcommit --config-dir=user && + ( + cd work/svnrepo && + svn up && + test ! -e foo && + test -e foo.sh && + test "x$(svn propget svn:mime-type foo.sh)" = \ + "xapplication/x-shellscript" && + test "x$(svn propget svn:eol-style foo.sh)" = "xLF" + ) ' test_done diff --git a/t/t9125-git-svn-multi-glob-branch-names.sh b/t/t9125-git-svn-multi-glob-branch-names.sh index 6b62b52f54..475c751c1c 100755 --- a/t/t9125-git-svn-multi-glob-branch-names.sh +++ b/t/t9125-git-svn-multi-glob-branch-names.sh @@ -1,7 +1,7 @@ #!/bin/sh # Copyright (c) 2008 Marcus Griep -test_description='git-svn multi-glob branch names' +test_description='git svn multi-glob branch names' . ./lib-git-svn.sh test_expect_success 'setup svnrepo' ' diff --git a/t/t9126-git-svn-follow-deleted-readded-directory.sh b/t/t9126-git-svn-follow-deleted-readded-directory.sh new file mode 100755 index 0000000000..edec640e97 --- /dev/null +++ b/t/t9126-git-svn-follow-deleted-readded-directory.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# +# Copyright (c) 2008 Alec Berryman + +test_description='git svn fetch repository with deleted and readded directory' + +. ./lib-git-svn.sh + +# Don't run this by default; it opens up a port. +require_svnserve + +test_expect_success 'load repository' ' + svnadmin load -q "$rawsvnrepo" < "$TEST_DIRECTORY"/t9126/follow-deleted-readded.dump + ' + +test_expect_success 'fetch repository' ' + start_svnserve && + git svn init svn://127.0.0.1:$SVNSERVE_PORT && + git svn fetch + ' + +test_done diff --git a/t/t9126/follow-deleted-readded.dump b/t/t9126/follow-deleted-readded.dump new file mode 100644 index 0000000000..19da5d1ddc --- /dev/null +++ b/t/t9126/follow-deleted-readded.dump @@ -0,0 +1,201 @@ +SVN-fs-dump-format-version: 2 + +UUID: 1807dc6f-c693-4cda-9710-00e1be8c1f21 + +Revision-number: 0 +Prop-content-length: 56 +Content-length: 56 + +K 8 +svn:date +V 27 +2008-09-14T19:53:13.006748Z +PROPS-END + +Revision-number: 1 +Prop-content-length: 111 +Content-length: 111 + +K 7 +svn:log +V 12 +Create trunk +K 10 +svn:author +V 4 +alec +K 8 +svn:date +V 27 +2008-09-14T19:53:13.239689Z +PROPS-END + +Node-path: trunk +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Revision-number: 2 +Prop-content-length: 119 +Content-length: 119 + +K 7 +svn:log +V 20 +Create trunk/project +K 10 +svn:author +V 4 +alec +K 8 +svn:date +V 27 +2008-09-14T19:53:13.548860Z +PROPS-END + +Node-path: trunk/project +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Revision-number: 3 +Prop-content-length: 111 +Content-length: 111 + +K 7 +svn:log +V 12 +add new file +K 10 +svn:author +V 4 +alec +K 8 +svn:date +V 27 +2008-09-14T19:53:15.433630Z +PROPS-END + +Node-path: trunk/project/foo +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 4 +Text-content-md5: d3b07384d113edec49eaa6238ad5ff00 +Content-length: 14 + +PROPS-END +foo + + +Revision-number: 4 +Prop-content-length: 116 +Content-length: 116 + +K 7 +svn:log +V 17 +change foo to bar +K 10 +svn:author +V 4 +alec +K 8 +svn:date +V 27 +2008-09-14T19:53:17.339884Z +PROPS-END + +Node-path: trunk/project/foo +Node-kind: file +Node-action: change +Text-content-length: 4 +Text-content-md5: c157a79031e1c40f85931829bc5fc552 +Content-length: 4 + +bar + + +Revision-number: 5 +Prop-content-length: 114 +Content-length: 114 + +K 7 +svn:log +V 15 +don't like that +K 10 +svn:author +V 4 +alec +K 8 +svn:date +V 27 +2008-09-14T19:53:19.335001Z +PROPS-END + +Node-path: trunk/project +Node-action: delete + + +Revision-number: 6 +Prop-content-length: 110 +Content-length: 110 + +K 7 +svn:log +V 11 +reset trunk +K 10 +svn:author +V 4 +alec +K 8 +svn:date +V 27 +2008-09-14T19:53:19.845897Z +PROPS-END + +Node-path: trunk/project +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 4 +Node-copyfrom-path: trunk/project + + +Revision-number: 7 +Prop-content-length: 113 +Content-length: 113 + +K 7 +svn:log +V 14 +change to quux +K 10 +svn:author +V 4 +alec +K 8 +svn:date +V 27 +2008-09-14T19:53:21.367947Z +PROPS-END + +Node-path: trunk/project/foo +Node-kind: file +Node-action: change +Text-content-length: 5 +Text-content-md5: d3b07a382ec010c01889250fce66fb13 +Content-length: 5 + +quux + + diff --git a/t/t9127-git-svn-partial-rebuild.sh b/t/t9127-git-svn-partial-rebuild.sh new file mode 100755 index 0000000000..87696a92dc --- /dev/null +++ b/t/t9127-git-svn-partial-rebuild.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# +# Copyright (c) 2008 Deskin Miller +# + +test_description='git svn partial-rebuild tests' +. ./lib-git-svn.sh + +test_expect_success 'initialize svnrepo' ' + mkdir import && + ( + cd import && + mkdir trunk branches tags && + cd trunk && + echo foo > foo && + cd .. && + svn import -m "import for git-svn" . "$svnrepo" >/dev/null && + svn copy "$svnrepo"/trunk "$svnrepo"/branches/a \ + -m "created branch a" && + cd .. && + rm -rf import && + svn co "$svnrepo"/trunk trunk && + cd trunk && + echo bar >> foo && + svn ci -m "updated trunk" && + cd .. && + svn co "$svnrepo"/branches/a a && + cd a && + echo baz >> a && + svn add a && + svn ci -m "updated a" && + cd .. && + git svn init --stdlayout "$svnrepo" + ) +' + +test_expect_success 'import an early SVN revision into git' ' + git svn fetch -r1:2 +' + +test_expect_success 'make full git mirror of SVN' ' + mkdir mirror && + ( + cd mirror && + git init && + git svn init --stdlayout "$svnrepo" && + git svn fetch && + cd .. + ) +' + +test_expect_success 'fetch from git mirror and partial-rebuild' ' + git config --add remote.origin.url "file://$PWD/mirror/.git" && + git config --add remote.origin.fetch refs/remotes/*:refs/remotes/* && + git fetch origin && + git svn fetch +' + +test_done diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index 988c3ac754..245a7c3662 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -9,7 +9,7 @@ test_description='Test export of commits to CVS' cvs >/dev/null 2>&1 if test $? -ne 1 then - test_expect_success 'skipping git-cvsexportcommit tests, cvs not found' : + test_expect_success 'skipping git cvsexportcommit tests, cvs not found' : test_done exit fi @@ -91,7 +91,7 @@ test_expect_success \ diff F/newfile6.png ../F/newfile6.png )' -# Should fail (but only on the git-cvsexportcommit stage) +# Should fail (but only on the git cvsexportcommit stage) test_expect_success \ 'Fail to change binary more than one generation old' \ 'cat F/newfile6.png >>D/newfile4.png && @@ -165,7 +165,7 @@ test_expect_success \ git commit -a -m "With spaces" && id=$(git rev-list --max-count=1 HEAD) && (cd "$CVSWORK" && - git-cvsexportcommit -c $id && + git cvsexportcommit -c $id && check_entries "G g" "with spaces.png/1.1/-kb|with spaces.txt/1.1/" )' @@ -177,7 +177,7 @@ test_expect_success \ git commit -a -m "Update with spaces" && id=$(git rev-list --max-count=1 HEAD) && (cd "$CVSWORK" && - git-cvsexportcommit -c $id + git cvsexportcommit -c $id check_entries "G g" "with spaces.png/1.2/-kb|with spaces.txt/1.2/" )' @@ -202,7 +202,7 @@ test_expect_success \ git commit -a -m "Går det så går det" && \ id=$(git rev-list --max-count=1 HEAD) && (cd "$CVSWORK" && - git-cvsexportcommit -v -c $id && + git cvsexportcommit -v -c $id && check_entries \ "Å/goo/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/å/ä/ö" \ "gårdetsågårdet.png/1.1/-kb|gårdetsågårdet.txt/1.1/" @@ -222,7 +222,7 @@ test_expect_success \ git commit -a -m "Update two" && id=$(git rev-list --max-count=1 HEAD) && (cd "$CVSWORK" && - test_must_fail git-cvsexportcommit -c $id + test_must_fail git cvsexportcommit -c $id )' case "$(git config --bool core.filemode)" in @@ -239,7 +239,7 @@ test_expect_success \ git add G/off && git commit -a -m "Execute test" && (cd "$CVSWORK" && - git-cvsexportcommit -c HEAD + git cvsexportcommit -c HEAD test -x G/on && ! test -x G/off )' diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index bd5d5af661..328444a306 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Shawn Pearce # -test_description='test git-fast-import utility' +test_description='test git fast-import utility' . ./test-lib.sh . "$TEST_DIRECTORY"/diff-lib.sh ;# test-lib chdir's into trash @@ -59,7 +59,7 @@ M 755 :4 file4 INPUT_END test_expect_success \ 'A: create pack from stdin' \ - 'git-fast-import --export-marks=marks.out <input && + 'git fast-import --export-marks=marks.out <input && git whatchanged master' test_expect_success \ 'A: verify pack' \ @@ -113,7 +113,7 @@ test_expect_success \ test_expect_success \ 'A: verify marks import' \ - 'git-fast-import \ + 'git fast-import \ --import-marks=marks.out \ --export-marks=marks.new \ </dev/null && @@ -133,7 +133,7 @@ M 755 :2 copy-of-file2 INPUT_END test_expect_success \ 'A: verify marks import does not crash' \ - 'git-fast-import --import-marks=marks.out <input && + 'git fast-import --import-marks=marks.out <input && git whatchanged verify--import-marks' test_expect_success \ 'A: verify pack' \ @@ -166,7 +166,7 @@ M 755 0000000000000000000000000000000000000001 zero1 INPUT_END test_expect_success 'B: fail on invalid blob sha1' ' - test_must_fail git-fast-import <input + test_must_fail git fast-import <input ' rm -f .git/objects/pack_* .git/objects/index_* @@ -181,7 +181,7 @@ from refs/heads/master INPUT_END test_expect_success 'B: fail on invalid branch name ".badbranchname"' ' - test_must_fail git-fast-import <input + test_must_fail git fast-import <input ' rm -f .git/objects/pack_* .git/objects/index_* @@ -196,7 +196,7 @@ from refs/heads/master INPUT_END test_expect_success 'B: fail on invalid branch name "bad[branch]name"' ' - test_must_fail git-fast-import <input + test_must_fail git fast-import <input ' rm -f .git/objects/pack_* .git/objects/index_* @@ -212,7 +212,7 @@ from refs/heads/master INPUT_END test_expect_success \ 'B: accept branch name "TEMP_TAG"' \ - 'git-fast-import <input && + 'git fast-import <input && test -f .git/TEMP_TAG && test `git rev-parse master` = `git rev-parse TEMP_TAG^`' rm -f .git/TEMP_TAG @@ -221,7 +221,7 @@ rm -f .git/TEMP_TAG ### series C ### -newf=`echo hi newf | git-hash-object -w --stdin` +newf=`echo hi newf | git hash-object -w --stdin` oldf=`git rev-parse --verify master:file2` test_tick cat >input <<INPUT_END @@ -239,7 +239,7 @@ D file3 INPUT_END test_expect_success \ 'C: incremental import create pack from stdin' \ - 'git-fast-import <input && + 'git fast-import <input && git whatchanged branch' test_expect_success \ 'C: verify pack' \ @@ -297,7 +297,7 @@ EOF INPUT_END test_expect_success \ 'D: inline data in commit' \ - 'git-fast-import <input && + 'git fast-import <input && git whatchanged branch' test_expect_success \ 'D: verify pack' \ @@ -340,11 +340,11 @@ from refs/heads/branch^0 INPUT_END test_expect_success 'E: rfc2822 date, --date-format=raw' ' - test_must_fail git-fast-import --date-format=raw <input + test_must_fail git fast-import --date-format=raw <input ' test_expect_success \ 'E: rfc2822 date, --date-format=rfc2822' \ - 'git-fast-import --date-format=rfc2822 <input' + 'git fast-import --date-format=rfc2822 <input' test_expect_success \ 'E: verify pack' \ 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done' @@ -381,7 +381,7 @@ from refs/heads/branch INPUT_END test_expect_success \ 'F: non-fast-forward update skips' \ - 'if git-fast-import <input + 'if git fast-import <input then echo BAD gfi did not fail return 1 @@ -431,7 +431,7 @@ from refs/heads/branch~1 INPUT_END test_expect_success \ 'G: non-fast-forward update forced' \ - 'git-fast-import --force <input' + 'git fast-import --force <input' test_expect_success \ 'G: verify pack' \ 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done' @@ -467,7 +467,7 @@ EOF INPUT_END test_expect_success \ 'H: deletall, add 1' \ - 'git-fast-import <input && + 'git fast-import <input && git whatchanged H' test_expect_success \ 'H: verify pack' \ @@ -507,7 +507,7 @@ from refs/heads/branch INPUT_END test_expect_success \ 'I: export-pack-edges' \ - 'git-fast-import --export-pack-edges=edges.list <input' + 'git fast-import --export-pack-edges=edges.list <input' cat >expect <<EOF .git/objects/pack/pack-.pack: `git rev-parse --verify export-boundary` @@ -541,7 +541,7 @@ COMMIT INPUT_END test_expect_success \ 'J: reset existing branch creates empty commit' \ - 'git-fast-import <input' + 'git fast-import <input' test_expect_success \ 'J: branch has 1 commit, empty tree' \ 'test 1 = `git rev-list J | wc -l` && @@ -571,7 +571,7 @@ from refs/heads/branch^1 INPUT_END test_expect_success \ 'K: reinit branch with from' \ - 'git-fast-import <input' + 'git fast-import <input' test_expect_success \ 'K: verify K^1 = branch^1' \ 'test `git rev-parse --verify branch^1` \ @@ -623,7 +623,7 @@ EXPECT_END test_expect_success \ 'L: verify internal tree sorting' \ - 'git-fast-import <input && + 'git fast-import <input && git diff-tree --abbrev --raw L^ L >output && test_cmp expect output' @@ -649,7 +649,7 @@ cat >expect <<EOF EOF test_expect_success \ 'M: rename file in same subdirectory' \ - 'git-fast-import <input && + 'git fast-import <input && git diff-tree -M -r M1^ M1 >actual && compare_diff_raw expect actual' @@ -670,7 +670,7 @@ cat >expect <<EOF EOF test_expect_success \ 'M: rename file to new subdirectory' \ - 'git-fast-import <input && + 'git fast-import <input && git diff-tree -M -r M2^ M2 >actual && compare_diff_raw expect actual' @@ -691,7 +691,7 @@ cat >expect <<EOF EOF test_expect_success \ 'M: rename subdirectory to new subdirectory' \ - 'git-fast-import <input && + 'git fast-import <input && git diff-tree -M -r M3^ M3 >actual && compare_diff_raw expect actual' @@ -717,7 +717,7 @@ cat >expect <<EOF EOF test_expect_success \ 'N: copy file in same subdirectory' \ - 'git-fast-import <input && + 'git fast-import <input && git diff-tree -C --find-copies-harder -r N1^ N1 >actual && compare_diff_raw expect actual' @@ -751,7 +751,7 @@ cat >expect <<EOF EOF test_expect_success \ 'N: copy then modify subdirectory' \ - 'git-fast-import <input && + 'git fast-import <input && git diff-tree -C --find-copies-harder -r N2^^ N2 >actual && compare_diff_raw expect actual' @@ -775,8 +775,8 @@ INPUT_END test_expect_success \ 'N: copy dirty subdirectory' \ - 'git-fast-import <input && - test `git-rev-parse N2^{tree}` = `git-rev-parse N3^{tree}`' + 'git fast-import <input && + test `git rev-parse N2^{tree}` = `git rev-parse N3^{tree}`' ### ### series O @@ -815,8 +815,8 @@ INPUT_END test_expect_success \ 'O: comments are all skipped' \ - 'git-fast-import <input && - test `git-rev-parse N3` = `git-rev-parse O1`' + 'git fast-import <input && + test `git rev-parse N3` = `git rev-parse O1`' cat >input <<INPUT_END commit refs/heads/O2 @@ -836,8 +836,8 @@ INPUT_END test_expect_success \ 'O: blank lines not necessary after data commands' \ - 'git-fast-import <input && - test `git-rev-parse N3` = `git-rev-parse O2`' + 'git fast-import <input && + test `git rev-parse N3` = `git rev-parse O2`' test_expect_success \ 'O: repack before next test' \ @@ -881,7 +881,7 @@ commits INPUT_END test_expect_success \ 'O: blank lines not necessary after other commands' \ - 'git-fast-import <input && + 'git fast-import <input && test 8 = `find .git/objects/pack -type f | wc -l` && test `git rev-parse refs/tags/O3-2nd` = `git rev-parse O3^` && git log --reverse --pretty=oneline O3 | sed s/^.*z// >actual && @@ -914,7 +914,7 @@ progress I'm done! INPUT_END test_expect_success \ 'O: progress outputs as requested by input' \ - 'git-fast-import <input >actual && + 'git fast-import <input >actual && grep "progress " <input >expect && test_cmp expect actual' @@ -979,7 +979,7 @@ INPUT_END test_expect_success \ 'P: supermodule & submodule mix' \ - 'git-fast-import <input && + 'git fast-import <input && git checkout subuse1 && rm -rf sub && mkdir sub && cd sub && git init && @@ -989,8 +989,8 @@ test_expect_success \ git submodule init && git submodule update' -SUBLAST=$(git-rev-parse --verify sub) -SUBPREV=$(git-rev-parse --verify sub^) +SUBLAST=$(git rev-parse --verify sub) +SUBPREV=$(git rev-parse --verify sub^) cat >input <<INPUT_END blob @@ -1024,8 +1024,8 @@ test_expect_success \ 'P: verbatim SHA gitlinks' \ 'git branch -D sub && git gc && git prune && - git-fast-import <input && - test $(git-rev-parse --verify subuse2) = $(git-rev-parse --verify subuse1)' + git fast-import <input && + test $(git rev-parse --verify subuse2) = $(git rev-parse --verify subuse1)' test_tick cat >input <<INPUT_END @@ -1045,7 +1045,7 @@ DATA INPUT_END test_expect_success 'P: fail on inline gitlink' ' - test_must_fail git-fast-import <input' + test_must_fail git fast-import <input' test_tick cat >input <<INPUT_END @@ -1068,6 +1068,6 @@ M 160000 :1 sub INPUT_END test_expect_success 'P: fail on blob mark in gitlink' ' - test_must_fail git-fast-import <input' + test_must_fail git fast-import <input' test_done diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh index 3cb9f80708..6ddd7c19fd 100755 --- a/t/t9301-fast-export.sh +++ b/t/t9301-fast-export.sh @@ -3,7 +3,7 @@ # Copyright (c) 2007 Johannes E. Schindelin # -test_description='git-fast-export' +test_description='git fast-export' . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index 4b91f8d4c4..c1850d2923 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -488,4 +488,17 @@ test_expect_success 'cvs co -c (shows module database)' ' ! grep -v "^master[ ]\+master$" < out ' +#------------ +# CVS ANNOTATE +#------------ + +cd "$WORKDIR" +test_expect_success 'cvs annotate' ' + cd cvswork && + GIT_CONFIG="$git_config" cvs annotate merge >../out && + sed -e "s/ .*//" ../out >../actual && + for i in 3 1 1 1 1 1 1 1 2 4; do echo 1.$i; done >../expect && + test_cmp ../expect ../actual +' + test_done diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh index 0d7786a8c7..d2379e7f62 100755 --- a/t/t9600-cvsimport.sh +++ b/t/t9600-cvsimport.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='git-cvsimport basic tests' +test_description='git cvsimport basic tests' . ./test-lib.sh CVSROOT=$(pwd)/cvsroot diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh index 0f04ba094b..b81d5dfc34 100755 --- a/t/t9700-perl-git.sh +++ b/t/t9700-perl-git.sh @@ -27,14 +27,14 @@ test_expect_success \ echo "changed file 1" > file1 && git commit -a -m "second commit" && - git-config --add color.test.slot1 green && - git-config --add test.string value && - git-config --add test.dupstring value1 && - git-config --add test.dupstring value2 && - git-config --add test.booltrue true && - git-config --add test.boolfalse no && - git-config --add test.boolother other && - git-config --add test.int 2k + git config --add color.test.slot1 green && + git config --add test.string value && + git config --add test.dupstring value1 && + git config --add test.dupstring value2 && + git config --add test.booltrue true && + git config --add test.boolfalse no && + git config --add test.boolother other && + git config --add test.int 2k ' test_external_without_stderr \ diff --git a/t/t9700/test.pl b/t/t9700/test.pl index 851cea4a4b..697daf3ffd 100755 --- a/t/t9700/test.pl +++ b/t/t9700/test.pl @@ -9,7 +9,6 @@ use Test::More qw(no_plan); use Cwd; use File::Basename; -use File::Temp; BEGIN { use_ok('Git') } @@ -35,7 +34,7 @@ is($r->get_color("color.test.slot1", "red"), $ansi_green, "get_color"); # Failure cases for config: # Save and restore STDERR; we will probably extract this into a # "dies_ok" method and possibly move the STDERR handling to Git.pm. -open our $tmpstderr, ">&", STDERR or die "cannot save STDERR"; close STDERR; +open our $tmpstderr, ">&STDERR" or die "cannot save STDERR"; close STDERR; eval { $r->config("test.dupstring") }; ok($@, "config: duplicate entry in scalar context fails"); eval { $r->config_bool("test.boolother") }; @@ -66,21 +65,25 @@ is($r->ident_person("Name", "email", "123 +0000"), "Name <email>", # objects and hashes ok(our $file1hash = $r->command_oneline('rev-parse', "HEAD:file1"), "(get file hash)"); -our $tmpfile = File::Temp->new; -is($r->cat_blob($file1hash, $tmpfile), 15, "cat_blob: size"); +my $tmpfile = "file.tmp"; +open TEMPFILE, "+>$tmpfile" or die "Can't open $tmpfile: $!"; +is($r->cat_blob($file1hash, \*TEMPFILE), 15, "cat_blob: size"); our $blobcontents; -{ local $/; seek $tmpfile, 0, 0; $blobcontents = <$tmpfile>; } +{ local $/; seek TEMPFILE, 0, 0; $blobcontents = <TEMPFILE>; } is($blobcontents, "changed file 1\n", "cat_blob: data"); -seek $tmpfile, 0, 0; +close TEMPFILE or die "Failed writing to $tmpfile: $!"; is(Git::hash_object("blob", $tmpfile), $file1hash, "hash_object: roundtrip"); -$tmpfile = File::Temp->new(); -print $tmpfile my $test_text = "test blob, to be inserted\n"; +open TEMPFILE, ">$tmpfile" or die "Can't open $tmpfile: $!"; +print TEMPFILE my $test_text = "test blob, to be inserted\n"; +close TEMPFILE or die "Failed writing to $tmpfile: $!"; like(our $newhash = $r->hash_and_insert_object($tmpfile), qr/[0-9a-fA-F]{40}/, "hash_and_insert_object: returns hash"); -$tmpfile = File::Temp->new; -is($r->cat_blob($newhash, $tmpfile), length $test_text, "cat_blob: roundtrip size"); -{ local $/; seek $tmpfile, 0, 0; $blobcontents = <$tmpfile>; } +open TEMPFILE, "+>$tmpfile" or die "Can't open $tmpfile: $!"; +is($r->cat_blob($newhash, \*TEMPFILE), length $test_text, "cat_blob: roundtrip size"); +{ local $/; seek TEMPFILE, 0, 0; $blobcontents = <TEMPFILE>; } is($blobcontents, $test_text, "cat_blob: roundtrip data"); +close TEMPFILE; +unlink $tmpfile; # paths is($r->repo_path, "./.git", "repo_path"); diff --git a/templates/Makefile b/templates/Makefile index 0722a926f7..a12c6e214e 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -31,9 +31,11 @@ boilerplates.made : $(bpsrc) dir=`expr "$$dst" : '\(.*\)/'` && \ mkdir -p blt/$$dir && \ case "$$boilerplate" in \ - *--) ;; \ - *) cp -p $$boilerplate blt/$$dst ;; \ - esac || exit; \ + *--) continue;; \ + esac && \ + cp $$boilerplate blt/$$dst && \ + if test -x "blt/$$dst"; then rx=rx; else rx=r; fi && \ + chmod a+$$rx "blt/$$dst" || exit; \ done && \ date >$@ diff --git a/transport.c b/transport.c index 71433d9997..f7db5d9110 100644 --- a/transport.c +++ b/transport.c @@ -619,7 +619,7 @@ static struct ref *get_refs_via_connect(struct transport *transport) struct ref *refs; connect_setup(transport); - get_remote_heads(data->fd[0], &refs, 0, NULL, 0); + get_remote_heads(data->fd[0], &refs, 0, NULL, 0, NULL); return refs; } @@ -652,7 +652,7 @@ static int fetch_refs_via_pack(struct transport *transport, if (!data->conn) { connect_setup(transport); - get_remote_heads(data->fd[0], &refs_tmp, 0, NULL, 0); + get_remote_heads(data->fd[0], &refs_tmp, 0, NULL, 0, NULL); } refs = fetch_pack(&args, data->fd, data->conn, diff --git a/tree-diff.c b/tree-diff.c index bbb126fc46..9f67af6c1f 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -303,7 +303,7 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, stru update_tree_entry(t2); continue; } - die("git-diff-tree: internal error"); + die("git diff-tree: internal error"); } return 0; } diff --git a/unpack-trees.c b/unpack-trees.c index ef21c62195..e59d144d28 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -941,8 +941,17 @@ int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o) return -1; } } - else if (newtree) + else if (newtree) { + if (oldtree && !o->initial_checkout) { + /* + * deletion of the path was staged; + */ + if (same(oldtree, newtree)) + return 1; + return reject_merge(oldtree, o); + } return merged_entry(newtree, current, o); + } return deleted_entry(oldtree, current, o); } diff --git a/unpack-trees.h b/unpack-trees.h index 94e567265a..0d26f3d73e 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -26,6 +26,7 @@ struct unpack_trees_options { verbose_update:1, aggressive:1, skip_unmerged:1, + initial_checkout:1, gently:1; const char *prefix; int pos; diff --git a/upload-pack.c b/upload-pack.c index c911e70c9a..e5adbc011e 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -157,7 +157,7 @@ static void create_pack_file(void) /* .data is just a boolean: any non-NULL value will do */ rev_list.data = create_full_pack ? &rev_list : NULL; if (start_async(&rev_list)) - die("git-upload-pack: unable to fork git-rev-list"); + die("git upload-pack: unable to fork git-rev-list"); argv[arg++] = "pack-objects"; argv[arg++] = "--stdout"; @@ -177,7 +177,7 @@ static void create_pack_file(void) pack_objects.argv = argv; if (start_command(&pack_objects)) - die("git-upload-pack: unable to fork git-pack-objects"); + die("git upload-pack: unable to fork git-pack-objects"); /* We read from pack_objects.err to capture stderr output for * progress bar, and pack_objects.out to capture the pack data. @@ -271,7 +271,7 @@ static void create_pack_file(void) } if (finish_command(&pack_objects)) { - error("git-upload-pack: git-pack-objects died with error."); + error("git upload-pack: git-pack-objects died with error."); goto fail; } if (finish_async(&rev_list)) @@ -291,7 +291,7 @@ static void create_pack_file(void) fail: send_client_data(3, abort_msg, sizeof(abort_msg)); - die("git-upload-pack: %s", abort_msg); + die("git upload-pack: %s", abort_msg); } static int got_sha1(char *hex, unsigned char *sha1) @@ -300,7 +300,7 @@ static int got_sha1(char *hex, unsigned char *sha1) int we_knew_they_have = 0; if (get_sha1_hex(hex, sha1)) - die("git-upload-pack: expected SHA1 object, got '%s'", hex); + die("git upload-pack: expected SHA1 object, got '%s'", hex); if (!has_sha1_file(sha1)) return -1; @@ -440,7 +440,7 @@ static int get_common_commits(void) packet_write(1, "NAK\n"); return -1; } - die("git-upload-pack: expected SHA1 list, got '%s'", line); + die("git upload-pack: expected SHA1 list, got '%s'", line); } } @@ -485,7 +485,7 @@ static void receive_needs(void) } if (prefixcmp(line, "want ") || get_sha1_hex(line+5, sha1_buf)) - die("git-upload-pack: protocol error, " + die("git upload-pack: protocol error, " "expected to get sha, not '%s'", line); if (strstr(line+45, "multi_ack")) multi_ack = 1; @@ -512,7 +512,7 @@ static void receive_needs(void) */ o = lookup_object(sha1_buf); if (!o || !(o->flags & OUR_REF)) - die("git-upload-pack: not our ref %s", line+5); + die("git upload-pack: not our ref %s", line+5); if (!(o->flags & WANTED)) { o->flags |= WANTED; add_object_array(o, NULL, &want_obj); @@ -577,7 +577,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo struct object *o = parse_object(sha1); if (!o) - die("git-upload-pack: cannot find object %s:", sha1_to_hex(sha1)); + die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1)); if (capabilities) packet_write(1, "%s %s%c%s\n", sha1_to_hex(sha1), refname, diff --git a/wt-status.c b/wt-status.c index 889e50f89f..7cf890f243 100644 --- a/wt-status.c +++ b/wt-status.c @@ -22,12 +22,6 @@ static char wt_status_colors[][COLOR_MAXLEN] = { "\033[31m", /* WT_STATUS_NOBRANCH: red */ }; -static const char use_add_msg[] = -"use \"git add <file>...\" to update what will be committed"; -static const char use_add_rm_msg[] = -"use \"git add/rm <file>...\" to update what will be committed"; -static const char use_add_to_include_msg[] = -"use \"git add <file>...\" to include in what will be committed"; enum untracked_status_type show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES; static int parse_status_slot(const char *var, int offset) @@ -76,12 +70,24 @@ static void wt_status_print_cached_header(struct wt_status *s) color_fprintf_ln(s->fp, c, "#"); } -static void wt_status_print_header(struct wt_status *s, - const char *main, const char *sub) +static void wt_status_print_dirty_header(struct wt_status *s, + int has_deleted) { const char *c = color(WT_STATUS_HEADER); - color_fprintf_ln(s->fp, c, "# %s:", main); - color_fprintf_ln(s->fp, c, "# (%s)", sub); + color_fprintf_ln(s->fp, c, "# Changed but not updated:"); + if (!has_deleted) + color_fprintf_ln(s->fp, c, "# (use \"git add <file>...\" to update what will be committed)"); + else + color_fprintf_ln(s->fp, c, "# (use \"git add/rm <file>...\" to update what will be committed)"); + color_fprintf_ln(s->fp, c, "# (use \"git checkout -- <file>...\" to discard changes in working directory)"); + color_fprintf_ln(s->fp, c, "#"); +} + +static void wt_status_print_untracked_header(struct wt_status *s) +{ + const char *c = color(WT_STATUS_HEADER); + color_fprintf_ln(s->fp, c, "# Untracked files:"); + color_fprintf_ln(s->fp, c, "# (use \"git add <file>...\" to include in what will be committed)"); color_fprintf_ln(s->fp, c, "#"); } @@ -166,14 +172,14 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q, struct wt_status *s = data; int i; if (q->nr) { - const char *msg = use_add_msg; + int has_deleted = 0; s->workdir_dirty = 1; for (i = 0; i < q->nr; i++) if (q->queue[i]->status == DIFF_STATUS_DELETED) { - msg = use_add_rm_msg; + has_deleted = 1; break; } - wt_status_print_header(s, "Changed but not updated", msg); + wt_status_print_dirty_header(s, has_deleted); } for (i = 0; i < q->nr; i++) wt_status_print_filepair(s, WT_STATUS_CHANGED, q->queue[i]); @@ -291,8 +297,7 @@ static void wt_status_print_untracked(struct wt_status *s) } if (!shown_header) { s->workdir_untracked = 1; - wt_status_print_header(s, "Untracked files", - use_add_to_include_msg); + wt_status_print_untracked_header(s); shown_header = 1; } color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t"); |