summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore354
-rw-r--r--Documentation/Makefile8
-rw-r--r--Documentation/RelNotes-1.6.6.txt108
-rw-r--r--Documentation/config.txt15
-rw-r--r--Documentation/diff-options.txt7
-rw-r--r--Documentation/fetch-options.txt48
-rw-r--r--Documentation/git-bisect.txt23
-rw-r--r--Documentation/git-check-ref-format.txt25
-rw-r--r--Documentation/git-describe.txt7
-rw-r--r--Documentation/git-fetch.txt29
-rw-r--r--Documentation/git-fsck.txt5
-rw-r--r--Documentation/git-ls-files.txt6
-rw-r--r--Documentation/git-merge.txt33
-rw-r--r--Documentation/git-pull.txt56
-rw-r--r--Documentation/git-rebase.txt9
-rw-r--r--Documentation/git-replace.txt21
-rw-r--r--Documentation/git-stash.txt3
-rw-r--r--Documentation/git-update-index.txt6
-rw-r--r--Documentation/git.txt6
-rw-r--r--Documentation/manpage-quote-apos.xsl16
-rw-r--r--Documentation/merge-options.txt91
-rw-r--r--Documentation/pretty-formats.txt9
-rw-r--r--Documentation/pt_BR/gittutorial.txt22
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--Makefile6
l---------RelNotes2
-rw-r--r--archive.c4
-rw-r--r--builtin-apply.c61
-rw-r--r--builtin-blame.c6
-rw-r--r--builtin-branch.c3
-rw-r--r--builtin-check-ref-format.c33
-rw-r--r--builtin-checkout.c68
-rw-r--r--builtin-commit.c51
-rw-r--r--builtin-describe.c54
-rw-r--r--builtin-fetch.c107
-rw-r--r--builtin-fsck.c2
-rw-r--r--builtin-gc.c11
-rw-r--r--builtin-log.c12
-rw-r--r--builtin-ls-files.c8
-rw-r--r--builtin-merge.c18
-rw-r--r--builtin-pack-objects.c7
-rw-r--r--builtin-push.c3
-rw-r--r--builtin-receive-pack.c20
-rw-r--r--builtin-rev-list.c7
-rw-r--r--builtin-shortlog.c9
-rw-r--r--builtin-show-branch.c4
-rw-r--r--cache.h5
-rw-r--r--command-list.txt1
-rw-r--r--commit.c4
-rw-r--r--commit.h22
-rw-r--r--compat/bswap.h10
-rw-r--r--contrib/buildsystems/Generators/Vcproj.pm4
-rwxr-xr-xcontrib/completion/git-completion.bash27
-rw-r--r--contrib/emacs/git-blame.el156
-rwxr-xr-xcontrib/fast-import/import-tars.perl5
-rw-r--r--diff.c427
-rw-r--r--diff.h3
-rwxr-xr-xgit-bisect.sh8
-rwxr-xr-xgit-cvsimport.perl17
-rwxr-xr-xgit-gui/git-gui.sh43
-rw-r--r--git-gui/lib/diff.tcl32
-rw-r--r--git-gui/lib/remote_branch_delete.tcl16
-rw-r--r--git-gui/po/el.po2005
-rw-r--r--git-gui/po/git-gui.pot5
-rw-r--r--git-gui/po/glossary/el.po171
-rw-r--r--git-gui/po/ru.po28
-rwxr-xr-xgit-instaweb.sh16
-rwxr-xr-xgit-pull.sh7
-rwxr-xr-xgit-rebase--interactive.sh9
-rwxr-xr-xgit-stash.sh8
-rwxr-xr-xgit-svn.perl149
-rw-r--r--git.c4
-rw-r--r--gitweb/gitweb.css10
-rwxr-xr-xgitweb/gitweb.perl121
-rw-r--r--imap-send.c4
-rw-r--r--log-tree.c26
-rw-r--r--pretty.c46
-rw-r--r--reflog-walk.c83
-rw-r--r--reflog-walk.h8
-rw-r--r--setup.c38
-rw-r--r--submodule.c114
-rw-r--r--submodule.h8
-rw-r--r--t/lib-git-svn.sh5
-rw-r--r--t/lib-rebase.sh6
-rwxr-xr-xt/t1402-check-ref-format.sh61
-rwxr-xr-xt/t3003-ls-files-exclude.sh8
-rwxr-xr-xt/t3404-rebase-interactive.sh14
-rw-r--r--t/t4013/diff.log_--decorate=full_--all2
-rw-r--r--t/t4013/diff.log_--decorate_--all2
-rwxr-xr-xt/t4014-format-patch.sh21
-rwxr-xr-xt/t4015-diff-whitespace.sh11
-rwxr-xr-xt/t4019-diff-wserror.sh11
-rwxr-xr-xt/t4041-diff-submodule.sh260
-rwxr-xr-xt/t4124-apply-ws-rule.sh91
-rwxr-xr-xt/t6006-rev-list-format.sh18
-rwxr-xr-xt/t6050-replace.sh7
-rwxr-xr-xt/t6120-describe.sh14
-rwxr-xr-xt/t7501-commit.sh41
-rwxr-xr-xt/t7502-commit.sh9
-rwxr-xr-xt/t7600-merge.sh41
-rwxr-xr-xt/t9150-svk-mergetickets.sh24
-rw-r--r--t/t9150/make-svk-dump57
-rw-r--r--t/t9150/svk-merge.dump616
-rwxr-xr-xt/t9151-svn-mergeinfo.sh22
-rw-r--r--t/t9151/.gitignore2
-rw-r--r--t/t9151/make-svnmerge-dump73
-rw-r--r--t/t9151/svn-mergeinfo.dump736
-rw-r--r--ws.c19
108 files changed, 6423 insertions, 793 deletions
diff --git a/.gitignore b/.gitignore
index f0d2e96b88..338c6d8881 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,185 +1,185 @@
-GIT-BUILD-OPTIONS
-GIT-CFLAGS
-GIT-GUI-VARS
-GIT-VERSION-FILE
-git
-git-add
-git-add--interactive
-git-am
-git-annotate
-git-apply
-git-archimport
-git-archive
-git-bisect
-git-bisect--helper
-git-blame
-git-branch
-git-bundle
-git-cat-file
-git-check-attr
-git-check-ref-format
-git-checkout
-git-checkout-index
-git-cherry
-git-cherry-pick
-git-clean
-git-clone
-git-commit
-git-commit-tree
-git-config
-git-count-objects
-git-cvsexportcommit
-git-cvsimport
-git-cvsserver
-git-daemon
-git-diff
-git-diff-files
-git-diff-index
-git-diff-tree
-git-difftool
-git-difftool--helper
-git-describe
-git-fast-export
-git-fast-import
-git-fetch
-git-fetch--tool
-git-fetch-pack
-git-filter-branch
-git-fmt-merge-msg
-git-for-each-ref
-git-format-patch
-git-fsck
-git-fsck-objects
-git-gc
-git-get-tar-commit-id
-git-grep
-git-hash-object
-git-help
-git-http-fetch
-git-http-push
-git-imap-send
-git-index-pack
-git-init
-git-init-db
-git-instaweb
-git-log
-git-lost-found
-git-ls-files
-git-ls-remote
-git-ls-tree
-git-mailinfo
-git-mailsplit
-git-merge
-git-merge-base
-git-merge-index
-git-merge-file
-git-merge-tree
-git-merge-octopus
-git-merge-one-file
-git-merge-ours
-git-merge-recursive
-git-merge-resolve
-git-merge-subtree
-git-mergetool
-git-mergetool--lib
-git-mktag
-git-mktree
-git-name-rev
-git-mv
-git-pack-redundant
-git-pack-objects
-git-pack-refs
-git-parse-remote
-git-patch-id
-git-peek-remote
-git-prune
-git-prune-packed
-git-pull
-git-push
-git-quiltimport
-git-read-tree
-git-rebase
-git-rebase--interactive
-git-receive-pack
-git-reflog
-git-relink
-git-remote
-git-remote-curl
-git-repack
-git-replace
-git-repo-config
-git-request-pull
-git-rerere
-git-reset
-git-rev-list
-git-rev-parse
-git-revert
-git-rm
-git-send-email
-git-send-pack
-git-sh-setup
-git-shell
-git-shortlog
-git-show
-git-show-branch
-git-show-index
-git-show-ref
-git-stage
-git-stash
-git-status
-git-stripspace
-git-submodule
-git-svn
-git-symbolic-ref
-git-tag
-git-tar-tree
-git-unpack-file
-git-unpack-objects
-git-update-index
-git-update-ref
-git-update-server-info
-git-upload-archive
-git-upload-pack
-git-var
-git-verify-pack
-git-verify-tag
-git-web--browse
-git-whatchanged
-git-write-tree
-git-core-*/?*
-gitk-wish
-gitweb/gitweb.cgi
-test-chmtime
-test-ctype
-test-date
-test-delta
-test-dump-cache-tree
-test-genrandom
-test-match-trees
-test-parse-options
-test-path-utils
-test-sha1
-test-sigchain
-common-cmds.h
+/GIT-BUILD-OPTIONS
+/GIT-CFLAGS
+/GIT-GUI-VARS
+/GIT-VERSION-FILE
+/git
+/git-add
+/git-add--interactive
+/git-am
+/git-annotate
+/git-apply
+/git-archimport
+/git-archive
+/git-bisect
+/git-bisect--helper
+/git-blame
+/git-branch
+/git-bundle
+/git-cat-file
+/git-check-attr
+/git-check-ref-format
+/git-checkout
+/git-checkout-index
+/git-cherry
+/git-cherry-pick
+/git-clean
+/git-clone
+/git-commit
+/git-commit-tree
+/git-config
+/git-count-objects
+/git-cvsexportcommit
+/git-cvsimport
+/git-cvsserver
+/git-daemon
+/git-diff
+/git-diff-files
+/git-diff-index
+/git-diff-tree
+/git-difftool
+/git-difftool--helper
+/git-describe
+/git-fast-export
+/git-fast-import
+/git-fetch
+/git-fetch--tool
+/git-fetch-pack
+/git-filter-branch
+/git-fmt-merge-msg
+/git-for-each-ref
+/git-format-patch
+/git-fsck
+/git-fsck-objects
+/git-gc
+/git-get-tar-commit-id
+/git-grep
+/git-hash-object
+/git-help
+/git-http-fetch
+/git-http-push
+/git-imap-send
+/git-index-pack
+/git-init
+/git-init-db
+/git-instaweb
+/git-log
+/git-lost-found
+/git-ls-files
+/git-ls-remote
+/git-ls-tree
+/git-mailinfo
+/git-mailsplit
+/git-merge
+/git-merge-base
+/git-merge-index
+/git-merge-file
+/git-merge-tree
+/git-merge-octopus
+/git-merge-one-file
+/git-merge-ours
+/git-merge-recursive
+/git-merge-resolve
+/git-merge-subtree
+/git-mergetool
+/git-mergetool--lib
+/git-mktag
+/git-mktree
+/git-name-rev
+/git-mv
+/git-pack-redundant
+/git-pack-objects
+/git-pack-refs
+/git-parse-remote
+/git-patch-id
+/git-peek-remote
+/git-prune
+/git-prune-packed
+/git-pull
+/git-push
+/git-quiltimport
+/git-read-tree
+/git-rebase
+/git-rebase--interactive
+/git-receive-pack
+/git-reflog
+/git-relink
+/git-remote
+/git-remote-curl
+/git-repack
+/git-replace
+/git-repo-config
+/git-request-pull
+/git-rerere
+/git-reset
+/git-rev-list
+/git-rev-parse
+/git-revert
+/git-rm
+/git-send-email
+/git-send-pack
+/git-sh-setup
+/git-shell
+/git-shortlog
+/git-show
+/git-show-branch
+/git-show-index
+/git-show-ref
+/git-stage
+/git-stash
+/git-status
+/git-stripspace
+/git-submodule
+/git-svn
+/git-symbolic-ref
+/git-tag
+/git-tar-tree
+/git-unpack-file
+/git-unpack-objects
+/git-update-index
+/git-update-ref
+/git-update-server-info
+/git-upload-archive
+/git-upload-pack
+/git-var
+/git-verify-pack
+/git-verify-tag
+/git-web--browse
+/git-whatchanged
+/git-write-tree
+/git-core-*/?*
+/gitk-git/gitk-wish
+/gitweb/gitweb.cgi
+/test-chmtime
+/test-ctype
+/test-date
+/test-delta
+/test-dump-cache-tree
+/test-genrandom
+/test-match-trees
+/test-parse-options
+/test-path-utils
+/test-sha1
+/test-sigchain
+/common-cmds.h
*.tar.gz
*.dsc
*.deb
-git.spec
+/git.spec
*.exe
*.[aos]
*.py[co]
*+
-config.mak
-autom4te.cache
-config.cache
-config.log
-config.status
-config.mak.autogen
-config.mak.append
-configure
-tags
-TAGS
-cscope*
+/config.mak
+/autom4te.cache
+/config.cache
+/config.log
+/config.status
+/config.mak.autogen
+/config.mak.append
+/configure
+/tags
+/TAGS
+/cscope*
*.obj
*.lib
*.sln
@@ -189,5 +189,5 @@ cscope*
*.user
*.idb
*.pdb
-Debug/
-Release/
+/Debug/
+/Release/
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 06b0c57b95..cd5b4396db 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -103,6 +103,14 @@ ifdef DOCBOOK_SUPPRESS_SP
XMLTO_EXTRA += -m manpage-suppress-sp.xsl
endif
+# If your target system uses GNU groff, it may try to render
+# apostrophes as a "pretty" apostrophe using unicode. This breaks
+# cut&paste, so you should set GNU_ROFF to force them to be ASCII
+# apostrophes. Unfortunately does not work with non-GNU roff.
+ifdef GNU_ROFF
+XMLTO_EXTRA += -m manpage-quote-apos.xsl
+endif
+
SHELL_PATH ?= $(SHELL)
# Shell quote;
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
diff --git a/Documentation/RelNotes-1.6.6.txt b/Documentation/RelNotes-1.6.6.txt
new file mode 100644
index 0000000000..abf34e6ace
--- /dev/null
+++ b/Documentation/RelNotes-1.6.6.txt
@@ -0,0 +1,108 @@
+GIT v1.6.6 Release Notes
+========================
+
+In this release, "git fsck" defaults to "git fsck --full" and checks
+packfiles, and because of this it will take much longer to complete
+than before. If you prefer a quicker check only on loose objects (the
+old default), you can say "git fsck --no-full". This has been
+supported by 1.5.4 and newer versions of git, so it is safe to write
+it in your script even if you use slightly older git on some of your
+machines.
+
+In git 1.7.0, which is planned to be the release after 1.6.6, "git
+push" into a branch that is currently checked out will be refused by
+default.
+
+You can choose what should happen upon such a push by setting the
+configuration variable receive.denyCurrentBranch in the receiving
+repository.
+
+Also, "git push $there :$killed" to delete the branch $killed in a remote
+repository $there, when $killed branch is the current branch pointed at by
+its HEAD, will be refused by default.
+
+You can choose what should happen upon such a push by setting the
+configuration variable receive.denyDeleteCurrent in the receiving
+repository.
+
+To ease the transition plan, the receiving repository of such a
+push running this release will issue a big warning when the
+configuration variable is missing. Please refer to:
+
+ http://git.or.cz/gitwiki/GitFaq#non-bare
+ http://thread.gmane.org/gmane.comp.version-control.git/107758/focus=108007
+
+for more details on the reason why this change is needed and the
+transition plan.
+
+Updates since v1.6.5
+--------------------
+
+(subsystems)
+
+(portability)
+
+(performance)
+
+(usability, bells and whistles)
+
+ * The object replace mechanism can be bypassed with --no-replace-objects
+ global option given to the "git" program.
+
+ * "git fsck" by default checks the packfiles (i.e. "--full" is the
+ default); you can turn it off with "git fsck --no-full".
+
+ * import-tars contributed fast-import frontend learned more types of
+ compressed tarballs.
+
+ * "git instaweb" knows how to talk with mod_cgid to apache2.
+
+ * "git log --decorate" shows the location of HEAD as well.
+
+ * "git rebase -i" learned "reword" that acts like "edit" but immediately
+ starts an editor to tweak the log message without returning control to
+ the shell, which is done by "edit" to give an opportunity to tweak the
+ contents.
+
+ * Author names shown in gitweb output are links to search commits by the
+ author.
+
+
+(developers)
+
+Fixes since v1.6.5
+------------------
+
+All of the fixes in v1.6.5.X maintenance series are included in this
+release, unless otherwise noted.
+
+ * "git apply" and "git diff" (including patch output from "git log -p")
+ now flags trailing blank lines as whitespace errors correctly (only
+ "apply --whitespace=fix" stripped them but "apply --whitespace=warn"
+ did not even warn).
+
+ * Two whitespace error classes, 'blank-at-eof' and 'blank-at-eol', have
+ been introduced (settable by core.whitespace configuration variable and
+ whitespace attribute). The 'trailing-space' whitespace error class has
+ become a short-hand to cover both of these and there is no behaviour
+ change for existing set-ups.
+
+ * "git cvsimport" did not work well when it is fed filenames from the
+ command line and is not started at the top of the work tree. We should
+ backport this by merging f6fdbb6 (cvsimport: fix relative argument
+ filenames, 2009-10-19).
+
+ * The way gitweb escapes its CGI parameters were broken especially when
+ the parameter was a UTF-8 string. We may want to backport this to
+ 1.6.5.X series by merging 452e225 (gitweb: fix esc_param, 2009-10-13).
+
+ * gitweb used to show 'patch' link for merge commits but the output from
+ it is not usable to feed "git am" with. We may want to backport this
+ to 1.6.5.X series by merging 1655c98 (gitweb: Do not show 'patch' link
+ for merge commits, 2009-10-09).
+
+---
+exec >/var/tmp/1
+echo O=$(git describe master)
+O=v1.6.5.2-73-g9b12444
+git shortlog --no-merges $O..master --not maint
diff --git a/Documentation/config.txt b/Documentation/config.txt
index cd1781498e..d1e2120e15 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -416,13 +416,17 @@ core.whitespace::
consider them as errors. You can prefix `-` to disable
any of them (e.g. `-trailing-space`):
+
-* `trailing-space` treats trailing whitespaces at the end of the line
+* `blank-at-eol` treats trailing whitespaces at the end of the line
as an error (enabled by default).
* `space-before-tab` treats a space character that appears immediately
before a tab character in the initial indent part of the line as an
error (enabled by default).
* `indent-with-non-tab` treats a line that is indented with 8 or more
space characters as an error (not enabled by default).
+* `blank-at-eof` treats blank lines added at the end of file as an error
+ (enabled by default).
+* `trailing-space` is a short-hand to cover both `blank-at-eol` and
+ `blank-at-eof`.
* `cr-at-eol` treats a carriage-return at the end of line as
part of the line terminator, i.e. with it, `trailing-space`
does not trigger if the character before such a carriage-return
@@ -1320,6 +1324,11 @@ rebase.stat::
Whether to show a diffstat of what changed upstream since the last
rebase. False by default.
+receive.autogc::
+ By default, git-receive-pack will run "git-gc --auto" after
+ receiving data from git-push and updating refs. You can stop
+ it by setting this variable to false.
+
receive.fsckObjects::
If it is set to true, git-receive-pack will check all received
objects. It will abort in the case of a malformed object or a
@@ -1355,6 +1364,10 @@ receive.denyNonFastForwards::
even if that push is forced. This configuration variable is
set when initializing a shared repository.
+receive.updateserverinfo::
+ If set to true, git-receive-pack will run git-update-server-info
+ after receiving data from git-push and updating refs.
+
remote.<name>.url::
The URL of a remote repository. See linkgit:git-fetch[1] or
linkgit:git-push[1].
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 9276faeb11..e26b84706f 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -87,6 +87,13 @@ endif::git-format-patch[]
Show only names and status of changed files. See the description
of the `--diff-filter` option on what the status letters mean.
+--submodule[=<format>]::
+ Chose the output format for submodule differences. <format> can be one of
+ 'short' and 'log'. 'short' just shows pairs of commit names, this format
+ is used when this option is not given. 'log' is the default value for this
+ option and lists the commits in that commit range like the 'summary'
+ option of linkgit:git-submodule[1] does.
+
--color::
Show colored diff.
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 5eb2b0ee07..28868747da 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -1,25 +1,13 @@
-ifndef::git-pull[]
--q::
---quiet::
- Pass --quiet to git-fetch-pack and silence any other internally
- used git commands.
-
--v::
---verbose::
- Be verbose.
-endif::git-pull[]
-
-a::
--append::
Append ref names and object names of fetched refs to the
existing contents of `.git/FETCH_HEAD`. Without this
option old data in `.git/FETCH_HEAD` will be overwritten.
---upload-pack <upload-pack>::
- When given, and the repository to fetch from is handled
- by 'git-fetch-pack', '--exec=<upload-pack>' is passed to
- the command to specify non-default path for the command
- run on the other end.
+--depth=<depth>::
+ Deepen the history of a 'shallow' repository created by
+ `git clone` with `--depth=<depth>` option (see linkgit:git-clone[1])
+ by the specified number of commits.
-f::
--force::
@@ -29,6 +17,10 @@ endif::git-pull[]
fetches is a descendant of `<lbranch>`. This option
overrides that check.
+-k::
+--keep::
+ Keep downloaded pack.
+
ifdef::git-pull[]
--no-tags::
endif::git-pull[]
@@ -49,10 +41,6 @@ endif::git-pull[]
flag lets all tags and their associated objects be
downloaded.
--k::
---keep::
- Keep downloaded pack.
-
-u::
--update-head-ok::
By default 'git-fetch' refuses to update the head which
@@ -62,7 +50,19 @@ endif::git-pull[]
implementing your own Porcelain you are not supposed to
use it.
---depth=<depth>::
- Deepen the history of a 'shallow' repository created by
- `git clone` with `--depth=<depth>` option (see linkgit:git-clone[1])
- by the specified number of commits.
+--upload-pack <upload-pack>::
+ When given, and the repository to fetch from is handled
+ by 'git-fetch-pack', '--exec=<upload-pack>' is passed to
+ the command to specify non-default path for the command
+ run on the other end.
+
+ifndef::git-pull[]
+-q::
+--quiet::
+ Pass --quiet to git-fetch-pack and silence any other internally
+ used git commands.
+
+-v::
+--verbose::
+ Be verbose.
+endif::git-pull[]
diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index 63e7a42cb3..d2ffae0c10 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -20,7 +20,7 @@ on the subcommand:
git bisect bad [<rev>]
git bisect good [<rev>...]
git bisect skip [(<rev>|<range>)...]
- git bisect reset [<branch>]
+ git bisect reset [<commit>]
git bisect visualize
git bisect replay <logfile>
git bisect log
@@ -81,16 +81,27 @@ will have been left with the first bad kernel revision in "refs/bisect/bad".
Bisect reset
~~~~~~~~~~~~
-To return to the original head after a bisect session, issue the
-following command:
+After a bisect session, to clean up the bisection state and return to
+the original HEAD, issue the following command:
------------------------------------------------
$ git bisect reset
------------------------------------------------
-This resets the tree to the original branch instead of being on the
-bisection commit ("git bisect start" will also do that, as it resets
-the bisection state).
+By default, this will return your tree to the commit that was checked
+out before `git bisect start`. (A new `git bisect start` will also do
+that, as it cleans up the old bisection state.)
+
+With an optional argument, you can return to a different commit
+instead:
+
+------------------------------------------------
+$ git bisect reset <commit>
+------------------------------------------------
+
+For example, `git bisect reset HEAD` will leave you on the current
+bisection commit and avoid switching commits at all, while `git bisect
+reset bisect/bad` will check out the first bad revision.
Bisect visualize
~~~~~~~~~~~~~~~~
diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt
index e9b3b40af4..0aeef24780 100644
--- a/Documentation/git-check-ref-format.txt
+++ b/Documentation/git-check-ref-format.txt
@@ -9,6 +9,7 @@ SYNOPSIS
--------
[verse]
'git check-ref-format' <refname>
+'git check-ref-format' --print <refname>
'git check-ref-format' --branch <branchname-shorthand>
DESCRIPTION
@@ -63,19 +64,31 @@ reference name expressions (see linkgit:git-rev-parse[1]):
. at-open-brace `@{` is used as a notation to access a reflog entry.
+With the `--print` option, if 'refname' is acceptable, it prints the
+canonicalized name of a hypothetical reference with that name. That is,
+it prints 'refname' with any extra `/` characters removed.
+
With the `--branch` option, it expands the ``previous branch syntax''
`@{-n}`. For example, `@{-1}` is a way to refer the last branch you
were on. This option should be used by porcelains to accept this
syntax anywhere a branch name is expected, so they can act as if you
typed the branch name.
-EXAMPLE
--------
-
-git check-ref-format --branch @{-1}::
-
-Print the name of the previous branch.
+EXAMPLES
+--------
+* Print the name of the previous branch:
++
+------------
+$ git check-ref-format --branch @{-1}
+------------
+
+* Determine the reference name to use for a new branch:
++
+------------
+$ ref=$(git check-ref-format --print "refs/heads/$newbranch") ||
+die "we do not like '$newbranch' as a branch name."
+------------
GIT
---
diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt
index 2f97916781..78b9808aa3 100644
--- a/Documentation/git-describe.txt
+++ b/Documentation/git-describe.txt
@@ -8,7 +8,9 @@ git-describe - Show the most recent tag that is reachable from a commit
SYNOPSIS
--------
+[verse]
'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] <committish>...
+'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>]
DESCRIPTION
-----------
@@ -27,6 +29,11 @@ OPTIONS
<committish>...::
Committish object names to describe.
+--dirty[=<mark>]::
+ Describe the working tree.
+ It means describe HEAD and appends <mark> (`-dirty` by
+ default) if the working tree is dirty.
+
--all::
Instead of using only the annotated tags, use any ref
found in `.git/refs/`. This option enables matching
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index d3164c5c88..f2483d624e 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -37,6 +37,35 @@ include::pull-fetch-param.txt[]
include::urls-remotes.txt[]
+
+EXAMPLES
+--------
+
+* Update the remote-tracking branches:
++
+------------------------------------------------
+$ git fetch origin
+------------------------------------------------
++
+The above command copies all branches from the remote refs/heads/
+namespace and stores them to the local refs/remotes/origin/ namespace,
+unless the branch.<name>.fetch option is used to specify a non-default
+refspec.
+
+* Using refspecs explicitly:
++
+------------------------------------------------
+$ git fetch origin +pu:pu maint:tmp
+------------------------------------------------
++
+This updates (or creates, as necessary) branches `pu` and `tmp` in
+the local repository by fetching from the branches (respectively)
+`pu` and `maint` from the remote repository.
++
+The `pu` branch will be updated even if it is does not fast-forward,
+because it is prefixed with a plus sign; `tmp` will not be.
+
+
SEE ALSO
--------
linkgit:git-pull[1]
diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt
index 287c4fc5e0..6fe9484da3 100644
--- a/Documentation/git-fsck.txt
+++ b/Documentation/git-fsck.txt
@@ -10,7 +10,7 @@ SYNOPSIS
--------
[verse]
'git fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
- [--full] [--strict] [--verbose] [--lost-found] [<object>*]
+ [--[no-]full] [--strict] [--verbose] [--lost-found] [<object>*]
DESCRIPTION
-----------
@@ -52,7 +52,8 @@ index file, all SHA1 references in .git/refs/*, and all reflogs (unless
or $GIT_DIR/objects/info/alternates,
and in packed git archives found in $GIT_DIR/objects/pack
and corresponding pack subdirectories in alternate
- object pools.
+ object pools. This is now default; you can turn it off
+ with --no-full.
--strict::
Enable more strict checking, namely to catch a file mode
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index 021066e95d..625723e41f 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -48,8 +48,10 @@ OPTIONS
-i::
--ignored::
- Show ignored files in the output.
- Note that this also reverses any exclude list present.
+ Show only ignored files in the output. When showing files in the
+ index, print only those matched by an exclude pattern. When
+ showing "other" files, show only those matched by an exclude
+ pattern.
-s::
--stage::
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index d05f324462..e886c2ef54 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -212,6 +212,39 @@ You can work through the conflict with a number of tools:
common ancestor, 'git show :2:filename' shows the HEAD
version and 'git show :3:filename' shows the remote version.
+
+EXAMPLES
+--------
+
+* Merge branches `fixes` and `enhancements` on top of
+ the current branch, making an octopus merge:
++
+------------------------------------------------
+$ git merge fixes enhancements
+------------------------------------------------
+
+* Merge branch `obsolete` into the current branch, using `ours`
+ merge strategy:
++
+------------------------------------------------
+$ git merge -s ours obsolete
+------------------------------------------------
+
+* Merge branch `maint` into the current branch, but do not make
+ a new commit automatically:
++
+------------------------------------------------
+$ git merge --no-commit maint
+------------------------------------------------
++
+This can be used when you want to include further changes to the
+merge, or want to write your own merge commit message.
++
+You should refrain from abusing this option to sneak substantial
+changes into a merge commit. Small fixups like bumping
+release/version name would be acceptable.
+
+
SEE ALSO
--------
linkgit:git-fmt-merge-msg[1], linkgit:git-pull[1],
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 7578623edb..b93201158f 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -26,6 +26,10 @@ Also note that options meant for 'git-pull' itself and underlying
OPTIONS
-------
+
+Options related to merging
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
include::merge-options.txt[]
:git-pull: 1
@@ -47,6 +51,9 @@ unless you have read linkgit:git-rebase[1] carefully.
--no-rebase::
Override earlier --rebase.
+Options related to fetching
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
include::fetch-options.txt[]
include::pull-fetch-param.txt[]
@@ -131,54 +138,13 @@ $ git pull origin next
------------------------------------------------
+
This leaves a copy of `next` temporarily in FETCH_HEAD, but
-does not update any remote-tracking branches.
-
-* Bundle local branch `fixes` and `enhancements` on top of
- the current branch, making an Octopus merge:
-+
-------------------------------------------------
-$ git pull . fixes enhancements
-------------------------------------------------
-+
-This `git pull .` syntax is equivalent to `git merge`.
-
-* Merge local branch `obsolete` into the current branch, using `ours`
- merge strategy:
-+
-------------------------------------------------
-$ git pull -s ours . obsolete
-------------------------------------------------
-
-* Merge local branch `maint` into the current branch, but do not make
- a commit automatically:
+does not update any remote-tracking branches. Using remote-tracking
+branches, the same can be done by invoking fetch and merge:
+
------------------------------------------------
-$ git pull --no-commit . maint
+$ git fetch origin
+$ git merge origin/next
------------------------------------------------
-+
-This can be used when you want to include further changes to the
-merge, or want to write your own merge commit message.
-+
-You should refrain from abusing this option to sneak substantial
-changes into a merge commit. Small fixups like bumping
-release/version name would be acceptable.
-
-* Command line pull of multiple branches from one repository:
-+
-------------------------------------------------
-$ git checkout master
-$ git fetch origin +pu:pu maint:tmp
-$ git pull . tmp
-------------------------------------------------
-+
-This updates (or creates, as necessary) branches `pu` and `tmp` in
-the local repository by fetching from the branches (respectively)
-`pu` and `maint` from the remote repository.
-+
-The `pu` branch will be updated even if it is does not fast-forward;
-the others will not be.
-+
-The final command then merges the newly fetched `tmp` into master.
If you tried a pull which resulted in a complex conflicts and
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 0aefc34d0d..33e0ef1f6d 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -368,14 +368,17 @@ By replacing the command "pick" with the command "edit", you can tell
the files and/or the commit message, amend the commit, and continue
rebasing.
+If you just want to edit the commit message for a commit, replace the
+command "pick" with the command "reword".
+
If you want to fold two or more commits into one, replace the command
"pick" with "squash" for the second and subsequent commit. If the
commits had different authors, it will attribute the squashed commit to
the author of the first commit.
-In both cases, or when a "pick" does not succeed (because of merge
-errors), the loop will stop to let you fix things, and you can continue
-the loop with `git rebase --continue`.
+'git-rebase' will stop when "pick" has been replaced with "edit" or
+when a command fails due to merge errors. When you are done editing
+and/or resolving conflicts you can continue with `git rebase --continue`.
For example, if you want to reorder the last 5 commits, such that what
was HEAD~4 becomes the new HEAD. To achieve that, you would call
diff --git a/Documentation/git-replace.txt b/Documentation/git-replace.txt
index 915cb77b29..8adc1ef55c 100644
--- a/Documentation/git-replace.txt
+++ b/Documentation/git-replace.txt
@@ -23,6 +23,26 @@ replacement object.
Unless `-f` is given, the replace reference must not yet exist in
`.git/refs/replace/` directory.
+Replace references will be used by default by all git commands except
+those doing reachability traversal (prune, pack transfer and fsck).
+
+It is possible to disable use of replacement refs for any command
+using the --no-replace-objects option just after "git".
+
+For example if commit "foo" has been replaced by commit "bar":
+
+------------------------------------------------
+$ git --no-replace-object cat-file commit foo
+------------------------------------------------
+
+show information about commit "foo", while:
+
+------------------------------------------------
+$ git cat-file commit foo
+------------------------------------------------
+
+show information about commit "bar".
+
OPTIONS
-------
-f::
@@ -54,6 +74,7 @@ SEE ALSO
--------
linkgit:git-tag[1]
linkgit:git-branch[1]
+linkgit:git[1]
Author
------
diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
index fafe728f89..3f14b727b8 100644
--- a/Documentation/git-stash.txt
+++ b/Documentation/git-stash.txt
@@ -78,8 +78,7 @@ stash@{1}: On master: 9cc0589... Add git-stash
----------------------------------------------------------------
+
The command takes options applicable to the 'git-log'
-command to control what is shown and how. If no options are set, the
-default is `-n 10`. See linkgit:git-log[1].
+command to control what is shown and how. See linkgit:git-log[1].
show [<stash>]::
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 25e0bbea86..6052484ab9 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -99,6 +99,10 @@ in the index e.g. when merging in a commit;
thus, in case the assumed-untracked file is changed upstream,
you will need to handle the situation manually.
+--really-refresh::
+ Like '--refresh', but checks stat information unconditionally,
+ without regard to the "assume unchanged" setting.
+
-g::
--again::
Runs 'git-update-index' itself on the paths whose index
@@ -308,7 +312,7 @@ Configuration
-------------
The command honors `core.filemode` configuration variable. If
-your repository is on an filesystem whose executable bits are
+your repository is on a filesystem whose executable bits are
unreliable, this should be set to 'false' (see linkgit:git-config[1]).
This causes the command to ignore differences in file modes recorded
in the index and the file mode on the filesystem if they differ only on
diff --git a/Documentation/git.txt b/Documentation/git.txt
index e3fe970b34..0f536793df 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -10,7 +10,7 @@ SYNOPSIS
--------
[verse]
'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]
- [-p|--paginate|--no-pager]
+ [-p|--paginate|--no-pager] [--no-replace-objects]
[--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
[--help] COMMAND [ARGS]
@@ -239,6 +239,10 @@ help ...`.
environment is not set, it is set to the current working
directory.
+--no-replace-objects::
+ Do not use replacement refs to replace git objects. See
+ linkgit:git-replace[1] for more information.
+
FURTHER DOCUMENTATION
---------------------
diff --git a/Documentation/manpage-quote-apos.xsl b/Documentation/manpage-quote-apos.xsl
new file mode 100644
index 0000000000..aeb8839f33
--- /dev/null
+++ b/Documentation/manpage-quote-apos.xsl
@@ -0,0 +1,16 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+<!-- work around newer groff/man setups using a prettier apostrophe
+ that unfortunately does not quote anything when cut&pasting
+ examples to the shell -->
+<xsl:template name="escape.apostrophe">
+ <xsl:param name="content"/>
+ <xsl:call-template name="string.subst">
+ <xsl:with-param name="string" select="$content"/>
+ <xsl:with-param name="target">'</xsl:with-param>
+ <xsl:with-param name="replacement">\(aq</xsl:with-param>
+ </xsl:call-template>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt
index adadf8e4bf..fec3394305 100644
--- a/Documentation/merge-options.txt
+++ b/Documentation/merge-options.txt
@@ -1,43 +1,42 @@
--q::
---quiet::
- Operate quietly.
-
--v::
---verbose::
- Be verbose.
-
---stat::
- Show a diffstat at the end of the merge. The diffstat is also
- controlled by the configuration option merge.stat.
-
--n::
---no-stat::
- Do not show a diffstat at the end of the merge.
+--commit::
+--no-commit::
+ Perform the merge and commit the result. This option can
+ be used to override --no-commit.
++
+With --no-commit perform the merge but pretend the merge
+failed and do not autocommit, to give the user a chance to
+inspect and further tweak the merge result before committing.
---summary::
---no-summary::
- Synonyms to --stat and --no-stat; these are deprecated and will be
- removed in the future.
+--ff::
+--no-ff::
+ Do not generate a merge commit if the merge resolved as
+ a fast-forward, only update the branch pointer. This is
+ the default behavior of git-merge.
++
+With --no-ff Generate a merge commit even if the merge
+resolved as a fast-forward.
--log::
+--no-log::
In addition to branch names, populate the log message with
one-line descriptions from the actual commits that are being
merged.
++
+With --no-log do not list one-line descriptions from the
+actual commits being merged.
---no-log::
- Do not list one-line descriptions from the actual commits being
- merged.
-
---no-commit::
- Perform the merge but pretend the merge failed and do
- not autocommit, to give the user a chance to inspect and
- further tweak the merge result before committing.
---commit::
- Perform the merge and commit the result. This option can
- be used to override --no-commit.
+--stat::
+-n::
+--no-stat::
+ Show a diffstat at the end of the merge. The diffstat is also
+ controlled by the configuration option merge.stat.
++
+With -n or --no-stat do not show a diffstat at the end of the
+merge.
--squash::
+--no-squash::
Produce the working tree and index state as if a real
merge happened (except for the merge information),
but do not actually make a commit or
@@ -46,19 +45,14 @@
commit. This allows you to create a single commit on
top of the current branch whose effect is the same as
merging another branch (or more in case of an octopus).
++
+With --no-squash perform the merge and commit the result. This
+option can be used to override --squash.
---no-squash::
- Perform the merge and commit the result. This option can
- be used to override --squash.
-
---no-ff::
- Generate a merge commit even if the merge resolved as a
- fast-forward.
-
---ff::
- Do not generate a merge commit if the merge resolved as
- a fast-forward, only update the branch pointer. This is
- the default behavior of git-merge.
+--ff-only::
+ Refuse to merge and exit with a non-zero status unless the
+ current `HEAD` is already up-to-date or the merge can be
+ resolved as a fast-forward.
-s <strategy>::
--strategy=<strategy>::
@@ -67,3 +61,16 @@
If there is no `-s` option, a built-in list of strategies
is used instead ('git-merge-recursive' when merging a single
head, 'git-merge-octopus' otherwise).
+
+--summary::
+--no-summary::
+ Synonyms to --stat and --no-stat; these are deprecated and will be
+ removed in the future.
+
+-q::
+--quiet::
+ Operate quietly.
+
+-v::
+--verbose::
+ Be verbose.
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 2a845b1e57..38b9904791 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -123,6 +123,9 @@ The placeholders are:
- '%s': subject
- '%f': sanitized subject line, suitable for a filename
- '%b': body
+- '%gD': reflog selector, e.g., `refs/stash@\{1\}`
+- '%gd': shortened reflog selector, e.g., `stash@\{1\}`
+- '%gs': reflog subject
- '%Cred': switch color to red
- '%Cgreen': switch color to green
- '%Cblue': switch color to blue
@@ -132,6 +135,12 @@ The placeholders are:
- '%n': newline
- '%x00': print a byte from a hex code
+NOTE: Some placeholders may depend on other options given to the
+revision traversal engine. For example, the `%g*` reflog options will
+insert an empty string unless we are traversing reflog entries (e.g., by
+`git log -g`). The `%d` placeholder will use the "short" decoration
+format if `--decorate` was not already provided on the command line.
+
* 'tformat:'
+
The 'tformat:' format works exactly like 'format:', except that it
diff --git a/Documentation/pt_BR/gittutorial.txt b/Documentation/pt_BR/gittutorial.txt
index 81e7ad7df4..beba065252 100644
--- a/Documentation/pt_BR/gittutorial.txt
+++ b/Documentation/pt_BR/gittutorial.txt
@@ -1,15 +1,15 @@
gittutorial(7)
==============
-NAME
+NOME
----
gittutorial - Um tutorial de introdução ao git (para versão 1.5.1 ou mais nova)
-SYNOPSIS
+SINOPSE
--------
git *
-DESCRIPTION
+DESCRIÇÃO
-----------
Este tutorial explica como importar um novo projeto para o git,
@@ -64,11 +64,11 @@ Git irá responder
Initialized empty Git repository in .git/
------------------------------------------------
-Você agora iniciou seu diretório de trabalho--você deve ter notado um
-novo diretório criado, com o nome de ".git".
+Agora que você iniciou seu diretório de trabalho, você deve ter notado que um
+novo diretório foi criado com o nome de ".git".
A seguir, diga ao git para gravar um instantâneo do conteúdo de todos os
-arquivos sob o diretório corrente (note o '.'), com 'git-add':
+arquivos sob o diretório atual (note o '.'), com 'git-add':
------------------------------------------------
$ git add .
@@ -126,8 +126,8 @@ mudanças com:
$ git commit
------------------------------------------------
-Isto irá novamente te pedir por uma mensagem descrevendo a mudança, e,
-então, gravar a nova versão do projeto.
+Ao executar esse comando, ele irá te pedir uma mensagem descrevendo a mudança,
+e, então, irá gravar a nova versão do projeto.
Alternativamente, ao invés de executar 'git-add' antes, você pode usar
@@ -143,7 +143,7 @@ idéia começar a mensagem com uma simples e curta (menos de 50
caracteres) linha sumarizando a mudança, seguida de uma linha em branco
e, então, uma descrição mais detalhada. Ferramentas que transformam
commits em email, por exemplo, usam a primeira linha no campo de
-cabeçalho Subject: e o resto no corpo.
+cabeçalho "Subject:" e o resto no corpo.
Git rastreia conteúdo, não arquivos
----------------------------
@@ -155,7 +155,7 @@ usado tanto para arquivos novos e arquivos recentemente modificados, e
em ambos os casos, ele tira o instantâneo dos arquivos dados e armazena
o conteúdo no índice, pronto para inclusão do próximo commit.
-Visualizando história do projeto
+Visualizando a história do projeto
-----------------------
Em qualquer ponto você pode visualizar a história das suas mudanças
@@ -165,7 +165,7 @@ usando
$ git log
------------------------------------------------
-Se você também quer ver a diferença completa a cada passo, use
+Se você também quiser ver a diferença completa a cada passo, use
------------------------------------------------
$ git log -p
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 09cb354ca0..710d361233 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.6.5.2
+DEF_VER=v1.6.5.GIT
LF='
'
diff --git a/Makefile b/Makefile
index 3bca8d42cc..5d5976f94f 100644
--- a/Makefile
+++ b/Makefile
@@ -159,6 +159,10 @@ all::
# Define ASCIIDOC_NO_ROFF if your DocBook XSL escapes raw roff directives
# (versions 1.72 and later and 1.68.1 and earlier).
#
+# Define GNU_ROFF if your target system uses GNU groff. This forces
+# apostrophes to be ASCII so that cut&pasting examples to the shell
+# will work.
+#
# Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's
# MakeMaker (e.g. using ActiveState under Cygwin).
#
@@ -453,6 +457,7 @@ LIB_H += sideband.h
LIB_H += sigchain.h
LIB_H += strbuf.h
LIB_H += string-list.h
+LIB_H += submodule.h
LIB_H += tag.h
LIB_H += transport.h
LIB_H += tree.h
@@ -551,6 +556,7 @@ LIB_OBJS += sideband.o
LIB_OBJS += sigchain.o
LIB_OBJS += strbuf.o
LIB_OBJS += string-list.o
+LIB_OBJS += submodule.o
LIB_OBJS += symlinks.o
LIB_OBJS += tag.o
LIB_OBJS += trace.o
diff --git a/RelNotes b/RelNotes
index 1cb2571eaa..5274ceed4e 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes-1.6.5.2.txt \ No newline at end of file
+Documentation/RelNotes-1.6.6.txt \ No newline at end of file
diff --git a/archive.c b/archive.c
index 0cc79d2a24..55b273246e 100644
--- a/archive.c
+++ b/archive.c
@@ -31,6 +31,8 @@ static void format_subst(const struct commit *commit,
{
char *to_free = NULL;
struct strbuf fmt = STRBUF_INIT;
+ struct pretty_print_context ctx = {0};
+ ctx.date_mode = DATE_NORMAL;
if (src == buf->buf)
to_free = strbuf_detach(buf, NULL);
@@ -48,7 +50,7 @@ static void format_subst(const struct commit *commit,
strbuf_add(&fmt, b + 8, c - b - 8);
strbuf_add(buf, src, b - src);
- format_commit_message(commit, fmt.buf, buf, DATE_NORMAL);
+ format_commit_message(commit, fmt.buf, buf, &ctx);
len -= c + 1 - src;
src = c + 1;
}
diff --git a/builtin-apply.c b/builtin-apply.c
index c8372a0a80..f667368d16 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -153,6 +153,7 @@ struct fragment {
const char *patch;
int size;
int rejected;
+ int linenr;
struct fragment *next;
};
@@ -1227,23 +1228,29 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
return -1;
}
-static void check_whitespace(const char *line, int len, unsigned ws_rule)
+static void record_ws_error(unsigned result, const char *line, int len, int linenr)
{
char *err;
- unsigned result = ws_check(line + 1, len - 1, ws_rule);
+
if (!result)
return;
whitespace_error++;
if (squelch_whitespace_errors &&
squelch_whitespace_errors < whitespace_error)
- ;
- else {
- err = whitespace_error_string(result);
- fprintf(stderr, "%s:%d: %s.\n%.*s\n",
- patch_input_file, linenr, err, len - 2, line + 1);
- free(err);
- }
+ return;
+
+ err = whitespace_error_string(result);
+ fprintf(stderr, "%s:%d: %s.\n%.*s\n",
+ patch_input_file, linenr, err, len, line);
+ free(err);
+}
+
+static void check_whitespace(const char *line, int len, unsigned ws_rule)
+{
+ unsigned result = ws_check(line + 1, len - 1, ws_rule);
+
+ record_ws_error(result, line + 1, len - 2, linenr);
}
/*
@@ -1359,6 +1366,7 @@ static int parse_single_patch(char *line, unsigned long size, struct patch *patc
int len;
fragment = xcalloc(1, sizeof(*fragment));
+ fragment->linenr = linenr;
len = parse_fragment(line, size, patch, fragment);
if (len <= 0)
die("corrupt patch at line %d", linenr);
@@ -2142,6 +2150,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
int len = linelen(patch, size);
int plen, added;
int added_blank_line = 0;
+ int is_blank_context = 0;
if (!len)
break;
@@ -2174,8 +2183,12 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
*new++ = '\n';
add_line_info(&preimage, "\n", 1, LINE_COMMON);
add_line_info(&postimage, "\n", 1, LINE_COMMON);
+ is_blank_context = 1;
break;
case ' ':
+ if (plen && (ws_rule & WS_BLANK_AT_EOF) &&
+ ws_blank_line(patch + 1, plen, ws_rule))
+ is_blank_context = 1;
case '-':
memcpy(old, patch + 1, plen);
add_line_info(&preimage, old, plen,
@@ -2202,7 +2215,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
(first == '+' ? 0 : LINE_COMMON));
new += added;
if (first == '+' &&
- added == 1 && new[-1] == '\n')
+ (ws_rule & WS_BLANK_AT_EOF) &&
+ ws_blank_line(patch + 1, plen, ws_rule))
added_blank_line = 1;
break;
case '@': case '\\':
@@ -2215,6 +2229,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
}
if (added_blank_line)
new_blank_lines_at_end++;
+ else if (is_blank_context)
+ ;
else
new_blank_lines_at_end = 0;
patch += len;
@@ -2296,17 +2312,24 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
}
if (applied_pos >= 0) {
- if (ws_error_action == correct_ws_error &&
- new_blank_lines_at_end &&
- postimage.nr + applied_pos == img->nr) {
+ if (new_blank_lines_at_end &&
+ preimage.nr + applied_pos == img->nr &&
+ (ws_rule & WS_BLANK_AT_EOF) &&
+ ws_error_action != nowarn_ws_error) {
+ record_ws_error(WS_BLANK_AT_EOF, "+", 1, frag->linenr);
+ if (ws_error_action == correct_ws_error) {
+ while (new_blank_lines_at_end--)
+ remove_last_line(&postimage);
+ }
/*
- * If the patch application adds blank lines
- * at the end, and if the patch applies at the
- * end of the image, remove those added blank
- * lines.
+ * We would want to prevent write_out_results()
+ * from taking place in apply_patch() that follows
+ * the callchain led us here, which is:
+ * apply_patch->check_patch_list->check_patch->
+ * apply_data->apply_fragments->apply_one_fragment
*/
- while (new_blank_lines_at_end--)
- remove_last_line(&postimage);
+ if (ws_error_action == die_on_ws_error)
+ apply = 0;
}
/*
diff --git a/builtin-blame.c b/builtin-blame.c
index 7512773b40..dd16b22297 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -1604,6 +1604,9 @@ static void emit_porcelain(struct scoreboard *sb, struct blame_entry *ent)
} while (ch != '\n' &&
cp < sb->final_buf + sb->final_buf_size);
}
+
+ if (sb->final_buf_size && cp[-1] != '\n')
+ putchar('\n');
}
static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
@@ -1667,6 +1670,9 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
} while (ch != '\n' &&
cp < sb->final_buf + sb->final_buf_size);
}
+
+ if (sb->final_buf_size && cp[-1] != '\n')
+ putchar('\n');
}
static void output(struct scoreboard *sb, int option)
diff --git a/builtin-branch.c b/builtin-branch.c
index 9f57992062..05e876e285 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -387,8 +387,9 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
commit = item->commit;
if (commit && !parse_commit(commit)) {
+ struct pretty_print_context ctx = {0};
pretty_print_commit(CMIT_FMT_ONELINE, commit,
- &subject, 0, NULL, NULL, 0, 0);
+ &subject, &ctx);
sub = subject.buf;
}
diff --git a/builtin-check-ref-format.c b/builtin-check-ref-format.c
index a5ba4eae5a..513f134638 100644
--- a/builtin-check-ref-format.c
+++ b/builtin-check-ref-format.c
@@ -8,9 +8,31 @@
#include "strbuf.h"
static const char builtin_check_ref_format_usage[] =
-"git check-ref-format <refname>\n"
+"git check-ref-format [--print] <refname>\n"
" or: git check-ref-format --branch <branchname-shorthand>";
+/*
+ * Replace each run of adjacent slashes in src with a single slash,
+ * and write the result to dst.
+ *
+ * This function is similar to normalize_path_copy(), but stripped down
+ * to meet check_ref_format's simpler needs.
+ */
+static void collapse_slashes(char *dst, const char *src)
+{
+ char ch;
+ char prev = '\0';
+
+ while ((ch = *src++) != '\0') {
+ if (prev == '/' && ch == prev)
+ continue;
+
+ *dst++ = ch;
+ prev = ch;
+ }
+ *dst = '\0';
+}
+
int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
{
if (argc == 3 && !strcmp(argv[1], "--branch")) {
@@ -21,6 +43,15 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
printf("%s\n", sb.buf + 11);
exit(0);
}
+ if (argc == 3 && !strcmp(argv[1], "--print")) {
+ char *refname = xmalloc(strlen(argv[2]) + 1);
+
+ if (check_ref_format(argv[2]))
+ exit(1);
+ collapse_slashes(refname, argv[2]);
+ printf("%s\n", refname);
+ exit(0);
+ }
if (argc != 2)
usage(builtin_check_ref_format_usage);
return !!check_ref_format(argv[1]);
diff --git a/builtin-checkout.c b/builtin-checkout.c
index d050c3789f..64f3a11ae1 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -302,8 +302,9 @@ static void show_local_changes(struct object *head)
static void describe_detached_head(char *msg, struct commit *commit)
{
struct strbuf sb = STRBUF_INIT;
+ struct pretty_print_context ctx = {0};
parse_commit(commit);
- pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0);
+ pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, &ctx);
fprintf(stderr, "%s %s... %s\n", msg,
find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
strbuf_release(&sb);
@@ -572,6 +573,40 @@ static int interactive_checkout(const char *revision, const char **pathspec,
return run_add_interactive(revision, "--patch=checkout", pathspec);
}
+struct tracking_name_data {
+ const char *name;
+ char *remote;
+ int unique;
+};
+
+static int check_tracking_name(const char *refname, const unsigned char *sha1,
+ int flags, void *cb_data)
+{
+ struct tracking_name_data *cb = cb_data;
+ const char *slash;
+
+ if (prefixcmp(refname, "refs/remotes/"))
+ return 0;
+ slash = strchr(refname + 13, '/');
+ if (!slash || strcmp(slash + 1, cb->name))
+ return 0;
+ if (cb->remote) {
+ cb->unique = 0;
+ return 0;
+ }
+ cb->remote = xstrdup(refname);
+ return 0;
+}
+
+static const char *unique_tracking_name(const char *name)
+{
+ struct tracking_name_data cb_data = { name, NULL, 1 };
+ for_each_ref(check_tracking_name, &cb_data);
+ if (cb_data.unique)
+ return cb_data.remote;
+ free(cb_data.remote);
+ return NULL;
+}
int cmd_checkout(int argc, const char **argv, const char *prefix)
{
@@ -582,6 +617,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
struct tree *source_tree = NULL;
char *conflict_style = NULL;
int patch_mode = 0;
+ int dwim_new_local_branch = 1;
struct option options[] = {
OPT__QUIET(&opts.quiet),
OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
@@ -597,6 +633,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
OPT_STRING(0, "conflict", &conflict_style, "style",
"conflict style (merge or diff3)"),
OPT_BOOLEAN('p', "patch", &patch_mode, "select hunks interactively"),
+ { OPTION_BOOLEAN, 0, "guess", &dwim_new_local_branch, NULL,
+ "second guess 'git checkout no-such-branch'",
+ PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
OPT_END(),
};
int has_dash_dash;
@@ -630,8 +669,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
opts.new_branch = argv0 + 1;
}
- if (opts.track == BRANCH_TRACK_UNSPECIFIED)
- opts.track = git_branch_track;
if (conflict_style) {
opts.merge = 1; /* implied */
git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
@@ -655,6 +692,11 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
* With no paths, if <something> is a commit, that is to
* switch to the branch or detach HEAD at it.
*
+ * With no paths, if <something> is _not_ a commit, no -t nor -b
+ * was given, and there is a tracking branch whose name is
+ * <something> in one and only one remote, then this is a short-hand
+ * to fork local <something> from that remote tracking branch.
+ *
* Otherwise <something> shall not be ambiguous.
* - If it's *only* a reference, treat it like case (1).
* - If it's only a path, treat it like case (2).
@@ -677,7 +719,21 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
if (get_sha1(arg, rev)) {
if (has_dash_dash) /* case (1) */
die("invalid reference: %s", arg);
- goto no_reference; /* case (3 -> 2) */
+ if (!patch_mode &&
+ dwim_new_local_branch &&
+ opts.track == BRANCH_TRACK_UNSPECIFIED &&
+ !opts.new_branch &&
+ !check_filename(NULL, arg) &&
+ argc == 1) {
+ const char *remote = unique_tracking_name(arg);
+ if (!remote || get_sha1(remote, rev))
+ goto no_reference;
+ opts.new_branch = arg;
+ arg = remote;
+ /* DWIMmed to create local branch */
+ }
+ else
+ goto no_reference;
}
/* we can't end up being in (2) anymore, eat the argument */
@@ -715,6 +771,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
}
no_reference:
+
+ if (opts.track == BRANCH_TRACK_UNSPECIFIED)
+ opts.track = git_branch_track;
+
if (argc) {
const char **pathspec = get_pathspec(prefix, argv);
diff --git a/builtin-commit.c b/builtin-commit.c
index 200ffdaad4..d525b894ec 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -414,6 +414,47 @@ static void determine_author_info(void)
author_date = date;
}
+static int ends_rfc2822_footer(struct strbuf *sb)
+{
+ int ch;
+ int hit = 0;
+ int i, j, k;
+ int len = sb->len;
+ int first = 1;
+ const char *buf = sb->buf;
+
+ for (i = len - 1; i > 0; i--) {
+ if (hit && buf[i] == '\n')
+ break;
+ hit = (buf[i] == '\n');
+ }
+
+ while (i < len - 1 && buf[i] == '\n')
+ i++;
+
+ for (; i < len; i = k) {
+ for (k = i; k < len && buf[k] != '\n'; k++)
+ ; /* do nothing */
+ k++;
+
+ if ((buf[k] == ' ' || buf[k] == '\t') && !first)
+ continue;
+
+ first = 0;
+
+ for (j = 0; i + j < len; j++) {
+ ch = buf[i + j];
+ if (ch == ':')
+ break;
+ if (isalnum(ch) ||
+ (ch == '-'))
+ continue;
+ return 0;
+ }
+ }
+ return 1;
+}
+
static int prepare_to_commit(const char *index_file, const char *prefix,
struct wt_status *s)
{
@@ -489,7 +530,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
; /* do nothing */
if (prefixcmp(sb.buf + i, sob.buf)) {
- if (prefixcmp(sb.buf + i, sign_off_header))
+ if (!i || !ends_rfc2822_footer(&sb))
strbuf_addch(&sb, '\n');
strbuf_addbuf(&sb, &sob);
}
@@ -684,8 +725,10 @@ static const char *find_author_by_nickname(const char *name)
prepare_revision_walk(&revs);
commit = get_revision(&revs);
if (commit) {
+ struct pretty_print_context ctx = {0};
+ ctx.date_mode = DATE_NORMAL;
strbuf_release(&buf);
- format_commit_message(commit, "%an <%ae>", &buf, DATE_NORMAL);
+ format_commit_message(commit, "%an <%ae>", &buf, &ctx);
return strbuf_detach(&buf, NULL);
}
die("No existing author found with '%s'", name);
@@ -942,8 +985,10 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
initial_commit ? " (root-commit)" : "");
if (!log_tree_commit(&rev, commit)) {
+ struct pretty_print_context ctx = {0};
struct strbuf buf = STRBUF_INIT;
- format_commit_message(commit, format + 7, &buf, DATE_NORMAL);
+ ctx.date_mode = DATE_NORMAL;
+ format_commit_message(commit, format + 7, &buf, &ctx);
printf("%s\n", buf.buf);
strbuf_release(&buf);
}
diff --git a/builtin-describe.c b/builtin-describe.c
index 7542b5705c..d4efb10ddf 100644
--- a/builtin-describe.c
+++ b/builtin-describe.c
@@ -5,12 +5,14 @@
#include "builtin.h"
#include "exec_cmd.h"
#include "parse-options.h"
+#include "diff.h"
#define SEEN (1u<<0)
#define MAX_TAGS (FLAG_BITS - 1)
static const char * const describe_usage[] = {
"git describe [options] <committish>*",
+ "git describe [options] --dirty",
NULL
};
@@ -23,6 +25,13 @@ static int max_candidates = 10;
static int found_names;
static const char *pattern;
static int always;
+static const char *dirty;
+
+/* diff-index command arguments to check if working tree is dirty. */
+static const char *diff_index_args[] = {
+ "diff-index", "--quiet", "HEAD", "--", NULL
+};
+
struct commit_name {
struct tag *tag;
@@ -96,8 +105,6 @@ static int get_name(const char *path, const unsigned char *sha1, int flag, void
if (!all) {
if (!prio)
return 0;
- if (!tags && prio < 2)
- return 0;
}
add_to_known_names(all ? path + 5 : path + 10, commit, prio, sha1);
return 0;
@@ -180,11 +187,11 @@ static void describe(const char *arg, int last_one)
unsigned char sha1[20];
struct commit *cmit, *gave_up_on = NULL;
struct commit_list *list;
- static int initialized = 0;
struct commit_name *n;
struct possible_tag all_matches[MAX_TAGS];
unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
unsigned long seen_commits = 0;
+ unsigned int unannotated_cnt = 0;
if (get_sha1(arg, sha1))
die("Not a valid object name %s", arg);
@@ -192,14 +199,6 @@ static void describe(const char *arg, int last_one)
if (!cmit)
die("%s is not a valid '%s' object", arg, commit_type);
- if (!initialized) {
- initialized = 1;
- for_each_ref(get_name, NULL);
- }
-
- if (!found_names && !always)
- die("cannot describe '%s'", sha1_to_hex(sha1));
-
n = cmit->util;
if (n) {
/*
@@ -208,6 +207,8 @@ static void describe(const char *arg, int last_one)
display_name(n);
if (longformat)
show_suffix(0, n->tag ? n->tag->tagged->sha1 : sha1);
+ if (dirty)
+ printf("%s", dirty);
printf("\n");
return;
}
@@ -226,7 +227,9 @@ static void describe(const char *arg, int last_one)
seen_commits++;
n = c->util;
if (n) {
- if (match_cnt < max_candidates) {
+ if (!tags && !all && n->prio < 2) {
+ unannotated_cnt++;
+ } else if (match_cnt < max_candidates) {
struct possible_tag *t = &all_matches[match_cnt++];
t->name = n;
t->depth = seen_commits - 1;
@@ -265,10 +268,20 @@ static void describe(const char *arg, int last_one)
if (!match_cnt) {
const unsigned char *sha1 = cmit->object.sha1;
if (always) {
- printf("%s\n", find_unique_abbrev(sha1, abbrev));
+ printf("%s", find_unique_abbrev(sha1, abbrev));
+ if (dirty)
+ printf("%s", dirty);
+ printf("\n");
return;
}
- die("cannot describe '%s'", sha1_to_hex(sha1));
+ if (unannotated_cnt)
+ die("No annotated tags can describe '%s'.\n"
+ "However, there were unannotated tags: try --tags.",
+ sha1_to_hex(sha1));
+ else
+ die("No tags can describe '%s'.\n"
+ "Try --always, or create some tags.",
+ sha1_to_hex(sha1));
}
qsort(all_matches, match_cnt, sizeof(all_matches[0]), compare_pt);
@@ -300,6 +313,8 @@ static void describe(const char *arg, int last_one)
display_name(all_matches[0].name);
if (abbrev)
show_suffix(all_matches[0].depth, cmit->object.sha1);
+ if (dirty)
+ printf("%s", dirty);
printf("\n");
if (!last_one)
@@ -324,6 +339,9 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
"only consider tags matching <pattern>"),
OPT_BOOLEAN(0, "always", &always,
"show abbreviated commit object as fallback"),
+ {OPTION_STRING, 0, "dirty", &dirty, "mark",
+ "append <mark> on dirty working tree (default: \"-dirty\")",
+ PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"},
OPT_END(),
};
@@ -359,8 +377,16 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
return cmd_name_rev(i + argc, args, prefix);
}
+ for_each_ref(get_name, NULL);
+ if (!found_names && !always)
+ die("No names found, cannot describe anything.");
+
if (argc == 0) {
+ if (dirty && !cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1, diff_index_args, prefix))
+ dirty = NULL;
describe("HEAD", 1);
+ } else if (dirty) {
+ die("--dirty is incompatible with committishes");
} else {
while (argc-- > 0) {
describe(*argv++, argc == 0);
diff --git a/builtin-fetch.c b/builtin-fetch.c
index cb48c57ca3..a35a6f8cb8 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -504,57 +504,98 @@ static int will_fetch(struct ref **head, const unsigned char *sha1)
return 0;
}
+struct tag_data {
+ struct ref **head;
+ struct ref ***tail;
+};
+
+static int add_to_tail(struct string_list_item *item, void *cb_data)
+{
+ struct tag_data *data = (struct tag_data *)cb_data;
+ struct ref *rm = NULL;
+
+ /* We have already decided to ignore this item */
+ if (!item->util)
+ return 0;
+
+ rm = alloc_ref(item->string);
+ rm->peer_ref = alloc_ref(item->string);
+ hashcpy(rm->old_sha1, item->util);
+
+ **data->tail = rm;
+ *data->tail = &rm->next;
+
+ return 0;
+}
+
static void find_non_local_tags(struct transport *transport,
struct ref **head,
struct ref ***tail)
{
struct string_list existing_refs = { NULL, 0, 0, 0 };
- struct string_list new_refs = { NULL, 0, 0, 1 };
- char *ref_name;
- int ref_name_len;
- const unsigned char *ref_sha1;
- const struct ref *tag_ref;
- struct ref *rm = NULL;
+ struct string_list remote_refs = { NULL, 0, 0, 0 };
+ struct tag_data data = {head, tail};
const struct ref *ref;
+ struct string_list_item *item = NULL;
for_each_ref(add_existing, &existing_refs);
for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
if (prefixcmp(ref->name, "refs/tags"))
continue;
- ref_name = xstrdup(ref->name);
- ref_name_len = strlen(ref_name);
- ref_sha1 = ref->old_sha1;
-
- if (!strcmp(ref_name + ref_name_len - 3, "^{}")) {
- ref_name[ref_name_len - 3] = 0;
- tag_ref = transport_get_remote_refs(transport);
- while (tag_ref) {
- if (!strcmp(tag_ref->name, ref_name)) {
- ref_sha1 = tag_ref->old_sha1;
- break;
- }
- tag_ref = tag_ref->next;
- }
+ /*
+ * The peeled ref always follows the matching base
+ * ref, so if we see a peeled ref that we don't want
+ * to fetch then we can mark the ref entry in the list
+ * as one to ignore by setting util to NULL.
+ */
+ if (!strcmp(ref->name + strlen(ref->name) - 3, "^{}")) {
+ if (item && !has_sha1_file(ref->old_sha1) &&
+ !will_fetch(head, ref->old_sha1) &&
+ !has_sha1_file(item->util) &&
+ !will_fetch(head, item->util))
+ item->util = NULL;
+ item = NULL;
+ continue;
}
- if (!string_list_has_string(&existing_refs, ref_name) &&
- !string_list_has_string(&new_refs, ref_name) &&
- (has_sha1_file(ref->old_sha1) ||
- will_fetch(head, ref->old_sha1))) {
- string_list_insert(ref_name, &new_refs);
+ /*
+ * If item is non-NULL here, then we previously saw a
+ * ref not followed by a peeled reference, so we need
+ * to check if it is a lightweight tag that we want to
+ * fetch.
+ */
+ if (item && !has_sha1_file(item->util) &&
+ !will_fetch(head, item->util))
+ item->util = NULL;
- rm = alloc_ref(ref_name);
- rm->peer_ref = alloc_ref(ref_name);
- hashcpy(rm->old_sha1, ref_sha1);
+ item = NULL;
- **tail = rm;
- *tail = &rm->next;
- }
- free(ref_name);
+ /* skip duplicates and refs that we already have */
+ if (string_list_has_string(&remote_refs, ref->name) ||
+ string_list_has_string(&existing_refs, ref->name))
+ continue;
+
+ item = string_list_insert(ref->name, &remote_refs);
+ item->util = (void *)ref->old_sha1;
}
string_list_clear(&existing_refs, 0);
- string_list_clear(&new_refs, 0);
+
+ /*
+ * We may have a final lightweight tag that needs to be
+ * checked to see if it needs fetching.
+ */
+ if (item && !has_sha1_file(item->util) &&
+ !will_fetch(head, item->util))
+ item->util = NULL;
+
+ /*
+ * For all the tags in the remote_refs string list, call
+ * add_to_tail to add them to the list of refs to be fetched
+ */
+ for_each_string_list(add_to_tail, &remote_refs, &data);
+
+ string_list_clear(&remote_refs, 0);
}
static void check_not_current_branch(struct ref *ref_map)
diff --git a/builtin-fsck.c b/builtin-fsck.c
index c58b0e337e..2d88e4570f 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -19,7 +19,7 @@ static int show_root;
static int show_tags;
static int show_unreachable;
static int include_reflogs = 1;
-static int check_full;
+static int check_full = 1;
static int check_strict;
static int keep_cache_objects;
static unsigned char head_sha1[20];
diff --git a/builtin-gc.c b/builtin-gc.c
index 7d3e9cc7a0..093517e390 100644
--- a/builtin-gc.c
+++ b/builtin-gc.c
@@ -216,10 +216,13 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
*/
if (!need_to_gc())
return 0;
- fprintf(stderr, "Auto packing your repository for optimum "
- "performance. You may also\n"
- "run \"git gc\" manually. See "
- "\"git help gc\" for more information.\n");
+ fprintf(stderr,
+ "Auto packing the repository for optimum performance.%s\n",
+ quiet
+ ? ""
+ : (" You may also\n"
+ "run \"git gc\" manually. See "
+ "\"git help gc\" for more information."));
} else
append_option(argv_repack,
prune_expire && !strcmp(prune_expire, "now")
diff --git a/builtin-log.c b/builtin-log.c
index 25e21ed415..fb5308220d 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -891,6 +891,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
struct patch_ids ids;
char *add_signoff = NULL;
struct strbuf buf = STRBUF_INIT;
+ int use_patch_format = 0;
const struct option builtin_format_patch_options[] = {
{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
"use [PATCH n/m] even with a single patch",
@@ -920,6 +921,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback },
OPT_BOOLEAN(0, "no-binary", &no_binary_diff,
"don't output binary diffs"),
+ OPT_BOOLEAN('p', NULL, &use_patch_format,
+ "show patch format instead of default (patch + stat)"),
OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
"don't include a patch matching a commit upstream"),
OPT_GROUP("Messaging"),
@@ -1027,8 +1030,10 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (argc > 1)
die ("unrecognized argument: %s", argv[1]);
- if (!rev.diffopt.output_format
- || rev.diffopt.output_format == DIFF_FORMAT_PATCH)
+ if (use_patch_format)
+ rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
+ else if (!rev.diffopt.output_format ||
+ rev.diffopt.output_format == DIFF_FORMAT_PATCH)
rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
@@ -1304,8 +1309,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
if (verbose) {
struct strbuf buf = STRBUF_INIT;
+ struct pretty_print_context ctx = {0};
pretty_print_commit(CMIT_FMT_ONELINE, commit,
- &buf, 0, NULL, NULL, 0, 0);
+ &buf, &ctx);
printf("%c %s %s\n", sign,
sha1_to_hex(commit->object.sha1), buf.buf);
strbuf_release(&buf);
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index c5c0407b0b..c9a03e5427 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -170,6 +170,10 @@ static void show_files(struct dir_struct *dir, const char *prefix)
if (show_cached | show_stage) {
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
+ int dtype = ce_to_dtype(ce);
+ if (dir->flags & DIR_SHOW_IGNORED &&
+ !excluded(dir, ce->name, &dtype))
+ continue;
if (show_unmerged && !ce_stage(ce))
continue;
if (ce->ce_flags & CE_UPDATE)
@@ -182,6 +186,10 @@ static void show_files(struct dir_struct *dir, const char *prefix)
struct cache_entry *ce = active_cache[i];
struct stat st;
int err;
+ int dtype = ce_to_dtype(ce);
+ if (dir->flags & DIR_SHOW_IGNORED &&
+ !excluded(dir, ce->name, &dtype))
+ continue;
if (ce->ce_flags & CE_UPDATE)
continue;
err = lstat(ce->name, &st);
diff --git a/builtin-merge.c b/builtin-merge.c
index e95c5dc717..c8d7bdecc4 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -43,6 +43,7 @@ static const char * const builtin_merge_usage[] = {
static int show_diffstat = 1, option_log, squash;
static int option_commit = 1, allow_fast_forward = 1;
+static int fast_forward_only;
static int allow_trivial = 1, have_message;
static struct strbuf merge_msg;
static struct commit_list *remoteheads;
@@ -167,6 +168,8 @@ static struct option builtin_merge_options[] = {
"perform a commit if the merge succeeds (default)"),
OPT_BOOLEAN(0, "ff", &allow_fast_forward,
"allow fast forward (default)"),
+ OPT_BOOLEAN(0, "ff-only", &fast_forward_only,
+ "abort if fast forward is not possible"),
OPT_CALLBACK('s', "strategy", &use_strategies, "strategy",
"merge strategy to use", option_parse_strategy),
OPT_CALLBACK('m', "message", &merge_msg, "message",
@@ -264,6 +267,7 @@ static void squash_message(void)
struct strbuf out = STRBUF_INIT;
struct commit_list *j;
int fd;
+ struct pretty_print_context ctx = {0};
printf("Squash commit -- not updating HEAD\n");
fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
@@ -285,13 +289,15 @@ static void squash_message(void)
if (prepare_revision_walk(&rev))
die("revision walk setup failed");
+ ctx.abbrev = rev.abbrev;
+ ctx.date_mode = rev.date_mode;
+
strbuf_addstr(&out, "Squashed commit of the following:\n");
while ((commit = get_revision(&rev)) != NULL) {
strbuf_addch(&out, '\n');
strbuf_addf(&out, "commit %s\n",
sha1_to_hex(commit->object.sha1));
- pretty_print_commit(rev.commit_format, commit, &out, rev.abbrev,
- NULL, NULL, rev.date_mode, 0);
+ pretty_print_commit(rev.commit_format, commit, &out, &ctx);
}
if (write(fd, out.buf, out.len) < 0)
die_errno("Writing SQUASH_MSG");
@@ -873,6 +879,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
option_commit = 0;
}
+ if (!allow_fast_forward && fast_forward_only)
+ die("You cannot combine --no-ff with --ff-only.");
+
if (!argc)
usage_with_options(builtin_merge_usage,
builtin_merge_options);
@@ -1039,7 +1048,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
* only one common.
*/
refresh_cache(REFRESH_QUIET);
- if (allow_trivial) {
+ if (allow_trivial && !fast_forward_only) {
/* See if it is really trivial. */
git_committer_info(IDENT_ERROR_ON_NO_NAME);
printf("Trying really trivial in-index merge...\n");
@@ -1078,6 +1087,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
}
}
+ if (fast_forward_only)
+ die("Not possible to fast forward, aborting.");
+
/* We are going to make a new commit. */
git_committer_info(IDENT_ERROR_ON_NO_NAME);
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 02f9246cdb..4c91e944c2 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1629,6 +1629,8 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
struct thread_params *p;
int i, ret, active_threads = 0;
+ if (!delta_search_threads) /* --threads=0 means autodetect */
+ delta_search_threads = online_cpus();
if (delta_search_threads <= 1) {
find_deltas(list, &list_size, window, depth, processed);
return;
@@ -2324,11 +2326,6 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
if (keep_unreachable && unpack_unreachable)
die("--keep-unreachable and --unpack-unreachable are incompatible.");
-#ifdef THREADED_DELTA_SEARCH
- if (!delta_search_threads) /* --threads=0 means autodetect */
- delta_search_threads = online_cpus();
-#endif
-
prepare_packed_git();
if (progress)
diff --git a/builtin-push.c b/builtin-push.c
index 8631c06ed6..752121f247 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -66,7 +66,6 @@ static void setup_push_tracking(void)
static void setup_default_push_refspecs(void)
{
- git_config(git_default_config, NULL);
switch (push_default) {
default:
case PUSH_DEFAULT_MATCHING:
@@ -173,7 +172,6 @@ int cmd_push(int argc, const char **argv, const char *prefix)
int tags = 0;
int rc;
const char *repo = NULL; /* default repository */
-
struct option options[] = {
OPT_BIT('q', "quiet", &flags, "be quiet", TRANSPORT_PUSH_QUIET),
OPT_BIT('v', "verbose", &flags, "be verbose", TRANSPORT_PUSH_VERBOSE),
@@ -191,6 +189,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
OPT_END()
};
+ git_config(git_default_config, NULL);
argc = parse_options(argc, argv, prefix, options, push_usage, 0);
if (tags)
diff --git a/builtin-receive-pack.c b/builtin-receive-pack.c
index b771fe9b20..e8bde02c27 100644
--- a/builtin-receive-pack.c
+++ b/builtin-receive-pack.c
@@ -28,6 +28,8 @@ static int transfer_unpack_limit = -1;
static int unpack_limit = 100;
static int report_status;
static int prefer_ofs_delta = 1;
+static int auto_update_server_info;
+static int auto_gc = 1;
static const char *head_name;
static char *capabilities_to_send;
@@ -88,6 +90,16 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
return 0;
}
+ if (strcmp(var, "receive.updateserverinfo") == 0) {
+ auto_update_server_info = git_config_bool(var, value);
+ return 0;
+ }
+
+ if (strcmp(var, "receive.autogc") == 0) {
+ auto_gc = git_config_bool(var, value);
+ return 0;
+ }
+
return git_default_config(var, value, cb);
}
@@ -672,6 +684,14 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
report(unpack_status);
run_receive_hook(post_receive_hook);
run_update_post_hook(commands);
+ if (auto_gc) {
+ const char *argv_gc_auto[] = {
+ "gc", "--auto", "--quiet", NULL,
+ };
+ run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
+ }
+ if (auto_update_server_info)
+ update_server_info(0);
}
return 0;
}
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 4ba1c12e0b..42cc8d8872 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -96,9 +96,10 @@ static void show_commit(struct commit *commit, void *data)
if (revs->verbose_header && commit->buffer) {
struct strbuf buf = STRBUF_INIT;
- pretty_print_commit(revs->commit_format, commit,
- &buf, revs->abbrev, NULL, NULL,
- revs->date_mode, 0);
+ struct pretty_print_context ctx = {0};
+ ctx.abbrev = revs->abbrev;
+ ctx.date_mode = revs->date_mode;
+ pretty_print_commit(revs->commit_format, commit, &buf, &ctx);
if (revs->graph) {
if (buf.len) {
if (revs->commit_format != CMIT_FMT_ONELINE)
diff --git a/builtin-shortlog.c b/builtin-shortlog.c
index 4d4a3c82d6..8aa63c7857 100644
--- a/builtin-shortlog.c
+++ b/builtin-shortlog.c
@@ -158,9 +158,12 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
sha1_to_hex(commit->object.sha1));
if (log->user_format) {
struct strbuf buf = STRBUF_INIT;
-
- pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf,
- DEFAULT_ABBREV, "", "", DATE_NORMAL, 0);
+ struct pretty_print_context ctx = {0};
+ ctx.abbrev = DEFAULT_ABBREV;
+ ctx.subject = "";
+ ctx.after_subject = "";
+ ctx.date_mode = DATE_NORMAL;
+ pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &buf, &ctx);
insert_one_record(log, author, buf.buf);
strbuf_release(&buf);
return;
diff --git a/builtin-show-branch.c b/builtin-show-branch.c
index be95930b78..9f13caa76d 100644
--- a/builtin-show-branch.c
+++ b/builtin-show-branch.c
@@ -293,8 +293,8 @@ static void show_one_commit(struct commit *commit, int no_name)
struct commit_name *name = commit->util;
if (commit->object.parsed) {
- pretty_print_commit(CMIT_FMT_ONELINE, commit,
- &pretty, 0, NULL, NULL, 0, 0);
+ struct pretty_print_context ctx = {0};
+ pretty_print_commit(CMIT_FMT_ONELINE, commit, &pretty, &ctx);
pretty_str = pretty.buf;
}
if (!prefixcmp(pretty_str, "[PATCH] "))
diff --git a/cache.h b/cache.h
index a5eeead1e2..71a731dbc9 100644
--- a/cache.h
+++ b/cache.h
@@ -396,6 +396,7 @@ extern const char *setup_git_directory_gently(int *);
extern const char *setup_git_directory(void);
extern const char *prefix_path(const char *prefix, int len, const char *path);
extern const char *prefix_filename(const char *prefix, int len, const char *path);
+extern int check_filename(const char *prefix, const char *name);
extern void verify_filename(const char *prefix, const char *name);
extern void verify_non_filename(const char *prefix, const char *name);
@@ -986,10 +987,12 @@ void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, i
* whitespace rules.
* used by both diff and apply
*/
-#define WS_TRAILING_SPACE 01
+#define WS_BLANK_AT_EOL 01
#define WS_SPACE_BEFORE_TAB 02
#define WS_INDENT_WITH_NON_TAB 04
#define WS_CR_AT_EOL 010
+#define WS_BLANK_AT_EOF 020
+#define WS_TRAILING_SPACE (WS_BLANK_AT_EOL|WS_BLANK_AT_EOF)
#define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB)
extern unsigned whitespace_rule_cfg;
extern unsigned whitespace_rule(const char *);
diff --git a/command-list.txt b/command-list.txt
index fb03a2ebb5..59b0adc39b 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -92,6 +92,7 @@ git-reflog ancillarymanipulators
git-relink ancillarymanipulators
git-remote ancillarymanipulators
git-repack ancillarymanipulators
+git-replace ancillarymanipulators
git-repo-config ancillarymanipulators deprecated
git-request-pull foreignscminterface
git-rerere ancillaryinterrogators
diff --git a/commit.c b/commit.c
index fedbd5e526..6393e1b362 100644
--- a/commit.c
+++ b/commit.c
@@ -132,8 +132,8 @@ struct commit_graft *read_graft_line(char *buf, int len)
int i;
struct commit_graft *graft = NULL;
- if (buf[len-1] == '\n')
- buf[--len] = 0;
+ while (len && isspace(buf[len-1]))
+ buf[--len] = '\0';
if (buf[0] == '#' || buf[0] == '\0')
return NULL;
if ((len + 1) % 41) {
diff --git a/commit.h b/commit.h
index f4fc5c5589..422f778f3f 100644
--- a/commit.h
+++ b/commit.h
@@ -63,6 +63,16 @@ enum cmit_fmt {
CMIT_FMT_UNSPECIFIED,
};
+struct pretty_print_context
+{
+ int abbrev;
+ const char *subject;
+ const char *after_subject;
+ enum date_mode date_mode;
+ int need_8bit_cte;
+ struct reflog_walk_info *reflog_info;
+};
+
extern int non_ascii(int);
extern int has_non_ascii(const char *text);
struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
@@ -70,13 +80,11 @@ extern char *reencode_commit_message(const struct commit *commit,
const char **encoding_p);
extern void get_commit_format(const char *arg, struct rev_info *);
extern void format_commit_message(const struct commit *commit,
- const void *format, struct strbuf *sb,
- enum date_mode dmode);
-extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,
- struct strbuf *,
- int abbrev, const char *subject,
- const char *after_subject, enum date_mode,
- int need_8bit_cte);
+ const char *format, struct strbuf *sb,
+ const struct pretty_print_context *context);
+extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
+ struct strbuf *sb,
+ const struct pretty_print_context *context);
void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
const char *line, enum date_mode dmode,
const char *encoding);
diff --git a/compat/bswap.h b/compat/bswap.h
index 5cc4acbfcc..279e0b48b1 100644
--- a/compat/bswap.h
+++ b/compat/bswap.h
@@ -28,6 +28,16 @@ static inline uint32_t default_swab32(uint32_t val)
} \
__res; })
+#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
+
+#include <stdlib.h>
+
+#define bswap32(x) _byteswap_ulong(x)
+
+#endif
+
+#ifdef bswap32
+
#undef ntohl
#undef htonl
#define ntohl(x) bswap32(x)
diff --git a/contrib/buildsystems/Generators/Vcproj.pm b/contrib/buildsystems/Generators/Vcproj.pm
index be94ba18d2..cfa74adcc2 100644
--- a/contrib/buildsystems/Generators/Vcproj.pm
+++ b/contrib/buildsystems/Generators/Vcproj.pm
@@ -178,6 +178,7 @@ sub createLibProject {
MinimalRebuild="true"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
+ ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
WarningLevel="3"
DebugInformationFormat="3"
/>
@@ -244,6 +245,7 @@ sub createLibProject {
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
+ ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
WarningLevel="3"
DebugInformationFormat="3"
/>
@@ -401,6 +403,7 @@ sub createAppProject {
MinimalRebuild="true"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
+ ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
WarningLevel="3"
DebugInformationFormat="3"
/>
@@ -472,6 +475,7 @@ sub createAppProject {
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
+ ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
WarningLevel="3"
DebugInformationFormat="3"
/>
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 7cf8557468..a0917d1809 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -958,6 +958,8 @@ __git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
_git_difftool ()
{
+ __git_has_doubledash && return
+
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--tool=*)
@@ -965,11 +967,15 @@ _git_difftool ()
return
;;
--*)
- __gitcomp "--tool="
+ __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
+ --base --ours --theirs
+ --no-renames --diff-filter= --find-copies-harder
+ --relative --ignore-submodules
+ --tool="
return
;;
esac
- COMPREPLY=()
+ __git_complete_file
}
__git_fetch_options="
@@ -1069,7 +1075,8 @@ _git_grep ()
return
;;
esac
- COMPREPLY=()
+
+ __gitcomp "$(__git_refs)"
}
_git_help ()
@@ -1217,7 +1224,7 @@ _git_log ()
__git_merge_options="
--no-commit --no-stat --log --no-log --squash --strategy
- --commit --stat --no-squash --ff --no-ff
+ --commit --stat --no-squash --ff --no-ff --ff-only
"
_git_merge ()
@@ -1322,8 +1329,18 @@ _git_rebase ()
fi
__git_complete_strategy && return
case "$cur" in
+ --whitespace=*)
+ __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
+ return
+ ;;
--*)
- __gitcomp "--onto --merge --strategy --interactive"
+ __gitcomp "
+ --onto --merge --strategy --interactive
+ --preserve-merges --stat --no-stat
+ --committer-date-is-author-date --ignore-date
+ --ignore-whitespace --whitespace=
+ "
+
return
esac
__gitcomp "$(__git_refs)"
diff --git a/contrib/emacs/git-blame.el b/contrib/emacs/git-blame.el
index 4fa70c5ad4..7f4c792978 100644
--- a/contrib/emacs/git-blame.el
+++ b/contrib/emacs/git-blame.el
@@ -80,6 +80,57 @@
(eval-when-compile (require 'cl)) ; to use `push', `pop'
+(defface git-blame-prefix-face
+ '((((background dark)) (:foreground "gray"
+ :background "black"))
+ (((background light)) (:foreground "gray"
+ :background "white"))
+ (t (:weight bold)))
+ "The face used for the hash prefix."
+ :group 'git-blame)
+
+(defgroup git-blame nil
+ "A minor mode showing Git blame information."
+ :group 'git
+ :link '(function-link git-blame-mode))
+
+
+(defcustom git-blame-use-colors t
+ "Use colors to indicate commits in `git-blame-mode'."
+ :type 'boolean
+ :group 'git-blame)
+
+(defcustom git-blame-prefix-format
+ "%h %20A:"
+ "The format of the prefix added to each line in `git-blame'
+mode. The format is passed to `format-spec' with the following format keys:
+
+ %h - the abbreviated hash
+ %H - the full hash
+ %a - the author name
+ %A - the author email
+ %c - the committer name
+ %C - the committer email
+ %s - the commit summary
+"
+ :group 'git-blame)
+
+(defcustom git-blame-mouseover-format
+ "%h %a %A: %s"
+ "The format of the description shown when pointing at a line in
+`git-blame' mode. The format string is passed to `format-spec'
+with the following format keys:
+
+ %h - the abbreviated hash
+ %H - the full hash
+ %a - the author name
+ %A - the author email
+ %c - the committer name
+ %C - the committer email
+ %s - the commit summary
+"
+ :group 'git-blame)
+
(defun git-blame-color-scale (&rest elements)
"Given a list, returns a list of triples formed with each
@@ -302,72 +353,69 @@ See also function `git-blame-mode'."
(src-line (string-to-number (match-string 2)))
(res-line (string-to-number (match-string 3)))
(num-lines (string-to-number (match-string 4))))
- (setq git-blame-current
- (if (string= hash "0000000000000000000000000000000000000000")
- nil
- (git-blame-new-commit
- hash src-line res-line num-lines))))
- (delete-region (point) (match-end 0))
- t)
- ((looking-at "filename \\(.+\\)\n")
- (let ((filename (match-string 1)))
- (git-blame-add-info "filename" filename))
- (delete-region (point) (match-end 0))
+ (delete-region (point) (match-end 0))
+ (setq git-blame-current (list (git-blame-new-commit hash)
+ src-line res-line num-lines)))
t)
((looking-at "\\([a-z-]+\\) \\(.+\\)\n")
(let ((key (match-string 1))
(value (match-string 2)))
- (git-blame-add-info key value))
- (delete-region (point) (match-end 0))
- t)
- ((looking-at "boundary\n")
- (setq git-blame-current nil)
- (delete-region (point) (match-end 0))
+ (delete-region (point) (match-end 0))
+ (git-blame-add-info (car git-blame-current) key value)
+ (when (string= key "filename")
+ (git-blame-create-overlay (car git-blame-current)
+ (caddr git-blame-current)
+ (cadddr git-blame-current))
+ (setq git-blame-current nil)))
t)
(t
nil)))
-(defun git-blame-new-commit (hash src-line res-line num-lines)
+(defun git-blame-new-commit (hash)
+ (with-current-buffer git-blame-file
+ (or (gethash hash git-blame-cache)
+ ;; Assign a random color to each new commit info
+ ;; Take care not to select the same color multiple times
+ (let* ((color (if git-blame-colors
+ (git-blame-random-pop git-blame-colors)
+ git-blame-ancient-color))
+ (info `(,hash (color . ,color))))
+ (puthash hash info git-blame-cache)
+ info))))
+
+(defun git-blame-create-overlay (info start-line num-lines)
(save-excursion
(set-buffer git-blame-file)
- (let ((info (gethash hash git-blame-cache))
- (inhibit-point-motion-hooks t)
+ (let ((inhibit-point-motion-hooks t)
(inhibit-modification-hooks t))
- (when (not info)
- ;; Assign a random color to each new commit info
- ;; Take care not to select the same color multiple times
- (let ((color (if git-blame-colors
- (git-blame-random-pop git-blame-colors)
- git-blame-ancient-color)))
- (setq info (list hash src-line res-line num-lines
- (git-describe-commit hash)
- (cons 'color color))))
- (puthash hash info git-blame-cache))
- (goto-line res-line)
- (while (> num-lines 0)
- (if (get-text-property (point) 'git-blame)
- (forward-line)
- (let* ((start (point))
- (end (progn (forward-line 1) (point)))
- (ovl (make-overlay start end)))
- (push ovl git-blame-overlays)
- (overlay-put ovl 'git-blame info)
- (overlay-put ovl 'help-echo hash)
+ (goto-line start-line)
+ (let* ((start (point))
+ (end (progn (forward-line num-lines) (point)))
+ (ovl (make-overlay start end))
+ (hash (car info))
+ (spec `((?h . ,(substring hash 0 6))
+ (?H . ,hash)
+ (?a . ,(git-blame-get-info info 'author))
+ (?A . ,(git-blame-get-info info 'author-mail))
+ (?c . ,(git-blame-get-info info 'committer))
+ (?C . ,(git-blame-get-info info 'committer-mail))
+ (?s . ,(git-blame-get-info info 'summary)))))
+ (push ovl git-blame-overlays)
+ (overlay-put ovl 'git-blame info)
+ (overlay-put ovl 'help-echo
+ (format-spec git-blame-mouseover-format spec))
+ (if git-blame-use-colors
(overlay-put ovl 'face (list :background
- (cdr (assq 'color (nthcdr 5 info)))))
- ;; the point-entered property doesn't seem to work in overlays
- ;;(overlay-put ovl 'point-entered
- ;; `(lambda (x y) (git-blame-identify ,hash)))
- (let ((modified (buffer-modified-p)))
- (put-text-property (if (= start 1) start (1- start)) (1- end)
- 'point-entered
- `(lambda (x y) (git-blame-identify ,hash)))
- (set-buffer-modified-p modified))))
- (setq num-lines (1- num-lines))))))
-
-(defun git-blame-add-info (key value)
- (if git-blame-current
- (nconc git-blame-current (list (cons (intern key) value)))))
+ (cdr (assq 'color (cdr info))))))
+ (overlay-put ovl 'line-prefix
+ (propertize (format-spec git-blame-prefix-format spec)
+ 'face 'git-blame-prefix-face))))))
+
+(defun git-blame-add-info (info key value)
+ (nconc info (list (cons (intern key) value))))
+
+(defun git-blame-get-info (info key)
+ (cdr (assq key (cdr info))))
(defun git-blame-current-commit ()
(let ((info (get-char-property (point) 'git-blame)))
diff --git a/contrib/fast-import/import-tars.perl b/contrib/fast-import/import-tars.perl
index 7001862bfd..95438e1ed4 100755
--- a/contrib/fast-import/import-tars.perl
+++ b/contrib/fast-import/import-tars.perl
@@ -20,7 +20,7 @@ use Getopt::Long;
my $metaext = '';
-die "usage: import-tars [--metainfo=extension] *.tar.{gz,bz2,Z}\n"
+die "usage: import-tars [--metainfo=extension] *.tar.{gz,bz2,lzma,xz,Z}\n"
unless GetOptions('metainfo=s' => \$metaext) && @ARGV;
my $branch_name = 'import-tars';
@@ -49,6 +49,9 @@ foreach my $tar_file (@ARGV)
} elsif ($tar_name =~ s/\.tar\.Z$//) {
open(I, '-|', 'uncompress', '-c', $tar_file)
or die "Unable to uncompress -c $tar_file: $!\n";
+ } elsif ($tar_name =~ s/\.(tar\.(lzma|xz)|(tlz|txz))$//) {
+ open(I, '-|', 'xz', '-dc', $tar_file)
+ or die "Unable to xz -dc $tar_file: $!\n";
} elsif ($tar_name =~ s/\.tar$//) {
open(I, $tar_file) or die "Unable to open $tar_file: $!\n";
} else {
diff --git a/diff.c b/diff.c
index e1be189742..3ad1f8c310 100644
--- a/diff.c
+++ b/diff.c
@@ -13,6 +13,7 @@
#include "utf8.h"
#include "userdiff.h"
#include "sigchain.h"
+#include "submodule.h"
#ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0
@@ -174,6 +175,175 @@ static struct diff_tempfile {
char tmp_path[PATH_MAX];
} diff_temp[2];
+typedef unsigned long (*sane_truncate_fn)(char *line, unsigned long len);
+
+struct emit_callback {
+ int color_diff;
+ unsigned ws_rule;
+ int blank_at_eof_in_preimage;
+ int blank_at_eof_in_postimage;
+ int lno_in_preimage;
+ int lno_in_postimage;
+ sane_truncate_fn truncate;
+ const char **label_path;
+ struct diff_words_data *diff_words;
+ int *found_changesp;
+ FILE *file;
+};
+
+static int count_lines(const char *data, int size)
+{
+ int count, ch, completely_empty = 1, nl_just_seen = 0;
+ count = 0;
+ while (0 < size--) {
+ ch = *data++;
+ if (ch == '\n') {
+ count++;
+ nl_just_seen = 1;
+ completely_empty = 0;
+ }
+ else {
+ nl_just_seen = 0;
+ completely_empty = 0;
+ }
+ }
+ if (completely_empty)
+ return 0;
+ if (!nl_just_seen)
+ count++; /* no trailing newline */
+ return count;
+}
+
+static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
+{
+ if (!DIFF_FILE_VALID(one)) {
+ mf->ptr = (char *)""; /* does not matter */
+ mf->size = 0;
+ return 0;
+ }
+ else if (diff_populate_filespec(one, 0))
+ return -1;
+
+ mf->ptr = one->data;
+ mf->size = one->size;
+ return 0;
+}
+
+static int count_trailing_blank(mmfile_t *mf, unsigned ws_rule)
+{
+ char *ptr = mf->ptr;
+ long size = mf->size;
+ int cnt = 0;
+
+ if (!size)
+ return cnt;
+ ptr += size - 1; /* pointing at the very end */
+ if (*ptr != '\n')
+ ; /* incomplete line */
+ else
+ ptr--; /* skip the last LF */
+ while (mf->ptr < ptr) {
+ char *prev_eol;
+ for (prev_eol = ptr; mf->ptr <= prev_eol; prev_eol--)
+ if (*prev_eol == '\n')
+ break;
+ if (!ws_blank_line(prev_eol + 1, ptr - prev_eol, ws_rule))
+ break;
+ cnt++;
+ ptr = prev_eol - 1;
+ }
+ return cnt;
+}
+
+static void check_blank_at_eof(mmfile_t *mf1, mmfile_t *mf2,
+ struct emit_callback *ecbdata)
+{
+ int l1, l2, at;
+ unsigned ws_rule = ecbdata->ws_rule;
+ l1 = count_trailing_blank(mf1, ws_rule);
+ l2 = count_trailing_blank(mf2, ws_rule);
+ if (l2 <= l1) {
+ ecbdata->blank_at_eof_in_preimage = 0;
+ ecbdata->blank_at_eof_in_postimage = 0;
+ return;
+ }
+ at = count_lines(mf1->ptr, mf1->size);
+ ecbdata->blank_at_eof_in_preimage = (at - l1) + 1;
+
+ at = count_lines(mf2->ptr, mf2->size);
+ ecbdata->blank_at_eof_in_postimage = (at - l2) + 1;
+}
+
+static void emit_line_0(FILE *file, const char *set, const char *reset,
+ int first, const char *line, int len)
+{
+ int has_trailing_newline, has_trailing_carriage_return;
+ int nofirst;
+
+ if (len == 0) {
+ has_trailing_newline = (first == '\n');
+ has_trailing_carriage_return = (!has_trailing_newline &&
+ (first == '\r'));
+ nofirst = has_trailing_newline || has_trailing_carriage_return;
+ } else {
+ 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--;
+ nofirst = 0;
+ }
+
+ fputs(set, file);
+
+ if (!nofirst)
+ fputc(first, file);
+ fwrite(line, len, 1, file);
+ fputs(reset, file);
+ if (has_trailing_carriage_return)
+ fputc('\r', file);
+ if (has_trailing_newline)
+ fputc('\n', file);
+}
+
+static void emit_line(FILE *file, const char *set, const char *reset,
+ const char *line, int len)
+{
+ emit_line_0(file, set, reset, line[0], line+1, len-1);
+}
+
+static int new_blank_line_at_eof(struct emit_callback *ecbdata, const char *line, int len)
+{
+ if (!((ecbdata->ws_rule & WS_BLANK_AT_EOF) &&
+ ecbdata->blank_at_eof_in_preimage &&
+ ecbdata->blank_at_eof_in_postimage &&
+ ecbdata->blank_at_eof_in_preimage <= ecbdata->lno_in_preimage &&
+ ecbdata->blank_at_eof_in_postimage <= ecbdata->lno_in_postimage))
+ return 0;
+ return ws_blank_line(line, len, ecbdata->ws_rule);
+}
+
+static void emit_add_line(const char *reset,
+ struct emit_callback *ecbdata,
+ const char *line, int len)
+{
+ const char *ws = diff_get_color(ecbdata->color_diff, DIFF_WHITESPACE);
+ const char *set = diff_get_color(ecbdata->color_diff, DIFF_FILE_NEW);
+
+ if (!*ws)
+ emit_line_0(ecbdata->file, set, reset, '+', line, len);
+ else if (new_blank_line_at_eof(ecbdata, line, len))
+ /* Blank line at EOF - paint '+' as well */
+ emit_line_0(ecbdata->file, ws, reset, '+', line, len);
+ else {
+ /* Emit just the prefix, then the rest. */
+ emit_line_0(ecbdata->file, set, reset, '+', "", 0);
+ ws_check_emit(line, len, ecbdata->ws_rule,
+ ecbdata->file, set, reset, ws);
+ }
+}
+
static struct diff_tempfile *claim_diff_tempfile(void) {
int i;
for (i = 0; i < ARRAY_SIZE(diff_temp); i++)
@@ -201,29 +371,6 @@ static void remove_tempfile_on_signal(int signo)
raise(signo);
}
-static int count_lines(const char *data, int size)
-{
- int count, ch, completely_empty = 1, nl_just_seen = 0;
- count = 0;
- while (0 < size--) {
- ch = *data++;
- if (ch == '\n') {
- count++;
- nl_just_seen = 1;
- completely_empty = 0;
- }
- else {
- nl_just_seen = 0;
- completely_empty = 0;
- }
- }
- if (completely_empty)
- return 0;
- if (!nl_just_seen)
- count++; /* no trailing newline */
- return count;
-}
-
static void print_line_count(FILE *file, int count)
{
switch (count) {
@@ -239,26 +386,36 @@ static void print_line_count(FILE *file, int count)
}
}
-static void copy_file_with_prefix(FILE *file,
- int prefix, const char *data, int size,
- const char *set, const char *reset)
+static void emit_rewrite_lines(struct emit_callback *ecb,
+ int prefix, const char *data, int size)
{
- int ch, nl_just_seen = 1;
- while (0 < size--) {
- ch = *data++;
- if (nl_just_seen) {
- fputs(set, file);
- putc(prefix, file);
+ const char *endp = NULL;
+ static const char *nneof = " No newline at end of file\n";
+ const char *old = diff_get_color(ecb->color_diff, DIFF_FILE_OLD);
+ const char *reset = diff_get_color(ecb->color_diff, DIFF_RESET);
+
+ while (0 < size) {
+ int len;
+
+ endp = memchr(data, '\n', size);
+ len = endp ? (endp - data + 1) : size;
+ if (prefix != '+') {
+ ecb->lno_in_preimage++;
+ emit_line_0(ecb->file, old, reset, '-',
+ data, len);
+ } else {
+ ecb->lno_in_postimage++;
+ emit_add_line(reset, ecb, data, len);
}
- if (ch == '\n') {
- nl_just_seen = 1;
- fputs(reset, file);
- } else
- nl_just_seen = 0;
- putc(ch, file);
+ size -= len;
+ data += len;
+ }
+ if (!endp) {
+ const char *plain = diff_get_color(ecb->color_diff,
+ DIFF_PLAIN);
+ emit_line_0(ecb->file, plain, reset, '\\',
+ nneof, strlen(nneof));
}
- if (!nl_just_seen)
- fprintf(file, "%s\n\\ No newline at end of file\n", reset);
}
static void emit_rewrite_diff(const char *name_a,
@@ -274,13 +431,12 @@ static void emit_rewrite_diff(const char *name_a,
const char *name_a_tab, *name_b_tab;
const char *metainfo = diff_get_color(color_diff, DIFF_METAINFO);
const char *fraginfo = diff_get_color(color_diff, DIFF_FRAGINFO);
- const char *old = diff_get_color(color_diff, DIFF_FILE_OLD);
- 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;
const char *data_one, *data_two;
size_t size_one, size_two;
+ struct emit_callback ecbdata;
if (diff_mnemonic_prefix && DIFF_OPT_TST(o, REVERSE_DIFF)) {
a_prefix = o->b_prefix;
@@ -321,6 +477,22 @@ static void emit_rewrite_diff(const char *name_a,
size_two = two->size;
}
+ memset(&ecbdata, 0, sizeof(ecbdata));
+ ecbdata.color_diff = color_diff;
+ ecbdata.found_changesp = &o->found_changes;
+ ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a);
+ ecbdata.file = o->file;
+ if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
+ mmfile_t mf1, mf2;
+ mf1.ptr = (char *)data_one;
+ mf2.ptr = (char *)data_two;
+ mf1.size = size_one;
+ mf2.size = size_two;
+ check_blank_at_eof(&mf1, &mf2, &ecbdata);
+ }
+ ecbdata.lno_in_preimage = 1;
+ ecbdata.lno_in_postimage = 1;
+
lc_a = count_lines(data_one, size_one);
lc_b = count_lines(data_two, size_two);
fprintf(o->file,
@@ -332,24 +504,9 @@ static void emit_rewrite_diff(const char *name_a,
print_line_count(o->file, lc_b);
fprintf(o->file, " @@%s\n", reset);
if (lc_a)
- copy_file_with_prefix(o->file, '-', data_one, size_one, old, reset);
+ emit_rewrite_lines(&ecbdata, '-', data_one, size_one);
if (lc_b)
- copy_file_with_prefix(o->file, '+', data_two, size_two, new, reset);
-}
-
-static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
-{
- if (!DIFF_FILE_VALID(one)) {
- mf->ptr = (char *)""; /* does not matter */
- mf->size = 0;
- return 0;
- }
- else if (diff_populate_filespec(one, 0))
- return -1;
-
- mf->ptr = one->data;
- mf->size = one->size;
- return 0;
+ emit_rewrite_lines(&ecbdata, '+', data_two, size_two);
}
struct diff_words_buffer {
@@ -529,18 +686,6 @@ static void diff_words_show(struct diff_words_data *diff_words)
diff_words->minus.text.size = diff_words->plus.text.size = 0;
}
-typedef unsigned long (*sane_truncate_fn)(char *line, unsigned long len);
-
-struct emit_callback {
- int nparents, color_diff;
- unsigned ws_rule;
- sane_truncate_fn truncate;
- const char **label_path;
- struct diff_words_data *diff_words;
- int *found_changesp;
- FILE *file;
-};
-
static void free_diff_words_data(struct emit_callback *ecbdata)
{
if (ecbdata->diff_words) {
@@ -566,42 +711,6 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix)
return "";
}
-static void emit_line(FILE *file, const char *set, const char *reset, const char *line, int len)
-{
- 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);
-}
-
-static void emit_add_line(const char *reset, struct emit_callback *ecbdata, const char *line, int len)
-{
- const char *ws = diff_get_color(ecbdata->color_diff, DIFF_WHITESPACE);
- const char *set = diff_get_color(ecbdata->color_diff, DIFF_FILE_NEW);
-
- if (!*ws)
- emit_line(ecbdata->file, set, reset, line, len);
- else {
- /* Emit just the prefix, then the rest. */
- emit_line(ecbdata->file, set, reset, line, ecbdata->nparents);
- ws_check_emit(line + ecbdata->nparents,
- len - ecbdata->nparents, ecbdata->ws_rule,
- ecbdata->file, set, reset, ws);
- }
-}
-
static unsigned long sane_truncate_line(struct emit_callback *ecb, char *line, unsigned long len)
{
const char *cp;
@@ -620,10 +729,23 @@ static unsigned long sane_truncate_line(struct emit_callback *ecb, char *line, u
return allot - l;
}
+static void find_lno(const char *line, struct emit_callback *ecbdata)
+{
+ const char *p;
+ ecbdata->lno_in_preimage = 0;
+ ecbdata->lno_in_postimage = 0;
+ p = strchr(line, '-');
+ if (!p)
+ return; /* cannot happen */
+ ecbdata->lno_in_preimage = strtol(p + 1, NULL, 10);
+ p = strchr(p, '+');
+ if (!p)
+ return; /* cannot happen */
+ ecbdata->lno_in_postimage = strtol(p + 1, NULL, 10);
+}
+
static void fn_out_consume(void *priv, char *line, unsigned long len)
{
- int i;
- int color;
struct emit_callback *ecbdata = priv;
const char *meta = diff_get_color(ecbdata->color_diff, DIFF_METAINFO);
const char *plain = diff_get_color(ecbdata->color_diff, DIFF_PLAIN);
@@ -650,14 +772,9 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
len = 1;
}
- /* This is not really necessary for now because
- * this codepath only deals with two-way diffs.
- */
- for (i = 0; i < len && line[i] == '@'; i++)
- ;
- if (2 <= i && i < len && line[i] == ' ') {
- ecbdata->nparents = i - 1;
+ if (line[0] == '@') {
len = sane_truncate_line(ecbdata, line, len);
+ find_lno(line, ecbdata);
emit_line(ecbdata->file,
diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO),
reset, line, len);
@@ -666,15 +783,11 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
return;
}
- if (len < ecbdata->nparents) {
+ if (len < 1) {
emit_line(ecbdata->file, reset, reset, line, len);
return;
}
- color = DIFF_PLAIN;
- if (ecbdata->diff_words && ecbdata->nparents != 1)
- /* fall back to normal diff */
- free_diff_words_data(ecbdata);
if (ecbdata->diff_words) {
if (line[0] == '-') {
diff_words_append(line, len,
@@ -693,20 +806,19 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
emit_line(ecbdata->file, plain, reset, line, len);
return;
}
- for (i = 0; i < ecbdata->nparents && len; i++) {
- if (line[i] == '-')
- color = DIFF_FILE_OLD;
- else if (line[i] == '+')
- color = DIFF_FILE_NEW;
- }
- if (color != DIFF_FILE_NEW) {
- emit_line(ecbdata->file,
- diff_get_color(ecbdata->color_diff, color),
- reset, line, len);
- return;
+ if (line[0] != '+') {
+ const char *color =
+ diff_get_color(ecbdata->color_diff,
+ line[0] == '-' ? DIFF_FILE_OLD : DIFF_PLAIN);
+ ecbdata->lno_in_preimage++;
+ if (line[0] == ' ')
+ ecbdata->lno_in_postimage++;
+ emit_line(ecbdata->file, color, reset, line, len);
+ } else {
+ ecbdata->lno_in_postimage++;
+ emit_add_line(reset, ecbdata, line + 1, len - 1);
}
- emit_add_line(reset, ecbdata, line, len);
}
static char *pprint_rename(const char *a, const char *b)
@@ -999,7 +1111,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
total_files, adds, dels);
}
-static void show_shortstats(struct diffstat_t* data, struct diff_options *options)
+static void show_shortstats(struct diffstat_t *data, struct diff_options *options)
{
int i, adds = 0, dels = 0, total_files = data->nr;
@@ -1211,7 +1323,6 @@ struct checkdiff_t {
struct diff_options *o;
unsigned ws_rule;
unsigned status;
- int trailing_blanks_start;
};
static int is_conflict_marker(const char *line, unsigned long len)
@@ -1255,10 +1366,6 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
if (line[0] == '+') {
unsigned bad;
data->lineno++;
- if (!ws_blank_line(line + 1, len - 1, data->ws_rule))
- data->trailing_blanks_start = 0;
- else if (!data->trailing_blanks_start)
- data->trailing_blanks_start = data->lineno;
if (is_conflict_marker(line + 1, len - 1)) {
data->status |= 1;
fprintf(data->o->file,
@@ -1278,14 +1385,12 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
data->o->file, set, reset, ws);
} else if (line[0] == ' ') {
data->lineno++;
- data->trailing_blanks_start = 0;
} else if (line[0] == '@') {
char *plus = strchr(line, '+');
if (plus)
data->lineno = strtol(plus, NULL, 10) - 1;
else
die("invalid diff");
- data->trailing_blanks_start = 0;
}
}
@@ -1453,6 +1558,17 @@ static void builtin_diff(const char *name_a,
const char *a_prefix, *b_prefix;
const char *textconv_one = NULL, *textconv_two = NULL;
+ if (DIFF_OPT_TST(o, SUBMODULE_LOG) &&
+ (!one->mode || S_ISGITLINK(one->mode)) &&
+ (!two->mode || S_ISGITLINK(two->mode))) {
+ const char *del = diff_get_color_opt(o, DIFF_FILE_OLD);
+ const char *add = diff_get_color_opt(o, DIFF_FILE_NEW);
+ show_submodule_summary(o->file, one ? one->path : two->path,
+ one->sha1, two->sha1,
+ del, add, reset);
+ return;
+ }
+
if (DIFF_OPT_TST(o, ALLOW_TEXTCONV)) {
textconv_one = get_textconv(one);
textconv_two = get_textconv(two);
@@ -1562,6 +1678,8 @@ static void builtin_diff(const char *name_a,
ecbdata.color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
ecbdata.found_changesp = &o->found_changes;
ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a);
+ if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
+ check_blank_at_eof(&mf1, &mf2, &ecbdata);
ecbdata.file = o->file;
xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
xecfg.ctxlen = o->context;
@@ -1704,11 +1822,22 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
&xpp, &xecfg, &ecb);
- if ((data.ws_rule & WS_TRAILING_SPACE) &&
- data.trailing_blanks_start) {
- fprintf(o->file, "%s:%d: ends with blank lines.\n",
- data.filename, data.trailing_blanks_start);
- data.status = 1; /* report errors */
+ if (data.ws_rule & WS_BLANK_AT_EOF) {
+ struct emit_callback ecbdata;
+ int blank_at_eof;
+
+ ecbdata.ws_rule = data.ws_rule;
+ check_blank_at_eof(&mf1, &mf2, &ecbdata);
+ blank_at_eof = ecbdata.blank_at_eof_in_preimage;
+
+ if (blank_at_eof) {
+ static char *err;
+ if (!err)
+ err = whitespace_error_string(WS_BLANK_AT_EOF);
+ fprintf(o->file, "%s:%d: %s.\n",
+ data.filename, blank_at_eof, err);
+ data.status = 1; /* report errors */
+ }
}
}
free_and_return:
@@ -2640,6 +2769,12 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
else if (!strcmp(arg, "--ignore-submodules"))
DIFF_OPT_SET(options, IGNORE_SUBMODULES);
+ else if (!strcmp(arg, "--submodule"))
+ DIFF_OPT_SET(options, SUBMODULE_LOG);
+ else if (!prefixcmp(arg, "--submodule=")) {
+ if (!strcmp(arg + 12, "log"))
+ DIFF_OPT_SET(options, SUBMODULE_LOG);
+ }
/* misc options */
else if (!strcmp(arg, "-z"))
diff --git a/diff.h b/diff.h
index 6616877ee5..2740421cfe 100644
--- a/diff.h
+++ b/diff.h
@@ -66,6 +66,9 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_OPT_DIRSTAT_CUMULATIVE (1 << 19)
#define DIFF_OPT_DIRSTAT_BY_FILE (1 << 20)
#define DIFF_OPT_ALLOW_TEXTCONV (1 << 21)
+
+#define DIFF_OPT_SUBMODULE_LOG (1 << 23)
+
#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag)
#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag)
diff --git a/git-bisect.sh b/git-bisect.sh
index 6f6f03966f..8b3c5858a9 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -13,8 +13,8 @@ git bisect skip [(<rev>|<range>)...]
mark <rev>... untestable revisions.
git bisect next
find next bisection to test and check it out.
-git bisect reset [<branch>]
- finish bisection search and go back to branch.
+git bisect reset [<commit>]
+ finish bisection search and go back to commit.
git bisect visualize
show bisect status in gitk.
git bisect replay <logfile>
@@ -311,8 +311,8 @@ bisect_reset() {
}
case "$#" in
0) branch=$(cat "$GIT_DIR/BISECT_START") ;;
- 1) git show-ref --verify --quiet -- "refs/heads/$1" ||
- die "$1 does not seem to be a valid branch"
+ 1) git rev-parse --quiet --verify "$1^{commit}" > /dev/null ||
+ die "'$1' is not a valid commit"
branch="$1" ;;
*)
usage ;;
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 1ad20ac964..a7d215c8aa 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -579,10 +579,21 @@ sub get_headref ($) {
return $r;
}
+my $user_filename_prepend = '';
+sub munge_user_filename {
+ my $name = shift;
+ return File::Spec->file_name_is_absolute($name) ?
+ $name :
+ $user_filename_prepend . $name;
+}
+
-d $git_tree
or mkdir($git_tree,0777)
or die "Could not create $git_tree: $!";
-chdir($git_tree);
+if ($git_tree ne '.') {
+ $user_filename_prepend = getwd() . '/';
+ chdir($git_tree);
+}
my $last_branch = "";
my $orig_branch = "";
@@ -644,7 +655,7 @@ unless (-d $git_dir) {
-f "$git_dir/cvs-authors" and
read_author_info("$git_dir/cvs-authors");
if ($opt_A) {
- read_author_info($opt_A);
+ read_author_info(munge_user_filename($opt_A));
write_author_info("$git_dir/cvs-authors");
}
@@ -679,7 +690,7 @@ unless ($opt_P) {
$? == 0 or die "git-cvsimport: fatal: cvsps reported error\n";
close $cvspsfh;
} else {
- $cvspsfile = $opt_P;
+ $cvspsfile = munge_user_filename($opt_P);
}
open(CVS, "<$cvspsfile") or die $!;
diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh
index 14b92ba786..037a1f2c21 100755
--- a/git-gui/git-gui.sh
+++ b/git-gui/git-gui.sh
@@ -745,6 +745,8 @@ set default_config(gui.newbranchtemplate) {}
set default_config(gui.spellingdictionary) {}
set default_config(gui.fontui) [font configure font_ui]
set default_config(gui.fontdiff) [font configure font_diff]
+# TODO: this option should be added to the git-config documentation
+set default_config(gui.maxfilesdisplayed) 5000
set font_descs {
{fontui font_ui {mc "Main Font"}}
{fontdiff font_diff {mc "Diff/Console Font"}}
@@ -1132,6 +1134,7 @@ set current_branch {}
set is_detached 0
set current_diff_path {}
set is_3way_diff 0
+set is_submodule_diff 0
set is_conflict_diff 0
set selected_commit_type new
set diff_empty_count 0
@@ -1698,10 +1701,12 @@ proc display_all_files_helper {w path icon_name m} {
$w insert end "[escape_path $path]\n"
}
+set files_warning 0
proc display_all_files {} {
global ui_index ui_workdir
global file_states file_lists
global last_clicked
+ global files_warning
$ui_index conf -state normal
$ui_workdir conf -state normal
@@ -1713,7 +1718,18 @@ proc display_all_files {} {
set file_lists($ui_index) [list]
set file_lists($ui_workdir) [list]
- foreach path [lsort [array names file_states]] {
+ set to_display [lsort [array names file_states]]
+ set display_limit [get_config gui.maxfilesdisplayed]
+ if {[llength $to_display] > $display_limit} {
+ if {!$files_warning} {
+ # do not repeatedly warn:
+ set files_warning 1
+ info_popup [mc "Displaying only %s of %s files." \
+ $display_limit [llength $to_display]]
+ }
+ set to_display [lrange $to_display 0 [expr {$display_limit-1}]]
+ }
+ foreach path $to_display {
set s $file_states($path)
set m [lindex $s 0]
set icon_name [lindex $s 1]
@@ -2010,6 +2026,19 @@ proc do_quit {{rc {1}}} {
# -- Stash our current window geometry into this repository.
#
+ set cfg_wmstate [wm state .]
+ if {[catch {set rc_wmstate $repo_config(gui.wmstate)}]} {
+ set rc_wmstate {}
+ }
+ if {$cfg_wmstate ne $rc_wmstate} {
+ catch {git config gui.wmstate $cfg_wmstate}
+ }
+ if {$cfg_wmstate eq {zoomed}} {
+ # on Windows wm geometry will lie about window
+ # position (but not size) when window is zoomed
+ # restore the window before querying wm geometry
+ wm state . normal
+ }
set cfg_geometry [list]
lappend cfg_geometry [wm geometry .]
lappend cfg_geometry [lindex [.vpane sash coord 0] 0]
@@ -3054,7 +3083,7 @@ frame .vpane.lower.diff.body
set ui_diff .vpane.lower.diff.body.t
text $ui_diff -background white -foreground black \
-borderwidth 0 \
- -width 80 -height 15 -wrap none \
+ -width 80 -height 5 -wrap none \
-font font_diff \
-xscrollcommand {.vpane.lower.diff.body.sbx set} \
-yscrollcommand {.vpane.lower.diff.body.sby set} \
@@ -3212,7 +3241,7 @@ proc popup_diff_menu {ctxm ctxmmg x y X Y} {
set l [mc "Stage Hunk For Commit"]
set t [mc "Stage Line For Commit"]
}
- if {$::is_3way_diff
+ if {$::is_3way_diff || $::is_submodule_diff
|| $current_diff_path eq {}
|| {__} eq $state
|| {_O} eq $state
@@ -3249,6 +3278,14 @@ wm geometry . [lindex $gm 0]
unset gm
}
+# -- Load window state
+#
+catch {
+set gws $repo_config(gui.wmstate)
+wm state . $gws
+unset gws
+}
+
# -- Key Bindings
#
bind $ui_comm <$M1B-Key-Return> {do_commit;break}
diff --git a/git-gui/lib/diff.tcl b/git-gui/lib/diff.tcl
index 925b3f56c1..bd5d189ed1 100644
--- a/git-gui/lib/diff.tcl
+++ b/git-gui/lib/diff.tcl
@@ -255,7 +255,7 @@ proc show_other_diff {path w m cont_info} {
proc start_show_diff {cont_info {add_opts {}}} {
global file_states file_lists
- global is_3way_diff diff_active repo_config
+ global is_3way_diff is_submodule_diff diff_active repo_config
global ui_diff ui_index ui_workdir
global current_diff_path current_diff_side current_diff_header
@@ -265,6 +265,7 @@ proc start_show_diff {cont_info {add_opts {}}} {
set s $file_states($path)
set m [lindex $s 0]
set is_3way_diff 0
+ set is_submodule_diff 0
set diff_active 1
set current_diff_header {}
@@ -295,6 +296,16 @@ proc start_show_diff {cont_info {add_opts {}}} {
lappend cmd $path
}
+ if {[string match {160000 *} [lindex $s 2]]
+ || [string match {160000 *} [lindex $s 3]]} {
+ set is_submodule_diff 1
+ if {$w eq $ui_index} {
+ set cmd [list submodule summary --cached -- $path]
+ } else {
+ set cmd [list submodule summary --files -- $path]
+ }
+ }
+
if {[catch {set fd [eval git_read --nice $cmd]} err]} {
set diff_active 0
unlock_index
@@ -312,7 +323,7 @@ proc start_show_diff {cont_info {add_opts {}}} {
}
proc read_diff {fd cont_info} {
- global ui_diff diff_active
+ global ui_diff diff_active is_submodule_diff
global is_3way_diff is_conflict_diff current_diff_header
global current_diff_queue
global diff_empty_count
@@ -374,6 +385,23 @@ proc read_diff {fd cont_info} {
set tags {}
}
}
+ } elseif {$is_submodule_diff} {
+ if {$line == ""} continue
+ if {[regexp {^\* } $line]} {
+ set line [string replace $line 0 1 {Submodule }]
+ set tags d_@
+ } else {
+ set op [string range $line 0 2]
+ switch -- $op {
+ { <} {set tags d_-}
+ { >} {set tags d_+}
+ { W} {set tags {}}
+ default {
+ puts "error: Unhandled submodule diff marker: {$op}"
+ set tags {}
+ }
+ }
+ }
} else {
set op [string index $line 0]
switch -- $op {
diff --git a/git-gui/lib/remote_branch_delete.tcl b/git-gui/lib/remote_branch_delete.tcl
index 4e02fc0d39..31e0947488 100644
--- a/git-gui/lib/remote_branch_delete.tcl
+++ b/git-gui/lib/remote_branch_delete.tcl
@@ -208,13 +208,15 @@ method _delete {} {
return
}
- if {[tk_messageBox \
- -icon warning \
- -type yesno \
- -title [wm title $w] \
- -parent $w \
- -message [mc "Recovering deleted branches is difficult.\n\nDelete the selected branches?"]] ne yes} {
- return
+ if {$checktype ne {head}} {
+ if {[tk_messageBox \
+ -icon warning \
+ -type yesno \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Recovering deleted branches is difficult.\n\nDelete the selected branches?"]] ne yes} {
+ return
+ }
}
destroy $w
diff --git a/git-gui/po/el.po b/git-gui/po/el.po
new file mode 100644
index 0000000000..3634ba469d
--- /dev/null
+++ b/git-gui/po/el.po
@@ -0,0 +1,2005 @@
+# Translation of git-gui to Greek
+# Copyright (C) 2009 Jimmy Angelakos
+# This file is distributed under the same license as the git-gui package.
+# Jimmy Angelakos <vyruss@hellug.gr>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: el\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-03-14 07:18+0100\n"
+"PO-Revision-Date: 2009-06-23 21:33+0300\n"
+"Last-Translator: Jimmy Angelakos <vyruss@hellug.gr>\n"
+"Language-Team: Greek <i18n@lists.hellug.gr>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Lokalize 0.3\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
+msgid "git-gui: fatal error"
+msgstr "git-gui: κρίσιμο σφάλμα"
+
+#: git-gui.sh:593
+#, tcl-format
+msgid "Invalid font specified in %s:"
+msgstr "Μη έγκυρη γραμματοσειρά στο %s:"
+
+#: git-gui.sh:620
+msgid "Main Font"
+msgstr "Κύρια Γραμματοσειρά"
+
+#: git-gui.sh:621
+msgid "Diff/Console Font"
+msgstr "Γραμματοσειρά Διαφοράς/Κονσόλας"
+
+#: git-gui.sh:635
+msgid "Cannot find git in PATH."
+msgstr "Δε βρέθηκε το git στο PATH."
+
+#: git-gui.sh:662
+msgid "Cannot parse Git version string:"
+msgstr "Αδύνατη η ανάγνωση στοιχειοσειράς έκδοσης Git:"
+
+#: git-gui.sh:680
+#, tcl-format
+msgid ""
+"Git version cannot be determined.\n"
+"\n"
+"%s claims it is version '%s'.\n"
+"\n"
+"%s requires at least Git 1.5.0 or later.\n"
+"\n"
+"Assume '%s' is version 1.5.0?\n"
+msgstr ""
+"Δε μπορεί να ανιχνευτεί η έκδοση του Git. \n"
+"\n"
+"Το %s υποστηρίζει πως είναι η έκδοση '%s'.\n"
+"\n"
+"Το %s απαιτεί τουλάχιστον Git 1.5.0 ή πιό πρόσφατη.\n"
+"\n"
+"Να υποτεθεί πως το '%s' είναι η έκδοση 1.5.0;\n"
+
+#: git-gui.sh:918
+msgid "Git directory not found:"
+msgstr "Δε βρέθηκε φάκελος Git:"
+
+#: git-gui.sh:925
+msgid "Cannot move to top of working directory:"
+msgstr "Δεν είναι δυνατή η μετακίνηση στην κορυφή του φακέλου εργασίας:"
+
+#: git-gui.sh:932
+msgid "Cannot use funny .git directory:"
+msgstr "Δεν είναι δυνατή η χρήση περίεργου φακέλου .git:"
+
+#: git-gui.sh:937
+msgid "No working directory"
+msgstr "Δεν υπάρχει φάκελος εργασίας"
+
+#: git-gui.sh:1084 lib/checkout_op.tcl:283
+msgid "Refreshing file status..."
+msgstr "Ανανέωση κατάστασης αρχείου..."
+
+#: git-gui.sh:1149
+msgid "Scanning for modified files ..."
+msgstr "Ανίχνευση για τροποποιημένα αρχεία..."
+
+#: git-gui.sh:1324 lib/browser.tcl:246
+msgid "Ready."
+msgstr "Έτοιμο."
+
+#: git-gui.sh:1590
+msgid "Unmodified"
+msgstr "Μη τροποποιημένο"
+
+#: git-gui.sh:1592
+msgid "Modified, not staged"
+msgstr "Τροποποιημένο, μη σταδιοποιημένο"
+
+#: git-gui.sh:1593 git-gui.sh:1598
+msgid "Staged for commit"
+msgstr "Σταδιοποιημένο προς υποβολή"
+
+#: git-gui.sh:1594 git-gui.sh:1599
+msgid "Portions staged for commit"
+msgstr "Μέρη σταδιοποιημένα προς υποβολή"
+
+#: git-gui.sh:1595 git-gui.sh:1600
+msgid "Staged for commit, missing"
+msgstr "Σταδιοποιημένο προς υποβολή, λείπει"
+
+#: git-gui.sh:1597
+msgid "Untracked, not staged"
+msgstr "Μη παρακολουθούμενο, μη σταδιοποιημένο"
+
+#: git-gui.sh:1602
+msgid "Missing"
+msgstr "Λείπει"
+
+#: git-gui.sh:1603
+msgid "Staged for removal"
+msgstr "Σταδιοποιημένο προς αφαίρεση"
+
+#: git-gui.sh:1604
+msgid "Staged for removal, still present"
+msgstr "Σταδιοποιημένο προς αφαίρεση, ακόμα παρόν"
+
+#: git-gui.sh:1606 git-gui.sh:1607 git-gui.sh:1608 git-gui.sh:1609
+msgid "Requires merge resolution"
+msgstr "Απαιτεί επίλυση συγχώνευσης"
+
+#: git-gui.sh:1644
+msgid "Starting gitk... please wait..."
+msgstr "Γίνεται εκκίνηση του gitk... παρακαλώ περιμένετε..."
+
+#: git-gui.sh:1653
+#, tcl-format
+msgid ""
+"Unable to start gitk:\n"
+"\n"
+"%s does not exist"
+msgstr ""
+"Αδυναμία εκκίνησης του gitk:\n"
+"\n"
+"Το %s δεν υπάρχει"
+
+#: git-gui.sh:1860 lib/choose_repository.tcl:36
+msgid "Repository"
+msgstr "Αποθετήριο"
+
+#: git-gui.sh:1861
+msgid "Edit"
+msgstr "Επεξεργασία"
+
+#: git-gui.sh:1863 lib/choose_rev.tcl:561
+msgid "Branch"
+msgstr "Κλάδος"
+
+#: git-gui.sh:1866 lib/choose_rev.tcl:548
+msgid "Commit@@noun"
+msgstr "Υποβολή@@noun"
+
+#: git-gui.sh:1869 lib/merge.tcl:120 lib/merge.tcl:149 lib/merge.tcl:167
+msgid "Merge"
+msgstr "Συγχώνευση"
+
+#: git-gui.sh:1870 lib/choose_rev.tcl:557
+msgid "Remote"
+msgstr "Απομακρυσμένο"
+
+#: git-gui.sh:1879
+msgid "Browse Current Branch's Files"
+msgstr "Περιήγηση Αρχείων Τρέχοντα Κλάδου"
+
+#: git-gui.sh:1883
+msgid "Browse Branch Files..."
+msgstr "Περιήγηση Αρχείων Κλάδου..."
+
+#: git-gui.sh:1888
+msgid "Visualize Current Branch's History"
+msgstr "Απεικόνιση Ιστορικού Τρέχοντα Κλάδου"
+
+#: git-gui.sh:1892
+msgid "Visualize All Branch History"
+msgstr "Απεικόνιση Ιστορικού Όλων των Κλάδων"
+
+#: git-gui.sh:1899
+#, tcl-format
+msgid "Browse %s's Files"
+msgstr "Περιήγηση Αρχείων του %s"
+
+#: git-gui.sh:1901
+#, tcl-format
+msgid "Visualize %s's History"
+msgstr "Απεικόνιση Ιστορικού του %s"
+
+#: git-gui.sh:1906 lib/database.tcl:27 lib/database.tcl:67
+msgid "Database Statistics"
+msgstr "Στατιστικά Βάσης Δεδομένων"
+
+#: git-gui.sh:1909 lib/database.tcl:34
+msgid "Compress Database"
+msgstr "Συμπίεση Βάσης Δεδομένων"
+
+#: git-gui.sh:1912
+msgid "Verify Database"
+msgstr "Επαλήθευση Βάσης Δεδομένων"
+
+#: git-gui.sh:1919 git-gui.sh:1923 git-gui.sh:1927 lib/shortcut.tcl:7
+#: lib/shortcut.tcl:39 lib/shortcut.tcl:71
+msgid "Create Desktop Icon"
+msgstr "Δημιουργία Εικονιδίου Επιφάνειας Εργασίας"
+
+#: git-gui.sh:1932 lib/choose_repository.tcl:177 lib/choose_repository.tcl:185
+msgid "Quit"
+msgstr "Έξοδος"
+
+#: git-gui.sh:1939
+msgid "Undo"
+msgstr "Αναίρεση"
+
+#: git-gui.sh:1942
+msgid "Redo"
+msgstr "Ξανά"
+
+#: git-gui.sh:1946 git-gui.sh:2443
+msgid "Cut"
+msgstr "Αποκοπή"
+
+#: git-gui.sh:1949 git-gui.sh:2446 git-gui.sh:2520 git-gui.sh:2614
+#: lib/console.tcl:69
+msgid "Copy"
+msgstr "Αντιγραφή"
+
+#: git-gui.sh:1952 git-gui.sh:2449
+msgid "Paste"
+msgstr "Επικόλληση"
+
+#: git-gui.sh:1955 git-gui.sh:2452 lib/branch_delete.tcl:26
+#: lib/remote_branch_delete.tcl:38
+msgid "Delete"
+msgstr "Διαγραφή"
+
+#: git-gui.sh:1959 git-gui.sh:2456 git-gui.sh:2618 lib/console.tcl:71
+msgid "Select All"
+msgstr "Επιλογή Όλων"
+
+#: git-gui.sh:1968
+msgid "Create..."
+msgstr "Δημιουργία..."
+
+#: git-gui.sh:1974
+msgid "Checkout..."
+msgstr "Εξαγωγή..."
+
+#: git-gui.sh:1980
+msgid "Rename..."
+msgstr "Μετονομασία..."
+
+#: git-gui.sh:1985 git-gui.sh:2085
+msgid "Delete..."
+msgstr "Διαγραφή..."
+
+#: git-gui.sh:1990
+msgid "Reset..."
+msgstr "Επαναφορά..."
+
+#: git-gui.sh:2002 git-gui.sh:2389
+msgid "New Commit"
+msgstr "Νέα Υποβολή"
+
+#: git-gui.sh:2010 git-gui.sh:2396
+msgid "Amend Last Commit"
+msgstr "Διόρθωση Τελευταίας Υποβολής"
+
+#: git-gui.sh:2019 git-gui.sh:2356 lib/remote_branch_delete.tcl:99
+msgid "Rescan"
+msgstr "Επανανίχνευση"
+
+#: git-gui.sh:2025
+msgid "Stage To Commit"
+msgstr "Σταδιοποίηση Προς Υποβολή"
+
+#: git-gui.sh:2031
+msgid "Stage Changed Files To Commit"
+msgstr "Σταδιοποίηση Αλλαγμένων Αρχείων Προς Υποβολή"
+
+#: git-gui.sh:2037
+msgid "Unstage From Commit"
+msgstr "Αποσταδιοποίηση Από Υποβολή"
+
+#: git-gui.sh:2042 lib/index.tcl:395
+msgid "Revert Changes"
+msgstr "Αναίρεση Αλλαγών"
+
+#: git-gui.sh:2049 git-gui.sh:2368 git-gui.sh:2467
+msgid "Sign Off"
+msgstr "Αποσύνδεση"
+
+#: git-gui.sh:2053 git-gui.sh:2372
+msgid "Commit@@verb"
+msgstr "Υποβολή@@verb"
+
+#: git-gui.sh:2064
+msgid "Local Merge..."
+msgstr "Τοπική Συγχώνευση..."
+
+#: git-gui.sh:2069
+msgid "Abort Merge..."
+msgstr "Ακύρωση Συγχώνευσης..."
+
+#: git-gui.sh:2081
+msgid "Push..."
+msgstr "Ώθηση..."
+
+#: git-gui.sh:2092 lib/choose_repository.tcl:41
+#, fuzzy
+msgid "Apple"
+msgstr ""
+
+#: git-gui.sh:2095 git-gui.sh:2117 lib/about.tcl:14
+#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50
+#, tcl-format
+msgid "About %s"
+msgstr "Περί %s"
+
+#: git-gui.sh:2099
+msgid "Preferences..."
+msgstr "Προτιμήσεις..."
+
+#: git-gui.sh:2107 git-gui.sh:2639
+msgid "Options..."
+msgstr "Επιλογές..."
+
+#: git-gui.sh:2113 lib/choose_repository.tcl:47
+msgid "Help"
+msgstr "Βοήθεια"
+
+#: git-gui.sh:2154
+msgid "Online Documentation"
+msgstr "Διαδικτυακή Τεκμηρίωση"
+
+#: git-gui.sh:2238
+#, tcl-format
+msgid "fatal: cannot stat path %s: No such file or directory"
+msgstr "κρίσιμο: δε βρέθηκε η διαδρομή: %s: Δεν υπάρχει το αρχείο ή ο φάκελος"
+
+#: git-gui.sh:2271
+msgid "Current Branch:"
+msgstr "Τρέχων Κλάδος:"
+
+#: git-gui.sh:2292
+msgid "Staged Changes (Will Commit)"
+msgstr "Σταδιοποιημένες Αλλαγές (Θα Υποβληθούν)"
+
+#: git-gui.sh:2312
+msgid "Unstaged Changes"
+msgstr "Μη Σταδιοποιημένες Αλλαγές"
+
+#: git-gui.sh:2362
+msgid "Stage Changed"
+msgstr "Σταδιοποίηση Αλλαγών"
+
+#: git-gui.sh:2378 lib/transport.tcl:93 lib/transport.tcl:182
+msgid "Push"
+msgstr "Ώθηση"
+
+#: git-gui.sh:2408
+msgid "Initial Commit Message:"
+msgstr "Αρχικό Μήνυμα Υποβολής:"
+
+#: git-gui.sh:2409
+msgid "Amended Commit Message:"
+msgstr "Διορθωμένο Μήνυμα Υποβολής:"
+
+#: git-gui.sh:2410
+msgid "Amended Initial Commit Message:"
+msgstr "Διορθωμένο Αρχικό Μήνυμα Υποβολής:"
+
+#: git-gui.sh:2411
+msgid "Amended Merge Commit Message:"
+msgstr "Διορθωμένο Μήνυμα Υποβολής Συγχώνευσης:"
+
+#: git-gui.sh:2412
+msgid "Merge Commit Message:"
+msgstr "Μήνυμα Υποβολής Συγχώνευσης:"
+
+#: git-gui.sh:2413
+msgid "Commit Message:"
+msgstr "Μήνυμα Υποβολής:"
+
+#: git-gui.sh:2459 git-gui.sh:2622 lib/console.tcl:73
+msgid "Copy All"
+msgstr "Αντιγραφή Όλων"
+
+#: git-gui.sh:2483 lib/blame.tcl:107
+msgid "File:"
+msgstr "Αρχείο:"
+
+#: git-gui.sh:2589
+msgid "Apply/Reverse Hunk"
+msgstr "Εφαρμογή/Αντιστροφή Κομματιού"
+
+#: git-gui.sh:2595
+msgid "Show Less Context"
+msgstr "Προβολή Στενότερου Πλαισίου"
+
+#: git-gui.sh:2602
+msgid "Show More Context"
+msgstr "Προβολή Ευρύτερου Πλαισίου"
+
+#: git-gui.sh:2610
+msgid "Refresh"
+msgstr "Ανανέωση"
+
+#: git-gui.sh:2631
+msgid "Decrease Font Size"
+msgstr "Μείωση Μεγέθους Γραμματοσειράς"
+
+#: git-gui.sh:2635
+msgid "Increase Font Size"
+msgstr "Αύξηση Μεγέθους Γραμματοσειράς"
+
+#: git-gui.sh:2646
+msgid "Unstage Hunk From Commit"
+msgstr "Αποσταδιοποίηση Κομματιού Από Υποβολή"
+
+#: git-gui.sh:2648
+msgid "Stage Hunk For Commit"
+msgstr "Σταδιοποίηση Κομματιού Προς Υποβολή"
+
+#: git-gui.sh:2667
+msgid "Initializing..."
+msgstr "Γίνεται αρχικοποίηση..."
+
+#: git-gui.sh:2762
+#, tcl-format
+msgid ""
+"Possible environment issues exist.\n"
+"\n"
+"The following environment variables are probably\n"
+"going to be ignored by any Git subprocess run\n"
+"by %s:\n"
+"\n"
+msgstr ""
+"Υπάρχουν πιθανά θέματα με το περιβάλλον.\n"
+"\n"
+"Οι εξής μεταβλητές περιβάλλοντος μάλλον θα\n"
+"αγνοηθούν από πιθανή εκτέλεση υποδιεργασίας Git\n"
+"από το %s:\n"
+"\n"
+
+#: git-gui.sh:2792
+msgid ""
+"\n"
+"This is due to a known issue with the\n"
+"Tcl binary distributed by Cygwin."
+msgstr ""
+"\n"
+"Αυτό οφείλεται σε ένα γνωστό θέμα με το\n"
+"εκτελέσιμο Tcl που διανέμεται με το Cygwin."
+
+#: git-gui.sh:2797
+#, tcl-format
+msgid ""
+"\n"
+"\n"
+"A good replacement for %s\n"
+"is placing values for the user.name and\n"
+"user.email settings into your personal\n"
+"~/.gitconfig file.\n"
+msgstr ""
+"\n"
+"\n"
+"Ένα καλό υποκατάστατο για το %s\n"
+"είναι η τοποθέτηση τιμών για τις ρυθμίσεις\n"
+"user.name και user.email στο προσωπικό σας\n"
+"αρχείο ~/.gitconfig .\n"
+
+#: lib/about.tcl:26
+msgid "git-gui - a graphical user interface for Git."
+msgstr "git-gui - ένα γραφικό περιβάλλον για το Git."
+
+#: lib/blame.tcl:77
+msgid "File Viewer"
+msgstr "Εφαρμογή Προβολής Αρχείου"
+
+#: lib/blame.tcl:81
+msgid "Commit:"
+msgstr "Υποβολή:"
+
+#: lib/blame.tcl:264
+msgid "Copy Commit"
+msgstr "Αντιγραφή Υποβολής"
+
+#: lib/blame.tcl:384
+#, tcl-format
+msgid "Reading %s..."
+msgstr "Ανάγνωση %s..."
+
+#: lib/blame.tcl:488
+msgid "Loading copy/move tracking annotations..."
+msgstr "Γίνεται φόρτωση σχολίων παρακολούθησης αντιγραφής/μετακίνησης..."
+
+#: lib/blame.tcl:508
+msgid "lines annotated"
+msgstr "γραμμές σχολιασμένες"
+
+#: lib/blame.tcl:689
+msgid "Loading original location annotations..."
+msgstr "Γίνεται φόρτωση σχολίων αρχικής τοποθεσίας..."
+
+#: lib/blame.tcl:692
+msgid "Annotation complete."
+msgstr "Έγινε ολοκλήρωση του σχολιασμού."
+
+#: lib/blame.tcl:746
+msgid "Loading annotation..."
+msgstr "Φόρτωση σχολίου..."
+
+#: lib/blame.tcl:802
+msgid "Author:"
+msgstr "Δημιουργός:"
+
+#: lib/blame.tcl:806
+msgid "Committer:"
+msgstr "Υποβολέας:"
+
+#: lib/blame.tcl:811
+msgid "Original File:"
+msgstr "Αρχικό Αρχείο:"
+
+#: lib/blame.tcl:925
+msgid "Originally By:"
+msgstr "Αρχικά Από:"
+
+#: lib/blame.tcl:931
+msgid "In File:"
+msgstr "Στο Αρχείο:"
+
+#: lib/blame.tcl:936
+msgid "Copied Or Moved Here By:"
+msgstr "Αντιγράφηκε ή Μετακινήθηκε Εδώ Από:"
+
+#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
+msgid "Checkout Branch"
+msgstr "Εξαγωγή Κλάδου"
+
+#: lib/branch_checkout.tcl:23
+msgid "Checkout"
+msgstr "Εξαγωγή"
+
+#: 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/option.tcl:103 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
+msgid "Cancel"
+msgstr "Ακύρωση"
+
+#: lib/branch_checkout.tcl:32 lib/browser.tcl:287
+msgid "Revision"
+msgstr "Αναθεώρηση"
+
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:242
+msgid "Options"
+msgstr "Επιλογές"
+
+#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
+msgstr "Ανάκτηση Κλάδου Παρακολούθησης"
+
+#: lib/branch_checkout.tcl:44
+msgid "Detach From Local Branch"
+msgstr "Αποκόλληση Από Τοπικό Κλάδο"
+
+#: lib/branch_create.tcl:22
+msgid "Create Branch"
+msgstr "Δημιουργία Κλάδου"
+
+#: lib/branch_create.tcl:27
+msgid "Create New Branch"
+msgstr "Δημιουργία Νέου Κλάδου"
+
+#: lib/branch_create.tcl:31 lib/choose_repository.tcl:371
+msgid "Create"
+msgstr "Δημιουργία"
+
+#: lib/branch_create.tcl:40
+msgid "Branch Name"
+msgstr "Όνομα Κλάδου"
+
+#: lib/branch_create.tcl:43
+msgid "Name:"
+msgstr "Όνομα:"
+
+#: lib/branch_create.tcl:58
+msgid "Match Tracking Branch Name"
+msgstr "Συμφωνία Ονόματος Κλάδου Παρακολούθησης"
+
+#: lib/branch_create.tcl:66
+msgid "Starting Revision"
+msgstr "Αρχική Αναθεώρηση"
+
+#: lib/branch_create.tcl:72
+msgid "Update Existing Branch:"
+msgstr "Ενημέρωση Υπάρχοντα Κλάδου:"
+
+#: lib/branch_create.tcl:75
+#, fuzzy
+msgid "No"
+msgstr "Όχι"
+
+#: lib/branch_create.tcl:80
+msgid "Fast Forward Only"
+msgstr "Συγχώνευση Επιτάχυνσης Μόνο"
+
+#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514
+msgid "Reset"
+msgstr "Επαναφορά"
+
+#: lib/branch_create.tcl:97
+msgid "Checkout After Creation"
+msgstr "Εξαγωγή Μετά τη Δημιουργία"
+
+#: lib/branch_create.tcl:131
+msgid "Please select a tracking branch."
+msgstr "Παρακαλώ επιλέξτε έναν κλάδο παρακολούθησης."
+
+#: lib/branch_create.tcl:140
+#, tcl-format
+msgid "Tracking branch %s is not a branch in the remote repository."
+msgstr ""
+"Ο κλάδος παρακολούθησης %s δεν είναι κλάδος που βρίσκεται στο απομακρυσμένο "
+"αποθετήριο."
+
+#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
+msgid "Please supply a branch name."
+msgstr "Παρακαλώ δώστε ένα όνομα κλάδου."
+
+#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
+#, tcl-format
+msgid "'%s' is not an acceptable branch name."
+msgstr "'%s' δεν είναι αποδεκτό όνομα κλάδου."
+
+#: lib/branch_delete.tcl:15
+msgid "Delete Branch"
+msgstr "Διαγραφή Κλάδου"
+
+#: lib/branch_delete.tcl:20
+msgid "Delete Local Branch"
+msgstr "Διαγραφή Τοπικού Κλάδου"
+
+#: lib/branch_delete.tcl:37
+msgid "Local Branches"
+msgstr "Τοπικοί Κλάδοι"
+
+#: lib/branch_delete.tcl:52
+msgid "Delete Only If Merged Into"
+msgstr "Διαγραφή Μόνο Εάν Είναι Συγχωνευμένο Με"
+
+#: lib/branch_delete.tcl:54
+msgid "Always (Do not perform merge test.)"
+msgstr "Πάντα (Μη διενεργηθεί δοκιμή συγχώνευσης.)"
+
+#: lib/branch_delete.tcl:103
+#, tcl-format
+msgid "The following branches are not completely merged into %s:"
+msgstr "Οι εξής κλάδοι δεν είναι πλήρως συγχωνευμένοι με το %s:"
+
+#: lib/branch_delete.tcl:115
+msgid ""
+"Recovering deleted branches is difficult. \n"
+"\n"
+" Delete the selected branches?"
+msgstr ""
+"Η ανάκτηση διεγραμμένων κλάδων είναι δύσκολη.\n"
+"\n"
+"Διαγραφή των επιλεγμένων κλάδων;"
+
+#: lib/branch_delete.tcl:141
+#, tcl-format
+msgid ""
+"Failed to delete branches:\n"
+"%s"
+msgstr ""
+"Αποτυχία διαγραφής κλάδων:\n"
+"%s"
+
+#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22
+msgid "Rename Branch"
+msgstr "Μετονομασία Κλάδου"
+
+#: lib/branch_rename.tcl:26
+msgid "Rename"
+msgstr "Μετονομασία"
+
+#: lib/branch_rename.tcl:36
+msgid "Branch:"
+msgstr "Κλάδος:"
+
+#: lib/branch_rename.tcl:39
+msgid "New Name:"
+msgstr "Νέο Όνομα:"
+
+#: lib/branch_rename.tcl:75
+msgid "Please select a branch to rename."
+msgstr "Παρακαλώ επιλέξτε κλάδο προς μετονομασία:"
+
+#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179
+#, tcl-format
+msgid "Branch '%s' already exists."
+msgstr "Ο Κλάδος '%s' υπάρχει ήδη."
+
+#: lib/branch_rename.tcl:117
+#, tcl-format
+msgid "Failed to rename '%s'."
+msgstr "Αποτυχία μετονομασίας '%s'."
+
+#: lib/browser.tcl:17
+msgid "Starting..."
+msgstr "Γίνεται Εκκίνηση..."
+
+#: lib/browser.tcl:26
+msgid "File Browser"
+msgstr "Περιηγητής Αρχείων"
+
+#: lib/browser.tcl:126 lib/browser.tcl:143
+#, tcl-format
+msgid "Loading %s..."
+msgstr "Γίνεται φόρτωση %s..."
+
+#: lib/browser.tcl:187
+#, fuzzy
+msgid "[Up To Parent]"
+msgstr "[Πάνω Προς Γονέα]"
+
+#: lib/browser.tcl:267 lib/browser.tcl:273
+msgid "Browse Branch Files"
+msgstr "Περιήγηση Αρχείων Κλάδου"
+
+#: lib/browser.tcl:278 lib/choose_repository.tcl:387
+#: lib/choose_repository.tcl:474 lib/choose_repository.tcl:484
+#: lib/choose_repository.tcl:987
+msgid "Browse"
+msgstr "Περιήγηση"
+
+#: lib/checkout_op.tcl:79
+#, tcl-format
+msgid "Fetching %s from %s"
+msgstr "Ανάκτηση %s από το %s"
+
+#: lib/checkout_op.tcl:127
+#, tcl-format
+msgid "fatal: Cannot resolve %s"
+msgstr "κρίσιμο: Δε μπόρεσε να επιλυθεί το %s"
+
+#: lib/checkout_op.tcl:140 lib/console.tcl:81 lib/database.tcl:31
+msgid "Close"
+msgstr "Κλείσιμο"
+
+#: lib/checkout_op.tcl:169
+#, tcl-format
+msgid "Branch '%s' does not exist."
+msgstr "Ο Κλάδος '%s' δεν υπάρχει."
+
+#: lib/checkout_op.tcl:206
+#, tcl-format
+msgid ""
+"Branch '%s' already exists.\n"
+"\n"
+"It cannot fast-forward to %s.\n"
+"A merge is required."
+msgstr ""
+"Ο Κλάδος '%s' υπάρχει ήδη.\n"
+"\n"
+"Δε γίνεται συγχώνευση επιτάχυνσής του στο %s.\n"
+"Απαιτείται συγχώνευση."
+
+#: lib/checkout_op.tcl:220
+#, tcl-format
+msgid "Merge strategy '%s' not supported."
+msgstr "Η στρατηγική Συγχώνευσης %s δεν υποστηρίζεται."
+
+#: lib/checkout_op.tcl:239
+#, tcl-format
+msgid "Failed to update '%s'."
+msgstr "Αποτυχία ενημέρωσης '%s'."
+
+#: lib/checkout_op.tcl:251
+msgid "Staging area (index) is already locked."
+msgstr "Η περιοχή σταδιοποίησης (το ευρετήριο) είναι ήδη κλειδωμένη."
+
+#: lib/checkout_op.tcl:266
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before the current branch can be changed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Η τελευταία κατάσταση που ανιχνεύθηκε δε συμφωνεί με την κατάσταση του "
+"αποθετηρίου.\n"
+"\n"
+"Κάποιο άλλο πρόγραμμα Git τροποποίησε το αποθετήριο από την τελευταία "
+"ανίχνευση. Πρέπει να γίνει επανανίχνευση πριν να αλλαχθεί ο τρέχων κλάδος.\n"
+"\n"
+"Η επανανίχνευση θα ξεκινήσει αυτόματα τώρα.\n"
+
+#: lib/checkout_op.tcl:322
+#, tcl-format
+msgid "Updating working directory to '%s'..."
+msgstr "Ενημέρωση φακέλου εργασίας σε '%s'..."
+
+#: lib/checkout_op.tcl:323
+msgid "files checked out"
+msgstr "αρχεία έχουν εξαχθεί"
+
+#: lib/checkout_op.tcl:353
+#, tcl-format
+msgid "Aborted checkout of '%s' (file level merging is required)."
+msgstr ""
+"Έγινε ακύρωση εξαγωγής του '%s' (απαιτείται συγχώνευση επιπέδου αρχείου)."
+
+#: lib/checkout_op.tcl:354
+msgid "File level merge required."
+msgstr "Απαιτείται συγχώνευση επιπέδου αρχείου."
+
+#: lib/checkout_op.tcl:358
+#, tcl-format
+msgid "Staying on branch '%s'."
+msgstr "Παραμονή στον κλάδο '%s'."
+
+#: lib/checkout_op.tcl:429
+msgid ""
+"You are no longer on a local branch.\n"
+"\n"
+"If you wanted to be on a branch, create one now starting from 'This Detached "
+"Checkout'."
+msgstr ""
+"Δε βρίσκεστε πια σε τοπικό κλάδο.\n"
+"\n"
+"Αν θέλατε να βρίσκεστε σε κλάδο, δημιουργήστε έναν τώρα αρχίζοντας από 'This "
+"Detached Checkout'."
+
+#: lib/checkout_op.tcl:446 lib/checkout_op.tcl:450
+#, tcl-format
+msgid "Checked out '%s'."
+msgstr "Έγινε εξαγωγή του '%s'."
+
+#: lib/checkout_op.tcl:478
+#, tcl-format
+msgid "Resetting '%s' to '%s' will lose the following commits:"
+msgstr "Η επαναφορά '%s' στο '%s' θα χάσει τις εξής υποβολές:"
+
+#: lib/checkout_op.tcl:500
+msgid "Recovering lost commits may not be easy."
+msgstr "Η ανάκτηση χαμένων υποβολών μπορεί να είναι δύσκολη."
+
+#: lib/checkout_op.tcl:505
+#, tcl-format
+msgid "Reset '%s'?"
+msgstr "Επαναφορά '%s';"
+
+#: lib/checkout_op.tcl:510 lib/merge.tcl:163
+msgid "Visualize"
+msgstr "Απεικόνιση"
+
+#: lib/checkout_op.tcl:578
+#, tcl-format
+msgid ""
+"Failed to set current branch.\n"
+"\n"
+"This working directory is only partially switched. We successfully updated "
+"your files, but failed to update an internal Git file.\n"
+"\n"
+"This should not have occurred. %s will now close and give up."
+msgstr ""
+"Αποτυχία ορισμού τρέχοντος κλάδου.\n"
+"\n"
+"Αυτός ο φάκελος εργασίας είναι μόνο εν μέρει επιλεγμένος. 'Εγινε επιτυχής "
+"ενημέρωση των αρχείων σας, αλλά απέτυχε η ενημέρωση ενός εσωτερικού αρχείου "
+"του Git.\n"
+"\n"
+"Αυτό δε θα έπρεπε να συμβεί. Το %s θα κλείσει και θα εγκαταλείψει τώρα."
+
+#: lib/choose_font.tcl:39
+msgid "Select"
+msgstr "Επιλογή"
+
+#: lib/choose_font.tcl:53
+msgid "Font Family"
+msgstr "Οικογένεια Γραμματοσειράς"
+
+#: lib/choose_font.tcl:74
+msgid "Font Size"
+msgstr "Μέγεθος Γραμματοσειράς"
+
+#: lib/choose_font.tcl:91
+msgid "Font Example"
+msgstr "Παράδειγμα Γραμματοσειράς"
+
+#: lib/choose_font.tcl:103
+msgid ""
+"This is example text.\n"
+"If you like this text, it can be your font."
+msgstr ""
+"Αυτό είναι ένα παράδειγμα κειμένου.\n"
+"Αν σας αρέσει αυτό το κείμενο, μπορεί να γίνει δικό σας."
+
+#: lib/choose_repository.tcl:28
+msgid "Git Gui"
+msgstr "Γραφικό Περιβάλλον Git"
+
+#: lib/choose_repository.tcl:81 lib/choose_repository.tcl:376
+msgid "Create New Repository"
+msgstr "Δημιουργία Νέου Αποθετηρίου"
+
+#: lib/choose_repository.tcl:87
+msgid "New..."
+msgstr "Νέο..."
+
+#: lib/choose_repository.tcl:94 lib/choose_repository.tcl:460
+msgid "Clone Existing Repository"
+msgstr "Κλωνοποίηση Υπάρχοντος Αποθετηρίου"
+
+#: lib/choose_repository.tcl:100
+msgid "Clone..."
+msgstr "Κλωνοποίηση..."
+
+#: lib/choose_repository.tcl:107 lib/choose_repository.tcl:976
+msgid "Open Existing Repository"
+msgstr "Άνοιγμα Υπάρχοντος Αποθετηρίου"
+
+#: lib/choose_repository.tcl:113
+msgid "Open..."
+msgstr "Άνοιγμα..."
+
+#: lib/choose_repository.tcl:126
+msgid "Recent Repositories"
+msgstr "Πρόσφατα Αποθετήρια"
+
+#: lib/choose_repository.tcl:132
+msgid "Open Recent Repository:"
+msgstr "Άνοιγμα Πρόσφατου Αποθετηρίου:"
+
+#: lib/choose_repository.tcl:296 lib/choose_repository.tcl:303
+#: lib/choose_repository.tcl:310
+#, tcl-format
+msgid "Failed to create repository %s:"
+msgstr "Αποτυχία δημιουργίας αποθετηρίου %s:"
+
+#: lib/choose_repository.tcl:381 lib/choose_repository.tcl:478
+msgid "Directory:"
+msgstr "Φάκελος:"
+
+#: lib/choose_repository.tcl:412 lib/choose_repository.tcl:537
+#: lib/choose_repository.tcl:1011
+msgid "Git Repository"
+msgstr "Αποθετήριο Git"
+
+#: lib/choose_repository.tcl:437
+#, tcl-format
+msgid "Directory %s already exists."
+msgstr "Ο Φάκελος '%s' υπάρχει ήδη."
+
+#: lib/choose_repository.tcl:441
+#, tcl-format
+msgid "File %s already exists."
+msgstr "Το αρχείο %s υπάρχει ήδη."
+
+#: lib/choose_repository.tcl:455
+msgid "Clone"
+msgstr "Κλώνος"
+
+#: lib/choose_repository.tcl:468
+#, fuzzy
+msgid "URL:"
+msgstr ""
+
+#: lib/choose_repository.tcl:489
+msgid "Clone Type:"
+msgstr "Τύπος Κλώνου:"
+
+#: lib/choose_repository.tcl:495
+msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
+msgstr "Τυπικό (Ταχύ, Ημι-Πλεονάζον, Hardlinks)"
+
+#: lib/choose_repository.tcl:501
+msgid "Full Copy (Slower, Redundant Backup)"
+msgstr "Πλήρες Αντίγραφο (Πιο αργό, Πλεονάζον Αντίγραφο Ασφαλείας)"
+
+#: lib/choose_repository.tcl:507
+msgid "Shared (Fastest, Not Recommended, No Backup)"
+msgstr "Κοινή Χρήση (Ταχύτατο, Δε Συνιστάται, Κανένα Αντίγραφο Ασφαλείας)"
+
+#: 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
+#, tcl-format
+msgid "Not a Git repository: %s"
+msgstr "Δεν είναι αποθετήριο Git: %s"
+
+#: lib/choose_repository.tcl:579
+msgid "Standard only available for local repository."
+msgstr "\"Τυπικό\" διαθέσιμο μόνο για τοπικό αποθετήριο."
+
+#: lib/choose_repository.tcl:583
+msgid "Shared only available for local repository."
+msgstr "\"Κοινή Χρήση\" διαθέσιμη μόνο για τοπικό αποθετήριο."
+
+#: lib/choose_repository.tcl:604
+#, tcl-format
+msgid "Location %s already exists."
+msgstr "Η Τοποθεσία %s υπάρχει ήδη."
+
+#: lib/choose_repository.tcl:615
+msgid "Failed to configure origin"
+msgstr "Αποτυχία ρύθμισης πηγής"
+
+#: lib/choose_repository.tcl:627
+msgid "Counting objects"
+msgstr "Γίνεται καταμέτρηση αντικειμένων"
+
+#: lib/choose_repository.tcl:628
+#, fuzzy
+msgid "buckets"
+msgstr ""
+
+#: lib/choose_repository.tcl:652
+#, tcl-format
+msgid "Unable to copy objects/info/alternates: %s"
+msgstr "Αδυναμία αντιγραφής αντικειμένων/πληροφοριών/ενναλακτικών: %s"
+
+#: lib/choose_repository.tcl:688
+#, tcl-format
+msgid "Nothing to clone from %s."
+msgstr "Τίποτα προς κλωνοποίηση από το %s."
+
+#: lib/choose_repository.tcl:690 lib/choose_repository.tcl:904
+#: lib/choose_repository.tcl:916
+msgid "The 'master' branch has not been initialized."
+msgstr "Ο κλάδος 'master' δεν έχει αρχικοποιηθεί."
+
+#: lib/choose_repository.tcl:703
+msgid "Hardlinks are unavailable. Falling back to copying."
+msgstr "Hardlinks μη διαθέσιμα. Μετάπτωση σε αντιγραφή."
+
+#: lib/choose_repository.tcl:715
+#, tcl-format
+msgid "Cloning from %s"
+msgstr "Γίνεται κλωνοποίηση από το %s"
+
+#: lib/choose_repository.tcl:746
+msgid "Copying objects"
+msgstr "Γίνεται αντιγραφή αντικειμένων"
+
+#: lib/choose_repository.tcl:747
+#, fuzzy
+msgid "KiB"
+msgstr ""
+
+#: lib/choose_repository.tcl:771
+#, tcl-format
+msgid "Unable to copy object: %s"
+msgstr "Αδυναμία αντιγραφής αντικειμένου: %s"
+
+#: lib/choose_repository.tcl:781
+msgid "Linking objects"
+msgstr "Γίνεται σύνδεση αντικειμένων"
+
+#: lib/choose_repository.tcl:782
+msgid "objects"
+msgstr "αντικείμενα"
+
+#: lib/choose_repository.tcl:790
+#, tcl-format
+msgid "Unable to hardlink object: %s"
+msgstr "Αδυναμία hardlink αντικειμένου: %s"
+
+#: lib/choose_repository.tcl:845
+msgid "Cannot fetch branches and objects. See console output for details."
+msgstr ""
+"Δε μπόρεσε να γίνει ανάκτηση κλάδων και αντικειμένων. Δείτε την έξοδο "
+"κονσόλας για λεπτομέρειες."
+
+#: lib/choose_repository.tcl:856
+msgid "Cannot fetch tags. See console output for details."
+msgstr ""
+"Δε μπόρεσε να γίνει ανάκτηση ετικετών. Δείτε την έξοδο κονσόλας για "
+"λεπτομέρειες."
+
+#: lib/choose_repository.tcl:880
+msgid "Cannot determine HEAD. See console output for details."
+msgstr ""
+"Δε μπόρεσε να γίνει καθορισμός του HEAD (παρακλαδιού). Δείτε την έξοδο "
+"κονσόλας για "
+"λεπτομέρειες."
+
+#: lib/choose_repository.tcl:889
+#, tcl-format
+msgid "Unable to cleanup %s"
+msgstr "Αδυναμία εκκαθάρισης %s"
+
+#: lib/choose_repository.tcl:895
+msgid "Clone failed."
+msgstr "Αποτυχία κλωνοποίησης."
+
+#: lib/choose_repository.tcl:902
+msgid "No default branch obtained."
+msgstr "Δεν έγινε ανάκτηση προεπιλεγμένου κλάδου."
+
+#: lib/choose_repository.tcl:913
+#, tcl-format
+msgid "Cannot resolve %s as a commit."
+msgstr "Δε μπόρεσε να επιλυθεί το %s ως υποβολή."
+
+#: lib/choose_repository.tcl:925
+msgid "Creating working directory"
+msgstr "Δημιουργία φακέλου εργασίας"
+
+#: lib/choose_repository.tcl:926 lib/index.tcl:65 lib/index.tcl:127
+#: lib/index.tcl:193
+msgid "files"
+msgstr "αρχεία"
+
+#: lib/choose_repository.tcl:955
+msgid "Initial file checkout failed."
+msgstr "Η αρχική εξαγωγή αρχείου απέτυχε."
+
+#: lib/choose_repository.tcl:971
+msgid "Open"
+msgstr "Άνοιγμα"
+
+#: lib/choose_repository.tcl:981
+msgid "Repository:"
+msgstr "Αποθετήριο:"
+
+#: lib/choose_repository.tcl:1031
+#, tcl-format
+msgid "Failed to open repository %s:"
+msgstr "Αποτυχία ανοίγματος αποθετηρίου %s:"
+
+#: lib/choose_rev.tcl:53
+#, fuzzy
+msgid "This Detached Checkout"
+msgstr "Αποσυνδεδεμένη Εξαγωγή"
+
+#: lib/choose_rev.tcl:60
+msgid "Revision Expression:"
+msgstr "Έκφραση Αναθεώρησης:"
+
+#: lib/choose_rev.tcl:74
+msgid "Local Branch"
+msgstr "Τοπικός Κλάδος"
+
+#: lib/choose_rev.tcl:79
+msgid "Tracking Branch"
+msgstr "Κλάδος Παρακολούθησης"
+
+#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:538
+msgid "Tag"
+msgstr "Ετικέτα"
+
+#: lib/choose_rev.tcl:317
+#, tcl-format
+msgid "Invalid revision: %s"
+msgstr "Μη έγκυρη αναθεώρηση: %s"
+
+#: lib/choose_rev.tcl:338
+msgid "No revision selected."
+msgstr "Δεν έχει επιλεγεί αναθεώρηση."
+
+#: lib/choose_rev.tcl:346
+msgid "Revision expression is empty."
+msgstr "Η έκφραση αναθεώρησης είναι κενή."
+
+#: lib/choose_rev.tcl:531
+msgid "Updated"
+msgstr "Ενημερωμένο"
+
+#: lib/choose_rev.tcl:559
+#, fuzzy
+msgid "URL"
+msgstr ""
+
+#: lib/commit.tcl:9
+msgid ""
+"There is nothing to amend.\n"
+"\n"
+"You are about to create the initial commit. There is no commit before this "
+"to amend.\n"
+msgstr ""
+"Δεν υπάρχει κάτι προς διόρθωση.\n"
+"\n"
+"Πρόκειται να δημιουργήσετε την αρχική υποβολή. Δεν υπάρχει υποβολή πριν από "
+"αυτή για να διορθώσετε.\n"
+
+#: lib/commit.tcl:18
+msgid ""
+"Cannot amend while merging.\n"
+"\n"
+"You are currently in the middle of a merge that has not been fully "
+"completed. You cannot amend the prior commit unless you first abort the "
+"current merge activity.\n"
+msgstr ""
+"Δε γίνεται διόρθωση καθώς συγχωνεύετε.\n"
+"\n"
+"Βρίσκεστε στο μέσο μιας συγχώνευσης που δεν έχει ολοκληρωθεί. Δε μπορείτε να "
+"διορθώσετε την προηγούμενη υποβολή εκτός εάν ακυρώσετε την τρέχουσα ενέργεια "
+"συγχώνευσης.\n"
+
+#: lib/commit.tcl:49
+msgid "Error loading commit data for amend:"
+msgstr "Σφάλμα φόρτωσης δεδομένων υποβολής προς διόρθωση:"
+
+#: lib/commit.tcl:76
+msgid "Unable to obtain your identity:"
+msgstr "Αδυναμία ανάκτησης της ταυτότητάς σας:"
+
+#: lib/commit.tcl:81
+msgid "Invalid GIT_COMMITTER_IDENT:"
+msgstr "Μη έγκυρο GIT_COMMITTER_IDENT:"
+
+#: lib/commit.tcl:133
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before another commit can be created.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Η τελευταία κατάσταση που ανιχνεύθηκε δε συμφωνεί με την κατάσταση του "
+"αποθετηρίου.\n"
+"\n"
+"Κάποιο άλλο πρόγραμμα Git τροποποίησε το αποθετήριο από την τελευταία "
+"ανίχνευση. Πρέπει να γίνει επανανίχνευση πριν τη δημιουργία νέας υποβολής.\n"
+"\n"
+"Η επανανίχνευση θα ξεκινήσει αυτόματα τώρα.\n"
+
+#: lib/commit.tcl:154
+#, tcl-format
+msgid ""
+"Unmerged files cannot be committed.\n"
+"\n"
+"File %s has merge conflicts. You must resolve them and stage the file "
+"before committing.\n"
+msgstr ""
+"Τα μη συγχωνευμένα αρχεία δε μπορούν να υποβληθούν.\n"
+"\n"
+"Το αρχείο %s έχει συγκρούσεις συγχώνευσης. Πρέπει να τις επιλύσετε και να "
+"σταδιοποιήσετε το αρχείο πριν την υποβολή.\n"
+
+#: lib/commit.tcl:162
+#, tcl-format
+msgid ""
+"Unknown file state %s detected.\n"
+"\n"
+"File %s cannot be committed by this program.\n"
+msgstr ""
+"Άγνωστη κατάσταση αρχείου %s ανιχνεύθηκε.\n"
+"\n"
+"Το αρχείο %s δε μπορεί να υποβληθεί από αυτό το πρόγραμμα.\n"
+
+#: lib/commit.tcl:170
+msgid ""
+"No changes to commit.\n"
+"\n"
+"You must stage at least 1 file before you can commit.\n"
+msgstr ""
+"Δεν υπάρχουν αλλαγές προς υποβολή.\n"
+"\n "
+"Πρέπει να σταδιοποιήσετε τουλάχιστον 1 αρχείο πριν να κάνετε υποβολή.\n"
+
+#: lib/commit.tcl:183
+msgid ""
+"Please supply a commit message.\n"
+"\n"
+"A good commit message has the following format:\n"
+"\n"
+"- First line: Describe in one sentence what you did.\n"
+"- Second line: Blank\n"
+"- Remaining lines: Describe why this change is good.\n"
+msgstr ""
+"Παρακαλώ δώστε ένα μήνυμα υποβολής.\n"
+"\n"
+"Ένα σωστό μήνυμα υποβολής έχει την εξής μορφή:\n"
+"\n"
+"- Πρώτη γραμμή: Περιγραφή σε μία πρόταση του τι κάνατε.\n"
+"- Δεύτερη γραμμή: Κενή\n"
+"- Υπόλοιπες γραμμές: Περιγραφή του γιατί αυτή η αλλαγή είναι σωστή.\n"
+
+#: lib/commit.tcl:207
+#, tcl-format
+msgid "warning: Tcl does not support encoding '%s'."
+msgstr "προειδοποίηση: H Tcl δεν υποστηρίζει την κωδικοποίηση '%s'."
+
+#: lib/commit.tcl:221
+msgid "Calling pre-commit hook..."
+msgstr "Γίνεται κλήση του pre-commit hook..."
+
+#: lib/commit.tcl:236
+msgid "Commit declined by pre-commit hook."
+msgstr "Η υποβολή απορρίφθηκε από το pre-commit hook."
+
+#: lib/commit.tcl:259
+msgid "Calling commit-msg hook..."
+msgstr "Γίνεται κλήση του commit-msg hook..."
+
+#: lib/commit.tcl:274
+msgid "Commit declined by commit-msg hook."
+msgstr "Η υποβολή απορρίφθηκε από το commit-msg hook."
+
+#: lib/commit.tcl:287
+msgid "Committing changes..."
+msgstr "Γίνεται υποβολή των αλλαγών..."
+
+#: lib/commit.tcl:303
+msgid "write-tree failed:"
+msgstr "το write-tree απέτυχε:"
+
+#: lib/commit.tcl:304 lib/commit.tcl:348 lib/commit.tcl:368
+msgid "Commit failed."
+msgstr "Η υποβολή απέτυχε."
+
+#: lib/commit.tcl:321
+#, tcl-format
+msgid "Commit %s appears to be corrupt"
+msgstr "Η υποβολή %s δείχνει κατεστραμμένη"
+
+#: lib/commit.tcl:326
+msgid ""
+"No changes to commit.\n"
+"\n"
+"No files were modified by this commit and it was not a merge commit.\n"
+"\n"
+"A rescan will be automatically started now.\n"
+msgstr ""
+"Δεν υπάρχουν αλλαγές προς υποβολή.\n"
+"\n"
+"Δεν τροποποιήθηκαν αρχεία από αυτή την υποβολή και δεν ήταν υποβολή "
+"συγχώνευσης.\n"
+"\n"
+"Θα ξεκινήσει αυτόματα επανανίχνευση τώρα.\n"
+
+#: lib/commit.tcl:333
+msgid "No changes to commit."
+msgstr "Δεν υπάρχουν αλλαγές προς υποβολή."
+
+#: lib/commit.tcl:347
+msgid "commit-tree failed:"
+msgstr "το commit-tree απέτυχε:"
+
+#: lib/commit.tcl:367
+msgid "update-ref failed:"
+msgstr "το update-ref απέτυχε:"
+
+#: lib/commit.tcl:454
+#, tcl-format
+msgid "Created commit %s: %s"
+msgstr "Δημιουργήθηκε υποβολή %s: %s"
+
+#: lib/console.tcl:59
+msgid "Working... please wait..."
+msgstr "Γίνεται εργασία... Παρακαλώ περιμένετε..."
+
+#: lib/console.tcl:186
+msgid "Success"
+msgstr "Επιτυχία"
+
+#: lib/console.tcl:200
+msgid "Error: Command Failed"
+msgstr "Σφάλμα: Η Εντολή Απέτυχε"
+
+#: lib/database.tcl:43
+msgid "Number of loose objects"
+msgstr "Αριθμός ελεύθερων αντικειμένων"
+
+#: lib/database.tcl:44
+msgid "Disk space used by loose objects"
+msgstr "Χώρος κατειλλημένος από ελεύθερα αντικείμενα"
+
+#: lib/database.tcl:45
+msgid "Number of packed objects"
+msgstr "Αριθμός πακεταρισμένων αντικειμένων"
+
+#: lib/database.tcl:46
+msgid "Number of packs"
+msgstr "Αριθμός πακέτων"
+
+#: lib/database.tcl:47
+msgid "Disk space used by packed objects"
+msgstr "Χώρος κατειλλημένος από πακεταρισμένα αντικείμενα"
+
+#: lib/database.tcl:48
+msgid "Packed objects waiting for pruning"
+msgstr "Πακεταρισμένα αντικείμενα έτοιμα για κλάδεμα"
+
+#: lib/database.tcl:49
+msgid "Garbage files"
+msgstr "Άχρηστα αρχεία"
+
+#: lib/database.tcl:72
+msgid "Compressing the object database"
+msgstr "Γίνεται συμπίεση της βάσης δεδομένων αντικειμένων"
+
+#: lib/database.tcl:83
+msgid "Verifying the object database with fsck-objects"
+msgstr ""
+"Γίνεται επαλήθευση της βάσης δεδομένων αντικειμένων με αντικείμενα fsck"
+
+#: lib/database.tcl:108
+#, tcl-format
+msgid ""
+"This repository currently has approximately %i loose objects.\n"
+"\n"
+"To maintain optimal performance it is strongly recommended that you compress "
+"the database when more than %i loose objects exist.\n"
+"\n"
+"Compress the database now?"
+msgstr ""
+"Αυτό το αποθετήριο έχει αυτή τη στιγμή περίπου %i ελεύθερα αντικείμενα.\n"
+"\n"
+"Για τη διατήρηση βέλτιστων επιδόσεων συνιστάται να συμπιέσετε τη βάση "
+"δεδομένων όταν υπάρχουν περισσότερα από %i ελεύθερα αντικείμενα.\n"
+"\n"
+"Συμπίεση της βάσης δεδομένων τώρα;"
+
+#: lib/date.tcl:25
+#, tcl-format
+msgid "Invalid date from Git: %s"
+msgstr "Μη έγκυρη ημερομηνία από το Git: %s"
+
+#: lib/diff.tcl:42
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
+"\n"
+"A rescan will be automatically started to find other files which may have "
+"the same state."
+msgstr ""
+"Δεν ανιχνεύθηκαν διαφορές.\n"
+"\n"
+"Το %s δεν έχει αλλαγές."
+"\n"
+"Η ημερομηνία τροποποίησης αυτού του αρχείου ενημερώθηκε από άλλη εφαρμογή, "
+"αλλά το περιεχόμενο του αρχείου δεν άλλαξε.\n"
+"\n"
+"Θα ξεκινήσει αυτόματα επανανίχνευση για να βρεθούν άλλα αρχεία που μπορεί να "
+"βρίσκονται σε ίδια κατάσταση."
+
+#: lib/diff.tcl:81
+#, tcl-format
+msgid "Loading diff of %s..."
+msgstr "Γίνεται φόρτωση διαφοράς του %s..."
+
+#: lib/diff.tcl:114 lib/diff.tcl:184
+#, tcl-format
+msgid "Unable to display %s"
+msgstr "Δεν είναι δυνατή η προβολή του %s"
+
+#: lib/diff.tcl:115
+msgid "Error loading file:"
+msgstr "Σφάλμα φόρτωσης αρχείου:"
+
+#: lib/diff.tcl:122
+msgid "Git Repository (subproject)"
+msgstr "Αποθετήριο Git (θυγατρικό έργο)"
+
+#: lib/diff.tcl:134
+msgid "* Binary file (not showing content)."
+msgstr "* Δυαδικό αρχείο (μη εμφάνιση περιεχομένου)."
+
+#: lib/diff.tcl:185
+msgid "Error loading diff:"
+msgstr "Σφάλμα φόρτωσης διαφοράς:"
+
+#: lib/diff.tcl:303
+msgid "Failed to unstage selected hunk."
+msgstr "Αποτυχία αποσταδιοποίησης επιλεγμένου κομματιού."
+
+#: lib/diff.tcl:310
+msgid "Failed to stage selected hunk."
+msgstr "Αποτυχία σταδιοποίησης επιλεγμένου κομματιού."
+
+#: lib/error.tcl:20 lib/error.tcl:114
+msgid "error"
+msgstr "σφάλμα"
+
+#: lib/error.tcl:36
+msgid "warning"
+msgstr "προειδοποίηση"
+
+#: lib/error.tcl:94
+msgid "You must correct the above errors before committing."
+msgstr "Πρέπει να διορθώσετε τα παραπάνω λάθη πριν την υποβολή."
+
+#: lib/index.tcl:6
+msgid "Unable to unlock the index."
+msgstr "Αδυναμία ξεκλειδώματος του ευρετηρίου."
+
+#: lib/index.tcl:15
+msgid "Index Error"
+msgstr "Σφάλμα Ευρετηρίου"
+
+#: lib/index.tcl:21
+msgid ""
+"Updating the Git index failed. A rescan will be automatically started to "
+"resynchronize git-gui."
+msgstr ""
+"Η ενημέρωση του ευρετηρίου Git απέτυχε. Θα ξεκινήσει αυτόματα επανανίχνευση "
+"για επανασυγχρονισμό του git-gui."
+
+#: lib/index.tcl:27
+msgid "Continue"
+msgstr "Συνέχεια"
+
+#: lib/index.tcl:31
+msgid "Unlock Index"
+msgstr "Ξεκλείδωμα Ευρετηρίου"
+
+#: lib/index.tcl:282
+#, tcl-format
+msgid "Unstaging %s from commit"
+msgstr "Αποσταδιοποίηση %s από υποβολή"
+
+#: lib/index.tcl:313
+msgid "Ready to commit."
+msgstr "Έτοιμο προς υποβολή."
+
+#: lib/index.tcl:326
+#, tcl-format
+msgid "Adding %s"
+msgstr "Προσθήκη %s"
+
+#: lib/index.tcl:381
+#, tcl-format
+msgid "Revert changes in file %s?"
+msgstr "Αναίρεση αλλαγών στο αρχείο %s;"
+
+#: lib/index.tcl:383
+#, tcl-format
+msgid "Revert changes in these %i files?"
+msgstr "Αναίρεση αλλαγών σε αυτά τα %i αρχεία;"
+
+#: lib/index.tcl:391
+msgid "Any unstaged changes will be permanently lost by the revert."
+msgstr ""
+"Όλες οι μη σταδιοποιημένες αλλαγές θα χαθούν οριστικά από την αναίρεση."
+
+#: lib/index.tcl:394
+msgid "Do Nothing"
+msgstr "Καμία Ενέργεια"
+
+#: lib/merge.tcl:13
+msgid ""
+"Cannot merge while amending.\n"
+"\n"
+"You must finish amending this commit before starting any type of merge.\n"
+msgstr ""
+"Δε γίνεται συγχώνευση καθώς διορθώνετε.\n"
+"\n"
+"Πρέπει να τελειώσετε τη διόρθωση αυτής της υποβολής πριν να ξεκινήσετε "
+"οποιασδήποτε μορφής συγχώνευση.\n"
+
+#: lib/merge.tcl:27
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before a merge can be performed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Η τελευταία κατάσταση που ανιχνεύθηκε δε συμφωνεί με την κατάσταση του "
+"αποθετηρίου.\n"
+"\n"
+"Κάποιο άλλο πρόγραμμα Git τροποποίησε το αποθετήριο από την τελευταία "
+"ανίχνευση. Πρέπει να γίνει επανανίχνευση πριν τη διενέργεια συγχώνευσης.\n"
+"\n"
+"Η επανανίχνευση θα ξεκινήσει αυτόματα τώρα.\n"
+
+#: lib/merge.tcl:44
+#, tcl-format
+msgid ""
+"You are in the middle of a conflicted merge.\n"
+"\n"
+"File %s has merge conflicts.\n"
+"\n"
+"You must resolve them, stage the file, and commit to complete the current "
+"merge. Only then can you begin another merge.\n"
+msgstr ""
+"Βρίσκεστε στο μέσο μιας συγκρουόμενης συγχώνευσης.\n"
+"\n"
+"Το αρχείο %s έχει συγκρούσεις συγχώνευσης.\n"
+"\n"
+"Πρέπει να τις επιλύσετε, να σταδιοποιήσετε το αρχείο, και να κάνετε υποβολή "
+"για να ολοκληρώσετε την τρέχουσα συγχώνευση. Μόνο τότε μπορείτε να "
+"ξεκινήσετε άλλη συγχώνευση.\n"
+
+#: lib/merge.tcl:54
+#, tcl-format
+msgid ""
+"You are in the middle of a change.\n"
+"\n"
+"File %s is modified.\n"
+"\n"
+"You should complete the current commit before starting a merge. Doing so "
+"will help you abort a failed merge, should the need arise.\n"
+msgstr ""
+"Βρίσκεστε στο μέσο μιας αλλαγής.\n"
+"\n"
+"Το αρχείο %s έχει τροποποιηθεί.\n"
+"\n"
+"Πρέπει να ολοκληρώσετε την τρέχουσα συγχώνευση πριν να ξεκινήσετε συγχώνευση."
+" Αυτό βοηθά στην ακύρωση αποτυχημένης συγχώνευσης, εάν χρειαστεί.\n"
+
+#: lib/merge.tcl:106
+#, tcl-format
+msgid "%s of %s"
+msgstr "%s από %s"
+
+#: lib/merge.tcl:119
+#, tcl-format
+msgid "Merging %s and %s..."
+msgstr "Γίνεται συγχώνευση του %s με το %s..."
+
+#: lib/merge.tcl:130
+msgid "Merge completed successfully."
+msgstr "Η συγχώνευση ολοκληρώθηκε επιτυχώς."
+
+#: lib/merge.tcl:132
+msgid "Merge failed. Conflict resolution is required."
+msgstr "Η συγχώνευση απέτυχε. Απαιτείται επίλυση συγκρούσεων."
+
+#: lib/merge.tcl:157
+#, tcl-format
+msgid "Merge Into %s"
+msgstr "Συγχώνευση με %s"
+
+#: lib/merge.tcl:176
+msgid "Revision To Merge"
+msgstr "Αναθεώρηση Προς Συγχώνευση"
+
+#: lib/merge.tcl:211
+msgid ""
+"Cannot abort while amending.\n"
+"\n"
+"You must finish amending this commit.\n"
+msgstr ""
+"Δε γίνεται ακύρωση καθώς διορθώνετε.\n"
+"\n"
+"Πρέπει να τελειώσετε τη διόρθωση αυτής της υποβολής.\n"
+
+#: lib/merge.tcl:221
+msgid ""
+"Abort merge?\n"
+"\n"
+"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with aborting the current merge?"
+msgstr ""
+"Ακύρωση συγχώνευσης;\n"
+"\n"
+"Η ακύρωση της τρέχουσας συγχώνευσης θα προκαλέσει απώλεια *ΟΛΩΝ* των μη "
+"υποβεβλημένων αλλαγών.\n"
+"\n"
+"Να προχωρήσει η ακύρωση της τρέχουσας συγχώνευσης;"
+
+#: lib/merge.tcl:227
+msgid ""
+"Reset changes?\n"
+"\n"
+"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with resetting the current changes?"
+msgstr ""
+"Επαναφορά αλλαγών;\n"
+"\n"
+"Η επαναφορά των αλλαγών θα προκαλέσει απώλεια *ΟΛΩΝ* των μη υποβεβλημένων "
+"αλλαγών.\n"
+"\n"
+"Να συνεχίσει η επαναφορά των τρέχουσων αλλαγών;"
+
+#: lib/merge.tcl:238
+msgid "Aborting"
+msgstr "Γίνεται ακύρωση"
+
+#: lib/merge.tcl:238
+msgid "files reset"
+msgstr "αρχεία που επαναφέρθηκαν"
+
+#: lib/merge.tcl:265
+msgid "Abort failed."
+msgstr "Η ακύρωση απέτυχε."
+
+#: lib/merge.tcl:267
+msgid "Abort completed. Ready."
+msgstr "Η ακύρωση απέτυχε. Έτοιμο."
+
+#: lib/option.tcl:95
+msgid "Restore Defaults"
+msgstr "Επαναφορά Προεπιλογών"
+
+#: lib/option.tcl:99
+msgid "Save"
+msgstr "Αποθήκευση"
+
+#: lib/option.tcl:109
+#, tcl-format
+msgid "%s Repository"
+msgstr "%s Αποθετήριο"
+
+#: lib/option.tcl:110
+msgid "Global (All Repositories)"
+msgstr "Ολικό (Όλα τα Αποθετήρια)"
+
+#: lib/option.tcl:116
+msgid "User Name"
+msgstr "Όνομα Χρήστη"
+
+#: lib/option.tcl:117
+msgid "Email Address"
+msgstr "Διεύθυνση Email"
+
+#: lib/option.tcl:119
+msgid "Summarize Merge Commits"
+msgstr "Περίληψη Υποβολών Συγχώνευσης"
+
+#: lib/option.tcl:120
+msgid "Merge Verbosity"
+msgstr "Λεπτομέρεια Συγχώνευσης"
+
+#: lib/option.tcl:121
+msgid "Show Diffstat After Merge"
+msgstr "Προβολή Στατιστικών Διαφοράς Μετά από Συγχώνευση"
+
+#: lib/option.tcl:123
+msgid "Trust File Modification Timestamps"
+msgstr "Εμπιστοσύνη Ημερομηνιών Μετατροπής Αρχείων"
+
+#: lib/option.tcl:124
+msgid "Prune Tracking Branches During Fetch"
+msgstr "Κλάδεμα Κλάδων Παρακολούθησης Κατά Την Ανάκτηση"
+
+#: lib/option.tcl:125
+msgid "Match Tracking Branches"
+msgstr "Συμφωνία Κλάδων Παρακολούθησης"
+
+#: lib/option.tcl:126
+msgid "Number of Diff Context Lines"
+msgstr "Αριθμός Γραμμών Εννοιολογικού Πλαισίου Διαφοράς"
+
+#: lib/option.tcl:127
+msgid "Commit Message Text Width"
+msgstr "Πλάτος Κειμένου Μηνύματος Υποβολής"
+
+#: lib/option.tcl:128
+msgid "New Branch Name Template"
+msgstr "Νέο Πρότυπο Ονόματος Κλάδου"
+
+#: lib/option.tcl:192
+msgid "Spelling Dictionary:"
+msgstr "Λεξικό Ορθογραφίας:"
+
+#: lib/option.tcl:216
+msgid "Change Font"
+msgstr "Αλλαγή Γραμματοσειράς"
+
+#: lib/option.tcl:220
+#, tcl-format
+msgid "Choose %s"
+msgstr "Επιλογή %s"
+
+#: lib/option.tcl:226
+#, fuzzy
+msgid "pt."
+msgstr ""
+
+#: lib/option.tcl:240
+msgid "Preferences"
+msgstr "Προτιμήσεις"
+
+#: lib/option.tcl:275
+msgid "Failed to completely save options:"
+msgstr "Αποτυχία πλήρους αποθήκευσης επιλογών:"
+
+#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
+msgid "Delete Remote Branch"
+msgstr "Διαγραφή Απομακρυσμένου Κλάδου"
+
+#: lib/remote_branch_delete.tcl:47
+msgid "From Repository"
+msgstr "Από Αποθετήριο"
+
+#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123
+msgid "Remote:"
+msgstr "Απομακρυσμένο:"
+
+#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138
+#, fuzzy
+msgid "Arbitrary URL:"
+msgstr "Αυθαίρετο URL:"
+
+#: lib/remote_branch_delete.tcl:84
+msgid "Branches"
+msgstr "Κλάδοι"
+
+#: lib/remote_branch_delete.tcl:109
+msgid "Delete Only If"
+msgstr "Διαγραφή Μόνο Εάν"
+
+#: lib/remote_branch_delete.tcl:111
+msgid "Merged Into:"
+msgstr "Συγχωνευμένο Με:"
+
+#: lib/remote_branch_delete.tcl:119
+msgid "Always (Do not perform merge checks)"
+msgstr "Πάντα (Μη διενεργηθούν έλεγχοι συγχώνευσης)"
+
+#: lib/remote_branch_delete.tcl:152
+msgid "A branch is required for 'Merged Into'."
+msgstr "Απαιτείται ένας κλάδος για 'Συγχωνευμένο Με'."
+
+#: lib/remote_branch_delete.tcl:184
+#, tcl-format
+msgid ""
+"The following branches are not completely merged into %s:\n"
+"\n"
+" - %s"
+msgstr ""
+"Οι εξής κλάδοι δεν είναι πλήρως συγχωνευμένοι με το %s:\n"
+"\n"
+" - %s"
+
+#: lib/remote_branch_delete.tcl:189
+#, tcl-format
+msgid ""
+"One or more of the merge tests failed because you have not fetched the "
+"necessary commits. Try fetching from %s first."
+msgstr ""
+"Μία ή περισσότερες από τις δοκιμές συγχώνευσης απέτυχαν επειδή δεν έχετε "
+"φέρει τις αναγκαίες υποβολές. Δοκιμάστε ανάκτηση από το %s πρώτα."
+
+#: lib/remote_branch_delete.tcl:207
+msgid "Please select one or more branches to delete."
+msgstr "Παρακαλώ επιλέξτε έναν ή περισσότερους κλάδους προς διαγραφή."
+
+#: lib/remote_branch_delete.tcl:216
+msgid ""
+"Recovering deleted branches is difficult.\n"
+"\n"
+"Delete the selected branches?"
+msgstr ""
+"Η ανάκτηση διεγραμμένων κλάδων είναι δύσκολη.\n"
+"\n"
+"Διαγραφή των επιλεγμένων κλάδων;"
+
+#: lib/remote_branch_delete.tcl:226
+#, tcl-format
+msgid "Deleting branches from %s"
+msgstr "Γίνεται διαγραφή κλάδων από %s"
+
+#: lib/remote_branch_delete.tcl:286
+msgid "No repository selected."
+msgstr "Δεν έχει επιλεγεί αποθετήριο."
+
+#: lib/remote_branch_delete.tcl:291
+#, tcl-format
+msgid "Scanning %s..."
+msgstr "Ανίχνευση %s..."
+
+#: lib/remote.tcl:165
+msgid "Prune from"
+msgstr "Κλάδεμα από"
+
+#: lib/remote.tcl:170
+msgid "Fetch from"
+msgstr "Ανάκτηση από"
+
+#: lib/remote.tcl:213
+msgid "Push to"
+msgstr "Ώθηση σε"
+
+#: lib/shortcut.tcl:20 lib/shortcut.tcl:61
+msgid "Cannot write shortcut:"
+msgstr "Δε μπόρεσε να αποθηκευτεί η συντόμευση:"
+
+#: lib/shortcut.tcl:136
+msgid "Cannot write icon:"
+msgstr "Δε μπόρεσε να αποθηκευτεί το εικονίδιο:"
+
+#: lib/spellcheck.tcl:57
+msgid "Unsupported spell checker"
+msgstr "Mη υποστηριζόμενος ελεγκτής ορθογραφίας"
+
+#: lib/spellcheck.tcl:65
+msgid "Spell checking is unavailable"
+msgstr "Έλεγχος ορθογραφίας μη διαθέσιμος"
+
+#: lib/spellcheck.tcl:68
+msgid "Invalid spell checking configuration"
+msgstr "Μη έγκυρη ρύθμιση ελέγχου ορθογραφίας"
+
+#: lib/spellcheck.tcl:70
+#, tcl-format
+msgid "Reverting dictionary to %s."
+msgstr "Γίνεται επαναφορά του λεξικού σε %s."
+
+#: lib/spellcheck.tcl:73
+msgid "Spell checker silently failed on startup"
+msgstr "Ο ελεγκτής ορθογραφίας απέτυχε σιωπηλά κατά την εκκίνηση"
+
+#: lib/spellcheck.tcl:80
+msgid "Unrecognized spell checker"
+msgstr "Μη αναγνωρίσιμος ελεγκτής ορθογραφίας"
+
+#: lib/spellcheck.tcl:180
+msgid "No Suggestions"
+msgstr "Καμία Πρόταση"
+
+#: lib/spellcheck.tcl:381
+msgid "Unexpected EOF from spell checker"
+msgstr "Μη αναμενόμενο τέλος αρχείου από τον ελεγκτή ορθογραφίας"
+
+#: lib/spellcheck.tcl:385
+msgid "Spell Checker Failed"
+msgstr "Αποτυχία Ελεγκτή Ορθογραφίας"
+
+#: lib/status_bar.tcl:83
+#, tcl-format
+msgid "%s ... %*i of %*i %s (%3i%%)"
+msgstr "%s ... %*i από %*i %s (%3i%%)"
+
+#: lib/transport.tcl:6
+#, tcl-format
+msgid "fetch %s"
+msgstr "ανάκτηση %s"
+
+#: lib/transport.tcl:7
+#, tcl-format
+msgid "Fetching new changes from %s"
+msgstr "Ανάκτηση νέων αλλαγών από το %s"
+
+#: lib/transport.tcl:18
+#, tcl-format
+msgid "remote prune %s"
+msgstr "απομακρυσμένο κλάδεμα %s"
+
+#: lib/transport.tcl:19
+#, tcl-format
+msgid "Pruning tracking branches deleted from %s"
+msgstr "Γίνεται κλάδεμα κλάδων παρακολούθησης που διεγράφησαν από το %s"
+
+#: lib/transport.tcl:25 lib/transport.tcl:71
+#, tcl-format
+msgid "push %s"
+msgstr "ώθηση %s"
+
+#: lib/transport.tcl:26
+#, tcl-format
+msgid "Pushing changes to %s"
+msgstr "Γίνεται ώθηση αλλαγών στο %s"
+
+#: lib/transport.tcl:72
+#, tcl-format
+msgid "Pushing %s %s to %s"
+msgstr "Γίνεται ώθηση %s %s στο %s"
+
+#: lib/transport.tcl:89
+msgid "Push Branches"
+msgstr "Ώθηση Κλάδων"
+
+#: lib/transport.tcl:103
+msgid "Source Branches"
+msgstr "Πηγαίοι Κλάδοι"
+
+#: lib/transport.tcl:120
+msgid "Destination Repository"
+msgstr "Αποθετήριο Προορισμού"
+
+#: lib/transport.tcl:158
+msgid "Transfer Options"
+msgstr "Επιλογές Μεταφοράς"
+
+#: lib/transport.tcl:160
+msgid "Force overwrite existing branch (may discard changes)"
+msgstr ""
+"Εξαναγκασμός επεγγραφής υπάρχοντος κλάδου (μπορεί να απορρίψει αλλαγές)"
+
+#: lib/transport.tcl:164
+msgid "Use thin pack (for slow network connections)"
+msgstr "Χρήση ισχνού πακέτου (για αργές συνδέσεις δικτύου)"
+
+#: lib/transport.tcl:168
+msgid "Include tags"
+msgstr "Συμπερίληψη ετικετών"
+
+
diff --git a/git-gui/po/git-gui.pot b/git-gui/po/git-gui.pot
index 53b7d3634d..074582d979 100644
--- a/git-gui/po/git-gui.pot
+++ b/git-gui/po/git-gui.pot
@@ -90,6 +90,11 @@ msgstr ""
msgid "Ready."
msgstr ""
+#: git-gui.sh:1726
+#, tcl-format
+msgid "Displaying only %s of %s files."
+msgstr ""
+
#: git-gui.sh:1819
msgid "Unmodified"
msgstr ""
diff --git a/git-gui/po/glossary/el.po b/git-gui/po/glossary/el.po
new file mode 100644
index 0000000000..1d3cc818d5
--- /dev/null
+++ b/git-gui/po/glossary/el.po
@@ -0,0 +1,171 @@
+# Translation of git-gui glossary to Greek
+# Copyright (C) 2009 Jimmy Angelakos
+# This file is distributed under the same license as the git-gui package.
+# Jimmy Angelakos <vyruss@hellug.gr>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: git-gui-glossary\n"
+"POT-Creation-Date: 2008-01-07 21:20+0100\n"
+"PO-Revision-Date: 2009-06-23 20:41+0300\n"
+"Last-Translator: Jimmy Angelakos <vyruss@hellug.gr>\n"
+"Language-Team: Greek <i18n@lists.hellug.gr>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Lokalize 0.3\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. "English Definition (Dear translator: This file will never be visible to the user! It should only serve as a tool for you, the translator. Nothing more.)"
+msgid "English Term (Dear translator: This file will never be visible to the user!)"
+msgstr ""
+
+#. ""
+msgid "amend"
+msgstr "διόρθωση"
+
+#. ""
+msgid "annotate"
+msgstr "σχολιασμός"
+
+#. "A 'branch' is an active line of development."
+msgid "branch [noun]"
+msgstr "κλάδος [αντικείμενο]"
+
+#. ""
+msgid "branch [verb]"
+msgstr "διακλάδωση [ενέργεια]"
+
+#. ""
+msgid "checkout [noun]"
+msgstr "εξαγωγή [αντικείμενο]"
+
+#. "The action of updating the working tree to a revision which was stored in the object database."
+msgid "checkout [verb]"
+msgstr "εξαγωγή [ενέργεια]"
+
+#. ""
+msgid "clone [verb]"
+msgstr "κλωνοποίηση [ενέργεια]"
+
+#. "A single point in the git history."
+msgid "commit [noun]"
+msgstr "υποβολή [αντικείμενο] "
+
+#. "The action of storing a new snapshot of the project's state in the git history."
+msgid "commit [verb]"
+msgstr "υποβολή [ενέργεια]"
+
+#. ""
+msgid "diff [noun]"
+msgstr "διαφορά [αντικείμενο] "
+
+#. ""
+msgid "diff [verb]"
+msgstr "διαφορά [ενέργεια]"
+
+#. "A fast-forward is a special type of merge where you have a revision and you are merging another branch's changes that happen to be a descendant of what you have."
+msgid "fast forward merge"
+msgstr "συγχώνευση επιτάχυνσης"
+
+#. "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too."
+msgid "fetch"
+msgstr "ανάκτηση"
+
+#. "One context of consecutive lines in a whole patch, which consists of many such hunks"
+msgid "hunk"
+msgstr "κομμάτι"
+
+#. "A collection of files. The index is a stored version of your working tree."
+msgid "index (in git-gui: staging area)"
+msgstr "ευρετήριο (στο git-gui: περιοχή σταδιοποίησης)"
+
+#. "A successful merge results in the creation of a new commit representing the result of the merge."
+msgid "merge [noun]"
+msgstr "συγχώνευση [αντικείμενο]"
+
+#. "To bring the contents of another branch into the current branch."
+msgid "merge [verb]"
+msgstr "συγχώνευση [ενέργεια]"
+
+#. ""
+msgid "message"
+msgstr "μήνυμα"
+
+#. "Deletes all stale tracking branches under <name>. These stale branches have already been removed from the remote repository referenced by <name>, but are still locally available in 'remotes/<name>'."
+msgid "prune"
+msgstr "κλάδεμα"
+
+#. "Pulling a branch means to fetch it and merge it."
+msgid "pull"
+msgstr "λήψη"
+
+#. "Pushing a branch means to get the branch's head ref from a remote repository, and ... (well, can someone please explain it for mere mortals?)"
+msgid "push"
+msgstr "ώθηση"
+
+#. ""
+msgid "redo"
+msgstr "ξανά"
+
+#. "An other repository ('remote'). One might have a set of remotes whose branches one tracks."
+msgid "remote"
+msgstr "απομακρυσμένο"
+
+#. "A collection of refs (?) together with an object database containing all objects which are reachable from the refs... (oops, you've lost me here. Again, please an explanation for mere mortals?)"
+msgid "repository"
+msgstr "αποθετήριο"
+
+#. ""
+msgid "reset"
+msgstr "επαναφορά"
+
+#. ""
+msgid "revert"
+msgstr "αναίρεση"
+
+#. "A particular state of files and directories which was stored in the object database."
+msgid "revision"
+msgstr "αναθεώρηση"
+
+#. ""
+#, fuzzy
+msgid "sign off"
+msgstr "αποσύνδεση"
+
+#. ""
+msgid "staging area"
+msgstr "περιοχή σταδιοποίησης"
+
+#. ""
+msgid "status"
+msgstr "κατάσταση"
+
+#. "A ref pointing to a tag or commit object"
+msgid "tag [noun]"
+msgstr "ετικέτα [αντικείμενο]"
+
+#. ""
+msgid "tag [verb]"
+msgstr "ετικέτα [ενέργεια]"
+
+#. "A regular git branch that is used to follow changes from another repository."
+msgid "tracking branch"
+msgstr "κλάδος παρακολούθησης"
+
+#. ""
+msgid "undo"
+msgstr "αναίρεση"
+
+#. ""
+msgid "update"
+msgstr "ενημέρωση"
+
+#. ""
+msgid "verify"
+msgstr "επαλήθευση"
+
+#. "The tree of actual checked out files."
+msgid "working copy, working tree"
+msgstr "αντίγραφο εργασίας"
+
+
diff --git a/git-gui/po/ru.po b/git-gui/po/ru.po
index 0ffc4a418f..364c074c50 100644
--- a/git-gui/po/ru.po
+++ b/git-gui/po/ru.po
@@ -90,12 +90,18 @@ msgstr "Вызов программы поддержки репозитория
#: git-gui.sh:1384
msgid "Commit declined by prepare-commit-msg hook."
-msgstr "Сохранение прервано программой поддержки репозитория prepare-commit-msg"
+msgstr ""
+"Сохранение прервано программой поддержки репозитория prepare-commit-msg"
#: git-gui.sh:1542 lib/browser.tcl:246
msgid "Ready."
msgstr "Готово."
+#: git-gui.sh:1726
+#, tcl-format
+msgid "Displaying only %s of %s files."
+msgstr "Показано %s из %s файлов."
+
#: git-gui.sh:1819
msgid "Unmodified"
msgstr "Не изменено"
@@ -1297,8 +1303,8 @@ msgid ""
msgstr ""
"Невозможно исправить состояние во время операции слияния.\n"
"\n"
-"Текущее слияние не завершено. Невозможно исправить предыдущее "
-"сохраненное состояние, не прерывая эту операцию.\n"
+"Текущее слияние не завершено. Невозможно исправить предыдущее сохраненное "
+"состояние, не прерывая эту операцию.\n"
#: lib/commit.tcl:48
msgid "Error loading commit data for amend:"
@@ -1723,8 +1729,7 @@ msgid ""
msgstr ""
"Невозможно выполнить слияние во время исправления.\n"
"\n"
-"Завершите исправление данного состояния перед выполнением операции "
-"слияния.\n"
+"Завершите исправление данного состояния перед выполнением операции слияния.\n"
#: lib/merge.tcl:27
msgid ""
@@ -1888,8 +1893,8 @@ msgstr ""
#, tcl-format
msgid "File %s seems to have unresolved conflicts, still stage?"
msgstr ""
-"Файл %s кажется содержит необработаные конфликты. "
-"Продолжить подготовку к сохранению?"
+"Файл %s кажется содержит необработаные конфликты. Продолжить подготовку к "
+"сохранению?"
#: lib/mergetool.tcl:60
#, tcl-format
@@ -2213,8 +2218,8 @@ msgid ""
"One or more of the merge tests failed because you have not fetched the "
"necessary commits. Try fetching from %s first."
msgstr ""
-"Некоторые тесты на слияние не прошли, потому что Вы не "
-"получили необходимые состояния. Попытайтесь получить их из %s."
+"Некоторые тесты на слияние не прошли, потому что Вы не получили необходимые "
+"состояния. Попытайтесь получить их из %s."
#: lib/remote_branch_delete.tcl:207
msgid "Please select one or more branches to delete."
@@ -2381,8 +2386,8 @@ msgstr "Выполнение: %s"
#: lib/tools.tcl:149
#, tcl-format
-msgid "Tool completed succesfully: %s"
-msgstr "Программа %s успешно завершилась."
+msgid "Tool completed successfully: %s"
+msgstr "Программа %s завершилась успешно."
#: lib/tools.tcl:151
#, tcl-format
@@ -2538,4 +2543,3 @@ msgstr "Использовать thin pack (для медленных сетев
#: lib/transport.tcl:179
msgid "Include tags"
msgstr "Передать метки"
-
diff --git a/git-instaweb.sh b/git-instaweb.sh
index d96eddbe56..622a5f0eb2 100755
--- a/git-instaweb.sh
+++ b/git-instaweb.sh
@@ -317,7 +317,21 @@ EOF
resolve_full_httpd
list_mods=$(echo "$full_httpd" | sed "s/-f$/-l/")
$list_mods | grep 'mod_cgi\.c' >/dev/null 2>&1 || \
- echo "LoadModule cgi_module $module_path/mod_cgi.so" >> "$conf"
+ if test -f "$module_path/mod_cgi.so"
+ then
+ echo "LoadModule cgi_module $module_path/mod_cgi.so" >> "$conf"
+ else
+ $list_mods | grep 'mod_cgid\.c' >/dev/null 2>&1 || \
+ if test -f "$module_path/mod_cgid.so"
+ then
+ echo "LoadModule cgid_module $module_path/mod_cgid.so" \
+ >> "$conf"
+ else
+ echo "You have no CGI support!"
+ exit 2
+ fi
+ echo "ScriptSock logs/gitweb.sock" >> "$conf"
+ fi
cat >> "$conf" <<EOF
AddHandler cgi-script .cgi
<Location /gitweb.cgi>
diff --git a/git-pull.sh b/git-pull.sh
index fc78592ae0..37f3d93017 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -16,7 +16,8 @@ cd_to_toplevel
test -z "$(git ls-files -u)" ||
die "You are in the middle of a conflicted merge."
-strategy_args= diffstat= no_commit= squash= no_ff= log_arg= verbosity=
+strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
+log_arg= verbosity=
curr_branch=$(git symbolic-ref -q HEAD)
curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||")
rebase=$(git config --bool branch.$curr_branch_short.rebase)
@@ -45,6 +46,8 @@ do
no_ff=--ff ;;
--no-ff)
no_ff=--no-ff ;;
+ --ff-only)
+ ff_only=--ff-only ;;
-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
--strateg=*|--strategy=*|\
-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
@@ -215,5 +218,5 @@ merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
test true = "$rebase" &&
exec git-rebase $diffstat $strategy_args --onto $merge_head \
${oldremoteref:-$merge_head}
-exec git-merge $diffstat $no_commit $squash $no_ff $log_arg $strategy_args \
+exec git-merge $diffstat $no_commit $squash $no_ff $ff_only $log_arg $strategy_args \
"$merge_name" HEAD $merge_head $verbosity
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 9b1e899e27..53ad248ee5 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -340,6 +340,14 @@ do_next () {
pick_one $sha1 ||
die_with_patch $sha1 "Could not apply $sha1... $rest"
;;
+ reword|r)
+ comment_for_reflog reword
+
+ mark_action_done
+ pick_one $sha1 ||
+ die_with_patch $sha1 "Could not apply $sha1... $rest"
+ git commit --amend
+ ;;
edit|e)
comment_for_reflog edit
@@ -757,6 +765,7 @@ first and then run 'git rebase --continue' again."
#
# Commands:
# p, pick = use commit
+# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
#
diff --git a/git-stash.sh b/git-stash.sh
index 4febbbfa5d..f796c2fe24 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -205,8 +205,7 @@ have_stash () {
list_stash () {
have_stash || return 0
- git log --no-color --pretty=oneline -g "$@" $ref_stash -- |
- sed -n -e 's/^[.0-9a-f]* refs\///p'
+ git log --format="%gd: %gs" -g "$@" $ref_stash --
}
show_stash () {
@@ -383,11 +382,6 @@ test -n "$seen_non_option" || set "save" "$@"
case "$1" in
list)
shift
- if test $# = 0
- then
- set x -n 10
- shift
- fi
list_stash "$@"
;;
show)
diff --git a/git-svn.perl b/git-svn.perl
index eb4b75aff3..6a3b501d24 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1765,7 +1765,7 @@ sub read_all_remotes {
my $use_svm_props = eval { command_oneline(qw/config --bool
svn.useSvmProps/) };
$use_svm_props = $use_svm_props eq 'true' if $use_svm_props;
- my $svn_refspec = qr{\s*/?(.*?)\s*:\s*(.+?)\s*};
+ my $svn_refspec = qr{\s*(.*?)\s*:\s*(.+?)\s*};
foreach (grep { s/^svn-remote\.// } command(qw/config -l/)) {
if (m!^(.+)\.fetch=$svn_refspec$!) {
my ($remote, $local_ref, $remote_ref) = ($1, $2, $3);
@@ -1979,7 +1979,7 @@ sub find_ref {
my ($ref_id) = @_;
foreach (command(qw/config -l/)) {
next unless m!^svn-remote\.(.+)\.fetch=
- \s*/?(.*?)\s*:\s*(.+?)\s*$!x;
+ \s*(.*?)\s*:\s*(.+?)\s*$!x;
my ($repo_id, $path, $ref) = ($1, $2, $3);
if ($ref eq $ref_id) {
$path = '' if ($path =~ m#^\./?#);
@@ -2878,14 +2878,157 @@ sub check_author {
$author;
}
+sub find_extra_svk_parents {
+ my ($self, $ed, $tickets, $parents) = @_;
+ # aha! svk:merge property changed...
+ my @tickets = split "\n", $tickets;
+ my @known_parents;
+ for my $ticket ( @tickets ) {
+ my ($uuid, $path, $rev) = split /:/, $ticket;
+ if ( $uuid eq $self->ra_uuid ) {
+ my $url = $self->rewrite_root || $self->{url};
+ my $repos_root = $url;
+ my $branch_from = $path;
+ $branch_from =~ s{^/}{};
+ my $gs = $self->other_gs($repos_root."/".$branch_from,
+ $url,
+ $branch_from,
+ $rev,
+ $self->{ref_id});
+ if ( my $commit = $gs->rev_map_get($rev, $uuid) ) {
+ # wahey! we found it, but it might be
+ # an old one (!)
+ push @known_parents, $commit;
+ }
+ }
+ }
+ for my $parent ( @known_parents ) {
+ my @cmd = ('rev-list', $parent, map { "^$_" } @$parents );
+ my ($msg_fh, $ctx) = command_output_pipe(@cmd);
+ my $new;
+ while ( <$msg_fh> ) {
+ $new=1;last;
+ }
+ command_close_pipe($msg_fh, $ctx);
+ if ( $new ) {
+ print STDERR
+ "Found merge parent (svk:merge ticket): $parent\n";
+ push @$parents, $parent;
+ }
+ }
+}
+
+# note: this function should only be called if the various dirprops
+# have actually changed
+sub find_extra_svn_parents {
+ my ($self, $ed, $mergeinfo, $parents) = @_;
+ # aha! svk:merge property changed...
+
+ # We first search for merged tips which are not in our
+ # history. Then, we figure out which git revisions are in
+ # that tip, but not this revision. If all of those revisions
+ # are now marked as merge, we can add the tip as a parent.
+ my @merges = split "\n", $mergeinfo;
+ my @merge_tips;
+ my @merged_commit_ranges;
+ my $url = $self->rewrite_root || $self->{url};
+ for my $merge ( @merges ) {
+ my ($source, $revs) = split ":", $merge;
+ my $path = $source;
+ $path =~ s{^/}{};
+ my $gs = Git::SVN->find_by_url($url.$source, $url, $path);
+ if ( !$gs ) {
+ warn "Couldn't find revmap for $url$source\n";
+ next;
+ }
+ my @ranges = split ",", $revs;
+ my ($tip, $tip_commit);
+ # find the tip
+ for my $range ( @ranges ) {
+ my ($bottom, $top) = split "-", $range;
+ $top ||= $bottom;
+ my $bottom_commit =
+ $gs->rev_map_get($bottom, $self->ra_uuid) ||
+ $gs->rev_map_get($bottom+1, $self->ra_uuid);
+ my $top_commit =
+ $gs->rev_map_get($top, $self->ra_uuid);
+
+ unless ($top_commit and $bottom_commit) {
+ warn "W:unknown path/rev in svn:mergeinfo "
+ ."dirprop: $source:$range\n";
+ next;
+ }
+
+ push @merged_commit_ranges,
+ "$bottom_commit..$top_commit";
+
+ if ( !defined $tip or $top > $tip ) {
+ $tip = $top;
+ $tip_commit = $top_commit;
+ }
+ }
+ unless (!$tip_commit or
+ grep { $_ eq $tip_commit } @$parents ) {
+ push @merge_tips, $tip_commit;
+ } else {
+ push @merge_tips, undef;
+ }
+ }
+ for my $merge_tip ( @merge_tips ) {
+ my $spec = shift @merges;
+ next unless $merge_tip;
+ my @cmd = ('rev-list', "-1", $merge_tip,
+ "--not", @$parents );
+ my ($msg_fh, $ctx) = command_output_pipe(@cmd);
+ my $new;
+ while ( <$msg_fh> ) {
+ $new=1;last;
+ }
+ command_close_pipe($msg_fh, $ctx);
+ if ( $new ) {
+ push @cmd, @merged_commit_ranges;
+ my ($msg_fh, $ctx) = command_output_pipe(@cmd);
+ my $unmerged;
+ while ( <$msg_fh> ) {
+ $unmerged=1;last;
+ }
+ command_close_pipe($msg_fh, $ctx);
+ if ( $unmerged ) {
+ warn "W:svn cherry-pick ignored ($spec)\n";
+ } else {
+ warn
+ "Found merge parent (svn:mergeinfo prop): ",
+ $merge_tip, "\n";
+ push @$parents, $merge_tip;
+ }
+ }
+ }
+}
+
sub make_log_entry {
my ($self, $rev, $parents, $ed) = @_;
my $untracked = $self->get_untracked($ed);
+ my @parents = @$parents;
+ my $ps = $ed->{path_strip} || "";
+ for my $path ( grep { m/$ps/ } %{$ed->{dir_prop}} ) {
+ my $props = $ed->{dir_prop}{$path};
+ if ( $props->{"svk:merge"} ) {
+ $self->find_extra_svk_parents
+ ($ed, $props->{"svk:merge"}, \@parents);
+ }
+ if ( $props->{"svn:mergeinfo"} ) {
+ $self->find_extra_svn_parents
+ ($ed,
+ $props->{"svn:mergeinfo"},
+ \@parents);
+ }
+ }
+
open my $un, '>>', "$self->{dir}/unhandled.log" or croak $!;
print $un "r$rev\n" or croak $!;
print $un $_, "\n" foreach @$untracked;
- my %log_entry = ( parents => $parents || [], revision => $rev,
+ my %log_entry = ( parents => \@parents, revision => $rev,
log => '');
my $headrev;
diff --git a/git.c b/git.c
index 9883009b5d..bd2c5fe77b 100644
--- a/git.c
+++ b/git.c
@@ -6,7 +6,7 @@
const char git_usage_string[] =
"git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]\n"
- " [-p|--paginate|--no-pager]\n"
+ " [-p|--paginate|--no-pager] [--no-replace-objects]\n"
" [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]\n"
" [--help] COMMAND [ARGS]";
@@ -87,6 +87,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
use_pager = 0;
if (envchanged)
*envchanged = 1;
+ } else if (!strcmp(cmd, "--no-replace-objects")) {
+ read_replace_refs = 0;
} else if (!strcmp(cmd, "--git-dir")) {
if (*argc < 2) {
fprintf(stderr, "No directory given for --git-dir.\n" );
diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 8f68fe3091..cb3f0baf05 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -32,6 +32,10 @@ img.avatar {
vertical-align: middle;
}
+a.list img.avatar {
+ border-style: none;
+}
+
div.page_header {
height: 25px;
padding: 8px;
@@ -341,6 +345,12 @@ td.mode {
font-family: monospace;
}
+/* format of (optional) objects size in 'tree' view */
+td.size {
+ font-family: monospace;
+ text-align: right;
+}
+
/* styling of diffs (patchsets): commitdiff and blobdiff views */
div.diff.header,
div.diff.extended_header {
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 24b219310a..62325ea877 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -297,6 +297,19 @@ our %feature = (
'override' => 0,
'default' => [1]},
+ # Enable showing size of blobs in a 'tree' view, in a separate
+ # column, similar to what 'ls -l' does. This cost a bit of IO.
+
+ # To disable system wide have in $GITWEB_CONFIG
+ # $feature{'show-sizes'}{'default'} = [0];
+ # To have project specific config enable override in $GITWEB_CONFIG
+ # $feature{'show-sizes'}{'override'} = 1;
+ # and in project config gitweb.showsizes = 0|1;
+ 'show-sizes' => {
+ 'sub' => sub { feature_bool('showsizes', @_) },
+ 'override' => 0,
+ 'default' => [1]},
+
# Make gitweb use an alternative format of the URLs which can be
# more readable and natural-looking: project name is embedded
# directly in the path and the query string contains other
@@ -1083,8 +1096,7 @@ sub to_utf8 {
# correct, but quoted slashes look too horrible in bookmarks
sub esc_param {
my $str = shift;
- $str =~ s/([^A-Za-z0-9\-_.~()\/:@])/sprintf("%%%02X", ord($1))/eg;
- $str =~ s/\+/%2B/g;
+ $str =~ s/([^A-Za-z0-9\-_.~()\/:@ ]+)/CGI::escape($1)/eg;
$str =~ s/ /\+/g;
return $str;
}
@@ -1595,6 +1607,29 @@ sub git_get_avatar {
}
}
+sub format_search_author {
+ my ($author, $searchtype, $displaytext) = @_;
+ my $have_search = gitweb_check_feature('search');
+
+ if ($have_search) {
+ my $performed = "";
+ if ($searchtype eq 'author') {
+ $performed = "authored";
+ } elsif ($searchtype eq 'committer') {
+ $performed = "committed";
+ }
+
+ return $cgi->a({-href => href(action=>"search", hash=>$hash,
+ searchtext=>$author,
+ searchtype=>$searchtype), class=>"list",
+ title=>"Search for commits $performed by $author"},
+ $displaytext);
+
+ } else {
+ return $displaytext;
+ }
+}
+
# format the author name of the given commit with the given tag
# the author name is chopped and escaped according to the other
# optional parameters (see chop_str).
@@ -1603,8 +1638,10 @@ sub format_author_html {
my $co = shift;
my $author = chop_and_escape_str($co->{'author_name'}, @_);
return "<$tag class=\"author\">" .
- git_get_avatar($co->{'author_email'}, -pad_after => 1) .
- $author . "</$tag>";
+ format_search_author($co->{'author_name'}, "author",
+ git_get_avatar($co->{'author_email'}, -pad_after => 1) .
+ $author) .
+ "</$tag>";
}
# format git diff header line, i.e. "diff --(git|combined|cc) ..."
@@ -2764,16 +2801,31 @@ sub parse_ls_tree_line {
my %opts = @_;
my %res;
- #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c'
- $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/s;
+ if ($opts{'-l'}) {
+ #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa 16717 panic.c'
+ $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40}) +(-|[0-9]+)\t(.+)$/s;
- $res{'mode'} = $1;
- $res{'type'} = $2;
- $res{'hash'} = $3;
- if ($opts{'-z'}) {
- $res{'name'} = $4;
+ $res{'mode'} = $1;
+ $res{'type'} = $2;
+ $res{'hash'} = $3;
+ $res{'size'} = $4;
+ if ($opts{'-z'}) {
+ $res{'name'} = $5;
+ } else {
+ $res{'name'} = unquote($5);
+ }
} else {
- $res{'name'} = unquote($4);
+ #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c'
+ $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/s;
+
+ $res{'mode'} = $1;
+ $res{'type'} = $2;
+ $res{'hash'} = $3;
+ if ($opts{'-z'}) {
+ $res{'name'} = $4;
+ } else {
+ $res{'name'} = unquote($4);
+ }
}
return wantarray ? %res : \%res;
@@ -3373,10 +3425,11 @@ sub git_print_authorship {
my $co = shift;
my %opts = @_;
my $tag = $opts{-tag} || 'div';
+ my $author = $co->{'author_name'};
my %ad = parse_date($co->{'author_epoch'}, $co->{'author_tz'});
print "<$tag class=\"author_date\">" .
- esc_html($co->{'author_name'}) .
+ format_search_author($author, "author", esc_html($author)) .
" [$ad{'rfc2822'}";
print_local_time(%ad) if ($opts{-localtime});
print "]" . git_get_avatar($co->{'author_email'}, -pad_before => 1)
@@ -3395,8 +3448,12 @@ sub git_print_authorship_rows {
@people = ('author', 'committer') unless @people;
foreach my $who (@people) {
my %wd = parse_date($co->{"${who}_epoch"}, $co->{"${who}_tz"});
- print "<tr><td>$who</td><td>" . esc_html($co->{$who}) . "</td>" .
- "<td rowspan=\"2\">" .
+ print "<tr><td>$who</td><td>" .
+ format_search_author($co->{"${who}_name"}, $who,
+ esc_html($co->{"${who}_name"})) . " " .
+ format_search_author($co->{"${who}_email"}, $who,
+ esc_html("<" . $co->{"${who}_email"} . ">")) .
+ "</td><td rowspan=\"2\">" .
git_get_avatar($co->{"${who}_email"}, -size => 'double') .
"</td></tr>\n" .
"<tr>" .
@@ -3564,6 +3621,9 @@ sub git_print_tree_entry {
# and link is the action links of the entry.
print "<td class=\"mode\">" . mode_str($t->{'mode'}) . "</td>\n";
+ if (exists $t->{'size'}) {
+ print "<td class=\"size\">$t->{'size'}</td>\n";
+ }
if ($t->{'type'} eq "blob") {
print "<td class=\"list\">" .
$cgi->a({-href => href(action=>"blob", hash=>$t->{'hash'},
@@ -3609,12 +3669,14 @@ sub git_print_tree_entry {
} elsif ($t->{'type'} eq "tree") {
print "<td class=\"list\">";
print $cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'},
- file_name=>"$basedir$t->{'name'}", %base_key)},
+ file_name=>"$basedir$t->{'name'}",
+ %base_key)},
esc_path($t->{'name'}));
print "</td>\n";
print "<td class=\"link\">";
print $cgi->a({-href => href(action=>"tree", hash=>$t->{'hash'},
- file_name=>"$basedir$t->{'name'}", %base_key)},
+ file_name=>"$basedir$t->{'name'}",
+ %base_key)},
"tree");
if (defined $hash_base) {
print " | " .
@@ -5065,7 +5127,8 @@ sub git_blob {
chomp $line;
$nr++;
$line = untabify($line);
- printf "<div class=\"pre\"><a id=\"l%i\" href=\"#l%i\" class=\"linenr\">%4i</a> %s</div>\n",
+ printf "<div class=\"pre\"><a id=\"l%i\" href=\"" . href(-replay => 1)
+ . "#l%i\" class=\"linenr\">%4i</a> %s</div>\n",
$nr, $nr, $nr, esc_html($line, -nbsp=>1);
}
}
@@ -5088,10 +5151,14 @@ sub git_tree {
}
die_error(404, "No such tree") unless defined($hash);
+ my $show_sizes = gitweb_check_feature('show-sizes');
+ my $have_blame = gitweb_check_feature('blame');
+
my @entries = ();
{
local $/ = "\0";
- open my $fd, "-|", git_cmd(), "ls-tree", '-z', $hash
+ open my $fd, "-|", git_cmd(), "ls-tree", '-z',
+ ($show_sizes ? '-l' : ()), @extra_options, $hash
or die_error(500, "Open git-ls-tree failed");
@entries = map { chomp; $_ } <$fd>;
close $fd
@@ -5102,7 +5169,6 @@ sub git_tree {
my $ref = format_ref_marker($refs, $hash_base);
git_header_html();
my $basedir = '';
- my $have_blame = gitweb_check_feature('blame');
if (defined $hash_base && (my %co = parse_commit($hash_base))) {
my @views_nav = ();
if (defined $file_name) {
@@ -5118,7 +5184,8 @@ sub git_tree {
# FIXME: Should be available when we have no hash base as well.
push @views_nav, $snapshot_links;
}
- git_print_page_nav('tree','', $hash_base, undef, undef, join(' | ', @views_nav));
+ git_print_page_nav('tree','', $hash_base, undef, undef,
+ join(' | ', @views_nav));
git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base);
} else {
undef $hash_base;
@@ -5151,8 +5218,10 @@ sub git_tree {
undef $up unless $up;
# based on git_print_tree_entry
print '<td class="mode">' . mode_str('040000') . "</td>\n";
+ print '<td class="size">&nbsp;</td>'."\n" if $show_sizes;
print '<td class="list">';
- print $cgi->a({-href => href(action=>"tree", hash_base=>$hash_base,
+ print $cgi->a({-href => href(action=>"tree",
+ hash_base=>$hash_base,
file_name=>$up)},
"..");
print "</td>\n";
@@ -5161,7 +5230,7 @@ sub git_tree {
print "</tr>\n";
}
foreach my $line (@entries) {
- my %t = parse_ls_tree_line($line, -z => 1);
+ my %t = parse_ls_tree_line($line, -z => 1, -l => $show_sizes);
if ($alternate) {
print "<tr class=\"dark\">\n";
@@ -5328,7 +5397,7 @@ sub git_commit {
} @$parents ) .
')';
}
- if (gitweb_check_feature('patches')) {
+ if (gitweb_check_feature('patches') && @$parents <= 1) {
$formats_nav .= " | " .
$cgi->a({-href => href(action=>"patch", -replay=>1)},
"patch");
@@ -5616,7 +5685,7 @@ sub git_commitdiff {
$formats_nav =
$cgi->a({-href => href(action=>"commitdiff_plain", -replay=>1)},
"raw");
- if ($patch_max) {
+ if ($patch_max && @{$co{'parents'}} <= 1) {
$formats_nav .= " | " .
$cgi->a({-href => href(action=>"patch", -replay=>1)},
"patch");
@@ -5824,7 +5893,7 @@ sub git_commitdiff_plain {
# format-patch-style patches
sub git_patch {
- git_commitdiff(-format => 'patch', -single=> 1);
+ git_commitdiff(-format => 'patch', -single => 1);
}
sub git_patches {
diff --git a/imap-send.c b/imap-send.c
index 3847fd151d..f805c6ed81 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -273,7 +273,11 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
fprintf(stderr, "SSL requested but SSL support not compiled in\n");
return -1;
#else
+#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
+ const SSL_METHOD *meth;
+#else
SSL_METHOD *meth;
+#endif
SSL_CTX *ctx;
int ret;
diff --git a/log-tree.c b/log-tree.c
index 1618f3c79a..0fdf159f80 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -43,6 +43,7 @@ void load_ref_decorations(int flags)
if (!loaded) {
loaded = 1;
for_each_ref(add_ref_decoration, &flags);
+ head_ref(add_ref_decoration, &flags);
}
}
@@ -178,8 +179,10 @@ void get_patch_filename(struct commit *commit, int nr, const char *suffix,
strbuf_addf(buf, commit ? "%04d-" : "%d", nr);
if (commit) {
int max_len = start_len + FORMAT_PATCH_NAME_MAX - suffix_len;
+ struct pretty_print_context ctx = {0};
+ ctx.date_mode = DATE_NORMAL;
- format_commit_message(commit, "%f", buf, DATE_NORMAL);
+ format_commit_message(commit, "%f", buf, &ctx);
if (max_len < buf->len)
strbuf_setlen(buf, max_len);
strbuf_addstr(buf, suffix);
@@ -276,10 +279,9 @@ void show_log(struct rev_info *opt)
struct strbuf msgbuf = STRBUF_INIT;
struct log_info *log = opt->loginfo;
struct commit *commit = log->commit, *parent = log->parent;
- int abbrev = opt->diffopt.abbrev;
int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;
- const char *subject = NULL, *extra_headers = opt->extra_headers;
- int need_8bit_cte = 0;
+ const char *extra_headers = opt->extra_headers;
+ struct pretty_print_context ctx = {0};
opt->loginfo = NULL;
if (!opt->verbose_header) {
@@ -346,8 +348,8 @@ void show_log(struct rev_info *opt)
*/
if (opt->commit_format == CMIT_FMT_EMAIL) {
- log_write_email_headers(opt, commit, &subject, &extra_headers,
- &need_8bit_cte);
+ log_write_email_headers(opt, commit, &ctx.subject, &extra_headers,
+ &ctx.need_8bit_cte);
} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
if (opt->commit_format != CMIT_FMT_ONELINE)
@@ -404,11 +406,13 @@ void show_log(struct rev_info *opt)
/*
* And then the pretty-printed message itself
*/
- if (need_8bit_cte >= 0)
- need_8bit_cte = has_non_ascii(opt->add_signoff);
- pretty_print_commit(opt->commit_format, commit, &msgbuf,
- abbrev, subject, extra_headers, opt->date_mode,
- need_8bit_cte);
+ if (ctx.need_8bit_cte >= 0)
+ ctx.need_8bit_cte = has_non_ascii(opt->add_signoff);
+ ctx.date_mode = opt->date_mode;
+ ctx.abbrev = opt->diffopt.abbrev;
+ ctx.after_subject = extra_headers;
+ ctx.reflog_info = opt->reflog_info;
+ pretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);
if (opt->add_signoff)
append_signoff(&msgbuf, opt->add_signoff);
diff --git a/pretty.c b/pretty.c
index f5983f8baa..da15cf2a80 100644
--- a/pretty.c
+++ b/pretty.c
@@ -7,6 +7,7 @@
#include "mailmap.h"
#include "log-tree.h"
#include "color.h"
+#include "reflog-walk.h"
static char *user_format;
@@ -442,7 +443,7 @@ struct chunk {
struct format_commit_context {
const struct commit *commit;
- enum date_mode dmode;
+ const struct pretty_print_context *pretty_ctx;
unsigned commit_header_parsed:1;
unsigned commit_message_parsed:1;
@@ -701,6 +702,22 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
case 'd':
format_decoration(sb, commit);
return 1;
+ case 'g': /* reflog info */
+ switch(placeholder[1]) {
+ case 'd': /* reflog selector */
+ case 'D':
+ if (c->pretty_ctx->reflog_info)
+ get_reflog_selector(sb,
+ c->pretty_ctx->reflog_info,
+ c->pretty_ctx->date_mode,
+ (placeholder[1] == 'd'));
+ return 2;
+ case 's': /* reflog message */
+ if (c->pretty_ctx->reflog_info)
+ get_reflog_message(sb, c->pretty_ctx->reflog_info);
+ return 2;
+ }
+ return 0; /* unknown %g placeholder */
}
/* For the rest we have to parse the commit header. */
@@ -711,11 +728,11 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
case 'a': /* author ... */
return format_person_part(sb, placeholder[1],
msg + c->author.off, c->author.len,
- c->dmode);
+ c->pretty_ctx->date_mode);
case 'c': /* committer ... */
return format_person_part(sb, placeholder[1],
msg + c->committer.off, c->committer.len,
- c->dmode);
+ c->pretty_ctx->date_mode);
case 'e': /* encoding */
strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
return 1;
@@ -740,14 +757,14 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
}
void format_commit_message(const struct commit *commit,
- const void *format, struct strbuf *sb,
- enum date_mode dmode)
+ const char *format, struct strbuf *sb,
+ const struct pretty_print_context *pretty_ctx)
{
struct format_commit_context context;
memset(&context, 0, sizeof(context));
context.commit = commit;
- context.dmode = dmode;
+ context.pretty_ctx = pretty_ctx;
strbuf_expand(sb, format, format_commit_item, &context);
}
@@ -900,18 +917,18 @@ char *reencode_commit_message(const struct commit *commit, const char **encoding
}
void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
- struct strbuf *sb, int abbrev,
- const char *subject, const char *after_subject,
- enum date_mode dmode, int need_8bit_cte)
+ struct strbuf *sb,
+ const struct pretty_print_context *context)
{
unsigned long beginning_of_body;
int indent = 4;
const char *msg = commit->buffer;
char *reencoded;
const char *encoding;
+ int need_8bit_cte = context->need_8bit_cte;
if (fmt == CMIT_FMT_USERFORMAT) {
- format_commit_message(commit, user_format, sb, dmode);
+ format_commit_message(commit, user_format, sb, context);
return;
}
@@ -946,8 +963,9 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
}
}
- pp_header(fmt, abbrev, dmode, encoding, commit, &msg, sb);
- if (fmt != CMIT_FMT_ONELINE && !subject) {
+ pp_header(fmt, context->abbrev, context->date_mode, encoding,
+ commit, &msg, sb);
+ if (fmt != CMIT_FMT_ONELINE && !context->subject) {
strbuf_addch(sb, '\n');
}
@@ -956,8 +974,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
/* These formats treat the title line specially. */
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
- pp_title_line(fmt, &msg, sb, subject,
- after_subject, encoding, need_8bit_cte);
+ pp_title_line(fmt, &msg, sb, context->subject,
+ context->after_subject, encoding, need_8bit_cte);
beginning_of_body = sb->len;
if (fmt != CMIT_FMT_ONELINE)
diff --git a/reflog-walk.c b/reflog-walk.c
index 5623ea6b48..caba4f743f 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -8,6 +8,7 @@
struct complete_reflogs {
char *ref;
+ const char *short_ref;
struct reflog_info {
unsigned char osha1[20], nsha1[20];
char *email;
@@ -241,36 +242,74 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
commit->object.flags &= ~(ADDED | SEEN | SHOWN);
}
-void show_reflog_message(struct reflog_walk_info *info, int oneline,
+void get_reflog_selector(struct strbuf *sb,
+ struct reflog_walk_info *reflog_info,
+ enum date_mode dmode,
+ int shorten)
+{
+ struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+ struct reflog_info *info;
+ const char *printed_ref;
+
+ if (!commit_reflog)
+ return;
+
+ if (shorten) {
+ if (!commit_reflog->reflogs->short_ref)
+ commit_reflog->reflogs->short_ref
+ = shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0);
+ printed_ref = commit_reflog->reflogs->short_ref;
+ } else {
+ printed_ref = commit_reflog->reflogs->ref;
+ }
+
+ strbuf_addf(sb, "%s@{", printed_ref);
+ if (commit_reflog->flag || dmode) {
+ info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+ strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));
+ } else {
+ strbuf_addf(sb, "%d", commit_reflog->reflogs->nr
+ - 2 - commit_reflog->recno);
+ }
+
+ strbuf_addch(sb, '}');
+}
+
+void get_reflog_message(struct strbuf *sb,
+ struct reflog_walk_info *reflog_info)
+{
+ struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+ struct reflog_info *info;
+ size_t len;
+
+ if (!commit_reflog)
+ return;
+
+ info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+ len = strlen(info->message);
+ if (len > 0)
+ len--; /* strip away trailing newline */
+ strbuf_add(sb, info->message, len);
+}
+
+void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
enum date_mode dmode)
{
- if (info && info->last_commit_reflog) {
- struct commit_reflog *commit_reflog = info->last_commit_reflog;
+ if (reflog_info && reflog_info->last_commit_reflog) {
+ struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
struct reflog_info *info;
+ struct strbuf selector = STRBUF_INIT;
info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
+ get_reflog_selector(&selector, reflog_info, dmode, 0);
if (oneline) {
- printf("%s@{", commit_reflog->reflogs->ref);
- if (commit_reflog->flag || dmode)
- printf("%s", show_date(info->timestamp,
- info->tz,
- dmode));
- else
- printf("%d", commit_reflog->reflogs->nr
- - 2 - commit_reflog->recno);
- printf("}: %s", info->message);
+ printf("%s: %s", selector.buf, info->message);
}
else {
- printf("Reflog: %s@{", commit_reflog->reflogs->ref);
- if (commit_reflog->flag || dmode)
- printf("%s", show_date(info->timestamp,
- info->tz,
- dmode));
- else
- printf("%d", commit_reflog->reflogs->nr
- - 2 - commit_reflog->recno);
- printf("} (%s)\nReflog message: %s",
- info->email, info->message);
+ printf("Reflog: %s (%s)\nReflog message: %s",
+ selector.buf, info->email, info->message);
}
+
+ strbuf_release(&selector);
}
}
diff --git a/reflog-walk.h b/reflog-walk.h
index 74c90964bd..7bd2cd4c4e 100644
--- a/reflog-walk.h
+++ b/reflog-walk.h
@@ -3,6 +3,8 @@
#include "cache.h"
+struct reflog_walk_info;
+
extern void init_reflog_walk(struct reflog_walk_info** info);
extern int add_reflog_for_walk(struct reflog_walk_info *info,
struct commit *commit, const char *name);
@@ -10,5 +12,11 @@ extern void fake_reflog_parent(struct reflog_walk_info *info,
struct commit *commit);
extern void show_reflog_message(struct reflog_walk_info *info, int,
enum date_mode);
+extern void get_reflog_message(struct strbuf *sb,
+ struct reflog_walk_info *reflog_info);
+extern void get_reflog_selector(struct strbuf *sb,
+ struct reflog_walk_info *reflog_info,
+ enum date_mode dmode,
+ int shorten);
#endif
diff --git a/setup.c b/setup.c
index 029371e584..f67250b7c1 100644
--- a/setup.c
+++ b/setup.c
@@ -61,6 +61,19 @@ const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
return path;
}
+int check_filename(const char *prefix, const char *arg)
+{
+ const char *name;
+ struct stat st;
+
+ name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
+ if (!lstat(name, &st))
+ return 1; /* file exists */
+ if (errno == ENOENT || errno == ENOTDIR)
+ return 0; /* file does not exist */
+ die_errno("failed to stat '%s'", arg);
+}
+
/*
* Verify a filename that we got as an argument for a pathspec
* entry. Note that a filename that begins with "-" never verifies
@@ -70,18 +83,12 @@ const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
*/
void verify_filename(const char *prefix, const char *arg)
{
- const char *name;
- struct stat st;
-
if (*arg == '-')
die("bad flag '%s' used after filename", arg);
- name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
- if (!lstat(name, &st))
+ if (check_filename(prefix, arg))
return;
- if (errno == ENOENT)
- die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
- "Use '--' to separate paths from revisions", arg);
- die_errno("failed to stat '%s'", arg);
+ die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
+ "Use '--' to separate paths from revisions", arg);
}
/*
@@ -91,19 +98,14 @@ void verify_filename(const char *prefix, const char *arg)
*/
void verify_non_filename(const char *prefix, const char *arg)
{
- const char *name;
- struct stat st;
-
if (!is_inside_work_tree() || is_inside_git_dir())
return;
if (*arg == '-')
return; /* flag */
- name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
- if (!lstat(name, &st))
- die("ambiguous argument '%s': both revision and filename\n"
- "Use '--' to separate filenames from revisions", arg);
- if (errno != ENOENT && errno != ENOTDIR)
- die_errno("failed to stat '%s'", arg);
+ if (!check_filename(prefix, arg))
+ return;
+ die("ambiguous argument '%s': both revision and filename\n"
+ "Use '--' to separate filenames from revisions", arg);
}
const char **get_pathspec(const char *prefix, const char **pathspec)
diff --git a/submodule.c b/submodule.c
new file mode 100644
index 0000000000..461faf0e00
--- /dev/null
+++ b/submodule.c
@@ -0,0 +1,114 @@
+#include "cache.h"
+#include "submodule.h"
+#include "dir.h"
+#include "diff.h"
+#include "commit.h"
+#include "revision.h"
+
+int add_submodule_odb(const char *path)
+{
+ struct strbuf objects_directory = STRBUF_INIT;
+ struct alternate_object_database *alt_odb;
+
+ strbuf_addf(&objects_directory, "%s/.git/objects/", path);
+ if (!is_directory(objects_directory.buf))
+ return -1;
+
+ /* avoid adding it twice */
+ for (alt_odb = alt_odb_list; alt_odb; alt_odb = alt_odb->next)
+ if (alt_odb->name - alt_odb->base == objects_directory.len &&
+ !strncmp(alt_odb->base, objects_directory.buf,
+ objects_directory.len))
+ return 0;
+
+ alt_odb = xmalloc(objects_directory.len + 42 + sizeof(*alt_odb));
+ alt_odb->next = alt_odb_list;
+ strcpy(alt_odb->base, objects_directory.buf);
+ alt_odb->name = alt_odb->base + objects_directory.len;
+ alt_odb->name[2] = '/';
+ alt_odb->name[40] = '\0';
+ alt_odb->name[41] = '\0';
+ alt_odb_list = alt_odb;
+ prepare_alt_odb();
+ return 0;
+}
+
+void show_submodule_summary(FILE *f, const char *path,
+ unsigned char one[20], unsigned char two[20],
+ const char *del, const char *add, const char *reset)
+{
+ struct rev_info rev;
+ struct commit *commit, *left = left, *right;
+ struct commit_list *merge_bases, *list;
+ const char *message = NULL;
+ struct strbuf sb = STRBUF_INIT;
+ static const char *format = " %m %s";
+ int fast_forward = 0, fast_backward = 0;
+
+ if (is_null_sha1(two))
+ message = "(submodule deleted)";
+ else if (add_submodule_odb(path))
+ message = "(not checked out)";
+ else if (is_null_sha1(one))
+ message = "(new submodule)";
+ else if (!(left = lookup_commit_reference(one)) ||
+ !(right = lookup_commit_reference(two)))
+ message = "(commits not present)";
+
+ if (!message) {
+ init_revisions(&rev, NULL);
+ setup_revisions(0, NULL, &rev, NULL);
+ rev.left_right = 1;
+ rev.first_parent_only = 1;
+ left->object.flags |= SYMMETRIC_LEFT;
+ add_pending_object(&rev, &left->object, path);
+ add_pending_object(&rev, &right->object, path);
+ merge_bases = get_merge_bases(left, right, 1);
+ if (merge_bases) {
+ if (merge_bases->item == left)
+ fast_forward = 1;
+ else if (merge_bases->item == right)
+ fast_backward = 1;
+ }
+ for (list = merge_bases; list; list = list->next) {
+ list->item->object.flags |= UNINTERESTING;
+ add_pending_object(&rev, &list->item->object,
+ sha1_to_hex(list->item->object.sha1));
+ }
+ if (prepare_revision_walk(&rev))
+ message = "(revision walker failed)";
+ }
+
+ strbuf_addf(&sb, "Submodule %s %s..", path,
+ find_unique_abbrev(one, DEFAULT_ABBREV));
+ if (!fast_backward && !fast_forward)
+ strbuf_addch(&sb, '.');
+ strbuf_addf(&sb, "%s", find_unique_abbrev(two, DEFAULT_ABBREV));
+ if (message)
+ strbuf_addf(&sb, " %s\n", message);
+ else
+ strbuf_addf(&sb, "%s:\n", fast_backward ? " (rewind)" : "");
+ fwrite(sb.buf, sb.len, 1, f);
+
+ if (!message) {
+ while ((commit = get_revision(&rev))) {
+ struct pretty_print_context ctx = {0};
+ ctx.date_mode = rev.date_mode;
+ strbuf_setlen(&sb, 0);
+ if (commit->object.flags & SYMMETRIC_LEFT) {
+ if (del)
+ strbuf_addstr(&sb, del);
+ }
+ else if (add)
+ strbuf_addstr(&sb, add);
+ format_commit_message(commit, format, &sb, &ctx);
+ if (reset)
+ strbuf_addstr(&sb, reset);
+ strbuf_addch(&sb, '\n');
+ fprintf(f, "%s", sb.buf);
+ }
+ clear_commit_marks(left, ~0);
+ clear_commit_marks(right, ~0);
+ }
+ strbuf_release(&sb);
+}
diff --git a/submodule.h b/submodule.h
new file mode 100644
index 0000000000..4c0269d679
--- /dev/null
+++ b/submodule.h
@@ -0,0 +1,8 @@
+#ifndef SUBMODULE_H
+#define SUBMODULE_H
+
+void show_submodule_summary(FILE *f, const char *path,
+ unsigned char one[20], unsigned char two[20],
+ const char *del, const char *add, const char *reset);
+
+#endif
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index fd8631f906..0f7f35ccc9 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -16,6 +16,7 @@ fi
GIT_DIR=$PWD/.git
GIT_SVN_DIR=$GIT_DIR/svn/refs/remotes/git-svn
SVN_TREE=$GIT_SVN_DIR/svn-tree
+PERL=${PERL:-perl}
svn >/dev/null 2>&1
if test $? -ne 1
@@ -29,7 +30,7 @@ export svnrepo
svnconf=$PWD/svnconf
export svnconf
-perl -w -e "
+$PERL -w -e "
use SVN::Core;
use SVN::Repos;
\$SVN::Core::VERSION gt '1.1.0' or exit(42);
@@ -130,7 +131,7 @@ stop_httpd () {
}
convert_to_rev_db () {
- perl -w -- - "$@" <<\EOF
+ $PERL -w -- - "$@" <<\EOF
use strict;
@ARGV == 2 or die "Usage: convert_to_rev_db <input> <output>";
open my $wr, '+>', $ARGV[1] or die "$!: couldn't open: $ARGV[1]";
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 260a231933..62f452c8ea 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -9,8 +9,8 @@
#
# "[<lineno1>] [<lineno2>]..."
#
-# If a line number is prefixed with "squash" or "edit", the respective line's
-# command will be replaced with the specified one.
+# If a line number is prefixed with "squash", "edit", or "reword", the
+# respective line's command will be replaced with the specified one.
set_fake_editor () {
echo "#!$SHELL_PATH" >fake-editor.sh
@@ -32,7 +32,7 @@ cat "$1".tmp
action=pick
for line in $FAKE_LINES; do
case $line in
- squash|edit)
+ squash|edit|reword)
action="$line";;
*)
echo sed -n "${line}s/^pick/$action/p"
diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh
new file mode 100755
index 0000000000..eb45afb018
--- /dev/null
+++ b/t/t1402-check-ref-format.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+test_description='Test git check-ref-format'
+
+. ./test-lib.sh
+
+valid_ref() {
+ test_expect_success "ref name '$1' is valid" \
+ "git check-ref-format '$1'"
+}
+invalid_ref() {
+ test_expect_success "ref name '$1' is not valid" \
+ "test_must_fail git check-ref-format '$1'"
+}
+
+valid_ref 'heads/foo'
+invalid_ref 'foo'
+valid_ref 'foo/bar/baz'
+valid_ref 'refs///heads/foo'
+invalid_ref 'heads/foo/'
+invalid_ref './foo'
+invalid_ref '.refs/foo'
+invalid_ref 'heads/foo..bar'
+invalid_ref 'heads/foo?bar'
+valid_ref 'foo./bar'
+invalid_ref 'heads/foo.lock'
+valid_ref 'heads/foo@bar'
+invalid_ref 'heads/v@{ation'
+invalid_ref 'heads/foo\bar'
+
+test_expect_success "check-ref-format --branch @{-1}" '
+ T=$(git write-tree) &&
+ sha1=$(echo A | git commit-tree $T) &&
+ git update-ref refs/heads/master $sha1 &&
+ git update-ref refs/remotes/origin/master $sha1
+ git checkout master &&
+ git checkout origin/master &&
+ git checkout master &&
+ refname=$(git check-ref-format --branch @{-1}) &&
+ test "$refname" = "$sha1" &&
+ refname2=$(git check-ref-format --branch @{-2}) &&
+ test "$refname2" = master'
+
+valid_ref_normalized() {
+ test_expect_success "ref name '$1' simplifies to '$2'" "
+ refname=\$(git check-ref-format --print '$1') &&
+ test \"\$refname\" = '$2'"
+}
+invalid_ref_normalized() {
+ test_expect_success "check-ref-format --print rejects '$1'" "
+ test_must_fail git check-ref-format --print '$1'"
+}
+
+valid_ref_normalized 'heads/foo' 'heads/foo'
+valid_ref_normalized 'refs///heads/foo' 'refs/heads/foo'
+invalid_ref_normalized 'foo'
+invalid_ref_normalized 'heads/foo/../bar'
+invalid_ref_normalized 'heads/./foo'
+invalid_ref_normalized 'heads\foo'
+
+test_done
diff --git a/t/t3003-ls-files-exclude.sh b/t/t3003-ls-files-exclude.sh
index fc1e379321..d5ec333131 100755
--- a/t/t3003-ls-files-exclude.sh
+++ b/t/t3003-ls-files-exclude.sh
@@ -29,4 +29,12 @@ test_expect_success 'add file to gitignore' '
'
check_all_output
+test_expect_success 'ls-files -i lists only tracked-but-ignored files' '
+ echo content >other-file &&
+ git add other-file &&
+ echo file >expect &&
+ git ls-files -i --exclude-standard >output &&
+ test_cmp expect output
+'
+
test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 4cae019521..3a37793c0d 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -470,4 +470,18 @@ test_expect_success 'avoid unnecessary reset' '
test 123456789 = $MTIME
'
+test_expect_success 'reword' '
+ git checkout -b reword-branch master &&
+ FAKE_LINES="1 2 3 reword 4" FAKE_COMMIT_MESSAGE="E changed" git rebase -i A &&
+ git show HEAD | grep "E changed" &&
+ test $(git rev-parse master) != $(git rev-parse HEAD) &&
+ test $(git rev-parse master^) = $(git rev-parse HEAD^) &&
+ FAKE_LINES="1 2 reword 3 4" FAKE_COMMIT_MESSAGE="D changed" git rebase -i A &&
+ git show HEAD^ | grep "D changed" &&
+ FAKE_LINES="reword 1 2 3 4" FAKE_COMMIT_MESSAGE="B changed" git rebase -i A &&
+ git show HEAD~3 | grep "B changed" &&
+ FAKE_LINES="1 reword 2 3 4" FAKE_COMMIT_MESSAGE="C changed" git rebase -i A &&
+ git show HEAD~2 | grep "C changed"
+'
+
test_done
diff --git a/t/t4013/diff.log_--decorate=full_--all b/t/t4013/diff.log_--decorate=full_--all
index 903d9d9659..d155e0bab2 100644
--- a/t/t4013/diff.log_--decorate=full_--all
+++ b/t/t4013/diff.log_--decorate=full_--all
@@ -1,5 +1,5 @@
$ git log --decorate=full --all
-commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (refs/heads/master)
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, refs/heads/master)
Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
diff --git a/t/t4013/diff.log_--decorate_--all b/t/t4013/diff.log_--decorate_--all
index 954210ea90..fd7c3e6439 100644
--- a/t/t4013/diff.log_--decorate_--all
+++ b/t/t4013/diff.log_--decorate_--all
@@ -1,5 +1,5 @@
$ git log --decorate --all
-commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (master)
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, master)
Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:04:00 2006 +0000
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 531f5b795c..cab6ce2e97 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -455,6 +455,27 @@ test_expect_success 'format-patch respects -U' '
'
+cat > expect << EOF
+
+diff --git a/file b/file
+index 40f36c6..2dc5c23 100644
+--- a/file
++++ b/file
+@@ -14,3 +14,19 @@ C
+ D
+ E
+ F
++5
+EOF
+
+test_expect_success 'format-patch -p suppresses stat' '
+
+ git format-patch -p -2 &&
+ sed -e "1,/^$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
+ test_cmp expect output
+
+'
+
test_expect_success 'format-patch from a subdirectory (1)' '
filename=$(
rm -rf sub &&
diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh
index 6d13da30da..8dd147d78f 100755
--- a/t/t4015-diff-whitespace.sh
+++ b/t/t4015-diff-whitespace.sh
@@ -362,10 +362,17 @@ test_expect_success 'line numbers in --check output are correct' '
'
-test_expect_success 'checkdiff detects trailing blank lines' '
+test_expect_success 'checkdiff detects new trailing blank lines (1)' '
echo "foo();" >x &&
echo "" >>x &&
- git diff --check | grep "ends with blank"
+ git diff --check | grep "new blank line"
+'
+
+test_expect_success 'checkdiff detects new trailing blank lines (2)' '
+ { echo a; echo b; echo; echo; } >x &&
+ git add x &&
+ { echo a; echo; echo; echo; echo; } >x &&
+ git diff --check | grep "new blank line"
'
test_expect_success 'checkdiff allows new blank lines' '
diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh
index 84a1fe3115..3a3663fbcb 100755
--- a/t/t4019-diff-wserror.sh
+++ b/t/t4019-diff-wserror.sh
@@ -165,7 +165,7 @@ test_expect_success 'trailing empty lines (1)' '
rm -f .gitattributes &&
test_must_fail git diff --check >output &&
- grep "ends with blank lines." output &&
+ grep "new blank line at" output &&
grep "trailing whitespace" output
'
@@ -190,4 +190,13 @@ test_expect_success 'do not color trailing cr in context' '
'
+test_expect_success 'color new trailing blank lines' '
+ { echo a; echo b; echo; echo; } >x &&
+ git add x &&
+ { echo a; echo; echo; echo; echo c; echo; echo; echo; echo; } >x &&
+ git diff --color x >output &&
+ cnt=$(grep "${blue_grep}" output | wc -l) &&
+ test $cnt = 2
+'
+
test_done
diff --git a/t/t4041-diff-submodule.sh b/t/t4041-diff-submodule.sh
new file mode 100755
index 0000000000..5bb4fed3f5
--- /dev/null
+++ b/t/t4041-diff-submodule.sh
@@ -0,0 +1,260 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Jens Lehmann, based on t7401 by Ping Yin
+#
+
+test_description='Support for verbose submodule differences in git diff
+
+This test tries to verify the sanity of the --submodule option of git diff.
+'
+
+. ./test-lib.sh
+
+add_file () {
+ sm=$1
+ shift
+ owd=$(pwd)
+ cd "$sm"
+ for name; do
+ echo "$name" > "$name" &&
+ git add "$name" &&
+ test_tick &&
+ git commit -m "Add $name"
+ done >/dev/null
+ git rev-parse --verify HEAD | cut -c1-7
+ cd "$owd"
+}
+commit_file () {
+ test_tick &&
+ git commit "$@" -m "Commit $*" >/dev/null
+}
+
+test_create_repo sm1 &&
+add_file . foo >/dev/null
+
+head1=$(add_file sm1 foo1 foo2)
+
+test_expect_success 'added submodule' "
+ git add sm1 &&
+ git diff-index -p --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 0000000...$head1 (new submodule)
+EOF
+"
+
+commit_file sm1 &&
+head2=$(add_file sm1 foo3)
+
+test_expect_success 'modified submodule(forward)' "
+ git diff-index -p --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head1..$head2:
+ > Add foo3
+EOF
+"
+
+test_expect_success 'modified submodule(forward)' "
+ git diff --submodule=log >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head1..$head2:
+ > Add foo3
+EOF
+"
+
+test_expect_success 'modified submodule(forward) --submodule' "
+ git diff --submodule >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head1..$head2:
+ > Add foo3
+EOF
+"
+
+fullhead1=$(cd sm1; git rev-list --max-count=1 $head1)
+fullhead2=$(cd sm1; git rev-list --max-count=1 $head2)
+test_expect_success 'modified submodule(forward) --submodule=short' "
+ git diff --submodule=short >actual &&
+ diff actual - <<-EOF
+diff --git a/sm1 b/sm1
+index $head1..$head2 160000
+--- a/sm1
++++ b/sm1
+@@ -1 +1 @@
+-Subproject commit $fullhead1
++Subproject commit $fullhead2
+EOF
+"
+
+commit_file sm1 &&
+cd sm1 &&
+git reset --hard HEAD~2 >/dev/null &&
+head3=$(git rev-parse --verify HEAD | cut -c1-7) &&
+cd ..
+
+test_expect_success 'modified submodule(backward)' "
+ git diff-index -p --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head2..$head3 (rewind):
+ < Add foo3
+ < Add foo2
+EOF
+"
+
+head4=$(add_file sm1 foo4 foo5) &&
+head4_full=$(GIT_DIR=sm1/.git git rev-parse --verify HEAD)
+test_expect_success 'modified submodule(backward and forward)' "
+ git diff-index -p --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head2...$head4:
+ > Add foo5
+ > Add foo4
+ < Add foo3
+ < Add foo2
+EOF
+"
+
+commit_file sm1 &&
+mv sm1 sm1-bak &&
+echo sm1 >sm1 &&
+head5=$(git hash-object sm1 | cut -c1-7) &&
+git add sm1 &&
+rm -f sm1 &&
+mv sm1-bak sm1
+
+test_expect_success 'typechanged submodule(submodule->blob), --cached' "
+ git diff --submodule=log --cached >actual &&
+ diff actual - <<-EOF
+Submodule sm1 41fbea9...0000000 (submodule deleted)
+diff --git a/sm1 b/sm1
+new file mode 100644
+index 0000000..9da5fb8
+--- /dev/null
++++ b/sm1
+@@ -0,0 +1 @@
++sm1
+EOF
+"
+
+test_expect_success 'typechanged submodule(submodule->blob)' "
+ git diff --submodule=log >actual &&
+ diff actual - <<-EOF
+diff --git a/sm1 b/sm1
+deleted file mode 100644
+index 9da5fb8..0000000
+--- a/sm1
++++ /dev/null
+@@ -1 +0,0 @@
+-sm1
+Submodule sm1 0000000...$head4 (new submodule)
+EOF
+"
+
+rm -rf sm1 &&
+git checkout-index sm1
+test_expect_success 'typechanged submodule(submodule->blob)' "
+ git diff-index -p --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head4...0000000 (submodule deleted)
+diff --git a/sm1 b/sm1
+new file mode 100644
+index 0000000..$head5
+--- /dev/null
++++ b/sm1
+@@ -0,0 +1 @@
++sm1
+EOF
+"
+
+rm -f sm1 &&
+test_create_repo sm1 &&
+head6=$(add_file sm1 foo6 foo7)
+fullhead6=$(cd sm1; git rev-list --max-count=1 $head6)
+test_expect_success 'nonexistent commit' "
+ git diff-index -p --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head4...$head6 (commits not present)
+EOF
+"
+
+commit_file
+test_expect_success 'typechanged submodule(blob->submodule)' "
+ git diff-index -p --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+diff --git a/sm1 b/sm1
+deleted file mode 100644
+index $head5..0000000
+--- a/sm1
++++ /dev/null
+@@ -1 +0,0 @@
+-sm1
+Submodule sm1 0000000...$head6 (new submodule)
+EOF
+"
+
+commit_file sm1 &&
+rm -rf sm1
+test_expect_success 'deleted submodule' "
+ git diff-index -p --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head6...0000000 (submodule deleted)
+EOF
+"
+
+test_create_repo sm2 &&
+head7=$(add_file sm2 foo8 foo9) &&
+git add sm2
+
+test_expect_success 'multiple submodules' "
+ git diff-index -p --submodule=log HEAD >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head6...0000000 (submodule deleted)
+Submodule sm2 0000000...$head7 (new submodule)
+EOF
+"
+
+test_expect_success 'path filter' "
+ git diff-index -p --submodule=log HEAD sm2 >actual &&
+ diff actual - <<-EOF
+Submodule sm2 0000000...$head7 (new submodule)
+EOF
+"
+
+commit_file sm2
+test_expect_success 'given commit' "
+ git diff-index -p --submodule=log HEAD^ >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head6...0000000 (submodule deleted)
+Submodule sm2 0000000...$head7 (new submodule)
+EOF
+"
+
+test_expect_success 'given commit --submodule' "
+ git diff-index -p --submodule HEAD^ >actual &&
+ diff actual - <<-EOF
+Submodule sm1 $head6...0000000 (submodule deleted)
+Submodule sm2 0000000...$head7 (new submodule)
+EOF
+"
+
+fullhead7=$(cd sm2; git rev-list --max-count=1 $head7)
+
+test_expect_success 'given commit --submodule=short' "
+ git diff-index -p --submodule=short HEAD^ >actual &&
+ diff actual - <<-EOF
+diff --git a/sm1 b/sm1
+deleted file mode 160000
+index $head6..0000000
+--- a/sm1
++++ /dev/null
+@@ -1 +0,0 @@
+-Subproject commit $fullhead6
+diff --git a/sm2 b/sm2
+new file mode 160000
+index 0000000..$head7
+--- /dev/null
++++ b/sm2
+@@ -0,0 +1 @@
++Subproject commit $fullhead7
+EOF
+"
+
+test_done
diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh
index fac2093d7f..ca26397590 100755
--- a/t/t4124-apply-ws-rule.sh
+++ b/t/t4124-apply-ws-rule.sh
@@ -170,4 +170,95 @@ test_expect_success 'trailing whitespace & no newline at the end of file' '
grep "^$" target
'
+test_expect_success 'blank at EOF with --whitespace=fix (1)' '
+ : these can fail depending on what we did before
+ git config --unset core.whitespace
+ rm -f .gitattributes
+
+ { echo a; echo b; echo c; } >one &&
+ git add one &&
+ { echo a; echo b; echo c; } >expect &&
+ { cat expect; echo; } >one &&
+ git diff -- one >patch &&
+
+ git checkout one &&
+ git apply --whitespace=fix patch &&
+ test_cmp expect one
+'
+
+test_expect_success 'blank at EOF with --whitespace=fix (2)' '
+ { echo a; echo b; echo c; } >one &&
+ git add one &&
+ { echo a; echo c; } >expect &&
+ { cat expect; echo; echo; } >one &&
+ git diff -- one >patch &&
+
+ git checkout one &&
+ git apply --whitespace=fix patch &&
+ test_cmp expect one
+'
+
+test_expect_success 'blank at EOF with --whitespace=fix (3)' '
+ { echo a; echo b; echo; } >one &&
+ git add one &&
+ { echo a; echo c; echo; } >expect &&
+ { cat expect; echo; echo; } >one &&
+ git diff -- one >patch &&
+
+ git checkout one &&
+ git apply --whitespace=fix patch &&
+ test_cmp expect one
+'
+
+test_expect_success 'blank at end of hunk, not at EOF with --whitespace=fix' '
+ { echo a; echo b; echo; echo; echo; echo; echo; echo d; } >one &&
+ git add one &&
+ { echo a; echo c; echo; echo; echo; echo; echo; echo; echo d; } >expect &&
+ cp expect one &&
+ git diff -- one >patch &&
+
+ git checkout one &&
+ git apply --whitespace=fix patch &&
+ test_cmp expect one
+'
+
+test_expect_success 'blank at EOF with --whitespace=warn' '
+ { echo a; echo b; echo c; } >one &&
+ git add one &&
+ echo >>one &&
+ cat one >expect &&
+ git diff -- one >patch &&
+
+ git checkout one &&
+ git apply --whitespace=warn patch 2>error &&
+ test_cmp expect one &&
+ grep "new blank line at EOF" error
+'
+
+test_expect_success 'blank at EOF with --whitespace=error' '
+ { echo a; echo b; echo c; } >one &&
+ git add one &&
+ cat one >expect &&
+ echo >>one &&
+ git diff -- one >patch &&
+
+ git checkout one &&
+ test_must_fail git apply --whitespace=error patch 2>error &&
+ test_cmp expect one &&
+ grep "new blank line at EOF" error
+'
+
+test_expect_success 'blank but not empty at EOF' '
+ { echo a; echo b; echo c; } >one &&
+ git add one &&
+ echo " " >>one &&
+ cat one >expect &&
+ git diff -- one >patch &&
+
+ git checkout one &&
+ git apply --whitespace=warn patch 2>error &&
+ test_cmp expect one &&
+ grep "new blank line at EOF" error
+'
+
test_done
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index 59d1f6283b..7f61ab0e52 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -162,4 +162,22 @@ test_expect_success 'empty email' '
}
'
+test_expect_success '"%h %gD: %gs" is same as git-reflog' '
+ git reflog >expect &&
+ git log -g --format="%h %gD: %gs" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '"%h %gD: %gs" is same as git-reflog (with date)' '
+ git reflog --date=raw >expect &&
+ git log -g --format="%h %gD: %gs" --date=raw >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '%gd shortens ref name' '
+ echo "master@{0}" >expect.gd-short &&
+ git log -g -1 --format=%gd refs/heads/master >actual.gd-short &&
+ test_cmp expect.gd-short actual.gd-short
+'
+
test_done
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index 8b8bd81c09..d4818b430a 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -70,6 +70,13 @@ test_expect_success 'replace the author' '
git show $HASH2 | grep "O Thor"
'
+test_expect_success 'test --no-replace-objects option' '
+ git cat-file commit $HASH2 | grep "author O Thor" &&
+ git --no-replace-objects cat-file commit $HASH2 | grep "author A U Thor" &&
+ git show $HASH2 | grep "O Thor" &&
+ git --no-replace-objects show $HASH2 | grep "A U Thor"
+'
+
cat >tag.sig <<EOF
object $HASH2
type commit
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index f5a1b615f6..c050f94bc6 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -125,6 +125,20 @@ test_expect_success 'rename tag Q back to A' '
test_expect_success 'pack tag refs' 'git pack-refs'
check_describe A-* HEAD
+check_describe "A-*[0-9a-f]" --dirty
+
+test_expect_success 'set-up dirty work tree' '
+ echo >>file
+'
+
+check_describe "A-*[0-9a-f]-dirty" --dirty
+
+check_describe "A-*[0-9a-f].mod" --dirty=.mod
+
+test_expect_success 'describe --dirty HEAD' '
+ test_must_fail git describe --dirty HEAD
+'
+
test_expect_success 'set-up matching pattern tests' '
git tag -a -m test-annotated test-annotated &&
echo >>file &&
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index e2ef53228e..d2de57679f 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -247,6 +247,47 @@ $existing" &&
'
+test_expect_success 'signoff gap' '
+
+ echo 3 >positive &&
+ git add positive &&
+ alt="Alt-RFC-822-Header: Value" &&
+ git commit -s -m "welcome
+
+$alt" &&
+ git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
+ (
+ echo welcome
+ echo
+ echo $alt
+ git var GIT_COMMITTER_IDENT |
+ sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
+ ) >expected &&
+ test_cmp expected actual
+'
+
+test_expect_success 'signoff gap 2' '
+
+ echo 4 >positive &&
+ git add positive &&
+ alt="fixed: 34" &&
+ git commit -s -m "welcome
+
+We have now
+$alt" &&
+ git cat-file commit HEAD | sed -e "1,/^\$/d" > actual &&
+ (
+ echo welcome
+ echo
+ echo We have now
+ echo $alt
+ echo
+ git var GIT_COMMITTER_IDENT |
+ sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /"
+ ) >expected &&
+ test_cmp expected actual
+'
+
test_expect_success 'multiple -m' '
>negative &&
diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh
index 56cd866019..fe94552296 100755
--- a/t/t7502-commit.sh
+++ b/t/t7502-commit.sh
@@ -258,4 +258,13 @@ test_expect_success 'Hand committing of a redundant merge removes dups' '
'
+test_expect_success 'A single-liner subject with a token plus colon is not a footer' '
+
+ git reset --hard &&
+ git commit -s -m "hello: kitty" --allow-empty &&
+ git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
+ test $(wc -l <actual) = 3
+
+'
+
test_done
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index e5b210bc96..57f6d2bae7 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -243,6 +243,16 @@ test_expect_success 'merge c0 with c1' '
test_debug 'gitk --all'
+test_expect_success 'merge c0 with c1 with --ff-only' '
+ git reset --hard c0 &&
+ git merge --ff-only c1 &&
+ git merge --ff-only HEAD c0 c1 &&
+ verify_merge file result.1 &&
+ verify_head "$c1"
+'
+
+test_debug 'gitk --all'
+
test_expect_success 'merge c1 with c2' '
git reset --hard c1 &&
test_tick &&
@@ -263,6 +273,14 @@ test_expect_success 'merge c1 with c2 and c3' '
test_debug 'gitk --all'
+test_expect_success 'failing merges with --ff-only' '
+ git reset --hard c1 &&
+ test_tick &&
+ test_must_fail git merge --ff-only c2 &&
+ test_must_fail git merge --ff-only c3 &&
+ test_must_fail git merge --ff-only c2 c3
+'
+
test_expect_success 'merge c0 with c1 (no-commit)' '
git reset --hard c0 &&
git merge --no-commit c1 &&
@@ -303,6 +321,17 @@ test_expect_success 'merge c0 with c1 (squash)' '
test_debug 'gitk --all'
+test_expect_success 'merge c0 with c1 (squash, ff-only)' '
+ git reset --hard c0 &&
+ git merge --squash --ff-only c1 &&
+ verify_merge file result.1 &&
+ verify_head $c0 &&
+ verify_no_mergehead &&
+ verify_diff squash.1 .git/SQUASH_MSG "[OOPS] bad squash message"
+'
+
+test_debug 'gitk --all'
+
test_expect_success 'merge c1 with c2 (squash)' '
git reset --hard c1 &&
git merge --squash c2 &&
@@ -314,6 +343,13 @@ test_expect_success 'merge c1 with c2 (squash)' '
test_debug 'gitk --all'
+test_expect_success 'unsuccesful merge of c1 with c2 (squash, ff-only)' '
+ git reset --hard c1 &&
+ test_must_fail git merge --squash --ff-only c2
+'
+
+test_debug 'gitk --all'
+
test_expect_success 'merge c1 with c2 and c3 (squash)' '
git reset --hard c1 &&
git merge --squash c2 c3 &&
@@ -432,6 +468,11 @@ test_expect_success 'combining --squash and --no-ff is refused' '
test_must_fail git merge --no-ff --squash c1
'
+test_expect_success 'combining --ff-only and --no-ff is refused' '
+ test_must_fail git merge --ff-only --no-ff c1 &&
+ test_must_fail git merge --no-ff --ff-only c1
+'
+
test_expect_success 'merge c0 with c1 (ff overrides no-ff)' '
git reset --hard c0 &&
git config branch.master.mergeoptions "--no-ff" &&
diff --git a/t/t9150-svk-mergetickets.sh b/t/t9150-svk-mergetickets.sh
new file mode 100755
index 0000000000..dd0c2bad24
--- /dev/null
+++ b/t/t9150-svk-mergetickets.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Sam Vilain
+#
+
+test_description='git-svn svk merge tickets'
+
+. ./lib-git-svn.sh
+
+test_expect_success 'load svk depot' "
+ svnadmin load -q '$rawsvnrepo' \
+ < '$TEST_DIRECTORY/t9150/svk-merge.dump' &&
+ git svn init --minimize-url -R svkmerge \
+ -T trunk -b branches '$svnrepo' &&
+ git svn fetch --all
+ "
+
+uuid=b48289b2-9c08-4d72-af37-0358a40b9c15
+
+test_expect_success 'svk merges were represented coming in' "
+ [ `git-cat-file commit HEAD | grep parent | wc -l` -eq 2 ]
+ "
+
+test_done
diff --git a/t/t9150/make-svk-dump b/t/t9150/make-svk-dump
new file mode 100644
index 0000000000..2242f14ebe
--- /dev/null
+++ b/t/t9150/make-svk-dump
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# this script sets up a Subversion repository for Makefile in the
+# first ever git merge, as if it were done with svk.
+#
+
+set -e
+
+svk depotmap foo ~/.svk/foo
+svk co /foo/ foo
+cd foo
+mkdir trunk
+mkdir branches
+svk add trunk branches
+svk commit -m "Setup trunk and branches"
+cd trunk
+
+git cat-file blob 6683463e:Makefile > Makefile
+svk add Makefile
+
+svk commit -m "ancestor"
+cd ..
+svk cp trunk branches/left
+
+svk commit -m "make left branch"
+cd branches/left/
+
+git cat-file blob 5873b67e:Makefile > Makefile
+svk commit -m "left update 1"
+
+cd ../../trunk
+git cat-file blob 75118b13:Makefile > Makefile
+svk commit -m "trunk update"
+
+cd ../branches/left
+git cat-file blob b5039db6:Makefile > Makefile
+svk commit -m "left update 2"
+
+cd ../../trunk
+svk sm /foo/branches/left
+# in theory we could delete the "left" branch here, but it's not
+# required so don't do it, in case people start getting ideas ;)
+svk commit -m "merge branch 'left' into 'trunk'"
+
+git cat-file blob b51ad431:Makefile > Makefile
+
+svk diff Makefile && echo "Hey! No differences, magic"
+
+cd ../..
+
+svnadmin dump ~/.svk/foo > svk-merge.dump
+
+svk co -d foo
+rm -rf foo
+svk depotmap -d /foo/
+rm -rf ~/.svk/foo
+
diff --git a/t/t9150/svk-merge.dump b/t/t9150/svk-merge.dump
new file mode 100644
index 0000000000..42f70dbec7
--- /dev/null
+++ b/t/t9150/svk-merge.dump
@@ -0,0 +1,616 @@
+SVN-fs-dump-format-version: 2
+
+UUID: b48289b2-9c08-4d72-af37-0358a40b9c15
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2009-10-19T23:44:03.722969Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 123
+Content-length: 123
+
+K 7
+svn:log
+V 24
+Setup trunk and branches
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-19T23:44:04.927533Z
+PROPS-END
+
+Node-path: branches
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+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: 106
+Content-length: 106
+
+K 7
+svn:log
+V 8
+ancestor
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-19T23:44:05.835585Z
+PROPS-END
+
+Node-path: trunk/Makefile
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2401
+Text-content-md5: bfd8ff778d1492dc6758567373176a89
+Content-length: 2411
+
+PROPS-END
+# -DCOLLISION_CHECK if you believe that SHA1's
+# 1461501637330902918203684832716283019655932542976 hashes do not give you
+# enough guarantees about no collisions between objects ever hapenning.
+#
+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
+# Note that you need some new glibc (at least >2.2.4) for this, and it will
+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
+# break unless your underlying filesystem supports those sub-second times
+# (my ext3 doesn't).
+CFLAGS=-g -O3 -Wall
+
+CC=gcc
+
+
+PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
+ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
+ check-files ls-tree merge-base
+
+all: $(PROG)
+
+install: $(PROG)
+ install $(PROG) $(HOME)/bin/
+
+LIBS= -lssl -lz
+
+init-db: init-db.o
+
+update-cache: update-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
+
+show-diff: show-diff.o read-cache.o
+ $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
+
+write-tree: write-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
+
+read-tree: read-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
+
+commit-tree: commit-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
+
+cat-file: cat-file.o read-cache.o
+ $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
+
+fsck-cache: fsck-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o $(LIBS)
+
+checkout-cache: checkout-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
+
+diff-tree: diff-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
+
+rev-tree: rev-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o $(LIBS)
+
+show-files: show-files.o read-cache.o
+ $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
+
+check-files: check-files.o read-cache.o
+ $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
+
+ls-tree: ls-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
+
+merge-base: merge-base.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS)
+
+read-cache.o: cache.h
+show-diff.o: cache.h
+
+clean:
+ rm -f *.o $(PROG)
+
+backup: clean
+ cd .. ; tar czvf dircache.tar.gz dir-cache
+
+
+Revision-number: 3
+Prop-content-length: 115
+Content-length: 115
+
+K 7
+svn:log
+V 16
+make left branch
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-19T23:44:06.719737Z
+PROPS-END
+
+Node-path: branches/left
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 2
+Node-copyfrom-path: trunk
+
+
+Revision-number: 4
+Prop-content-length: 112
+Content-length: 112
+
+K 7
+svn:log
+V 13
+left update 1
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-19T23:44:07.167666Z
+PROPS-END
+
+Node-path: branches/left/Makefile
+Node-kind: file
+Node-action: change
+Text-content-length: 2465
+Text-content-md5: 16e38d9753b061731650561ce01b1195
+Content-length: 2465
+
+# -DCOLLISION_CHECK if you believe that SHA1's
+# 1461501637330902918203684832716283019655932542976 hashes do not give you
+# enough guarantees about no collisions between objects ever hapenning.
+#
+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
+# Note that you need some new glibc (at least >2.2.4) for this, and it will
+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
+# break unless your underlying filesystem supports those sub-second times
+# (my ext3 doesn't).
+CFLAGS=-g -O3 -Wall
+
+CC=gcc
+
+
+PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
+ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
+ check-files ls-tree merge-base
+
+all: $(PROG)
+
+install: $(PROG)
+ install $(PROG) $(HOME)/bin/
+
+LIBS= -lssl -lz
+
+init-db: init-db.o
+
+update-cache: update-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
+
+show-diff: show-diff.o read-cache.o
+ $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
+
+write-tree: write-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
+
+read-tree: read-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
+
+commit-tree: commit-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
+
+cat-file: cat-file.o read-cache.o
+ $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
+
+fsck-cache: fsck-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o $(LIBS)
+
+checkout-cache: checkout-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
+
+diff-tree: diff-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
+
+rev-tree: rev-tree.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+show-files: show-files.o read-cache.o
+ $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
+
+check-files: check-files.o read-cache.o
+ $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
+
+ls-tree: ls-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
+
+merge-base: merge-base.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS)
+
+read-cache.o: cache.h
+show-diff.o: cache.h
+
+clean:
+ rm -f *.o $(PROG)
+
+backup: clean
+ cd .. ; tar czvf dircache.tar.gz dir-cache
+
+
+Revision-number: 5
+Prop-content-length: 111
+Content-length: 111
+
+K 7
+svn:log
+V 12
+trunk update
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-19T23:44:07.619633Z
+PROPS-END
+
+Node-path: trunk/Makefile
+Node-kind: file
+Node-action: change
+Text-content-length: 2521
+Text-content-md5: 0668418a621333f4aa8b6632cd63e2a0
+Content-length: 2521
+
+# -DCOLLISION_CHECK if you believe that SHA1's
+# 1461501637330902918203684832716283019655932542976 hashes do not give you
+# enough guarantees about no collisions between objects ever hapenning.
+#
+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
+# Note that you need some new glibc (at least >2.2.4) for this, and it will
+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
+# break unless your underlying filesystem supports those sub-second times
+# (my ext3 doesn't).
+CFLAGS=-g -O3 -Wall
+
+CC=gcc
+
+
+PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
+ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
+ check-files ls-tree merge-base merge-cache
+
+all: $(PROG)
+
+install: $(PROG)
+ install $(PROG) $(HOME)/bin/
+
+LIBS= -lssl -lz
+
+init-db: init-db.o
+
+update-cache: update-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
+
+show-diff: show-diff.o read-cache.o
+ $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
+
+write-tree: write-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
+
+read-tree: read-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
+
+commit-tree: commit-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
+
+cat-file: cat-file.o read-cache.o
+ $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
+
+fsck-cache: fsck-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o $(LIBS)
+
+checkout-cache: checkout-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
+
+diff-tree: diff-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
+
+rev-tree: rev-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o $(LIBS)
+
+show-files: show-files.o read-cache.o
+ $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
+
+check-files: check-files.o read-cache.o
+ $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
+
+ls-tree: ls-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
+
+merge-base: merge-base.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS)
+
+merge-cache: merge-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-cache merge-cache.o read-cache.o $(LIBS)
+
+read-cache.o: cache.h
+show-diff.o: cache.h
+
+clean:
+ rm -f *.o $(PROG)
+
+backup: clean
+ cd .. ; tar czvf dircache.tar.gz dir-cache
+
+
+Revision-number: 6
+Prop-content-length: 112
+Content-length: 112
+
+K 7
+svn:log
+V 13
+left update 2
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-19T23:44:08.067554Z
+PROPS-END
+
+Node-path: branches/left/Makefile
+Node-kind: file
+Node-action: change
+Text-content-length: 2593
+Text-content-md5: 5ccff689fb290e00b85fe18ee50c54ba
+Content-length: 2593
+
+# -DCOLLISION_CHECK if you believe that SHA1's
+# 1461501637330902918203684832716283019655932542976 hashes do not give you
+# enough guarantees about no collisions between objects ever hapenning.
+#
+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
+# Note that you need some new glibc (at least >2.2.4) for this, and it will
+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
+# break unless your underlying filesystem supports those sub-second times
+# (my ext3 doesn't).
+CFLAGS=-g -O3 -Wall
+
+CC=gcc
+
+
+PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
+ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
+ check-files ls-tree merge-base
+
+all: $(PROG)
+
+install: $(PROG)
+ install $(PROG) $(HOME)/bin/
+
+LIBS= -lssl -lz
+
+init-db: init-db.o
+
+update-cache: update-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
+
+show-diff: show-diff.o read-cache.o
+ $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
+
+write-tree: write-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
+
+read-tree: read-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
+
+commit-tree: commit-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
+
+cat-file: cat-file.o read-cache.o
+ $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
+
+fsck-cache: fsck-cache.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+checkout-cache: checkout-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
+
+diff-tree: diff-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
+
+rev-tree: rev-tree.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+show-files: show-files.o read-cache.o
+ $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
+
+check-files: check-files.o read-cache.o
+ $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
+
+ls-tree: ls-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
+
+merge-base: merge-base.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+read-cache.o: cache.h
+show-diff.o: cache.h
+
+clean:
+ rm -f *.o $(PROG)
+
+backup: clean
+ cd .. ; tar czvf dircache.tar.gz dir-cache
+
+
+Revision-number: 7
+Prop-content-length: 131
+Content-length: 131
+
+K 7
+svn:log
+V 32
+merge branch 'left' into 'trunk'
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-19T23:44:08.971801Z
+PROPS-END
+
+Node-path: trunk
+Node-kind: dir
+Node-action: change
+Prop-content-length: 83
+Content-length: 83
+
+K 9
+svk:merge
+V 53
+b48289b2-9c08-4d72-af37-0358a40b9c15:/branches/left:6
+PROPS-END
+
+
+Node-path: trunk/Makefile
+Node-kind: file
+Node-action: change
+Text-content-length: 2713
+Text-content-md5: 0afbe34f244cd662b1f97d708c687f90
+Content-length: 2713
+
+# -DCOLLISION_CHECK if you believe that SHA1's
+# 1461501637330902918203684832716283019655932542976 hashes do not give you
+# enough guarantees about no collisions between objects ever hapenning.
+#
+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
+# Note that you need some new glibc (at least >2.2.4) for this, and it will
+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
+# break unless your underlying filesystem supports those sub-second times
+# (my ext3 doesn't).
+CFLAGS=-g -O3 -Wall
+
+CC=gcc
+
+
+PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
+ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
+ check-files ls-tree merge-base merge-cache
+
+all: $(PROG)
+
+install: $(PROG)
+ install $(PROG) $(HOME)/bin/
+
+LIBS= -lssl -lz
+
+init-db: init-db.o
+
+update-cache: update-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
+
+show-diff: show-diff.o read-cache.o
+ $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
+
+write-tree: write-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
+
+read-tree: read-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
+
+commit-tree: commit-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
+
+cat-file: cat-file.o read-cache.o
+ $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
+
+fsck-cache: fsck-cache.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+checkout-cache: checkout-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
+
+diff-tree: diff-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
+
+rev-tree: rev-tree.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+show-files: show-files.o read-cache.o
+ $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
+
+check-files: check-files.o read-cache.o
+ $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
+
+ls-tree: ls-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
+
+merge-base: merge-base.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+merge-cache: merge-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-cache merge-cache.o read-cache.o $(LIBS)
+
+read-cache.o: cache.h
+show-diff.o: cache.h
+
+clean:
+ rm -f *.o $(PROG)
+
+backup: clean
+ cd .. ; tar czvf dircache.tar.gz dir-cache
+
+
diff --git a/t/t9151-svn-mergeinfo.sh b/t/t9151-svn-mergeinfo.sh
new file mode 100755
index 0000000000..9bee516358
--- /dev/null
+++ b/t/t9151-svn-mergeinfo.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Copyright (c) 2007, 2009 Sam Vilain
+#
+
+test_description='git-svn svn mergeinfo properties'
+
+. ./lib-git-svn.sh
+
+test_expect_success 'load svn dump' "
+ svnadmin load -q '$rawsvnrepo' \
+ < '$TEST_DIRECTORY/t9151/svn-mergeinfo.dump' &&
+ git svn init --minimize-url -R svnmerge \
+ -T trunk -b branches '$svnrepo' &&
+ git svn fetch --all
+ "
+
+test_expect_success 'svn merges were represented coming in' "
+ [ `git cat-file commit HEAD | grep parent | wc -l` -eq 2 ]
+ "
+
+test_done
diff --git a/t/t9151/.gitignore b/t/t9151/.gitignore
new file mode 100644
index 0000000000..587c37dba3
--- /dev/null
+++ b/t/t9151/.gitignore
@@ -0,0 +1,2 @@
+foo
+foo.svn
diff --git a/t/t9151/make-svnmerge-dump b/t/t9151/make-svnmerge-dump
new file mode 100644
index 0000000000..e35d64d585
--- /dev/null
+++ b/t/t9151/make-svnmerge-dump
@@ -0,0 +1,73 @@
+#!/bin/sh
+#
+# this script sets up a Subversion repository for Makefile in the
+# first ever git merge, as if it were done with svnmerge (SVN 1.5+)
+#
+
+rm -rf foo.svn foo
+set -e
+
+mkdir foo.svn
+svnadmin create foo.svn
+svn co file://`pwd`/foo.svn foo
+
+cd foo
+mkdir trunk
+mkdir branches
+svn add trunk branches
+svn commit -m "Setup trunk and branches"
+cd trunk
+
+git cat-file blob 6683463e:Makefile > Makefile
+svn add Makefile
+
+echo "Committing ANCESTOR"
+svn commit -m "ancestor"
+cd ..
+svn cp trunk branches/left
+
+echo "Committing BRANCH POINT"
+svn commit -m "make left branch"
+cd branches/left/
+
+#$sm init
+#svn commit -m "init svnmerge"
+
+git cat-file blob 5873b67e:Makefile > Makefile
+echo "Committing BRANCH UPDATE 1"
+svn commit -m "left update 1"
+cd ../..
+
+cd trunk
+git cat-file blob 75118b13:Makefile > Makefile
+echo "Committing TRUNK UPDATE"
+svn commit -m "trunk update"
+
+cd ../branches/left
+git cat-file blob ff5ebe39:Makefile > Makefile
+echo "Committing BRANCH UPDATE 2"
+svn commit -m "left update 2"
+
+git cat-file blob b5039db6:Makefile > Makefile
+echo "Committing BRANCH UPDATE 3"
+svn commit -m "left update 3"
+
+# merge to trunk
+
+cd ../..
+svn update
+cd trunk
+
+svn merge ../branches/left --accept postpone
+
+git cat-file blob b51ad431:Makefile > Makefile
+
+svn resolved Makefile
+
+svn commit -m "Merge trunk"
+
+cd ../..
+
+svnadmin dump foo.svn > svn-mergeinfo.dump
+
+rm -rf foo foo.svn
diff --git a/t/t9151/svn-mergeinfo.dump b/t/t9151/svn-mergeinfo.dump
new file mode 100644
index 0000000000..2153187c9b
--- /dev/null
+++ b/t/t9151/svn-mergeinfo.dump
@@ -0,0 +1,736 @@
+SVN-fs-dump-format-version: 2
+
+UUID: 1ce241d1-ba54-4eb9-bded-03057fe48a33
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2009-10-20T01:33:37.692723Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 123
+Content-length: 123
+
+K 7
+svn:log
+V 24
+Setup trunk and branches
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-20T01:33:38.159933Z
+PROPS-END
+
+Node-path: branches
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+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: 106
+Content-length: 106
+
+K 7
+svn:log
+V 8
+ancestor
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-20T01:33:39.160059Z
+PROPS-END
+
+Node-path: trunk/Makefile
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2401
+Text-content-md5: bfd8ff778d1492dc6758567373176a89
+Content-length: 2411
+
+PROPS-END
+# -DCOLLISION_CHECK if you believe that SHA1's
+# 1461501637330902918203684832716283019655932542976 hashes do not give you
+# enough guarantees about no collisions between objects ever hapenning.
+#
+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
+# Note that you need some new glibc (at least >2.2.4) for this, and it will
+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
+# break unless your underlying filesystem supports those sub-second times
+# (my ext3 doesn't).
+CFLAGS=-g -O3 -Wall
+
+CC=gcc
+
+
+PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
+ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
+ check-files ls-tree merge-base
+
+all: $(PROG)
+
+install: $(PROG)
+ install $(PROG) $(HOME)/bin/
+
+LIBS= -lssl -lz
+
+init-db: init-db.o
+
+update-cache: update-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
+
+show-diff: show-diff.o read-cache.o
+ $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
+
+write-tree: write-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
+
+read-tree: read-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
+
+commit-tree: commit-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
+
+cat-file: cat-file.o read-cache.o
+ $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
+
+fsck-cache: fsck-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o $(LIBS)
+
+checkout-cache: checkout-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
+
+diff-tree: diff-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
+
+rev-tree: rev-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o $(LIBS)
+
+show-files: show-files.o read-cache.o
+ $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
+
+check-files: check-files.o read-cache.o
+ $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
+
+ls-tree: ls-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
+
+merge-base: merge-base.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS)
+
+read-cache.o: cache.h
+show-diff.o: cache.h
+
+clean:
+ rm -f *.o $(PROG)
+
+backup: clean
+ cd .. ; tar czvf dircache.tar.gz dir-cache
+
+
+Revision-number: 3
+Prop-content-length: 115
+Content-length: 115
+
+K 7
+svn:log
+V 16
+make left branch
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-20T01:33:41.148192Z
+PROPS-END
+
+Node-path: branches/left
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 1
+Node-copyfrom-path: trunk
+Prop-content-length: 34
+Content-length: 34
+
+K 13
+svn:mergeinfo
+V 0
+
+PROPS-END
+
+
+Node-path: branches/left/Makefile
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 2
+Node-copyfrom-path: trunk/Makefile
+Text-copy-source-md5: bfd8ff778d1492dc6758567373176a89
+
+
+Revision-number: 4
+Prop-content-length: 112
+Content-length: 112
+
+K 7
+svn:log
+V 13
+left update 1
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-20T01:33:42.148773Z
+PROPS-END
+
+Node-path: branches/left/Makefile
+Node-kind: file
+Node-action: change
+Text-content-length: 2465
+Text-content-md5: 16e38d9753b061731650561ce01b1195
+Content-length: 2465
+
+# -DCOLLISION_CHECK if you believe that SHA1's
+# 1461501637330902918203684832716283019655932542976 hashes do not give you
+# enough guarantees about no collisions between objects ever hapenning.
+#
+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
+# Note that you need some new glibc (at least >2.2.4) for this, and it will
+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
+# break unless your underlying filesystem supports those sub-second times
+# (my ext3 doesn't).
+CFLAGS=-g -O3 -Wall
+
+CC=gcc
+
+
+PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
+ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
+ check-files ls-tree merge-base
+
+all: $(PROG)
+
+install: $(PROG)
+ install $(PROG) $(HOME)/bin/
+
+LIBS= -lssl -lz
+
+init-db: init-db.o
+
+update-cache: update-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
+
+show-diff: show-diff.o read-cache.o
+ $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
+
+write-tree: write-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
+
+read-tree: read-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
+
+commit-tree: commit-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
+
+cat-file: cat-file.o read-cache.o
+ $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
+
+fsck-cache: fsck-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o $(LIBS)
+
+checkout-cache: checkout-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
+
+diff-tree: diff-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
+
+rev-tree: rev-tree.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+show-files: show-files.o read-cache.o
+ $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
+
+check-files: check-files.o read-cache.o
+ $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
+
+ls-tree: ls-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
+
+merge-base: merge-base.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS)
+
+read-cache.o: cache.h
+show-diff.o: cache.h
+
+clean:
+ rm -f *.o $(PROG)
+
+backup: clean
+ cd .. ; tar czvf dircache.tar.gz dir-cache
+
+
+Revision-number: 5
+Prop-content-length: 111
+Content-length: 111
+
+K 7
+svn:log
+V 12
+trunk update
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-20T01:33:43.159959Z
+PROPS-END
+
+Node-path: trunk/Makefile
+Node-kind: file
+Node-action: change
+Text-content-length: 2521
+Text-content-md5: 0668418a621333f4aa8b6632cd63e2a0
+Content-length: 2521
+
+# -DCOLLISION_CHECK if you believe that SHA1's
+# 1461501637330902918203684832716283019655932542976 hashes do not give you
+# enough guarantees about no collisions between objects ever hapenning.
+#
+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
+# Note that you need some new glibc (at least >2.2.4) for this, and it will
+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
+# break unless your underlying filesystem supports those sub-second times
+# (my ext3 doesn't).
+CFLAGS=-g -O3 -Wall
+
+CC=gcc
+
+
+PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
+ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
+ check-files ls-tree merge-base merge-cache
+
+all: $(PROG)
+
+install: $(PROG)
+ install $(PROG) $(HOME)/bin/
+
+LIBS= -lssl -lz
+
+init-db: init-db.o
+
+update-cache: update-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
+
+show-diff: show-diff.o read-cache.o
+ $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
+
+write-tree: write-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
+
+read-tree: read-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
+
+commit-tree: commit-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
+
+cat-file: cat-file.o read-cache.o
+ $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
+
+fsck-cache: fsck-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o $(LIBS)
+
+checkout-cache: checkout-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
+
+diff-tree: diff-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
+
+rev-tree: rev-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o $(LIBS)
+
+show-files: show-files.o read-cache.o
+ $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
+
+check-files: check-files.o read-cache.o
+ $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
+
+ls-tree: ls-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
+
+merge-base: merge-base.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS)
+
+merge-cache: merge-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-cache merge-cache.o read-cache.o $(LIBS)
+
+read-cache.o: cache.h
+show-diff.o: cache.h
+
+clean:
+ rm -f *.o $(PROG)
+
+backup: clean
+ cd .. ; tar czvf dircache.tar.gz dir-cache
+
+
+Revision-number: 6
+Prop-content-length: 112
+Content-length: 112
+
+K 7
+svn:log
+V 13
+left update 2
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-20T01:33:44.164175Z
+PROPS-END
+
+Node-path: branches/left/Makefile
+Node-kind: file
+Node-action: change
+Text-content-length: 2529
+Text-content-md5: f6b197cc3f2e89a83e545d4bb003de73
+Content-length: 2529
+
+# -DCOLLISION_CHECK if you believe that SHA1's
+# 1461501637330902918203684832716283019655932542976 hashes do not give you
+# enough guarantees about no collisions between objects ever hapenning.
+#
+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
+# Note that you need some new glibc (at least >2.2.4) for this, and it will
+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
+# break unless your underlying filesystem supports those sub-second times
+# (my ext3 doesn't).
+CFLAGS=-g -O3 -Wall
+
+CC=gcc
+
+
+PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
+ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
+ check-files ls-tree merge-base
+
+all: $(PROG)
+
+install: $(PROG)
+ install $(PROG) $(HOME)/bin/
+
+LIBS= -lssl -lz
+
+init-db: init-db.o
+
+update-cache: update-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
+
+show-diff: show-diff.o read-cache.o
+ $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
+
+write-tree: write-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
+
+read-tree: read-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
+
+commit-tree: commit-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
+
+cat-file: cat-file.o read-cache.o
+ $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
+
+fsck-cache: fsck-cache.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+checkout-cache: checkout-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
+
+diff-tree: diff-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
+
+rev-tree: rev-tree.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+show-files: show-files.o read-cache.o
+ $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
+
+check-files: check-files.o read-cache.o
+ $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
+
+ls-tree: ls-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
+
+merge-base: merge-base.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS)
+
+read-cache.o: cache.h
+show-diff.o: cache.h
+
+clean:
+ rm -f *.o $(PROG)
+
+backup: clean
+ cd .. ; tar czvf dircache.tar.gz dir-cache
+
+
+Revision-number: 7
+Prop-content-length: 112
+Content-length: 112
+
+K 7
+svn:log
+V 13
+left update 3
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-20T01:33:45.144214Z
+PROPS-END
+
+Node-path: branches/left/Makefile
+Node-kind: file
+Node-action: change
+Text-content-length: 2593
+Text-content-md5: 5ccff689fb290e00b85fe18ee50c54ba
+Content-length: 2593
+
+# -DCOLLISION_CHECK if you believe that SHA1's
+# 1461501637330902918203684832716283019655932542976 hashes do not give you
+# enough guarantees about no collisions between objects ever hapenning.
+#
+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
+# Note that you need some new glibc (at least >2.2.4) for this, and it will
+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
+# break unless your underlying filesystem supports those sub-second times
+# (my ext3 doesn't).
+CFLAGS=-g -O3 -Wall
+
+CC=gcc
+
+
+PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
+ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
+ check-files ls-tree merge-base
+
+all: $(PROG)
+
+install: $(PROG)
+ install $(PROG) $(HOME)/bin/
+
+LIBS= -lssl -lz
+
+init-db: init-db.o
+
+update-cache: update-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
+
+show-diff: show-diff.o read-cache.o
+ $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
+
+write-tree: write-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
+
+read-tree: read-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
+
+commit-tree: commit-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
+
+cat-file: cat-file.o read-cache.o
+ $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
+
+fsck-cache: fsck-cache.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+checkout-cache: checkout-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
+
+diff-tree: diff-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
+
+rev-tree: rev-tree.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+show-files: show-files.o read-cache.o
+ $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
+
+check-files: check-files.o read-cache.o
+ $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
+
+ls-tree: ls-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
+
+merge-base: merge-base.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+read-cache.o: cache.h
+show-diff.o: cache.h
+
+clean:
+ rm -f *.o $(PROG)
+
+backup: clean
+ cd .. ; tar czvf dircache.tar.gz dir-cache
+
+
+Revision-number: 8
+Prop-content-length: 110
+Content-length: 110
+
+K 7
+svn:log
+V 11
+Merge trunk
+K 10
+svn:author
+V 4
+samv
+K 8
+svn:date
+V 27
+2009-10-20T01:33:48.176135Z
+PROPS-END
+
+Node-path: trunk
+Node-kind: dir
+Node-action: change
+Prop-content-length: 53
+Content-length: 53
+
+K 13
+svn:mergeinfo
+V 18
+/branches/left:2-7
+PROPS-END
+
+
+Node-path: trunk/Makefile
+Node-kind: file
+Node-action: change
+Text-content-length: 2713
+Text-content-md5: 0afbe34f244cd662b1f97d708c687f90
+Content-length: 2713
+
+# -DCOLLISION_CHECK if you believe that SHA1's
+# 1461501637330902918203684832716283019655932542976 hashes do not give you
+# enough guarantees about no collisions between objects ever hapenning.
+#
+# -DNSEC if you want git to care about sub-second file mtimes and ctimes.
+# Note that you need some new glibc (at least >2.2.4) for this, and it will
+# BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
+# break unless your underlying filesystem supports those sub-second times
+# (my ext3 doesn't).
+CFLAGS=-g -O3 -Wall
+
+CC=gcc
+
+
+PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
+ cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
+ check-files ls-tree merge-base merge-cache
+
+all: $(PROG)
+
+install: $(PROG)
+ install $(PROG) $(HOME)/bin/
+
+LIBS= -lssl -lz
+
+init-db: init-db.o
+
+update-cache: update-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o update-cache update-cache.o read-cache.o $(LIBS)
+
+show-diff: show-diff.o read-cache.o
+ $(CC) $(CFLAGS) -o show-diff show-diff.o read-cache.o $(LIBS)
+
+write-tree: write-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o write-tree write-tree.o read-cache.o $(LIBS)
+
+read-tree: read-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o read-tree read-tree.o read-cache.o $(LIBS)
+
+commit-tree: commit-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o commit-tree commit-tree.o read-cache.o $(LIBS)
+
+cat-file: cat-file.o read-cache.o
+ $(CC) $(CFLAGS) -o cat-file cat-file.o read-cache.o $(LIBS)
+
+fsck-cache: fsck-cache.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o fsck-cache fsck-cache.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+checkout-cache: checkout-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o checkout-cache checkout-cache.o read-cache.o $(LIBS)
+
+diff-tree: diff-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o diff-tree diff-tree.o read-cache.o $(LIBS)
+
+rev-tree: rev-tree.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o rev-tree rev-tree.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+show-files: show-files.o read-cache.o
+ $(CC) $(CFLAGS) -o show-files show-files.o read-cache.o $(LIBS)
+
+check-files: check-files.o read-cache.o
+ $(CC) $(CFLAGS) -o check-files check-files.o read-cache.o $(LIBS)
+
+ls-tree: ls-tree.o read-cache.o
+ $(CC) $(CFLAGS) -o ls-tree ls-tree.o read-cache.o $(LIBS)
+
+merge-base: merge-base.o read-cache.o object.o commit.o tree.o blob.o
+ $(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o object.o commit.o tree.o blob.o $(LIBS)
+
+merge-cache: merge-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-cache merge-cache.o read-cache.o $(LIBS)
+
+read-cache.o: cache.h
+show-diff.o: cache.h
+
+clean:
+ rm -f *.o $(PROG)
+
+backup: clean
+ cd .. ; tar czvf dircache.tar.gz dir-cache
+
+
diff --git a/ws.c b/ws.c
index 59d0883c1f..760b5743fa 100644
--- a/ws.c
+++ b/ws.c
@@ -16,6 +16,8 @@ static struct whitespace_rule {
{ "space-before-tab", WS_SPACE_BEFORE_TAB, 0 },
{ "indent-with-non-tab", WS_INDENT_WITH_NON_TAB, 0 },
{ "cr-at-eol", WS_CR_AT_EOL, 1 },
+ { "blank-at-eol", WS_BLANK_AT_EOL, 0 },
+ { "blank-at-eof", WS_BLANK_AT_EOF, 0 },
};
unsigned parse_whitespace_rule(const char *string)
@@ -102,8 +104,17 @@ unsigned whitespace_rule(const char *pathname)
char *whitespace_error_string(unsigned ws)
{
struct strbuf err = STRBUF_INIT;
- if (ws & WS_TRAILING_SPACE)
+ if ((ws & WS_TRAILING_SPACE) == WS_TRAILING_SPACE)
strbuf_addstr(&err, "trailing whitespace");
+ else {
+ if (ws & WS_BLANK_AT_EOL)
+ strbuf_addstr(&err, "trailing whitespace");
+ if (ws & WS_BLANK_AT_EOF) {
+ if (err.len)
+ strbuf_addstr(&err, ", ");
+ strbuf_addstr(&err, "new blank line at EOF");
+ }
+ }
if (ws & WS_SPACE_BEFORE_TAB) {
if (err.len)
strbuf_addstr(&err, ", ");
@@ -141,11 +152,11 @@ static unsigned ws_check_emit_1(const char *line, int len, unsigned ws_rule,
}
/* Check for trailing whitespace. */
- if (ws_rule & WS_TRAILING_SPACE) {
+ if (ws_rule & WS_BLANK_AT_EOL) {
for (i = len - 1; i >= 0; i--) {
if (isspace(line[i])) {
trailing_whitespace = i;
- result |= WS_TRAILING_SPACE;
+ result |= WS_BLANK_AT_EOL;
}
else
break;
@@ -261,7 +272,7 @@ int ws_fix_copy(char *dst, const char *src, int len, unsigned ws_rule, int *erro
/*
* Strip trailing whitespace
*/
- if (ws_rule & WS_TRAILING_SPACE) {
+ if (ws_rule & WS_BLANK_AT_EOL) {
if (0 < len && src[len - 1] == '\n') {
add_nl_to_tail = 1;
len--;