aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/RelNotes/1.7.4.5.txt4
-rw-r--r--Documentation/RelNotes/1.7.5.1.txt47
-rw-r--r--Documentation/RelNotes/1.7.5.2.txt57
-rw-r--r--Documentation/RelNotes/1.7.5.3.txt32
-rw-r--r--Documentation/RelNotes/1.7.5.txt10
-rw-r--r--Documentation/SubmittingPatches210
-rw-r--r--Documentation/config.txt102
-rw-r--r--Documentation/diff-config.txt92
-rw-r--r--Documentation/diff-options.txt21
-rw-r--r--Documentation/git-add.txt2
-rw-r--r--Documentation/git-archive.txt3
-rw-r--r--Documentation/git-cherry-pick.txt7
-rw-r--r--Documentation/git-clone.txt3
-rw-r--r--Documentation/git-fast-import.txt4
-rw-r--r--Documentation/git-fetch.txt2
-rw-r--r--Documentation/git-format-patch.txt232
-rw-r--r--Documentation/git-fsck.txt4
-rw-r--r--Documentation/git-imap-send.txt29
-rw-r--r--Documentation/git-init-db.txt2
-rw-r--r--Documentation/git-init.txt3
-rw-r--r--Documentation/git-merge-base.txt34
-rw-r--r--Documentation/git-pack-objects.txt2
-rw-r--r--Documentation/git-send-email.txt19
-rw-r--r--Documentation/git-svn.txt45
-rw-r--r--Documentation/git.txt12
-rw-r--r--Documentation/technical/api-diff.txt4
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--LGPL-2.1511
-rw-r--r--Makefile46
l---------RelNotes2
-rw-r--r--builtin/add.c49
-rw-r--r--builtin/apply.c9
-rw-r--r--builtin/blame.c2
-rw-r--r--builtin/clone.c2
-rw-r--r--builtin/diff-tree.c12
-rw-r--r--builtin/diff.c4
-rw-r--r--builtin/init-db.c2
-rw-r--r--builtin/log.c55
-rw-r--r--builtin/merge-base.c3
-rw-r--r--builtin/merge.c53
-rw-r--r--builtin/pack-objects.c8
-rw-r--r--builtin/revert.c7
-rw-r--r--builtin/send-pack.c11
-rw-r--r--cache.h2
-rw-r--r--compat/mingw.c2
-rw-r--r--compat/nedmalloc/malloc.c.h10
-rw-r--r--config.c6
-rw-r--r--connect.c35
-rwxr-xr-xcontrib/completion/git-completion.bash8
-rw-r--r--date.c5
-rw-r--r--diff-lib.c15
-rw-r--r--diff.c92
-rw-r--r--diff.h7
-rw-r--r--diffcore-rename.c111
-rw-r--r--dir.c2
-rw-r--r--environment.c1
-rw-r--r--fast-import.c11
-rw-r--r--fsck.c2
-rwxr-xr-xgit-add--interactive.perl25
-rwxr-xr-xgit-cvsimport.perl53
-rwxr-xr-xgit-merge-one-file.sh7
-rw-r--r--git-mergetool--lib.sh9
-rwxr-xr-xgit-mergetool.sh90
-rwxr-xr-xgit-rebase--interactive.sh2
-rwxr-xr-xgit-send-email.perl2
-rwxr-xr-xgit-stash.sh25
-rwxr-xr-xgit-submodule.sh2
-rwxr-xr-xgit-svn.perl2
-rw-r--r--gitweb/README2
-rwxr-xr-xgitweb/gitweb.perl2
-rw-r--r--http.c1
-rw-r--r--ident.c1
-rw-r--r--merge-recursive.c16
-rw-r--r--pretty.c61
-rw-r--r--rerere.c10
-rw-r--r--revision.c80
-rw-r--r--run-command.c10
-rw-r--r--setup.c2
-rw-r--r--sha1_file.c19
-rw-r--r--sha1_name.c11
-rw-r--r--shell.c2
-rw-r--r--t/annotate-tests.sh13
-rwxr-xr-xt/t0001-init.sh4
-rwxr-xr-xt/t0006-date.sh1
-rwxr-xr-xt/t0061-run-command.sh23
-rwxr-xr-xt/t0081-line-buffer.sh106
-rwxr-xr-xt/t1400-update-ref.sh2
-rwxr-xr-xt/t1411-reflog-show.sh18
-rwxr-xr-xt/t1501-worktree.sh7
-rwxr-xr-xt/t1506-rev-parse-diagnosis.sh20
-rwxr-xr-xt/t2011-checkout-invalid-head.sh2
-rwxr-xr-xt/t2021-checkout-overwrite.sh2
-rwxr-xr-xt/t2200-add-update.sh24
-rwxr-xr-xt/t2201-add-update-typechange.sh2
-rwxr-xr-xt/t3200-branch.sh4
-rwxr-xr-xt/t3306-notes-prune.sh3
-rwxr-xr-xt/t3409-rebase-preserve-merges.sh32
-rwxr-xr-xt/t3503-cherry-pick-root.sh27
-rwxr-xr-xt/t3600-rm.sh3
-rwxr-xr-xt/t3701-add-interactive.sh41
-rwxr-xr-xt/t3903-stash.sh44
-rwxr-xr-xt/t3904-stash-patch.sh12
-rwxr-xr-xt/t4001-diff-rename.sh25
-rwxr-xr-xt/t4002-diff-basic.sh5
-rwxr-xr-xt/t4013-diff-various.sh27
-rw-r--r--t/t4013/diff.diff_--dirstat-by-file_initial_rearrange3
-rw-r--r--t/t4013/diff.diff_--dirstat_initial_rearrange3
-rw-r--r--t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^2
-rw-r--r--t/t4013/diff.log_--decorate=full_--all6
-rw-r--r--t/t4013/diff.log_--decorate_--all6
-rwxr-xr-xt/t4014-format-patch.sh42
-rwxr-xr-xt/t4020-diff-external.sh2
-rwxr-xr-xt/t4027-diff-submodule.sh1
-rwxr-xr-xt/t4034-diff-words.sh26
-rwxr-xr-xt/t4046-diff-unmerged.sh87
-rwxr-xr-xt/t5304-prune.sh3
-rwxr-xr-xt/t5400-send-pack.sh4
-rwxr-xr-xt/t5532-fetch-proxy.sh43
-rwxr-xr-xt/t6017-rev-list-stdin.sh17
-rwxr-xr-xt/t6060-merge-index.sh100
-rwxr-xr-xt/t7011-skip-worktree-reading.sh4
-rwxr-xr-xt/t7012-skip-worktree-writing.sh2
-rwxr-xr-xt/t7060-wtstatus.sh62
-rwxr-xr-xt/t7300-clean.sh7
-rwxr-xr-xt/t7600-merge.sh32
-rwxr-xr-xt/t7610-mergetool.sh290
-rwxr-xr-xt/t8002-blame.sh2
-rwxr-xr-xt/t9116-git-svn-log.sh15
-rw-r--r--t/test-lib.sh3
-rw-r--r--test-run-command.c2
-rw-r--r--transport.c2
-rw-r--r--upload-pack.c23
-rw-r--r--vcs-svn/trp.txt2
-rw-r--r--xdiff-interface.c2
134 files changed, 2862 insertions, 881 deletions
diff --git a/Documentation/RelNotes/1.7.4.5.txt b/Documentation/RelNotes/1.7.4.5.txt
new file mode 100644
index 000000000..b7a0eeb22
--- /dev/null
+++ b/Documentation/RelNotes/1.7.4.5.txt
@@ -0,0 +1,4 @@
+Git v1.7.4.5 Release Notes
+==========================
+
+This contains only minor documentation fixes accumulated since 1.7.4.4.
diff --git a/Documentation/RelNotes/1.7.5.1.txt b/Documentation/RelNotes/1.7.5.1.txt
new file mode 100644
index 000000000..c6ebd76d1
--- /dev/null
+++ b/Documentation/RelNotes/1.7.5.1.txt
@@ -0,0 +1,47 @@
+Git v1.7.5.1 Release Notes
+==========================
+
+Fixes since v1.7.5
+------------------
+
+ * When an object "$tree:$path" does not exist, if $path does exist in the
+ subtree of $tree that corresponds to the subdirectory the user is in,
+ git now suggests using "$tree:./$path" in addition to the advice to use
+ the full path from the root of the working tree.
+
+ * The "--date=relative" output format used to say "X years, 12 months"
+ when it should have said "X+1 years".
+
+ * The smart-HTTP transfer was broken in 1.7.5 when the client needs
+ to issue a small POST (which uses content-length) and then a large
+ POST (which uses chunked) back to back.
+
+ * "git clean" used to fail on an empty directory that is not readable,
+ even though rmdir(2) could remove such a directory. Now we attempt it
+ as the last resort.
+
+ * The "--dirstat" option of "diff" family of commands used to totally
+ ignore a change that only rearranged lines within a file. Such a
+ change now counts as at least a minimum but non zero change.
+
+ * The "--dirstat" option of "diff" family of commands used to use the
+ pathname in the original, instead of the pathname in the result,
+ when renames are involved.
+
+ * "git pack-object" did not take core.bigfilethreashold into account
+ (unlike fast-import); now it does.
+
+ * "git reflog" ignored options like "--format=.." on the command line.
+
+ * "git stash apply" used to refuse to work if there was any change in
+ the working tree, even when the change did not overlap with the change
+ the stash recorded.
+
+ * "git stash apply @{99999}" was not diagnosed as an error, even when you
+ did not have that many stash entries.
+
+ * An error message from "git send-email" to diagnose a broken SMTP
+ connection configuration lacked a space between "hello=<smtp-domain>"
+ and "port=<smtp-server-port>".
+
+And other minor fixes and documentation updates.
diff --git a/Documentation/RelNotes/1.7.5.2.txt b/Documentation/RelNotes/1.7.5.2.txt
new file mode 100644
index 000000000..951eb7cb0
--- /dev/null
+++ b/Documentation/RelNotes/1.7.5.2.txt
@@ -0,0 +1,57 @@
+Git v1.7.5.2 Release Notes
+==========================
+
+The release notes to 1.7.5.1 forgot to mention:
+
+ * "git stash -p --no-keep-index" and "git stash --no-keep-index -p" now
+ mean the same thing.
+
+ * "git upload-pack" (hence "git push" over git native protocol) had a
+ subtle race condition that could lead to a deadlock.
+
+Fixes since v1.7.5.1
+--------------------
+
+ * "git add -p" did not work correctly when a hunk is split and then
+ one of them was given to the editor.
+
+ * "git add -u" did not resolve a conflict where our history deleted and
+ their history modified the same file, and the working tree resolved to
+ keep a file.
+
+ * "git cvsimport" did not know that CVSNT stores its password file in a
+ location different from the traditional CVS.
+
+ * "git diff-files" did not show the mode information from the working
+ tree side of an unmerged path correctly.
+
+ * "git diff -M --cached" used to use unmerged path as a possible rename
+ source candidate, which made no sense.
+
+ * The option name parser in "git fast-import" used prefix matches for
+ some options where it shouldn't, and accepted non-existent options,
+ e.g. "--relative-marksmith" or "--forceps".
+
+ * "git format-patch" did not quote RFC822 special characters in the
+ email address (e.g From: Junio C. Hamano <jch@example.com>, not
+ From: "Junio C. Hamano" <jch@example.com>).
+
+ * "git format-patch" when run with "--quiet" option used to produce a
+ nonsense result that consists of alternating empty output.
+
+ * In "git merge", per-branch branch.<name>.mergeoptions configuration
+ variables did not override the fallback default merge.<option>
+ configuration variables such as merge.ff, merge.log, etc.
+
+ * "git merge-one-file" did not honor GIT_WORK_TREE settings when
+ handling a "both sides added, differently" conflict.
+
+ * "git mergetool" did not handle conflicted submoudules gracefully.
+
+ * "git-p4" (in contrib) used a wrong base image while merge a file that
+ was added on both branches differently.
+
+ * "git rebase -i -p" failed to preserve the history when there is a
+ redundant merge created with the --no-ff option.
+
+And other minor fixes and documentation updates.
diff --git a/Documentation/RelNotes/1.7.5.3.txt b/Documentation/RelNotes/1.7.5.3.txt
new file mode 100644
index 000000000..9c03353af
--- /dev/null
+++ b/Documentation/RelNotes/1.7.5.3.txt
@@ -0,0 +1,32 @@
+Git v1.7.5.3 Release Notes
+==========================
+
+Fixes since v1.7.5.2
+--------------------
+
+ * The bash completion scripts should correctly work using zsh's bash
+ completion emulation layer now.
+
+ * Setting $(prefix) in config.mak did not affect where etc/gitconfig
+ file is read from, even though passing it from the command line of
+ $(MAKE) did.
+
+ * The logic to handle "&" (expand to UNIX username) in GECOS field
+ miscounted the length of the name it formatted.
+
+ * "git cherry-pick -s resolve" failed to cherry-pick a root commit.
+
+ * "git diff --word-diff" misbehaved when diff.suppress-blank-empty was
+ in effect.
+
+ * "git log --stdin path" with an input that has additional pathspec
+ used to corrupt memory.
+
+ * "git send-pack" (hence "git push") over smalt-HTTP protocol could
+ deadlock when the client side pack-object died early.
+
+ * Compressed tarball gitweb generates used to be made with the timestamp
+ of the tarball generation; this was bad because snapshot from the same
+ tree should result in a same tarball.
+
+And other minor fixes and documentation updates.
diff --git a/Documentation/RelNotes/1.7.5.txt b/Documentation/RelNotes/1.7.5.txt
index b1b25133e..987919c32 100644
--- a/Documentation/RelNotes/1.7.5.txt
+++ b/Documentation/RelNotes/1.7.5.txt
@@ -1,4 +1,4 @@
-Git v1.7.5 Release Notes (draft)
+Git v1.7.5 Release Notes
========================
Updates since v1.7.4
@@ -8,7 +8,7 @@ Updates since v1.7.4
* Various git-p4 enhancements (in contrib).
- * Various vcs-svn enhancements.
+ * Various vcs-svn, git-svn and gitk enhancements and fixes.
* Various git-gui updates (0.14.0).
@@ -130,9 +130,3 @@ release, unless otherwise noted.
doing both a mirror fetch and a mirror push at the same time, which
made little sense. We now warn and require the command line to specify
either --mirror=fetch or --mirror=push.
-
----
-exec >/var/tmp/1
-O=v1.7.5-rc1
-echo O=$(git describe 'master')
-git shortlog --no-merges ^maint ^$O master
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index c3b0816ed..938eccf2a 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -276,7 +276,7 @@ don't hide your real name.
If you like, you can put extra tags at the end:
-1. "Reported-by:" is used to to credit someone who found the bug that
+1. "Reported-by:" is used to credit someone who found the bug that
the patch attempts to fix.
2. "Acked-by:" says that the person who is more familiar with the area
the patch attempts to modify liked the patch.
@@ -344,50 +344,20 @@ MUA specific hints
Some of patches I receive or pick up from the list share common
patterns of breakage. Please make sure your MUA is set up
-properly not to corrupt whitespaces. Here are two common ones
-I have seen:
+properly not to corrupt whitespaces.
-* Empty context lines that do not have _any_ whitespace.
+See the DISCUSSION section of git-format-patch(1) for hints on
+checking your patch by mailing it to yourself and applying with
+git-am(1).
-* Non empty context lines that have one extra whitespace at the
- beginning.
-
-One test you could do yourself if your MUA is set up correctly is:
-
-* Send the patch to yourself, exactly the way you would, except
- To: and Cc: lines, which would not contain the list and
- maintainer address.
-
-* Save that patch to a file in UNIX mailbox format. Call it say
- a.patch.
-
-* Try to apply to the tip of the "master" branch from the
- git.git public repository:
-
- $ git fetch http://kernel.org/pub/scm/git/git.git master:test-apply
- $ git checkout test-apply
- $ git reset --hard
- $ git am a.patch
-
-If it does not apply correctly, there can be various reasons.
-
-* Your patch itself does not apply cleanly. That is _bad_ but
- does not have much to do with your MUA. Please rebase the
- patch appropriately.
-
-* Your MUA corrupted your patch; "am" would complain that
- the patch does not apply. Look at .git/rebase-apply/ subdirectory and
- see what 'patch' file contains and check for the common
- corruption patterns mentioned above.
-
-* While you are at it, check what are in 'info' and
- 'final-commit' files as well. If what is in 'final-commit' is
- not exactly what you would want to see in the commit log
- message, it is very likely that your maintainer would end up
- hand editing the log message when he applies your patch.
- Things like "Hi, this is my first patch.\n", if you really
- want to put in the patch e-mail, should come after the
- three-dash line that signals the end of the commit message.
+While you are at it, check the resulting commit log message from
+a trial run of applying the patch. If what is in the resulting
+commit is not exactly what you would want to see, it is very
+likely that your maintainer would end up hand editing the log
+message when he applies your patch. Things like "Hi, this is my
+first patch.\n", if you really want to put in the patch e-mail,
+should come after the three-dash line that signals the end of the
+commit message.
Pine
@@ -443,89 +413,10 @@ that or Gentoo did it.) So you need to set the
it.
-Thunderbird
------------
-
-(A Large Angry SCM)
-
-By default, Thunderbird will both wrap emails as well as flag them as
-being 'format=flowed', both of which will make the resulting email unusable
-by git.
-
-Here are some hints on how to successfully submit patches inline using
-Thunderbird.
-
-There are two different approaches. One approach is to configure
-Thunderbird to not mangle patches. The second approach is to use
-an external editor to keep Thunderbird from mangling the patches.
-
-Approach #1 (configuration):
-
-This recipe is current as of Thunderbird 2.0.0.19. Three steps:
- 1. Configure your mail server composition as plain text
- Edit...Account Settings...Composition & Addressing,
- uncheck 'Compose Messages in HTML'.
- 2. Configure your general composition window to not wrap
- Edit..Preferences..Composition, wrap plain text messages at 0
- 3. Disable the use of format=flowed
- Edit..Preferences..Advanced..Config Editor. Search for:
- mailnews.send_plaintext_flowed
- toggle it to make sure it is set to 'false'.
-
-After that is done, you should be able to compose email as you
-otherwise would (cut + paste, git-format-patch | git-imap-send, etc),
-and the patches should not be mangled.
-
-Approach #2 (external editor):
-
-This recipe appears to work with the current [*1*] Thunderbird from Suse.
-
-The following Thunderbird extensions are needed:
- AboutConfig 0.5
- http://aboutconfig.mozdev.org/
- External Editor 0.7.2
- http://globs.org/articles.php?lng=en&pg=8
-
-1) Prepare the patch as a text file using your method of choice.
-
-2) Before opening a compose window, use Edit->Account Settings to
-uncheck the "Compose messages in HTML format" setting in the
-"Composition & Addressing" panel of the account to be used to send the
-patch. [*2*]
-
-3) In the main Thunderbird window, _before_ you open the compose window
-for the patch, use Tools->about:config to set the following to the
-indicated values:
- mailnews.send_plaintext_flowed => false
- mailnews.wraplength => 0
-
-4) Open a compose window and click the external editor icon.
-
-5) In the external editor window, read in the patch file and exit the
-editor normally.
-
-6) Back in the compose window: Add whatever other text you wish to the
-message, complete the addressing and subject fields, and press send.
-
-7) Optionally, undo the about:config/account settings changes made in
-steps 2 & 3.
+Thunderbird, KMail, GMail
+-------------------------
-
-[Footnotes]
-*1* Version 1.0 (20041207) from the MozillaThunderbird-1.0-5 rpm of Suse
-9.3 professional updates.
-
-*2* It may be possible to do this with about:config and the following
-settings but I haven't tried, yet.
- mail.html_compose => false
- mail.identity.default.compose_html => false
- mail.identity.id?.compose_html => false
-
-(Lukas Sandström)
-
-There is a script in contrib/thunderbird-patch-inline which can help
-you include patches with Thunderbird in an easy way. To use it, do the
-steps above and then use the script as the external editor.
+See the MUA-SPECIFIC HINTS section of git-format-patch(1).
Gnus
----
@@ -540,72 +431,3 @@ characters (most notably in people's names), and also
whitespaces (fatal in patches). Running 'C-u g' to display the
message in raw form before using '|' to run the pipe can work
this problem around.
-
-
-KMail
------
-
-This should help you to submit patches inline using KMail.
-
-1) Prepare the patch as a text file.
-
-2) Click on New Mail.
-
-3) Go under "Options" in the Composer window and be sure that
-"Word wrap" is not set.
-
-4) Use Message -> Insert file... and insert the patch.
-
-5) Back in the compose window: add whatever other text you wish to the
-message, complete the addressing and subject fields, and press send.
-
-
-Gmail
------
-
-GMail does not appear to have any way to turn off line wrapping in the web
-interface, so this will mangle any emails that you send. You can however
-use "git send-email" and send your patches through the GMail SMTP server, or
-use any IMAP email client to connect to the google IMAP server and forward
-the emails through that.
-
-To use "git send-email" and send your patches through the GMail SMTP server,
-edit ~/.gitconfig to specify your account settings:
-
-[sendemail]
- smtpencryption = tls
- smtpserver = smtp.gmail.com
- smtpuser = user@gmail.com
- smtppass = p4ssw0rd
- smtpserverport = 587
-
-Once your commits are ready to be sent to the mailing list, run the
-following commands:
-
- $ git format-patch --cover-letter -M origin/master -o outgoing/
- $ edit outgoing/0000-*
- $ git send-email outgoing/*
-
-To submit using the IMAP interface, first, edit your ~/.gitconfig to specify your
-account settings:
-
-[imap]
- folder = "[Gmail]/Drafts"
- host = imaps://imap.gmail.com
- user = user@gmail.com
- pass = p4ssw0rd
- port = 993
- sslverify = false
-
-You might need to instead use: folder = "[Google Mail]/Drafts" if you get an error
-that the "Folder doesn't exist".
-
-Once your commits are ready to be sent to the mailing list, run the
-following commands:
-
- $ git format-patch --cover-letter -M --stdout origin/master | git imap-send
-
-Just make sure to disable line wrapping in the email client (GMail web
-interface will line wrap no matter what, so you need to use a real
-IMAP client).
-
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 750c86d4f..cc6d48010 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -442,8 +442,6 @@ for most projects as source code and other text files can still
be delta compressed, but larger binary media files won't be.
+
Common unit suffixes of 'k', 'm', or 'g' are supported.
-+
-Currently only linkgit:git-fast-import[1] honors this setting.
core.excludesfile::
In addition to '.gitignore' (per-directory) and
@@ -708,9 +706,16 @@ second is the background. The position of the attribute, if any,
doesn't matter.
color.diff::
- When set to `always`, always use colors in patch.
- When false (or `never`), never. When set to `true` or `auto`, use
- colors only when the output is to the terminal. Defaults to false.
+ Whether to use ANSI escape sequences to add color to patches.
+ If this is set to `always`, linkgit:git-diff[1],
+ linkgit:git-log[1], and linkgit:git-show[1] will use color
+ for all patches. If it is set to `true` or `auto`, those
+ commands will only use color when output is to the terminal.
+ Defaults to false.
++
+This does not affect linkgit:git-format-patch[1] nor the
+'git-diff-{asterisk}' plumbing commands. Can be overridden on the
+command line with the `--color[=<when>]` option.
color.diff.<slot>::
Use customized color for diff colorization. `<slot>` specifies
@@ -796,11 +801,15 @@ color.status.<slot>::
color.branch.<slot>.
color.ui::
- When set to `always`, always use colors in all git commands which
- are capable of colored output. When false (or `never`), never. When
- set to `true` or `auto`, use colors only when the output is to the
- terminal. When more specific variables of color.* are set, they always
- take precedence over this setting. Defaults to false.
+ This variable determines the default value for variables such
+ as `color.diff` and `color.grep` that control the use of color
+ per command family. Its scope will expand as more commands learn
+ configuration to set a default for the `--color` option. Set it
+ to `always` if you want all output not intended for machine
+ consumption to use color, to `true` or `auto` if you want such
+ output to use color when written to the terminal, or to `false` or
+ `never` if you prefer git commands not to use color unless enabled
+ explicitly with some other configuration or the `--color` option.
commit.status::
A boolean to enable/disable inclusion of status information in the
@@ -812,68 +821,7 @@ commit.template::
"{tilde}/" is expanded to the value of `$HOME` and "{tilde}user/" to the
specified user's home directory.
-diff.autorefreshindex::
- When using 'git diff' to compare with work tree
- files, do not consider stat-only change as changed.
- Instead, silently run `git update-index --refresh` to
- update the cached stat information for paths whose
- contents in the work tree match the contents in the
- index. This option defaults to true. Note that this
- affects only 'git diff' Porcelain, and not lower level
- 'diff' commands such as 'git diff-files'.
-
-diff.external::
- If this config variable is set, diff generation is not
- performed using the internal diff machinery, but using the
- given command. Can be overridden with the `GIT_EXTERNAL_DIFF'
- environment variable. The command is called with parameters
- as described under "git Diffs" in linkgit:git[1]. Note: if
- you want to use an external diff program only on a subset of
- your files, you might want to use linkgit:gitattributes[5] instead.
-
-diff.mnemonicprefix::
- If set, 'git diff' uses a prefix pair that is different from the
- standard "a/" and "b/" depending on what is being compared. When
- this configuration is in effect, reverse diff output also swaps
- the order of the prefixes:
-`git diff`;;
- compares the (i)ndex and the (w)ork tree;
-`git diff HEAD`;;
- compares a (c)ommit and the (w)ork tree;
-`git diff --cached`;;
- compares a (c)ommit and the (i)ndex;
-`git diff HEAD:file1 file2`;;
- compares an (o)bject and a (w)ork tree entity;
-`git diff --no-index a b`;;
- compares two non-git things (1) and (2).
-
-diff.noprefix::
- If set, 'git diff' does not show any source or destination prefix.
-
-diff.renameLimit::
- The number of files to consider when performing the copy/rename
- detection; equivalent to the 'git diff' option '-l'.
-
-diff.renames::
- Tells git to detect renames. If set to any boolean value, it
- will enable basic rename detection. If set to "copies" or
- "copy", it will detect copies, as well.
-
-diff.ignoreSubmodules::
- Sets the default value of --ignore-submodules. Note that this
- affects only 'git diff' Porcelain, and not lower level 'diff'
- commands such as 'git diff-files'. 'git checkout' also honors
- this setting when reporting uncommitted changes.
-
-diff.suppressBlankEmpty::
- A boolean to inhibit the standard behavior of printing a space
- before each empty output line. Defaults to false.
-
-diff.tool::
- Controls which diff tool is used. `diff.tool` overrides
- `merge.tool` when used by linkgit:git-difftool[1] and has
- the same valid values as `merge.tool` minus "tortoisemerge"
- and plus "kompare".
+include::diff-config.txt[]
difftool.<tool>.path::
Override the path for the given tool. This is useful in case
@@ -977,6 +925,16 @@ format.signoff::
the rights to submit this work under the same open source license.
Please see the 'SubmittingPatches' document for further discussion.
+filter.<driver>.clean::
+ The command which is used to convert the content of a worktree
+ file to a blob upon checkin. See linkgit:gitattributes[5] for
+ details.
+
+filter.<driver>.smudge::
+ The command which is used to convert the content of a blob
+ object to a worktree file upon checkout. See
+ linkgit:gitattributes[5] for details.
+
gc.aggressiveWindow::
The window size parameter used in the delta compression
algorithm used by 'git gc --aggressive'. This defaults
diff --git a/Documentation/diff-config.txt b/Documentation/diff-config.txt
new file mode 100644
index 000000000..2b1605f5c
--- /dev/null
+++ b/Documentation/diff-config.txt
@@ -0,0 +1,92 @@
+diff.autorefreshindex::
+ When using 'git diff' to compare with work tree
+ files, do not consider stat-only change as changed.
+ Instead, silently run `git update-index --refresh` to
+ update the cached stat information for paths whose
+ contents in the work tree match the contents in the
+ index. This option defaults to true. Note that this
+ affects only 'git diff' Porcelain, and not lower level
+ 'diff' commands such as 'git diff-files'.
+
+diff.external::
+ If this config variable is set, diff generation is not
+ performed using the internal diff machinery, but using the
+ given command. Can be overridden with the `GIT_EXTERNAL_DIFF'
+ environment variable. The command is called with parameters
+ as described under "git Diffs" in linkgit:git[1]. Note: if
+ you want to use an external diff program only on a subset of
+ your files, you might want to use linkgit:gitattributes[5] instead.
+
+diff.ignoreSubmodules::
+ Sets the default value of --ignore-submodules. Note that this
+ affects only 'git diff' Porcelain, and not lower level 'diff'
+ commands such as 'git diff-files'. 'git checkout' also honors
+ this setting when reporting uncommitted changes.
+
+diff.mnemonicprefix::
+ If set, 'git diff' uses a prefix pair that is different from the
+ standard "a/" and "b/" depending on what is being compared. When
+ this configuration is in effect, reverse diff output also swaps
+ the order of the prefixes:
+`git diff`;;
+ compares the (i)ndex and the (w)ork tree;
+`git diff HEAD`;;
+ compares a (c)ommit and the (w)ork tree;
+`git diff --cached`;;
+ compares a (c)ommit and the (i)ndex;
+`git diff HEAD:file1 file2`;;
+ compares an (o)bject and a (w)ork tree entity;
+`git diff --no-index a b`;;
+ compares two non-git things (1) and (2).
+
+diff.noprefix::
+ If set, 'git diff' does not show any source or destination prefix.
+
+diff.renameLimit::
+ The number of files to consider when performing the copy/rename
+ detection; equivalent to the 'git diff' option '-l'.
+
+diff.renames::
+ Tells git to detect renames. If set to any boolean value, it
+ will enable basic rename detection. If set to "copies" or
+ "copy", it will detect copies, as well.
+
+diff.suppressBlankEmpty::
+ A boolean to inhibit the standard behavior of printing a space
+ before each empty output line. Defaults to false.
+
+diff.<driver>.command::
+ The custom diff driver command. See linkgit:gitattributes[5]
+ for details.
+
+diff.<driver>.xfuncname::
+ The regular expression that the diff driver should use to
+ recognize the hunk header. A built-in pattern may also be used.
+ See linkgit:gitattributes[5] for details.
+
+diff.<driver>.binary::
+ Set this option to true to make the diff driver treat files as
+ binary. See linkgit:gitattributes[5] for details.
+
+diff.<driver>.textconv::
+ The command that the diff driver should call to generate the
+ text-converted version of a file. The result of the
+ conversion is used to generate a human-readable diff. See
+ linkgit:gitattributes[5] for details.
+
+diff.<driver>.wordregex::
+ The regular expression that the diff driver should use to
+ split words in a line. See linkgit:gitattributes[5] for
+ details.
+
+diff.<driver>.cachetextconv::
+ Set this option to true to make the diff driver cache the text
+ conversion outputs. See linkgit:gitattributes[5] for details.
+
+diff.tool::
+ The diff tool to be used by linkgit:git-difftool[1]. This
+ option overrides `merge.tool`, and has the same valid built-in
+ values as `merge.tool` minus "tortoisemerge" and plus
+ "kompare". Any other value is treated as a custom diff tool,
+ and there must be a corresponding `difftool.<tool>.cmd`
+ option.
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index c93124be7..80fd817c2 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -72,6 +72,10 @@ endif::git-format-patch[]
a cut-off percent (3% by default) are not shown. The cut-off percent
can be set with `--dirstat=<limit>`. Changes in a child directory are not
counted for the parent directory, unless `--cumulative` is used.
++
+Note that the `--dirstat` option computes the changes while ignoring
+the amount of pure code movements within a file. In other words,
+rearranging lines in a file is not counted as much as other changes.
--dirstat-by-file[=<limit>]::
Same as `--dirstat`, but counts changed files instead of lines.
@@ -120,12 +124,19 @@ any of those replacements occurred.
--color[=<when>]::
Show colored diff.
- The value must be always (the default), never, or auto.
+ The value must be `always` (the default for `<when>`), `never`, or `auto`.
+ The default value is `never`.
+ifdef::git-diff[]
+ It can be changed by the `color.ui` and `color.diff`
+ configuration settings.
+endif::git-diff[]
--no-color::
- Turn off colored diff, even when the configuration file
- gives the default to color output.
- Same as `--color=never`.
+ Turn off colored diff.
+ifdef::git-diff[]
+ This can be used to override configuration settings.
+endif::git-diff[]
+ It is the same as `--color=never`.
--word-diff[=<mode>]::
Show a word diff, using the <mode> to delimit changed words.
@@ -239,7 +250,7 @@ ifdef::git-log[]
For following files across renames while traversing history, see
`--follow`.
endif::git-log[]
- If `n` is specified, it is a is a threshold on the similarity
+ If `n` is specified, it is a threshold on the similarity
index (i.e. amount of addition/deletions compared to the
file's size). For example, `-M90%` means git should consider a
delete/add pair to be a rename if more than 90% of the file
diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 7eebbefe7..35cb5d3f6 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -134,6 +134,8 @@ subdirectories.
If some files could not be added because of errors indexing
them, do not abort the operation, but continue adding the
others. The command shall still exit with non-zero status.
+ The configuration variable `add.ignoreErrors` can be set to
+ true to make this the default behaviour.
--ignore-missing::
This option can only be used together with --dry-run. By using
diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt
index f2b868459..9c750e244 100644
--- a/Documentation/git-archive.txt
+++ b/Documentation/git-archive.txt
@@ -98,7 +98,8 @@ tar.umask::
tar archive entries. The default is 0002, which turns off the
world write bit. The special value "user" indicates that the
archiving user's umask will be used instead. See umask(2) for
- details.
+ details. If `--remote` is used then only the configuration of
+ the remote repository takes effect.
ATTRIBUTES
----------
diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index 01db83039..9d8fe0d26 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt
@@ -51,9 +51,10 @@ OPTIONS
message prior to committing.
-x::
- When recording the commit, append to the original commit
- message a note that indicates which commit this change
- was cherry-picked from. Append the note only for cherry
+ When recording the commit, append a line that says
+ "(cherry picked from commit ...)" to the original commit
+ message in order to indicate which commit this change was
+ cherry-picked from. This is done only for cherry
picks without conflicts. Do not use this option if
you are cherry-picking from your private branch because
the information is useless to the recipient. If on the
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 86eb4c936..b093e4549 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -12,7 +12,7 @@ SYNOPSIS
'git clone' [--template=<template_directory>]
[-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
[-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
- [--separate-git-dir|-L <git dir>]
+ [--separate-git-dir <git dir>]
[--depth <depth>] [--recursive|--recurse-submodules] [--] <repository>
[<directory>]
@@ -177,7 +177,6 @@ objects from the source repository into a pack in the cloned repository.
repository does not have a worktree/checkout (i.e. if any of
`--no-checkout`/`-n`, `--bare`, or `--mirror` is given)
--L=<git dir>::
--separate-git-dir=<git dir>::
Instead of placing the cloned repository where it is supposed
to be, place the cloned repository at the specified directory,
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index 2c2ea12c5..249249aac 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -83,7 +83,7 @@ OPTIONS
skips the file if it does not exist.
--relative-marks::
- After specifying --relative-marks= the paths specified
+ After specifying --relative-marks the paths specified
with --import-marks= and --export-marks= are relative
to an internal directory in the current repository.
In git-fast-import this means that the paths are relative
@@ -93,7 +93,7 @@ OPTIONS
--no-relative-marks::
Negates a previous --relative-marks. Allows for combining
relative and non-relative marks by interweaving
- --(no-)-relative-marks= with the --(import|export)-marks=
+ --(no-)-relative-marks with the --(import|export)-marks=
options.
--cat-blob-fd=<fd>::
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index 67d221467..60ac8d26e 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -34,7 +34,7 @@ pointed by remote tags that it does not yet have, then fetch
those missing tags. If the other end has tags that point at
branches you are not interested in, you will not get them.
-'git fetch' can fetch from either a single named repository, or
+'git fetch' can fetch from either a single named repository,
or from several repositories at once if <group> is given and
there is a remotes.<group> entry in the configuration file.
(See linkgit:git-config[1]).
diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt
index a5525e9aa..d13c9b23f 100644
--- a/Documentation/git-format-patch.txt
+++ b/Documentation/git-format-patch.txt
@@ -20,7 +20,7 @@ SYNOPSIS
[--ignore-if-in-upstream]
[--subject-prefix=Subject-Prefix]
[--to=<email>] [--cc=<email>]
- [--cover-letter]
+ [--cover-letter] [--quiet]
[<common diff options>]
[ <since> | <revision range> ]
@@ -196,6 +196,9 @@ will want to ensure that threading is disabled for `git send-email`.
Note that the leading character does not have to be a dot; for example,
you can use `--suffix=-patch` to get `0001-description-of-my-change-patch`.
+--quiet::
+ Do not print the names of the generated files to standard output.
+
--no-binary::
Do not output contents of changes in binary files, instead
display a notice that those files changed. Patches generated
@@ -229,6 +232,233 @@ attachments, and sign off patches with configuration variables.
------------
+DISCUSSION
+----------
+
+The patch produced by 'git format-patch' is in UNIX mailbox format,
+with a fixed "magic" time stamp to indicate that the file is output
+from format-patch rather than a real mailbox, like so:
+
+------------
+From 8f72bad1baf19a53459661343e21d6491c3908d3 Mon Sep 17 00:00:00 2001
+From: Tony Luck <tony.luck@intel.com>
+Date: Tue, 13 Jul 2010 11:42:54 -0700
+Subject: [PATCH] =?UTF-8?q?[IA64]=20Put=20ia64=20config=20files=20on=20the=20?=
+ =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig=20diet?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+arch/arm config files were slimmed down using a python script
+(See commit c2330e286f68f1c408b4aa6515ba49d57f05beae comment)
+
+Do the same for ia64 so we can have sleek & trim looking
+...
+------------
+
+Typically it will be placed in a MUA's drafts folder, edited to add
+timely commentary that should not go in the changelog after the three
+dashes, and then sent as a message whose body, in our example, starts
+with "arch/arm config files were...". On the receiving end, readers
+can save interesting patches in a UNIX mailbox and apply them with
+linkgit:git-am[1].
+
+When a patch is part of an ongoing discussion, the patch generated by
+'git format-patch' can be tweaked to take advantage of the 'git am
+--scissors' feature. After your response to the discussion comes a
+line that consists solely of "`-- >8 --`" (scissors and perforation),
+followed by the patch with unnecessary header fields removed:
+
+------------
+...
+> So we should do such-and-such.
+
+Makes sense to me. How about this patch?
+
+-- >8 --
+Subject: [IA64] Put ia64 config files on the Uwe Kleine-König diet
+
+arch/arm config files were slimmed down using a python script
+...
+------------
+
+When sending a patch this way, most often you are sending your own
+patch, so in addition to the "`From $SHA1 $magic_timestamp`" marker you
+should omit `From:` and `Date:` lines from the patch file. The patch
+title is likely to be different from the subject of the discussion the
+patch is in response to, so it is likely that you would want to keep
+the Subject: line, like the example above.
+
+Checking for patch corruption
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Many mailers if not set up properly will corrupt whitespace. Here are
+two common types of corruption:
+
+* Empty context lines that do not have _any_ whitespace.
+
+* Non-empty context lines that have one extra whitespace at the
+ beginning.
+
+One way to test if your MUA is set up correctly is:
+
+* Send the patch to yourself, exactly the way you would, except
+ with To: and Cc: lines that do not contain the list and
+ maintainer address.
+
+* Save that patch to a file in UNIX mailbox format. Call it a.patch,
+ say.
+
+* Apply it:
+
+ $ git fetch <project> master:test-apply
+ $ git checkout test-apply
+ $ git reset --hard
+ $ git am a.patch
+
+If it does not apply correctly, there can be various reasons.
+
+* The patch itself does not apply cleanly. That is _bad_ but
+ does not have much to do with your MUA. You might want to rebase
+ the patch with linkgit:git-rebase[1] before regenerating it in
+ this case.
+
+* The MUA corrupted your patch; "am" would complain that
+ the patch does not apply. Look in the .git/rebase-apply/ subdirectory and
+ see what 'patch' file contains and check for the common
+ corruption patterns mentioned above.
+
+* While at it, check the 'info' and 'final-commit' files as well.
+ If what is in 'final-commit' is not exactly what you would want to
+ see in the commit log message, it is very likely that the
+ receiver would end up hand editing the log message when applying
+ your patch. Things like "Hi, this is my first patch.\n" in the
+ patch e-mail should come after the three-dash line that signals
+ the end of the commit message.
+
+MUA-SPECIFIC HINTS
+------------------
+Here are some hints on how to successfully submit patches inline using
+various mailers.
+
+GMail
+~~~~~
+GMail does not have any way to turn off line wrapping in the web
+interface, so it will mangle any emails that you send. You can however
+use "git send-email" and send your patches through the GMail SMTP server, or
+use any IMAP email client to connect to the google IMAP server and forward
+the emails through that.
+
+For hints on using 'git send-email' to send your patches through the
+GMail SMTP server, see the EXAMPLE section of linkgit:git-send-email[1].
+
+For hints on submission using the IMAP interface, see the EXAMPLE
+section of linkgit:git-imap-send[1].
+
+Thunderbird
+~~~~~~~~~~~
+By default, Thunderbird will both wrap emails as well as flag
+them as being 'format=flowed', both of which will make the
+resulting email unusable by git.
+
+There are three different approaches: use an add-on to turn off line wraps,
+configure Thunderbird to not mangle patches, or use
+an external editor to keep Thunderbird from mangling the patches.
+
+Approach #1 (add-on)
+^^^^^^^^^^^^^^^^^^^^
+
+Install the Toggle Word Wrap add-on that is available from
+https://addons.mozilla.org/thunderbird/addon/toggle-word-wrap/
+It adds a menu entry "Enable Word Wrap" in the composer's "Options" menu
+that you can tick off. Now you can compose the message as you otherwise do
+(cut + paste, 'git format-patch' | 'git imap-send', etc), but you have to
+insert line breaks manually in any text that you type.
+
+Approach #2 (configuration)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Three steps:
+
+1. Configure your mail server composition as plain text:
+ Edit...Account Settings...Composition & Addressing,
+ uncheck "Compose Messages in HTML".
+
+2. Configure your general composition window to not wrap.
++
+In Thunderbird 2:
+Edit..Preferences..Composition, wrap plain text messages at 0
++
+In Thunderbird 3:
+Edit..Preferences..Advanced..Config Editor. Search for
+"mail.wrap_long_lines".
+Toggle it to make sure it is set to `false`.
+
+3. Disable the use of format=flowed:
+Edit..Preferences..Advanced..Config Editor. Search for
+"mailnews.send_plaintext_flowed".
+Toggle it to make sure it is set to `false`.
+
+After that is done, you should be able to compose email as you
+otherwise would (cut + paste, 'git format-patch' | 'git imap-send', etc),
+and the patches will not be mangled.
+
+Approach #3 (external editor)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following Thunderbird extensions are needed:
+AboutConfig from http://aboutconfig.mozdev.org/ and
+External Editor from http://globs.org/articles.php?lng=en&pg=8
+
+1. Prepare the patch as a text file using your method of choice.
+
+2. Before opening a compose window, use Edit->Account Settings to
+ uncheck the "Compose messages in HTML format" setting in the
+ "Composition & Addressing" panel of the account to be used to
+ send the patch.
+
+3. In the main Thunderbird window, 'before' you open the compose
+ window for the patch, use Tools->about:config to set the
+ following to the indicated values:
++
+----------
+ mailnews.send_plaintext_flowed => false
+ mailnews.wraplength => 0
+----------
+
+4. Open a compose window and click the external editor icon.
+
+5. In the external editor window, read in the patch file and exit
+ the editor normally.
+
+Side note: it may be possible to do step 2 with
+about:config and the following settings but no one's tried yet.
+
+----------
+ mail.html_compose => false
+ mail.identity.default.compose_html => false
+ mail.identity.id?.compose_html => false
+----------
+
+There is a script in contrib/thunderbird-patch-inline which can help
+you include patches with Thunderbird in an easy way. To use it, do the
+steps above and then use the script as the external editor.
+
+KMail
+~~~~~
+This should help you to submit patches inline using KMail.
+
+1. Prepare the patch as a text file.
+
+2. Click on New Mail.
+
+3. Go under "Options" in the Composer window and be sure that
+ "Word wrap" is not set.
+
+4. Use Message -> Insert file... and insert the patch.
+
+5. Back in the compose window: add whatever other text you wish to the
+ message, complete the addressing and subject fields, and press send.
+
+
EXAMPLES
--------
diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt
index c9ede794b..a2a508dc2 100644
--- a/Documentation/git-fsck.txt
+++ b/Documentation/git-fsck.txt
@@ -26,7 +26,7 @@ index file, all SHA1 references in .git/refs/*, and all reflogs (unless
--no-reflogs is given) as heads.
--unreachable::
- Print out objects that exist but that aren't readable from any
+ Print out objects that exist but that aren't reachable from any
of the reference nodes.
--root::
@@ -76,7 +76,7 @@ It tests SHA1 and general object sanity, and it does full tracking of
the resulting reachability and everything else. It prints out any
corruption it finds (missing or bad objects), and if you use the
'--unreachable' flag it will also print out objects that exist but
-that aren't readable from any of the specified head nodes.
+that aren't reachable from any of the specified head nodes.
So for example
diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt
index d3013d6a2..4e09708cc 100644
--- a/Documentation/git-imap-send.txt
+++ b/Documentation/git-imap-send.txt
@@ -111,6 +111,31 @@ Using direct mode with SSL:
..........................
+EXAMPLE
+-------
+To submit patches using GMail's IMAP interface, first, edit your ~/.gitconfig
+to specify your account settings:
+
+---------
+[imap]
+ folder = "[Gmail]/Drafts"
+ host = imaps://imap.gmail.com
+ user = user@gmail.com
+ port = 993
+ sslverify = false
+---------
+
+You might need to instead use: folder = "[Google Mail]/Drafts" if you get an error
+that the "Folder doesn't exist".
+
+Once the commits are ready to be sent, run the following command:
+
+ $ git format-patch --cover-letter -M --stdout origin/master | git imap-send
+
+Just make sure to disable line wrapping in the email client (GMail's web
+interface will wrap lines no matter what, so you need to use a real
+IMAP client).
+
CAUTION
-------
It is still your responsibility to make sure that the email message
@@ -124,6 +149,10 @@ Thunderbird in particular is known to be problematic. Thunderbird
users may wish to visit this web page for more information:
http://kb.mozillazine.org/Plain_text_e-mail_-_Thunderbird#Completely_plain_email
+SEE ALSO
+--------
+linkgit:git-format-patch[1], linkgit:git-send-email[1], mbox(5)
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt
index 2c4c716f3..9f97f5a91 100644
--- a/Documentation/git-init-db.txt
+++ b/Documentation/git-init-db.txt
@@ -8,7 +8,7 @@ git-init-db - Creates an empty git repository
SYNOPSIS
--------
-'git init-db' [-q | --quiet] [--bare] [--template=<template_directory>] [--shared[=<permissions>]]
+'git init-db' [-q | --quiet] [--bare] [--template=<template_directory>] [--separate-git-dir <git dir>] [--shared[=<permissions>]]
DESCRIPTION
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 58cd01145..f2777a778 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -9,7 +9,7 @@ git-init - Create an empty git repository or reinitialize an existing one
SYNOPSIS
--------
'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
- [--separate-git-dir|-L <git dir>]
+ [--separate-git-dir <git dir>]
[--shared[=<permissions>]] [directory]
@@ -54,7 +54,6 @@ current working directory.
Specify the directory from which templates will be used. (See the "TEMPLATE
DIRECTORY" section below.)
--L=<git dir>::
--separate-git-dir=<git dir>::
Instead of initializing the repository where it is supposed to be,
diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt
index ba36ec04f..b295bf833 100644
--- a/Documentation/git-merge-base.txt
+++ b/Documentation/git-merge-base.txt
@@ -9,7 +9,8 @@ git-merge-base - Find as good common ancestors as possible for a merge
SYNOPSIS
--------
[verse]
-'git merge-base' [-a|--all] [--octopus] <commit> <commit>...
+'git merge-base' [-a|--all] <commit> <commit>...
+'git merge-base' [-a|--all] --octopus <commit>...
'git merge-base' --independent <commit>...
DESCRIPTION
@@ -22,23 +23,21 @@ that does not have any better common ancestor is a 'best common
ancestor', i.e. a 'merge base'. Note that there can be more than one
merge base for a pair of commits.
-Unless `--octopus` is given, among the two commits to compute the merge
-base from, one is specified by the first commit argument on the command
-line; the other commit is a (possibly hypothetical) commit that is a merge
-across all the remaining commits on the command line. As the most common
-special case, specifying only two commits on the command line means
-computing the merge base between the given two commits.
+OPERATION MODE
+--------------
+
+As the most common special case, specifying only two commits on the
+command line means computing the merge base between the given two commits.
+
+More generally, among the two commits to compute the merge base from,
+one is specified by the first commit argument on the command line;
+the other commit is a (possibly hypothetical) commit that is a merge
+across all the remaining commits on the command line.
As a consequence, the 'merge base' is not necessarily contained in each of the
commit arguments if more than two commits are specified. This is different
from linkgit:git-show-branch[1] when used with the `--merge-base` option.
-OPTIONS
--------
--a::
---all::
- Output all merge bases for the commits, instead of just one.
-
--octopus::
Compute the best common ancestors of all supplied commits,
in preparation for an n-way merge. This mimics the behavior
@@ -51,6 +50,12 @@ OPTIONS
from any other. This mimics the behavior of 'git show-branch
--independent'.
+OPTIONS
+-------
+-a::
+--all::
+ Output all merge bases for the commits, instead of just one.
+
DISCUSSION
----------
@@ -89,6 +94,9 @@ and the result of `git merge-base A M` is '1'. Commit '2' is also a
common ancestor between 'A' and 'M', but '1' is a better common ancestor,
because '2' is an ancestor of '1'. Hence, '2' is not a merge base.
+The result of `git merge-base --octopus A B C` is '2', because '2' is
+the best common ancestor of all commits.
+
When the history involves criss-cross merges, there can be more than one
'best' common ancestor for two commits. For example, with this topology:
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index 08c89d221..20c8551d6 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -115,7 +115,7 @@ base-name::
--honor-pack-keep::
This flag causes an object already in a local pack that
- has a .keep file to be ignored, even if it it would have
+ has a .keep file to be ignored, even if it would have
otherwise been packed.
--incremental::
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index ee14f74fd..5a168cfab 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -348,10 +348,12 @@ sendemail.confirm::
one of 'always', 'never', 'cc', 'compose', or 'auto'. See '--confirm'
in the previous section for the meaning of these values.
+EXAMPLE
+-------
Use gmail as the smtp server
-----------------------------
-
-Add the following section to the config file:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+To use 'git send-email' to send your patches through the GMail SMTP server,
+edit ~/.gitconfig to specify your account settings:
[sendemail]
smtpencryption = tls
@@ -359,9 +361,20 @@ Add the following section to the config file:
smtpuser = yourname@gmail.com
smtpserverport = 587
+Once your commits are ready to be sent to the mailing list, run the
+following commands:
+
+ $ git format-patch --cover-letter -M origin/master -o outgoing/
+ $ edit outgoing/0000-*
+ $ git send-email outgoing/*
+
Note: the following perl modules are required
Net::SMTP::SSL, MIME::Base64 and Authen::SASL
+SEE ALSO
+--------
+linkgit:git-format-patch[1], linkgit:git-imap-send[1], mbox(5)
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 4aa6404f4..39feb6212 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -145,17 +145,6 @@ Skip "branches" and "tags" of first level directories;;
------------------------------------------------------------------------
--
---use-log-author;;
- When retrieving svn commits into git (as part of fetch, rebase, or
- dcommit operations), look for the first From: or Signed-off-by: line
- in the log message and use that as the author string.
---add-author-from;;
- When committing to svn from git (as part of commit or dcommit
- operations), if the existing log message doesn't already have a
- From: or Signed-off-by: line, append a From: line based on the
- git commit's author string. If you use this, then --use-log-author
- will retrieve a valid author string for all commits.
-
'clone'::
Runs 'init' and 'fetch'. It will automatically create a
directory based on the basename of the URL passed to it;
@@ -217,6 +206,13 @@ config key: svn.commiturl (overwrites all svn-remote.<name>.commiturl options)
Using this option for any other purpose (don't ask) is very strongly
discouraged.
+--mergeinfo=<mergeinfo>;;
+ Add the given merge information during the dcommit
+ (e.g. `--mergeinfo="/branches/foo:1-10"`). All svn server versions can
+ store this information (as a property), and svn clients starting from
+ version 1.5 can make use of it. 'git svn' currently does not use it
+ and does not set it automatically.
+
'branch'::
Create a branch in the SVN repository.
@@ -565,6 +561,17 @@ repository that will be fetched from.
For 'branch' and 'tag', display the urls that will be used for copying when
creating the branch or tag.
+--use-log-author::
+ When retrieving svn commits into git (as part of 'fetch', 'rebase', or
+ 'dcommit' operations), look for the first `From:` or `Signed-off-by:` line
+ in the log message and use that as the author string.
+--add-author-from::
+ When committing to svn from git (as part of 'commit-diff', 'set-tree' or 'dcommit'
+ operations), if the existing log message doesn't already have a
+ `From:` or `Signed-off-by:` line, append a `From:` line based on the
+ git commit's author string. If you use this, then `--use-log-author`
+ will retrieve a valid author string for all commits.
+
ADVANCED OPTIONS
----------------
@@ -767,10 +774,9 @@ use `git svn rebase` to update your work branch instead of `git pull` or
when committing into SVN, which can lead to merge commits reversing
previous commits in SVN.
-DESIGN PHILOSOPHY
------------------
-Merge tracking in Subversion is lacking and doing branched development
-with Subversion can be cumbersome as a result. While 'git svn' can track
+MERGE TRACKING
+--------------
+While 'git svn' can track
copy history (including branches and tags) for repositories adopting a
standard layout, it cannot yet represent merge history that happened
inside git back upstream to SVN users. Therefore it is advised that
@@ -780,16 +786,15 @@ compatibility with SVN (see the CAVEATS section below).
CAVEATS
-------
-For the sake of simplicity and interoperating with a less-capable system
-(SVN), it is recommended that all 'git svn' users clone, fetch and dcommit
+For the sake of simplicity and interoperating with Subversion,
+it is recommended that all 'git svn' users clone, fetch and dcommit
directly from the SVN server, and avoid all 'git clone'/'pull'/'merge'/'push'
operations between git repositories and branches. The recommended
method of exchanging code between git branches and users is
'git format-patch' and 'git am', or just 'dcommit'ing to the SVN repository.
Running 'git merge' or 'git pull' is NOT recommended on a branch you
-plan to 'dcommit' from. Subversion does not represent merges in any
-reasonable or useful fashion; so users using Subversion cannot see any
+plan to 'dcommit' from because Subversion users cannot see any
merges you've made. Furthermore, if you merge or pull from a git branch
that is a mirror of an SVN branch, 'dcommit' may commit to the wrong
branch.
@@ -839,7 +844,7 @@ Renamed and copied directories are not detected by git and hence not
tracked when committing to SVN. I do not plan on adding support for
this as it's quite difficult and time-consuming to get working for all
the possible corner cases (git doesn't do it, either). Committing
-renamed and copied files are fully supported if they're similar enough
+renamed and copied files is fully supported if they're similar enough
for git to detect them.
CONFIGURATION
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 7df49ea0d..504e1b118 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -44,9 +44,18 @@ unreleased) version of git, that is available from 'master'
branch of the `git.git` repository.
Documentation for older releases are available here:
-* link:v1.7.4.4/git.html[documentation for release 1.7.4.4]
+* link:v1.7.5.3/git.html[documentation for release 1.7.5.3]
* release notes for
+ link:RelNotes/1.7.5.3.txt[1.7.5.3],
+ link:RelNotes/1.7.5.2.txt[1.7.5.2],
+ link:RelNotes/1.7.5.1.txt[1.7.5.1],
+ link:RelNotes/1.7.5.txt[1.7.5].
+
+* link:v1.7.4.5/git.html[documentation for release 1.7.4.5]
+
+* release notes for
+ link:RelNotes/1.7.4.5.txt[1.7.4.5],
link:RelNotes/1.7.4.4.txt[1.7.4.4],
link:RelNotes/1.7.4.3.txt[1.7.4.3],
link:RelNotes/1.7.4.2.txt[1.7.4.2],
@@ -622,7 +631,6 @@ where:
contents of <old|new>,
<old|new>-hex:: are the 40-hexdigit SHA1 hashes,
<old|new>-mode:: are the octal representation of the file modes.
-
+
The file parameters can point at the user's working file
(e.g. `new-file` in "git-diff-files"), `/dev/null` (e.g. `old-file`
diff --git a/Documentation/technical/api-diff.txt b/Documentation/technical/api-diff.txt
index 20b0241d3..2d2ebc04b 100644
--- a/Documentation/technical/api-diff.txt
+++ b/Documentation/technical/api-diff.txt
@@ -32,7 +32,7 @@ Calling sequence
* As you find different pairs of files, call `diff_change()` to feed
modified files, `diff_addremove()` to feed created or deleted files,
- or `diff_unmerged()` to feed a file whose state is 'unmerged' to the
+ or `diff_unmerge()` to feed a file whose state is 'unmerged' to the
API. These are thin wrappers to a lower-level `diff_queue()` function
that is flexible enough to record any of these kinds of changes.
@@ -50,7 +50,7 @@ Data structures
This is the internal representation for a single file (blob). It
records the blob object name (if known -- for a work tree file it
typically is a NUL SHA-1), filemode and pathname. This is what the
-`diff_addremove()`, `diff_change()` and `diff_unmerged()` synthesize and
+`diff_addremove()`, `diff_change()` and `diff_unmerge()` synthesize and
feed `diff_queue()` function with.
* `struct diff_filepair`
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index e9b2a47af..85e25a6dd 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.5-rc1
+DEF_VER=v1.7.5.3
LF='
'
diff --git a/LGPL-2.1 b/LGPL-2.1
new file mode 100644
index 000000000..d38b1b92b
--- /dev/null
+++ b/LGPL-2.1
@@ -0,0 +1,511 @@
+
+ While most of this project is under the GPL (see COPYING), the xdiff/
+ library and some libc code from compat/ are licensed under the
+ GNU LGPL, version 2.1 or (at your option) any later version and some
+ other files are under other licenses. Check the individual files to
+ be sure.
+
+----------------------------------------
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/Makefile b/Makefile
index cbc3fce2d..d2e2ea1c4 100644
--- a/Makefile
+++ b/Makefile
@@ -274,8 +274,7 @@ STRIP ?= strip
# mandir
# infodir
# htmldir
-# ETC_GITCONFIG (but not sysconfdir)
-# ETC_GITATTRIBUTES
+# sysconfdir
# can be specified as a relative path some/where/else;
# this is interpreted as relative to $(prefix) and "git" at
# runtime figures out where they are based on the path to the executable.
@@ -291,15 +290,8 @@ sharedir = $(prefix)/share
gitwebdir = $(sharedir)/gitweb
template_dir = share/git-core/templates
htmldir = share/doc/git-doc
-ifeq ($(prefix),/usr)
-sysconfdir = /etc
ETC_GITCONFIG = $(sysconfdir)/gitconfig
ETC_GITATTRIBUTES = $(sysconfdir)/gitattributes
-else
-sysconfdir = $(prefix)/etc
-ETC_GITCONFIG = etc/gitconfig
-ETC_GITATTRIBUTES = etc/gitattributes
-endif
lib = lib
# DESTDIR=
pathsep = :
@@ -1192,6 +1184,14 @@ endif
-include config.mak.autogen
-include config.mak
+ifndef sysconfdir
+ifeq ($(prefix),/usr)
+sysconfdir = /etc
+else
+sysconfdir = etc
+endif
+endif
+
ifdef CHECK_HEADER_DEPENDENCIES
COMPUTE_HEADER_DEPENDENCIES =
USE_COMPUTED_HEADER_DEPENDENCIES =
@@ -1747,33 +1747,7 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
gitweb:
$(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) all
-ifdef JSMIN
-GITWEB_PROGRAMS += gitweb/static/gitweb.min.js
-GITWEB_JS = gitweb/static/gitweb.min.js
-else
-GITWEB_JS = gitweb/static/gitweb.js
-endif
-ifdef CSSMIN
-GITWEB_PROGRAMS += gitweb/static/gitweb.min.css
-GITWEB_CSS = gitweb/static/gitweb.min.css
-else
-GITWEB_CSS = gitweb/static/gitweb.css
-endif
-OTHER_PROGRAMS += gitweb/gitweb.cgi $(GITWEB_PROGRAMS)
-gitweb/gitweb.cgi: gitweb/gitweb.perl $(GITWEB_PROGRAMS)
- $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@)
-
-ifdef JSMIN
-gitweb/static/gitweb.min.js: gitweb/static/gitweb.js
- $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@)
-endif # JSMIN
-ifdef CSSMIN
-gitweb/static/gitweb.min.css: gitweb/static/gitweb.css
- $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@)
-endif # CSSMIN
-
-
-git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/static/gitweb.css gitweb/static/gitweb.js
+git-instaweb: git-instaweb.sh gitweb
$(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
diff --git a/RelNotes b/RelNotes
index 540b756d2..bb805da97 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.7.5.txt \ No newline at end of file
+Documentation/RelNotes/1.7.5.3.txt \ No newline at end of file
diff --git a/builtin/add.c b/builtin/add.c
index d39a6ab93..e57abddf5 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -26,6 +26,27 @@ struct update_callback_data {
int add_errors;
};
+static int fix_unmerged_status(struct diff_filepair *p,
+ struct update_callback_data *data)
+{
+ if (p->status != DIFF_STATUS_UNMERGED)
+ return p->status;
+ if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
+ /*
+ * This is not an explicit add request, and the
+ * path is missing from the working tree (deleted)
+ */
+ return DIFF_STATUS_DELETED;
+ else
+ /*
+ * Either an explicit add request, or path exists
+ * in the working tree. An attempt to explicitly
+ * add a path that does not exist in the working tree
+ * will be caught as an error by the caller immediately.
+ */
+ return DIFF_STATUS_MODIFIED;
+}
+
static void update_callback(struct diff_queue_struct *q,
struct diff_options *opt, void *cbdata)
{
@@ -35,30 +56,9 @@ static void update_callback(struct diff_queue_struct *q,
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
const char *path = p->one->path;
- switch (p->status) {
+ switch (fix_unmerged_status(p, data)) {
default:
die(_("unexpected diff status %c"), p->status);
- case DIFF_STATUS_UNMERGED:
- /*
- * ADD_CACHE_IGNORE_REMOVAL is unset if "git
- * add -u" is calling us, In such a case, a
- * missing work tree file needs to be removed
- * if there is an unmerged entry at stage #2,
- * but such a diff record is followed by
- * another with DIFF_STATUS_DELETED (and if
- * there is no stage #2, we won't see DELETED
- * nor MODIFIED). We can simply continue
- * either way.
- */
- if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL))
- continue;
- /*
- * Otherwise, it is "git add path" is asking
- * to explicitly add it; we fall through. A
- * missing work tree file is an error and is
- * caught by add_file_to_index() in such a
- * case.
- */
case DIFF_STATUS_MODIFIED:
case DIFF_STATUS_TYPE_CHANGED:
if (add_file_to_index(&the_index, path, data->flags)) {
@@ -91,6 +91,7 @@ int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
data.flags = flags;
data.add_errors = 0;
rev.diffopt.format_callback_data = &data;
+ rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
return !!data.add_errors;
}
@@ -330,8 +331,8 @@ static struct option builtin_add_options[] = {
static int add_config(const char *var, const char *value, void *cb)
{
- if (!strcasecmp(var, "add.ignoreerrors") ||
- !strcasecmp(var, "add.ignore-errors")) {
+ if (!strcmp(var, "add.ignoreerrors") ||
+ !strcmp(var, "add.ignore-errors")) {
ignore_add_errors = git_config_bool(var, value);
return 0;
}
diff --git a/builtin/apply.c b/builtin/apply.c
index 36e150768..530d4bb7e 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -43,6 +43,7 @@ static int apply = 1;
static int apply_in_reverse;
static int apply_with_reject;
static int apply_verbosely;
+static int allow_overlap;
static int no_add;
static const char *fake_ancestor;
static int line_termination = '\n';
@@ -2430,9 +2431,9 @@ static void update_image(struct image *img,
memcpy(img->line + applied_pos,
postimage->line,
postimage->nr * sizeof(*img->line));
- for (i = 0; i < postimage->nr; i++)
- img->line[applied_pos + i].flag |= LINE_PATCHED;
-
+ if (!allow_overlap)
+ for (i = 0; i < postimage->nr; i++)
+ img->line[applied_pos + i].flag |= LINE_PATCHED;
img->nr = nr;
}
@@ -3889,6 +3890,8 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
"don't expect at least one line of context"),
OPT_BOOLEAN(0, "reject", &apply_with_reject,
"leave the rejected hunks in corresponding *.rej files"),
+ OPT_BOOLEAN(0, "allow-overlap", &allow_overlap,
+ "allow overlapping hunks"),
OPT__VERBOSE(&apply_verbosely, "be verbose"),
OPT_BIT(0, "inaccurate-eof", &options,
"tolerate incorrectly detected missing new-line at the end of file",
diff --git a/builtin/blame.c b/builtin/blame.c
index f6b03f750..41525f1ea 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1377,7 +1377,7 @@ static void get_ac_line(const char *inbuf, const char *what,
timepos = tmp;
*tmp = 0;
- while (person < tmp && *tmp != ' ')
+ while (person < tmp && !(*tmp == ' ' && tmp[1] == '<'))
tmp--;
if (tmp <= person)
return;
diff --git a/builtin/clone.c b/builtin/clone.c
index 49c838fd3..f579794d9 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -81,7 +81,7 @@ static struct option builtin_clone_options[] = {
"path to git-upload-pack on the remote"),
OPT_STRING(0, "depth", &option_depth, "depth",
"create a shallow clone of that depth"),
- OPT_STRING('L', "separate-git-dir", &real_git_dir, "gitdir",
+ OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
"separate git dir from working tree"),
OPT_END()
diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c
index 0d2a3e9fa..be6417d16 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -163,6 +163,9 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
}
if (read_stdin) {
+ int saved_nrl = 0;
+ int saved_dcctc = 0;
+
if (opt->diffopt.detect_rename)
opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
DIFF_SETUP_USE_CACHE);
@@ -173,9 +176,16 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
fputs(line, stdout);
fflush(stdout);
}
- else
+ else {
diff_tree_stdin(line);
+ if (saved_nrl < opt->diffopt.needed_rename_limit)
+ saved_nrl = opt->diffopt.needed_rename_limit;
+ if (opt->diffopt.degraded_cc_to_c)
+ saved_dcctc = 1;
+ }
}
+ opt->diffopt.degraded_cc_to_c = saved_dcctc;
+ opt->diffopt.needed_rename_limit = saved_nrl;
}
return diff_result_code(&opt->diffopt, 0);
diff --git a/builtin/diff.c b/builtin/diff.c
index 717fa1a34..14bd14fce 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -202,7 +202,6 @@ static void refresh_index_quietly(void)
static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv)
{
- int result;
unsigned int options = 0;
while (1 < argc && argv[1][0] == '-') {
@@ -236,8 +235,7 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv
perror("read_cache_preload");
return -1;
}
- result = run_diff_files(revs, options);
- return diff_result_code(&revs->diffopt, result);
+ return run_diff_files(revs, options);
}
int cmd_diff(int argc, const char **argv, const char *prefix)
diff --git a/builtin/init-db.c b/builtin/init-db.c
index ba13a5479..025aa47c8 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -490,7 +490,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
"specify that the git repository is to be shared amongst several users",
PARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0},
OPT_BIT('q', "quiet", &flags, "be quiet", INIT_DB_QUIET),
- OPT_STRING('L', "separate-git-dir", &real_git_dir, "gitdir",
+ OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
"separate git dir from working tree"),
OPT_END()
};
diff --git a/builtin/log.c b/builtin/log.c
index 9db43edb0..55abe0761 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -49,13 +49,8 @@ static int parse_decoration_style(const char *var, const char *value)
return -1;
}
-static void cmd_log_init(int argc, const char **argv, const char *prefix,
- struct rev_info *rev, struct setup_revision_opt *opt)
+static void cmd_log_init_defaults(struct rev_info *rev)
{
- int i;
- int decoration_given = 0;
- struct userformat_want w;
-
rev->abbrev = DEFAULT_ABBREV;
rev->commit_format = CMIT_FMT_DEFAULT;
if (fmt_pretty)
@@ -68,7 +63,14 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
if (default_date_mode)
rev->date_mode = parse_date_format(default_date_mode);
+}
+static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
+ struct rev_info *rev, struct setup_revision_opt *opt)
+{
+ int i;
+ int decoration_given = 0;
+ struct userformat_want w;
/*
* Check for -h before setup_revisions(), or "git log -h" will
* fail when run without a git directory.
@@ -128,6 +130,13 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
setup_pager();
}
+static void cmd_log_init(int argc, const char **argv, const char *prefix,
+ struct rev_info *rev, struct setup_revision_opt *opt)
+{
+ cmd_log_init_defaults(rev);
+ cmd_log_init_finish(argc, argv, prefix, rev, opt);
+}
+
/*
* This gives a rough estimate for how many commits we
* will print out in the list.
@@ -247,6 +256,8 @@ static void finish_early_output(struct rev_info *rev)
static int cmd_log_walk(struct rev_info *rev)
{
struct commit *commit;
+ int saved_nrl = 0;
+ int saved_dcctc = 0;
if (rev->early_output)
setup_early_output(rev);
@@ -277,7 +288,14 @@ static int cmd_log_walk(struct rev_info *rev)
}
free_commit_list(commit->parents);
commit->parents = NULL;
+ if (saved_nrl < rev->diffopt.needed_rename_limit)
+ saved_nrl = rev->diffopt.needed_rename_limit;
+ if (rev->diffopt.degraded_cc_to_c)
+ saved_dcctc = 1;
}
+ rev->diffopt.degraded_cc_to_c = saved_dcctc;
+ rev->diffopt.needed_rename_limit = saved_nrl;
+
if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF &&
DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) {
return 02;
@@ -486,16 +504,11 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix)
rev.verbose_header = 1;
memset(&opt, 0, sizeof(opt));
opt.def = "HEAD";
- cmd_log_init(argc, argv, prefix, &rev, &opt);
-
- /*
- * This means that we override whatever commit format the user gave
- * on the cmd line. Sad, but cmd_log_init() currently doesn't
- * allow us to set a different default.
- */
+ cmd_log_init_defaults(&rev);
rev.commit_format = CMIT_FMT_ONELINE;
rev.use_terminator = 1;
rev.always_show_header = 1;
+ cmd_log_init_finish(argc, argv, prefix, &rev, &opt);
return cmd_log_walk(&rev);
}
@@ -623,7 +636,7 @@ static FILE *realstdout = NULL;
static const char *output_directory = NULL;
static int outdir_offset;
-static int reopen_stdout(struct commit *commit, struct rev_info *rev)
+static int reopen_stdout(struct commit *commit, struct rev_info *rev, int quiet)
{
struct strbuf filename = STRBUF_INIT;
int suffix_len = strlen(fmt_patch_suffix) + 1;
@@ -639,7 +652,7 @@ static int reopen_stdout(struct commit *commit, struct rev_info *rev)
get_patch_filename(commit, rev->nr, fmt_patch_suffix, &filename);
- if (!DIFF_OPT_TST(&rev->diffopt, QUICK))
+ if (!quiet)
fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
if (freopen(filename.buf, "w", stdout) == NULL)
@@ -718,7 +731,8 @@ static void print_signature(void)
static void make_cover_letter(struct rev_info *rev, int use_stdout,
int numbered, int numbered_files,
struct commit *origin,
- int nr, struct commit **list, struct commit *head)
+ int nr, struct commit **list, struct commit *head,
+ int quiet)
{
const char *committer;
const char *subject_start = NULL;
@@ -754,7 +768,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
sha1_to_hex(head->object.sha1), committer, committer);
}
- if (!use_stdout && reopen_stdout(commit, rev))
+ if (!use_stdout && reopen_stdout(commit, rev, quiet))
return;
if (commit) {
@@ -995,6 +1009,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
char *add_signoff = NULL;
struct strbuf buf = STRBUF_INIT;
int use_patch_format = 0;
+ int quiet = 0;
const struct option builtin_format_patch_options[] = {
{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
"use [PATCH n/m] even with a single patch",
@@ -1050,6 +1065,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
PARSE_OPT_OPTARG, thread_callback },
OPT_STRING(0, "signature", &signature, "signature",
"add a signature"),
+ OPT_BOOLEAN(0, "quiet", &quiet,
+ "don't print the patch filenames"),
OPT_END()
};
@@ -1259,7 +1276,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (thread)
gen_message_id(&rev, "cover");
make_cover_letter(&rev, use_stdout, numbered, numbered_files,
- origin, nr, list, head);
+ origin, nr, list, head, quiet);
total++;
start_number--;
}
@@ -1305,7 +1322,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
}
if (!use_stdout && reopen_stdout(numbered_files ? NULL : commit,
- &rev))
+ &rev, quiet))
die(_("Failed to create output files"));
shown = log_tree_commit(&rev, commit);
free(commit->buffer);
diff --git a/builtin/merge-base.c b/builtin/merge-base.c
index 96dd16073..4f30f1b0c 100644
--- a/builtin/merge-base.c
+++ b/builtin/merge-base.c
@@ -23,7 +23,8 @@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
}
static const char * const merge_base_usage[] = {
- "git merge-base [-a|--all] [--octopus] <commit> <commit>...",
+ "git merge-base [-a|--all] <commit> <commit>...",
+ "git merge-base [-a|--all] --octopus <commit>...",
"git merge-base --independent <commit>...",
NULL
};
diff --git a/builtin/merge.c b/builtin/merge.c
index 08245b6d6..24445f411 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -56,6 +56,7 @@ static size_t use_strategies_nr, use_strategies_alloc;
static const char **xopts;
static size_t xopts_nr, xopts_alloc;
static const char *branch;
+static char *branch_mergeoptions;
static int option_renormalize;
static int verbosity;
static int allow_rerere_auto;
@@ -503,26 +504,34 @@ cleanup:
strbuf_release(&bname);
}
+static void parse_branch_merge_options(char *bmo)
+{
+ const char **argv;
+ int argc;
+
+ if (!bmo)
+ return;
+ argc = split_cmdline(bmo, &argv);
+ if (argc < 0)
+ die(_("Bad branch.%s.mergeoptions string: %s"), branch,
+ split_cmdline_strerror(argc));
+ argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
+ memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
+ argc++;
+ argv[0] = "branch.*.mergeoptions";
+ parse_options(argc, argv, NULL, builtin_merge_options,
+ builtin_merge_usage, 0);
+ free(argv);
+}
+
static int git_merge_config(const char *k, const char *v, void *cb)
{
if (branch && !prefixcmp(k, "branch.") &&
!prefixcmp(k + 7, branch) &&
!strcmp(k + 7 + strlen(branch), ".mergeoptions")) {
- const char **argv;
- int argc;
- char *buf;
-
- buf = xstrdup(v);
- argc = split_cmdline(buf, &argv);
- if (argc < 0)
- die(_("Bad branch.%s.mergeoptions string: %s"), branch,
- split_cmdline_strerror(argc));
- argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
- memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
- argc++;
- parse_options(argc, argv, NULL, builtin_merge_options,
- builtin_merge_usage, 0);
- free(buf);
+ free(branch_mergeoptions);
+ branch_mergeoptions = xstrdup(v);
+ return 0;
}
if (!strcmp(k, "merge.diffstat") || !strcmp(k, "merge.stat"))
@@ -590,6 +599,14 @@ static void write_tree_trivial(unsigned char *sha1)
die(_("git write-tree failed to write a tree"));
}
+static const char *merge_argument(struct commit *commit)
+{
+ if (commit)
+ return sha1_to_hex(commit->object.sha1);
+ else
+ return EMPTY_TREE_SHA1_HEX;
+}
+
int try_merge_command(const char *strategy, size_t xopts_nr,
const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes)
@@ -610,11 +627,11 @@ int try_merge_command(const char *strategy, size_t xopts_nr,
args[i++] = s;
}
for (j = common; j; j = j->next)
- args[i++] = xstrdup(sha1_to_hex(j->item->object.sha1));
+ args[i++] = xstrdup(merge_argument(j->item));
args[i++] = "--";
args[i++] = head_arg;
for (j = remotes; j; j = j->next)
- args[i++] = xstrdup(sha1_to_hex(j->item->object.sha1));
+ args[i++] = xstrdup(merge_argument(j->item));
args[i] = NULL;
ret = run_command_v_opt(args, RUN_GIT_CMD);
strbuf_release(&buf);
@@ -1010,6 +1027,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
if (diff_use_color_default == -1)
diff_use_color_default = git_use_color_default;
+ if (branch_mergeoptions)
+ parse_branch_merge_options(branch_mergeoptions);
argc = parse_options(argc, argv, prefix, builtin_merge_options,
builtin_merge_usage, 0);
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index b0503b202..f402a843b 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1142,8 +1142,12 @@ static void get_object_details(void)
sorted_by_offset[i] = objects + i;
qsort(sorted_by_offset, nr_objects, sizeof(*sorted_by_offset), pack_offset_sort);
- for (i = 0; i < nr_objects; i++)
- check_object(sorted_by_offset[i]);
+ for (i = 0; i < nr_objects; i++) {
+ struct object_entry *entry = sorted_by_offset[i];
+ check_object(entry);
+ if (big_file_threshold <= entry->size)
+ entry->no_try_delta = 1;
+ }
free(sorted_by_offset);
}
diff --git a/builtin/revert.c b/builtin/revert.c
index 2bb13ebb1..1f27c6334 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -76,7 +76,8 @@ static void parse_args(int argc, const char **argv)
struct option options[] = {
OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"),
OPT_BOOLEAN('e', "edit", &edit, "edit the commit message"),
- OPT_BOOLEAN('r', NULL, &noop, "no-op (backward compatibility)"),
+ { OPTION_BOOLEAN, 'r', NULL, &noop, NULL, "no-op (backward compatibility)",
+ PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 0 },
OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
OPT_INTEGER('m', "mainline", &mainline, "parent number"),
OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
@@ -407,8 +408,6 @@ static int do_pick_commit(void)
discard_cache();
if (!commit->parents) {
- if (action == REVERT)
- die (_("Cannot revert a root commit"));
parent = NULL;
}
else if (commit->parents->next) {
@@ -466,7 +465,7 @@ static int do_pick_commit(void)
strbuf_addstr(&msgbuf, "\"\n\nThis reverts commit ");
strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1));
- if (commit->parents->next) {
+ if (commit->parents && commit->parents->next) {
strbuf_addstr(&msgbuf, ", reversing\nchanges made to ");
strbuf_addstr(&msgbuf, sha1_to_hex(parent->object.sha1));
}
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 8b0911c0d..c1f6ddd92 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -228,8 +228,11 @@ static void print_helper_status(struct ref *ref)
static int sideband_demux(int in, int out, void *data)
{
- int *fd = data;
- int ret = recv_sideband("send-pack", fd[0], out);
+ int *fd = data, ret;
+#ifdef NO_PTHREADS
+ close(fd[1]);
+#endif
+ ret = recv_sideband("send-pack", fd[0], out);
close(out);
return ret;
}
@@ -339,6 +342,10 @@ int send_pack(struct send_pack_args *args,
if (pack_objects(out, remote_refs, extra_have, args) < 0) {
for (ref = remote_refs; ref; ref = ref->next)
ref->status = REF_STATUS_NONE;
+ if (args->stateless_rpc)
+ close(out);
+ if (git_connection_is_socket(conn))
+ shutdown(fd[0], SHUT_WR);
if (use_sideband)
finish_async(&demux);
return -1;
diff --git a/cache.h b/cache.h
index 2674f4cf5..dd34fede9 100644
--- a/cache.h
+++ b/cache.h
@@ -573,6 +573,7 @@ extern int core_compression_seen;
extern size_t packed_git_window_size;
extern size_t packed_git_limit;
extern size_t delta_base_cache_limit;
+extern unsigned long big_file_threshold;
extern int read_replace_refs;
extern int fsync_object_files;
extern int core_preload_index;
@@ -964,6 +965,7 @@ extern struct ref *find_ref_by_name(const struct ref *list, const char *name);
extern char *git_getpass(const char *prompt);
extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
extern int finish_connect(struct child_process *conn);
+extern int git_connection_is_socket(struct child_process *conn);
extern int path_match(const char *path, int nr, char **match);
struct extra_have_objects {
int nr, alloc;
diff --git a/compat/mingw.c b/compat/mingw.c
index 878b1de97..442396176 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1130,7 +1130,7 @@ char **make_augmented_environ(const char *const *vars)
/*
* Note, this isn't a complete replacement for getaddrinfo. It assumes
- * that service contains a numerical port, or that it it is null. It
+ * that service contains a numerical port, or that it is null. It
* does a simple search using gethostbyname, and returns one IPv4 host
* if one was found.
*/
diff --git a/compat/nedmalloc/malloc.c.h b/compat/nedmalloc/malloc.c.h
index 87260d264..ff7c2c4fd 100644
--- a/compat/nedmalloc/malloc.c.h
+++ b/compat/nedmalloc/malloc.c.h
@@ -100,7 +100,7 @@
If you don't like either of these options, you can define
CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything
- else. And if if you are sure that your program using malloc has
+ else. And if you are sure that your program using malloc has
no errors or vulnerabilities, you can define INSECURE to 1,
which might (or might not) provide a small performance improvement.
@@ -2279,12 +2279,12 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
of the same size are arranged in a circularly-linked list, with only
the oldest chunk (the next to be used, in our FIFO ordering)
actually in the tree. (Tree members are distinguished by a non-null
- parent pointer.) If a chunk with the same size an an existing node
+ parent pointer.) If a chunk with the same size as an existing node
is inserted, it is linked off the existing node using pointers that
work in the same way as fd/bk pointers of small chunks.
Each tree contains a power of 2 sized range of chunk sizes (the
- smallest is 0x100 <= x < 0x180), which is is divided in half at each
+ smallest is 0x100 <= x < 0x180), which is divided in half at each
tree level, with the chunks in the smaller half of the range (0x100
<= x < 0x140 for the top nose) in the left subtree and the larger
half (0x140 <= x < 0x180) in the right subtree. This is, of course,
@@ -3943,7 +3943,7 @@ static void* sys_alloc(mstate m, size_t nb) {
least-preferred order):
1. A call to MORECORE that can normally contiguously extend memory.
(disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or
- or main space is mmapped or a previous contiguous call failed)
+ main space is mmapped or a previous contiguous call failed)
2. A call to MMAP new space (disabled if not HAVE_MMAP).
Note that under the default settings, if MORECORE is unable to
fulfill a request, and HAVE_MMAP is true, then mmap is
@@ -5748,5 +5748,3 @@ History:
structure of old version, but most details differ.)
*/
-
-
diff --git a/config.c b/config.c
index 0abcada93..d06fb19d5 100644
--- a/config.c
+++ b/config.c
@@ -567,6 +567,12 @@ static int git_default_core_config(const char *var, const char *value)
return 0;
}
+ if (!strcmp(var, "core.bigfilethreshold")) {
+ long n = git_config_int(var, value);
+ big_file_threshold = 0 < n ? n : 0;
+ return 0;
+ }
+
if (!strcmp(var, "core.packedgitlimit")) {
packed_git_limit = git_config_int(var, value);
return 0;
diff --git a/connect.c b/connect.c
index 57dc20c43..2119c3f74 100644
--- a/connect.c
+++ b/connect.c
@@ -395,26 +395,28 @@ static int git_use_proxy(const char *host)
return (git_proxy_command && *git_proxy_command);
}
-static void git_proxy_connect(int fd[2], char *host)
+static struct child_process *git_proxy_connect(int fd[2], char *host)
{
const char *port = STR(DEFAULT_GIT_PORT);
- const char *argv[4];
- struct child_process proxy;
+ const char **argv;
+ struct child_process *proxy;
get_host_and_port(&host, &port);
+ argv = xmalloc(sizeof(*argv) * 4);
argv[0] = git_proxy_command;
argv[1] = host;
argv[2] = port;
argv[3] = NULL;
- memset(&proxy, 0, sizeof(proxy));
- proxy.argv = argv;
- proxy.in = -1;
- proxy.out = -1;
- if (start_command(&proxy))
+ proxy = xcalloc(1, sizeof(*proxy));
+ proxy->argv = argv;
+ proxy->in = -1;
+ proxy->out = -1;
+ if (start_command(proxy))
die("cannot start proxy %s", argv[0]);
- fd[0] = proxy.out; /* read from proxy stdout */
- fd[1] = proxy.in; /* write to proxy stdin */
+ fd[0] = proxy->out; /* read from proxy stdout */
+ fd[1] = proxy->in; /* write to proxy stdin */
+ return proxy;
}
#define MAX_CMD_LEN 1024
@@ -455,7 +457,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
char *host, *path;
char *end;
int c;
- struct child_process *conn;
+ struct child_process *conn = &no_fork;
enum protocol protocol = PROTO_LOCAL;
int free_path = 0;
char *port = NULL;
@@ -540,7 +542,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
*/
char *target_host = xstrdup(host);
if (git_use_proxy(host))
- git_proxy_connect(fd, host);
+ conn = git_proxy_connect(fd, host);
else
git_tcp_connect(fd, host, flags);
/*
@@ -558,7 +560,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
free(url);
if (free_path)
free(path);
- return &no_fork;
+ return conn;
}
conn = xcalloc(1, sizeof(*conn));
@@ -607,10 +609,15 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
return conn;
}
+int git_connection_is_socket(struct child_process *conn)
+{
+ return conn == &no_fork;
+}
+
int finish_connect(struct child_process *conn)
{
int code;
- if (!conn || conn == &no_fork)
+ if (!conn || git_connection_is_socket(conn))
return 0;
code = finish_command(conn);
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 840ae3876..a7d20df23 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2710,6 +2710,10 @@ _git ()
if [[ -n ${ZSH_VERSION-} ]]; then
emulate -L bash
setopt KSH_TYPESET
+
+ # workaround zsh's bug that leaves 'words' as a special
+ # variable in versions < 4.3.12
+ typeset -h words
fi
local cur words cword
@@ -2761,6 +2765,10 @@ _gitk ()
if [[ -n ${ZSH_VERSION-} ]]; then
emulate -L bash
setopt KSH_TYPESET
+
+ # workaround zsh's bug that leaves 'words' as a special
+ # variable in versions < 4.3.12
+ typeset -h words
fi
__git_has_doubledash && return
diff --git a/date.c b/date.c
index 00f9eb5d0..896fbb480 100644
--- a/date.c
+++ b/date.c
@@ -129,8 +129,9 @@ const char *show_date_relative(unsigned long time, int tz,
}
/* Give years and months for 5 years or so */
if (diff < 1825) {
- unsigned long years = diff / 365;
- unsigned long months = (diff % 365 + 15) / 30;
+ unsigned long totalmonths = (diff * 12 * 2 + 365) / (365 * 2);
+ unsigned long years = totalmonths / 12;
+ unsigned long months = totalmonths % 12;
int n;
n = snprintf(timebuf, timebuf_size, "%lu year%s",
years, (years > 1 ? "s" : ""));
diff --git a/diff-lib.c b/diff-lib.c
index 2870de400..3b5f2242a 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -112,6 +112,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
if (ce_stage(ce)) {
struct combine_diff_path *dpath;
+ struct diff_filepair *pair;
+ unsigned int wt_mode = 0;
int num_compare_stages = 0;
size_t path_len;
@@ -130,7 +132,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
changed = check_removed(ce, &st);
if (!changed)
- dpath->mode = ce_mode_from_stat(ce, st.st_mode);
+ wt_mode = ce_mode_from_stat(ce, st.st_mode);
else {
if (changed < 0) {
perror(ce->name);
@@ -138,7 +140,9 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
}
if (silent_on_removed)
continue;
+ wt_mode = 0;
}
+ dpath->mode = wt_mode;
while (i < entries) {
struct cache_entry *nce = active_cache[i];
@@ -184,7 +188,9 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
* Show the diff for the 'ce' if we found the one
* from the desired stage.
*/
- diff_unmerge(&revs->diffopt, ce->name, 0, null_sha1);
+ pair = diff_unmerge(&revs->diffopt, ce->name);
+ if (wt_mode)
+ pair->two->mode = wt_mode;
if (ce_stage(ce) != diff_unmerged_stage)
continue;
}
@@ -373,8 +379,9 @@ static void do_oneway_diff(struct unpack_trees_options *o,
match_missing = !revs->ignore_merges;
if (cached && idx && ce_stage(idx)) {
- diff_unmerge(&revs->diffopt, idx->name, idx->ce_mode,
- idx->sha1);
+ struct diff_filepair *pair;
+ pair = diff_unmerge(&revs->diffopt, idx->name);
+ fill_filespec(pair->one, idx->sha1, idx->ce_mode);
return;
}
diff --git a/diff.c b/diff.c
index 9fa841010..559bf574a 100644
--- a/diff.c
+++ b/diff.c
@@ -1050,8 +1050,16 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
emit_line(ecbdata->opt, plain, reset, line, len);
fputs("~\n", ecbdata->opt->file);
} else {
- /* don't print the prefix character */
- emit_line(ecbdata->opt, plain, reset, line+1, len-1);
+ /*
+ * Skip the prefix character, if any. With
+ * diff_suppress_blank_empty, there may be
+ * none.
+ */
+ if (line[0] != '\n') {
+ line++;
+ len--;
+ }
+ emit_line(ecbdata->opt, plain, reset, line, len);
}
return;
}
@@ -1538,8 +1546,36 @@ static void show_dirstat(struct diff_options *options)
struct diff_filepair *p = q->queue[i];
const char *name;
unsigned long copied, added, damage;
+ int content_changed;
+
+ name = p->two->path ? p->two->path : p->one->path;
+
+ if (p->one->sha1_valid && p->two->sha1_valid)
+ content_changed = hashcmp(p->one->sha1, p->two->sha1);
+ else
+ content_changed = 1;
- name = p->one->path ? p->one->path : p->two->path;
+ if (!content_changed) {
+ /*
+ * The SHA1 has not changed, so pre-/post-content is
+ * identical. We can therefore skip looking at the
+ * file contents altogether.
+ */
+ damage = 0;
+ goto found_damage;
+ }
+
+ if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE)) {
+ /*
+ * In --dirstat-by-file mode, we don't really need to
+ * look at the actual file contents at all.
+ * The fact that the SHA1 changed is enough for us to
+ * add this file to the list of results
+ * (with each file contributing equal damage).
+ */
+ damage = 1;
+ goto found_damage;
+ }
if (DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
diff_populate_filespec(p->one, 0);
@@ -1563,14 +1599,18 @@ static void show_dirstat(struct diff_options *options)
/*
* Original minus copied is the removed material,
* added is the new material. They are both damages
- * made to the preimage. In --dirstat-by-file mode, count
- * damaged files, not damaged lines. This is done by
- * counting only a single damaged line per file.
+ * made to the preimage.
+ * If the resulting damage is zero, we know that
+ * diffcore_count_changes() considers the two entries to
+ * be identical, but since content_changed is true, we
+ * know that there must have been _some_ kind of change,
+ * so we force all entries to have damage > 0.
*/
damage = (p->one->size - copied) + added;
- if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE) && damage > 0)
+ if (!damage)
damage = 1;
+found_damage:
ALLOC_GROW(dir.files, dir.nr + 1, dir.alloc);
dir.files[dir.nr].name = name;
dir.files[dir.nr].changed = damage;
@@ -3955,6 +3995,28 @@ static int is_summary_empty(const struct diff_queue_struct *q)
return 1;
}
+static const char rename_limit_warning[] =
+"inexact rename detection was skipped due to too many files.";
+
+static const char degrade_cc_to_c_warning[] =
+"only found copies from modified paths due to too many files.";
+
+static const char rename_limit_advice[] =
+"you may want to set your %s variable to at least "
+"%d and retry the command.";
+
+void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc)
+{
+ if (degraded_cc)
+ warning(degrade_cc_to_c_warning);
+ else if (needed)
+ warning(rename_limit_warning);
+ else
+ return;
+ if (0 < needed && needed < 32767)
+ warning(rename_limit_advice, varname, needed);
+}
+
void diff_flush(struct diff_options *options)
{
struct diff_queue_struct *q = &diff_queued_diff;
@@ -4236,6 +4298,10 @@ void diffcore_std(struct diff_options *options)
int diff_result_code(struct diff_options *opt, int status)
{
int result = 0;
+
+ diff_warn_rename_limit("diff.renamelimit",
+ opt->needed_rename_limit,
+ opt->degraded_cc_to_c);
if (!DIFF_OPT_TST(opt, EXIT_WITH_STATUS) &&
!(opt->output_format & DIFF_FORMAT_CHECKDIFF))
return status;
@@ -4349,20 +4415,20 @@ void diff_change(struct diff_options *options,
DIFF_OPT_SET(options, HAS_CHANGES);
}
-void diff_unmerge(struct diff_options *options,
- const char *path,
- unsigned mode, const unsigned char *sha1)
+struct diff_filepair *diff_unmerge(struct diff_options *options, const char *path)
{
+ struct diff_filepair *pair;
struct diff_filespec *one, *two;
if (options->prefix &&
strncmp(path, options->prefix, options->prefix_length))
- return;
+ return NULL;
one = alloc_filespec(path);
two = alloc_filespec(path);
- fill_filespec(one, sha1, mode);
- diff_queue(&diff_queued_diff, one, two)->is_unmerged = 1;
+ pair = diff_queue(&diff_queued_diff, one, two);
+ pair->is_unmerged = 1;
+ return pair;
}
static char *run_textconv(const char *pgm, struct diff_filespec *spec,
diff --git a/diff.h b/diff.h
index 007a0554d..6e4d436e0 100644
--- a/diff.h
+++ b/diff.h
@@ -111,6 +111,7 @@ struct diff_options {
int rename_score;
int rename_limit;
int needed_rename_limit;
+ int degraded_cc_to_c;
int show_rename_progress;
int dirstat_percent;
int setup;
@@ -208,10 +209,7 @@ extern void diff_change(struct diff_options *,
const char *fullpath,
unsigned dirty_submodule1, unsigned dirty_submodule2);
-extern void diff_unmerge(struct diff_options *,
- const char *path,
- unsigned mode,
- const unsigned char *sha1);
+extern struct diff_filepair *diff_unmerge(struct diff_options *, const char *path);
#define DIFF_SETUP_REVERSE 1
#define DIFF_SETUP_USE_CACHE 2
@@ -273,6 +271,7 @@ extern void diffcore_fix_diff_index(struct diff_options *);
extern int diff_queue_is_empty(void);
extern void diff_flush(struct diff_options*);
+extern void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc);
/* diff-raw status letters */
#define DIFF_STATUS_ADDED 'A'
diff --git a/diffcore-rename.c b/diffcore-rename.c
index d40e40a3a..d0259be41 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -55,22 +55,23 @@ static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
/* Table of rename/copy src files */
static struct diff_rename_src {
- struct diff_filespec *one;
+ struct diff_filepair *p;
unsigned short score; /* to remember the break score */
} *rename_src;
static int rename_src_nr, rename_src_alloc;
-static struct diff_rename_src *register_rename_src(struct diff_filespec *one,
- unsigned short score)
+static struct diff_rename_src *register_rename_src(struct diff_filepair *p)
{
int first, last;
+ struct diff_filespec *one = p->one;
+ unsigned short score = p->score;
first = 0;
last = rename_src_nr;
while (last > first) {
int next = (last + first) >> 1;
struct diff_rename_src *src = &(rename_src[next]);
- int cmp = strcmp(one->path, src->one->path);
+ int cmp = strcmp(one->path, src->p->one->path);
if (!cmp)
return src;
if (cmp < 0) {
@@ -90,7 +91,7 @@ static struct diff_rename_src *register_rename_src(struct diff_filespec *one,
if (first < rename_src_nr)
memmove(rename_src + first + 1, rename_src + first,
(rename_src_nr - first - 1) * sizeof(*rename_src));
- rename_src[first].one = one;
+ rename_src[first].p = p;
rename_src[first].score = score;
return &(rename_src[first]);
}
@@ -205,7 +206,7 @@ static void record_rename_pair(int dst_index, int src_index, int score)
if (rename_dst[dst_index].pair)
die("internal error: dst already matched.");
- src = rename_src[src_index].one;
+ src = rename_src[src_index].p->one;
src->rename_used++;
src->count++;
@@ -389,7 +390,7 @@ static int find_exact_renames(struct diff_options *options)
init_hash(&file_table);
for (i = 0; i < rename_src_nr; i++)
- insert_file_table(&file_table, -1, i, rename_src[i].one);
+ insert_file_table(&file_table, -1, i, rename_src[i].p->one);
for (i = 0; i < rename_dst_nr; i++)
insert_file_table(&file_table, 1, i, rename_dst[i].two);
@@ -419,6 +420,55 @@ static void record_if_better(struct diff_score m[], struct diff_score *o)
m[worst] = *o;
}
+/*
+ * Returns:
+ * 0 if we are under the limit;
+ * 1 if we need to disable inexact rename detection;
+ * 2 if we would be under the limit if we were given -C instead of -C -C.
+ */
+static int too_many_rename_candidates(int num_create,
+ struct diff_options *options)
+{
+ int rename_limit = options->rename_limit;
+ int num_src = rename_src_nr;
+ int i;
+
+ options->needed_rename_limit = 0;
+
+ /*
+ * This basically does a test for the rename matrix not
+ * growing larger than a "rename_limit" square matrix, ie:
+ *
+ * num_create * num_src > rename_limit * rename_limit
+ *
+ * but handles the potential overflow case specially (and we
+ * assume at least 32-bit integers)
+ */
+ if (rename_limit <= 0 || rename_limit > 32767)
+ rename_limit = 32767;
+ if ((num_create <= rename_limit || num_src <= rename_limit) &&
+ (num_create * num_src <= rename_limit * rename_limit))
+ return 0;
+
+ options->needed_rename_limit =
+ num_src > num_create ? num_src : num_create;
+
+ /* Are we running under -C -C? */
+ if (!DIFF_OPT_TST(options, FIND_COPIES_HARDER))
+ return 1;
+
+ /* Would we bust the limit if we were running under -C? */
+ for (num_src = i = 0; i < rename_src_nr; i++) {
+ if (diff_unmodified_pair(rename_src[i].p))
+ continue;
+ num_src++;
+ }
+ if ((num_create <= rename_limit || num_src <= rename_limit) &&
+ (num_create * num_src <= rename_limit * rename_limit))
+ return 2;
+ return 1;
+}
+
static int find_renames(struct diff_score *mx, int dst_cnt, int minimum_score, int copies)
{
int count = 0, i;
@@ -432,7 +482,7 @@ static int find_renames(struct diff_score *mx, int dst_cnt, int minimum_score, i
dst = &rename_dst[mx[i].dst];
if (dst->pair)
continue; /* already done, either exact or fuzzy. */
- if (!copies && rename_src[mx[i].src].one->rename_used)
+ if (!copies && rename_src[mx[i].src].p->one->rename_used)
continue;
record_rename_pair(mx[i].dst, mx[i].src, mx[i].score);
count++;
@@ -444,11 +494,10 @@ void diffcore_rename(struct diff_options *options)
{
int detect_rename = options->detect_rename;
int minimum_score = options->rename_score;
- int rename_limit = options->rename_limit;
struct diff_queue_struct *q = &diff_queued_diff;
struct diff_queue_struct outq;
struct diff_score *mx;
- int i, j, rename_count;
+ int i, j, rename_count, skip_unmodified = 0;
int num_create, num_src, dst_cnt;
struct progress *progress = NULL;
@@ -466,7 +515,7 @@ void diffcore_rename(struct diff_options *options)
else
locate_rename_dst(p->two, 1);
}
- else if (!DIFF_FILE_VALID(p->two)) {
+ else if (!DIFF_PAIR_UNMERGED(p) && !DIFF_FILE_VALID(p->two)) {
/*
* If the source is a broken "delete", and
* they did not really want to get broken,
@@ -476,7 +525,7 @@ void diffcore_rename(struct diff_options *options)
*/
if (p->broken_pair && !p->score)
p->one->rename_used++;
- register_rename_src(p->one, p->score);
+ register_rename_src(p);
}
else if (detect_rename == DIFF_DETECT_COPY) {
/*
@@ -484,7 +533,7 @@ void diffcore_rename(struct diff_options *options)
* one, to indicate ourselves as a user.
*/
p->one->rename_used++;
- register_rename_src(p->one, p->score);
+ register_rename_src(p);
}
}
if (rename_dst_nr == 0 || rename_src_nr == 0)
@@ -511,23 +560,15 @@ void diffcore_rename(struct diff_options *options)
if (!num_create)
goto cleanup;
- /*
- * This basically does a test for the rename matrix not
- * growing larger than a "rename_limit" square matrix, ie:
- *
- * num_create * num_src > rename_limit * rename_limit
- *
- * but handles the potential overflow case specially (and we
- * assume at least 32-bit integers)
- */
- options->needed_rename_limit = 0;
- if (rename_limit <= 0 || rename_limit > 32767)
- rename_limit = 32767;
- if ((num_create > rename_limit && num_src > rename_limit) ||
- (num_create * num_src > rename_limit * rename_limit)) {
- options->needed_rename_limit =
- num_src > num_create ? num_src : num_create;
+ switch (too_many_rename_candidates(num_create, options)) {
+ case 1:
goto cleanup;
+ case 2:
+ options->degraded_cc_to_c = 1;
+ skip_unmodified = 1;
+ break;
+ default:
+ break;
}
if (options->show_rename_progress) {
@@ -549,8 +590,13 @@ void diffcore_rename(struct diff_options *options)
m[j].dst = -1;
for (j = 0; j < rename_src_nr; j++) {
- struct diff_filespec *one = rename_src[j].one;
+ struct diff_filespec *one = rename_src[j].p->one;
struct diff_score this_src;
+
+ if (skip_unmodified &&
+ diff_unmodified_pair(rename_src[j].p))
+ continue;
+
this_src.score = estimate_similarity(one, two,
minimum_score);
this_src.name_score = basename_same(one, two);
@@ -586,7 +632,10 @@ void diffcore_rename(struct diff_options *options)
struct diff_filepair *p = q->queue[i];
struct diff_filepair *pair_to_free = NULL;
- if (!DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
+ if (DIFF_PAIR_UNMERGED(p)) {
+ diff_q(&outq, p);
+ }
+ else if (!DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
/*
* Creation
*
diff --git a/dir.c b/dir.c
index 325fb56ad..532bcb65b 100644
--- a/dir.c
+++ b/dir.c
@@ -1192,7 +1192,7 @@ int remove_dir_recursively(struct strbuf *path, int flag)
dir = opendir(path->buf);
if (!dir)
- return -1;
+ return rmdir(path->buf);
if (path->buf[original_len - 1] != '/')
strbuf_addch(path, '/');
diff --git a/environment.c b/environment.c
index f4549d3f7..40185bc85 100644
--- a/environment.c
+++ b/environment.c
@@ -35,6 +35,7 @@ int fsync_object_files;
size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
size_t delta_base_cache_limit = 16 * 1024 * 1024;
+unsigned long big_file_threshold = 512 * 1024 * 1024;
const char *pager_program;
int pager_use_color = 1;
const char *editor_program;
diff --git a/fast-import.c b/fast-import.c
index 65d65bf8f..78d978684 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -274,7 +274,6 @@ struct recent_command {
/* Configured limits on output */
static unsigned long max_depth = 10;
static off_t max_packsize;
-static uintmax_t big_file_threshold = 512 * 1024 * 1024;
static int force_update;
static int pack_compression_level = Z_DEFAULT_COMPRESSION;
static int pack_compression_seen;
@@ -3136,11 +3135,11 @@ static int parse_one_feature(const char *feature, int from_stream)
option_export_marks(feature + 13);
} else if (!strcmp(feature, "cat-blob")) {
; /* Don't die - this feature is supported */
- } else if (!prefixcmp(feature, "relative-marks")) {
+ } else if (!strcmp(feature, "relative-marks")) {
relative_marks_paths = 1;
- } else if (!prefixcmp(feature, "no-relative-marks")) {
+ } else if (!strcmp(feature, "no-relative-marks")) {
relative_marks_paths = 0;
- } else if (!prefixcmp(feature, "force")) {
+ } else if (!strcmp(feature, "force")) {
force_update = 1;
} else if (!strcmp(feature, "notes") || !strcmp(feature, "ls")) {
; /* do nothing; we have the feature */
@@ -3206,10 +3205,6 @@ static int git_pack_config(const char *k, const char *v, void *cb)
max_packsize = git_config_ulong(k, v);
return 0;
}
- if (!strcmp(k, "core.bigfilethreshold")) {
- long n = git_config_int(k, v);
- big_file_threshold = 0 < n ? n : 0;
- }
return git_default_config(k, v, cb);
}
diff --git a/fsck.c b/fsck.c
index 6f266c1ea..60bd4bbf6 100644
--- a/fsck.c
+++ b/fsck.c
@@ -349,7 +349,7 @@ int fsck_error_function(struct object *obj, int type, const char *fmt, ...)
va_list ap;
struct strbuf sb = STRBUF_INIT;
- strbuf_addf(&sb, "object %s:", obj->sha1?sha1_to_hex(obj->sha1):"(null)");
+ strbuf_addf(&sb, "object %s:", sha1_to_hex(obj->sha1));
va_start(ap, fmt);
strbuf_vaddf(&sb, fmt, ap);
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index a329c5a1f..4f08fe704 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -705,7 +705,7 @@ sub add_untracked_cmd {
sub run_git_apply {
my $cmd = shift;
my $fh;
- open $fh, '| git ' . $cmd;
+ open $fh, '| git ' . $cmd . " --recount --allow-overlap";
print $fh @_;
return close $fh;
}
@@ -1050,7 +1050,7 @@ EOF
sub diff_applies {
my $fh;
- return run_git_apply($patch_mode_flavour{APPLY_CHECK} . ' --recount --check',
+ return run_git_apply($patch_mode_flavour{APPLY_CHECK} . ' --check',
map { @{$_->{TEXT}} } @_);
}
@@ -1139,7 +1139,7 @@ EOF
sub apply_patch {
my $cmd = shift;
- my $ret = run_git_apply $cmd . ' --recount', @_;
+ my $ret = run_git_apply $cmd, @_;
if (!$ret) {
print STDERR @_;
}
@@ -1148,17 +1148,17 @@ sub apply_patch {
sub apply_patch_for_checkout_commit {
my $reverse = shift;
- my $applies_index = run_git_apply 'apply '.$reverse.' --cached --recount --check', @_;
- my $applies_worktree = run_git_apply 'apply '.$reverse.' --recount --check', @_;
+ my $applies_index = run_git_apply 'apply '.$reverse.' --cached --check', @_;
+ my $applies_worktree = run_git_apply 'apply '.$reverse.' --check', @_;
if ($applies_worktree && $applies_index) {
- run_git_apply 'apply '.$reverse.' --cached --recount', @_;
- run_git_apply 'apply '.$reverse.' --recount', @_;
+ run_git_apply 'apply '.$reverse.' --cached', @_;
+ run_git_apply 'apply '.$reverse, @_;
return 1;
} elsif (!$applies_index) {
print colored $error_color, "The selected hunks do not apply to the index!\n";
if (prompt_yesno "Apply them to the worktree anyway? ") {
- return run_git_apply 'apply '.$reverse.' --recount', @_;
+ return run_git_apply 'apply '.$reverse, @_;
} else {
print colored $error_color, "Nothing was applied.\n";
return 0;
@@ -1366,14 +1366,13 @@ sub patch_update_file {
next;
}
elsif ($line =~ /^q/i) {
- while ($ix < $num) {
- if (!defined $hunk[$ix]{USE}) {
- $hunk[$ix]{USE} = 0;
+ for ($i = 0; $i < $num; $i++) {
+ if (!defined $hunk[$i]{USE}) {
+ $hunk[$i]{USE} = 0;
}
- $ix++;
}
$quit = 1;
- next;
+ last;
}
elsif ($line =~ m|^/(.*)|) {
my $regex = $1;
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index bbf327f3e..8d41610bc 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -227,6 +227,31 @@ sub new {
return $self;
}
+sub find_password_entry {
+ my ($cvspass, @cvsroot) = @_;
+ my ($file, $delim) = @$cvspass;
+ my $pass;
+ local ($_);
+
+ if (open(my $fh, $file)) {
+ # :pserver:cvs@mea.tmt.tele.fi:/cvsroot/zmailer Ah<Z
+ CVSPASSFILE:
+ while (<$fh>) {
+ chomp;
+ s/^\/\d+\s+//;
+ my ($w, $p) = split($delim,$_,2);
+ for my $cvsroot (@cvsroot) {
+ if ($w eq $cvsroot) {
+ $pass = $p;
+ last CVSPASSFILE;
+ }
+ }
+ }
+ close($fh);
+ }
+ return $pass;
+}
+
sub conn {
my $self = shift;
my $repo = $self->{'fullrep'};
@@ -259,19 +284,23 @@ sub conn {
if ($pass) {
$pass = $self->_scramble($pass);
} else {
- open(H,$ENV{'HOME'}."/.cvspass") and do {
- # :pserver:cvs@mea.tmt.tele.fi:/cvsroot/zmailer Ah<Z
- while (<H>) {
- chomp;
- s/^\/\d+\s+//;
- my ($w,$p) = split(/\s/,$_,2);
- if ($w eq $rr or $w eq $rr2) {
- $pass = $p;
- last;
- }
+ my @cvspass = ([$ENV{'HOME'}."/.cvspass", qr/\s/],
+ [$ENV{'HOME'}."/.cvs/cvspass", qr/=/]);
+ my @loc = ();
+ foreach my $cvspass (@cvspass) {
+ my $p = find_password_entry($cvspass, $rr, $rr2);
+ if ($p) {
+ push @loc, $cvspass->[0];
+ $pass = $p;
}
- };
- $pass = "A" unless $pass;
+ }
+
+ if (1 < @loc) {
+ die("Multiple cvs password files have ".
+ "entries for CVSROOT $opt_d: @loc");
+ } elsif (!$pass) {
+ $pass = "A";
+ }
}
my ($s, $rep);
diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh
index b86402afa..7aeb96952 100755
--- a/git-merge-one-file.sh
+++ b/git-merge-one-file.sh
@@ -22,6 +22,11 @@ LONG_USAGE="Usage: git merge-one-file $USAGE
Blob ids and modes should be empty for missing files."
+SUBDIRECTORY_OK=Yes
+. git-sh-setup
+cd_to_toplevel
+require_work_tree
+
if ! test "$#" -eq 7
then
echo "$LONG_USAGE"
@@ -132,7 +137,7 @@ case "${1:-.}${2:-.}${3:-.}" in
# Create the working tree file, using "our tree" version from the
# index, and then store the result of the merge.
- git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4"
+ git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4" || exit 1
rm -f -- "$orig" "$src1" "$src2"
if [ "$6" != "$7" ]; then
diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh
index fb3f52ba2..4db921233 100644
--- a/git-mergetool--lib.sh
+++ b/git-mergetool--lib.sh
@@ -258,12 +258,9 @@ run_merge_tool () {
;;
p4merge)
if merge_mode; then
- touch "$BACKUP"
- if $base_present; then
- "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
- else
- "$merge_tool_path" "$LOCAL" "$LOCAL" "$REMOTE" "$MERGED"
- fi
+ touch "$BACKUP"
+ $base_present || >"$BASE"
+ "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
check_unchanged
else
"$merge_tool_path" "$LOCAL" "$REMOTE"
diff --git a/git-mergetool.sh b/git-mergetool.sh
index bacbda2bb..3aab5aae8 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -21,6 +21,10 @@ is_symlink () {
test "$1" = 120000
}
+is_submodule () {
+ test "$1" = 160000
+}
+
local_present () {
test -n "$local_mode"
}
@@ -35,7 +39,8 @@ base_present () {
cleanup_temp_files () {
if test "$1" = --save-backup ; then
- mv -- "$BACKUP" "$MERGED.orig"
+ rm -rf -- "$MERGED.orig"
+ test -e "$BACKUP" && mv -- "$BACKUP" "$MERGED.orig"
rm -f -- "$LOCAL" "$REMOTE" "$BASE"
else
rm -f -- "$LOCAL" "$REMOTE" "$BASE" "$BACKUP"
@@ -52,11 +57,13 @@ describe_file () {
echo "deleted"
elif is_symlink "$mode" ; then
echo "a symbolic link -> '$(cat "$file")'"
+ elif is_submodule "$mode" ; then
+ echo "submodule commit $file"
else
if base_present; then
- echo "modified"
+ echo "modified file"
else
- echo "created"
+ echo "created file"
fi
fi
}
@@ -112,6 +119,67 @@ resolve_deleted_merge () {
done
}
+resolve_submodule_merge () {
+ while true; do
+ printf "Use (l)ocal or (r)emote, or (a)bort? "
+ read ans
+ case "$ans" in
+ [lL]*)
+ if ! local_present; then
+ if test -n "$(git ls-tree HEAD -- "$MERGED")"; then
+ # Local isn't present, but it's a subdirectory
+ git ls-tree --full-name -r HEAD -- "$MERGED" | git update-index --index-info || exit $?
+ else
+ test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
+ git update-index --force-remove "$MERGED"
+ cleanup_temp_files --save-backup
+ fi
+ elif is_submodule "$local_mode"; then
+ stage_submodule "$MERGED" "$local_sha1"
+ else
+ git checkout-index -f --stage=2 -- "$MERGED"
+ git add -- "$MERGED"
+ fi
+ return 0
+ ;;
+ [rR]*)
+ if ! remote_present; then
+ if test -n "$(git ls-tree MERGE_HEAD -- "$MERGED")"; then
+ # Remote isn't present, but it's a subdirectory
+ git ls-tree --full-name -r MERGE_HEAD -- "$MERGED" | git update-index --index-info || exit $?
+ else
+ test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
+ git update-index --force-remove "$MERGED"
+ fi
+ elif is_submodule "$remote_mode"; then
+ ! is_submodule "$local_mode" && test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
+ stage_submodule "$MERGED" "$remote_sha1"
+ else
+ test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
+ git checkout-index -f --stage=3 -- "$MERGED"
+ git add -- "$MERGED"
+ fi
+ cleanup_temp_files --save-backup
+ return 0
+ ;;
+ [aA]*)
+ return 1
+ ;;
+ esac
+ done
+}
+
+stage_submodule () {
+ path="$1"
+ submodule_sha1="$2"
+ mkdir -p "$path" || die "fatal: unable to create directory for module at $path"
+ # Find $path relative to work tree
+ work_tree_root=$(cd_to_toplevel && pwd)
+ work_rel_path=$(cd "$path" && GIT_WORK_TREE="${work_tree_root}" git rev-parse --show-prefix)
+ test -n "$work_rel_path" || die "fatal: unable to get path of module $path relative to work tree"
+ git update-index --add --replace --cacheinfo 160000 "$submodule_sha1" "${work_rel_path%/}" || die
+}
+
checkout_staged_file () {
tmpfile=$(expr "$(git checkout-index --temp --stage="$1" "$2")" : '\([^ ]*\) ')
@@ -139,13 +207,23 @@ merge_file () {
REMOTE="./$MERGED.REMOTE.$ext"
BASE="./$MERGED.BASE.$ext"
- mv -- "$MERGED" "$BACKUP"
- cp -- "$BACKUP" "$MERGED"
-
base_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}')
local_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}')
remote_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}')
+ if is_submodule "$local_mode" || is_submodule "$remote_mode"; then
+ echo "Submodule merge conflict for '$MERGED':"
+ local_sha1=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $2;}')
+ remote_sha1=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $2;}')
+ describe_file "$local_mode" "local" "$local_sha1"
+ describe_file "$remote_mode" "remote" "$remote_sha1"
+ resolve_submodule_merge
+ return
+ fi
+
+ mv -- "$MERGED" "$BACKUP"
+ cp -- "$BACKUP" "$MERGED"
+
base_present && checkout_staged_file 1 "$MERGED" "$BASE"
local_present && checkout_staged_file 2 "$MERGED" "$LOCAL"
remote_present && checkout_staged_file 3 "$MERGED" "$REMOTE"
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 5873ba4bc..c308529a9 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -339,7 +339,7 @@ pick_one_preserving_merges () {
# No point in merging the first parent, that's HEAD
new_parents=${new_parents# $first_parent}
if ! do_with_author output \
- git merge $STRATEGY -m "$msg" $new_parents
+ git merge --no-ff $STRATEGY -m "$msg" $new_parents
then
printf "%s\n" "$msg" > "$GIT_DIR"/MERGE_MSG
die_with_patch $sha1 "Error redoing merge $sha1"
diff --git a/git-send-email.perl b/git-send-email.perl
index 76565de2e..98ab33aae 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -1091,7 +1091,7 @@ X-Mailer: git-send-email $gitversion
"VALUES: server=$smtp_server ",
"encryption=$smtp_encryption ",
"hello=$smtp_domain",
- defined $smtp_server_port ? "port=$smtp_server_port" : "";
+ defined $smtp_server_port ? " port=$smtp_server_port" : "";
}
if (defined $smtp_authuser) {
diff --git a/git-stash.sh b/git-stash.sh
index a305fb19f..0a9403653 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -136,11 +136,12 @@ save_stash () {
keep_index=t
;;
--no-keep-index)
- keep_index=
+ keep_index=n
;;
-p|--patch)
patch_mode=t
- keep_index=t
+ # only default to keep if we don't already have an override
+ test -z "$keep_index" && keep_index=t
;;
-q|--quiet)
GIT_QUIET=t
@@ -185,7 +186,7 @@ save_stash () {
then
git reset --hard ${GIT_QUIET:+-q}
- if test -n "$keep_index" && test -n $i_tree
+ if test "$keep_index" = "t" && test -n $i_tree
then
git read-tree --reset -u $i_tree
fi
@@ -193,7 +194,7 @@ save_stash () {
git apply -R < "$TMP-patch" ||
die "Cannot remove worktree changes"
- if test -z "$keep_index"
+ if test "$keep_index" != "t"
then
git reset
fi
@@ -264,7 +265,7 @@ parse_flags_and_rev()
b_tree=
i_tree=
- REV=$(git rev-parse --no-flags --symbolic "$@" 2>/dev/null)
+ REV=$(git rev-parse --no-flags --symbolic "$@") || exit 1
FLAGS=
for opt
@@ -310,16 +311,6 @@ parse_flags_and_rev()
IS_STASH_LIKE=t &&
test "$ref_stash" = "$(git rev-parse --symbolic-full-name "${REV%@*}")" &&
IS_STASH_REF=t
-
- if test "${REV}" != "${REV%{*\}}"
- then
- # maintainers: it would be better if git rev-parse indicated
- # this condition with a non-zero status code but as of 1.7.2.1 it
- # it did not. So, we use non-empty stderr output as a proxy for the
- # condition of interest.
- test -z "$(git rev-parse "$REV" 2>&1 >/dev/null)" || die "$REV does not exist in the stash log"
- fi
-
}
is_stash_like()
@@ -344,9 +335,7 @@ apply_stash () {
assert_stash_like "$@"
- git update-index -q --refresh &&
- git diff-files --quiet --ignore-submodules ||
- die 'Cannot apply to a dirty working tree, please stage your changes'
+ git update-index -q --refresh || die 'unable to refresh index'
# current index state
c_tree=$(git write-tree) ||
diff --git a/git-submodule.sh b/git-submodule.sh
index b010a6730..4361ae418 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -491,7 +491,7 @@ cmd_update()
# Run fetch only if $sha1 isn't present or it
# is not reachable from a ref.
(clear_local_git_env; cd "$path" &&
- ((rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
+ ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
test -z "$rev") || git-fetch)) ||
die "Unable to fetch in submodule path '$path'"
fi
diff --git a/git-svn.perl b/git-svn.perl
index bf0451b46..da3fea8bd 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -5752,7 +5752,7 @@ sub cmd_show_log {
my (@k, $c, $d, $stat);
my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
while (<$log>) {
- if (/^${esc_color}commit (- )?($::sha1_short)/o) {
+ if (/^${esc_color}commit (?:- )?($::sha1_short)/o) {
my $cmt = $1;
if ($c && cmt_showable($c) && $c->{r} != $r_last) {
$r_last = $c->{r};
diff --git a/gitweb/README b/gitweb/README
index 4a673933a..a92bde7f1 100644
--- a/gitweb/README
+++ b/gitweb/README
@@ -29,7 +29,7 @@ You can specify the following configuration variables when building GIT:
The filesystem traversing limit for getting the project list; the number
is taken as depth relative to the projectroot. It is used when
GITWEB_LIST is a directory (or is not set; then project root is used).
- Is is meant to speed up project listing on large work trees by limiting
+ This is meant to speed up project listing on large work trees by limiting
search depth. [Default: 2007]
* GITWEB_LIST
Points to a directory to scan for projects (defaults to project root
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index ee69ea683..f8db40a1c 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -186,7 +186,7 @@ our %known_snapshot_formats = (
'type' => 'application/x-gzip',
'suffix' => '.tar.gz',
'format' => 'tar',
- 'compressor' => ['gzip']},
+ 'compressor' => ['gzip', '-n']},
'tbz2' => {
'display' => 'tar.bz2',
diff --git a/http.c b/http.c
index 9e767723e..b27bb57d6 100644
--- a/http.c
+++ b/http.c
@@ -536,6 +536,7 @@ struct active_request_slot *get_active_slot(void)
curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, NULL);
curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, NULL);
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, NULL);
+ curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, NULL);
curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0);
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
diff --git a/ident.c b/ident.c
index 1c4adb0a9..8e56b5e94 100644
--- a/ident.c
+++ b/ident.c
@@ -34,6 +34,7 @@ static void copy_gecos(const struct passwd *w, char *name, size_t sz)
*dst++ = toupper(*w->pw_name);
memcpy(dst, w->pw_name + 1, nlen - 1);
dst += nlen - 1;
+ len += nlen;
}
}
if (len < sz)
diff --git a/merge-recursive.c b/merge-recursive.c
index af131508e..ae6ade4ec 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -22,11 +22,6 @@
#include "dir.h"
#include "submodule.h"
-static const char rename_limit_advice[] =
-"inexact rename detection was skipped because there were too many\n"
-" files. You may want to set your merge.renamelimit variable to at least\n"
-" %d and retry this merge.";
-
static struct tree *shift_tree_object(struct tree *one, struct tree *two,
const char *subtree_shift)
{
@@ -1652,8 +1647,9 @@ int merge_recursive(struct merge_options *o,
commit_list_insert(h2, &(*result)->parents->next);
}
flush_output(o);
- if (o->needed_rename_limit)
- warning(rename_limit_advice, o->needed_rename_limit);
+ if (show(o, 2))
+ diff_warn_rename_limit("merge.renamelimit",
+ o->needed_rename_limit, 0);
return clean;
}
@@ -1711,15 +1707,15 @@ int merge_recursive_generic(struct merge_options *o,
static int merge_recursive_config(const char *var, const char *value, void *cb)
{
struct merge_options *o = cb;
- if (!strcasecmp(var, "merge.verbosity")) {
+ if (!strcmp(var, "merge.verbosity")) {
o->verbosity = git_config_int(var, value);
return 0;
}
- if (!strcasecmp(var, "diff.renamelimit")) {
+ if (!strcmp(var, "diff.renamelimit")) {
o->diff_rename_limit = git_config_int(var, value);
return 0;
}
- if (!strcasecmp(var, "merge.renamelimit")) {
+ if (!strcmp(var, "merge.renamelimit")) {
o->merge_rename_limit = git_config_int(var, value);
return 0;
}
diff --git a/pretty.c b/pretty.c
index e1d8a8f41..13618d826 100644
--- a/pretty.c
+++ b/pretty.c
@@ -208,6 +208,58 @@ int has_non_ascii(const char *s)
return 0;
}
+static int is_rfc822_special(char ch)
+{
+ switch (ch) {
+ case '(':
+ case ')':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case ':':
+ case ';':
+ case '@':
+ case ',':
+ case '.':
+ case '"':
+ case '\\':
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int has_rfc822_specials(const char *s, int len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ if (is_rfc822_special(s[i]))
+ return 1;
+ return 0;
+}
+
+static void add_rfc822_quoted(struct strbuf *out, const char *s, int len)
+{
+ int i;
+
+ /* just a guess, we may have to also backslash-quote */
+ strbuf_grow(out, len + 2);
+
+ strbuf_addch(out, '"');
+ for (i = 0; i < len; i++) {
+ switch (s[i]) {
+ case '"':
+ case '\\':
+ strbuf_addch(out, '\\');
+ /* fall through */
+ default:
+ strbuf_addch(out, s[i]);
+ }
+ }
+ strbuf_addch(out, '"');
+}
+
static int is_rfc2047_special(char ch)
{
return (non_ascii(ch) || (ch == '=') || (ch == '?') || (ch == '_'));
@@ -293,7 +345,14 @@ void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
name_tail--;
display_name_length = name_tail - line;
strbuf_addstr(sb, "From: ");
- add_rfc2047(sb, line, display_name_length, encoding);
+ if (!has_rfc822_specials(line, display_name_length)) {
+ add_rfc2047(sb, line, display_name_length, encoding);
+ } else {
+ struct strbuf quoted = STRBUF_INIT;
+ add_rfc822_quoted(&quoted, line, display_name_length);
+ add_rfc2047(sb, quoted.buf, quoted.len, encoding);
+ strbuf_release(&quoted);
+ }
strbuf_add(sb, name_tail, namelen - display_name_length);
strbuf_addch(sb, '\n');
} else {
diff --git a/rerere.c b/rerere.c
index 22dfc843d..6ec452f7b 100644
--- a/rerere.c
+++ b/rerere.c
@@ -47,8 +47,14 @@ static void read_rr(struct string_list *rr)
name = xstrdup(buf);
if (fgetc(in) != '\t')
die("corrupt MERGE_RR");
- for (i = 0; i < sizeof(buf) && (buf[i] = fgetc(in)); i++)
- ; /* do nothing */
+ for (i = 0; i < sizeof(buf); i++) {
+ int c = fgetc(in);
+ if (c < 0)
+ die("corrupt MERGE_RR");
+ buf[i] = c;
+ if (c == 0)
+ break;
+ }
if (i == sizeof(buf))
die("filename too long");
string_list_insert(rr, buf)->util = name;
diff --git a/revision.c b/revision.c
index 0f38364cf..707a703a0 100644
--- a/revision.c
+++ b/revision.c
@@ -1096,35 +1096,34 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
return 0;
}
-static void read_pathspec_from_stdin(struct rev_info *revs, struct strbuf *sb, const char ***prune_data)
-{
- const char **prune = *prune_data;
- int prune_nr;
- int prune_alloc;
+struct cmdline_pathspec {
+ int alloc;
+ int nr;
+ const char **path;
+};
- /* count existing ones */
- if (!prune)
- prune_nr = 0;
- else
- for (prune_nr = 0; prune[prune_nr]; prune_nr++)
- ;
- prune_alloc = prune_nr; /* not really, but we do not know */
+static void append_prune_data(struct cmdline_pathspec *prune, const char **av)
+{
+ while (*av) {
+ ALLOC_GROW(prune->path, prune->nr+1, prune->alloc);
+ prune->path[prune->nr++] = *(av++);
+ }
+}
+static void read_pathspec_from_stdin(struct rev_info *revs, struct strbuf *sb,
+ struct cmdline_pathspec *prune)
+{
while (strbuf_getwholeline(sb, stdin, '\n') != EOF) {
int len = sb->len;
if (len && sb->buf[len - 1] == '\n')
sb->buf[--len] = '\0';
- ALLOC_GROW(prune, prune_nr+1, prune_alloc);
- prune[prune_nr++] = xstrdup(sb->buf);
+ ALLOC_GROW(prune->path, prune->nr+1, prune->alloc);
+ prune->path[prune->nr++] = xstrdup(sb->buf);
}
- if (prune) {
- ALLOC_GROW(prune, prune_nr+1, prune_alloc);
- prune[prune_nr] = NULL;
- }
- *prune_data = prune;
}
-static void read_revisions_from_stdin(struct rev_info *revs, const char ***prune)
+static void read_revisions_from_stdin(struct rev_info *revs,
+ struct cmdline_pathspec *prune)
{
struct strbuf sb;
int seen_dashdash = 0;
@@ -1498,34 +1497,6 @@ static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void
return for_each_ref_in_submodule(submodule, "refs/bisect/good", fn, cb_data);
}
-static void append_prune_data(const char ***prune_data, const char **av)
-{
- const char **prune = *prune_data;
- int prune_nr;
- int prune_alloc;
-
- if (!prune) {
- *prune_data = av;
- return;
- }
-
- /* count existing ones */
- for (prune_nr = 0; prune[prune_nr]; prune_nr++)
- ;
- prune_alloc = prune_nr; /* not really, but we do not know */
-
- while (*av) {
- ALLOC_GROW(prune, prune_nr+1, prune_alloc);
- prune[prune_nr++] = *av;
- av++;
- }
- if (prune) {
- ALLOC_GROW(prune, prune_nr+1, prune_alloc);
- prune[prune_nr] = NULL;
- }
- *prune_data = prune;
-}
-
/*
* Parse revision information, filling in the "rev_info" structure,
* and removing the used arguments from the argument list.
@@ -1536,11 +1507,12 @@ static void append_prune_data(const char ***prune_data, const char **av)
int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *opt)
{
int i, flags, left, seen_dashdash, read_from_stdin, got_rev_arg = 0;
- const char **prune_data = NULL;
+ struct cmdline_pathspec prune_data;
const char *submodule = NULL;
const char *optarg;
int argcount;
+ memset(&prune_data, 0, sizeof(prune_data));
if (opt)
submodule = opt->submodule;
@@ -1553,7 +1525,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
argv[i] = NULL;
argc = i;
if (argv[i + 1])
- prune_data = argv + i + 1;
+ append_prune_data(&prune_data, argv + i + 1);
seen_dashdash = 1;
break;
}
@@ -1672,8 +1644,12 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
got_rev_arg = 1;
}
- if (prune_data)
- init_pathspec(&revs->prune_data, get_pathspec(revs->prefix, prune_data));
+ if (prune_data.nr) {
+ ALLOC_GROW(prune_data.path, prune_data.nr+1, prune_data.alloc);
+ prune_data.path[prune_data.nr++] = NULL;
+ init_pathspec(&revs->prune_data,
+ get_pathspec(revs->prefix, prune_data.path));
+ }
if (revs->def == NULL)
revs->def = opt ? opt->def : NULL;
diff --git a/run-command.c b/run-command.c
index 8619c769a..70e8a249d 100644
--- a/run-command.c
+++ b/run-command.c
@@ -72,8 +72,7 @@ static void notify_parent(void)
* know, so failures like ENOENT can be handled right away; but
* otherwise, finish_command will still report the error.
*/
- if (write(child_notifier, "", 1))
- ; /* yes, dear gcc -D_FORTIFY_SOURCE, there was an error. */
+ xwrite(child_notifier, "", 1);
}
static NORETURN void die_child(const char *err, va_list params)
@@ -83,10 +82,9 @@ static NORETURN void die_child(const char *err, va_list params)
if (len > sizeof(msg))
len = sizeof(msg);
- if (write(child_err, "fatal: ", 7) ||
- write(child_err, msg, len) ||
- write(child_err, "\n", 1))
- ; /* yes, gcc -D_FORTIFY_SOURCE, we know there was an error. */
+ write_in_full(child_err, "fatal: ", 7);
+ write_in_full(child_err, msg, len);
+ write_in_full(child_err, "\n", 1);
exit(128);
}
#endif
diff --git a/setup.c b/setup.c
index 03cd84f2f..e7a37863c 100644
--- a/setup.c
+++ b/setup.c
@@ -275,7 +275,7 @@ const char *read_gitfile_gently(const char *path)
const char *slash;
struct stat st;
int fd;
- size_t len;
+ ssize_t len;
if (stat(path, &st))
return NULL;
diff --git a/sha1_file.c b/sha1_file.c
index df0edbad1..1a7e41070 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -31,8 +31,6 @@ static inline uintmax_t sz_fmt(size_t s) { return s; }
const unsigned char null_sha1[20];
-static int git_open_noatime(const char *name, struct packed_git *p);
-
/*
* This is meant to hold a *small* number of objects that you would
* want read_sha1_file() to be able to return, but yet you do not want
@@ -227,6 +225,7 @@ struct alternate_object_database *alt_odb_list;
static struct alternate_object_database **alt_odb_tail;
static void read_info_alternates(const char * alternates, int depth);
+static int git_open_noatime(const char *name);
/*
* Prepare alternate object database registry.
@@ -360,7 +359,7 @@ static void read_info_alternates(const char * relative_base, int depth)
int fd;
sprintf(path, "%s/%s", relative_base, alt_file_name);
- fd = git_open_noatime(path, NULL);
+ fd = git_open_noatime(path);
if (fd < 0)
return;
if (fstat(fd, &st) || (st.st_size == 0)) {
@@ -475,7 +474,7 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
struct pack_idx_header *hdr;
size_t idx_size;
uint32_t version, nr, i, *index;
- int fd = git_open_noatime(path, p);
+ int fd = git_open_noatime(path);
struct stat st;
if (fd < 0)
@@ -757,7 +756,7 @@ static int open_packed_git_1(struct packed_git *p)
while (pack_max_fds <= pack_open_fds && unuse_one_window(NULL, -1))
; /* nothing */
- p->pack_fd = git_open_noatime(p->pack_name, p);
+ p->pack_fd = git_open_noatime(p->pack_name);
if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
return -1;
pack_open_fds++;
@@ -1145,7 +1144,7 @@ int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long siz
return hashcmp(sha1, real_sha1) ? -1 : 0;
}
-static int git_open_noatime(const char *name, struct packed_git *p)
+static int git_open_noatime(const char *name)
{
static int sha1_file_open_flag = O_NOATIME;
@@ -1170,7 +1169,7 @@ static int open_sha1_file(const unsigned char *sha1)
char *name = sha1_file_name(sha1);
struct alternate_object_database *alt;
- fd = git_open_noatime(name, NULL);
+ fd = git_open_noatime(name);
if (fd >= 0)
return fd;
@@ -1179,7 +1178,7 @@ static int open_sha1_file(const unsigned char *sha1)
for (alt = alt_odb_list; alt; alt = alt->next) {
name = alt->name;
fill_sha1_path(name, sha1);
- fd = git_open_noatime(alt->base, NULL);
+ fd = git_open_noatime(alt->base);
if (fd >= 0)
return fd;
}
@@ -1308,7 +1307,7 @@ static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size
/*
* The above condition must be (bytes <= size), not
* (bytes < size). In other words, even though we
- * expect no more output and set avail_out to zer0,
+ * expect no more output and set avail_out to zero,
* the input zlib stream may have bytes that express
* "this concludes the stream", and we *do* want to
* eat that input.
@@ -1534,7 +1533,7 @@ static int unpack_object_header(struct packed_git *p,
enum object_type type;
/* use_pack() assures us we have [base, base + 20) available
- * as a range that we can look at at. (Its actually the hash
+ * as a range that we can look at. (Its actually the hash
* size that is assured.) With our object header encoding
* the maximum deflated object size is 2^137, which is just
* insane, so we know won't exceed what we have been given.
diff --git a/sha1_name.c b/sha1_name.c
index faea58dc8..69cd6c815 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -1012,11 +1012,13 @@ static void diagnose_invalid_sha1_path(const char *prefix,
if (!get_tree_entry(tree_sha1, fullname,
sha1, &mode)) {
die("Path '%s' exists, but not '%s'.\n"
- "Did you mean '%s:%s'?",
+ "Did you mean '%s:%s' aka '%s:./%s'?",
fullname,
filename,
object_name,
- fullname);
+ fullname,
+ object_name,
+ filename);
}
die("Path '%s' does not exist in '%s'",
filename, object_name);
@@ -1065,9 +1067,10 @@ static void diagnose_invalid_index_path(int stage,
if (ce_namelen(ce) == fullnamelen &&
!memcmp(ce->name, fullname, fullnamelen))
die("Path '%s' is in the index, but not '%s'.\n"
- "Did you mean ':%d:%s'?",
+ "Did you mean ':%d:%s' aka ':%d:./%s'?",
fullname, filename,
- ce_stage(ce), fullname);
+ ce_stage(ce), fullname,
+ ce_stage(ce), filename);
}
if (!lstat(filename, &st))
diff --git a/shell.c b/shell.c
index dea4cfdd2..abb862246 100644
--- a/shell.c
+++ b/shell.c
@@ -137,6 +137,8 @@ int main(int argc, char **argv)
int devnull_fd;
int count;
+ git_extract_argv0_path(argv[0]);
+
/*
* Always open file descriptors 0/1/2 to avoid clobbering files
* in die(). It also avoids not messing up when the pipes are
diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh
index d34208cc2..c56a77d23 100644
--- a/t/annotate-tests.sh
+++ b/t/annotate-tests.sh
@@ -1,5 +1,5 @@
# This file isn't used as a test script directly, instead it is
-# sourced from t8001-annotate.sh and t8001-blame.sh.
+# sourced from t8001-annotate.sh and t8002-blame.sh.
check_count () {
head=
@@ -124,3 +124,14 @@ test_expect_success \
test_expect_success \
'some edit' \
'check_count A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1'
+
+test_expect_success \
+ 'an obfuscated email added' \
+ 'echo "No robots allowed" > file.new &&
+ cat file >> file.new &&
+ mv file.new file &&
+ GIT_AUTHOR_NAME="E" GIT_AUTHOR_EMAIL="E at test dot git" git commit -a -m "norobots"'
+
+test_expect_success \
+ 'obfuscated email parsed' \
+ 'check_count A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1'
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 651e0982c..ad6641056 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -402,14 +402,14 @@ test_expect_success 're-init to move gitdir' '
test -d realgitdir/refs
'
-test_expect_success 're-init to move gitdir symlink' '
+test_expect_success SYMLINKS 're-init to move gitdir symlink' '
rm -rf newdir realgitdir &&
git init newdir &&
(
cd newdir &&
mv .git here &&
ln -s here .git &&
- git init -L ../realgitdir
+ git init --separate-git-dir ../realgitdir
) &&
echo "gitdir: `pwd`/realgitdir" >expected &&
test_cmp expected newdir/.git &&
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 1d4d0a5c7..f87abb5a0 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -25,6 +25,7 @@ check_show 37500000 '1 year, 2 months ago'
check_show 55188000 '1 year, 9 months ago'
check_show 630000000 '20 years ago'
check_show 31449600 '12 months ago'
+check_show 62985600 '2 years ago'
check_parse() {
echo "$1 -> $2" >expect
diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh
index 10b26e4d8..8d4938f01 100755
--- a/t/t0061-run-command.sh
+++ b/t/t0061-run-command.sh
@@ -7,8 +7,31 @@ test_description='Test run command'
. ./test-lib.sh
+cat >hello-script <<-EOF
+ #!$SHELL_PATH
+ cat hello-script
+EOF
+>empty
+
test_expect_success 'start_command reports ENOENT' '
test-run-command start-command-ENOENT ./does-not-exist
'
+test_expect_success 'run_command can run a command' '
+ cat hello-script >hello.sh &&
+ chmod +x hello.sh &&
+ test-run-command run-command ./hello.sh >actual 2>err &&
+
+ test_cmp hello-script actual &&
+ test_cmp empty err
+'
+
+test_expect_success POSIXPERM 'run_command reports EACCES' '
+ cat hello-script >hello.sh &&
+ chmod -x hello.sh &&
+ test_must_fail test-run-command run-command ./hello.sh 2>err &&
+
+ grep "fatal: cannot exec.*hello.sh" err
+'
+
test_done
diff --git a/t/t0081-line-buffer.sh b/t/t0081-line-buffer.sh
index 5067d1e15..bd83ed371 100755
--- a/t/t0081-line-buffer.sh
+++ b/t/t0081-line-buffer.sh
@@ -2,74 +2,14 @@
test_description="Test the svn importer's input handling routines.
-These tests exercise the line_buffer library, but their real purpose
-is to check the assumptions that library makes of the platform's input
-routines. Processes engaged in bi-directional communication would
-hang if fread or fgets is too greedy.
+These tests provide some simple checks that the line_buffer API
+behaves as advertised.
While at it, check that input of newlines and null bytes are handled
correctly.
"
. ./test-lib.sh
-test -n "$GIT_REMOTE_SVN_TEST_BIG_FILES" && test_set_prereq EXPENSIVE
-
-generate_tens_of_lines () {
- tens=$1 &&
- line=$2 &&
-
- i=0 &&
- while test $i -lt "$tens"
- do
- for j in a b c d e f g h i j
- do
- echo "$line"
- done &&
- : $((i = $i + 1)) ||
- return
- done
-}
-
-long_read_test () {
- : each line is 10 bytes, including newline &&
- line=abcdefghi &&
- echo "$line" >expect &&
-
- if ! test_declared_prereq PIPE
- then
- echo >&4 "long_read_test: need to declare PIPE prerequisite"
- return 127
- fi &&
- tens_of_lines=$(($1 / 100 + 1)) &&
- lines=$(($tens_of_lines * 10)) &&
- readsize=$((($lines - 1) * 10 + 3)) &&
- copysize=7 &&
- rm -f input &&
- mkfifo input &&
- {
- (
- generate_tens_of_lines $tens_of_lines "$line" &&
- exec sleep 100
- ) >input &
- } &&
- test-line-buffer input <<-EOF >output &&
- binary $readsize
- copy $copysize
- EOF
- kill $! &&
- test_line_count = $lines output &&
- tail -n 1 <output >actual &&
- test_cmp expect actual
-}
-
-test_expect_success 'setup: have pipes?' '
- rm -f frob &&
- if mkfifo frob
- then
- test_set_prereq PIPE
- fi
-'
-
test_expect_success 'hello world' '
echo ">HELLO" >expect &&
test-line-buffer <<-\EOF >actual &&
@@ -79,21 +19,6 @@ test_expect_success 'hello world' '
test_cmp expect actual
'
-test_expect_success PIPE '0-length read, no input available' '
- printf ">" >expect &&
- rm -f input &&
- mkfifo input &&
- {
- sleep 100 >input &
- } &&
- test-line-buffer input <<-\EOF >actual &&
- binary 0
- copy 0
- EOF
- kill $! &&
- test_cmp expect actual
-'
-
test_expect_success '0-length read, send along greeting' '
echo ">HELLO" >expect &&
test-line-buffer <<-\EOF >actual &&
@@ -104,33 +29,6 @@ test_expect_success '0-length read, send along greeting' '
test_cmp expect actual
'
-test_expect_success PIPE '1-byte read, no input available' '
- printf ">%s" ab >expect &&
- rm -f input &&
- mkfifo input &&
- {
- (
- printf "%s" a &&
- printf "%s" b &&
- exec sleep 100
- ) >input &
- } &&
- test-line-buffer input <<-\EOF >actual &&
- binary 1
- copy 1
- EOF
- kill $! &&
- test_cmp expect actual
-'
-
-test_expect_success PIPE 'long read (around 8192 bytes)' '
- long_read_test 8192
-'
-
-test_expect_success PIPE,EXPENSIVE 'longer read (around 65536 bytes)' '
- long_read_test 65536
-'
-
test_expect_success 'read from file descriptor' '
rm -f input &&
echo hello >expect &&
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index ff747f822..4fd83a667 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -6,7 +6,7 @@
test_description='Test git update-ref and basic ref logging'
. ./test-lib.sh
-Z=0000000000000000000000000000000000000000
+Z=$_z40
test_expect_success setup '
diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh
index ba25ff354..caa687b5b 100755
--- a/t/t1411-reflog-show.sh
+++ b/t/t1411-reflog-show.sh
@@ -28,6 +28,24 @@ test_expect_success 'oneline reflog format' '
test_cmp expect actual
'
+test_expect_success 'reflog default format' '
+ git reflog -1 >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+commit e46513e
+Reflog: HEAD@{0} (C O Mitter <committer@example.com>)
+Reflog message: commit (initial): one
+Author: A U Thor <author@example.com>
+
+ one
+EOF
+test_expect_success 'override reflog default format' '
+ git reflog --format=short -1 >actual &&
+ test_cmp expect actual
+'
+
cat >expect <<'EOF'
Reflog: HEAD@{Thu Apr 7 15:13:13 2005 -0700} (C O Mitter <committer@example.com>)
Reflog message: commit (initial): one
diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh
index da6252b11..63849836c 100755
--- a/t/t1501-worktree.sh
+++ b/t/t1501-worktree.sh
@@ -7,7 +7,6 @@ test_expect_success 'setup' '
EMPTY_TREE=$(git write-tree) &&
EMPTY_BLOB=$(git hash-object -t blob --stdin </dev/null) &&
CHANGED_BLOB=$(echo changed | git hash-object -t blob --stdin) &&
- ZEROES=0000000000000000000000000000000000000000 &&
EMPTY_BLOB7=$(echo $EMPTY_BLOB | sed "s/\(.......\).*/\1/") &&
CHANGED_BLOB7=$(echo $CHANGED_BLOB | sed "s/\(.......\).*/\1/") &&
@@ -239,10 +238,10 @@ test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' '
test_expect_success 'diff-index respects work tree under .git dir' '
cat >diff-index-cached.expected <<-EOF &&
- :000000 100644 $ZEROES $EMPTY_BLOB A sub/dir/tracked
+ :000000 100644 $_z40 $EMPTY_BLOB A sub/dir/tracked
EOF
cat >diff-index.expected <<-EOF &&
- :000000 100644 $ZEROES $ZEROES A sub/dir/tracked
+ :000000 100644 $_z40 $_z40 A sub/dir/tracked
EOF
(
@@ -258,7 +257,7 @@ test_expect_success 'diff-index respects work tree under .git dir' '
test_expect_success 'diff-files respects work tree under .git dir' '
cat >diff-files.expected <<-EOF &&
- :100644 100644 $EMPTY_BLOB $ZEROES M sub/dir/tracked
+ :100644 100644 $EMPTY_BLOB $_z40 M sub/dir/tracked
EOF
(
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index 9f8adb1f8..0843a1c13 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -6,6 +6,16 @@ exec </dev/null
. ./test-lib.sh
+test_did_you_mean ()
+{
+ sq="'" &&
+ cat >expected <<-EOF &&
+ fatal: Path '$2$3' $4, but not ${5:-$sq$3$sq}.
+ Did you mean '$1:$2$3'${2:+ aka $sq$1:./$3$sq}?
+ EOF
+ test_cmp expected error
+}
+
HASH_file=
test_expect_success 'set up basic repo' '
@@ -106,7 +116,7 @@ test_expect_success 'incorrect file in sha1:path' '
grep "fatal: Path '"'"'index-only.txt'"'"' exists on disk, but not in '"'"'HEAD'"'"'." error &&
(cd subdir &&
test_must_fail git rev-parse HEAD:file2.txt 2> error &&
- grep "Did you mean '"'"'HEAD:subdir/file2.txt'"'"'?" error )
+ test_did_you_mean HEAD subdir/ file2.txt exists )
'
test_expect_success 'incorrect file in :path and :N:path' '
@@ -115,14 +125,14 @@ test_expect_success 'incorrect file in :path and :N:path' '
test_must_fail git rev-parse :1:nothing.txt 2> error &&
grep "Path '"'"'nothing.txt'"'"' does not exist (neither on disk nor in the index)." error &&
test_must_fail git rev-parse :1:file.txt 2> error &&
- grep "Did you mean '"'"':0:file.txt'"'"'?" error &&
+ test_did_you_mean ":0" "" file.txt "is in the index" "at stage 1" &&
(cd subdir &&
test_must_fail git rev-parse :1:file.txt 2> error &&
- grep "Did you mean '"'"':0:file.txt'"'"'?" error &&
+ test_did_you_mean ":0" "" file.txt "is in the index" "at stage 1" &&
test_must_fail git rev-parse :file2.txt 2> error &&
- grep "Did you mean '"'"':0:subdir/file2.txt'"'"'?" error &&
+ test_did_you_mean ":0" subdir/ file2.txt "is in the index" &&
test_must_fail git rev-parse :2:file2.txt 2> error &&
- grep "Did you mean '"'"':0:subdir/file2.txt'"'"'?" error) &&
+ test_did_you_mean :0 subdir/ file2.txt "is in the index") &&
test_must_fail git rev-parse :disk-only.txt 2> error &&
grep "fatal: Path '"'"'disk-only.txt'"'"' exists on disk, but not in the index." error
'
diff --git a/t/t2011-checkout-invalid-head.sh b/t/t2011-checkout-invalid-head.sh
index 15ebdc26e..300f8bf25 100755
--- a/t/t2011-checkout-invalid-head.sh
+++ b/t/t2011-checkout-invalid-head.sh
@@ -15,7 +15,7 @@ test_expect_success 'checkout should not start branch from a tree' '
'
test_expect_success 'checkout master from invalid HEAD' '
- echo 0000000000000000000000000000000000000000 >.git/HEAD &&
+ echo $_z40 >.git/HEAD &&
git checkout master --
'
diff --git a/t/t2021-checkout-overwrite.sh b/t/t2021-checkout-overwrite.sh
index 27db2ad52..5da63e9fa 100755
--- a/t/t2021-checkout-overwrite.sh
+++ b/t/t2021-checkout-overwrite.sh
@@ -39,7 +39,7 @@ test_expect_success SYMLINKS 'create a commit where dir a/b changed to symlink'
git commit -m "dir to symlink"
'
-test_expect_failure SYMLINKS 'checkout commit with dir must not remove untracked a/b' '
+test_expect_success SYMLINKS 'checkout commit with dir must not remove untracked a/b' '
git rm --cached a/b &&
git commit -m "un-track the symlink" &&
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index 2d7d3115d..4cdebda6a 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -149,31 +149,21 @@ test_expect_success 'add -u resolves unmerged paths' '
echo 3 >path1 &&
echo 2 >path3 &&
echo 2 >path5 &&
- git add -u &&
- git ls-files -s path1 path2 path3 path4 path5 path6 >actual &&
- {
- echo "100644 $three 0 path1"
- echo "100644 $one 1 path3"
- echo "100644 $one 1 path4"
- echo "100644 $one 3 path5"
- echo "100644 $one 3 path6"
- } >expect &&
- test_cmp expect actual &&
- # Bonus tests. Explicit resolving
- git add path3 path5 &&
+ # Explicit resolving by adding removed paths should fail
test_must_fail git add path4 &&
test_must_fail git add path6 &&
- git rm path4 &&
- git rm path6 &&
- git ls-files -s "path?" >actual &&
+ # "add -u" should notice removals no matter what stages
+ # the index entries are in.
+ git add -u &&
+ git ls-files -s path1 path2 path3 path4 path5 path6 >actual &&
{
echo "100644 $three 0 path1"
echo "100644 $two 0 path3"
echo "100644 $two 0 path5"
- } >expect
-
+ } >expect &&
+ test_cmp expect actual
'
test_expect_success '"add -u non-existent" should fail' '
diff --git a/t/t2201-add-update-typechange.sh b/t/t2201-add-update-typechange.sh
index 2e8f70245..954fc51e5 100755
--- a/t/t2201-add-update-typechange.sh
+++ b/t/t2201-add-update-typechange.sh
@@ -4,8 +4,6 @@ test_description='more git add -u'
. ./test-lib.sh
-_z40=0000000000000000000000000000000000000000
-
test_expect_success setup '
>xyzzy &&
_empty=$(git hash-object --stdin <xyzzy) &&
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 0ce95c04e..9e69c8c92 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -46,7 +46,7 @@ test_expect_success \
'git branch a/b/c && test -f .git/refs/heads/a/b/c'
cat >expect <<EOF
-0000000000000000000000000000000000000000 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master
+$_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master
EOF
test_expect_success \
'git branch -l d/e/f should create a branch and a log' \
@@ -232,7 +232,7 @@ test_expect_success \
# Keep this test last, as it changes the current branch
cat >expect <<EOF
-0000000000000000000000000000000000000000 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master
+$_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master
EOF
test_expect_success \
'git checkout -b g/h/i -l should create a branch and a log' \
diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh
index c4282179b..86bf909ee 100755
--- a/t/t3306-notes-prune.sh
+++ b/t/t3306-notes-prune.sh
@@ -20,6 +20,9 @@ test_expect_success 'setup: create a few commits with notes' '
git add file3 &&
test_tick &&
git commit -m 3rd &&
+ COMMIT_FILE=.git/objects/5e/e1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
+ test -f $COMMIT_FILE &&
+ test-chmtime =+0 $COMMIT_FILE &&
git notes add -m "Note #3"
'
diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh
index 19341e5ca..08201e233 100755
--- a/t/t3409-rebase-preserve-merges.sh
+++ b/t/t3409-rebase-preserve-merges.sh
@@ -27,7 +27,17 @@ export GIT_AUTHOR_EMAIL
# \
# B2 <-- origin/topic
#
-# In both cases, 'topic' is rebased onto 'origin/topic'.
+# Clone 3 (no-ff merge):
+#
+# A1--A2--B3 <-- origin/master
+# \
+# B1------M <-- topic
+# \ /
+# \--A3 <-- topic2
+# \
+# B2 <-- origin/topic
+#
+# In all cases, 'topic' is rebased onto 'origin/topic'.
test_expect_success 'setup for merge-preserving rebase' \
'echo First > A &&
@@ -61,6 +71,16 @@ test_expect_success 'setup for merge-preserving rebase' \
git commit -m "Merge origin/master into topic"
) &&
+ git clone ./. clone3 &&
+ (
+ cd clone3 &&
+ git checkout -b topic2 origin/topic &&
+ echo Sixth > A &&
+ git commit -a -m "Modify A3" &&
+ git checkout -b topic origin/topic &&
+ git merge --no-ff topic2
+ ) &&
+
git checkout topic &&
echo Fourth >> B &&
git commit -a -m "Modify B2"
@@ -93,4 +113,14 @@ test_expect_success '--continue works after a conflict' '
)
'
+test_expect_success 'rebase -p preserves no-ff merges' '
+ (
+ cd clone3 &&
+ git fetch &&
+ git rebase -p origin/topic &&
+ test 3 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) &&
+ test 1 = $(git rev-list --all --pretty=oneline | grep "Merge branch" | wc -l)
+ )
+'
+
test_done
diff --git a/t/t3503-cherry-pick-root.sh b/t/t3503-cherry-pick-root.sh
index b0faa2991..9aefe3a1b 100755
--- a/t/t3503-cherry-pick-root.sh
+++ b/t/t3503-cherry-pick-root.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='test cherry-picking a root commit'
+test_description='test cherry-picking (and reverting) a root commit'
. ./test-lib.sh
@@ -23,7 +23,30 @@ test_expect_success setup '
test_expect_success 'cherry-pick a root commit' '
git cherry-pick master &&
- test first = $(cat file1)
+ echo first >expect &&
+ test_cmp expect file1
+
+'
+
+test_expect_success 'revert a root commit' '
+
+ git revert master &&
+ test_path_is_missing file1
+
+'
+
+test_expect_success 'cherry-pick a root commit with an external strategy' '
+
+ git cherry-pick --strategy=resolve master &&
+ echo first >expect &&
+ test_cmp expect file1
+
+'
+
+test_expect_success 'revert a root commit with an external strategy' '
+
+ git revert --strategy=resolve master &&
+ test_path_is_missing file1
'
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index cd093bd34..9fd28bcf3 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -240,11 +240,10 @@ test_expect_success 'refresh index before checking if it is up-to-date' '
test_expect_success 'choking "git rm" should not let it die with cruft' '
git reset -q --hard &&
- H=0000000000000000000000000000000000000000 &&
i=0 &&
while test $i -lt 12000
do
- echo "100644 $H 0 some-file-$i"
+ echo "100644 $_z40 0 some-file-$i"
i=$(( $i + 1 ))
done | git update-index --index-info &&
git rm -n "some-file-*" | :;
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index d6327e7c7..9e236f9cc 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -82,10 +82,9 @@ EOF
'
test_expect_success PERL 'setup fake editor' '
- cat >fake_editor.sh <<EOF
- EOF
+ >fake_editor.sh &&
chmod a+x fake_editor.sh &&
- test_set_editor "$(pwd)/fake_editor.sh" &&
+ test_set_editor "$(pwd)/fake_editor.sh"
'
test_expect_success PERL 'dummy edit works' '
@@ -295,4 +294,40 @@ test_expect_success PERL 'deleting an empty file' '
test_cmp expected diff
'
+test_expect_success PERL 'split hunk setup' '
+ git reset --hard &&
+ for i in 10 20 30 40 50 60
+ do
+ echo $i
+ done >test &&
+ git add test &&
+ test_tick &&
+ git commit -m test &&
+
+ for i in 10 15 20 21 22 23 24 30 40 50 60
+ do
+ echo $i
+ done >test
+'
+
+test_expect_success PERL 'split hunk "add -p (edit)"' '
+ # Split, say Edit and do nothing. Then:
+ #
+ # 1. Broken version results in a patch that does not apply and
+ # only takes [y/n] (edit again) so the first q is discarded
+ # and then n attempts to discard the edit. Repeat q enough
+ # times to get out.
+ #
+ # 2. Correct version applies the (not)edited version, and asks
+ # about the next hunk, against wich we say q and program
+ # exits.
+ for a in s e q n q q
+ do
+ echo $a
+ done |
+ EDITOR=: git add -p &&
+ git diff >actual &&
+ ! grep "^+15" actual
+'
+
test_done
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index f62aaf581..5c7254064 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -37,14 +37,32 @@ test_expect_success 'parents of stash' '
test_cmp output expect
'
-test_expect_success 'apply needs clean working directory' '
- echo 4 > other-file &&
+test_expect_success 'applying bogus stash does nothing' '
+ test_must_fail git stash apply stash@{1} &&
+ echo 1 >expect &&
+ test_cmp expect file
+'
+
+test_expect_success 'apply does not need clean working directory' '
+ echo 4 >other-file &&
git add other-file &&
- echo 5 > other-file &&
- test_must_fail git stash apply
+ echo 5 >other-file &&
+ git stash apply &&
+ echo 3 >expect &&
+ test_cmp expect file
+'
+
+test_expect_success 'apply does not clobber working directory changes' '
+ git reset --hard &&
+ echo 4 >file &&
+ test_must_fail git stash apply &&
+ echo 4 >expect &&
+ test_cmp expect file
'
test_expect_success 'apply stashed changes' '
+ git reset --hard &&
+ echo 5 >other-file &&
git add other-file &&
test_tick &&
git commit -m other-file &&
@@ -218,6 +236,14 @@ test_expect_success 'stash -k' '
test bar,bar4 = $(cat file),$(cat file2)
'
+test_expect_success 'stash --no-keep-index' '
+ echo bar33 > file &&
+ echo bar44 > file2 &&
+ git add file2 &&
+ git stash --no-keep-index &&
+ test bar,bar2 = $(cat file),$(cat file2)
+'
+
test_expect_success 'stash --invalid-option' '
echo bar5 > file &&
echo bar6 > file2 &&
@@ -537,11 +563,11 @@ test_expect_success 'invalid ref of the form stash@{n}, n >= N' '
echo bar6 > file2 &&
git add file2 &&
git stash &&
- test_must_fail git drop stash@{1} &&
- test_must_fail git pop stash@{1} &&
- test_must_fail git apply stash@{1} &&
- test_must_fail git show stash@{1} &&
- test_must_fail git branch tmp stash@{1} &&
+ test_must_fail git stash drop stash@{1} &&
+ test_must_fail git stash pop stash@{1} &&
+ test_must_fail git stash apply stash@{1} &&
+ test_must_fail git stash show stash@{1} &&
+ test_must_fail git stash branch tmp stash@{1} &&
git stash drop
'
diff --git a/t/t3904-stash-patch.sh b/t/t3904-stash-patch.sh
index 1e7193ac0..781fd7168 100755
--- a/t/t3904-stash-patch.sh
+++ b/t/t3904-stash-patch.sh
@@ -48,6 +48,18 @@ test_expect_success PERL 'git stash -p --no-keep-index' '
verify_state bar dummy bar_index
'
+test_expect_success PERL 'git stash --no-keep-index -p' '
+ set_state dir/foo work index &&
+ set_state bar bar_work bar_index &&
+ (echo n; echo y) | git stash save --no-keep-index -p &&
+ verify_state dir/foo head head &&
+ verify_state bar bar_work dummy &&
+ git reset --hard &&
+ git stash apply --index &&
+ verify_state dir/foo work index &&
+ verify_state bar dummy bar_index
+'
+
test_expect_success PERL 'none of this moved HEAD' '
verify_saved_head
'
diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh
index 9a16d1cd9..844277cfa 100755
--- a/t/t4001-diff-rename.sh
+++ b/t/t4001-diff-rename.sh
@@ -77,4 +77,29 @@ test_expect_success 'favour same basenames even with minor differences' '
git show HEAD:path1 | sed "s/15/16/" > subdir/path1 &&
git status | test_i18ngrep "renamed: .*path1 -> subdir/path1"'
+test_expect_success 'setup for many rename source candidates' '
+ git reset --hard &&
+ for i in 0 1 2 3 4 5 6 7 8 9;
+ do
+ for j in 0 1 2 3 4 5 6 7 8 9;
+ do
+ echo "$i$j" >"path$i$j"
+ done
+ done &&
+ git add "path??" &&
+ test_tick &&
+ git commit -m "hundred" &&
+ (cat path1; echo new) >new-path &&
+ echo old >>path1 &&
+ git add new-path path1 &&
+ git diff -l 4 -C -C --cached --name-status >actual 2>actual.err &&
+ sed -e "s/^\([CM]\)[0-9]* /\1 /" actual >actual.munged &&
+ cat >expect <<-EOF &&
+ C path1 new-path
+ M path1
+ EOF
+ test_cmp expect actual.munged &&
+ grep warning actual.err
+'
+
test_done
diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh
index 9fb8ca06a..a5e8b8308 100755
--- a/t/t4002-diff-basic.sh
+++ b/t/t4002-diff-basic.sh
@@ -126,15 +126,12 @@ cat >.test-recursive-AB <<\EOF
:100644 100644 3fdbe17fd013303a2e981e1ca1c6cd6e72789087 7e09d6a3a14bd630913e8c75693cea32157b606d M Z/NM
EOF
-x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
-x40="$x40$x40$x40$x40$x40$x40$x40$x40"
-z40='0000000000000000000000000000000000000000'
cmp_diff_files_output () {
# diff-files never reports additions. Also it does not fill in the
# object ID for the changed files because it wants you to look at the
# filesystem.
sed <"$2" >.test-tmp \
- -e '/^:000000 /d;s/'$x40'\( [MCRNDU][0-9]*\) /'$z40'\1 /' &&
+ -e '/^:000000 /d;s/'$_x40'\( [MCRNDU][0-9]*\) /'$_z40'\1 /' &&
test_cmp "$1" .test-tmp
}
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 5daa0f2a0..93a6f2087 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -80,18 +80,31 @@ test_expect_success setup '
git config log.showroot false &&
git commit --amend &&
+
+ GIT_AUTHOR_DATE="2006-06-26 00:06:00 +0000" &&
+ GIT_COMMITTER_DATE="2006-06-26 00:06:00 +0000" &&
+ export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&
+ git checkout -b rearrange initial &&
+ for i in B A; do echo $i; done >dir/sub &&
+ git add dir/sub &&
+ git commit -m "Rearranged lines in dir/sub" &&
+ git checkout master &&
+
git show-branch
'
: <<\EOF
! [initial] Initial
* [master] Merge branch 'side'
- ! [side] Side
----
- - [master] Merge branch 'side'
- *+ [side] Side
- * [master^] Second
-+*+ [initial] Initial
+ ! [rearrange] Rearranged lines in dir/sub
+ ! [side] Side
+----
+ + [rearrange] Rearranged lines in dir/sub
+ - [master] Merge branch 'side'
+ * + [side] Side
+ * [master^] Third
+ * [master~2] Second
++*++ [initial] Initial
EOF
V=`git version | sed -e 's/^git version //' -e 's/\./\\./g'`
@@ -287,6 +300,8 @@ diff --no-index --name-status -- dir2 dir
diff --no-index dir dir3
diff master master^ side
diff --dirstat master~1 master~2
+diff --dirstat initial rearrange
+diff --dirstat-by-file initial rearrange
EOF
test_expect_success 'log -S requires an argument' '
diff --git a/t/t4013/diff.diff_--dirstat-by-file_initial_rearrange b/t/t4013/diff.diff_--dirstat-by-file_initial_rearrange
new file mode 100644
index 000000000..e48e33f67
--- /dev/null
+++ b/t/t4013/diff.diff_--dirstat-by-file_initial_rearrange
@@ -0,0 +1,3 @@
+$ git diff --dirstat-by-file initial rearrange
+ 100.0% dir/
+$
diff --git a/t/t4013/diff.diff_--dirstat_initial_rearrange b/t/t4013/diff.diff_--dirstat_initial_rearrange
new file mode 100644
index 000000000..5fb02c13b
--- /dev/null
+++ b/t/t4013/diff.diff_--dirstat_initial_rearrange
@@ -0,0 +1,3 @@
+$ git diff --dirstat initial rearrange
+ 100.0% dir/
+$
diff --git a/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^ b/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
index 1f0f9ad44..3b4e11301 100644
--- a/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
+++ b/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
@@ -1,7 +1,7 @@
$ git format-patch --stdout --cover-letter -n initial..master^
From 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Mon Sep 17 00:00:00 2001
From: C O Mitter <committer@example.com>
-Date: Mon, 26 Jun 2006 00:05:00 +0000
+Date: Mon, 26 Jun 2006 00:06:00 +0000
Subject: [DIFFERENT_PREFIX 0/2] *** SUBJECT HERE ***
*** BLURB HERE ***
diff --git a/t/t4013/diff.log_--decorate=full_--all b/t/t4013/diff.log_--decorate=full_--all
index d155e0bab..44d45257d 100644
--- a/t/t4013/diff.log_--decorate=full_--all
+++ b/t/t4013/diff.log_--decorate=full_--all
@@ -1,4 +1,10 @@
$ git log --decorate=full --all
+commit cd4e72fd96faed3f0ba949dc42967430374e2290 (refs/heads/rearrange)
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:06:00 2006 +0000
+
+ Rearranged lines in dir/sub
+
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, refs/heads/master)
Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--decorate_--all b/t/t4013/diff.log_--decorate_--all
index fd7c3e643..27d3eabc2 100644
--- a/t/t4013/diff.log_--decorate_--all
+++ b/t/t4013/diff.log_--decorate_--all
@@ -1,4 +1,10 @@
$ git log --decorate --all
+commit cd4e72fd96faed3f0ba949dc42967430374e2290 (rearrange)
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:06:00 2006 +0000
+
+ Rearranged lines in dir/sub
+
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, master)
Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 37a4109c9..4a3bf5ba4 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -793,4 +793,46 @@ test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
test_cmp expect subject
'
+check_author() {
+ echo content >>file &&
+ git add file &&
+ GIT_AUTHOR_NAME=$1 git commit -m author-check &&
+ git format-patch --stdout -1 >patch &&
+ grep ^From: patch >actual &&
+ test_cmp expect actual
+}
+
+cat >expect <<'EOF'
+From: "Foo B. Bar" <author@example.com>
+EOF
+test_expect_success 'format-patch quotes dot in headers' '
+ check_author "Foo B. Bar"
+'
+
+cat >expect <<'EOF'
+From: "Foo \"The Baz\" Bar" <author@example.com>
+EOF
+test_expect_success 'format-patch quotes double-quote in headers' '
+ check_author "Foo \"The Baz\" Bar"
+'
+
+cat >expect <<'EOF'
+From: =?UTF-8?q?"F=C3=B6o=20B.=20Bar"?= <author@example.com>
+EOF
+test_expect_success 'rfc2047-encoded headers also double-quote 822 specials' '
+ check_author "Föo B. Bar"
+'
+
+cat >expect <<'EOF'
+Subject: header with . in it
+EOF
+test_expect_success 'subject lines do not have 822 atom-quoting' '
+ echo content >>file &&
+ git add file &&
+ git commit -m "header with . in it" &&
+ git format-patch -k -1 --stdout >patch &&
+ grep ^Subject: patch >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh
index a7602cf92..083f62d1d 100755
--- a/t/t4020-diff-external.sh
+++ b/t/t4020-diff-external.sh
@@ -4,8 +4,6 @@ test_description='external diff interface test'
. ./test-lib.sh
-_z40=0000000000000000000000000000000000000000
-
test_expect_success setup '
test_tick &&
diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh
index 241a74d2a..518bf9524 100755
--- a/t/t4027-diff-submodule.sh
+++ b/t/t4027-diff-submodule.sh
@@ -5,7 +5,6 @@ test_description='difference in submodules'
. ./test-lib.sh
. "$TEST_DIRECTORY"/diff-lib.sh
-_z40=0000000000000000000000000000000000000000
test_expect_success setup '
test_tick &&
test_create_repo sub &&
diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh
index 37aeab0d5..c374aa4c1 100755
--- a/t/t4034-diff-words.sh
+++ b/t/t4034-diff-words.sh
@@ -307,4 +307,30 @@ test_language_driver python
test_language_driver ruby
test_language_driver tex
+test_expect_success 'word-diff with diff.sbe' '
+ cat >expect <<-\EOF &&
+ diff --git a/pre b/post
+ index a1a53b5..bc8fe6d 100644
+ --- a/pre
+ +++ b/post
+ @@ -1,3 +1,3 @@
+ a
+
+ [-b-]{+c+}
+ EOF
+ cat >pre <<-\EOF &&
+ a
+
+ b
+ EOF
+ cat >post <<-\EOF &&
+ a
+
+ c
+ EOF
+ test_when_finished "git config --unset diff.suppress-blank-empty" &&
+ git config diff.suppress-blank-empty true &&
+ word_diff --word-diff=plain
+'
+
test_done
diff --git a/t/t4046-diff-unmerged.sh b/t/t4046-diff-unmerged.sh
new file mode 100755
index 000000000..25d50a654
--- /dev/null
+++ b/t/t4046-diff-unmerged.sh
@@ -0,0 +1,87 @@
+#!/bin/sh
+
+test_description='diff with unmerged index entries'
+. ./test-lib.sh
+
+test_expect_success setup '
+ for i in 0 1 2 3
+ do
+ blob=$(echo $i | git hash-object --stdin) &&
+ eval "blob$i=$blob" &&
+ eval "m$i=\"100644 \$blob$i $i\"" || break
+ done &&
+ paths= &&
+ for b in o x
+ do
+ for o in o x
+ do
+ for t in o x
+ do
+ path="$b$o$t" &&
+ case "$path" in ooo) continue ;; esac
+ paths="$paths$path " &&
+ p=" $path" &&
+ case "$b" in x) echo "$m1$p" ;; esac &&
+ case "$o" in x) echo "$m2$p" ;; esac &&
+ case "$t" in x) echo "$m3$p" ;; esac ||
+ break
+ done || break
+ done || break
+ done >ls-files-s.expect &&
+ git update-index --index-info <ls-files-s.expect &&
+ git ls-files -s >ls-files-s.actual &&
+ test_cmp ls-files-s.expect ls-files-s.actual
+'
+
+test_expect_success 'diff-files -0' '
+ for path in $paths
+ do
+ >"$path" &&
+ echo ":000000 100644 $_z40 $_z40 U $path"
+ done >diff-files-0.expect &&
+ git diff-files -0 >diff-files-0.actual &&
+ test_cmp diff-files-0.expect diff-files-0.actual
+'
+
+test_expect_success 'diff-files -1' '
+ for path in $paths
+ do
+ >"$path" &&
+ echo ":000000 100644 $_z40 $_z40 U $path" &&
+ case "$path" in
+ x??) echo ":100644 100644 $blob1 $_z40 M $path"
+ esac
+ done >diff-files-1.expect &&
+ git diff-files -1 >diff-files-1.actual &&
+ test_cmp diff-files-1.expect diff-files-1.actual
+'
+
+test_expect_success 'diff-files -2' '
+ for path in $paths
+ do
+ >"$path" &&
+ echo ":000000 100644 $_z40 $_z40 U $path" &&
+ case "$path" in
+ ?x?) echo ":100644 100644 $blob2 $_z40 M $path"
+ esac
+ done >diff-files-2.expect &&
+ git diff-files -2 >diff-files-2.actual &&
+ test_cmp diff-files-2.expect diff-files-2.actual &&
+ git diff-files >diff-files-default-2.actual &&
+ test_cmp diff-files-2.expect diff-files-default-2.actual
+'
+
+test_expect_success 'diff-files -3' '
+ for path in $paths
+ do
+ >"$path" &&
+ echo ":000000 100644 $_z40 $_z40 U $path" &&
+ case "$path" in
+ ??x) echo ":100644 100644 $blob3 $_z40 M $path"
+ esac
+ done >diff-files-3.expect &&
+ git diff-files -3 >diff-files-3.actual &&
+ test_cmp diff-files-3.expect diff-files-3.actual
+'
+
+test_done
diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh
index e2ed13dba..d64532860 100755
--- a/t/t5304-prune.sh
+++ b/t/t5304-prune.sh
@@ -14,7 +14,8 @@ add_blob() {
BLOB=$(echo aleph_0 | git hash-object -w --stdin) &&
BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") &&
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
- test -f $BLOB_FILE
+ test -f $BLOB_FILE &&
+ test-chmtime =+0 $BLOB_FILE
}
test_expect_success setup '
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index b0b2684a1..0eace37a0 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -190,7 +190,7 @@ test_expect_success 'pushing explicit refspecs respects forcing' '
+refs/heads/master:refs/heads/master
) &&
parent_head=$(cd parent && git rev-parse --verify master) &&
- child_head=$(cd parent && git rev-parse --verify master) &&
+ child_head=$(cd child && git rev-parse --verify master) &&
test "$parent_head" = "$child_head"
'
@@ -210,7 +210,7 @@ test_expect_success 'pushing wildcard refspecs respects forcing' '
"+refs/heads/*:refs/heads/*"
) &&
parent_head=$(cd parent && git rev-parse --verify master) &&
- child_head=$(cd parent && git rev-parse --verify master) &&
+ child_head=$(cd child && git rev-parse --verify master) &&
test "$parent_head" = "$child_head"
'
diff --git a/t/t5532-fetch-proxy.sh b/t/t5532-fetch-proxy.sh
new file mode 100755
index 000000000..62f246004
--- /dev/null
+++ b/t/t5532-fetch-proxy.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+test_description='fetching via git:// using core.gitproxy'
+. ./test-lib.sh
+
+test_expect_success 'setup remote repo' '
+ git init remote &&
+ (cd remote &&
+ echo content >file &&
+ git add file &&
+ git commit -m one
+ )
+'
+
+cat >proxy <<'EOF'
+#!/bin/sh
+echo >&2 "proxying for $*"
+cmd=`perl -e '
+ read(STDIN, $buf, 4);
+ my $n = hex($buf) - 4;
+ read(STDIN, $buf, $n);
+ my ($cmd, $other) = split /\0/, $buf;
+ # drop absolute-path on repo name
+ $cmd =~ s{ /}{ };
+ print $cmd;
+'`
+echo >&2 "Running '$cmd'"
+exec $cmd
+EOF
+chmod +x proxy
+test_expect_success 'setup local repo' '
+ git remote add fake git://example.com/remote &&
+ git config core.gitproxy ./proxy
+'
+
+test_expect_success 'fetch through proxy works' '
+ git fetch fake &&
+ echo one >expect &&
+ git log -1 --format=%s FETCH_HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t6017-rev-list-stdin.sh b/t/t6017-rev-list-stdin.sh
index f1c32dba4..667b37564 100755
--- a/t/t6017-rev-list-stdin.sh
+++ b/t/t6017-rev-list-stdin.sh
@@ -58,4 +58,21 @@ check side-3 ^side-4 -- file-3
check side-3 ^side-2
check side-3 ^side-2 -- file-1
+test_expect_success 'not only --stdin' '
+ cat >expect <<-EOF &&
+ 7
+
+ file-1
+ file-2
+ EOF
+ cat >input <<-EOF &&
+ ^master^
+ --
+ file-2
+ EOF
+ git log --pretty=tformat:%s --name-only --stdin master -- file-1 \
+ <input >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t6060-merge-index.sh b/t/t6060-merge-index.sh
new file mode 100755
index 000000000..debadbd29
--- /dev/null
+++ b/t/t6060-merge-index.sh
@@ -0,0 +1,100 @@
+#!/bin/sh
+
+test_description='basic git merge-index / git-merge-one-file tests'
+. ./test-lib.sh
+
+test_expect_success 'setup diverging branches' '
+ for i in 1 2 3 4 5 6 7 8 9 10; do
+ echo $i
+ done >file &&
+ git add file &&
+ git commit -m base &&
+ git tag base &&
+ sed s/2/two/ <file >tmp &&
+ mv tmp file &&
+ git commit -a -m two &&
+ git tag two &&
+ git checkout -b other HEAD^ &&
+ sed s/10/ten/ <file >tmp &&
+ mv tmp file &&
+ git commit -a -m ten &&
+ git tag ten
+'
+
+cat >expect-merged <<'EOF'
+1
+two
+3
+4
+5
+6
+7
+8
+9
+ten
+EOF
+
+test_expect_success 'read-tree does not resolve content merge' '
+ git read-tree -i -m base ten two &&
+ echo file >expect &&
+ git diff-files --name-only --diff-filter=U >unmerged &&
+ test_cmp expect unmerged
+'
+
+test_expect_success 'git merge-index git-merge-one-file resolves' '
+ git merge-index git-merge-one-file -a &&
+ git diff-files --name-only --diff-filter=U >unmerged &&
+ >expect &&
+ test_cmp expect unmerged &&
+ test_cmp expect-merged file &&
+ git cat-file blob :file >file-index &&
+ test_cmp expect-merged file-index
+'
+
+test_expect_success 'setup bare merge' '
+ git clone --bare . bare.git &&
+ (cd bare.git &&
+ GIT_INDEX_FILE=$PWD/merge.index &&
+ export GIT_INDEX_FILE &&
+ git read-tree -i -m base ten two
+ )
+'
+
+test_expect_success 'merge-one-file fails without a work tree' '
+ (cd bare.git &&
+ GIT_INDEX_FILE=$PWD/merge.index &&
+ export GIT_INDEX_FILE &&
+ test_must_fail git merge-index git-merge-one-file -a
+ )
+'
+
+test_expect_success 'merge-one-file respects GIT_WORK_TREE' '
+ (cd bare.git &&
+ mkdir work &&
+ GIT_WORK_TREE=$PWD/work &&
+ export GIT_WORK_TREE &&
+ GIT_INDEX_FILE=$PWD/merge.index &&
+ export GIT_INDEX_FILE &&
+ git merge-index git-merge-one-file -a &&
+ git cat-file blob :file >work/file-index
+ ) &&
+ test_cmp expect-merged bare.git/work/file &&
+ test_cmp expect-merged bare.git/work/file-index
+'
+
+test_expect_success 'merge-one-file respects core.worktree' '
+ mkdir subdir &&
+ git clone . subdir/child &&
+ (cd subdir &&
+ GIT_DIR=$PWD/child/.git &&
+ export GIT_DIR &&
+ git config core.worktree "$PWD/child" &&
+ git read-tree -i -m base ten two &&
+ git merge-index git-merge-one-file -a &&
+ git cat-file blob :file >file-index
+ ) &&
+ test_cmp expect-merged subdir/child/file &&
+ test_cmp expect-merged subdir/file-index
+'
+
+test_done
diff --git a/t/t7011-skip-worktree-reading.sh b/t/t7011-skip-worktree-reading.sh
index bb4066f76..8f3b54d82 100755
--- a/t/t7011-skip-worktree-reading.sh
+++ b/t/t7011-skip-worktree-reading.sh
@@ -24,7 +24,7 @@ H sub/2
EOF
NULL_SHA1=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
-ZERO_SHA0=0000000000000000000000000000000000000000
+
setup_absent() {
test -f 1 && rm 1
git update-index --remove 1 &&
@@ -120,7 +120,7 @@ test_expect_success 'grep with skip-worktree file' '
test "$(git grep --no-ext-grep test)" = "1:test"
'
-echo ":000000 100644 $ZERO_SHA0 $NULL_SHA1 A 1" > expected
+echo ":000000 100644 $_z40 $NULL_SHA1 A 1" > expected
test_expect_success 'diff-index does not examine skip-worktree absent entries' '
setup_absent &&
git diff-index HEAD -- 1 > result &&
diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh
index cffb2696d..9ceaa4049 100755
--- a/t/t7012-skip-worktree-writing.sh
+++ b/t/t7012-skip-worktree-writing.sh
@@ -54,7 +54,7 @@ test_expect_success 'read-tree removes worktree, dirty case' '
'
NULL_SHA1=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
-ZERO_SHA0=0000000000000000000000000000000000000000
+
setup_absent() {
test -f 1 && rm 1
git update-index --remove 1 &&
diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh
index da2a1f194..b8cb4906a 100755
--- a/t/t7060-wtstatus.sh
+++ b/t/t7060-wtstatus.sh
@@ -56,4 +56,66 @@ test_expect_success 'M/D conflict does not segfault' '
)
'
+test_expect_success 'rename & unmerged setup' '
+ git rm -f -r . &&
+ cat "$TEST_DIRECTORY/README" >ONE &&
+ git add ONE &&
+ test_tick &&
+ git commit -m "One commit with ONE" &&
+
+ echo Modified >TWO &&
+ cat ONE >>TWO &&
+ cat ONE >>THREE &&
+ git add TWO THREE &&
+ sha1=$(git rev-parse :ONE) &&
+ git rm --cached ONE &&
+ (
+ echo "100644 $sha1 1 ONE" &&
+ echo "100644 $sha1 2 ONE" &&
+ echo "100644 $sha1 3 ONE"
+ ) | git update-index --index-info &&
+ echo Further >>THREE
+'
+
+test_expect_success 'rename & unmerged status' '
+ git status -suno >actual &&
+ cat >expect <<-EOF &&
+ UU ONE
+ AM THREE
+ A TWO
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'git diff-index --cached shows 2 added + 1 unmerged' '
+ cat >expected <<-EOF &&
+ U ONE
+ A THREE
+ A TWO
+ EOF
+ git diff-index --cached --name-status HEAD >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'git diff-index --cached -M shows 2 added + 1 unmerged' '
+ cat >expected <<-EOF &&
+ U ONE
+ A THREE
+ A TWO
+ EOF
+ git diff-index --cached --name-status HEAD >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'git diff-index --cached -C shows 2 copies + 1 unmerged' '
+ cat >expected <<-EOF &&
+ U ONE
+ C ONE THREE
+ C ONE TWO
+ EOF
+ git diff-index --cached -C --name-status HEAD |
+ sed "s/^C[0-9]*/C/g" >actual &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 7e1be4440..800b5368a 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -453,4 +453,11 @@ test_expect_success 'git clean -e' '
)
'
+test_expect_success SANITY 'git clean -d with an unreadable empty directory' '
+ mkdir foo &&
+ chmod a= foo &&
+ git clean -dfx foo &&
+ ! test -d foo
+'
+
test_done
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index e84e82221..2d4ed206e 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -324,6 +324,38 @@ test_expect_success 'merge c1 with c2 (no-commit in config)' '
test_debug 'git log --graph --decorate --oneline --all'
+test_expect_success 'merge c1 with c2 (log in config)' '
+ git config branch.master.mergeoptions "" &&
+ git reset --hard c1 &&
+ git merge --log c2 &&
+ git show -s --pretty=tformat:%s%n%b >expect &&
+
+ git config branch.master.mergeoptions --log &&
+ git reset --hard c1 &&
+ git merge c2 &&
+ git show -s --pretty=tformat:%s%n%b >actual &&
+
+ test_cmp expect actual
+'
+
+test_expect_success 'merge c1 with c2 (log in config gets overridden)' '
+ (
+ git config --remove-section branch.master
+ git config --remove-section merge
+ )
+ git reset --hard c1 &&
+ git merge c2 &&
+ git show -s --pretty=tformat:%s%n%b >expect &&
+
+ git config branch.master.mergeoptions "--no-log" &&
+ git config merge.log true &&
+ git reset --hard c1 &&
+ git merge c2 &&
+ git show -s --pretty=tformat:%s%n%b >actual &&
+
+ test_cmp expect actual
+'
+
test_expect_success 'merge c1 with c2 (squash in config)' '
git reset --hard c1 &&
git config branch.master.mergeoptions "--squash" &&
diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh
index dc838c93b..cbc08e327 100755
--- a/t/t7610-mergetool.sh
+++ b/t/t7610-mergetool.sh
@@ -22,26 +22,50 @@ test_expect_success 'setup' '
echo master file14 >file14 &&
mkdir subdir &&
echo master sub >subdir/file3 &&
- git add file1 file1[1-4] subdir/file3 &&
+ test_create_repo submod &&
+ (
+ cd submod &&
+ : >foo &&
+ git add foo &&
+ git commit -m "Add foo"
+ ) &&
+ git submodule add git://example.com/submod submod &&
+ git add file1 file1[1-4] subdir/file3 .gitmodules submod &&
git commit -m "add initial versions" &&
git checkout -b branch1 master &&
+ git submodule update -N &&
echo branch1 change >file1 &&
echo branch1 newfile >file2 &&
echo branch1 change file11 >file11 &&
echo branch1 change file13 >file13 &&
echo branch1 sub >subdir/file3 &&
- git add file1 file11 file13 file2 subdir/file3 &&
+ (
+ cd submod &&
+ echo branch1 submodule >bar &&
+ git add bar &&
+ git commit -m "Add bar on branch1" &&
+ git checkout -b submod-branch1
+ ) &&
+ git add file1 file11 file13 file2 subdir/file3 submod &&
git rm file12 &&
git commit -m "branch1 changes" &&
git checkout master &&
+ git submodule update -N &&
echo master updated >file1 &&
echo master new >file2 &&
echo master updated file12 >file12 &&
echo master updated file14 >file14 &&
echo master new sub >subdir/file3 &&
- git add file1 file12 file14 file2 subdir/file3 &&
+ (
+ cd submod &&
+ echo master submodule >bar &&
+ git add bar &&
+ git commit -m "Add bar on master" &&
+ git checkout -b submod-master
+ ) &&
+ git add file1 file12 file14 file2 subdir/file3 submod &&
git rm file11 &&
git commit -m "master updates" &&
@@ -52,15 +76,18 @@ test_expect_success 'setup' '
test_expect_success 'custom mergetool' '
git checkout -b test1 branch1 &&
+ git submodule update -N &&
test_must_fail git merge master >/dev/null 2>&1 &&
( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
+ ( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
test "$(cat file1)" = "master updated" &&
test "$(cat file2)" = "master new" &&
test "$(cat subdir/file3)" = "master new sub" &&
+ test "$(cat submod/bar)" = "branch1 submodule" &&
git commit -m "branch1 resolved with mergetool"
'
@@ -73,9 +100,12 @@ test_expect_success 'mergetool crlf' '
( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
+ ( yes "r" | git mergetool submod >/dev/null 2>&1 ) &&
test "$(printf x | cat file1 -)" = "$(printf "master updated\r\nx")" &&
test "$(printf x | cat file2 -)" = "$(printf "master new\r\nx")" &&
test "$(printf x | cat subdir/file3 -)" = "$(printf "master new sub\r\nx")" &&
+ git submodule update -N &&
+ test "$(cat submod/bar)" = "master submodule" &&
git commit -m "branch1 resolved with mergetool - autocrlf" &&
git config core.autocrlf false &&
git reset --hard
@@ -83,6 +113,7 @@ test_expect_success 'mergetool crlf' '
test_expect_success 'mergetool in subdir' '
git checkout -b test3 branch1 &&
+ git submodule update -N &&
(
cd subdir &&
test_must_fail git merge master >/dev/null 2>&1 &&
@@ -98,18 +129,22 @@ test_expect_success 'mergetool on file in parent dir' '
( yes "" | git mergetool ../file2 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool ../file11 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool ../file12 >/dev/null 2>&1 ) &&
+ ( yes "l" | git mergetool ../submod >/dev/null 2>&1 ) &&
test "$(cat ../file1)" = "master updated" &&
test "$(cat ../file2)" = "master new" &&
+ test "$(cat ../submod/bar)" = "branch1 submodule" &&
git commit -m "branch1 resolved with mergetool - subdir"
)
'
test_expect_success 'mergetool skips autoresolved' '
git checkout -b test4 branch1 &&
+ git submodule update -N &&
test_must_fail git merge master &&
test -n "$(git ls-files -u)" &&
( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
+ ( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
output="$(git mergetool --no-prompt)" &&
test "$output" = "No files need merging" &&
git reset --hard
@@ -120,10 +155,13 @@ test_expect_success 'mergetool merges all from subdir' '
cd subdir &&
git config rerere.enabled false &&
test_must_fail git merge master &&
+ ( yes "r" | git mergetool ../submod ) &&
( yes "d" "d" | git mergetool --no-prompt ) &&
test "$(cat ../file1)" = "master updated" &&
test "$(cat ../file2)" = "master new" &&
test "$(cat file3)" = "master new sub" &&
+ ( cd .. && git submodule update -N ) &&
+ test "$(cat ../submod/bar)" = "master submodule" &&
git commit -m "branch2 resolved by mergetool from subdir"
)
'
@@ -132,11 +170,257 @@ test_expect_success 'mergetool skips resolved paths when rerere is active' '
git config rerere.enabled true &&
rm -rf .git/rr-cache &&
git checkout -b test5 branch1
+ git submodule update -N &&
test_must_fail git merge master >/dev/null 2>&1 &&
+ ( yes "l" | git mergetool --no-prompt submod >/dev/null 2>&1 ) &&
( yes "d" "d" | git mergetool --no-prompt >/dev/null 2>&1 ) &&
+ git submodule update -N &&
output="$(yes "n" | git mergetool --no-prompt)" &&
test "$output" = "No files need merging" &&
git reset --hard
'
+test_expect_success 'deleted vs modified submodule' '
+ git checkout -b test6 branch1 &&
+ git submodule update -N &&
+ mv submod submod-movedaside &&
+ git rm submod &&
+ git commit -m "Submodule deleted from branch" &&
+ git checkout -b test6.a test6 &&
+ test_must_fail git merge master &&
+ test -n "$(git ls-files -u)" &&
+ ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+ ( yes "r" | git mergetool submod ) &&
+ rmdir submod && mv submod-movedaside submod &&
+ test "$(cat submod/bar)" = "branch1 submodule" &&
+ git submodule update -N &&
+ test "$(cat submod/bar)" = "master submodule" &&
+ output="$(git mergetool --no-prompt)" &&
+ test "$output" = "No files need merging" &&
+ git commit -m "Merge resolved by keeping module" &&
+
+ mv submod submod-movedaside &&
+ git checkout -b test6.b test6 &&
+ git submodule update -N &&
+ test_must_fail git merge master &&
+ test -n "$(git ls-files -u)" &&
+ ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+ ( yes "l" | git mergetool submod ) &&
+ test ! -e submod &&
+ output="$(git mergetool --no-prompt)" &&
+ test "$output" = "No files need merging" &&
+ git commit -m "Merge resolved by deleting module" &&
+
+ mv submod-movedaside submod &&
+ git checkout -b test6.c master &&
+ git submodule update -N &&
+ test_must_fail git merge test6 &&
+ test -n "$(git ls-files -u)" &&
+ ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+ ( yes "r" | git mergetool submod ) &&
+ test ! -e submod &&
+ test -d submod.orig &&
+ git submodule update -N &&
+ output="$(git mergetool --no-prompt)" &&
+ test "$output" = "No files need merging" &&
+ git commit -m "Merge resolved by deleting module" &&
+ mv submod.orig submod &&
+
+ git checkout -b test6.d master &&
+ git submodule update -N &&
+ test_must_fail git merge test6 &&
+ test -n "$(git ls-files -u)" &&
+ ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+ ( yes "l" | git mergetool submod ) &&
+ test "$(cat submod/bar)" = "master submodule" &&
+ git submodule update -N &&
+ test "$(cat submod/bar)" = "master submodule" &&
+ output="$(git mergetool --no-prompt)" &&
+ test "$output" = "No files need merging" &&
+ git commit -m "Merge resolved by keeping module" &&
+ git reset --hard HEAD
+'
+
+test_expect_success 'file vs modified submodule' '
+ git checkout -b test7 branch1 &&
+ git submodule update -N &&
+ mv submod submod-movedaside &&
+ git rm submod &&
+ echo not a submodule >submod &&
+ git add submod &&
+ git commit -m "Submodule path becomes file" &&
+ git checkout -b test7.a branch1 &&
+ test_must_fail git merge master &&
+ test -n "$(git ls-files -u)" &&
+ ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+ ( yes "r" | git mergetool submod ) &&
+ rmdir submod && mv submod-movedaside submod &&
+ test "$(cat submod/bar)" = "branch1 submodule" &&
+ git submodule update -N &&
+ test "$(cat submod/bar)" = "master submodule" &&
+ output="$(git mergetool --no-prompt)" &&
+ test "$output" = "No files need merging" &&
+ git commit -m "Merge resolved by keeping module" &&
+
+ mv submod submod-movedaside &&
+ git checkout -b test7.b test7 &&
+ test_must_fail git merge master &&
+ test -n "$(git ls-files -u)" &&
+ ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+ ( yes "l" | git mergetool submod ) &&
+ git submodule update -N &&
+ test "$(cat submod)" = "not a submodule" &&
+ output="$(git mergetool --no-prompt)" &&
+ test "$output" = "No files need merging" &&
+ git commit -m "Merge resolved by keeping file" &&
+
+ git checkout -b test7.c master &&
+ rmdir submod && mv submod-movedaside submod &&
+ test ! -e submod.orig &&
+ git submodule update -N &&
+ test_must_fail git merge test7 &&
+ test -n "$(git ls-files -u)" &&
+ ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+ ( yes "r" | git mergetool submod ) &&
+ test -d submod.orig &&
+ git submodule update -N &&
+ test "$(cat submod)" = "not a submodule" &&
+ output="$(git mergetool --no-prompt)" &&
+ test "$output" = "No files need merging" &&
+ git commit -m "Merge resolved by keeping file" &&
+
+ git checkout -b test7.d master &&
+ rmdir submod && mv submod.orig submod &&
+ git submodule update -N &&
+ test_must_fail git merge test7 &&
+ test -n "$(git ls-files -u)" &&
+ ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
+ ( yes "l" | git mergetool submod ) &&
+ test "$(cat submod/bar)" = "master submodule" &&
+ git submodule update -N &&
+ test "$(cat submod/bar)" = "master submodule" &&
+ output="$(git mergetool --no-prompt)" &&
+ test "$output" = "No files need merging" &&
+ git commit -m "Merge resolved by keeping module"
+'
+
+test_expect_success 'submodule in subdirectory' '
+ git checkout -b test10 branch1 &&
+ git submodule update -N &&
+ (
+ cd subdir &&
+ test_create_repo subdir_module &&
+ (
+ cd subdir_module &&
+ : >file15 &&
+ git add file15 &&
+ git commit -m "add initial versions"
+ )
+ ) &&
+ git submodule add git://example.com/subsubmodule subdir/subdir_module &&
+ git add subdir/subdir_module &&
+ git commit -m "add submodule in subdirectory" &&
+
+ git checkout -b test10.a test10 &&
+ git submodule update -N &&
+ (
+ cd subdir/subdir_module &&
+ git checkout -b super10.a &&
+ echo test10.a >file15 &&
+ git add file15 &&
+ git commit -m "on branch 10.a"
+ ) &&
+ git add subdir/subdir_module &&
+ git commit -m "change submodule in subdirectory on test10.a" &&
+
+ git checkout -b test10.b test10 &&
+ git submodule update -N &&
+ (
+ cd subdir/subdir_module &&
+ git checkout -b super10.b &&
+ echo test10.b >file15 &&
+ git add file15 &&
+ git commit -m "on branch 10.b"
+ ) &&
+ git add subdir/subdir_module &&
+ git commit -m "change submodule in subdirectory on test10.b" &&
+
+ test_must_fail git merge test10.a >/dev/null 2>&1 &&
+ (
+ cd subdir &&
+ ( yes "l" | git mergetool subdir_module )
+ ) &&
+ test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
+ git submodule update -N &&
+ test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
+ git reset --hard &&
+ git submodule update -N &&
+
+ test_must_fail git merge test10.a >/dev/null 2>&1 &&
+ ( yes "r" | git mergetool subdir/subdir_module ) &&
+ test "$(cat subdir/subdir_module/file15)" = "test10.b" &&
+ git submodule update -N &&
+ test "$(cat subdir/subdir_module/file15)" = "test10.a" &&
+ git commit -m "branch1 resolved with mergetool" &&
+ rm -rf subdir/subdir_module
+'
+
+test_expect_success 'directory vs modified submodule' '
+ git checkout -b test11 branch1 &&
+ mv submod submod-movedaside &&
+ git rm submod &&
+ mkdir submod &&
+ echo not a submodule >submod/file16 &&
+ git add submod/file16 &&
+ git commit -m "Submodule path becomes directory" &&
+
+ test_must_fail git merge master &&
+ test -n "$(git ls-files -u)" &&
+ ( yes "l" | git mergetool submod ) &&
+ test "$(cat submod/file16)" = "not a submodule" &&
+ rm -rf submod.orig &&
+
+ git reset --hard &&
+ test_must_fail git merge master &&
+ test -n "$(git ls-files -u)" &&
+ test ! -e submod.orig &&
+ ( yes "r" | git mergetool submod ) &&
+ test -d submod.orig &&
+ test "$(cat submod.orig/file16)" = "not a submodule" &&
+ rm -r submod.orig &&
+ mv submod-movedaside/.git submod &&
+ ( cd submod && git clean -f && git reset --hard ) &&
+ git submodule update -N &&
+ test "$(cat submod/bar)" = "master submodule" &&
+ git reset --hard && rm -rf submod-movedaside &&
+
+ git checkout -b test11.c master &&
+ git submodule update -N &&
+ test_must_fail git merge test11 &&
+ test -n "$(git ls-files -u)" &&
+ ( yes "l" | git mergetool submod ) &&
+ git submodule update -N &&
+ test "$(cat submod/bar)" = "master submodule" &&
+
+ git reset --hard &&
+ git submodule update -N &&
+ test_must_fail git merge test11 &&
+ test -n "$(git ls-files -u)" &&
+ test ! -e submod.orig &&
+ ( yes "r" | git mergetool submod ) &&
+ test "$(cat submod/file16)" = "not a submodule" &&
+
+ git reset --hard master &&
+ ( cd submod && git clean -f && git reset --hard ) &&
+ git submodule update -N
+'
+
test_done
diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh
index d3a51e126..e2896cffc 100755
--- a/t/t8002-blame.sh
+++ b/t/t8002-blame.sh
@@ -8,7 +8,7 @@ PROG='git blame -c'
PROG='git blame -c -e'
test_expect_success 'Blame --show-email works' '
- check_count "<A@test.git>" 1 "<B@test.git>" 1 "<B1@test.git>" 1 "<B2@test.git>" 1 "<author@example.com>" 1 "<C@test.git>" 1 "<D@test.git>" 1
+ check_count "<A@test.git>" 1 "<B@test.git>" 1 "<B1@test.git>" 1 "<B2@test.git>" 1 "<author@example.com>" 1 "<C@test.git>" 1 "<D@test.git>" 1 "<E at test dot git>" 1
'
test_done
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 5d477e4bd..cf4c05261 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -60,6 +60,21 @@ test_expect_success 'test ascending revision range' "
git svn log -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r1-r2-r4 -
"
+test_expect_success 'test ascending revision range with --show-commit' "
+ git reset --hard trunk &&
+ git svn log --show-commit -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | test_cmp expected-range-r1-r2-r4 -
+ "
+
+test_expect_success 'test ascending revision range with --show-commit (sha1)' "
+ git svn find-rev r1 >expected-range-r1-r2-r4-sha1 &&
+ git svn find-rev r2 >>expected-range-r1-r2-r4-sha1 &&
+ git svn find-rev r4 >>expected-range-r1-r2-r4-sha1 &&
+ git reset --hard trunk &&
+ git svn log --show-commit -r 1:4 | grep '^r[0-9]' | cut -d'|' -f2 >out &&
+ git rev-parse \$(cat out) >actual &&
+ test_cmp expected-range-r1-r2-r4-sha1 actual
+ "
+
printf 'r4 \nr2 \nr1 \n' > expected-range-r4-r2-r1
test_expect_success 'test descending revision range' "
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 763b9c55a..a3fe16d2b 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -89,6 +89,9 @@ esac
_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
+# Zero SHA-1
+_z40=0000000000000000000000000000000000000000
+
# Each test should start with something like this, after copyright notices:
#
# test_description='Description of this test...
diff --git a/test-run-command.c b/test-run-command.c
index 0612bfa7c..37918e15f 100644
--- a/test-run-command.c
+++ b/test-run-command.c
@@ -29,6 +29,8 @@ int main(int argc, char **argv)
fprintf(stderr, "FAIL %s\n", argv[1]);
return 1;
}
+ if (!strcmp(argv[1], "run-command"))
+ exit(run_command(&proc));
fprintf(stderr, "check usage\n");
return 1;
diff --git a/transport.c b/transport.c
index a02f79aae..69dae7110 100644
--- a/transport.c
+++ b/transport.c
@@ -156,7 +156,7 @@ static void set_upstreams(struct transport *transport, struct ref *refs,
continue;
if (!ref->peer_ref)
continue;
- if (!ref->new_sha1 || is_null_sha1(ref->new_sha1))
+ if (is_null_sha1(ref->new_sha1))
continue;
/* Follow symbolic refs (mainly for HEAD). */
diff --git a/upload-pack.c b/upload-pack.c
index bba053f0a..ce5cbbea6 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -157,15 +157,8 @@ static void create_pack_file(void)
const char *argv[10];
int arg = 0;
- if (shallow_nr) {
- memset(&rev_list, 0, sizeof(rev_list));
- rev_list.proc = do_rev_list;
- rev_list.out = -1;
- if (start_async(&rev_list))
- die("git upload-pack: unable to fork git-rev-list");
- argv[arg++] = "pack-objects";
- } else {
- argv[arg++] = "pack-objects";
+ argv[arg++] = "pack-objects";
+ if (!shallow_nr) {
argv[arg++] = "--revs";
if (create_full_pack)
argv[arg++] = "--all";
@@ -183,7 +176,7 @@ static void create_pack_file(void)
argv[arg++] = NULL;
memset(&pack_objects, 0, sizeof(pack_objects));
- pack_objects.in = shallow_nr ? rev_list.out : -1;
+ pack_objects.in = -1;
pack_objects.out = -1;
pack_objects.err = -1;
pack_objects.git_cmd = 1;
@@ -192,8 +185,14 @@ static void create_pack_file(void)
if (start_command(&pack_objects))
die("git upload-pack: unable to fork git-pack-objects");
- /* pass on revisions we (don't) want */
- if (!shallow_nr) {
+ if (shallow_nr) {
+ memset(&rev_list, 0, sizeof(rev_list));
+ rev_list.proc = do_rev_list;
+ rev_list.out = pack_objects.in;
+ if (start_async(&rev_list))
+ die("git upload-pack: unable to fork git-rev-list");
+ }
+ else {
FILE *pipe_fd = xfdopen(pack_objects.in, "w");
if (!create_full_pack) {
int i;
diff --git a/vcs-svn/trp.txt b/vcs-svn/trp.txt
index 5ca6b42ed..177ebca33 100644
--- a/vcs-svn/trp.txt
+++ b/vcs-svn/trp.txt
@@ -96,7 +96,7 @@ node_type *foo_search(struct trp_root \*treap, node_type \*key)::
node_type *foo_nsearch(struct trp_root \*treap, node_type \*key)::
- Like `foo_search`, but if if the key is missing return what
+ Like `foo_search`, but if the key is missing return what
would be key's successor, were key in treap (NULL if no
successor).
diff --git a/xdiff-interface.c b/xdiff-interface.c
index 164581f87..0e2c16922 100644
--- a/xdiff-interface.c
+++ b/xdiff-interface.c
@@ -347,7 +347,7 @@ int git_xmerge_style = -1;
int git_xmerge_config(const char *var, const char *value, void *cb)
{
- if (!strcasecmp(var, "merge.conflictstyle")) {
+ if (!strcmp(var, "merge.conflictstyle")) {
if (!value)
die("'%s' is not a boolean", var);
if (!strcmp(value, "diff3"))