aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/Makefile4
-rw-r--r--Documentation/RelNotes-1.6.0.2.txt41
-rw-r--r--Documentation/RelNotes-1.6.0.3.txt45
-rw-r--r--Documentation/RelNotes-1.6.1.txt29
-rw-r--r--Documentation/config.txt25
-rw-r--r--Documentation/git-annotate.txt5
-rw-r--r--Documentation/git-for-each-ref.txt1
-rw-r--r--Documentation/git-read-tree.txt11
-rw-r--r--Documentation/git-rebase.txt8
-rw-r--r--Documentation/git-repack.txt2
-rw-r--r--Documentation/git-web--browse.txt3
-rw-r--r--Documentation/git.txt5
-rw-r--r--Documentation/gitattributes.txt26
-rw-r--r--Documentation/gitdiffcore.txt55
-rw-r--r--Documentation/merge-config.txt2
-rw-r--r--Documentation/pretty-formats.txt1
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--INSTALL21
-rw-r--r--Makefile42
-rw-r--r--builtin-archive.c2
-rw-r--r--builtin-blame.c9
-rw-r--r--builtin-checkout-index.c14
-rw-r--r--builtin-checkout.c45
-rw-r--r--builtin-clone.c2
-rw-r--r--builtin-commit-tree.c2
-rw-r--r--builtin-count-objects.c2
-rw-r--r--builtin-diff-files.c7
-rw-r--r--builtin-diff-tree.c5
-rw-r--r--builtin-diff.c10
-rw-r--r--builtin-fetch-pack.c2
-rw-r--r--builtin-fetch.c6
-rw-r--r--builtin-for-each-ref.c139
-rw-r--r--builtin-http-fetch.c6
-rw-r--r--builtin-init-db.c2
-rw-r--r--builtin-log.c31
-rw-r--r--builtin-merge.c2
-rw-r--r--builtin-pack-objects.c14
-rw-r--r--builtin-prune.c22
-rw-r--r--builtin-read-tree.c3
-rw-r--r--builtin-remote.c18
-rw-r--r--builtin-rev-list.c2
-rw-r--r--builtin-rm.c2
-rw-r--r--builtin-send-pack.c2
-rw-r--r--builtin-tar-tree.c16
-rw-r--r--builtin-unpack-objects.c2
-rw-r--r--builtin-update-index.c8
-rw-r--r--builtin.h2
-rw-r--r--combine-diff.c24
-rw-r--r--compat/fnmatch/fnmatch.c (renamed from compat/fnmatch.c)0
-rw-r--r--compat/fnmatch/fnmatch.h (renamed from compat/fnmatch.h)0
-rw-r--r--compat/regex/regex.c (renamed from compat/regex.c)0
-rw-r--r--compat/regex/regex.h (renamed from compat/regex.h)0
-rw-r--r--config.mak.in1
-rw-r--r--configure.ac32
-rwxr-xr-xcontrib/completion/git-completion.bash28
-rw-r--r--contrib/hooks/setgitperms.perl4
-rw-r--r--csum-file.c27
-rw-r--r--daemon.c3
-rw-r--r--diff-lib.c3
-rw-r--r--diff-no-index.c1
-rw-r--r--diff.c68
-rw-r--r--diff.h2
-rw-r--r--diffcore.h1
-rw-r--r--fast-import.c4
-rwxr-xr-xgit-bisect.sh173
-rw-r--r--git-gui/.gitattributes3
-rwxr-xr-xgit-gui/git-gui.sh611
-rw-r--r--git-gui/lib/blame.tcl217
-rw-r--r--git-gui/lib/browser.tcl2
-rw-r--r--git-gui/lib/commit.tcl11
-rw-r--r--git-gui/lib/diff.tcl185
-rw-r--r--git-gui/lib/encoding.tcl250
-rw-r--r--git-gui/lib/index.tcl12
-rw-r--r--git-gui/lib/mergetool.tcl400
-rw-r--r--git-gui/lib/option.tcl39
-rw-r--r--git-gui/po/de.po193
-rw-r--r--git-gui/po/fr.po784
-rw-r--r--git-gui/po/po2msg.sh4
-rwxr-xr-xgit-rebase--interactive.sh14
-rwxr-xr-xgit-repack.sh2
-rwxr-xr-xgit-stash.sh20
-rwxr-xr-xgit-submodule.sh8
-rwxr-xr-xgit-svn.perl157
-rwxr-xr-xgit-web--browse.sh8
-rw-r--r--git.c8
-rw-r--r--git.spec.in4
-rw-r--r--gitk-git/gitk44
-rwxr-xr-xgitweb/gitweb.perl2
-rw-r--r--graph.c57
-rw-r--r--graph.h40
-rw-r--r--help.c89
-rw-r--r--help.h2
-rw-r--r--http-push.c2
-rw-r--r--http.c13
-rw-r--r--index-pack.c2
-rw-r--r--levenshtein.c47
-rw-r--r--levenshtein.h8
-rw-r--r--log-tree.c36
-rw-r--r--log-tree.h1
-rw-r--r--object.h13
-rw-r--r--pack-write.c2
-rw-r--r--perl/Git.pm42
-rw-r--r--pretty.c21
-rw-r--r--read-cache.c1
-rw-r--r--refs.c20
-rw-r--r--remote.c10
-rw-r--r--remote.h2
-rw-r--r--revision.c38
-rw-r--r--revision.h1
-rw-r--r--sha1_file.c4
-rw-r--r--t/lib-git-svn.sh26
-rw-r--r--t/t0024-crlf-archive.sh46
-rwxr-xr-xt/t1300-repo-config.sh10
-rwxr-xr-xt/t4018-diff-funcname.sh6
-rwxr-xr-xt/t4019-diff-wserror.sh12
-rwxr-xr-xt/t5300-pack-object.sh3
-rwxr-xr-xt/t5510-fetch.sh20
-rwxr-xr-xt/t6013-rev-list-reverse-parents.sh42
-rwxr-xr-xt/t6023-merge-file.sh4
-rwxr-xr-xt/t6030-bisect-porcelain.sh114
-rwxr-xr-xt/t6300-for-each-ref.sh44
-rwxr-xr-xt/t7201-co.sh32
-rwxr-xr-xt/t7501-commit.sh12
-rwxr-xr-xt/t7606-merge-custom.sh2
-rwxr-xr-xt/t9100-git-svn-basic.sh90
-rwxr-xr-xt/t9101-git-svn-props.sh72
-rwxr-xr-xt/t9102-git-svn-deep-rmdir.sh14
-rwxr-xr-xt/t9103-git-svn-tracked-directory-removed.sh2
-rwxr-xr-xt/t9104-git-svn-follow-parent.sh38
-rwxr-xr-xt/t9105-git-svn-commit-diff.sh12
-rwxr-xr-xt/t9106-git-svn-commit-diff-clobber.sh22
-rwxr-xr-xt/t9106-git-svn-dcommit-clobber-series.sh2
-rwxr-xr-xt/t9107-git-svn-migrate.sh34
-rwxr-xr-xt/t9108-git-svn-glob.sh8
-rwxr-xr-xt/t9108-git-svn-multi-glob.sh10
-rwxr-xr-xt/t9110-git-svn-use-svm-props.sh32
-rwxr-xr-xt/t9111-git-svn-use-svnsync-props.sh28
-rwxr-xr-xt/t9112-git-svn-md5less-file.sh4
-rwxr-xr-xt/t9113-git-svn-dcommit-new-file.sh16
-rwxr-xr-xt/t9114-git-svn-dcommit-merge.sh2
-rwxr-xr-xt/t9115-git-svn-dcommit-funky-renames.sh4
-rwxr-xr-xt/t9116-git-svn-log.sh6
-rwxr-xr-xt/t9117-git-svn-init-clone.sh2
-rwxr-xr-xt/t9118-git-svn-funky-branch-names.sh18
-rwxr-xr-xt/t9119-git-svn-info.sh213
-rwxr-xr-xt/t9120-git-svn-clone-with-percent-escapes.sh4
-rwxr-xr-xt/t9121-git-svn-fetch-renamed-dir.sh2
-rwxr-xr-xt/t9122-git-svn-author.sh2
-rwxr-xr-xt/t9123-git-svn-rebuild-with-rewriteroot.sh6
-rwxr-xr-xt/t9124-git-svn-dcommit-auto-props.sh33
-rwxr-xr-xt/t9125-git-svn-multi-glob-branch-names.sh2
-rwxr-xr-xt/t9126-git-svn-follow-deleted-readded-directory.sh22
-rw-r--r--t/t9126/follow-deleted-readded.dump201
-rwxr-xr-xt/t9127-git-svn-partial-rebuild.sh59
-rwxr-xr-xt/t9200-git-cvsexportcommit.sh14
-rwxr-xr-xt/t9300-fast-import.sh80
-rwxr-xr-xt/t9301-fast-export.sh2
-rwxr-xr-xt/t9400-git-cvsserver-server.sh13
-rwxr-xr-xt/t9600-cvsimport.sh2
-rwxr-xr-xt/t9700-perl-git.sh16
-rwxr-xr-xt/t9700/test.pl25
-rw-r--r--templates/Makefile8
-rw-r--r--unpack-trees.c11
-rw-r--r--unpack-trees.h1
164 files changed, 4535 insertions, 1475 deletions
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 62269e39c..ded0e40b9 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
index 686e60713..7a9646fc4 100644
--- a/Documentation/RelNotes-1.6.0.2.txt
+++ b/Documentation/RelNotes-1.6.0.2.txt
@@ -17,27 +17,64 @@ Fixes since v1.6.0.1
* 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 log --grep=pattern -i" did not ignore case.
+* "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.
@@ -45,6 +82,6 @@ Also contains many documentation updates.
--
exec >/var/tmp/1
-O=v1.6.0.1-49-g6a42cfe
+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 000000000..46e13a450
--- /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 7f41e30e2..421e569ea 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)
@@ -31,8 +32,19 @@ on.
* 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".
@@ -53,6 +65,12 @@ on.
* "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.
@@ -67,6 +85,9 @@ on.
* "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.
@@ -108,8 +129,12 @@ release, unless otherwise noted.
* "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.1-215-g9b8ae93
+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 ed3285f89..bea867df6 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'.
@@ -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/git-annotate.txt b/Documentation/git-annotate.txt
index 8b6b56a54..0aba022ba 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-for-each-ref.txt b/Documentation/git-for-each-ref.txt
index ebd7c5fbb..5061d3e4e 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -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-read-tree.txt b/Documentation/git-read-tree.txt
index 6f4b9b017..309deac23 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 59c1b021a..32f0f122e 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 38ac60947..bbe1485a9 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-web--browse.txt b/Documentation/git-web--browse.txt
index 36afad8d4..278cf7352 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 e178fb581..df420aeb3 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 5fb500741..e848c9439 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -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 2bdbc3d4f..e8041bc08 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/merge-config.txt b/Documentation/merge-config.txt
index 00277e061..c735788b0 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 388d4925e..f18d33e00 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/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 156dc1373..6c7465c75 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='
'
diff --git a/INSTALL b/INSTALL
index 2bae53fcb..a4fd8624b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -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
diff --git a/Makefile b/Makefile
index dfed7bae9..3c0664a07 100644
--- a/Makefile
+++ b/Makefile
@@ -296,6 +296,7 @@ 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,6 +359,7 @@ 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
@@ -434,6 +436,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
@@ -633,6 +636,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 +688,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 +704,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 +716,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 +769,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 +801,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 +844,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 +1271,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 +1380,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 +1413,9 @@ install-info:
quick-install-doc:
$(MAKE) -C Documentation quick-install
+quick-install-html:
+ $(MAKE) -C Documentation quick-install-html
+
### Maintainer's dist rules
diff --git a/builtin-archive.c b/builtin-archive.c
index 5ceec433f..432ce2acc 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -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 adc3dc727..6b7b9f446 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('^');
}
@@ -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-checkout-index.c b/builtin-checkout-index.c
index 90f8523eb..55b7aafe0 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)
diff --git a/builtin-checkout.c b/builtin-checkout.c
index efdb1e02b..9a0c173c1 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;
@@ -299,7 +328,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;
@@ -551,6 +580,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 c8435295c..5b40e07ba 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",
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index 8a5ba4c66..f2684bb75 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)
{
diff --git a/builtin-count-objects.c b/builtin-count-objects.c
index 6e80fe7c0..ab35b65b0 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 9bf10bb37..2b578c714 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-tree.c b/builtin-diff-tree.c
index 1138c2da7..8ecefd4f0 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 037c3039a..35da366f4 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);
@@ -223,7 +225,13 @@ 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;
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index 459c6f0da..4dfef29bc 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -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 7eec4a0e4..ee93d3a93 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 21e92bbcb..e59bd8075 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-http-fetch.c b/builtin-http-fetch.c
index 3a062487a..f3e63d720 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 baf0d09ac..8140c1299 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 1d3c5cbf5..fc5e4da82 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-merge.c b/builtin-merge.c
index 9ad979106..1094c5fd5 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -476,6 +476,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++;
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index ba2cf00f5..1158e42cb 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\
@@ -465,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);
@@ -1725,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;
@@ -1872,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 c767a0ac8..1663f8bdb 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 dddc3044b..0706c9581 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;
@@ -206,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/builtin-remote.c b/builtin-remote.c
index 01945a865..4cb763f98 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 c023003b2..facaff288 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 6bd82111d..fdac34f24 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.
diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index 7588d2288..2af9f2934 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -43,7 +43,7 @@ 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
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index cb7007e25..0713bca77 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]);
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index a89186666..40b20f26e 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 ce8322475..417f9724a 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;
@@ -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);
diff --git a/builtin.h b/builtin.h
index f3502d305..e67cb2090 100644
--- a/builtin.h
+++ b/builtin.h
@@ -11,7 +11,7 @@ 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,
diff --git a/combine-diff.c b/combine-diff.c
index 0cf2a830b..de83c6972 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 1f4ead5f9..1f4ead5f9 100644
--- a/compat/fnmatch.c
+++ b/compat/fnmatch/fnmatch.c
diff --git a/compat/fnmatch.h b/compat/fnmatch/fnmatch.h
index cc3ec3794..cc3ec3794 100644
--- a/compat/fnmatch.h
+++ b/compat/fnmatch/fnmatch.h
diff --git a/compat/regex.c b/compat/regex/regex.c
index 87b33e466..87b33e466 100644
--- a/compat/regex.c
+++ b/compat/regex/regex.c
diff --git a/compat/regex.h b/compat/regex/regex.h
index 6eb64f140..6eb64f140 100644
--- a/compat/regex.h
+++ b/compat/regex/regex.h
diff --git a/config.mak.in b/config.mak.in
index f67d673d0..17e9861c0 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 7c2856efc..27bab00a4 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])
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index d3fb6ae50..93f088189 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
@@ -750,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 dab7c8e3a..a577ad095 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 28389541a..bb70c75ee 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,7 +37,7 @@ 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);
@@ -47,7 +45,7 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
hashcpy(result, f->buffer);
if (flags & (CSUM_CLOSE | CSUM_FSYNC)) {
/* write checksum and close fd */
- 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;
diff --git a/daemon.c b/daemon.c
index c315932ce..0e026f65e 100644
--- a/daemon.c
+++ b/daemon.c
@@ -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");
diff --git a/diff-lib.c b/diff-lib.c
index e7eaff9a6..ae96c64ca 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 7d68b7f1b..b60d3455d 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);
diff --git a/diff.c b/diff.c
index 2de86eb76..a2f4850d4 100644
--- a/diff.c
+++ b/diff.c
@@ -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);
}
@@ -1406,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\\}{.*\\)$" },
@@ -1443,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,
@@ -1456,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;
- a_one = quote_two(o->a_prefix, name_a + (*name_a == '/'));
- b_two = quote_two(o->b_prefix, name_b + (*name_b == '/'));
+ 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(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);
@@ -2315,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)
@@ -2399,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;
}
@@ -3397,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);
diff --git a/diff.h b/diff.h
index c34688881..a49d865bd 100644
--- a/diff.h
+++ b/diff.h
@@ -161,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 cc96c2073..8ae35785f 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);
diff --git a/fast-import.c b/fast-import.c
index ccdf2e57b..ab6689a64 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -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));
diff --git a/git-bisect.sh b/git-bisect.sh
index 97ac60087..79de7017e 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-gui/.gitattributes b/git-gui/.gitattributes
new file mode 100644
index 000000000..f96112d47
--- /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 ad65aaad5..4085e8fea 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 b6e42cbc8..eb61374d2 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 ab470d126..0410cc68d 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 40a710355..334514996 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 52b79e4a1..abe502d97 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 7f06b0d47..32668fc9c 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 3c1fce747..b045219a1 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 000000000..6ab5701d9
--- /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 ffb3f00ff..c80c93987 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 fa43947ad..793cca1e7 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 89b6d51ea..26b866f55 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 b7c4bf3fd..1e9f99252 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 929d681c4..edb6ec6ed 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 683960b04..d39eb6cea 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 e15c12abc..6bd2572f7 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 1c39b593a..92be0feb5 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 7a1d26db8..80a572837 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 384148a59..78d236b77 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)
diff --git a/git.c b/git.c
index fdb0f7101..00f5dd1d4 100644
--- a/git.c
+++ b/git.c
@@ -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"
@@ -364,7 +366,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 +501,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 c6492e5be..6733b6f55 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 087c4ac73..2eaa2ae7d 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.perl b/gitweb/gitweb.perl
index 29e21564c..da474d082 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -2123,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
diff --git a/graph.c b/graph.c
index e2633f837..5f821706c 100644
--- a/graph.c
+++ b/graph.c
@@ -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;
diff --git a/graph.h b/graph.h
index eab4e3dab..bc30d687c 100644
--- a/graph.h
+++ b/graph.h
@@ -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
diff --git a/help.c b/help.c
index b278257aa..300cd38a9 100644
--- a/help.c
+++ b/help.c
@@ -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_;
@@ -250,9 +261,85 @@ int is_in_cmdlist(struct cmdnames *c, const char *s)
return 0;
}
-void help_unknown_cmd(const char *cmd)
+static int autocorrect;
+
+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);
+
+ 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);
+}
+
+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));
+
+ git_config(git_unknown_cmd_config, NULL);
+
+ load_command_list("git-", &main_cmds, &other_cmds);
+
+ ALLOC_GROW(main_cmds.names, main_cmds.cnt + other_cmds.cnt,
+ main_cmds.alloc);
+ memcpy(main_cmds.names + main_cmds.cnt, other_cmds.names,
+ other_cmds.cnt * sizeof(other_cmds.names[0]));
+ main_cmds.cnt += other_cmds.cnt;
+ free(other_cmds.names);
+
+ /* 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);
}
diff --git a/help.h b/help.h
index 2733433bf..56bc15406 100644
--- a/help.h
+++ b/help.h
@@ -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 680528885..c9dd9a1f6 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;
diff --git a/http.c b/http.c
index 1108ab4a3..ed59b7970 100644
--- a/http.c
+++ b/http.c
@@ -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 a6e91fe3b..530d82037 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
diff --git a/levenshtein.c b/levenshtein.c
new file mode 100644
index 000000000..db52f2c20
--- /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 000000000..0173abeef
--- /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 30cd5bb22..2c1f3e673 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 59ba4c48b..3c8127bb7 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/object.h b/object.h
index 036bd66fe..d962ff11d 100644
--- a/object.h
+++ b/object.h
@@ -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 939ed5636..3621f1dd3 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 {
diff --git a/perl/Git.pm b/perl/Git.pm
index 102e6a4ce..6aab712e6 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
diff --git a/pretty.c b/pretty.c
index a29c29000..8beafa08d 100644
--- a/pretty.c
+++ b/pretty.c
@@ -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 5150c1e14..5b1b3ad03 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);
diff --git a/refs.c b/refs.c
index 39a3b2380..b6807505e 100644
--- a/refs.c
+++ b/refs.c
@@ -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) {
diff --git a/remote.c b/remote.c
index 3ef09a44a..c45d96e98 100644
--- a/remote.c
+++ b/remote.c
@@ -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;
diff --git a/remote.h b/remote.h
index 2601f6e76..c6163ff5b 100644
--- a/remote.h
+++ b/remote.h
@@ -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);
diff --git a/revision.c b/revision.c
index 499f0e022..2f646deab 100644
--- a/revision.c
+++ b/revision.c
@@ -1793,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
*/
@@ -1885,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 fc23522b3..2fdb2dd0f 100644
--- a/revision.h
+++ b/revision.h
@@ -54,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;
diff --git a/sha1_file.c b/sha1_file.c
index 9ee1ed16a..aec81bbae 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2136,7 +2136,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/t/lib-git-svn.sh b/t/lib-git-svn.sh
index a841df2a9..67c431d4e 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 000000000..e5330395f
--- /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/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 64567fb94..11b82f43d 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/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh
index 833d6cbcf..18bcd9713 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 7eae1f450..84a1fe311 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/t5300-pack-object.sh b/t/t5300-pack-object.sh
index 3a0ef8759..b335c6b42 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -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/t5510-fetch.sh b/t/t5510-fetch.sh
index de26c2032..9aae4965d 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -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/t6013-rev-list-reverse-parents.sh b/t/t6013-rev-list-reverse-parents.sh
new file mode 100755
index 000000000..59fc2f06e
--- /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 42620e073..5e18d68c9 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/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 36c9a6965..85fa39cf0 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -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/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 26995b3cd..8bfae44a8 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -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/t7201-co.sh b/t/t7201-co.sh
index 543b1c289..62d73f934 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -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/t7501-commit.sh b/t/t7501-commit.sh
index 469bff887..63bfc6d8b 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -141,7 +141,7 @@ EOF
test_expect_success \
'validate git rev-list output.' \
- 'diff current expected'
+ '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/t7606-merge-custom.sh b/t/t7606-merge-custom.sh
index de9b6ed5b..52a451dd5 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/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index 843a5013b..9b238c329 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 f420796c3..1e31d6ea7 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 0e7ce34b9..e22321801 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 9ffd8458e..963dd95e4 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 4d964e2db..0a091e048 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 63230367b..ba99abb6d 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 83896e968..6eb0fd85c 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 bc37db9d6..fd185011b 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 d9b553ad5..acad16a6f 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 8b792a137..d8582b1aa 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 358372165..8f79c3f25 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 83bd1cf17..a06e4c5b8 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 c5dfd61e4..bd081c2ec 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 d470a920e..a61d6716d 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 ae78e334a..e9b6128b3 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 61d778161..17b2855c4 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 b0ba1f020..9be7aefae 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 4b2cc878f..fd6d1d204 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 7a689bb1c..dde46cd92 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 3281cbd34..7a7c12868 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 5fd36a148..27dd7c273 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 5979e133b..ef2c0523c 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 92e69a2a7..000cad37c 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 1190576a6..1b1cf4728 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 c18878fad..cf0415274 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 8223c5909..263dbf5fc 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 6b62b52f5..475c751c1 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 000000000..edec640e9
--- /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 000000000..19da5d1dd
--- /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 000000000..87696a92d
--- /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 988c3ac75..245a7c366 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 bd5d5af66..328444a30 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 3cb9f8070..6ddd7c19f 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 4b91f8d4c..c1850d292 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 0d7786a8c..d2379e7f6 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 0f04ba094..b81d5dfc3 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 851cea4a4..697daf3ff 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 0722a926f..a12c6e214 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/unpack-trees.c b/unpack-trees.c
index ef21c6219..e59d144d2 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 94e567265..0d26f3d73 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;