Compare commits

...

77 Commits

Author SHA1 Message Date
341e7e8eda Git 2.0.1
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-25 12:21:11 -07:00
62bfd831bc Merge branch 'na/no-http-test-in-the-middle' into maint
The mode to run tests with HTTP server tests disabled was broken.

* na/no-http-test-in-the-middle:
  t5538: move http push tests out to t5542
2014-06-25 11:50:13 -07:00
287a8701f6 Merge branch 'jl/status-added-submodule-is-never-ignored' into maint
"git status" (and "git commit") behaved as if changes in a modified
submodule are not there if submodule.*.ignore configuration is set,
which was misleading.  The configuration is only to unclutter diff
output during the course of development, and should not to hide
changes in the "status" output to cause the users forget to commit
them.

* jl/status-added-submodule-is-never-ignored:
  commit -m: commit staged submodules regardless of ignore config
  status/commit: show staged submodules regardless of ignore config
2014-06-25 11:50:03 -07:00
1881d2b88c Merge branch 'ym/fix-opportunistic-index-update-race' into maint
"git status", even though it is a read-only operation, tries to
update the index with refreshed lstat(2) info to optimize future
accesses to the working tree opportunistically, but this could
race with a "read-write" operation that modify the index while it
is running.  Detect such a race and avoid overwriting the index.

* ym/fix-opportunistic-index-update-race:
  read-cache.c: verify index file before we opportunistically update it
  wrapper.c: add xpread() similar to xread()
2014-06-25 11:49:48 -07:00
85785df6d6 Merge branch 'mk/show-s-no-extra-blank-line-for-merges' into maint
"git show -s" (i.e. show log message only) used to incorrectly emit
an extra blank line after a merge commit.

* mk/show-s-no-extra-blank-line-for-merges:
  git-show: fix 'git show -s' to not add extra terminator after merge commit
2014-06-25 11:49:39 -07:00
d9036cd28c Merge branch 'rr/rebase-autostash-fix' into maint
The autostash mode of "git rebase -i" did not restore the dirty
working tree state if the user aborted the interactive rebase by
emptying the insn sheet.

* rr/rebase-autostash-fix:
  rebase -i: test "Nothing to do" case with autostash
  rebase -i: handle "Nothing to do" case with autostash
2014-06-25 11:49:31 -07:00
8675779454 Merge branch 'jc/shortlog-ref-exclude' into maint
"git log --exclude=<glob> --all | git shortlog" worked as expected,
but "git shortlog --exclude=<glob> --all", which is supposed to be
identical to the above pipeline, was not accepted at the command
line argument parser level.

* jc/shortlog-ref-exclude:
  shortlog: allow --exclude=<glob> to be passed
2014-06-25 11:49:11 -07:00
c4f79d13b9 Merge branch 'jl/remote-rm-prune' into maint
"git remote rm" and "git remote prune" can involve removing many
refs at once, which is not a very efficient thing to do when very
many refs exist in the packed-refs file.

* jl/remote-rm-prune:
  remote prune: optimize "dangling symref" check/warning
  remote: repack packed-refs once when deleting multiple refs
  remote rm: delete remote configuration as the last
2014-06-25 11:49:01 -07:00
ada8710e63 Merge branch 'fc/rerere-conflict-style' into maint
"git rerere forget" did not work well when merge.conflictstyle
was set to a non-default value.

* fc/rerere-conflict-style:
  rerere: fix for merge.conflictstyle
2014-06-25 11:48:54 -07:00
5327207e0f Merge branch 'rs/pack-objects-no-unnecessary-realloc' into maint
"git pack-objects" unnecessarily copied the previous contents when
extending the hashtable, even though it will populate the table
from scratch anyway.

* rs/pack-objects-no-unnecessary-realloc:
  pack-objects: use free()+xcalloc() instead of xrealloc()+memset()
2014-06-25 11:48:43 -07:00
5fa38cc3a4 Merge branch 'dt/merge-recursive-case-insensitive' into maint
On a case insensitive filesystem, merge-recursive incorrectly
deleted the file that is to be renamed to a name that is the same
except for case differences.

* dt/merge-recursive-case-insensitive:
  mv: allow renaming to fix case on case insensitive filesystems
  merge-recursive.c: fix case-changing merge bug
2014-06-25 11:48:34 -07:00
ed5d0d2105 Merge branch 'rs/mailinfo-header-cmp' into maint
"git mailinfo" used to read beyond the end of header string while
parsing an incoming e-mail message to extract the patch.

* rs/mailinfo-header-cmp:
  mailinfo: use strcmp() for string comparison
2014-06-25 11:48:23 -07:00
182c3d69e4 Merge branch 'jk/index-pack-report-missing' into maint
The error reporting from "git index-pack" has been improved to
distinguish missing objects from type errors.

* jk/index-pack-report-missing:
  index-pack: distinguish missing objects from type errors
2014-06-25 11:48:14 -07:00
a9041df7ab Merge branch 'nd/index-pack-one-fd-per-thread' into maint
We used to disable threaded "git index-pack" on platforms without
thread-safe pread(); use a different workaround for such
platforms to allow threaded "git index-pack".

* nd/index-pack-one-fd-per-thread:
  index-pack: work around thread-unsafe pread()
2014-06-25 11:47:58 -07:00
75b1b04c63 Merge branch 'sk/spawn-less-case-insensitively-from-grep-O-i' into maint
"git grep -O" to show the lines that hit in the pager did not work
well with case insensitive search.  We now spawn "less" with its
"-I" option when it is used as the pager (which is the default).

* sk/spawn-less-case-insensitively-from-grep-O-i:
  git grep -O -i: if the pager is 'less', pass the '-I' option
2014-06-25 11:47:49 -07:00
94c734a607 Merge branch 'nd/daemonize-gc' into maint
"git gc --auto" was recently changed to run in the background to
give control back early to the end-user sitting in front of the
terminal, but it forgot that housekeeping involving reflogs should
be done without other processes competing for accesses to the refs.

* nd/daemonize-gc:
  gc --auto: do not lock refs in the background
2014-06-25 11:47:36 -07:00
cb4575fb18 Merge branch 'jk/diff-follow-must-take-one-pathspec' into maint
"git format-patch" did not enforce the rule that the "--follow"
option from the log/diff family of commands must be used with
exactly one pathspec.

* jk/diff-follow-must-take-one-pathspec:
  move "--follow needs one pathspec" rule to diff_setup_done
2014-06-25 11:47:23 -07:00
11aae3e1c1 Merge branch 'jk/diff-files-assume-unchanged' into maint
"git diff --find-copies-harder" sometimes pretended as if the mode
bits have changed for paths that are marked with assume-unchanged
bit.

* jk/diff-files-assume-unchanged:
  run_diff_files: do not look at uninitialized stat data
2014-06-25 11:47:09 -07:00
b659f81085 Merge branch 'jk/commit-C-pick-empty' into maint
"git commit --allow-empty-message -C $commit" did not work when the
commit did not have any log message.

* jk/commit-C-pick-empty:
  commit: do not complain of empty messages from -C
2014-06-25 11:46:54 -07:00
4d27d8cbc4 Merge branch 'bc/blame-crlf-test' into maint
"git blame" assigned the blame to the copy in the working-tree if
the repository is set to core.autocrlf=input and the file used CRLF
line endings.

* bc/blame-crlf-test:
  blame: correctly handle files regardless of autocrlf
2014-06-25 11:46:45 -07:00
6bf84263b3 Merge branch 'jx/blame-align-relative-time' into maint
"git blame" miscounted number of columns needed to show localized
timestamps, resulting in jaggy left-side-edge of the source code
lines in its output.

* jx/blame-align-relative-time:
  blame: dynamic blame_date_width for different locales
  blame: fix broken time_buf paddings in relative timestamp
2014-06-25 11:46:34 -07:00
c122c9a968 Merge branch 'jc/apply-ignore-whitespace' into maint
"--ignore-space-change" option of "git apply" ignored the spaces
at the beginning of line too aggressively, which is inconsistent
with the option of the same name "diff" and "git diff" have.

* jc/apply-ignore-whitespace:
  apply --ignore-space-change: lines with and without leading whitespaces do not match
2014-06-25 11:46:23 -07:00
ff7e96b78f Merge branch 'jk/complete-merge-pull' into maint
The completion scripts (in contrib/) did not know about quite a few
options that are common between "git merge" and "git pull", and a
couple of options unique to "git merge".

* jk/complete-merge-pull:
  completion: add missing options for git-merge
  completion: add a note that merge options are shared
2014-06-25 11:46:12 -07:00
fbfdf13b5c Merge branch 'ow/config-mailmap-pathname' into maint
The "mailmap.file" configuration option did not support the tilde
expansion (i.e. ~user/path and ~/path).

* ow/config-mailmap-pathname:
  config: respect '~' and '~user' in mailmap.file
2014-06-25 11:45:55 -07:00
ad5d893907 Merge branch 'as/pretty-truncate' into maint
The "%<(10,trunc)%s" pretty format specifier in the log family of
commands is used to truncate the string to a given length (e.g. 10
in the example) with padding to column-align the output, but did
not take into account that number of bytes and number of display
columns are different.

* as/pretty-truncate:
  pretty.c: format string with truncate respects logOutputEncoding
  t4205, t6006: add tests that fail with i18n.logOutputEncoding set
  t4205 (log-pretty-format): use `tformat` rather than `format`
  t4041, t4205, t6006, t7102: don't hardcode tested encoding value
  t4205 (log-pretty-formats): don't hardcode SHA-1 in expected outputs
2014-06-25 11:45:32 -07:00
91043fc95c Merge branch 'jc/revision-dash-count-parsing' into maint
"git log -2master" is a common typo that shows two commits starting
from whichever random branch that is not 'master' that happens to
be checked out currently.

* jc/revision-dash-count-parsing:
  revision: parse "git log -<count>" more carefully
2014-06-25 11:44:53 -07:00
81bd9b1000 Merge branch 'jk/report-fail-to-read-objects-better' into maint
Reworded the error message given upon a failure to open an existing
loose object file due to e.g. permission issues; it was reported as
the object being corrupt, but that is not quite true.

* jk/report-fail-to-read-objects-better:
  open_sha1_file: report "most interesting" errno
2014-06-25 11:43:58 -07:00
73505ef7a5 Merge branch 'mn/sideband-no-ansi' into maint
Tools that read diagnostic output in our standard error stream do
not want to see terminal control sequence (e.g. erase-to-eol).
Detect them by checking if the standard error stream is connected
to a tty.

* mn/sideband-no-ansi:
  sideband.c: do not use ANSI control sequence on non-terminal
2014-06-25 11:43:43 -07:00
e293c563b0 Merge branch 'je/pager-do-not-recurse' into maint
We used to unconditionally disable the pager in the pager process
we spawn to feed out output, but that prevented people who want to
run "less" within "less" from doing so.

* je/pager-do-not-recurse:
  pager: do allow spawning pager recursively
2014-06-25 11:43:07 -07:00
9a597edc83 Merge branch 'jc/rev-parse-argh-dashed-multi-words' into maint
* jc/rev-parse-argh-dashed-multi-words:
  update-index: fix segfault with missing --cacheinfo argument
2014-06-12 12:17:57 -07:00
8f92c7755e pull: do not abuse 'break' inside a shell 'case'
It is not C. The code would break under mksh when 'pull.ff' is set:

  $ git pull
  /usr/lib/git-core/git-pull[67]: break: can't break
  Already up-to-date.

Signed-off-by: Jacek Konieczny <jajcus@jajcus.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-12 12:15:49 -07:00
e3fa568cb3 revision: parse "git log -<count>" more carefully
This mistyped command line simply ignores "master" and ends up
showing two commits from the current HEAD:

    $ git log -2master

because we feed "2master" to atoi() without making sure that the
whole string is parsed as an integer.

Use the strtol_i() helper function instead.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-09 14:53:49 -07:00
eb077745a4 shortlog: allow --exclude=<glob> to be passed
These two commands are supposed to be equivalent:

  $ git log --exclude=refs/notes/\* --all --no-merges --since=2.days |
    git shortlog
  $ git shortlog --exclude=refs/notes/\* --all --no-merges --since=2.days

However, the latter does not understand the ref-exclusion command
line option, even though other options understood by "log", such as
"--all" and "--no-merges", are understood.

This was because e7b432c5 (revision: introduce --exclude=<glob> to
tame wildcards, 2013-08-30) did not wire the new option fully to the
machinery.  A new option understood by handle_revision_pseudo_opt()
must be told to handle_revision_opt() as well.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-04 13:41:33 -07:00
c8e1ee4f2c update-index: fix segfault with missing --cacheinfo argument
Running "git update-index --cacheinfo" without any further
arguments results in a segfault rather than an error
message. Commit ec160ae (update-index: teach --cacheinfo a
new syntax "mode,sha1,path", 2014-03-23) added code to
examine the format of the argument, but forgot to handle the
NULL case.

Returning an error from the parser is enough, since we then
treat it as an old-style "--cacheinfo <mode> <sha1> <path>",
and complain that we have less than 3 arguments to read.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-04 11:02:55 -07:00
fb79947487 pack-objects: use free()+xcalloc() instead of xrealloc()+memset()
Whenever the hash table becomes too small then its size is increased,
the original part (and the added space) is zerod out using memset(),
and the table is rebuilt from scratch.

Simplify this proceess by returning the old memory using free() and
allocating the new buffer using xcalloc(), which already clears the
buffer for us.  That way we avoid copying the old hash table contents
needlessly inside xrealloc().

While at it, use the first array member with sizeof instead of a
specific type.  The old code used uint32_t and int, while index is
actually an array of int32_t.  Their sizes are the same basically
everywhere, so it's not actually a problem, but the new code is
cleaner and doesn't have to be touched should the type be changed.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-02 13:51:22 -07:00
b1a013dd6a mailinfo: use strcmp() for string comparison
The array header is defined as:

	static const char *header[MAX_HDR_PARSED] = {
	     "From","Subject","Date",
	};

When looking for the index of a specfic string in that array, simply
use strcmp() instead of memcmp().  This avoids running over the end of
the string (e.g. with memcmp("Subject", "From", 7)) and gets rid of
magic string length constants.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-02 13:30:18 -07:00
38de156a05 sideband.c: do not use ANSI control sequence on non-terminal
Diagnostic messages received on the sideband #2 from the server side
are sent to the standard error with ANSI terminal control sequence
"\033[K" that erases to the end of line appended at the end of each
line.

However, some programs (e.g. GitExtensions for Windows) read and
interpret and/or show the message without understanding the terminal
control sequences, resulting them to be shown to their end users.
To help these programs, squelch the control sequence when the
standard error stream is not being sent to a tty.

NOTE: I considered to cover the case that a pager has already been
started. But decided that is probably not worth worrying about here,
though, as we shouldn't be using a pager for commands that do network
communications (and if we do, omitting the magic line-clearing signal
is probably a sane thing to do).

Thanks-to: Erik Faye-Lund <kusmabite@gmail.com>
Thanks-to: Jeff King <peff@peff.net>
Signed-off-by: Michael Naumov <mnaoumov@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-02 11:02:27 -07:00
afa53fe5d1 t5538: move http push tests out to t5542
As 0232852b, but for the push tests instead: this avoids a start_httpd
in the middle of the file, which fails under GIT_TEST_HTTPD=false.

Note that we have to munge the test in a few ways while
moving it:

  1. We drop the `test -z "$GIT_TEST_HTTPD"` check; this is
     too simplistic since 83d842d, and we should let
     lib-httpd.sh handle it.

  2. We have to port over some of the old setup from t5538.

  3. In the final test, we no longer expect the extra commit
     "1" built on top of "4". This was a side effect from an
     earlier test in t5538 which was not ported over.

Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-30 11:13:45 -07:00
bce14aa132 Sync with 1.9.4 2014-05-30 10:57:52 -07:00
34d5217584 Git 1.9.4
This is expected to be the final maintenance release for 1.9 series,
merging the remaining fixes that are relevant and are already in 2.0.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-30 10:13:41 -07:00
d717282532 t5537: re-drop http tests
These were originally removed by 0232852 (t5537: move
http tests out to t5539, 2014-02-13). However, they were
accidentally re-added in 1ddb4d7 (Merge branch
'nd/upload-pack-shallow', 2014-03-21).

This looks like an error in manual conflict resolution.
Here's what happened:

  1. v1.9.0 shipped with the http tests in t5537.

  2. We realized that this caused problems, and built
     0232852 on top to move the tests to their own file.
     This fix made it into v1.9.1.

  3. We later had another fix in nd/upload-pack-shallow that
     also touched t5537. It was built directly on v1.9.0.

When we merged nd/upload-pack-shallow to master, we got a
conflict; it was built on a version with the http tests, but
we had since removed them. The correct resolution was to
drop the http tests and keep the new ones, but instead we
kept everything.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-30 09:46:19 -07:00
12188a8299 Merge branch 'rh/prompt-pcmode-avoid-eval-on-refname' into maint
* rh/prompt-pcmode-avoid-eval-on-refname:
  git-prompt.sh: don't assume the shell expands the value of PS1
2014-05-28 15:46:36 -07:00
64d8c31ebe Merge branch 'mw/symlinks' into maint
* mw/symlinks:
  setup: fix windows path buffer over-stepping
  setup: don't dereference in-tree symlinks for absolute paths
  setup: add abspath_part_inside_repo() function
  t0060: add tests for prefix_path when path begins with work tree
  t0060: add test for prefix_path when path == work tree
  t0060: add test for prefix_path on symlinks via absolute paths
  t3004: add test for ls-files on symlinks via absolute paths
2014-05-28 15:45:57 -07:00
9352fd5708 config: respect '~' and '~user' in mailmap.file
git_config_string() does not handle '~' and '~user' as part of the
value. Using git_config_pathname() fixes this.

Signed-off-by: Øystein Walle <oystwa@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 12:59:32 -07:00
62aad1849f gc --auto: do not lock refs in the background
9f673f9 (gc: config option for running --auto in background -
2014-02-08) puts "gc --auto" in background to reduce user's wait
time. Part of the garbage collecting is pack-refs and pruning
reflogs. These require locking some refs and may abort other processes
trying to lock the same ref. If gc --auto is fired in the middle of a
script, gc's holding locks in the background could fail the script,
which could never happen before 9f673f9.

Keep running pack-refs and "reflog --prune" in foreground to stop
parallel ref updates. The remaining background operations (repack,
prune and rerere) should not impact running git processes.

Reported-by: Adam Borowski <kilobyte@angband.pl>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 12:33:53 -07:00
e6bea66db6 remote prune: optimize "dangling symref" check/warning
When 'git remote prune' was used to delete many refs in a repository
with many refs, a lot of time was spent checking for (now) dangling
symbolic refs pointing to the deleted ref, since warn_dangling_symref()
was once per deleted ref to check all other refs in the repository.

Avoid this using the new warn_dangling_symrefs() function which
makes one pass over all refs and checks for all the deleted refs in
one go, after they have all been deleted.

Signed-off-by: Jens Lindström <jl@opera.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 12:30:47 -07:00
c9e768bb77 remote: repack packed-refs once when deleting multiple refs
When 'git remote rm' or 'git remote prune' were used in a repository
with many refs, and needed to delete many remote-tracking refs, a lot
of time was spent deleting those refs since for each deleted ref,
repack_without_refs() was called to rewrite packed-refs without just
that deleted ref.

To avoid this, call repack_without_refs() first to repack without all
the refs that will be deleted, before calling delete_ref() to delete
each one completely.  The call to repack_without_ref() in delete_ref()
then becomes a no-op, since packed-refs already won't contain any of
the deleted refs.

Signed-off-by: Jens Lindström <jl@opera.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 12:30:42 -07:00
8fee872647 completion: add missing options for git-merge
The options added to __git_merge_options are those that git-pull passes
to git-merge, since that variable is used by both commands.

Those added directly in _git_merge() are specific to git-merge and
are not passed thru from git-pull.

Reported-by: Haralan Dobrev <hkdobrev@gmail.com>
Signed-off-by: John Keeping <john@keeping.me.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 12:27:50 -07:00
6d2b06f02b completion: add a note that merge options are shared
This should avoid future confusion after a subsequent patch has added
some options to __git_merge_options and some directly in _git_merge().

Signed-off-by: John Keeping <john@keeping.me.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 12:27:36 -07:00
b07bdd3472 remote rm: delete remote configuration as the last
When removing a remote, delete the remote-tracking branches before
deleting the remote configuration.  This way, if the operation fails or
is aborted while deleting the remote-tracking branches, the command can
be rerun to complete the operation.

Signed-off-by: Jens Lindström <jl@opera.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-23 11:56:15 -07:00
7d509878b8 pretty.c: format string with truncate respects logOutputEncoding
Pretty format string %<(N,[ml]trunc)>%s truncates subject to a given
length with an appropriate padding. This works for non-ASCII texts when
i18n.logOutputEncoding is UTF-8 only (independently of a printed commit
message encoding) but does not work when i18n.logOutputEncoding is NOT
UTF-8.

In 7e77df3 (pretty: two phase conversion for non utf-8 commits, 2013-04-19)
'format_commit_item' function assumes commit message to be in UTF-8.
And that was so until ecaee80 (pretty: --format output should honor
logOutputEncoding, 2013-06-26) where conversion to logOutputEncoding was
added before calling 'format_commit_message'.

Correct this by converting a commit message to UTF-8 first (as it
assumed in 7e77df3 (pretty: two phase conversion for non utf-8 commits,
2013-04-19)). Only after that convert a commit message to an actual
logOutputEncoding.

Signed-off-by: Alexey Shumkin <Alex.Crezoff@gmail.com>
Reviewed-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-21 11:13:30 -07:00
d928d81051 t4205, t6006: add tests that fail with i18n.logOutputEncoding set
Pretty format string %<(N,[ml]trunc)>%s truncates subject to a given
length with an appropriate padding. This works for non-ASCII texts when
i18n.logOutputEncoding is UTF-8 only (independently of a printed commit
message encoding) but does not work when i18n.logOutputEncoding is NOT
UTF-8.

There were no breakages as far as were no tests for the case
when both a commit message and logOutputEncoding are not UTF-8.

Add failing tests for that which will be fixed in the next patch.

Signed-off-by: Alexey Shumkin <Alex.Crezoff@gmail.com>
Helped-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Helped-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-21 11:11:50 -07:00
c82134a9f3 t4205 (log-pretty-format): use tformat rather than format
Use `tformat` to avoid using of `echo` to complete end of line.

Signed-off-by: Alexey Shumkin <Alex.Crezoff@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-21 11:10:10 -07:00
ee3efaf66c t4041, t4205, t6006, t7102: don't hardcode tested encoding value
The tested encoding is always available in a variable. Use it instead of
hardcoding. Also, to be in line with other tests use ISO8859-1
(uppercase) rather then iso8859-1.

Signed-off-by: Alexey Shumkin <Alex.Crezoff@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-21 11:10:06 -07:00
ddb5432d23 rebase -i: test "Nothing to do" case with autostash
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-20 11:33:49 -07:00
dd63f169d9 move "--follow needs one pathspec" rule to diff_setup_done
Because of the way "--follow" is implemented, we must have
exactly one pathspec. "git log" enforces this restriction,
but other users of the revision traversal code do not. For
example, "git format-patch --follow" will segfault during
try_to_follow_renames, as we have no pathspecs at all.

We can push this check down into diff_setup_done, which is
probably a better place anyway. It is the diff code that
introduces this restriction, so other parts of the code
should not need to care themselves.

Reported-by: "Michael S. Tsirkin" <mst@redhat.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-20 11:09:03 -07:00
e4244eb395 rebase -i: handle "Nothing to do" case with autostash
When a user invokes

  $ git rebase -i @~3

with dirty files and rebase.autostash turned on, and exits the $EDITOR
with an empty buffer, the autostash fails to apply. Although the primary
focus of rr/rebase-autostash was to get the git-rebase--backend.sh
scripts to return control to git-rebase.sh, it missed this case in
git-rebase--interactive.sh. Since this case is unlike the other cases
which return control for housekeeping, assign it a special return status
and handle that return value explicitly in git-rebase.sh.

Reported-by: Karen Etheridge <ether@cpan.org>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-19 15:36:24 -07:00
496a69802b t4205 (log-pretty-formats): don't hardcode SHA-1 in expected outputs
The expected SHA-1 digests are always available in variables. Use
them instead of hardcoding.

That was introduced in a742f2a (t4205 (log-pretty-formats): don't
hardcode SHA-1 in expected outputs, 2013-06-26) but unfortunately was
not followed in 5e1361c (log: properly handle decorations with chained
tags, 2013-12-17)

Signed-off-by: Alexey Shumkin <Alex.Crezoff@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-19 11:24:46 -07:00
f7febbea07 git grep -O -i: if the pager is 'less', pass the '-I' option
When <command> happens to be the magic string "less", today

	git grep -O<command> -e<pattern>

helpfully passes +/<pattern> to less so you can navigate through
the results within a file using the n and shift+n keystrokes.

Alas, that doesn't do the right thing for a case-insensitive match,
i.e.

	git grep -i -O<command> -e<pattern>

For that case we should pass --IGNORE-CASE to "less" so that n and
shift+n can move between results ignoring case in the pattern.

The original patch came from msysgit and used "-i", but that was not
due to lack of support for "-I" but it merely overlooked that it
ought to work even when the pattern contains capital letters.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Stepan Kasal <kasal@ucw.cz>
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-15 12:49:23 -07:00
d6c8a05bd5 open_sha1_file: report "most interesting" errno
When we try to open a loose object file, we first attempt to
open in the local object database, and then try any
alternates. This means that the errno value when we return
will be from the last place we looked (and due to the way
the code is structured, simply ENOENT if we do not have have
any alternates).

This can cause confusing error messages, as read_sha1_file
checks for ENOENT when reporting a missing object. If errno
is something else, we report that. If it is ENOENT, but
has_loose_object reports that we have it, then we claim the
object is corrupted. For example:

    $ chmod 0 .git/objects/??/*
    $ git rev-list --all
    fatal: loose object b2d6fab18b92d49eac46dc3c5a0bcafabda20131 (stored in .git/objects/b2/d6fab18b92d49eac46dc3c5a0bcafabda20131) is corrupt

This patch instead keeps track of the "most interesting"
errno we receive during our search. We consider ENOENT to be
the least interesting of all, and otherwise report the first
error found (so problems in the object database take
precedence over ones in alternates). Here it is with this
patch:

    $ git rev-list --all
    fatal: failed to read object b2d6fab18b92d49eac46dc3c5a0bcafabda20131: Permission denied

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-15 10:03:06 -07:00
5304810044 run_diff_files: do not look at uninitialized stat data
If we try to diff an index entry marked CE_VALID (because it
was marked with --assume-unchanged), we do not bother even
running stat() on the file to see if it was removed. This
started long ago with 540e694 (Prevent diff machinery from
examining assume-unchanged entries on worktree, 2009-08-11).

However, the subsequent code may look at our "struct stat"
and expect to find actual data; currently it will find
whatever cruft was left on the stack. This can cause
problems in two situations:

  1. We call match_stat_with_submodule with the stat data,
     so a submodule may be erroneously marked as changed.

  2. If --find-copies-harder is in effect, we pass all
     entries, even unchanged ones, to diff_change, so it can
     list them as rename/copy sources. Since we found no
     change, we assume that function will realize it and not
     actually display any diff output. However, we end up
     feeding it a bogus mode, leading it to sometimes claim
     there was a mode change.

We can fix both by splitting the CE_VALID and regular code
paths, and making sure only to look at the stat information
in the latter. Furthermore, we push the declaration of our
"struct stat" down into the code paths that actually set it,
so we cannot accidentally access it uninitialized in future
code.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-15 09:35:33 -07:00
ad2f7255b3 git-show: fix 'git show -s' to not add extra terminator after merge commit
When git show -s is called for merge commit it prints extra newline
after any merge commit. This differs from output for commits with one
parent. Fix it by more thorough checking that diff output is disabled.

The code in question exists since commit 3969cf7db1. The additional
newline is really needed for cases when patch is requested, test
t4013-diff-various.sh contains cases which can demonstrate behavior when
the condition is restricted further.

Tests:

Added merge commit to 'set up a bit of history' case in t7007-show.sh to
cover the fix.

Existing tests are updated to demonstrate the new behaviour.  Earlier,
the tests that used "git show -s --pretty=format:%s", even though
"--pretty=format:%s" calls for item separator semantics and does not ask
for the terminating newline after the last item, expected the output to
end with such a newline.  They were relying on the buggy behaviour.  Use
of "--format=%s", which is equivalent to "--pretty=tformat:%s" that asks
for a terminating newline after each item, is a more realistic way to
use the command.

In the test 'merge log messages' the expected data is changed, because
it was explicitly listing the extra newline. Also the msg.nologff and
msg.nolognoff expected files are replaced by one msg.nolog, because they
were diffing because of the bug, and now there should be no difference.

Signed-off-by: Max Kirillov <max@max630.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-15 09:32:08 -07:00
77583e7739 index-pack: distinguish missing objects from type errors
When we fetch a pack that does not contain an object we
expected to receive, we get an error like:

  $ git init --bare tmp.git && cd tmp.git
  $ git fetch ../parent.git
  [...]
  error: Could not read 964953ec7bcc0245cb1d0db4095455edd21a2f2e
  fatal: Failed to traverse parents of commit b8247b40caf6704fe52736cdece6d6aae87471aa
  error: ../parent.git did not send all necessary objects

This comes from the check_everything_connected rev-list. If
we try cloning the same repo (rather than a fetch), we end
up using index-pack's --check-self-contained-and-connected
option instead, which produces output like:

  $ git clone --no-local --bare parent.git tmp.git
  [...]
  fatal: object of unexpected type
  fatal: index-pack failed

Not only is the sha1 missing, but it's a misleading message.
There's no type problem, but rather a missing object
problem; we don't notice the difference because we simply
compare OBJ_BAD != OBJ_BLOB.  Let's provide a different
message for this case:

  $ git clone --no-local --bare parent.git tmp.git
  fatal: did not receive expected object 6b00a8c61ed379d5f925a72c1987c9c52129d364
  fatal: index-pack failed

While we're at it, let's also improve a true type mismatch
error to look like

  fatal: object 6b00a8c61ed379d5f925a72c1987c9c52129d364: expected type blob, got tree

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-12 11:27:50 -07:00
4d4813a52f blame: correctly handle files regardless of autocrlf
If a file contained CRLF line endings in a repository with
core.autocrlf=input, then blame always marked lines as "Not
Committed Yet", even if they were unmodified.  Don't attempt to
convert the line endings when creating the fake commit so that blame
works correctly regardless of the autocrlf setting.

Reported-by: Ephrim Khong <dr.khong@gmail.com>
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-08 14:43:49 -07:00
baa37bff9a mv: allow renaming to fix case on case insensitive filesystems
"git mv hello.txt Hello.txt" on a case insensitive filesystem
always triggers "destination already exists" error, because these
two names refer to the same path from the filesystem's point of
view, and requires the user to give "--force" when correcting the
case of the path recorded in the index and in the next commit.

Detect this case and allow it without requiring "--force".

Signed-off-by: David Turner <dturner@twitter.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-08 14:34:00 -07:00
ae352c7f37 merge-recursive.c: fix case-changing merge bug
On a case-insensitive filesystem, when merging, a file would be
wrongly deleted from the working tree if an incoming commit had
renamed it changing only its case.  When merging a rename, the file
with the old name would be deleted -- but since the filesystem
considers the old name to be the same as the new name, the new
file would in fact be deleted.

We avoid this by not deleting files that have a case-clone in the
index at stage 0.

Signed-off-by: David Turner <dturner@twitter.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-07 13:53:10 -07:00
de3d8bb773 rerere: fix for merge.conflictstyle
If we use a different conflict style `git rerere forget` is not able
to find the matching conflict SHA-1 because the diff generated is
actually different from what `git merge` generated, due to the
XDL_MERGE_* option differences among the codepaths.

The fix is to call git_xmerge_config() so that git_xmerge_style is set
properly and the diffs match.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-30 10:30:02 -07:00
c0459ca4dc pager: do allow spawning pager recursively
This reverts commit 88e8f908f2, which
tried to allow

    GIT_PAGER="git -p column --mode='dense color'" git -p branch

and still wanted to avoid "git -p column" to invoke itself.  However,
this falls into "don't do that -p then" category.

In particular, inside "git log", with results going through less, a
potentially interesting commit may be found and from there inside
"less", the user may want to execute "git show <commit>".  Before
the commit being reverted, this used to show the patch in less but
it no longer does.

Signed-off-by: Jörn Engel <joern@logfs.org>
Reviewed-by: Jeff King <peff@peff.net>
Reviewed-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Acked-by: Duy Nguyen <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-28 16:03:22 -07:00
076cbd6341 commit: do not complain of empty messages from -C
When we pick another commit's message, we die() immediately
if we find that it's empty and we are not going to run an
editor (i.e., when running "-C" instead of "-c").  However,
this check is redundant and harmful.

It's redundant because we will already notice the empty
message later, after we would have run the editor, and die
there (just as we would for a regular, not "-C" case, where
the user provided an empty message in the editor).

It's harmful for a few reasons:

  1. It does not respect --allow-empty-message. As a result,
     a "git rebase -i" cannot "pick" such a commit. So you
     cannot even go back in time to fix it with a "reword"
     or "edit" instruction.

  2. It does not take into account other ways besides the
     editor to modify the message. For example, "git commit
     -C empty-commit -m foo" could take the author
     information from empty-commit, but add a message to it.
     There's more to do to make that work correctly (and
     right now we explicitly forbid "-C with -m"), but this
     removes one roadblock.

  3. The existing check is not enough to prevent segfaults.
     We try to find the "\n\n" header/body boundary in the
     commit. If it is at the end of the string (i.e., no
     body), _or_ if we cannot find it at all (i.e., a
     truncated commit object), we consider the message
     empty. With "-C", that's OK; we die in either case. But
     with "-c", we continue on, and in the case of a
     truncated commit may end up dereferencing NULL+2.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-28 09:58:09 -07:00
dd75553b35 blame: dynamic blame_date_width for different locales
When show date in relative date format for git-blame, the max display
width of datetime is set as the length of the string "Thu Oct 19
16:00:04 2006 -0700" (30 characters long).  But actually the max width
for C locale is only 22 (the length of string "x years, xx months ago").
And for other locale, it maybe smaller.  E.g. For Chinese locale, only
needs a half (16-character width).

Set blame_date_width as the display width of _("4 years, 11 months
ago"), so that translators can make the choice.

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-23 00:02:15 -07:00
bccce0f809 blame: fix broken time_buf paddings in relative timestamp
Command `git blame --date relative` aligns the date field with a
fixed-width (defined by blame_date_width), and if time_str is shorter
than that, it adds spaces for padding.  But there are two bugs in the
following codes:

        time_len = strlen(time_str);
        ...
        memset(time_buf + time_len, ' ', blame_date_width - time_len);

 1. The type of blame_date_width is size_t, which is unsigned.  If
    time_len is greater than blame_date_width, the result of
    "blame_date_width - time_len" will never be a negative number, but a
    really big positive number, and will cause memory overwrite.

    This bug can be triggered if either l10n message for function
    show_date_relative() in date.c is longer than 30 characters, then
    `git blame --date relative` may exit abnormally.

 2. When show blame information with relative time, the UTF-8 characters
    in time_str will break the alignment of columns after the date field.
    This is because the time_buf padding with spaces should have a
    constant display width, not a fixed strlen size.  So we should call
    utf8_strwidth() instead of strlen() for width calibration.

Helped-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-23 00:01:52 -07:00
39539495ac index-pack: work around thread-unsafe pread()
Multi-threaing of index-pack was disabled with c0f8654
(index-pack: Disable threading on cygwin - 2012-06-26), because
pread() implementations for Cygwin and MSYS were not thread
safe.  Recent Cygwin does offer usable pread() and we enabled
multi-threading with 103d530f (Cygwin 1.7 has thread-safe pread,
2013-07-19).

Work around this problem on platforms with a thread-unsafe
pread() emulation by opening one file handle per thread; it
would prevent parallel pread() on different file handles from
stepping on each other.

Also remove NO_THREAD_SAFE_PREAD that was introduced in c0f8654
because it's no longer used anywhere.

This workaround is unconditional, even for platforms with
thread-safe pread() because the overhead is small (a couple file
handles more) and not worth fragmenting the code.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Tested-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-16 09:29:41 -07:00
426ddeead6 read-cache.c: verify index file before we opportunistically update it
Before we proceed to opportunistically update the index (often done
by an otherwise read-only operation like "git status" and "git diff"
that internally refreshes the index), we must verify that the
current index file is the same as the one that we read earlier
before we took the lock on it, in order to avoid a possible race.

In the example below git-status does "opportunistic update" and
git-rebase updates the index, but the race can happen in general.

  1. process A calls git-rebase (or does anything that uses the index)

  2. process A applies 1st commit

  3. process B calls git-status (or does anything that updates the index)

  4. process B reads index

  5. process A applies 2nd commit

  6. process B takes the lock, then overwrites process A's changes.

  7. process A applies 3rd commit

As an end result the 3rd commit will have a revert of the 2nd commit.
When process B takes the lock, it needs to make sure that the index
hasn't changed since step 4.

Signed-off-by: Yiannis Marangos <yiannis.marangos@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-10 12:27:58 -07:00
9aa91af036 wrapper.c: add xpread() similar to xread()
It is a common mistake to call read(2)/pread(2) and forget to
anticipate that they may return error with EAGAIN/EINTR when the
system call is interrupted.

We have xread() helper to relieve callers of read(2) from having to
worry about it; add xpread() helper to do the same for pread(2).

Update the caller in the builtin/index-pack.c and the mmap emulation
in compat/.

Signed-off-by: Yiannis Marangos <yiannis.marangos@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-10 12:18:55 -07:00
c215d3d282 commit -m: commit staged submodules regardless of ignore config
The previous commit fixed the problem that the staged but that ignored
submodules did not show up in the status output of the commit command and
weren't committed afterwards either. But when commit doesn't generate the
status output (e.g. when used in a script with '-m') the ignored submodule
will still not be committed. This is because in that case a different code
path is taken which calls index_differs_from() instead of calling the
wt_status functions.

Fix that by calling index_differs_from() from builtin/commit.c with a
diff_options argument value that tells it not ignore any submodule changes
unless the '--ignore-submodules' option is used. Even though this option
isn't yet implemented for cmd_commit() but only for cmd_status() this
prepares cmd_commit() to correctly handle the '--ignore-submodules' option
later. As status and commit share the same ignore_submodule_arg variable
this makes the code more robust against accidental breakage and documents
how to correctly call index_differs_from().

Change the expected result of the test documenting this problem from
failure to success.

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-07 10:42:35 -07:00
1d2f393ac9 status/commit: show staged submodules regardless of ignore config
Currently setting submodule.<name>.ignore and/or diff.ignoreSubmodules to
"all" suppresses all output of submodule changes for the diff family,
status and commit. For status and commit this is really confusing, as it
even when the user chooses to record a new commit for an ignored submodule
by adding it manually this change won't show up under the to-be-committed
changes. To add insult to injury, a later "git commit" will error out with
"nothing to commit" when only ignored submodules are staged.

Fix that by making wt_status always print staged submodule changes, no
matter what ignore settings are configured. The only exception is when the
user explicitly uses the "--ignore-submodules=all" command line option, in
that case the submodule output is still suppressed. This also makes "git
commit" work again when only modifications of ignored submodules are
staged, as that command uses the "commitable" member of the wt_status
struct to determine if staged changes are present. But this only happens
when the commit command uses the wt_status* functions to produce status
output for human consumption (when forking an editor or with --dry-run),
in all other cases (e.g. when run in a script with '-m') another code path
is taken which uses index_differs_from() to determine if any changes are
staged which still ignores submodules according to their configuration.
This will be fixed in a follow-up commit.

Change t7508 to reflect this new behavior and add three new tests to show
that a single staged submodule configured to be ignored will be committed
when the status output is generated and won't be if not. Also update the
documentation of the ignore config options accordingly.

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-04-07 10:32:20 -07:00
14d3bb4955 apply --ignore-space-change: lines with and without leading whitespaces do not match
The fuzzy_matchlines() function is used when attempting to resurrect
a patch that is whitespace-damaged, or when applying a patch that
was produced against an old codebase to the codebase after
indentation change.

The patch may want to change a line "a_bc" ("_" is used throught
this description for a whitespace to make it stand out) in the
original into something else, and we may not find "a_bc" in the
current source, but there may be "a__bc" (two spaces instead of one
the whitespace-damaged patch claims to expect).  By ignoring the
amount of whitespaces, it forces "git apply" to consider that "a_bc"
in the broken patch meant to refer to "a__bc" in reality.

However, the implementation special cases a run of whitespaces at
the beginning of a line and makes "abc" match "_abc", even though a
whitespace in the middle of string never matches a 0-width gap,
e.g. "a_bc" does not match "abc".  A run of whitespace at the end of
one string does not match a 0-width end of line on the other line,
either, e.g. "abc_" does not match "abc".

Fix this inconsistency by making the code skip leading whitespaces
only when both strings begin with a whitespace.  This makes the
option mean the same as the option of the same name in "diff" and
"git diff".

Note that I am not sure if anybody sane should use this option in
the first place.  The fuzzy match logic may be able to find the
original line that the patch author may have meant to touch because
it does not fully trust what the original lines say (i.e. context
lines prefixed by " " and old lines prefixed by "-" does not have to
exactly match the contents the patch is applied to).  There is no
reason for us to trust what the replacement lines (i.e. new lines
prefixed by "+") say, either, but with this option enabled, we end
up copying these new lines with suspicious whitespace distributions
literally into the patched result.  But as long as we keep it, we
should make it do its insane thing consistently.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-03-26 14:02:33 -07:00
63 changed files with 1047 additions and 283 deletions

View File

@ -0,0 +1,16 @@
Git v1.9.4 Release Notes
========================
Fixes since v1.9.3
------------------
* Commands that take pathspecs on the command line misbehaved when
the pathspec is given as an absolute pathname (which is a
practice not particularly encouraged) that points at a symbolic
link in the working tree.
* An earlier fix to the shell prompt script (in contrib/) for using
the PROMPT_COMMAND interface did not correctly check if the extra
code path needs to trigger, causing the branch name not to appear
when 'promptvars' option is disabled in bash or PROMPT_SUBST is
unset in zsh.

View File

@ -0,0 +1,115 @@
Git v2.0.1 Release Notes
========================
* We used to unconditionally disable the pager in the pager process
we spawn to feed out output, but that prevented people who want to
run "less" within "less" from doing so.
* Tools that read diagnostic output in our standard error stream do
not want to see terminal control sequence (e.g. erase-to-eol).
Detect them by checking if the standard error stream is connected
to a tty.
* Reworded the error message given upon a failure to open an existing
loose object file due to e.g. permission issues; it was reported as
the object being corrupt, but that is not quite true.
* "git log -2master" is a common typo that shows two commits starting
from whichever random branch that is not 'master' that happens to
be checked out currently.
* The "%<(10,trunc)%s" pretty format specifier in the log family of
commands is used to truncate the string to a given length (e.g. 10
in the example) with padding to column-align the output, but did
not take into account that number of bytes and number of display
columns are different.
* The "mailmap.file" configuration option did not support the tilde
expansion (i.e. ~user/path and ~/path).
* The completion scripts (in contrib/) did not know about quite a few
options that are common between "git merge" and "git pull", and a
couple of options unique to "git merge".
* "--ignore-space-change" option of "git apply" ignored the spaces
at the beginning of line too aggressively, which is inconsistent
with the option of the same name "diff" and "git diff" have.
* "git blame" miscounted number of columns needed to show localized
timestamps, resulting in jaggy left-side-edge of the source code
lines in its output.
* "git blame" assigned the blame to the copy in the working-tree if
the repository is set to core.autocrlf=input and the file used CRLF
line endings.
* "git commit --allow-empty-message -C $commit" did not work when the
commit did not have any log message.
* "git diff --find-copies-harder" sometimes pretended as if the mode
bits have changed for paths that are marked with assume-unchanged
bit.
* "git format-patch" did not enforce the rule that the "--follow"
option from the log/diff family of commands must be used with
exactly one pathspec.
* "git gc --auto" was recently changed to run in the background to
give control back early to the end-user sitting in front of the
terminal, but it forgot that housekeeping involving reflogs should
be done without other processes competing for accesses to the refs.
* "git grep -O" to show the lines that hit in the pager did not work
well with case insensitive search. We now spawn "less" with its
"-I" option when it is used as the pager (which is the default).
* We used to disable threaded "git index-pack" on platforms without
thread-safe pread(); use a different workaround for such
platforms to allow threaded "git index-pack".
* The error reporting from "git index-pack" has been improved to
distinguish missing objects from type errors.
* "git mailinfo" used to read beyond the end of header string while
parsing an incoming e-mail message to extract the patch.
* On a case insensitive filesystem, merge-recursive incorrectly
deleted the file that is to be renamed to a name that is the same
except for case differences.
* "git pack-objects" unnecessarily copied the previous contents when
extending the hashtable, even though it will populate the table
from scratch anyway.
* "git rerere forget" did not work well when merge.conflictstyle
was set to a non-default value.
* "git remote rm" and "git remote prune" can involve removing many
refs at once, which is not a very efficient thing to do when very
many refs exist in the packed-refs file.
* "git log --exclude=<glob> --all | git shortlog" worked as expected,
but "git shortlog --exclude=<glob> --all", which is supposed to be
identical to the above pipeline, was not accepted at the command
line argument parser level.
* The autostash mode of "git rebase -i" did not restore the dirty
working tree state if the user aborted the interactive rebase by
emptying the insn sheet.
* "git show -s" (i.e. show log message only) used to incorrectly emit
an extra blank line after a merge commit.
* "git status", even though it is a read-only operation, tries to
update the index with refreshed lstat(2) info to optimize future
accesses to the working tree opportunistically, but this could
race with a "read-write" operation that modify the index while it
is running. Detect such a race and avoid overwriting the index.
* "git status" (and "git commit") behaved as if changes in a modified
submodule are not there if submodule.*.ignore configuration is set,
which was misleading. The configuration is only to unclutter diff
output during the course of development, and should not to hide
changes in the "status" output to cause the users forget to commit
them.
* The mode to run tests with HTTP server tests disabled was broken.

View File

@ -2293,7 +2293,9 @@ status.submodulesummary::
--summary-limit option of linkgit:git-submodule[1]). Please note
that the summary output command will be suppressed for all
submodules when `diff.ignoreSubmodules` is set to 'all' or only
for those submodules where `submodule.<name>.ignore=all`. To
for those submodules where `submodule.<name>.ignore=all`. The only
exception to that rule is that status and commit will show staged
submodule changes. To
also view the summary for ignored submodules you can either use
the --ignore-submodules=dirty command line option or the 'git
submodule summary' command, which shows a similar output but does
@ -2324,7 +2326,9 @@ submodule.<name>.fetchRecurseSubmodules::
submodule.<name>.ignore::
Defines under what circumstances "git status" and the diff family show
a submodule as modified. When set to "all", it will never be considered
modified, "dirty" will ignore all changes to the submodules work tree and
modified (but it will nonetheless show up in the output of status and
commit when it has been staged), "dirty" will ignore all changes
to the submodules work tree and
takes only differences between the HEAD of the submodule and the commit
recorded in the superproject into account. "untracked" will additionally
let submodules with modified tracked files in their work tree show up.

View File

@ -43,14 +43,16 @@ unreleased) version of Git, that is available from 'master'
branch of the `git.git` repository.
Documentation for older releases are available here:
* link:v2.0.0/git.html[documentation for release 2.0]
* link:v2.0.1/git.html[documentation for release 2.0.1]
* release notes for
link:RelNotes/2.0.1.txt[2.0.1],
link:RelNotes/2.0.0.txt[2.0.0].
* link:v1.9.3/git.html[documentation for release 1.9.3]
* link:v1.9.4/git.html[documentation for release 1.9.4]
* release notes for
link:RelNotes/1.9.4.txt[1.9.4],
link:RelNotes/1.9.3.txt[1.9.3],
link:RelNotes/1.9.2.txt[1.9.2],
link:RelNotes/1.9.1.txt[1.9.1],

View File

@ -67,7 +67,9 @@ submodule.<name>.fetchRecurseSubmodules::
submodule.<name>.ignore::
Defines under what circumstances "git status" and the diff family show
a submodule as modified. When set to "all", it will never be considered
modified, "dirty" will ignore all changes to the submodules work tree and
modified (but will nonetheless show up in the output of status and
commit when it has been staged), "dirty" will ignore all changes
to the submodules work tree and
takes only differences between the HEAD of the submodule and the commit
recorded in the superproject into account. "untracked" will additionally
let submodules with modified tracked files in their work tree show up.

View File

@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
DEF_VER=v2.0.0
DEF_VER=v2.0.1
LF='
'

View File

@ -183,9 +183,6 @@ all::
# Define NO_STRUCT_ITIMERVAL if you don't have struct itimerval
# This also implies NO_SETITIMER
#
# Define NO_THREAD_SAFE_PREAD if your pread() implementation is not
# thread-safe. (e.g. compat/pread.c or cygwin)
#
# Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is
# generally faster on your platform than accessing the working directory.
#
@ -1339,10 +1336,6 @@ endif
ifdef NO_PREAD
COMPAT_CFLAGS += -DNO_PREAD
COMPAT_OBJS += compat/pread.o
NO_THREAD_SAFE_PREAD = YesPlease
endif
ifdef NO_THREAD_SAFE_PREAD
BASIC_CFLAGS += -DNO_THREAD_SAFE_PREAD
endif
ifdef NO_FAST_WORKING_DIRECTORY
BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY

View File

@ -1 +1 @@
Documentation/RelNotes/2.0.0.txt
Documentation/RelNotes/2.0.1.txt

View File

@ -300,11 +300,13 @@ static int fuzzy_matchlines(const char *s1, size_t n1,
while ((*last2 == '\r') || (*last2 == '\n'))
last2--;
/* skip leading whitespace */
while (isspace(*s1) && (s1 <= last1))
s1++;
while (isspace(*s2) && (s2 <= last2))
s2++;
/* skip leading whitespaces, if both begin with whitespace */
if (s1 <= last1 && s2 <= last2 && isspace(*s1) && isspace(*s2)) {
while (isspace(*s1) && (s1 <= last1))
s1++;
while (isspace(*s2) && (s2 <= last2))
s2++;
}
/* early return if both lines are empty */
if ((s1 > last1) && (s2 > last2))
return 1;

View File

@ -1556,22 +1556,29 @@ static void assign_blame(struct scoreboard *sb, int opt)
static const char *format_time(unsigned long time, const char *tz_str,
int show_raw_time)
{
static char time_buf[128];
static struct strbuf time_buf = STRBUF_INIT;
strbuf_reset(&time_buf);
if (show_raw_time) {
snprintf(time_buf, sizeof(time_buf), "%lu %s", time, tz_str);
strbuf_addf(&time_buf, "%lu %s", time, tz_str);
}
else {
const char *time_str;
int time_len;
size_t time_width;
int tz;
tz = atoi(tz_str);
time_str = show_date(time, tz, blame_date_mode);
time_len = strlen(time_str);
memcpy(time_buf, time_str, time_len);
memset(time_buf + time_len, ' ', blame_date_width - time_len);
strbuf_addstr(&time_buf, time_str);
/*
* Add space paddings to time_buf to display a fixed width
* string, and use time_width for display width calibration.
*/
for (time_width = utf8_strwidth(time_str);
time_width < blame_date_width;
time_width++)
strbuf_addch(&time_buf, ' ');
}
return time_buf;
return time_buf.buf;
}
#define OUTPUT_ANNOTATE_COMPAT 001
@ -2088,7 +2095,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
if (strbuf_read(&buf, 0, 0) < 0)
die_errno("failed to read from stdin");
}
convert_to_git(path, buf.buf, buf.len, &buf, 0);
origin->file.ptr = buf.buf;
origin->file.size = buf.len;
pretend_sha1_file(buf.buf, buf.len, OBJ_BLOB, origin->blob_sha1);
@ -2331,7 +2337,14 @@ parse_done:
blame_date_width = sizeof("2006-10-19");
break;
case DATE_RELATIVE:
/* "normal" is used as the fallback for "relative" */
/* TRANSLATORS: This string is used to tell us the maximum
display width for a relative timestamp in "git blame"
output. For C locale, "4 years, 11 months ago", which
takes 22 places, is the longest among various forms of
relative timestamps, but your language may need more or
fewer display columns. */
blame_date_width = utf8_strwidth(_("4 years, 11 months ago")) + 1; /* add the null */
break;
case DATE_LOCAL:
case DATE_NORMAL:
blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700");

View File

@ -650,9 +650,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
} else if (use_message) {
char *buffer;
buffer = strstr(use_message_buffer, "\n\n");
if (!use_editor && (!buffer || buffer[2] == '\0'))
die(_("commit has empty message"));
strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
if (buffer)
strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
hook_arg1 = "commit";
hook_arg2 = use_message;
} else if (fixup_message) {
@ -833,8 +832,22 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
if (get_sha1(parent, sha1))
commitable = !!active_nr;
else
commitable = index_differs_from(parent, 0);
else {
/*
* Unless the user did explicitly request a submodule
* ignore mode by passing a command line option we do
* not ignore any changed submodule SHA-1s when
* comparing index and parent, no matter what is
* configured. Otherwise we won't commit any
* submodules which were manually staged, which would
* be really confusing.
*/
int diff_flags = DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;
if (ignore_submodule_arg &&
!strcmp(ignore_submodule_arg, "all"))
diff_flags |= DIFF_OPT_IGNORE_SUBMODULES;
commitable = index_differs_from(parent, diff_flags);
}
}
strbuf_release(&committer_ident);

View File

@ -26,6 +26,7 @@ static const char * const builtin_gc_usage[] = {
};
static int pack_refs = 1;
static int prune_reflogs = 1;
static int aggressive_depth = 250;
static int aggressive_window = 250;
static int gc_auto_threshold = 6700;
@ -258,6 +259,19 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
return NULL;
}
static int gc_before_repack(void)
{
if (pack_refs && run_command_v_opt(pack_refs_cmd.argv, RUN_GIT_CMD))
return error(FAILED_RUN, pack_refs_cmd.argv[0]);
if (prune_reflogs && run_command_v_opt(reflog.argv, RUN_GIT_CMD))
return error(FAILED_RUN, reflog.argv[0]);
pack_refs = 0;
prune_reflogs = 0;
return 0;
}
int cmd_gc(int argc, const char **argv, const char *prefix)
{
int aggressive = 0;
@ -320,12 +334,15 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
fprintf(stderr, _("Auto packing the repository for optimum performance.\n"));
fprintf(stderr, _("See \"git help gc\" for manual housekeeping.\n"));
}
if (detach_auto)
if (detach_auto) {
if (gc_before_repack())
return -1;
/*
* failure to daemonize is ok, we'll continue
* in foreground
*/
daemonize();
}
} else
add_repack_all_option();
@ -337,11 +354,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
name, (uintmax_t)pid);
}
if (pack_refs && run_command_v_opt(pack_refs_cmd.argv, RUN_GIT_CMD))
return error(FAILED_RUN, pack_refs_cmd.argv[0]);
if (run_command_v_opt(reflog.argv, RUN_GIT_CMD))
return error(FAILED_RUN, reflog.argv[0]);
if (gc_before_repack())
return -1;
if (run_command_v_opt(repack.argv, RUN_GIT_CMD))
return error(FAILED_RUN, repack.argv[0]);

View File

@ -874,6 +874,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (len > 4 && is_dir_sep(pager[len - 5]))
pager += len - 4;
if (opt.ignore_case && !strcmp("less", pager))
string_list_append(&path_list, "-I");
if (!strcmp("less", pager) || !strcmp("vi", pager)) {
struct strbuf buf = STRBUF_INIT;
strbuf_addf(&buf, "+/%s%s",

View File

@ -40,17 +40,13 @@ struct base_data {
int ofs_first, ofs_last;
};
#if !defined(NO_PTHREADS) && defined(NO_THREAD_SAFE_PREAD)
/* pread() emulation is not thread-safe. Disable threading. */
#define NO_PTHREADS
#endif
struct thread_local {
#ifndef NO_PTHREADS
pthread_t thread;
#endif
struct base_data *base_cache;
size_t base_cache_used;
int pack_fd;
};
/*
@ -91,7 +87,8 @@ static off_t consumed_bytes;
static unsigned deepest_delta;
static git_SHA_CTX input_ctx;
static uint32_t input_crc32;
static int input_fd, output_fd, pack_fd;
static int input_fd, output_fd;
static const char *curr_pack;
#ifndef NO_PTHREADS
@ -134,6 +131,7 @@ static inline void unlock_mutex(pthread_mutex_t *mutex)
*/
static void init_thread(void)
{
int i;
init_recursive_mutex(&read_mutex);
pthread_mutex_init(&counter_mutex, NULL);
pthread_mutex_init(&work_mutex, NULL);
@ -141,11 +139,18 @@ static void init_thread(void)
pthread_mutex_init(&deepest_delta_mutex, NULL);
pthread_key_create(&key, NULL);
thread_data = xcalloc(nr_threads, sizeof(*thread_data));
for (i = 0; i < nr_threads; i++) {
thread_data[i].pack_fd = open(curr_pack, O_RDONLY);
if (thread_data[i].pack_fd == -1)
die_errno(_("unable to open %s"), curr_pack);
}
threads_active = 1;
}
static void cleanup_thread(void)
{
int i;
if (!threads_active)
return;
threads_active = 0;
@ -154,6 +159,8 @@ static void cleanup_thread(void)
pthread_mutex_destroy(&work_mutex);
if (show_stat)
pthread_mutex_destroy(&deepest_delta_mutex);
for (i = 0; i < nr_threads; i++)
close(thread_data[i].pack_fd);
pthread_key_delete(key);
free(thread_data);
}
@ -200,8 +207,13 @@ static unsigned check_object(struct object *obj)
if (!(obj->flags & FLAG_CHECKED)) {
unsigned long size;
int type = sha1_object_info(obj->sha1, &size);
if (type != obj->type || type <= 0)
die(_("object of unexpected type"));
if (type <= 0)
die(_("did not receive expected object %s"),
sha1_to_hex(obj->sha1));
if (type != obj->type)
die(_("object %s: expected type %s, found %s"),
sha1_to_hex(obj->sha1),
typename(obj->type), typename(type));
obj->flags |= FLAG_CHECKED;
return 1;
}
@ -288,13 +300,13 @@ static const char *open_pack_file(const char *pack_name)
output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
if (output_fd < 0)
die_errno(_("unable to create '%s'"), pack_name);
pack_fd = output_fd;
nothread_data.pack_fd = output_fd;
} else {
input_fd = open(pack_name, O_RDONLY);
if (input_fd < 0)
die_errno(_("cannot open packfile '%s'"), pack_name);
output_fd = -1;
pack_fd = input_fd;
nothread_data.pack_fd = input_fd;
}
git_SHA1_Init(&input_ctx);
return pack_name;
@ -542,7 +554,7 @@ static void *unpack_data(struct object_entry *obj,
do {
ssize_t n = (len < 64*1024) ? len : 64*1024;
n = pread(pack_fd, inbuf, n, from);
n = xpread(get_thread_data()->pack_fd, inbuf, n, from);
if (n < 0)
die_errno(_("cannot pread pack file"));
if (!n)
@ -1490,7 +1502,7 @@ static void show_pack_info(int stat_only)
int cmd_index_pack(int argc, const char **argv, const char *prefix)
{
int i, fix_thin_pack = 0, verify = 0, stat_only = 0;
const char *curr_pack, *curr_index;
const char *curr_index;
const char *index_name = NULL, *pack_name = NULL;
const char *keep_name = NULL, *keep_msg = NULL;
char *index_name_buf = NULL, *keep_name_buf = NULL;

View File

@ -158,13 +158,9 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
if (rev->show_notes)
init_display_notes(&rev->notes_opt);
if (rev->diffopt.pickaxe || rev->diffopt.filter)
if (rev->diffopt.pickaxe || rev->diffopt.filter ||
DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES))
rev->always_show_header = 0;
if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {
rev->always_show_header = 0;
if (rev->diffopt.pathspec.nr != 1)
usage("git logs can only follow renames on one pathname at a time");
}
if (source)
rev->show_source = 1;

View File

@ -334,7 +334,7 @@ static int check_header(const struct strbuf *line,
}
if (starts_with(line->buf, "[PATCH]") && isspace(line->buf[7])) {
for (i = 0; header[i]; i++) {
if (!memcmp("Subject", header[i], 7)) {
if (!strcmp("Subject", header[i])) {
handle_header(&hdr_data[i], line);
ret = 1;
goto check_header_out;
@ -929,13 +929,13 @@ static void handle_info(void)
else
continue;
if (!memcmp(header[i], "Subject", 7)) {
if (!strcmp(header[i], "Subject")) {
if (!keep_subject) {
cleanup_subject(hdr);
cleanup_space(hdr);
}
output_header_lines(fout, "Subject", hdr);
} else if (!memcmp(header[i], "From", 4)) {
} else if (!strcmp(header[i], "From")) {
cleanup_space(hdr);
handle_from(hdr);
fprintf(fout, "Author: %s\n", name.buf);

View File

@ -203,7 +203,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
}
} else if (cache_name_pos(src, length) < 0)
bad = _("not under version control");
else if (lstat(dst, &st) == 0) {
else if (lstat(dst, &st) == 0 &&
(!ignore_case || strcasecmp(src, dst))) {
bad = _("destination exists");
if (force) {
/*

View File

@ -749,15 +749,23 @@ static int mv(int argc, const char **argv)
static int remove_branches(struct string_list *branches)
{
const char **branch_names;
int i, result = 0;
branch_names = xmalloc(branches->nr * sizeof(*branch_names));
for (i = 0; i < branches->nr; i++)
branch_names[i] = branches->items[i].string;
result |= repack_without_refs(branch_names, branches->nr);
free(branch_names);
for (i = 0; i < branches->nr; i++) {
struct string_list_item *item = branches->items + i;
const char *refname = item->string;
unsigned char *sha1 = item->util;
if (delete_ref(refname, sha1, 0))
if (delete_ref(refname, NULL, 0))
result |= error(_("Could not remove branch %s"), refname);
}
return result;
}
@ -789,10 +797,6 @@ static int rm(int argc, const char **argv)
known_remotes.to_delete = remote;
for_each_remote(add_known_remote, &known_remotes);
strbuf_addf(&buf, "remote.%s", remote->name);
if (git_config_rename_section(buf.buf, NULL) < 1)
return error(_("Could not remove config section '%s'"), buf.buf);
read_branches();
for (i = 0; i < branch_list.nr; i++) {
struct string_list_item *item = branch_list.items + i;
@ -837,6 +841,12 @@ static int rm(int argc, const char **argv)
}
string_list_clear(&skipped, 0);
if (!result) {
strbuf_addf(&buf, "remote.%s", remote->name);
if (git_config_rename_section(buf.buf, NULL) < 1)
return error(_("Could not remove config section '%s'"), buf.buf);
}
return result;
}
@ -1303,6 +1313,8 @@ static int prune_remote(const char *remote, int dry_run)
{
int result = 0, i;
struct ref_states states;
struct string_list delete_refs_list = STRING_LIST_INIT_NODUP;
const char **delete_refs;
const char *dangling_msg = dry_run
? _(" %s will become dangling!")
: _(" %s has become dangling!");
@ -1316,11 +1328,20 @@ static int prune_remote(const char *remote, int dry_run)
states.remote->url_nr
? states.remote->url[0]
: _("(no URL)"));
delete_refs = xmalloc(states.stale.nr * sizeof(*delete_refs));
for (i = 0; i < states.stale.nr; i++)
delete_refs[i] = states.stale.items[i].util;
if (!dry_run)
result |= repack_without_refs(delete_refs, states.stale.nr);
free(delete_refs);
}
for (i = 0; i < states.stale.nr; i++) {
const char *refname = states.stale.items[i].util;
string_list_insert(&delete_refs_list, refname);
if (!dry_run)
result |= delete_ref(refname, NULL, 0);
@ -1330,9 +1351,11 @@ static int prune_remote(const char *remote, int dry_run)
else
printf_ln(_(" * [pruned] %s"),
abbrev_ref(refname, "refs/remotes/"));
warn_dangling_symref(stdout, dangling_msg, refname);
}
warn_dangling_symrefs(stdout, dangling_msg, &delete_refs_list);
string_list_clear(&delete_refs_list, 0);
free_remote_ref_states(&states);
return result;
}

View File

@ -60,6 +60,8 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, rerere_usage, 0);
git_config(git_xmerge_config, NULL);
if (autoupdate == 1)
flags = RERERE_AUTOUPDATE;
if (autoupdate == 0)

View File

@ -637,6 +637,9 @@ static int parse_new_style_cacheinfo(const char *arg,
unsigned long ul;
char *endp;
if (!arg)
return -1;
errno = 0;
ul = strtoul(arg, &endp, 8);
if (errno || endp == arg || *endp != ',' || (unsigned int) ul != ul)

View File

@ -279,6 +279,7 @@ struct index_state {
initialized : 1;
struct hashmap name_hash;
struct hashmap dir_hash;
unsigned char sha1[20];
};
extern struct index_state the_index;
@ -1322,6 +1323,8 @@ extern void fsync_or_die(int fd, const char *);
extern ssize_t read_in_full(int fd, void *buf, size_t count);
extern ssize_t write_in_full(int fd, const void *buf, size_t count);
extern ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset);
static inline ssize_t write_str_in_full(int fd, const char *str)
{
return write_in_full(fd, str, strlen(str));

View File

@ -1339,7 +1339,8 @@ void diff_tree_combined(const unsigned char *sha1,
if (show_log_first && i == 0) {
show_log(rev);
if (rev->verbose_header && opt->output_format)
if (rev->verbose_header && opt->output_format &&
opt->output_format != DIFF_FORMAT_NO_OUTPUT)
printf("%s%c", diff_line_prefix(opt),
opt->line_termination);
}

View File

@ -14,7 +14,7 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of
}
while (n < length) {
ssize_t count = pread(fd, (char *)start + n, length - n, offset + n);
ssize_t count = xpread(fd, (char *)start + n, length - n, offset + n);
if (count == 0) {
memset((char *)start+n, 0, length-n);
@ -22,8 +22,6 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of
}
if (count < 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
free(start);
errno = EACCES;
return MAP_FAILED;

View File

@ -952,7 +952,7 @@ static int git_default_push_config(const char *var, const char *value)
static int git_default_mailmap_config(const char *var, const char *value)
{
if (!strcmp(var, "mailmap.file"))
return git_config_string(&git_mailmap_file, var, value);
return git_config_pathname(&git_mailmap_file, var, value);
if (!strcmp(var, "mailmap.blob"))
return git_config_string(&git_mailmap_blob, var, value);

View File

@ -157,7 +157,6 @@ ifeq ($(uname_O),Cygwin)
NO_SYMLINK_HEAD = YesPlease
NO_IPV6 = YesPlease
OLD_ICONV = UnfortunatelyYes
NO_THREAD_SAFE_PREAD = YesPlease
# There are conflicting reports about this.
# On some boxes NO_MMAP is needed, and not so elsewhere.
# Try commenting this out if you suspect MMAP is more efficient

View File

@ -1472,9 +1472,12 @@ _git_log ()
__git_complete_revlist
}
# Common merge options shared by git-merge(1) and git-pull(1).
__git_merge_options="
--no-commit --no-stat --log --no-log --squash --strategy
--commit --stat --no-squash --ff --no-ff --ff-only --edit --no-edit
--verify-signatures --no-verify-signatures --gpg-sign
--quiet --verbose --progress --no-progress
"
_git_merge ()
@ -1483,7 +1486,8 @@ _git_merge ()
case "$cur" in
--*)
__gitcomp "$__git_merge_options"
__gitcomp "$__git_merge_options
--rerere-autoupdate --no-rerere-autoupdate --abort"
return
esac
__gitcomp_nl "$(__git_refs)"

View File

@ -97,7 +97,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
diff_unmerged_stage = 2;
entries = active_nr;
for (i = 0; i < entries; i++) {
struct stat st;
unsigned int oldmode, newmode;
struct cache_entry *ce = active_cache[i];
int changed;
@ -115,6 +114,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
unsigned int wt_mode = 0;
int num_compare_stages = 0;
size_t path_len;
struct stat st;
path_len = ce_namelen(ce);
@ -195,26 +195,35 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
continue;
/* If CE_VALID is set, don't look at workdir for file removal */
changed = (ce->ce_flags & CE_VALID) ? 0 : check_removed(ce, &st);
if (changed) {
if (changed < 0) {
perror(ce->name);
if (ce->ce_flags & CE_VALID) {
changed = 0;
newmode = ce->ce_mode;
} else {
struct stat st;
changed = check_removed(ce, &st);
if (changed) {
if (changed < 0) {
perror(ce->name);
continue;
}
diff_addremove(&revs->diffopt, '-', ce->ce_mode,
ce->sha1, !is_null_sha1(ce->sha1),
ce->name, 0);
continue;
}
diff_addremove(&revs->diffopt, '-', ce->ce_mode,
ce->sha1, !is_null_sha1(ce->sha1),
ce->name, 0);
continue;
changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
ce_option, &dirty_submodule);
newmode = ce_mode_from_stat(ce, st.st_mode);
}
changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
ce_option, &dirty_submodule);
if (!changed && !dirty_submodule) {
ce_mark_uptodate(ce);
if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
continue;
}
oldmode = ce->ce_mode;
newmode = ce_mode_from_stat(ce, st.st_mode);
diff_change(&revs->diffopt, oldmode, newmode,
ce->sha1, (changed ? null_sha1 : ce->sha1),
!is_null_sha1(ce->sha1), (changed ? 0 : !is_null_sha1(ce->sha1)),

3
diff.c
View File

@ -3325,6 +3325,9 @@ void diff_setup_done(struct diff_options *options)
}
options->diff_path_counter = 0;
if (DIFF_OPT_TST(options, FOLLOW_RENAMES) && options->pathspec.nr != 1)
die(_("--follow requires exactly one pathspec"));
}
static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)

View File

@ -531,6 +531,7 @@ extern void *xcalloc(size_t nmemb, size_t size);
extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
extern ssize_t xread(int fd, void *buf, size_t len);
extern ssize_t xwrite(int fd, const void *buf, size_t len);
extern ssize_t xpread(int fd, void *buf, size_t len, off_t offset);
extern int xdup(int fd);
extern FILE *xfdopen(int fd, const char *mode);
extern int xmkstemp(char *template);

View File

@ -58,11 +58,9 @@ pull_ff=$(git config pull.ff)
case "$pull_ff" in
false)
no_ff=--no-ff
break
;;
only)
ff_only=--ff-only
break
;;
esac

View File

@ -1049,14 +1049,14 @@ fi
has_action "$todo" ||
die_abort "Nothing to do"
return 2
cp "$todo" "$todo".backup
git_sequence_editor "$todo" ||
die_abort "Could not execute editor"
has_action "$todo" ||
die_abort "Nothing to do"
return 2
expand_todo_ids

View File

@ -155,7 +155,7 @@ move_to_original_branch () {
esac
}
finish_rebase () {
apply_autostash () {
if test -f "$state_dir/autostash"
then
stash_sha1=$(cat "$state_dir/autostash")
@ -171,6 +171,10 @@ You can run "git stash pop" or "git stash drop" at any time.
'
fi
fi
}
finish_rebase () {
apply_autostash &&
git gc --auto &&
rm -rf "$state_dir"
}
@ -186,6 +190,11 @@ run_specific_rebase () {
if test $ret -eq 0
then
finish_rebase
elif test $ret -eq 2 # special exit status for rebase -i
then
apply_autostash &&
rm -rf "$state_dir" &&
die "Nothing to do"
fi
exit $ret
}

View File

@ -589,6 +589,12 @@ static int remove_file(struct merge_options *o, int clean,
return -1;
}
if (update_working_directory) {
if (ignore_case) {
struct cache_entry *ce;
ce = cache_file_exists(path, strlen(path), ignore_case);
if (ce && ce_stage(ce) == 0)
return 0;
}
if (remove_path(path))
return -1;
}

View File

@ -47,8 +47,8 @@ static void rehash_objects(struct packing_data *pdata)
if (pdata->index_size < 1024)
pdata->index_size = 1024;
pdata->index = xrealloc(pdata->index, sizeof(uint32_t) * pdata->index_size);
memset(pdata->index, 0, sizeof(int) * pdata->index_size);
free(pdata->index);
pdata->index = xcalloc(pdata->index_size, sizeof(*pdata->index));
entry = pdata->objects;

View File

@ -64,7 +64,7 @@ void setup_pager(void)
{
const char *pager = git_pager(isatty(1));
if (!pager || pager_in_use())
if (!pager)
return;
/*

View File

@ -1506,13 +1506,18 @@ void format_commit_message(const struct commit *commit,
context.commit = commit;
context.pretty_ctx = pretty_ctx;
context.wrap_start = sb->len;
/*
* convert a commit message to UTF-8 first
* as far as 'format_commit_item' assumes it in UTF-8
*/
context.message = logmsg_reencode(commit,
&context.commit_encoding,
output_enc);
utf8);
strbuf_expand(sb, format, format_commit_item, &context);
rewrap_message_tail(sb, &context, 0, 0, 0);
/* then convert a commit message to an actual output encoding */
if (output_enc) {
if (same_encoding(utf8, output_enc))
output_enc = NULL;

View File

@ -1477,6 +1477,7 @@ int read_index_from(struct index_state *istate, const char *path)
if (verify_hdr(hdr, mmap_size) < 0)
goto unmap;
hashcpy(istate->sha1, (unsigned char *)hdr + mmap_size - 20);
istate->version = ntohl(hdr->hdr_version);
istate->cache_nr = ntohl(hdr->hdr_entries);
istate->cache_alloc = alloc_nr(istate->cache_nr);
@ -1760,6 +1761,50 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce,
return result;
}
/*
* This function verifies if index_state has the correct sha1 of the
* index file. Don't die if we have any other failure, just return 0.
*/
static int verify_index_from(const struct index_state *istate, const char *path)
{
int fd;
ssize_t n;
struct stat st;
unsigned char sha1[20];
if (!istate->initialized)
return 0;
fd = open(path, O_RDONLY);
if (fd < 0)
return 0;
if (fstat(fd, &st))
goto out;
if (st.st_size < sizeof(struct cache_header) + 20)
goto out;
n = pread_in_full(fd, sha1, 20, st.st_size - 20);
if (n != 20)
goto out;
if (hashcmp(istate->sha1, sha1))
goto out;
close(fd);
return 1;
out:
close(fd);
return 0;
}
static int verify_index(const struct index_state *istate)
{
return verify_index_from(istate, get_index_file());
}
static int has_racy_timestamp(struct index_state *istate)
{
int entries = istate->cache_nr;
@ -1779,7 +1824,7 @@ static int has_racy_timestamp(struct index_state *istate)
void update_index_if_able(struct index_state *istate, struct lock_file *lockfile)
{
if ((istate->cache_changed || has_racy_timestamp(istate)) &&
!write_index(istate, lockfile->fd))
verify_index(istate) && !write_index(istate, lockfile->fd))
commit_locked_index(lockfile);
else
rollback_lock_file(lockfile);

21
refs.c
View File

@ -1611,6 +1611,7 @@ int peel_ref(const char *refname, unsigned char *sha1)
struct warn_if_dangling_data {
FILE *fp;
const char *refname;
const struct string_list *refnames;
const char *msg_fmt;
};
@ -1625,8 +1626,12 @@ static int warn_if_dangling_symref(const char *refname, const unsigned char *sha
return 0;
resolves_to = resolve_ref_unsafe(refname, junk, 0, NULL);
if (!resolves_to || strcmp(resolves_to, d->refname))
if (!resolves_to
|| (d->refname
? strcmp(resolves_to, d->refname)
: !string_list_has_string(d->refnames, resolves_to))) {
return 0;
}
fprintf(d->fp, d->msg_fmt, refname);
fputc('\n', d->fp);
@ -1639,6 +1644,18 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
data.fp = fp;
data.refname = refname;
data.refnames = NULL;
data.msg_fmt = msg_fmt;
for_each_rawref(warn_if_dangling_symref, &data);
}
void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames)
{
struct warn_if_dangling_data data;
data.fp = fp;
data.refname = NULL;
data.refnames = refnames;
data.msg_fmt = msg_fmt;
for_each_rawref(warn_if_dangling_symref, &data);
}
@ -2431,7 +2448,7 @@ static int curate_packed_ref_fn(struct ref_entry *entry, void *cb_data)
return 0;
}
static int repack_without_refs(const char **refnames, int n)
int repack_without_refs(const char **refnames, int n)
{
struct ref_dir *packed;
struct string_list refs_to_delete = STRING_LIST_INIT_DUP;

3
refs.h
View File

@ -89,6 +89,7 @@ static inline const char *has_glob_specials(const char *pattern)
extern int for_each_rawref(each_ref_fn, void *);
extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname);
extern void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list* refnames);
/*
* Lock the packed-refs file for writing. Flags is passed to
@ -132,6 +133,8 @@ extern void rollback_packed_refs(void);
*/
int pack_refs(unsigned int flags);
extern int repack_without_refs(const char **refnames, int n);
extern int ref_exists(const char *);
/*

View File

@ -1633,6 +1633,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
!strcmp(arg, "--reflog") || !strcmp(arg, "--not") ||
!strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") ||
!strcmp(arg, "--bisect") || starts_with(arg, "--glob=") ||
starts_with(arg, "--exclude=") ||
starts_with(arg, "--branches=") || starts_with(arg, "--tags=") ||
starts_with(arg, "--remotes=") || starts_with(arg, "--no-walk="))
{
@ -1648,8 +1649,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
revs->skip_count = atoi(optarg);
return argcount;
} else if ((*arg == '-') && isdigit(arg[1])) {
/* accept -<digit>, like traditional "head" */
revs->max_count = atoi(arg + 1);
/* accept -<digit>, like traditional "head" */
if (strtol_i(arg + 1, 10, &revs->max_count) < 0 ||
revs->max_count < 0)
die("'%s': not a non-negative integer", arg + 1);
revs->no_walk = 0;
} else if (!strcmp(arg, "-n")) {
if (argc <= 1)

View File

@ -1437,19 +1437,23 @@ static int open_sha1_file(const unsigned char *sha1)
{
int fd;
struct alternate_object_database *alt;
int most_interesting_errno;
fd = git_open_noatime(sha1_file_name(sha1));
if (fd >= 0)
return fd;
most_interesting_errno = errno;
prepare_alt_odb();
errno = ENOENT;
for (alt = alt_odb_list; alt; alt = alt->next) {
fill_sha1_path(alt->name, sha1);
fd = git_open_noatime(alt->base);
if (fd >= 0)
return fd;
if (most_interesting_errno == ENOENT)
most_interesting_errno = errno;
}
errno = most_interesting_errno;
return -1;
}

View File

@ -30,7 +30,7 @@ int recv_sideband(const char *me, int in_stream, int out)
memcpy(buf, PREFIX, pf);
term = getenv("TERM");
if (term && strcmp(term, "dumb"))
if (isatty(2) && term && strcmp(term, "dumb"))
suffix = ANSI_SUFFIX;
else
suffix = DUMB_SUFFIX;

View File

@ -121,7 +121,7 @@ test_expect_success 'merge my-side@{u} records the correct name' '
git branch -D new ;# can fail but is ok
git branch -t new my-side@{u} &&
git merge -s ours new@{u} &&
git show -s --pretty=format:%s >actual &&
git show -s --pretty=tformat:%s >actual &&
echo "Merge remote-tracking branch ${sq}origin/side${sq}" >expect &&
test_cmp expect actual
)

View File

@ -29,6 +29,10 @@ test_expect_success 'update-index -h with corrupt index' '
test_i18ngrep "[Uu]sage: git update-index" broken/usage
'
test_expect_success '--cacheinfo complains of missing arguments' '
test_must_fail git update-index --cacheinfo
'
test_expect_success '--cacheinfo does not accept blob null sha1' '
echo content >file &&
git add file &&

View File

@ -167,4 +167,19 @@ testrebase "" .git/rebase-apply
testrebase " --merge" .git/rebase-merge
testrebase " --interactive" .git/rebase-merge
test_expect_success 'abort rebase -i with --autostash' '
test_when_finished "git reset --hard" &&
echo uncommited-content >file0 &&
(
write_script abort-editor.sh <<-\EOF &&
echo >"$1"
EOF
test_set_editor "$(pwd)/abort-editor.sh" &&
test_must_fail git rebase -i --autostash HEAD^ &&
rm -f abort-editor.sh
) &&
echo uncommited-content >expected &&
test_cmp expected file0
'
test_done

View File

@ -28,4 +28,15 @@ test_expect_success 'diff-files does not examine assume-unchanged entries' '
test -z "$(git diff-files -- one)"
'
test_expect_success POSIXPERM 'find-copies-harder is not confused by mode bits' '
echo content >exec &&
chmod +x exec &&
git add exec &&
git commit -m exec &&
git update-index --assume-unchanged exec &&
>expect &&
git diff-files --find-copies-harder -- exec >actual &&
test_cmp expect actual
'
test_done

View File

@ -11,6 +11,9 @@ This test tries to verify the sanity of the --submodule option of git diff.
. ./test-lib.sh
# Tested non-UTF-8 encoding
test_encoding="ISO8859-1"
# String "added" in German (translated with Google Translate), encoded in UTF-8,
# used in sample commit log messages in add_file() function below.
added=$(printf "hinzugef\303\274gt")
@ -23,8 +26,8 @@ add_file () {
echo "$name" >"$name" &&
git add "$name" &&
test_tick &&
msg_added_iso88591=$(echo "Add $name ($added $name)" | iconv -f utf-8 -t iso8859-1) &&
git -c 'i18n.commitEncoding=iso8859-1' commit -m "$msg_added_iso88591"
msg_added_iso88591=$(echo "Add $name ($added $name)" | iconv -f utf-8 -t $test_encoding) &&
git -c "i18n.commitEncoding=$test_encoding" commit -m "$msg_added_iso88591"
done >/dev/null &&
git rev-parse --short --verify HEAD
)

View File

@ -111,7 +111,6 @@ sed -e 's/T/ /g' > main.c.final <<\EOF
#include <stdio.h>
void print_int(int num);
T/* a comment */
int func(int num);
int main() {
@ -154,7 +153,8 @@ test_expect_success 'patch2 reverse applies with --ignore-space-change' '
git config apply.ignorewhitespace change
test_expect_success 'patch2 applies (apply.ignorewhitespace = change)' '
git apply patch2.patch
git apply patch2.patch &&
test_cmp main.c.final main.c
'
test_expect_success 'patch3 fails (missing string at EOL)' '
@ -165,12 +165,8 @@ test_expect_success 'patch4 fails (missing EOL at EOF)' '
test_must_fail git apply patch4.patch
'
test_expect_success 'patch5 applies (leading whitespace)' '
git apply patch5.patch
'
test_expect_success 'patches do not mangle whitespace' '
test_cmp main.c main.c.final
test_expect_success 'patch5 fails (leading whitespace differences matter)' '
test_must_fail git apply patch5.patch
'
test_expect_success 're-create file (with --ignore-whitespace)' '

View File

@ -188,4 +188,10 @@ test_expect_success 'shortlog ignores commits with missing authors' '
test_cmp expect actual
'
test_expect_success 'shortlog with revision pseudo options' '
git shortlog --all &&
git shortlog --branches &&
git shortlog --exclude=refs/heads/m* --all
'
test_done

View File

@ -7,6 +7,9 @@
test_description='Test pretty formats'
. ./test-lib.sh
# Tested non-UTF-8 encoding
test_encoding="ISO8859-1"
sample_utf8_part=$(printf "f\303\244ng")
commit_msg () {
@ -27,8 +30,8 @@ test_expect_success 'set up basic repos' '
>bar &&
git add foo &&
test_tick &&
git config i18n.commitEncoding iso8859-1 &&
git commit -m "$(commit_msg iso8859-1)" &&
git config i18n.commitEncoding $test_encoding &&
git commit -m "$(commit_msg $test_encoding)" &&
git add bar &&
test_tick &&
git commit -m "add bar" &&
@ -56,8 +59,8 @@ test_expect_success 'alias user-defined format' '
test_cmp expected actual
'
test_expect_success 'alias user-defined tformat with %s (iso8859-1 encoding)' '
git config i18n.logOutputEncoding iso8859-1 &&
test_expect_success 'alias user-defined tformat with %s (ISO8859-1 encoding)' '
git config i18n.logOutputEncoding $test_encoding &&
git log --oneline >expected-s &&
git log --pretty="tformat:%h %s" >actual-s &&
git config --unset i18n.logOutputEncoding &&
@ -141,9 +144,7 @@ test_expect_success 'setup more commits' '
'
test_expect_success 'left alignment formatting' '
git log --pretty="format:%<(40)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%<(40)%s" >actual &&
qz_to_tab_space <<EOF >expected &&
message two Z
message one Z
@ -153,10 +154,19 @@ EOF
test_cmp expected actual
'
test_expect_success 'left alignment formatting. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(40)%s" >actual &&
qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
message two Z
message one Z
add bar Z
$(commit_msg) Z
EOF
test_cmp expected actual
'
test_expect_success 'left alignment formatting at the nth column' '
git log --pretty="format:%h %<|(40)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%h %<|(40)%s" >actual &&
qz_to_tab_space <<EOF >expected &&
$head1 message two Z
$head2 message one Z
@ -166,10 +176,19 @@ EOF
test_cmp expected actual
'
test_expect_success 'left alignment formatting at the nth column. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %<|(40)%s" >actual &&
qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
$head1 message two Z
$head2 message one Z
$head3 add bar Z
$head4 $(commit_msg) Z
EOF
test_cmp expected actual
'
test_expect_success 'left alignment formatting with no padding' '
git log --pretty="format:%<(1)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%<(1)%s" >actual &&
cat <<EOF >expected &&
message two
message one
@ -179,10 +198,19 @@ EOF
test_cmp expected actual
'
test_expect_success 'left alignment formatting with no padding. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(1)%s" >actual &&
cat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
message two
message one
add bar
$(commit_msg)
EOF
test_cmp expected actual
'
test_expect_success 'left alignment formatting with trunc' '
git log --pretty="format:%<(10,trunc)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%<(10,trunc)%s" >actual &&
qz_to_tab_space <<EOF >expected &&
message ..
message ..
@ -192,10 +220,19 @@ EOF
test_cmp expected actual
'
test_expect_success 'left alignment formatting with trunc. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,trunc)%s" >actual &&
qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
message ..
message ..
add bar Z
initial...
EOF
test_cmp expected actual
'
test_expect_success 'left alignment formatting with ltrunc' '
git log --pretty="format:%<(10,ltrunc)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%<(10,ltrunc)%s" >actual &&
qz_to_tab_space <<EOF >expected &&
..sage two
..sage one
@ -205,10 +242,19 @@ EOF
test_cmp expected actual
'
test_expect_success 'left alignment formatting with ltrunc. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,ltrunc)%s" >actual &&
qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
..sage two
..sage one
add bar Z
..${sample_utf8_part}lich
EOF
test_cmp expected actual
'
test_expect_success 'left alignment formatting with mtrunc' '
git log --pretty="format:%<(10,mtrunc)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%<(10,mtrunc)%s" >actual &&
qz_to_tab_space <<EOF >expected &&
mess.. two
mess.. one
@ -218,10 +264,19 @@ EOF
test_cmp expected actual
'
test_expect_success 'left alignment formatting with mtrunc. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,mtrunc)%s" >actual &&
qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
mess.. two
mess.. one
add bar Z
init..lich
EOF
test_cmp expected actual
'
test_expect_success 'right alignment formatting' '
git log --pretty="format:%>(40)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%>(40)%s" >actual &&
qz_to_tab_space <<EOF >expected &&
Z message two
Z message one
@ -231,10 +286,19 @@ EOF
test_cmp expected actual
'
test_expect_success 'right alignment formatting. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%>(40)%s" >actual &&
qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
Z message two
Z message one
Z add bar
Z $(commit_msg)
EOF
test_cmp expected actual
'
test_expect_success 'right alignment formatting at the nth column' '
git log --pretty="format:%h %>|(40)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%h %>|(40)%s" >actual &&
qz_to_tab_space <<EOF >expected &&
$head1 message two
$head2 message one
@ -244,10 +308,19 @@ EOF
test_cmp expected actual
'
test_expect_success 'right alignment formatting at the nth column. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %>|(40)%s" >actual &&
qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
$head1 message two
$head2 message one
$head3 add bar
$head4 $(commit_msg)
EOF
test_cmp expected actual
'
test_expect_success 'right alignment formatting with no padding' '
git log --pretty="format:%>(1)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%>(1)%s" >actual &&
cat <<EOF >expected &&
message two
message one
@ -257,10 +330,19 @@ EOF
test_cmp expected actual
'
test_expect_success 'right alignment formatting with no padding. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%>(1)%s" >actual &&
cat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
message two
message one
add bar
$(commit_msg)
EOF
test_cmp expected actual
'
test_expect_success 'center alignment formatting' '
git log --pretty="format:%><(40)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%><(40)%s" >actual &&
qz_to_tab_space <<EOF >expected &&
Z message two Z
Z message one Z
@ -270,10 +352,18 @@ EOF
test_cmp expected actual
'
test_expect_success 'center alignment formatting. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%><(40)%s" >actual &&
qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
Z message two Z
Z message one Z
Z add bar Z
Z $(commit_msg) Z
EOF
test_cmp expected actual
'
test_expect_success 'center alignment formatting at the nth column' '
git log --pretty="format:%h %><|(40)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%h %><|(40)%s" >actual &&
qz_to_tab_space <<EOF >expected &&
$head1 message two Z
$head2 message one Z
@ -283,10 +373,19 @@ EOF
test_cmp expected actual
'
test_expect_success 'center alignment formatting at the nth column. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %><|(40)%s" >actual &&
qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
$head1 message two Z
$head2 message one Z
$head3 add bar Z
$head4 $(commit_msg) Z
EOF
test_cmp expected actual
'
test_expect_success 'center alignment formatting with no padding' '
git log --pretty="format:%><(1)%s" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%><(1)%s" >actual &&
cat <<EOF >expected &&
message two
message one
@ -296,11 +395,23 @@ EOF
test_cmp expected actual
'
# save HEAD's SHA-1 digest (with no abbreviations) to use it below
# as far as the next test amends HEAD
old_head1=$(git rev-parse --verify HEAD~0)
test_expect_success 'center alignment formatting with no padding. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%><(1)%s" >actual &&
cat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
message two
message one
add bar
$(commit_msg)
EOF
test_cmp expected actual
'
test_expect_success 'left/right alignment formatting with stealing' '
git commit --amend -m short --author "long long long <long@me.com>" &&
git log --pretty="format:%<(10,trunc)%s%>>(10,ltrunc)% an" >actual &&
# complete the incomplete line at the end
echo >>actual &&
git log --pretty="tformat:%<(10,trunc)%s%>>(10,ltrunc)% an" >actual &&
cat <<EOF >expected &&
short long long long
message .. A U Thor
@ -309,6 +420,20 @@ initial... A U Thor
EOF
test_cmp expected actual
'
test_expect_success 'left/right alignment formatting with stealing. i18n.logOutputEncoding' '
git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,trunc)%s%>>(10,ltrunc)% an" >actual &&
cat <<EOF | iconv -f utf-8 -t $test_encoding >expected &&
short long long long
message .. A U Thor
add bar A U Thor
initial... A U Thor
EOF
test_cmp expected actual
'
# get new digests (with no abbreviations)
head1=$(git rev-parse --verify HEAD~0) &&
head2=$(git rev-parse --verify HEAD~1) &&
test_expect_success 'log decoration properly follows tag chain' '
git tag -a tag1 -m tag1 &&
@ -317,9 +442,9 @@ test_expect_success 'log decoration properly follows tag chain' '
git commit --amend -m shorter &&
git log --no-walk --tags --pretty="%H %d" --decorate=full >actual &&
cat <<EOF >expected &&
6a908c10688b2503073c39c9ba26322c73902bb5 (tag: refs/tags/tag2)
9f716384d92283fb915a4eee5073f030638e05f9 (tag: refs/tags/message-one)
b87e4cccdb77336ea79d89224737be7ea8e95367 (tag: refs/tags/message-two)
$head1 (tag: refs/tags/tag2)
$head2 (tag: refs/tags/message-one)
$old_head1 (tag: refs/tags/message-two)
EOF
sort actual >actual1 &&
test_cmp expected actual1

View File

@ -173,33 +173,6 @@ EOF
)
'
if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
say 'skipping remaining tests, git built without http support'
test_done
fi
LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5537'}
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
test_expect_success 'clone http repository' '
git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
git clone $HTTPD_URL/smart/repo.git clone &&
(
cd clone &&
git fsck &&
git log --format=%s origin/master >actual &&
cat <<EOF >expect &&
7
6
5
4
3
EOF
test_cmp expect actual
)
'
test_expect_success POSIXPERM,SANITY 'shallow fetch from a read-only repo' '
cp -R .git read-only.git &&
find read-only.git -print | xargs chmod -w &&
@ -213,5 +186,4 @@ EOF
test_cmp expect actual
'
stop_httpd
test_done

View File

@ -120,63 +120,4 @@ EOF
git cat-file blob `echo 1|git hash-object --stdin` >/dev/null
)
'
if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
say 'skipping remaining tests, git built without http support'
test_done
fi
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
test_expect_success 'push to shallow repo via http' '
git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
(
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
git config http.receivepack true
) &&
(
cd full &&
commit 9 &&
git push $HTTPD_URL/smart/repo.git +master:refs/remotes/top/master
) &&
(
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
git fsck &&
git log --format=%s top/master >actual &&
cat <<EOF >expect &&
9
4
3
EOF
test_cmp expect actual
)
'
test_expect_success 'push from shallow repo via http' '
mv "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" shallow-upstream.git &&
git clone --bare --no-local full "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
(
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
git config http.receivepack true
) &&
commit 10 &&
git push $HTTPD_URL/smart/repo.git +master:refs/remotes/top/master &&
(
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
git fsck &&
git log --format=%s top/master >actual &&
cat <<EOF >expect &&
10
1
4
3
2
1
EOF
test_cmp expect actual
)
'
stop_httpd
test_done

100
t/t5542-push-http-shallow.sh Executable file
View File

@ -0,0 +1,100 @@
#!/bin/sh
test_description='push from/to a shallow clone over http'
. ./test-lib.sh
if test -n "$NO_CURL"; then
say 'skipping test, git built without http support'
test_done
fi
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
commit() {
echo "$1" >tracked &&
git add tracked &&
git commit -m "$1"
}
test_expect_success 'setup' '
git config --global transfer.fsckObjects true &&
commit 1 &&
commit 2 &&
commit 3 &&
commit 4 &&
git clone . full &&
(
git init full-abc &&
cd full-abc &&
commit a &&
commit b &&
commit c
) &&
git clone --no-local --depth=2 .git shallow &&
git --git-dir=shallow/.git log --format=%s >actual &&
cat <<EOF >expect &&
4
3
EOF
test_cmp expect actual &&
git clone --no-local --depth=2 full-abc/.git shallow2 &&
git --git-dir=shallow2/.git log --format=%s >actual &&
cat <<EOF >expect &&
c
b
EOF
test_cmp expect actual
'
test_expect_success 'push to shallow repo via http' '
git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
(
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
git config http.receivepack true
) &&
(
cd full &&
commit 9 &&
git push $HTTPD_URL/smart/repo.git +master:refs/remotes/top/master
) &&
(
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
git fsck &&
git log --format=%s top/master >actual &&
cat <<EOF >expect &&
9
4
3
EOF
test_cmp expect actual
)
'
test_expect_success 'push from shallow repo via http' '
mv "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" shallow-upstream.git &&
git clone --bare --no-local full "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
(
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
git config http.receivepack true
) &&
commit 10 &&
git push $HTTPD_URL/smart/repo.git +master:refs/remotes/top/master &&
(
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
git fsck &&
git log --format=%s top/master >actual &&
cat <<EOF >expect &&
10
4
3
2
1
EOF
test_cmp expect actual
)
'
stop_httpd
test_done

View File

@ -9,19 +9,32 @@ test_description='git rev-list --pretty=format test'
. "$TEST_DIRECTORY"/lib-terminal.sh
test_tick
# Tested non-UTF-8 encoding
test_encoding="ISO8859-1"
# String "added" in German
# (translated with Google Translate),
# encoded in UTF-8, used as a commit log message below.
added=$(printf "added (hinzugef\303\274gt) foo")
added_iso88591=$(echo "$added" | iconv -f utf-8 -t iso8859-1)
added_utf8_part=$(printf "\303\274")
added_utf8_part_iso88591=$(echo "$added_utf8_part" | iconv -f utf-8 -t $test_encoding)
added=$(printf "added (hinzugef${added_utf8_part}gt) foo")
added_iso88591=$(echo "$added" | iconv -f utf-8 -t $test_encoding)
# same but "changed"
changed=$(printf "changed (ge\303\244ndert) foo")
changed_iso88591=$(echo "$changed" | iconv -f utf-8 -t iso8859-1)
changed_utf8_part=$(printf "\303\244")
changed_utf8_part_iso88591=$(echo "$changed_utf8_part" | iconv -f utf-8 -t $test_encoding)
changed=$(printf "changed (ge${changed_utf8_part}ndert) foo")
changed_iso88591=$(echo "$changed" | iconv -f utf-8 -t $test_encoding)
# Count of char to truncate
# Number is chosen so, that non-ACSII characters
# (see $added_utf8_part and $changed_utf8_part)
# fall into truncated parts of appropriate words both from left and right
truncate_count=20
test_expect_success 'setup' '
: >foo &&
git add foo &&
git config i18n.commitEncoding iso8859-1 &&
git config i18n.commitEncoding $test_encoding &&
git commit -m "$added_iso88591" &&
head1=$(git rev-parse --verify HEAD) &&
head1_short=$(git rev-parse --verify --short $head1) &&
@ -124,9 +137,9 @@ EOF
test_format encoding %e <<EOF
commit $head2
iso8859-1
$test_encoding
commit $head1
iso8859-1
$test_encoding
EOF
test_format subject %s <<EOF
@ -136,6 +149,13 @@ commit $head1
$added
EOF
test_format subject-truncated "%<($truncate_count,trunc)%s" <<EOF
commit $head2
changed (ge${changed_utf8_part}ndert)..
commit $head1
added (hinzugef${added_utf8_part}gt..
EOF
test_format body %b <<EOF
commit $head2
commit $head1
@ -203,16 +223,16 @@ test_expect_success '%C(auto) respects --color=auto (stdout not tty)' '
)
'
iconv -f utf-8 -t iso8859-1 > commit-msg <<EOF
iconv -f utf-8 -t $test_encoding > commit-msg <<EOF
Test printing of complex bodies
This commit message is much longer than the others,
and it will be encoded in iso8859-1. We should therefore
include an iso8859 character: ¡bueno!
and it will be encoded in $test_encoding. We should therefore
include an ISO8859 character: ¡bueno!
EOF
test_expect_success 'setup complex body' '
git config i18n.commitencoding iso8859-1 &&
git config i18n.commitencoding $test_encoding &&
echo change2 >foo && git commit -a -F commit-msg &&
head3=$(git rev-parse --verify HEAD) &&
head3_short=$(git rev-parse --short $head3)
@ -220,11 +240,11 @@ test_expect_success 'setup complex body' '
test_format complex-encoding %e <<EOF
commit $head3
iso8859-1
$test_encoding
commit $head2
iso8859-1
$test_encoding
commit $head1
iso8859-1
$test_encoding
EOF
test_format complex-subject %s <<EOF
@ -236,20 +256,47 @@ commit $head1
$added_iso88591
EOF
test_format complex-subject-trunc "%<($truncate_count,trunc)%s" <<EOF
commit $head3
Test printing of c..
commit $head2
changed (ge${changed_utf8_part_iso88591}ndert)..
commit $head1
added (hinzugef${added_utf8_part_iso88591}gt..
EOF
test_format complex-subject-mtrunc "%<($truncate_count,mtrunc)%s" <<EOF
commit $head3
Test prin..ex bodies
commit $head2
changed (..dert) foo
commit $head1
added (hi..f${added_utf8_part_iso88591}gt) foo
EOF
test_format complex-subject-ltrunc "%<($truncate_count,ltrunc)%s" <<EOF
commit $head3
.. of complex bodies
commit $head2
..ged (ge${changed_utf8_part_iso88591}ndert) foo
commit $head1
.. (hinzugef${added_utf8_part_iso88591}gt) foo
EOF
test_expect_success 'prepare expected messages (for test %b)' '
cat <<-EOF >expected.utf-8 &&
commit $head3
This commit message is much longer than the others,
and it will be encoded in iso8859-1. We should therefore
include an iso8859 character: ¡bueno!
and it will be encoded in $test_encoding. We should therefore
include an ISO8859 character: ¡bueno!
commit $head2
commit $head1
EOF
iconv -f utf-8 -t iso8859-1 expected.utf-8 >expected.iso8859-1
iconv -f utf-8 -t $test_encoding expected.utf-8 >expected.ISO8859-1
'
test_format complex-body %b <expected.iso8859-1
test_format complex-body %b <expected.ISO8859-1
# Git uses i18n.commitEncoding if no i18n.logOutputEncoding set
# so unset i18n.commitEncoding to test encoding conversion
@ -264,6 +311,33 @@ commit $head1
$added
EOF
test_format complex-subject-commitencoding-unset-trunc "%<($truncate_count,trunc)%s" <<EOF
commit $head3
Test printing of c..
commit $head2
changed (ge${changed_utf8_part}ndert)..
commit $head1
added (hinzugef${added_utf8_part}gt..
EOF
test_format complex-subject-commitencoding-unset-mtrunc "%<($truncate_count,mtrunc)%s" <<EOF
commit $head3
Test prin..ex bodies
commit $head2
changed (..dert) foo
commit $head1
added (hi..f${added_utf8_part}gt) foo
EOF
test_format complex-subject-commitencoding-unset-ltrunc "%<($truncate_count,ltrunc)%s" <<EOF
commit $head3
.. of complex bodies
commit $head2
..ged (ge${changed_utf8_part}ndert) foo
commit $head1
.. (hinzugef${added_utf8_part}gt) foo
EOF
test_format complex-body-commitencoding-unset %b <expected.utf-8
test_expect_success '%x00 shows NUL' '

53
t/t6039-merge-ignorecase.sh Executable file
View File

@ -0,0 +1,53 @@
#!/bin/sh
test_description='git-merge with case-changing rename on case-insensitive file system'
. ./test-lib.sh
if ! test_have_prereq CASE_INSENSITIVE_FS
then
skip_all='skipping case insensitive tests - case sensitive file system'
test_done
fi
test_expect_success 'merge with case-changing rename' '
test $(git config core.ignorecase) = true &&
>TestCase &&
git add TestCase &&
git commit -m "add TestCase" &&
git tag baseline
git checkout -b with-camel &&
>foo &&
git add foo &&
git commit -m "intervening commit" &&
git checkout master &&
git rm TestCase &&
>testcase &&
git add testcase &&
git commit -m "rename to testcase" &&
git checkout with-camel &&
git merge master -m "merge" &&
test_path_is_file testcase
'
test_expect_success 'merge with case-changing rename on both sides' '
git checkout master &&
git reset --hard baseline &&
git branch -D with-camel &&
git checkout -b with-camel &&
git mv TestCase testcase &&
git commit -m "recase on branch" &&
>foo &&
git add foo &&
git commit -m "intervening commit" &&
git checkout master &&
git rm TestCase &&
>testcase &&
git add testcase &&
git commit -m "rename to testcase" &&
git checkout with-camel &&
git merge master -m "merge" &&
test_path_is_file testcase
'
test_done

View File

@ -24,7 +24,8 @@ test_expect_success 'set up a bit of history' '
git tag -m "annotated tag" annotated &&
git checkout -b side HEAD^^ &&
test_commit side2 &&
test_commit side3
test_commit side3 &&
test_merge merge main3
'
test_expect_success 'showing two commits' '
@ -109,8 +110,11 @@ test_expect_success 'showing range' '
'
test_expect_success '-s suppresses diff' '
echo main3 >expect &&
git show -s --format=%s main3 >actual &&
cat >expect <<-\EOF &&
merge
main3
EOF
git show -s --format=%s merge main3 >actual &&
test_cmp expect actual
'

View File

@ -22,6 +22,9 @@ commit_msg () {
fi
}
# Tested non-UTF-8 encoding
test_encoding="ISO8859-1"
test_expect_success 'creating initial files and commits' '
test_tick &&
echo "1st file" >first &&
@ -41,7 +44,7 @@ test_expect_success 'creating initial files and commits' '
echo "1st line 2nd file" >secondfile &&
echo "2nd line 2nd file" >>secondfile &&
git -c "i18n.commitEncoding=iso8859-1" commit -a -m "$(commit_msg iso8859-1)" &&
git -c "i18n.commitEncoding=$test_encoding" commit -a -m "$(commit_msg $test_encoding)" &&
head5=$(git rev-parse --verify HEAD)
'
# git log --pretty=oneline # to see those SHA1 involved
@ -64,10 +67,10 @@ test_expect_success 'reset --hard message' '
test_cmp .expected .actual
'
test_expect_success 'reset --hard message (iso8859-1 logoutputencoding)' '
test_expect_success 'reset --hard message (ISO8859-1 logoutputencoding)' '
hex=$(git log -1 --format="%h") &&
git -c "i18n.logOutputEncoding=iso8859-1" reset --hard > .actual &&
echo HEAD is now at $hex $(commit_msg iso8859-1) > .expected &&
git -c "i18n.logOutputEncoding=$test_encoding" reset --hard > .actual &&
echo HEAD is now at $hex $(commit_msg $test_encoding) > .expected &&
test_cmp .expected .actual
'
@ -331,7 +334,7 @@ test_expect_success 'redoing the last two commits should succeed' '
echo "1st line 2nd file" >secondfile &&
echo "2nd line 2nd file" >>secondfile &&
git -c "i18n.commitEncoding=iso8859-1" commit -a -m "$(commit_msg iso8859-1)" &&
git -c "i18n.commitEncoding=$test_encoding" commit -a -m "$(commit_msg $test_encoding)" &&
check_changes $head5
'

View File

@ -223,7 +223,8 @@ test_expect_success 'Commit without message is allowed with --allow-empty-messag
git add foo &&
>empty &&
git commit --allow-empty-message <empty &&
commit_msg_is ""
commit_msg_is "" &&
git tag empty-message-commit
'
test_expect_success 'Commit without message is no-no without --allow-empty-message' '
@ -240,6 +241,14 @@ test_expect_success 'Commit a message with --allow-empty-message' '
commit_msg_is "hello there"
'
test_expect_success 'commit -C empty respects --allow-empty-message' '
echo more >>foo &&
git add foo &&
test_must_fail git commit -C empty-message-commit &&
git commit -C empty-message-commit --allow-empty-message &&
commit_msg_is ""
'
commit_for_rebase_autosquash_setup () {
echo "first content line" >>foo &&
git add foo &&

View File

@ -1380,7 +1380,32 @@ EOF
test_i18ncmp expect output
'
test_expect_success '.gitmodules ignore=all suppresses submodule summary' '
test_expect_success '.gitmodules ignore=all suppresses unstaged submodule summary' '
cat > expect << EOF &&
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: sm
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: dir1/modified
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitmodules
dir1/untracked
dir2/modified
dir2/untracked
expect
output
untracked
EOF
git config --add -f .gitmodules submodule.subname.ignore all &&
git config --add -f .gitmodules submodule.subname.path sm &&
git status > output &&
@ -1388,7 +1413,7 @@ test_expect_success '.gitmodules ignore=all suppresses submodule summary' '
git config -f .gitmodules --remove-section submodule.subname
'
test_expect_success '.git/config ignore=all suppresses submodule summary' '
test_expect_success '.git/config ignore=all suppresses unstaged submodule summary' '
git config --add -f .gitmodules submodule.subname.ignore none &&
git config --add -f .gitmodules submodule.subname.path sm &&
git config --add submodule.subname.ignore all &&
@ -1461,4 +1486,49 @@ test_expect_success 'Restore default test environment' '
git config --unset status.showUntrackedFiles
'
test_expect_success 'git commit will commit a staged but ignored submodule' '
git config --add -f .gitmodules submodule.subname.ignore all &&
git config --add -f .gitmodules submodule.subname.path sm &&
git config --add submodule.subname.ignore all &&
git status -s --ignore-submodules=dirty >output &&
test_i18ngrep "^M. sm" output &&
GIT_EDITOR="echo hello >>\"\$1\"" &&
export GIT_EDITOR &&
git commit -uno &&
git status -s --ignore-submodules=dirty >output &&
test_i18ngrep ! "^M. sm" output
'
test_expect_success 'git commit --dry-run will show a staged but ignored submodule' '
git reset HEAD^ &&
git add sm &&
cat >expect << EOF &&
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: sm
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: dir1/modified
Untracked files not listed (use -u option to show untracked files)
EOF
git commit -uno --dry-run >output &&
test_i18ncmp expect output &&
git status -s --ignore-submodules=dirty >output &&
test_i18ngrep "^M. sm" output
'
test_expect_success 'git commit -m will commit a staged but ignored submodule' '
git commit -uno -m message &&
git status -s --ignore-submodules=dirty >output &&
test_i18ngrep ! "^M. sm" output &&
git config --remove-section submodule.subname &&
git config -f .gitmodules --remove-section submodule.subname
'
test_done

View File

@ -57,11 +57,10 @@ create_merge_msgs () {
git log --no-merges ^HEAD c2 c3
} >squash.1-5-9 &&
: >msg.nologff &&
echo >msg.nolognoff &&
: >msg.nolognoff &&
{
echo "* tag 'c3':" &&
echo " commit 3" &&
echo
echo " commit 3"
} >msg.log
}
@ -71,7 +70,7 @@ verify_merge () {
git diff --exit-code &&
if test -n "$3"
then
git show -s --pretty=format:%s HEAD >msg.act &&
git show -s --pretty=tformat:%s HEAD >msg.act &&
test_cmp "$3" msg.act
fi
}
@ -620,10 +619,10 @@ test_expect_success 'merge early part of c2' '
git tag c6 &&
git branch -f c5-branch c5 &&
git merge c5-branch~1 &&
git show -s --pretty=format:%s HEAD >actual.branch &&
git show -s --pretty=tformat:%s HEAD >actual.branch &&
git reset --keep HEAD^ &&
git merge c5~1 &&
git show -s --pretty=format:%s HEAD >actual.tag &&
git show -s --pretty=tformat:%s HEAD >actual.tag &&
test_cmp expected.branch actual.branch &&
test_cmp expected.tag actual.tag
'

View File

@ -191,4 +191,13 @@ test_expect_success 'indent of line numbers, ten lines' '
test $(grep -c " " actual) = 9
'
test_expect_success 'blaming files with CRLF newlines' '
git config core.autocrlf false &&
printf "testcase\r\n" >crlffile &&
git add crlffile &&
git commit -m testcase &&
git -c core.autocrlf=input blame crlffile >actual &&
grep "A U Thor" actual
'
test_done

View File

@ -174,6 +174,24 @@ ssize_t xwrite(int fd, const void *buf, size_t len)
}
}
/*
* xpread() is the same as pread(), but it automatically restarts pread()
* operations with a recoverable error (EAGAIN and EINTR). xpread() DOES
* NOT GUARANTEE that "len" bytes is read even if the data is available.
*/
ssize_t xpread(int fd, void *buf, size_t len, off_t offset)
{
ssize_t nr;
if (len > MAX_IO_SIZE)
len = MAX_IO_SIZE;
while (1) {
nr = pread(fd, buf, len, offset);
if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
continue;
return nr;
}
}
ssize_t read_in_full(int fd, void *buf, size_t count)
{
char *p = buf;
@ -214,6 +232,26 @@ ssize_t write_in_full(int fd, const void *buf, size_t count)
return total;
}
ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset)
{
char *p = buf;
ssize_t total = 0;
while (count > 0) {
ssize_t loaded = xpread(fd, p, count, offset);
if (loaded < 0)
return -1;
if (loaded == 0)
return total;
count -= loaded;
p += loaded;
total += loaded;
offset += loaded;
}
return total;
}
int xdup(int fd)
{
int ret = dup(fd);

View File

@ -519,9 +519,19 @@ static void wt_status_collect_changes_index(struct wt_status *s)
opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;
setup_revisions(0, NULL, &rev, &opt);
DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
if (s->ignore_submodule_arg) {
DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
} else {
/*
* Unless the user did explicitly request a submodule ignore
* mode by passing a command line option we do not ignore any
* changed submodule SHA-1s when comparing index and HEAD, no
* matter what is configured. Otherwise the user won't be
* shown any submodules she manually added (and which are
* staged to be committed), which would be really confusing.
*/
handle_ignore_submodules_arg(&rev.diffopt, "dirty");
}
rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;