Compare commits

...

212 Commits

Author SHA1 Message Date
9a8c2b67cd Git 2.0.5
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:30:46 -08:00
5e519fb8b0 Sync with v1.9.5
* maint-1.9:
  Git 1.9.5
  Git 1.8.5.6
  fsck: complain about NTFS ".git" aliases in trees
  read-cache: optionally disallow NTFS .git variants
  path: add is_ntfs_dotgit() helper
  fsck: complain about HFS+ ".git" aliases in trees
  read-cache: optionally disallow HFS+ .git variants
  utf8: add is_hfs_dotgit() helper
  fsck: notice .git case-insensitively
  t1450: refactor ".", "..", and ".git" fsck tests
  verify_dotfile(): reject .git case-insensitively
  read-tree: add tests for confusing paths like ".." and ".git"
  unpack-trees: propagate errors adding entries to the index
2014-12-17 11:28:54 -08:00
83332636f5 Git 1.9.5
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:22:32 -08:00
6898b79721 Sync with v1.8.5.6
* maint-1.8.5:
  Git 1.8.5.6
  fsck: complain about NTFS ".git" aliases in trees
  read-cache: optionally disallow NTFS .git variants
  path: add is_ntfs_dotgit() helper
  fsck: complain about HFS+ ".git" aliases in trees
  read-cache: optionally disallow HFS+ .git variants
  utf8: add is_hfs_dotgit() helper
  fsck: notice .git case-insensitively
  t1450: refactor ".", "..", and ".git" fsck tests
  verify_dotfile(): reject .git case-insensitively
  read-tree: add tests for confusing paths like ".." and ".git"
  unpack-trees: propagate errors adding entries to the index
2014-12-17 11:20:31 -08:00
5c8213a769 Git 1.8.5.6
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:18:45 -08:00
2aa9100846 Merge branch 'dotgit-case-maint-1.8.5' into maint-1.8.5
* dotgit-case-maint-1.8.5:
  fsck: complain about NTFS ".git" aliases in trees
  read-cache: optionally disallow NTFS .git variants
  path: add is_ntfs_dotgit() helper
  fsck: complain about HFS+ ".git" aliases in trees
  read-cache: optionally disallow HFS+ .git variants
  utf8: add is_hfs_dotgit() helper
  fsck: notice .git case-insensitively
  t1450: refactor ".", "..", and ".git" fsck tests
  verify_dotfile(): reject .git case-insensitively
  read-tree: add tests for confusing paths like ".." and ".git"
  unpack-trees: propagate errors adding entries to the index
2014-12-17 11:11:15 -08:00
d08c13b947 fsck: complain about NTFS ".git" aliases in trees
Now that the index can block pathnames that can be mistaken
to mean ".git" on NTFS and FAT32, it would be helpful for
fsck to notice such problematic paths. This lets servers
which use receive.fsckObjects block them before the damage
spreads.

Note that the fsck check is always on, even for systems
without core.protectNTFS set. This is technically more
restrictive than we need to be, as a set of users on ext4
could happily use these odd filenames without caring about
NTFS.

However, on balance, it's helpful for all servers to block
these (because the paths can be used for mischief, and
servers which bother to fsck would want to stop the spread
whether they are on NTFS themselves or not), and hardly
anybody will be affected (because the blocked names are
variants of .git or git~1, meaning mischief is almost
certainly what the tree author had in mind).

Ideally these would be controlled by a separate
"fsck.protectNTFS" flag. However, it would be much nicer to
be able to enable/disable _any_ fsck flag individually, and
any scheme we choose should match such a system. Given the
likelihood of anybody using such a path in practice, it is
not unreasonable to wait until such a system materializes.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:04:45 -08:00
2b4c6efc82 read-cache: optionally disallow NTFS .git variants
The point of disallowing ".git" in the index is that we
would never want to accidentally overwrite files in the
repository directory. But this means we need to respect the
filesystem's idea of when two paths are equal. The prior
commit added a helper to make such a comparison for NTFS
and FAT32; let's use it in verify_path().

We make this check optional for two reasons:

  1. It restricts the set of allowable filenames, which is
     unnecessary for people who are not on NTFS nor FAT32.
     In practice this probably doesn't matter, though, as
     the restricted names are rather obscure and almost
     certainly would never come up in practice.

  2. It has a minor performance penalty for every path we
     insert into the index.

This patch ties the check to the core.protectNTFS config
option. Though this is expected to be most useful on Windows,
we allow it to be set everywhere, as NTFS may be mounted on
other platforms. The variable does default to on for Windows,
though.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:04:45 -08:00
1d1d69bc52 path: add is_ntfs_dotgit() helper
We do not allow paths with a ".git" component to be added to
the index, as that would mean repository contents could
overwrite our repository files. However, asking "is this
path the same as .git" is not as simple as strcmp() on some
filesystems.

On NTFS (and FAT32), there exist so-called "short names" for
backwards-compatibility: 8.3 compliant names that refer to the same files
as their long names. As ".git" is not an 8.3 compliant name, a short name
is generated automatically, typically "git~1".

Depending on the Windows version, any combination of trailing spaces and
periods are ignored, too, so that both "git~1." and ".git." still refer
to the Git directory. The reason is that 8.3 stores file names shorter
than 8 characters with trailing spaces. So literally, it does not matter
for the short name whether it is padded with spaces or whether it is
shorter than 8 characters, it is considered to be the exact same.

The period is the separator between file name and file extension, and
again, an empty extension consists just of spaces in 8.3 format. So
technically, we would need only take care of the equivalent of this
regex:
        (\.git {0,4}|git~1 {0,3})\. {0,3}

However, there are indications that at least some Windows versions might
be more lenient and accept arbitrary combinations of trailing spaces and
periods and strip them out. So we're playing it real safe here. Besides,
there can be little doubt about the intention behind using file names
matching even the more lenient pattern specified above, therefore we
should be fine with disallowing such patterns.

Extra care is taken to catch names such as '.\\.git\\booh' because the
backslash is marked as a directory separator only on Windows, and we want
to use this new helper function also in fsck on other platforms.

A big thank you goes to Ed Thomson and an unnamed Microsoft engineer for
the detailed analysis performed to come up with the corresponding fixes
for libgit2.

This commit adds a function to detect whether a given file name can refer
to the Git directory by mistake.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:04:45 -08:00
a18fcc9ff2 fsck: complain about HFS+ ".git" aliases in trees
Now that the index can block pathnames that case-fold to
".git" on HFS+, it would be helpful for fsck to notice such
problematic paths. This lets servers which use
receive.fsckObjects block them before the damage spreads.

Note that the fsck check is always on, even for systems
without core.protectHFS set. This is technically more
restrictive than we need to be, as a set of users on ext4
could happily use these odd filenames without caring about
HFS+.

However, on balance, it's helpful for all servers to block
these (because the paths can be used for mischief, and
servers which bother to fsck would want to stop the spread
whether they are on HFS+ themselves or not), and hardly
anybody will be affected (because the blocked names are
variants of .git with invisible Unicode code-points mixed
in, meaning mischief is almost certainly what the tree
author had in mind).

Ideally these would be controlled by a separate
"fsck.protectHFS" flag. However, it would be much nicer to
be able to enable/disable _any_ fsck flag individually, and
any scheme we choose should match such a system. Given the
likelihood of anybody using such a path in practice, it is
not unreasonable to wait until such a system materializes.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:04:45 -08:00
a42643aa8d read-cache: optionally disallow HFS+ .git variants
The point of disallowing ".git" in the index is that we
would never want to accidentally overwrite files in the
repository directory. But this means we need to respect the
filesystem's idea of when two paths are equal. The prior
commit added a helper to make such a comparison for HFS+;
let's use it in verify_path.

We make this check optional for two reasons:

  1. It restricts the set of allowable filenames, which is
     unnecessary for people who are not on HFS+. In practice
     this probably doesn't matter, though, as the restricted
     names are rather obscure and almost certainly would
     never come up in practice.

  2. It has a minor performance penalty for every path we
     insert into the index.

This patch ties the check to the core.protectHFS config
option. Though this is expected to be most useful on OS X,
we allow it to be set everywhere, as HFS+ may be mounted on
other platforms. The variable does default to on for OS X,
though.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:04:44 -08:00
6162a1d323 utf8: add is_hfs_dotgit() helper
We do not allow paths with a ".git" component to be added to
the index, as that would mean repository contents could
overwrite our repository files. However, asking "is this
path the same as .git" is not as simple as strcmp() on some
filesystems.

HFS+'s case-folding does more than just fold uppercase into
lowercase (which we already handle with strcasecmp). It may
also skip past certain "ignored" Unicode code points, so
that (for example) ".gi\u200ct" is mapped ot ".git".

The full list of folds can be found in the tables at:

  https://www.opensource.apple.com/source/xnu/xnu-1504.15.3/bsd/hfs/hfscommon/Unicode/UCStringCompareData.h

Implementing a full "is this path the same as that path"
comparison would require us importing the whole set of
tables.  However, what we want to do is much simpler: we
only care about checking ".git". We know that 'G' is the
only thing that folds to 'g', and so on, so we really only
need to deal with the set of ignored code points, which is
much smaller.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:04:39 -08:00
76e86fc6e3 fsck: notice .git case-insensitively
We complain about ".git" in a tree because it cannot be
loaded into the index or checked out. Since we now also
reject ".GIT" case-insensitively, fsck should notice the
same, so that errors do not propagate.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:04:39 -08:00
450870cba7 t1450: refactor ".", "..", and ".git" fsck tests
We check that fsck notices and complains about confusing
paths in trees. However, there are a few shortcomings:

  1. We check only for these paths as file entries, not as
     intermediate paths (so ".git" and not ".git/foo").

  2. We check "." and ".." together, so it is possible that
     we notice only one and not the other.

  3. We repeat a lot of boilerplate.

Let's use some loops to be more thorough in our testing, and
still end up with shorter code.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:04:39 -08:00
cc2fc7c2f0 verify_dotfile(): reject .git case-insensitively
We do not allow ".git" to enter into the index as a path
component, because checking out the result to the working
tree may causes confusion for subsequent git commands.
However, on case-insensitive file systems, ".Git" or ".GIT"
is the same. We should catch and prevent those, too.

Note that technically we could allow this for repos on
case-sensitive filesystems. But there's not much point. It's
unlikely that anybody cares, and it creates a repository
that is unexpectedly non-portable to other systems.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:04:31 -08:00
96b50cc190 read-tree: add tests for confusing paths like ".." and ".git"
We should prevent nonsense paths from entering the index in
the first place, as they can cause confusing results if they
are ever checked out into the working tree. We already do
so, but we never tested it.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 11:00:37 -08:00
4616918013 unpack-trees: propagate errors adding entries to the index
When unpack_trees tries to write an entry to the index,
add_index_entry may report an error to stderr, but we ignore
its return value. This leads to us returning a successful
exit code for an operation that partially failed. Let's make
sure to propagate this code.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-17 10:57:53 -08:00
76f8611a5f Merge branch 'maint-1.9' into maint-2.0
* maint-1.9:
  git-tag.txt: Add a missing hyphen to `-s`
2014-10-07 13:40:39 -07:00
9181365b85 Merge branch 'maint-1.8.5' into maint-1.9
* maint-1.8.5:
  git-tag.txt: Add a missing hyphen to `-s`
2014-10-07 13:40:19 -07:00
eeff891ac7 git-tag.txt: Add a missing hyphen to -s
Signed-off-by: Wieland Hoffmann <themineo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-07 11:08:06 -07:00
32f56600bb Git 2.0.4
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-30 14:19:53 -07:00
d8b396e17e commit --amend: test specifies authorship but forgets to check
The test case "--amend option copies authorship" specifies that the
git-commit option `--amend` uses the authorship of the replaced
commit for the new commit. Add the omitted check that this property
actually holds.

Signed-off-by: Fabian Ruch <bafain@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-30 11:32:12 -07:00
d299e9e550 t4013: test diff-tree's --stdin commit formatting
Once upon a time, git-log was just "rev-list | diff-tree",
and we did not bother to test it separately. These days git-log
is implemented internally, but we want to make sure that the
rev-list to diff-tree pipeline continues to function. Let's
add a basic sanity test.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-28 11:31:32 -07:00
5d7c37a130 Merge branch 'jk/alloc-commit-id-maint' into maint
* jk/alloc-commit-id-maint:
  diff-tree: avoid lookup_unknown_object
  object_as_type: set commit index
  alloc: factor out commit index
  add object_as_type helper for casting objects
  parse_object_buffer: do not set object type
  move setting of object->type to alloc_* functions
  alloc: write out allocator definitions
  alloc.c: remove the alloc_raw_commit_node() function
2014-07-28 10:35:35 -07:00
b794ebeac9 diff-tree: avoid lookup_unknown_object
We generally want to avoid lookup_unknown_object, because it
results in allocating more memory for the object than may be
strictly necessary.

In this case, it is used to check whether we have an
already-parsed object before calling parse_object, to save
us from reading the object from disk. Using lookup_object
would be fine for that purpose, but we can take it a step
further. Since this code was written, parse_object already
learned the "check lookup_object" optimization, so we can
simply call parse_object directly.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-28 10:14:34 -07:00
34dfe197a9 object_as_type: set commit index
The point of the "index" field of struct commit is that
every allocated commit would have one. It is supposed to be
an invariant that whenever object->type is set to
OBJ_COMMIT, we have a unique index.

Commit 969eba6 (commit: push commit_index update into
alloc_commit_node, 2014-06-10) covered this case for
newly-allocated commits. However, we may also allocate an
"unknown" object via lookup_unknown_object, and only later
convert it to a commit. We must make sure that we set the
commit index when we switch the type field.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-28 10:14:34 -07:00
5de7f500c1 alloc: factor out commit index
We keep a static counter to set the commit index on newly
allocated objects. However, since we also need to set the
index on any_objects which are converted to commits, let's
make the counter available as a public function.

While we're moving it, let's make sure the counter is
allocated as an unsigned integer to match the index field in
"struct commit".

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-28 10:14:33 -07:00
c4ad00f8cc add object_as_type helper for casting objects
When we call lookup_commit, lookup_tree, etc, the logic goes
something like:

  1. Look for an existing object struct. If we don't have
     one, allocate and return a new one.

  2. Double check that any object we have is the expected
     type (and complain and return NULL otherwise).

  3. Convert an object with type OBJ_NONE (from a prior
     call to lookup_unknown_object) to the expected type.

We can encapsulate steps 2 and 3 in a helper function which
checks whether we have the expected object type, converts
OBJ_NONE as appropriate, and returns the object.

Not only does this shorten the code, but it also provides
one central location for converting OBJ_NONE objects into
objects of other types. Future patches will use that to
enforce type-specific invariants.

Since this is a refactoring, we would want it to behave
exactly as the current code. It takes a little reasoning to
see that this is the case:

  - for lookup_{commit,tree,etc} functions, we are just
    pulling steps 2 and 3 into a function that does the same
    thing.

  - for the call in peel_object, we currently only do step 3
    (but we want to consolidate it with the others, as
    mentioned above). However, step 2 is a noop here, as the
    surrounding conditional makes sure we have OBJ_NONE
    (which we want to keep to avoid an extraneous call to
    sha1_object_info).

  - for the call in lookup_commit_reference_gently, we are
    currently doing step 2 but not step 3. However, step 3
    is a noop here. The object we got will have just come
    from deref_tag, which must have figured out the type for
    each object in order to know when to stop peeling.
    Therefore the type will never be OBJ_NONE.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-28 10:14:33 -07:00
fe0444b50b parse_object_buffer: do not set object type
The only way that "obj" can be non-NULL is if it came from
one of the lookup_* functions. These functions always ensure
that the object has the expected type (and return NULL
otherwise), so there is no need for us to set the type.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-28 10:14:33 -07:00
fe24d396e1 move setting of object->type to alloc_* functions
The "struct object" type implements basic object
polymorphism.  Individual instances are allocated as
concrete types (or as a union type that can store any
object), and a "struct object *" can be cast into its real
type after examining its "type" enum.  This means it is
dangerous to have a type field that does not match the
allocation (e.g., setting the type field of a "struct blob"
to "OBJ_COMMIT" would mean that a reader might read past the
allocated memory).

In most of the current code this is not a problem; the first
thing we do after allocating an object is usually to set its
type field by passing it to create_object. However, the
virtual commits we create in merge-recursive.c do not ever
get their type set. This does not seem to have caused
problems in practice, though (presumably because we always
pass around a "struct commit" pointer and never even look at
the type).

We can fix this oversight and also make it harder for future
code to get it wrong by setting the type directly in the
object allocation functions.

This will also make it easier to fix problems with commit
index allocation, as we know that any object allocated by
alloc_commit_node will meet the invariant that an object
with an OBJ_COMMIT type field will have a unique index
number.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-28 10:14:33 -07:00
52604d7144 alloc: write out allocator definitions
Because the allocator functions for tree, blobs, etc are all
very similar, we originally used a macro to avoid repeating
ourselves. Since the prior commit, though, the heavy lifting
is done by an inline helper function.  The macro does still
save us a few lines, but at some readability cost.  It
obfuscates the function definitions (and makes them hard to
find via grep).

Much worse, though, is the fact that it isn't used
consistently for all allocators. Somebody coming later may
be tempted to modify DEFINE_ALLOCATOR, but they would miss
alloc_commit_node, which is treated specially.

Let's just drop the macro and write everything out
explicitly.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-28 10:14:33 -07:00
8c3f3f28cb alloc.c: remove the alloc_raw_commit_node() function
In order to encapsulate the setting of the unique commit index, commit
969eba63 ("commit: push commit_index update into alloc_commit_node",
10-06-2014) introduced a (logically private) intermediary allocator
function. However, this function (alloc_raw_commit_node()) was declared
as a public function, which undermines its entire purpose.

Introduce an inline function, alloc_node(), which implements the main
logic of the allocator used by DEFINE_ALLOCATOR, and redefine the macro
in terms of the new function. In addition, use the new function in the
implementation of the alloc_commit_node() allocator, rather than the
intermediary allocator, which can now be removed.

Noticed by sparse ("symbol 'alloc_raw_commit_node' was not declared.
Should it be static?").

Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-28 10:14:33 -07:00
740c281d21 Git 2.0.3
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-23 11:33:16 -07:00
98b12a4b9a .mailmap: combine Stefan Beller's emails
Google mail has had the extension @googlemail.com for a long time
in Germany as @gmail.de was already taken by a competitor.
Nowadays the original gmail company isn't there anymore(?), hence
Googlemail also introduced @gmail.com in Germany, which I switched to.

This changed mail address of mine first appeared in 398dd4bd03
(2014-07-10, .mailmap: map different names with the same email
address together) ironically.

Signed-off-by: Stefan Beller <stefanbeller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-23 11:27:05 -07:00
405869d0d5 git.1: switch homepage for stats
According to http://meta.ohloh.net/2014/07/black-duck-open-hub/
the site name of ohloh changed to openhub.

Change the man page accordingly.

Signed-off-by: Stefan Beller <stefanbeller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-23 11:26:52 -07:00
cd989a97ec Merge branch 'ah/fix-http-push' into maint
* ah/fix-http-push:
  http-push.c: make CURLOPT_IOCTLDATA a usable pointer
2014-07-22 10:29:07 -07:00
0d854fc1e3 Merge branch 'po/error-message-style' into maint
* po/error-message-style:
  doc: give some guidelines for error messages
2014-07-22 10:28:59 -07:00
a1991f1734 Merge branch 'zk/log-graph-showsig' into maint
* zk/log-graph-showsig:
  log: fix indentation for --graph --show-signature
2014-07-22 10:28:51 -07:00
514dd21326 Merge branch 'mg/fix-log-mergetag-color' into maint
* mg/fix-log-mergetag-color:
  log: correctly identify mergetag signature verification status
2014-07-22 10:28:43 -07:00
5796c5baa3 Merge branch 'cb/filter-branch-prune-empty-degenerate-merges' into maint
* cb/filter-branch-prune-empty-degenerate-merges:
  filter-branch: eliminate duplicate mapped parents
2014-07-22 10:28:30 -07:00
1a1f7b2c52 Merge branch 'ye/doc-http-proto' into maint
* ye/doc-http-proto:
  http-protocol.txt: Basic Auth is defined in RFC 2617, not RFC 2616
2014-07-22 10:28:02 -07:00
0196a605f7 Merge branch 'jm/api-strbuf-doc' into maint
* jm/api-strbuf-doc:
  api-strbuf.txt minor typos
2014-07-22 10:26:52 -07:00
054e22caf4 Merge branch 'jm/dedup-test-config' into maint
* jm/dedup-test-config:
  t/t7810-grep.sh: remove duplicate test_config()
2014-07-22 10:26:45 -07:00
ef937140a6 Merge branch 'sk/test-cmp-bin' into maint
* sk/test-cmp-bin:
  t5000, t5003: do not use test_cmp to compare binary files
2014-07-22 10:26:34 -07:00
79e9dba0d4 Merge branch 'jm/doc-wording-tweaks' into maint
* jm/doc-wording-tweaks:
  Documentation: wording fixes in the user manual and glossary
2014-07-22 10:26:17 -07:00
af3e5d1b2a Merge branch 'jm/instaweb-apache-24' into maint
* jm/instaweb-apache-24:
  git-instaweb: add support for Apache 2.4
2014-07-22 10:25:24 -07:00
cfececfe1f Merge branch 'bg/xcalloc-nmemb-then-size' into maint
* bg/xcalloc-nmemb-then-size:
  transport-helper.c: rearrange xcalloc arguments
  remote.c: rearrange xcalloc arguments
  reflog-walk.c: rearrange xcalloc arguments
  pack-revindex.c: rearrange xcalloc arguments
  notes.c: rearrange xcalloc arguments
  imap-send.c: rearrange xcalloc arguments
  http-push.c: rearrange xcalloc arguments
  diff.c: rearrange xcalloc arguments
  config.c: rearrange xcalloc arguments
  commit.c: rearrange xcalloc arguments
  builtin/remote.c: rearrange xcalloc arguments
  builtin/ls-remote.c: rearrange xcalloc arguments
2014-07-22 10:25:17 -07:00
1fbc6e6e60 Merge branch 'cb/byte-order' into maint
* cb/byte-order:
  compat/bswap.h: fix endianness detection
  compat/bswap.h: restore preference __BIG_ENDIAN over BIG_ENDIAN
  compat/bswap.h: detect endianness on more platforms that don't use BYTE_ORDER
2014-07-22 10:25:02 -07:00
85dd37941a Merge branch 'lt/request-pull' into maint
* lt/request-pull:
  fix brown paper bag breakage in t5150-request-pull.sh
2014-07-22 10:23:41 -07:00
63618af24a Merge branch 'ep/shell-assign-and-export-vars' into maint
* ep/shell-assign-and-export-vars:
  scripts: more "export VAR=VALUE" fixes
  scripts: "export VAR=VALUE" construct is not portable
2014-07-22 10:22:57 -07:00
bba6acb335 Merge branch 'maint-1.9' into maint
* maint-1.9:
  Documentation: fix missing text for rev-parse --verify
2014-07-22 10:17:34 -07:00
d31f3ad23d Merge branch 'maint-1.8.5' into maint-1.9
* maint-1.8.5:
  Documentation: fix missing text for rev-parse --verify
2014-07-22 10:16:50 -07:00
e6aaa39347 Documentation: fix missing text for rev-parse --verify
The caret (^) is used as a markup symbol in AsciiDoc.  Due to the
inability of AsciiDoc to parse a line containing an unmatched caret, it
omitted the line from the output, resulting in the man page missing the
end of a sentence.  Escape this caret so that the man page ends up with
the complete text.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-22 10:10:57 -07:00
5c0b13f85a use xmemdupz() to allocate copies of strings given by start and length
Use xmemdupz() to allocate the memory, copy the data and make sure to
NUL-terminate the result, all in one step.  The resulting code is
shorter, doesn't contain the constants 1 and '\0', and avoids
duplicating function parameters.

For blame, the last copied byte (o->file.ptr[o->file.size]) is always
set to NUL by fake_working_tree_commit() or read_sha1_file(), so no
information is lost by the conversion to using xmemdupz().

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-21 10:37:02 -07:00
51a60f5bfb use xcalloc() to allocate zero-initialized memory
Use xcalloc() instead of xmalloc() followed by memset() to allocate
and zero out memory because it's shorter and avoids duplicating the
function parameters.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-21 10:30:21 -07:00
ebc5da3208 Git 2.0.2
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-16 11:19:56 -07:00
2e931843ad Merge branch 'jc/fix-clone-single-starting-at-a-tag' into maint
"git clone -b brefs/tags/bar" would have mistakenly thought we were
following a single tag, even though it was a name of the branch,
because it incorrectly used strstr().

* jc/fix-clone-single-starting-at-a-tag:
  builtin/clone.c: detect a clone starting at a tag correctly
2014-07-16 11:17:36 -07:00
588de86f06 Merge branch 'jk/pretty-G-format-fixes' into maint
"%G" (nothing after G) is an invalid pretty format specifier, but
the parser did not notice it as garbage.

* jk/pretty-G-format-fixes:
  move "%G" format test from t7510 to t6006
  pretty: avoid reading past end-of-string with "%G"
  t7510: check %G* pretty-format output
  t7510: test a commit signed by an unknown key
  t7510: use consistent &&-chains in loop
  t7510: stop referring to master in later tests
2014-07-16 11:17:21 -07:00
5a3db94539 Merge branch 'rs/fix-alt-odb-path-comparison' into maint
Code to avoid adding the same alternate object store twice was
subtly broken for a long time, but nobody seems to have noticed.

* rs/fix-alt-odb-path-comparison:
  sha1_file: avoid overrunning alternate object base string
2014-07-16 11:17:08 -07:00
5c18fde0d9 Merge branch 'jk/commit-buffer-length' into maint
A handful of code paths had to read the commit object more than
once when showing header fields that are usually not parsed.  The
internal data structure to keep track of the contents of the commit
object has been updated to reduce the need for this double-reading,
and to allow the caller find the length of the object.

* jk/commit-buffer-length:
  reuse cached commit buffer when parsing signatures
  commit: record buffer length in cache
  commit: convert commit->buffer to a slab
  commit-slab: provide a static initializer
  use get_commit_buffer everywhere
  convert logmsg_reencode to get_commit_buffer
  use get_commit_buffer to avoid duplicate code
  use get_cached_commit_buffer where appropriate
  provide helpers to access the commit buffer
  provide a helper to set the commit buffer
  provide a helper to free commit buffer
  sequencer: use logmsg_reencode in get_message
  logmsg_reencode: return const buffer
  do not create "struct commit" with xcalloc
  commit: push commit_index update into alloc_commit_node
  alloc: include any-object allocations in alloc_report
  replace dangerous uses of strbuf_attach
  commit_tree: take a pointer/len pair rather than a const strbuf
2014-07-16 11:16:38 -07:00
64630d807a Merge branch 'bc/fix-rebase-merge-skip' into maint
During "git rebase --merge", a conflicted patch could not be
skipped with "--skip" if the next one also conflicted.

* bc/fix-rebase-merge-skip:
  rebase--merge: fix --skip with two conflicts in a row
2014-07-16 11:16:16 -07:00
9092a9696b Merge branch 'maint-1.9' into maint
* maint-1.9:
  annotate: use argv_array
2014-07-16 11:11:06 -07:00
d22acacf81 Merge branch 'maint-1.8.5' into maint-1.9
* maint-1.8.5:
  annotate: use argv_array
  t7300: repair filesystem permissions with test_when_finished
  enums: remove trailing ',' after last item in enum
2014-07-16 11:10:30 -07:00
8c2cfa5544 annotate: use argv_array
Simplify the code and get rid of some magic constants by using
argv_array to build the argument list for cmd_blame.  Be lazy and let
the OS release our allocated memory, as before.

Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-16 11:10:11 -07:00
479eaa8ef8 http-push.c: make CURLOPT_IOCTLDATA a usable pointer
Fixes a small bug affecting push to remotes which use some sort of
multi-pass authentication. In particular the bug affected SabreDAV as
configured by Box.com [1].

It must be a weird server configuration for the bug to have survived
this long. Someone should write a test for it.

[1] http://marc.info/?l=git&m=140460482604482

Signed-off-by: Abbaad Haider <abbaad@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-13 17:57:59 -07:00
42c55ce49e log: correctly identify mergetag signature verification status
A wrong '}' made our code record the results of mergetag signature
verification incorrectly.

Fix it.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-10 15:25:03 -07:00
0ae0e882b2 doc: give some guidelines for error messages
Clarify error message puntuation to reduce review workload.

Signed-off-by: Philip Oakley <philipoakley@iee.org>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-10 13:31:55 -07:00
8693e1cc2f Start preparing for 2.0.2
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-10 11:15:10 -07:00
cbf4e024ad Merge branch 'pb/trim-trailing-spaces' into maint
* pb/trim-trailing-spaces:
  t0008: do not depend on 'echo' handling backslashes specially
  dir.c:trim_trailing_spaces(): fix for " \ " sequence
2014-07-10 11:10:52 -07:00
f35392b018 Merge branch 'jk/repack-pack-keep-objects' into maint
* jk/repack-pack-keep-objects:
  repack: s/write_bitmap/&s/ in code
  repack: respect pack.writebitmaps
  repack: do not accidentally pack kept objects by default
2014-07-10 11:10:05 -07:00
3fea9ebdff Merge branch 'mc/doc-submodule-sync-recurse' into maint
* mc/doc-submodule-sync-recurse:
  submodule: document "sync --recursive"
2014-07-10 11:08:31 -07:00
cf3983d1ff log: fix indentation for --graph --show-signature
The git log --graph --show-signature command incorrectly indents the gpg
information about signed commits and merged signed tags. It does not
follow the level of indentation of the current commit.

Example of garbled output:
$ git log --show-signature --graph
*   commit 258e0a237cb69aaa587b0a4fb528bb0316b1b776
|\  gpg: Signature made Mon, Jun 30, 2014 13:22:33 EDT using RSA key ID DA08
gpg: Good signature from "Jason Pyeron <jpye...@pdinc.us>"
Merge: 727c355 1ca13ed
| | Author: Jason Pyeron <jpye...@pdinc.us>
| | Date:   Mon Jun 30 13:22:29 2014 -0400
| |
| |     Merge of 1ca13ed2271d60ba9 branch - rebranding
| |
| * commit 1ca13ed2271d60ba93d40bcc8db17ced8545f172
| | gpg: Signature made Mon, Jun 23, 2014  9:45:47 EDT using RSA key ID DD37
gpg: Good signature from "Stephen Robert Guglielmo <s...@guglielmo.us>"
gpg:                 aka "Stephen Robert Guglielmo <srguglie...@gmail.com>"
Author: Stephen R Guglielmo <s...@guglielmo.us>
| | Date:   Mon Jun 23 09:45:27 2014 -0400
| |
| |     Minor URL updates

In log-tree.c modify show_sig_lines() function to call graph_show_oneline()
after each line of gpg information it has printed in order to preserve
the level of indentation for the next output line.

Reported-by: Jason Pyeron <jpyeron@pdinc.us>
Signed-off-by: Zoltan Klinger <zoltan.klinger@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-09 09:37:43 -07:00
c2f7b1026e Merge branch 'maint-1.8.5' into maint
* maint-1.8.5:
  t7300: repair filesystem permissions with test_when_finished
  enums: remove trailing ',' after last item in enum
2014-07-02 12:51:50 -07:00
45067fc973 t7300: repair filesystem permissions with test_when_finished
We create a directory that cannot be removed, confirm that
it cannot be removed, and then fix it like:

  chmod 0 foo &&
  test_must_fail git clean -d -f &&
  chmod 755 foo

If the middle step fails but leaves the directory (e.g., the
bug is that clean does not notice the failure), this
pollutes the test repo with an unremovable directory. Not
only does this cause further tests to fail, but it means
that "rm -rf" fails on the whole trash directory, and the
user has to intervene manually to even re-run the test script.

We can bump the "chmod 755" recovery to a test_when_finished
block to be sure that it always runs.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-02 12:51:38 -07:00
782735203c enums: remove trailing ',' after last item in enum
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-02 12:37:05 -07:00
80b47854ca sha1_file: avoid overrunning alternate object base string
While checking if a new alternate object database is a duplicate make
sure that old and new base paths have the same length before comparing
them with memcmp.  This avoids overrunning the buffer of the existing
entry if the new one is longer and it stops rejecting foobar/ after
foo/ was already added.

Signed-off-by: Rene Scharfe <ls.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-01 13:30:50 -07:00
79bc4ef368 filter-branch: eliminate duplicate mapped parents
When multiple parents of a merge commit get mapped to the same
commit, filter-branch used to pass all instances of the parent
commit to the parent and commit filters and to "git commit-tree" or
"git_commit_non_empty_tree".

This can often happen when extracting a small project from a large
repository; merges can join history with no commits on any branch
which affect the paths being retained.  Once the intermediate
commits have been filtered out, all the immediate parents of the
merge commit can end up being mapped to the same commit - either the
original merge-base or an ancestor of it.

"git commit-tree" would display an error but write the commit with
the normalized parents in any case.  "git_commit_non_empty_tree"
would fail to notice that the commit being made was in fact a
non-merge commit and would retain it even if a further pass with
"--prune-empty" would discard the commit as empty.

Ensure that duplicate parents are pruned before the parent filter to
make "--prune-empty" idempotent, removing all empty non-merge
commits in a singe pass.

Signed-off-by: Charles Bailey <cbailey32@bloomberg.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-07-01 08:30:41 -07:00
958b2eb26c move "%G" format test from t7510 to t6006
The final test in t7510 checks that "--format" placeholders
that look similar to GPG placeholders (but that we don't
actually understand) are passed through. That test was
placed in t7510, since the other GPG placeholder tests are
there. However, it does not have a GPG prerequisite, because
it is not actually checking any signed commits.

This causes the test to erroneously fail when gpg is not
installed on a system, however. Not because we need signed
commits, but because we need _any_ commit to run "git log".
If we don't have gpg installed, t7510 doesn't create any
commits at all.

We can fix this by moving the test into t6006. This is
arguably a better place anyway, because it is where we test
most of the other placeholders (we do not test GPG
placeholders there because of the infrastructure needed to
make signed commits).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-25 15:01:06 -07:00
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
60a5f5fc79 builtin/clone.c: detect a clone starting at a tag correctly
31b808a0 (clone --single: limit the fetch refspec to fetched branch,
2012-09-20) tried to see if the given "branch" to follow is actually
a tag at the remote repository by checking with "refs/tags/" but it
incorrectly used strstr(3); it is actively wrong to treat a "branch"
"refs/heads/refs/tags/foo" and use the logic for the "refs/tags/"
ref hierarchy.  What the code really wanted to do is to see if it
starts with "refs/tags/".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-23 14:31:35 -07:00
aa4b78d483 pretty: avoid reading past end-of-string with "%G"
If the user asks for --format=%G with nothing else, we
correctly realize that "%G" is not a valid placeholder (it
should be "%G?", "%GK", etc). But we still tell the
strbuf_expand code that we consumed 2 characters, causing it
to jump over the trailing NUL and output garbage.

This also fixes the case where "%GX" would be consumed (and
produce no output). In other cases, we pass unrecognized
placeholders through to the final string.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-17 13:41:41 -07:00
06ca0f45a0 t7510: check %G* pretty-format output
We do not check these along with the other pretty-format
placeholders in t6006, because we need signed commits to
make them interesting. t7510 has such commits, and can
easily exercise them in addition to the regular
--show-signature code path.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-17 13:41:39 -07:00
4baf839fe0 t7510: test a commit signed by an unknown key
We tested both good and bad signatures, but not ones made
correctly but with a key for which we have no trust.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-17 13:41:28 -07:00
7b1732c116 t7510: use consistent &&-chains in loop
We check multiple commits in a loop. Because we want to
break out of the loop if any single iteration fails, we use
a subshell/exit like:

  (
	for i in $stuff
	do
		do-something $i || exit 1
	done
  )

However, we are inconsistent in our loop body. Some commands
get their own "|| exit 1", and others try to chain to the
next command with "&&", like:

  X &&
  Y || exit 1
  Z || exit 1

This is a little hard to read and follow, because X and Y
are treated differently for no good reason. But much worse,
the second loop follows a similar pattern and gets it wrong.
"Y" is expected to fail, so we use "&& exit 1", giving us:

  X &&
  Y && exit 1
  Z || exit 1

That gets the test for X wrong (we do not exit unless both X
fails and Y unexpectedly succeeds, but we would want to exit
if _either_ is wrong). We can write this clearly and
correctly by consistently using "&&", followed by a single
"|| exit 1", and negating Y with "!" (as we would in a
normal &&-chain). Like:

  X &&
  ! Y &&
  Z || exit 1

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-17 13:39:52 -07:00
526d56e072 t7510: stop referring to master in later tests
Our setup creates a sequence of commits, each with its own
tag. However, we sometimes refer to "seventh-signed" as
"master". This works, since it is at the tip of the created
branch, but is brittle if new tests need to add more
commits. Let's use its tag name to be unambiguous.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-17 13:39:12 -07:00
95104c7e25 rebase--merge: fix --skip with two conflicts in a row
If git rebase --merge encountered a conflict, --skip would not work if the
next commit also conflicted.  The msgnum file would never be updated with
the new patch number, so no patch would actually be skipped, resulting in an
inescapable loop.

Update the msgnum file's value as the first thing in call_merge.  This also
avoids an "Already applied" message when skipping a commit.  There is no
visible change for the other contexts in which call_merge is invoked, as the
msgnum file's value remains unchanged in those situations.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-16 13:29:16 -07:00
04953bc888 http-protocol.txt: Basic Auth is defined in RFC 2617, not RFC 2616
Signed-off-by: Yi EungJun <eungjun.yi@navercorp.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-16 12:00:43 -07:00
9393ae79c9 submodule: document "sync --recursive"
The "git submodule sync" command supports the --recursive flag, but
the documentation does not mention this.  That flag is useful, for
example when a remote is changed in a submodule of a submodule.

Signed-off-by: Matthew Chen <charlesmchen@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 15:00:17 -07:00
97c1364be6 t0008: do not depend on 'echo' handling backslashes specially
The original used to pass with /bin/dash but not with /bin/bash set
to $SHELL_PATH.  The former turns "\\" into "\", but the latter does
not.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 13:29:03 -07:00
218aa3a616 reuse cached commit buffer when parsing signatures
When we call show_signature or show_mergetag, we read the
commit object fresh via read_sha1_file and reparse its
headers. However, in most cases we already have the object
data available, attached to the "struct commit". This is
partially laziness in dealing with the memory allocation
issues, but partially defensive programming, in that we
would always want to verify a clean version of the buffer
(not one that might have been munged by other users of the
commit).

However, we do not currently ever munge the commit buffer,
and not using the already-available buffer carries a fairly
big performance penalty when we are looking at a large
number of commits. Here are timings on linux.git:

  [baseline, no signatures]
  $ time git log >/dev/null
  real    0m4.902s
  user    0m4.784s
  sys     0m0.120s

  [before]
  $ time git log --show-signature >/dev/null
  real    0m14.735s
  user    0m9.964s
  sys     0m0.944s

  [after]
  $ time git log --show-signature >/dev/null
  real    0m9.981s
  user    0m5.260s
  sys     0m0.936s

Note that our user CPU time drops almost in half, close to
the non-signature case, but we do still spend more
wall-clock and system time, presumably from dealing with
gpg.

An alternative to this is to note that most commits do not
have signatures (less than 1% in this repo), yet we pay the
re-parsing cost for every commit just to find out if it has
a mergetag or signature. If we checked that when parsing the
commit initially, we could avoid re-examining most commits
later on. Even if we did pursue that direction, however,
this would still speed up the cases where we _do_ have
signatures. So it's probably worth doing either way.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 12:10:13 -07:00
8597ea3afe commit: record buffer length in cache
Most callsites which use the commit buffer try to use the
cached version attached to the commit, rather than
re-reading from disk. Unfortunately, that interface provides
only a pointer to the NUL-terminated buffer, with no
indication of the original length.

For the most part, this doesn't matter. People do not put
NULs in their commit messages, and the log code is happy to
treat it all as a NUL-terminated string. However, some code
paths do care. For example, when checking signatures, we
want to be very careful that we verify all the bytes to
avoid malicious trickery.

This patch just adds an optional "size" out-pointer to
get_commit_buffer and friends. The existing callers all pass
NULL (there did not seem to be any obvious sites where we
could avoid an immediate strlen() call, though perhaps with
some further refactoring we could).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 12:09:38 -07:00
c1b3c71f4b commit: convert commit->buffer to a slab
This will make it easier to manage the buffer cache
independently of the "struct commit" objects. It also
shrinks "struct commit" by one pointer, which may be
helpful.

Unfortunately it does not reduce the max memory size of
something like "rev-list", because rev-list uses
get_cached_commit_buffer() to decide not to show each
commit's output (and due to the design of slab_at, accessing
the slab requires us to extend it, allocating exactly the
same number of buffer pointers we dropped from the commit
structs).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 12:08:17 -07:00
80cdaba569 commit-slab: provide a static initializer
Callers currently must use init_foo_slab() at runtime before
accessing a slab. For global slabs, it's much nicer if we
can initialize them in BSS, so that each user does not have
to add code to check-and-initialize.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 12:08:17 -07:00
bc6b8fc130 use get_commit_buffer everywhere
Each of these sites assumes that commit->buffer is valid.
Since they would segfault if this was not the case, they are
likely to be correct in practice. However, we can
future-proof them by using get_commit_buffer.

And as a side effect, we abstract away the final bare uses
of commit->buffer.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 12:08:17 -07:00
b66103c3ba convert logmsg_reencode to get_commit_buffer
Like the callsites in the previous commit, logmsg_reencode
already falls back to read_sha1_file when necessary.
However, I split its conversion out into its own commit
because it's a bit more complex.

We return either:

  1. The original commit->buffer

  2. A newly allocated buffer from read_sha1_file

  3. A reencoded buffer (based on either 1 or 2 above).

while trying to do as few extra reads/allocations as
possible. Callers currently free the result with
logmsg_free, but we can simplify this by pointing them
straight to unuse_commit_buffer. This is a slight layering
violation, in that we may be passing a buffer from (3).
However, since the end result is to free() anything except
(1), which is unlikely to change, and because this makes the
interface much simpler, it's a reasonable bending of the
rules.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 12:08:17 -07:00
ba41c1c93f use get_commit_buffer to avoid duplicate code
For both of these sites, we already do the "fallback to
read_sha1_file" trick. But we can shorten the code by just
using get_commit_buffer.

Note that the error cases are slightly different when
read_sha1_file fails. get_commit_buffer will die() if the
object cannot be loaded, or is a non-commit.

For get_sha1_oneline, this will almost certainly never
happen, as we will have just called parse_object (and if it
does, it's probably worth complaining about).

For record_author_date, the new behavior is probably better;
we notify the user of the error instead of silently ignoring
it. And because it's used only for sorting by author-date,
somebody examining a corrupt repo can fallback to the
regular traversal order.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 12:08:17 -07:00
a97934d820 use get_cached_commit_buffer where appropriate
Some call sites check commit->buffer to see whether we have
a cached buffer, and if so, do some work with it. In the
long run we may want to switch these code paths to make
their decision on a different boolean flag (because checking
the cache may get a little more expensive in the future).
But for now, we can easily support them by converting the
calls to use get_cached_commit_buffer.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 12:08:17 -07:00
152ff1cceb provide helpers to access the commit buffer
Many sites look at commit->buffer to get more detailed
information than what is in the parsed commit struct.
However, we sometimes drop commit->buffer to save memory,
in which case the caller would need to read the object
afresh. Some callers do this (leading to duplicated code),
and others do not (which opens the possibility of a segfault
if somebody else frees the buffer).

Let's provide a pair of helpers, "get" and "unuse", that let
callers easily get the buffer. They will use the cached
buffer when possible, and otherwise load from disk using
read_sha1_file.

Note that we also need to add a "get_cached" variant which
returns NULL when we do not have a cached buffer. At first
glance this seems to defeat the purpose of "get", which is
to always provide a return value. However, some log code
paths actually use the NULL-ness of commit->buffer as a
boolean flag to decide whether to try printing the
commit. At least for now, we want to continue supporting
that use.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 12:08:17 -07:00
66c2827ea4 provide a helper to set the commit buffer
Right now this is just a one-liner, but abstracting it will
make it easier to change later.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 12:08:17 -07:00
0fb370da9c provide a helper to free commit buffer
This converts two lines into one at each caller. But more
importantly, it abstracts the concept of freeing the buffer,
which will make it easier to change later.

Note that we also need to provide a "detach" mechanism for a
tricky case in index-pack. We are passed a buffer for the
object generated by processing the incoming pack. If we are
not using --strict, we just calculate the sha1 on that
buffer and return, leaving the caller to free it.  But if we
are using --strict, we actually attach that buffer to an
object, pass the object to the fsck functions, and then
detach the buffer from the object again (so that the caller
can free it as usual).  In this case, we don't want to free
the buffer ourselves, but just make sure it is no longer
associated with the commit.

Note that we are making the assumption here that the
attach/detach process does not impact the buffer at all
(e.g., it is never reallocated or modified). That holds true
now, and we have no plans to change that. However, as we
abstract the commit_buffer code, this dependency becomes
less obvious. So when we detach, let's also make sure that
we get back the same buffer that we gave to the
commit_buffer code.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-13 12:07:47 -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
d74a4e57d2 sequencer: use logmsg_reencode in get_message
This simplifies the code, as logmsg_reencode handles the
reencoding for us in a single call. It also means we learn
logmsg_reencode's trick of pulling the buffer from disk when
commit->buffer is NULL (we currently just silently return!).
It is doubtful this matters in practice, though, as
sequencer operations would not generally turn off
save_commit_buffer.

Note that we may be fixing a bug here. The existing code
does:

  if (same_encoding(to, from))
	  reencode_string(buf, to, from);

That probably should have been "!same_encoding".

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-12 10:29:43 -07:00
b000c59b0c logmsg_reencode: return const buffer
The return value from logmsg_reencode may be either a newly
allocated buffer or a pointer to the existing commit->buffer.
We would not want the caller to accidentally free() or
modify the latter, so let's mark it as const.  We can cast
away the constness in logmsg_free, but only once we have
determined that it is a free-able buffer.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-12 10:29:43 -07:00
10322a0aaf do not create "struct commit" with xcalloc
In both blame and merge-recursive, we sometimes create a
"fake" commit struct for convenience (e.g., to represent the
HEAD state as if we would commit it). By allocating
ourselves rather than using alloc_commit_node, we do not
properly set the "index" field of the commit. This can
produce subtle bugs if we then use commit-slab on the
resulting commit, as we will share the "0" index with
another commit.

We can fix this by using alloc_commit_node() to allocate.
Note that we cannot free the result, as it is part of our
commit allocator. However, both cases were already leaking
the allocated commit anyway, so there's nothing to fix up.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-12 10:29:42 -07:00
969eba6341 commit: push commit_index update into alloc_commit_node
Whenever we create a commit object via lookup_commit, we
give it a unique index to be used with the commit-slab API.
The theory is that any "struct commit" we create would
follow this code path, so any such struct would get an
index. However, callers could use alloc_commit_node()
directly (and get multiple commits with index 0).

Let's push the indexing into alloc_commit_node so that it's
hard for callers to get it wrong.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-12 10:29:42 -07:00
c335d74d34 alloc: include any-object allocations in alloc_report
When 2c1cbec (Use proper object allocators for unknown
object nodes too, 2007-04-16), added a special "any_object"
allocator, it never taught alloc_report to report on it. To
do so we need to add an extra type argument to the REPORT
macro, as that commit did for DEFINE_ALLOCATOR.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-12 10:29:42 -07:00
e6dfcd6767 replace dangerous uses of strbuf_attach
It is not a good idea to strbuf_attach an arbitrary pointer
just because a function you are calling wants a strbuf.
Attaching implies a transfer of memory ownership; if anyone
were to modify or release the resulting strbuf, we would
free() the pointer, leading to possible problems:

  1. Other users of the original pointer might access freed
     memory.

  2. The pointer might not be the start of a malloc'd
     area, so calling free() on it in the first place would
     be wrong.

In the two cases modified here, we are fortunate that nobody
touches the strbuf once it is attached, but it is an
accident waiting to happen.  Since the previous commit,
commit_tree and friends take a pointer/buf pair, so we can
just do away with the strbufs entirely.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-12 10:29:42 -07:00
3ffefb54c0 commit_tree: take a pointer/len pair rather than a const strbuf
While strbufs are pretty common throughout our code, it is
more flexible for functions to take a pointer/len pair than
a strbuf. It's easy to turn a strbuf into such a pair (by
dereferencing its members), but less easy to go the other
way (you can strbuf_attach, but that has implications about
memory ownership).

This patch teaches commit_tree (and its associated callers
and sub-functions) to take such a pair for the commit
message rather than a strbuf.  This makes passing the buffer
around slightly more verbose, but means we can get rid of
some dangerous strbuf_attach calls in the next patch.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-12 10:29:41 -07:00
d078d85bc3 repack: s/write_bitmap/&s/ in code
The config name is "writeBitmaps", so the internal variable
missing the plural is unnecessarily confusing to write.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-10 14:01:30 -07:00
3198b89fb2 repack: respect pack.writebitmaps
The config option to turn on bitmaps is read all the way
down in the plumbing of pack-objects. This makes it hard for
other options in the porcelain of repack to make decisions
based on the bitmap setting. For example,
repack.packKeptObjects tries to kick in by default only when
bitmaps are turned on. But it can't do so reliably because
it doesn't yet know whether we are using bitmaps.

This patch teaches repack to respect pack.writebitmaps. It
means we pass a redundant command-line flag to pack-objects,
but that's OK; it shouldn't affect the outcome.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-10 14:01:08 -07:00
64d3dc9468 repack: do not accidentally pack kept objects by default
Commit ee34a2b (repack: add `repack.packKeptObjects` config
var, 2014-03-03) added a flag which could duplicate kept
objects, but did not mean to turn it on by default. Instead,
the option is tied by default to the decision to write
bitmaps, like:

  if (pack_kept_objects < 0)
	  pack_kept_objects = write_bitmap;

after which we expect pack_kept_objects to be a boolean 0 or
1.  However, that assignment neglects that write_bitmap is
_also_ a tri-state with "-1" as the default, and with
neither option given, we accidentally turn the option on.

This patch is the minimal fix to restore the desired
behavior for the default state. Further patches will fix the
more complicated cases.

Note the update to t7700. It failed to turn on bitmaps,
meaning we were actually confirming the wrong behavior!

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-10 13:58:43 -07:00
97ea0d1043 api-strbuf.txt minor typos
Fixed some minor typos in api-strbuf.txt: 'A' instead of 'An', 'have'
instead of 'has', a overlong line, and 'another' instead of 'an other'.

Signed-off-by: Jeremiah Mahler <jmmahler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-09 14:54:52 -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
dce6818d10 t/t7810-grep.sh: remove duplicate test_config()
t/t7810-grep.sh had its own test_config() function which served the
same purpose as the one in t/test-lib-functions.sh.  Removed, all tests
pass.

Signed-off-by: Jeremiah Mahler <jmmahler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-05 11:56:01 -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
b93e6e3663 t5000, t5003: do not use test_cmp to compare binary files
test_cmp() is primarily meant to compare text files (and display the
difference for debug purposes).

Raw "cmp" is better suited to compare binary files (tar, zip, etc.).

On MinGW, test_cmp is a shell function mingw_test_cmp that tries to
read both files into environment, stripping CR characters (introduced
in commit 4d715ac0).

This function usually speeds things up, as fork is extremly slow on
Windows.  But no wonder that this function is extremely slow and
sometimes even crashes when comparing large tar or zip files.

Signed-off-by: Stepan Kasal <kasal@ucw.cz>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-04 11:14:25 -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
e61a6c1d82 dir.c:trim_trailing_spaces(): fix for " \ " sequence
Discard the unnecessary 'nr_spaces' variable, remove 'strlen()' and
improve the 'if' structure.  Switch to pointers instead of integers
to control the loop.

Slightly more rare occurrences of 'text  \    ' with a backslash
in between spaces are handled correctly.  Namely, the code in
7e2e4b37 (dir: ignore trailing spaces in exclude patterns, 2014-02-09)
does not reset 'last_space' when a backslash is encountered and the above
line stays intact as a result.

Add a test at the end of t/t0008-ignores.sh to exhibit this behavior.

Signed-off-by: Pasha Bolokhov <pasha.bolokhov@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-02 15:48:48 -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
644edd02c1 fix brown paper bag breakage in t5150-request-pull.sh
The recent addition to the test case 'pull request format' interrupted
the single-quoted text, effectively adding a third argument to the
test_expect_success command. Since we do not have a prerequisite named
"pull request format", the test is skipped, no matter what. Additionally,
the file name argument to the grep command is missing. Fix both issues.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-02 11:05:33 -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
9c65ee15ee compat/bswap.h: fix endianness detection
The changes to make detection of endianness more portable had a bug
that breaks on (at least) Solaris x86.

The bug appears to be a simple copy/paste typo. It checks for
_BIG_ENDIAN and not _LITTLE_ENDIAN for both the case where we would
decide the system is big endian and little endian. Instead, the
second test should be for _LITTLE_ENDIAN and not _BIG_ENDIAN.

Two fixes were possible:

 1. Change the negation order of the conditions in the second test.
 2. Reverse the order of the conditions in the second test.

Use the second option so that the condition we expect is always a
positive check.

Signed-off-by: Ben Walton <bdwalton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-30 11:48:28 -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
e156455ea4 Git 2.0 2014-05-28 11:04:19 -07:00
3c735e0776 Documentation: wording fixes in the user manual and glossary
Re-word the section on "Updating a repository with git fetch" in the
user manual.

Various other minor fixes in the manual and glossary.

Signed-off-by: Jeremiah Mahler <jmmahler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-28 10:40:06 -07:00
92e25b6b5b transport-helper.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
transport_helper_init passes the arguments in reverse order, passing the
size of a helper_data*, followed by the number to allocate.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:02:45 -07:00
da7a478bc0 remote.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
parse_refspec_internal passes the arguments in reverse order, passing the
size of a refspec, followed by the number to allocate.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:02:45 -07:00
8e1aa2f792 reflog-walk.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
reflog-walk.c includes several calls to xcalloc() that pass the arguments
in reverse order.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:02:45 -07:00
48d547fb38 pack-revindex.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
init_pack_revindex() passes the arguments in reverse order, passing the
size of a pack_revindex, followed by the number to allocate.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:02:45 -07:00
65bbf082c2 notes.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
notes.c includes several calls to xcalloc() that pass the arguments in
reverse order.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:02:45 -07:00
3345c0f5b9 imap-send.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
imap_open_store() passes the arguments in reverse order, passing the
size of an imap_store*, followed by the number to allocate.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:02:45 -07:00
f3d51ffde8 http-push.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
http-push passes the arguments in reverse order, passing the size
of a repo, followed by the number to allocate.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:02:45 -07:00
1a4927c5c5 diff.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
diffstat_add() passes the arguments in reverse order, passing the
size of a diffstat_file*, followed by the number of diffstat_file* to
be allocated.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:02:03 -07:00
f1064f6bc8 config.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
config.c includes several calls to xcalloc() that pass the arguments
in reverse order: the size of a struct lock_file*, followed by the
number to allocate.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:00:44 -07:00
c4a7b0092b commit.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
reduce_heads() passes the arguments in reverse order, passing the
size of a commit*, followed by the number of commit* to be allocated.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:00:43 -07:00
380694544d builtin/remote.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
builtin/remote.c includes several calls to xcalloc() that pass the
arguments in reverse order.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:00:43 -07:00
edd2d84665 builtin/ls-remote.c: rearrange xcalloc arguments
xcalloc() takes two arguments: the number of elements and their size.
cmd_ls_remote() passes the arguments in reverse order, passing the
size of a char*, followed by the number of char* to be allocated.

Rearrange them so they are in the correct order.

Signed-off-by: Brian Gesiak <modocache@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 14:00:43 -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
f8ee1f02da git-instaweb: add support for Apache 2.4
Detect available Apache MPMs and use first available according to
following order of precedence:
mpm_event
mpm_prefork
mpm_worker

Add authz_core module if available to avoid HTTP Error 500 errors.

Signed-off-by: Jonathan McCrohan <jmccrohan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-27 12:57:19 -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
c1cebcf431 scripts: more "export VAR=VALUE" fixes
Found by

    git grep '[^-]export [^&]*=' -- \*.sh

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-23 15:32:54 -07:00
bed137d2d5 scripts: "export VAR=VALUE" construct is not portable
Found by check-non-portable-shell.pl

Signed-off-by: Elia Pinto <gitter.spiros@gmail.com>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-23 15:32:33 -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
4a28f169ad Update draft release notes to 2.0
Hopefully for the last time ;-)

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-21 11:50:35 -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
839fa9c500 compat/bswap.h: restore preference __BIG_ENDIAN over BIG_ENDIAN
The previous commit swaps the order we check the macros defined by
the compiler and the system headers from the original.  Since the
order of check should not matter (i.e. it is insane to define both
__BIG_ENDIAN and friends and BIG_ENDIAN and friends and in a
conflicting way), it is the most conservative thing to do not to
change it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-02 12:36:10 -07:00
3cf6bb3406 compat/bswap.h: detect endianness on more platforms that don't use BYTE_ORDER
Signed-off-by: Charles Bailey <cbailey32@bloomberg.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-05-02 12:31:59 -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
155 changed files with 2246 additions and 779 deletions

View File

@ -202,6 +202,7 @@ Seth Falcon <seth@userprimary.net> <sfalcon@fhcrc.org>
Shawn O. Pearce <spearce@spearce.org>
Simon Hausmann <hausmann@kde.org> <simon@lst.de>
Simon Hausmann <hausmann@kde.org> <shausman@trolltech.com>
Stefan Beller <stefanbeller@gmail.com> <stefanbeller@googlemail.com>
Stefan Naewe <stefan.naewe@gmail.com> <stefan.naewe@atlas-elektronik.com>
Stefan Naewe <stefan.naewe@gmail.com> <stefan.naewe@googlemail.com>
Stefan Sperling <stsp@elego.de> <stsp@stsp.name>

View File

@ -264,6 +264,15 @@ For Python scripts:
documentation for version 2.6 does not mention this prefix, it has
been supported since version 2.6.0.
Error Messages
- Do not end error messages with a full stop.
- Do not capitalize ("unable to open %s", not "Unable to open %s")
- Say what the error is first ("cannot open %s", not "%s: cannot open")
Writing Documentation:
Most (if not all) of the documentation pages are written in the

View File

@ -0,0 +1,34 @@
Git v1.8.5.6 Release Notes
==========================
Fixes since v1.8.5.5
--------------------
* We used to allow committing a path ".Git/config" with Git that is
running on a case sensitive filesystem, but an attempt to check out
such a path with Git that runs on a case insensitive filesystem
would have clobbered ".git/config", which is definitely not what
the user would have expected. Git now prevents you from tracking
a path with ".Git" (in any case combination) as a path component.
* On Windows, certain path components that are different from ".git"
are mapped to ".git", e.g. "git~1/config" is treated as if it were
".git/config". HFS+ has a similar issue, where certain unicode
codepoints are ignored, e.g. ".g\u200cit/config" is treated as if
it were ".git/config". Pathnames with these potential issues are
rejected on the affected systems. Git on systems that are not
affected by this issue (e.g. Linux) can also be configured to
reject them to ensure cross platform interoperability of the hosted
projects.
* "git fsck" notices a tree object that records such a path that can
be confused with ".git", and with receive.fsckObjects configuration
set to true, an attempt to "git push" such a tree object will be
rejected. Such a path may not be a problem on a well behaving
filesystem but in order to protect those on HFS+ and on case
insensitive filesystems, this check is enabled on all platforms.
A big "thanks!" for bringing this issue to us goes to our friends in
the Mercurial land, namely, Matt Mackall and Augie Fackler.
Also contains typofixes, documentation updates and trivial code clean-ups.

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,34 @@
Git v1.9.5 Release Notes
========================
Fixes since v1.9.4
------------------
* We used to allow committing a path ".Git/config" with Git that is
running on a case sensitive filesystem, but an attempt to check out
such a path with Git that runs on a case insensitive filesystem
would have clobbered ".git/config", which is definitely not what
the user would have expected. Git now prevents you from tracking
a path with ".Git" (in any case combination) as a path component.
* On Windows, certain path components that are different from ".git"
are mapped to ".git", e.g. "git~1/config" is treated as if it were
".git/config". HFS+ has a similar issue, where certain unicode
codepoints are ignored, e.g. ".g\u200cit/config" is treated as if
it were ".git/config". Pathnames with these potential issues are
rejected on the affected systems. Git on systems that are not
affected by this issue (e.g. Linux) can also be configured to
reject them to ensure cross platform interoperability of the hosted
projects.
* "git fsck" notices a tree object that records such a path that can
be confused with ".git", and with receive.fsckObjects configuration
set to true, an attempt to "git push" such a tree object will be
rejected. Such a path may not be a problem on a well behaving
filesystem but in order to protect those on HFS+ and on case
insensitive filesystems, this check is enabled on all platforms.
A big "thanks!" for bringing this issue to us goes to our friends in
the Mercurial land, namely, Matt Mackall and Augie Fackler.
Also contains typofixes, documentation updates and trivial code clean-ups.

View File

@ -55,8 +55,9 @@ UI, Workflows & Features
* The "multi-mail" post-receive hook (in contrib/) has been updated
to a more recent version from upstream.
* The "remote-hg/bzr" remote-helper interfaces (in contrib/) are
now maintained separately as a third-party plug-in.
* The "remote-hg/bzr" remote-helper interfaces (used to be in
contrib/) are no more. They are now maintained separately as
third-party plug-ins in their own repositories.
* "git gc --aggressive" learned "--depth" option and
"gc.aggressiveDepth" configuration variable to allow use of a less
@ -190,12 +191,7 @@ notes for details).
* The shell prompt script (in contrib/), when using the PROMPT_COMMAND
interface, used an unsafe construct when showing the branch name in
$PS1.
(merge 8976500 rh/prompt-pcmode-avoid-eval-on-refname later to maint).
* The remote-helper interface to fast-import/fast-export via the
transport-helper has been tightened to avoid leaving the import
marks file from a failed/crashed run, as such a file that is out-of-
sync with reality confuses a later invocation of itself.
(merge 1e4119c8 rh/prompt-pcmode-avoid-eval-on-refname later to maint).
* "git rebase" used a POSIX shell construct FreeBSD's /bin/sh does not
work well with.
@ -344,7 +340,7 @@ notes for details).
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.
(merge later 655ee9e mw/symlinks to maint.)
(merge 6127ff6 mw/symlinks later to maint.)
* "git diff --quiet -- pathspec1 pathspec2" sometimes did not return
the correct status value.

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

@ -0,0 +1,32 @@
Git v2.0.2 Release Notes
========================
* Documentation for "git submodule sync" forgot to say that the subcommand
can take the "--recursive" option.
* Mishandling of patterns in .gitignore that has trailing SPs quoted
with backslashes (e.g. ones that end with "\ ") have been
corrected.
* Recent updates to "git repack" started to duplicate objects that
are in packfiles marked with .keep flag into the new packfile by
mistake.
* "git clone -b brefs/tags/bar" would have mistakenly thought we were
following a single tag, even though it was a name of the branch,
because it incorrectly used strstr().
* "%G" (nothing after G) is an invalid pretty format specifier, but
the parser did not notice it as garbage.
* Code to avoid adding the same alternate object store twice was
subtly broken for a long time, but nobody seems to have noticed.
* A handful of code paths had to read the commit object more than
once when showing header fields that are usually not parsed. The
internal data structure to keep track of the contents of the commit
object has been updated to reduce the need for this double-reading,
and to allow the caller find the length of the object.
* During "git rebase --merge", a conflicted patch could not be
skipped with "--skip" if the next one also conflicted.

View File

@ -0,0 +1,17 @@
Git v2.0.3 Release Notes
========================
* An ancient rewrite passed a wrong pointer to a curl library
function in a rarely used code path.
* "filter-branch" left an empty single-parent commit that results when
all parents of a merge commit gets mapped to the same commit, even
under "--prune-empty".
* "log --show-signature" incorrectly decided the color to paint a
mergetag that was and was not correctly validated.
* "log --show-signature" did not pay attention to "--graph" option.
Also a lot of fixes to the tests and some updates to the docs are
included.

View File

@ -0,0 +1,5 @@
Git v2.0.4 Release Notes
========================
* An earlier update to v2.0.2 broken output from "git diff-tree",
which is fixed in this release.

View File

@ -0,0 +1,34 @@
Git v2.0.5 Release Notes
========================
Fixes since v2.0.4
------------------
* We used to allow committing a path ".Git/config" with Git that is
running on a case sensitive filesystem, but an attempt to check out
such a path with Git that runs on a case insensitive filesystem
would have clobbered ".git/config", which is definitely not what
the user would have expected. Git now prevents you from tracking
a path with ".Git" (in any case combination) as a path component.
* On Windows, certain path components that are different from ".git"
are mapped to ".git", e.g. "git~1/config" is treated as if it were
".git/config". HFS+ has a similar issue, where certain unicode
codepoints are ignored, e.g. ".g\u200cit/config" is treated as if
it were ".git/config". Pathnames with these potential issues are
rejected on the affected systems. Git on systems that are not
affected by this issue (e.g. Linux) can also be configured to
reject them to ensure cross platform interoperability of the hosted
projects.
* "git fsck" notices a tree object that records such a path that can
be confused with ".git", and with receive.fsckObjects configuration
set to true, an attempt to "git push" such a tree object will be
rejected. Such a path may not be a problem on a well behaving
filesystem but in order to protect those on HFS+ and on case
insensitive filesystems, this check is enabled on all platforms.
A big "thanks!" for bringing this issue to us goes to our friends in
the Mercurial land, namely, Matt Mackall and Augie Fackler.
Also contains typofixes, documentation updates and trivial code clean-ups.

View File

@ -233,6 +233,17 @@ core.precomposeunicode::
When false, file names are handled fully transparent by Git,
which is backward compatible with older versions of Git.
core.protectHFS::
If set to true, do not allow checkout of paths that would
be considered equivalent to `.git` on an HFS+ filesystem.
Defaults to `true` on Mac OS, and `false` elsewhere.
core.protectNTFS::
If set to true, do not allow checkout of paths that would
cause problems with the NTFS filesystem, e.g. conflict with
8.3 "short" names.
Defaults to `true` on Windows, and `false` elsewhere.
core.trustctime::
If false, the ctime differences between the index and the
working tree are ignored; useful when the inode change time
@ -2293,7 +2304,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 +2337,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

@ -102,7 +102,7 @@ eval "set -- $(git rev-parse --sq --prefix "$prefix" "$@")"
+
If you want to make sure that the output actually names an object in
your object database and/or can be used as a specific type of object
you require, you can add "^{type}" peeling operator to the parameter.
you require, you can add "\^{type}" peeling operator to the parameter.
For example, `git rev-parse "$VAR^{commit}"` will make sure `$VAR`
names an existing object that is a commit-ish (i.e. a commit, or an
annotated tag that points at a commit). To make sure that `$VAR`

View File

@ -20,7 +20,7 @@ SYNOPSIS
'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]
[commit] [--] [<path>...]
'git submodule' [--quiet] foreach [--recursive] <command>
'git submodule' [--quiet] sync [--] [<path>...]
'git submodule' [--quiet] sync [--recursive] [--] [<path>...]
DESCRIPTION

View File

@ -42,7 +42,7 @@ committer identity for the current user is used to find the
GnuPG key for signing. The configuration variable `gpg.program`
is used to specify custom GnuPG binary.
Tag objects (created with `-a`, `s`, or `-u`) are called "annotated"
Tag objects (created with `-a`, `-s`, or `-u`) are called "annotated"
tags; they contain a creation date, the tagger name and e-mail, a
tagging message, and an optional GnuPG signature. Whereas a
"lightweight" tag is simply a name for an object (usually a commit

View File

@ -43,17 +43,30 @@ unreleased) version of Git, that is available from 'master'
branch of the `git.git` repository.
Documentation for older releases are available here:
* link:v1.9.3/git.html[documentation for release 1.9.3]
* link:v2.0.5/git.html[documentation for release 2.0.5]
* release notes for
link:RelNotes/2.0.5.txt[2.0.5],
link:RelNotes/2.0.4.txt[2.0.4],
link:RelNotes/2.0.3.txt[2.0.3],
link:RelNotes/2.0.2.txt[2.0.2],
link:RelNotes/2.0.1.txt[2.0.1],
link:RelNotes/2.0.0.txt[2.0.0].
* link:v1.9.5/git.html[documentation for release 1.9.5]
* release notes for
link:RelNotes/1.9.5.txt[1.9.5],
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],
link:RelNotes/1.9.0.txt[1.9.0].
* link:v1.8.5.5/git.html[documentation for release 1.8.5.5]
* link:v1.8.5.6/git.html[documentation for release 1.8.5.6]
* release notes for
link:RelNotes/1.8.5.6.txt[1.8.5.6],
link:RelNotes/1.8.5.5.txt[1.8.5.5],
link:RelNotes/1.8.5.4.txt[1.8.5.4],
link:RelNotes/1.8.5.3.txt[1.8.5.3],
@ -1036,7 +1049,7 @@ Authors
-------
Git was started by Linus Torvalds, and is currently maintained by Junio
C Hamano. Numerous contributions have come from the Git mailing list
<git@vger.kernel.org>. http://www.ohloh.net/p/git/contributors/summary
<git@vger.kernel.org>. http://www.openhub.net/p/git/contributors/summary
gives you a more complete list of contributors.
If you have a clone of git.git itself, the

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 @@
[[def_alternate_object_database]]alternate object database::
Via the alternates mechanism, a <<def_repository,repository>>
can inherit part of its <<def_object_database,object database>>
from another object database, which is called "alternate".
from another object database, which is called an "alternate".
[[def_bare_repository]]bare repository::
A bare repository is normally an appropriately

View File

@ -7,10 +7,10 @@ use the mem* functions than a str* one (memchr vs. strchr e.g.).
Though, one has to be careful about the fact that str* functions often
stop on NULs and that strbufs may have embedded NULs.
An strbuf is NUL terminated for convenience, but no function in the
A strbuf is NUL terminated for convenience, but no function in the
strbuf API actually relies on the string being free of NULs.
strbufs has some invariants that are very important to keep in mind:
strbufs have some invariants that are very important to keep in mind:
. The `buf` member is never NULL, so it can be used in any usual C
string operations safely. strbuf's _have_ to be initialized either by
@ -56,8 +56,8 @@ Data structures
* `struct strbuf`
This is the string buffer structure. The `len` member can be used to
determine the current length of the string, and `buf` member provides access to
the string itself.
determine the current length of the string, and `buf` member provides
access to the string itself.
Functions
---------
@ -184,7 +184,7 @@ strbuf_addstr(sb, "immediate string");
`strbuf_addbuf`::
Copy the contents of an other buffer at the end of the current one.
Copy the contents of another buffer at the end of the current one.
`strbuf_adddup`::

View File

@ -60,7 +60,7 @@ Because Git repositories are accessed by standard path components
server administrators MAY use directory based permissions within
their HTTP server to control repository access.
Clients SHOULD support Basic authentication as described by RFC 2616.
Clients SHOULD support Basic authentication as described by RFC 2617.
Servers SHOULD support Basic authentication by relying upon the
HTTP server placed in front of the Git server software.

View File

@ -416,12 +416,11 @@ REVISIONS" section of linkgit:gitrevisions[7].
Updating a repository with git fetch
------------------------------------
Eventually the developer cloned from will do additional work in her
repository, creating new commits and advancing the branches to point
at the new commits.
After you clone a repository and commit a few changes of your own, you
may wish to check the original repository for updates.
The command `git fetch`, with no arguments, will update all of the
remote-tracking branches to the latest version found in her
The `git-fetch` command, with no arguments, will update all of the
remote-tracking branches to the latest version found in the original
repository. It will not touch any of your own branches--not even the
"master" branch that was created for you on clone.
@ -1811,8 +1810,8 @@ manner.
You can then import these into your mail client and send them by
hand. However, if you have a lot to send at once, you may prefer to
use the linkgit:git-send-email[1] script to automate the process.
Consult the mailing list for your project first to determine how they
prefer such patches be handled.
Consult the mailing list for your project first to determine
their requirements for submitting patches.
[[importing-patches]]
Importing patches to a project
@ -2255,7 +2254,7 @@ $ git checkout test && git merge speed-up-spinlocks
It is unlikely that you would have any conflicts here ... but you might if you
spent a while on this step and had also pulled new versions from upstream.
Some time later when enough time has passed and testing done, you can pull the
Sometime later when enough time has passed and testing done, you can pull the
same branch into the `release` tree ready to go upstream. This is where you
see the value of keeping each patch (or patch series) in its own branch. It
means that the patches can be moved into the `release` tree in any order.

View File

@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
DEF_VER=v2.0.0-rc4
DEF_VER=v2.0.5
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.5.txt

106
alloc.c
View File

@ -18,25 +18,6 @@
#define BLOCKING 1024
#define DEFINE_ALLOCATOR(name, type) \
static unsigned int name##_allocs; \
void *alloc_##name##_node(void) \
{ \
static int nr; \
static type *block; \
void *ret; \
\
if (!nr) { \
nr = BLOCKING; \
block = xmalloc(BLOCKING * sizeof(type)); \
} \
nr--; \
name##_allocs++; \
ret = block++; \
memset(ret, 0, sizeof(type)); \
return ret; \
}
union any_object {
struct object object;
struct blob blob;
@ -45,11 +26,75 @@ union any_object {
struct tag tag;
};
DEFINE_ALLOCATOR(blob, struct blob)
DEFINE_ALLOCATOR(tree, struct tree)
DEFINE_ALLOCATOR(commit, struct commit)
DEFINE_ALLOCATOR(tag, struct tag)
DEFINE_ALLOCATOR(object, union any_object)
struct alloc_state {
int count; /* total number of nodes allocated */
int nr; /* number of nodes left in current allocation */
void *p; /* first free node in current allocation */
};
static inline void *alloc_node(struct alloc_state *s, size_t node_size)
{
void *ret;
if (!s->nr) {
s->nr = BLOCKING;
s->p = xmalloc(BLOCKING * node_size);
}
s->nr--;
s->count++;
ret = s->p;
s->p = (char *)s->p + node_size;
memset(ret, 0, node_size);
return ret;
}
static struct alloc_state blob_state;
void *alloc_blob_node(void)
{
struct blob *b = alloc_node(&blob_state, sizeof(struct blob));
b->object.type = OBJ_BLOB;
return b;
}
static struct alloc_state tree_state;
void *alloc_tree_node(void)
{
struct tree *t = alloc_node(&tree_state, sizeof(struct tree));
t->object.type = OBJ_TREE;
return t;
}
static struct alloc_state tag_state;
void *alloc_tag_node(void)
{
struct tag *t = alloc_node(&tag_state, sizeof(struct tag));
t->object.type = OBJ_TAG;
return t;
}
static struct alloc_state object_state;
void *alloc_object_node(void)
{
struct object *obj = alloc_node(&object_state, sizeof(union any_object));
obj->type = OBJ_NONE;
return obj;
}
static struct alloc_state commit_state;
unsigned int alloc_commit_index(void)
{
static unsigned int count;
return count++;
}
void *alloc_commit_node(void)
{
struct commit *c = alloc_node(&commit_state, sizeof(struct commit));
c->object.type = OBJ_COMMIT;
c->index = alloc_commit_index();
return c;
}
static void report(const char *name, unsigned int count, size_t size)
{
@ -57,13 +102,14 @@ static void report(const char *name, unsigned int count, size_t size)
name, count, (uintmax_t) size);
}
#define REPORT(name) \
report(#name, name##_allocs, name##_allocs * sizeof(struct name) >> 10)
#define REPORT(name, type) \
report(#name, name##_state.count, name##_state.count * sizeof(type) >> 10)
void alloc_report(void)
{
REPORT(blob);
REPORT(tree);
REPORT(commit);
REPORT(tag);
REPORT(blob, struct blob);
REPORT(tree, struct tree);
REPORT(commit, struct commit);
REPORT(tag, struct tag);
REPORT(object, union any_object);
}

11
blob.c
View File

@ -7,15 +7,8 @@ struct blob *lookup_blob(const unsigned char *sha1)
{
struct object *obj = lookup_object(sha1);
if (!obj)
return create_object(sha1, OBJ_BLOB, alloc_blob_node());
if (!obj->type)
obj->type = OBJ_BLOB;
if (obj->type != OBJ_BLOB) {
error("Object %s is a %s, not a blob",
sha1_to_hex(sha1), typename(obj->type));
return NULL;
}
return (struct blob *) obj;
return create_object(sha1, alloc_blob_node());
return object_as_type(obj, OBJ_BLOB, 0);
}
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size)

View File

@ -5,20 +5,18 @@
*/
#include "git-compat-util.h"
#include "builtin.h"
#include "argv-array.h"
int cmd_annotate(int argc, const char **argv, const char *prefix)
{
const char **nargv;
struct argv_array args = ARGV_ARRAY_INIT;
int i;
nargv = xmalloc(sizeof(char *) * (argc + 2));
nargv[0] = "annotate";
nargv[1] = "-c";
argv_array_pushl(&args, "annotate", "-c", NULL);
for (i = 1; i < argc; i++) {
nargv[i+1] = argv[i];
argv_array_push(&args, argv[i]);
}
nargv[argc + 1] = NULL;
return cmd_blame(argc + 1, nargv, prefix);
return cmd_blame(args.argc, args.argv, prefix);
}

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;
@ -2867,9 +2869,7 @@ static int apply_binary_fragment(struct image *img, struct patch *patch)
case BINARY_LITERAL_DEFLATED:
clear_image(img);
img->len = fragment->size;
img->buf = xmalloc(img->len+1);
memcpy(img->buf, fragment->patch, img->len);
img->buf[img->len] = '\0';
img->buf = xmemdupz(fragment->patch, img->len);
return 0;
}
return -1;

View File

@ -1405,7 +1405,7 @@ static void get_commit_info(struct commit *commit,
{
int len;
const char *subject, *encoding;
char *message;
const char *message;
commit_info_init(ret);
@ -1416,7 +1416,7 @@ static void get_commit_info(struct commit *commit,
&ret->author_time, &ret->author_tz);
if (!detailed) {
logmsg_free(message, commit);
unuse_commit_buffer(commit, message);
return;
}
@ -1430,7 +1430,7 @@ static void get_commit_info(struct commit *commit,
else
strbuf_addf(&ret->summary, "(%s)", sha1_to_hex(commit->object.sha1));
logmsg_free(message, commit);
unuse_commit_buffer(commit, message);
}
/*
@ -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
@ -1998,6 +2005,18 @@ static void append_merge_parents(struct commit_list **tail)
strbuf_release(&line);
}
/*
* This isn't as simple as passing sb->buf and sb->len, because we
* want to transfer ownership of the buffer to the commit (so we
* must use detach).
*/
static void set_commit_buffer_from_strbuf(struct commit *c, struct strbuf *sb)
{
size_t len;
void *buf = strbuf_detach(sb, &len);
set_commit_buffer(c, buf, len);
}
/*
* Prepare a dummy commit that represents the work tree (or staged) item.
* Note that annotating work tree item never works in the reverse.
@ -2019,10 +2038,9 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
struct strbuf msg = STRBUF_INIT;
time(&now);
commit = xcalloc(1, sizeof(*commit));
commit = alloc_commit_node();
commit->object.parsed = 1;
commit->date = now;
commit->object.type = OBJ_COMMIT;
parent_tail = &commit->parents;
if (!resolve_ref_unsafe("HEAD", head_sha1, 1, NULL))
@ -2046,7 +2064,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
ident, ident, path,
(!contents_from ? path :
(!strcmp(contents_from, "-") ? "standard input" : contents_from)));
commit->buffer = strbuf_detach(&msg, NULL);
set_commit_buffer_from_strbuf(commit, &msg);
if (!contents_from || strcmp("-", contents_from)) {
struct stat st;
@ -2088,7 +2106,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 +2348,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");
@ -2433,11 +2457,8 @@ parse_done:
die("revision walk setup failed");
if (is_null_sha1(sb.final->object.sha1)) {
char *buf;
o = sb.final->util;
buf = xmalloc(o->file.size + 1);
memcpy(buf, o->file.ptr, o->file.size + 1);
sb.final_buf = buf;
sb.final_buf = xmemdupz(o->file.ptr, o->file.size);
sb.final_buf_size = o->file.size;
}
else {

View File

@ -48,7 +48,7 @@ enum color_clean {
CLEAN_COLOR_PROMPT = 2,
CLEAN_COLOR_HEADER = 3,
CLEAN_COLOR_HELP = 4,
CLEAN_COLOR_ERROR = 5,
CLEAN_COLOR_ERROR = 5
};
#define MENU_OPTS_SINGLETON 01
@ -621,8 +621,7 @@ static int *list_and_choose(struct menu_opts *opts, struct menu_stuff *stuff)
nr += chosen[i];
}
result = xmalloc(sizeof(int) * (nr + 1));
memset(result, 0, sizeof(int) * (nr + 1));
result = xcalloc(nr + 1, sizeof(int));
for (i = 0; i < stuff->nr && j < nr; i++) {
if (chosen[i])
result[j++] = i;

View File

@ -695,7 +695,7 @@ static void write_refspec_config(const char* src_ref_prefix,
if (option_mirror || !option_bare) {
if (option_single_branch && !option_mirror) {
if (option_branch) {
if (strstr(our_head_points_at->name, "refs/tags/"))
if (starts_with(our_head_points_at->name, "refs/tags/"))
strbuf_addf(&value, "+%s:%s", our_head_points_at->name,
our_head_points_at->name);
else

View File

@ -123,8 +123,8 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
die_errno("git commit-tree: failed to read");
}
if (commit_tree(&buffer, tree_sha1, parents, commit_sha1,
NULL, sign_commit)) {
if (commit_tree(buffer.buf, buffer.len, tree_sha1, parents,
commit_sha1, NULL, sign_commit)) {
strbuf_release(&buffer);
return 1;
}

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);
@ -1659,8 +1672,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
append_merge_tag_headers(parents, &tail);
}
if (commit_tree_extended(&sb, active_cache_tree->sha1, parents, sha1,
author_ident.buf, sign_commit, extra)) {
if (commit_tree_extended(sb.buf, sb.len, active_cache_tree->sha1,
parents, sha1, author_ident.buf, sign_commit, extra)) {
rollback_index_files();
die(_("failed to write commit object"));
}

View File

@ -72,9 +72,7 @@ static int diff_tree_stdin(char *line)
line[len-1] = 0;
if (get_sha1_hex(line, sha1))
return -1;
obj = lookup_unknown_object(sha1);
if (!obj || !obj->parsed)
obj = parse_object(sha1);
obj = parse_object(sha1);
if (!obj)
return -1;
if (obj->type == OBJ_COMMIT)

View File

@ -279,6 +279,7 @@ static const char *find_encoding(const char *begin, const char *end)
static void handle_commit(struct commit *commit, struct rev_info *rev)
{
int saved_output_format = rev->diffopt.output_format;
const char *commit_buffer;
const char *author, *author_end, *committer, *committer_end;
const char *encoding, *message;
char *reencoded = NULL;
@ -288,7 +289,8 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)
rev->diffopt.output_format = DIFF_FORMAT_CALLBACK;
parse_commit_or_die(commit);
author = strstr(commit->buffer, "\nauthor ");
commit_buffer = get_commit_buffer(commit, NULL);
author = strstr(commit_buffer, "\nauthor ");
if (!author)
die ("Could not find author in commit %s",
sha1_to_hex(commit->object.sha1));
@ -335,6 +337,7 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)
? strlen(message) : 0),
reencoded ? reencoded : message ? message : "");
free(reencoded);
unuse_commit_buffer(commit, commit_buffer);
for (i = 0, p = commit->parents; p; p = p->next) {
int mark = get_object_mark(&p->item->object);

View File

@ -230,12 +230,14 @@ static void add_branch_desc(struct strbuf *out, const char *name)
static void record_person(int which, struct string_list *people,
struct commit *commit)
{
const char *buffer;
char *name_buf, *name, *name_end;
struct string_list_item *elem;
const char *field;
field = (which == 'a') ? "\nauthor " : "\ncommitter ";
name = strstr(commit->buffer, field);
buffer = get_commit_buffer(commit, NULL);
name = strstr(buffer, field);
if (!name)
return;
name += strlen(field);
@ -247,6 +249,7 @@ static void record_person(int which, struct string_list *people,
if (name_end < name)
return;
name_buf = xmemdupz(name, name_end - name + 1);
unuse_commit_buffer(commit, buffer);
elem = string_list_lookup(people, name_buf);
if (!elem) {

View File

@ -310,8 +310,7 @@ static int fsck_obj(struct object *obj)
if (obj->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *) obj;
free(commit->buffer);
commit->buffer = NULL;
free_commit_buffer(commit);
if (!commit->parents && show_root)
printf("root %s\n", sha1_to_hex(commit->object.sha1));

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;
@ -350,8 +362,7 @@ static void set_thread_data(struct thread_local *data)
static struct base_data *alloc_base_data(void)
{
struct base_data *base = xmalloc(sizeof(struct base_data));
memset(base, 0, sizeof(*base));
struct base_data *base = xcalloc(1, sizeof(struct base_data));
base->ref_last = -1;
base->ofs_last = -1;
return base;
@ -542,7 +553,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)
@ -774,7 +785,8 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
}
if (obj->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *) obj;
commit->buffer = NULL;
if (detach_commit_buffer(commit, NULL) != data)
die("BUG: parse_object_buffer transmogrified our buffer");
}
obj->flags |= FLAG_CHECKED;
}
@ -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;
@ -349,8 +345,7 @@ static int cmd_log_walk(struct rev_info *rev)
rev->max_count++;
if (!rev->reflog_info) {
/* we allow cycles in reflog ancestry */
free(commit->buffer);
commit->buffer = NULL;
free_commit_buffer(commit);
}
free_commit_list(commit->parents);
commit->parents = NULL;
@ -919,9 +914,12 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
log_write_email_headers(rev, head, &pp.subject, &pp.after_subject,
&need_8bit_cte);
for (i = 0; !need_8bit_cte && i < nr; i++)
if (has_non_ascii(list[i]->buffer))
for (i = 0; !need_8bit_cte && i < nr; i++) {
const char *buf = get_commit_buffer(list[i], NULL);
if (has_non_ascii(buf))
need_8bit_cte = 1;
unuse_commit_buffer(list[i], buf);
}
if (!branch_name)
branch_name = find_branch_name(rev);
@ -1508,8 +1506,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
reopen_stdout(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
die(_("Failed to create output files"));
shown = log_tree_commit(&rev, commit);
free(commit->buffer);
commit->buffer = NULL;
free_commit_buffer(commit);
/* We put one extra blank line between formatted
* patches and this flag is used by log-tree code

View File

@ -92,7 +92,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
if (argv[i]) {
int j;
pattern = xcalloc(sizeof(const char *), argc - i + 1);
pattern = xcalloc(argc - i + 1, sizeof(const char *));
for (j = i; j < argc; j++) {
int len = strlen(argv[j]);
char *p = xmalloc(len + 3);

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

@ -852,8 +852,8 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
parent->next->item = remoteheads->item;
parent->next->next = NULL;
prepare_to_commit(remoteheads);
if (commit_tree(&merge_msg, result_tree, parent, result_commit, NULL,
sign_commit))
if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parent,
result_commit, NULL, sign_commit))
die(_("failed to write commit object"));
finish(head, remoteheads, result_commit, "In-index merge");
drop_save();
@ -877,8 +877,8 @@ static int finish_automerge(struct commit *head,
commit_list_insert(head, &parents);
strbuf_addch(&merge_msg, '\n');
prepare_to_commit(remoteheads);
if (commit_tree(&merge_msg, result_tree, parents, result_commit,
NULL, sign_commit))
if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parents,
result_commit, NULL, sign_commit))
die(_("failed to write commit object"));
strbuf_addf(&buf, "Merge made by the '%s' strategy.", wt_strategy);
finish(head, remoteheads, result_commit, buf.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

@ -282,7 +282,7 @@ static int config_read_branches(const char *key, const char *value, void *cb)
item = string_list_insert(&branch_list, name);
if (!item->util)
item->util = xcalloc(sizeof(struct branch_info), 1);
item->util = xcalloc(1, sizeof(struct branch_info));
info = item->util;
if (type == REMOTE) {
if (info->remote_name)
@ -398,7 +398,7 @@ static int get_push_ref_states(const struct ref *remote_refs,
item = string_list_append(&states->push,
abbrev_branch(ref->peer_ref->name));
item->util = xcalloc(sizeof(struct push_info), 1);
item->util = xcalloc(1, sizeof(struct push_info));
info = item->util;
info->forced = ref->force;
info->dest = xstrdup(abbrev_branch(ref->name));
@ -433,7 +433,7 @@ static int get_push_ref_states_noquery(struct ref_states *states)
states->push.strdup_strings = 1;
if (!remote->push_refspec_nr) {
item = string_list_append(&states->push, _("(matching)"));
info = item->util = xcalloc(sizeof(struct push_info), 1);
info = item->util = xcalloc(1, sizeof(struct push_info));
info->status = PUSH_STATUS_NOTQUERIED;
info->dest = xstrdup(item->string);
}
@ -446,7 +446,7 @@ static int get_push_ref_states_noquery(struct ref_states *states)
else
item = string_list_append(&states->push, _("(delete)"));
info = item->util = xcalloc(sizeof(struct push_info), 1);
info = item->util = xcalloc(1, sizeof(struct push_info));
info->forced = spec->force;
info->status = PUSH_STATUS_NOTQUERIED;
info->dest = xstrdup(spec->dst ? spec->dst : item->string);
@ -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

@ -10,6 +10,7 @@
static int delta_base_offset = 1;
static int pack_kept_objects = -1;
static int write_bitmaps = -1;
static char *packdir, *packtmp;
static const char *const git_repack_usage[] = {
@ -27,6 +28,10 @@ static int repack_config(const char *var, const char *value, void *cb)
pack_kept_objects = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "pack.writebitmaps")) {
write_bitmaps = git_config_bool(var, value);
return 0;
}
return git_default_config(var, value, cb);
}
@ -149,7 +154,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
int no_update_server_info = 0;
int quiet = 0;
int local = 0;
int write_bitmap = -1;
struct option builtin_repack_options[] = {
OPT_BIT('a', NULL, &pack_everything,
@ -168,7 +172,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
OPT__QUIET(&quiet, N_("be quiet")),
OPT_BOOL('l', "local", &local,
N_("pass --local to git-pack-objects")),
OPT_BOOL('b', "write-bitmap-index", &write_bitmap,
OPT_BOOL('b', "write-bitmap-index", &write_bitmaps,
N_("write bitmap index")),
OPT_STRING(0, "unpack-unreachable", &unpack_unreachable, N_("approxidate"),
N_("with -A, do not loosen objects older than this")),
@ -191,7 +195,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
git_repack_usage, 0);
if (pack_kept_objects < 0)
pack_kept_objects = write_bitmap;
pack_kept_objects = write_bitmaps > 0;
packdir = mkpathdup("%s/pack", get_object_directory());
packtmp = mkpathdup("%s/.tmp-%d-pack", packdir, (int)getpid());
@ -217,9 +221,9 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
argv_array_pushf(&cmd_args, "--no-reuse-delta");
if (no_reuse_object)
argv_array_pushf(&cmd_args, "--no-reuse-object");
if (write_bitmap >= 0)
if (write_bitmaps >= 0)
argv_array_pushf(&cmd_args, "--%swrite-bitmap-index",
write_bitmap ? "" : "no-");
write_bitmaps ? "" : "no-");
if (pack_everything & ALL_INTO_ONE) {
get_non_kept_pack_filenames(&existing_packs);

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

@ -93,7 +93,7 @@ static int reset_index(const unsigned char *sha1, int reset_type, int quiet)
static void print_new_head_line(struct commit *commit)
{
const char *hex, *body;
char *msg;
const char *msg;
hex = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV);
printf(_("HEAD is now at %s"), hex);
@ -109,7 +109,7 @@ static void print_new_head_line(struct commit *commit)
}
else
printf("\n");
logmsg_free(msg, commit);
unuse_commit_buffer(commit, msg);
}
static void update_index_from_diff(struct diff_queue_struct *q,

View File

@ -106,7 +106,7 @@ static void show_commit(struct commit *commit, void *data)
else
putchar('\n');
if (revs->verbose_header && commit->buffer) {
if (revs->verbose_header && get_cached_commit_buffer(commit, NULL)) {
struct strbuf buf = STRBUF_INIT;
struct pretty_print_context ctx = {0};
ctx.abbrev = revs->abbrev;
@ -173,8 +173,7 @@ static void finish_commit(struct commit *commit, void *data)
free_commit_list(commit->parents);
commit->parents = NULL;
}
free(commit->buffer);
commit->buffer = NULL;
free_commit_buffer(commit);
}
static void finish_object(struct object *obj,

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;
@ -596,6 +597,8 @@ extern int fsync_object_files;
extern int core_preload_index;
extern int core_apply_sparse_checkout;
extern int precomposed_unicode;
extern int protect_hfs;
extern int protect_ntfs;
/*
* The character that begins a commented line in user-editable file
@ -810,6 +813,7 @@ int longest_ancestor_length(const char *path, struct string_list *prefixes);
char *strip_path_suffix(const char *path, const char *suffix);
int daemon_avoid_alias(const char *path);
int offset_1st_component(const char *path);
extern int is_ntfs_dotgit(const char *name);
/* object replacement */
#define LOOKUP_REPLACE_OBJECT 1
@ -1322,6 +1326,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));
@ -1351,6 +1357,7 @@ extern void *alloc_commit_node(void);
extern void *alloc_tag_node(void);
extern void *alloc_object_node(void);
extern void alloc_report(void);
extern unsigned int alloc_commit_index(void);
/* trace.c */
__attribute__((format (printf, 1, 2)))

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

@ -117,4 +117,16 @@ static int stat_ ##slabname## realloc
* catch because GCC silently parses it by default.
*/
/*
* Statically initialize a commit slab named "var". Note that this
* evaluates "stride" multiple times! Example:
*
* struct indegree indegrees = COMMIT_SLAB_INIT(1, indegrees);
*
*/
#define COMMIT_SLAB_INIT(stride, var) { \
COMMIT_SLAB_SIZE / sizeof(**((var).slab)) / (stride), \
(stride), 0, NULL \
}
#endif /* COMMIT_SLAB_H */

158
commit.c
View File

@ -17,20 +17,6 @@ static struct commit_extra_header *read_commit_extra_header_lines(const char *bu
int save_commit_buffer = 1;
const char *commit_type = "commit";
static int commit_count;
static struct commit *check_commit(struct object *obj,
const unsigned char *sha1,
int quiet)
{
if (obj->type != OBJ_COMMIT) {
if (!quiet)
error("Object %s is a %s, not a commit",
sha1_to_hex(sha1), typename(obj->type));
return NULL;
}
return (struct commit *) obj;
}
struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
int quiet)
@ -39,7 +25,7 @@ struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
if (!obj)
return NULL;
return check_commit(obj, sha1, quiet);
return object_as_type(obj, OBJ_COMMIT, quiet);
}
struct commit *lookup_commit_reference(const unsigned char *sha1)
@ -62,14 +48,9 @@ struct commit *lookup_commit_or_die(const unsigned char *sha1, const char *ref_n
struct commit *lookup_commit(const unsigned char *sha1)
{
struct object *obj = lookup_object(sha1);
if (!obj) {
struct commit *c = alloc_commit_node();
c->index = commit_count++;
return create_object(sha1, OBJ_COMMIT, c);
}
if (!obj->type)
obj->type = OBJ_COMMIT;
return check_commit(obj, sha1, 0);
if (!obj)
return create_object(sha1, alloc_commit_node());
return object_as_type(obj, OBJ_COMMIT, 0);
}
struct commit *lookup_commit_reference_by_name(const char *name)
@ -247,6 +228,76 @@ int unregister_shallow(const unsigned char *sha1)
return 0;
}
struct commit_buffer {
void *buffer;
unsigned long size;
};
define_commit_slab(buffer_slab, struct commit_buffer);
static struct buffer_slab buffer_slab = COMMIT_SLAB_INIT(1, buffer_slab);
void set_commit_buffer(struct commit *commit, void *buffer, unsigned long size)
{
struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
v->buffer = buffer;
v->size = size;
}
const void *get_cached_commit_buffer(const struct commit *commit, unsigned long *sizep)
{
struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
if (sizep)
*sizep = v->size;
return v->buffer;
}
const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep)
{
const void *ret = get_cached_commit_buffer(commit, sizep);
if (!ret) {
enum object_type type;
unsigned long size;
ret = read_sha1_file(commit->object.sha1, &type, &size);
if (!ret)
die("cannot read commit object %s",
sha1_to_hex(commit->object.sha1));
if (type != OBJ_COMMIT)
die("expected commit for %s, got %s",
sha1_to_hex(commit->object.sha1), typename(type));
if (sizep)
*sizep = size;
}
return ret;
}
void unuse_commit_buffer(const struct commit *commit, const void *buffer)
{
struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
if (v->buffer != buffer)
free((void *)buffer);
}
void free_commit_buffer(struct commit *commit)
{
struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
free(v->buffer);
v->buffer = NULL;
v->size = 0;
}
const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep)
{
struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
void *ret;
ret = v->buffer;
if (sizep)
*sizep = v->size;
v->buffer = NULL;
v->size = 0;
return ret;
}
int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long size)
{
const char *tail = buffer;
@ -324,7 +375,7 @@ int parse_commit(struct commit *item)
}
ret = parse_commit_buffer(item, buffer, size);
if (save_commit_buffer && !ret) {
item->buffer = buffer;
set_commit_buffer(item, buffer, size);
return 0;
}
free(buffer);
@ -539,22 +590,12 @@ static void record_author_date(struct author_date_slab *author_date,
struct commit *commit)
{
const char *buf, *line_end, *ident_line;
char *buffer = NULL;
const char *buffer = get_commit_buffer(commit, NULL);
struct ident_split ident;
char *date_end;
unsigned long date;
if (!commit->buffer) {
unsigned long size;
enum object_type type;
buffer = read_sha1_file(commit->object.sha1, &type, &size);
if (!buffer)
return;
}
for (buf = commit->buffer ? commit->buffer : buffer;
buf;
buf = line_end + 1) {
for (buf = buffer; buf; buf = line_end + 1) {
line_end = strchrnul(buf, '\n');
ident_line = skip_prefix(buf, "author ");
if (!ident_line) {
@ -575,7 +616,7 @@ static void record_author_date(struct author_date_slab *author_date,
*(author_date_slab_at(author_date, commit)) = date;
fail_exit:
free(buffer);
unuse_commit_buffer(commit, buffer);
}
static int compare_commits_by_author_date(const void *a_, const void *b_,
@ -1031,7 +1072,7 @@ struct commit_list *reduce_heads(struct commit_list *heads)
p->item->object.flags |= STALE;
num_head++;
}
array = xcalloc(sizeof(*array), num_head);
array = xcalloc(num_head, sizeof(*array));
for (p = heads, i = 0; p; p = p->next) {
if (p->item->object.flags & STALE) {
array[i++] = p->item;
@ -1080,17 +1121,14 @@ static int do_sign_commit(struct strbuf *buf, const char *keyid)
return 0;
}
int parse_signed_commit(const unsigned char *sha1,
int parse_signed_commit(const struct commit *commit,
struct strbuf *payload, struct strbuf *signature)
{
unsigned long size;
enum object_type type;
char *buffer = read_sha1_file(sha1, &type, &size);
int in_signature, saw_signature = -1;
char *line, *tail;
if (!buffer || type != OBJ_COMMIT)
goto cleanup;
unsigned long size;
const char *buffer = get_commit_buffer(commit, &size);
int in_signature, saw_signature = -1;
const char *line, *tail;
line = buffer;
tail = buffer + size;
@ -1098,7 +1136,7 @@ int parse_signed_commit(const unsigned char *sha1,
saw_signature = 0;
while (line < tail) {
const char *sig = NULL;
char *next = memchr(line, '\n', tail - line);
const char *next = memchr(line, '\n', tail - line);
next = next ? next + 1 : tail;
if (in_signature && line[0] == ' ')
@ -1119,8 +1157,7 @@ int parse_signed_commit(const unsigned char *sha1,
}
line = next;
}
cleanup:
free(buffer);
unuse_commit_buffer(commit, buffer);
return saw_signature;
}
@ -1211,8 +1248,7 @@ void check_commit_signature(const struct commit* commit, struct signature_check
sigc->result = 'N';
if (parse_signed_commit(commit->object.sha1,
&payload, &signature) <= 0)
if (parse_signed_commit(commit, &payload, &signature) <= 0)
goto out;
status = verify_signed_buffer(payload.buf, payload.len,
signature.buf, signature.len,
@ -1257,11 +1293,9 @@ struct commit_extra_header *read_commit_extra_headers(struct commit *commit,
{
struct commit_extra_header *extra = NULL;
unsigned long size;
enum object_type type;
char *buffer = read_sha1_file(commit->object.sha1, &type, &size);
if (buffer && type == OBJ_COMMIT)
extra = read_commit_extra_header_lines(buffer, size, exclude);
free(buffer);
const char *buffer = get_commit_buffer(commit, &size);
extra = read_commit_extra_header_lines(buffer, size, exclude);
unuse_commit_buffer(commit, buffer);
return extra;
}
@ -1344,7 +1378,8 @@ void free_commit_extra_headers(struct commit_extra_header *extra)
}
}
int commit_tree(const struct strbuf *msg, const unsigned char *tree,
int commit_tree(const char *msg, size_t msg_len,
const unsigned char *tree,
struct commit_list *parents, unsigned char *ret,
const char *author, const char *sign_commit)
{
@ -1352,7 +1387,7 @@ int commit_tree(const struct strbuf *msg, const unsigned char *tree,
int result;
append_merge_tag_headers(parents, &tail);
result = commit_tree_extended(msg, tree, parents, ret,
result = commit_tree_extended(msg, msg_len, tree, parents, ret,
author, sign_commit, extra);
free_commit_extra_headers(extra);
return result;
@ -1473,7 +1508,8 @@ static const char commit_utf8_warn[] =
"You may want to amend it after fixing the message, or set the config\n"
"variable i18n.commitencoding to the encoding your project uses.\n";
int commit_tree_extended(const struct strbuf *msg, const unsigned char *tree,
int commit_tree_extended(const char *msg, size_t msg_len,
const unsigned char *tree,
struct commit_list *parents, unsigned char *ret,
const char *author, const char *sign_commit,
struct commit_extra_header *extra)
@ -1484,7 +1520,7 @@ int commit_tree_extended(const struct strbuf *msg, const unsigned char *tree,
assert_sha1_type(tree, OBJ_TREE);
if (memchr(msg->buf, '\0', msg->len))
if (memchr(msg, '\0', msg_len))
return error("a NUL byte in commit log message not allowed.");
/* Not having i18n.commitencoding is the same as having utf-8 */
@ -1523,7 +1559,7 @@ int commit_tree_extended(const struct strbuf *msg, const unsigned char *tree,
strbuf_addch(&buffer, '\n');
/* And add the comment */
strbuf_addbuf(&buffer, msg);
strbuf_add(&buffer, msg, msg_len);
/* And check the encoding */
if (encoding_is_utf8 && !verify_utf8(&buffer))

View File

@ -20,7 +20,6 @@ struct commit {
unsigned long date;
struct commit_list *parents;
struct tree *tree;
char *buffer;
};
extern int save_commit_buffer;
@ -51,6 +50,44 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s
int parse_commit(struct commit *item);
void parse_commit_or_die(struct commit *item);
/*
* Associate an object buffer with the commit. The ownership of the
* memory is handed over to the commit, and must be free()-able.
*/
void set_commit_buffer(struct commit *, void *buffer, unsigned long size);
/*
* Get any cached object buffer associated with the commit. Returns NULL
* if none. The resulting memory should not be freed.
*/
const void *get_cached_commit_buffer(const struct commit *, unsigned long *size);
/*
* Get the commit's object contents, either from cache or by reading the object
* from disk. The resulting memory should not be modified, and must be given
* to unuse_commit_buffer when the caller is done.
*/
const void *get_commit_buffer(const struct commit *, unsigned long *size);
/*
* Tell the commit subsytem that we are done with a particular commit buffer.
* The commit and buffer should be the input and return value, respectively,
* from an earlier call to get_commit_buffer. The buffer may or may not be
* freed by this call; callers should not access the memory afterwards.
*/
void unuse_commit_buffer(const struct commit *, const void *buffer);
/*
* Free any cached object buffer associated with the commit.
*/
void free_commit_buffer(struct commit *);
/*
* Disassociate any cached object buffer from the commit, but do not free it.
* The buffer (or NULL, if none) is returned.
*/
const void *detach_commit_buffer(struct commit *, unsigned long *sizep);
/* Find beginning and length of commit subject. */
int find_commit_subject(const char *commit_buffer, const char **subject);
@ -115,10 +152,9 @@ struct userformat_want {
extern int has_non_ascii(const char *text);
struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
extern char *logmsg_reencode(const struct commit *commit,
char **commit_encoding,
const char *output_encoding);
extern void logmsg_free(char *msg, const struct commit *commit);
extern const char *logmsg_reencode(const struct commit *commit,
char **commit_encoding,
const char *output_encoding);
extern void get_commit_format(const char *arg, struct rev_info *);
extern const char *format_subject(struct strbuf *sb, const char *msg,
const char *line_separator);
@ -261,11 +297,13 @@ struct commit_extra_header {
extern void append_merge_tag_headers(struct commit_list *parents,
struct commit_extra_header ***tail);
extern int commit_tree(const struct strbuf *msg, const unsigned char *tree,
extern int commit_tree(const char *msg, size_t msg_len,
const unsigned char *tree,
struct commit_list *parents, unsigned char *ret,
const char *author, const char *sign_commit);
extern int commit_tree_extended(const struct strbuf *msg, const unsigned char *tree,
extern int commit_tree_extended(const char *msg, size_t msg_len,
const unsigned char *tree,
struct commit_list *parents, unsigned char *ret,
const char *author, const char *sign_commit,
struct commit_extra_header *);
@ -287,7 +325,7 @@ struct merge_remote_desc {
*/
struct commit *get_merge_parent(const char *name);
extern int parse_signed_commit(const unsigned char *sha1,
extern int parse_signed_commit(const struct commit *commit,
struct strbuf *message, struct strbuf *signature);
extern void print_commit_list(struct commit_list *list,
const char *format_cur,

View File

@ -101,19 +101,34 @@ static inline uint64_t git_bswap64(uint64_t x)
#undef ntohll
#undef htonll
#if !defined(__BYTE_ORDER)
# if defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
# define __BYTE_ORDER BYTE_ORDER
# define __LITTLE_ENDIAN LITTLE_ENDIAN
# define __BIG_ENDIAN BIG_ENDIAN
#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN)
# define GIT_BYTE_ORDER __BYTE_ORDER
# define GIT_LITTLE_ENDIAN __LITTLE_ENDIAN
# define GIT_BIG_ENDIAN __BIG_ENDIAN
#elif defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
# define GIT_BYTE_ORDER BYTE_ORDER
# define GIT_LITTLE_ENDIAN LITTLE_ENDIAN
# define GIT_BIG_ENDIAN BIG_ENDIAN
#else
# define GIT_BIG_ENDIAN 4321
# define GIT_LITTLE_ENDIAN 1234
# if defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
# define GIT_BYTE_ORDER GIT_BIG_ENDIAN
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
# define GIT_BYTE_ORDER GIT_LITTLE_ENDIAN
# else
# error "Cannot determine endianness"
# endif
#endif
#if !defined(__BYTE_ORDER)
# error "Cannot determine endianness"
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
#if GIT_BYTE_ORDER == GIT_BIG_ENDIAN
# define ntohll(n) (n)
# define htonll(n) (n)
#else

View File

@ -1226,8 +1226,7 @@ static int WSAAPI getaddrinfo_stub(const char *node, const char *service,
else
ai->ai_canonname = NULL;
sin = xmalloc(ai->ai_addrlen);
memset(sin, 0, ai->ai_addrlen);
sin = xcalloc(1, ai->ai_addrlen);
sin->sin_family = AF_INET;
/* Note: getaddrinfo is supposed to allow service to be a string,
* which should be looked up using getservbyname. This is

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

@ -874,6 +874,16 @@ static int git_default_core_config(const char *var, const char *value)
return 0;
}
if (!strcmp(var, "core.protecthfs")) {
protect_hfs = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "core.protectntfs")) {
protect_ntfs = git_config_bool(var, value);
return 0;
}
/* Add other config variables here and to Documentation/config.txt. */
return 0;
}
@ -952,7 +962,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);
@ -1538,7 +1548,7 @@ int git_config_set_multivar_in_file(const char *config_filename,
* The lock serves a purpose in addition to locking: the new
* contents of .git/config will be written into it.
*/
lock = xcalloc(sizeof(struct lock_file), 1);
lock = xcalloc(1, sizeof(struct lock_file));
fd = hold_lock_file_for_update(lock, config_filename, 0);
if (fd < 0) {
error("could not lock config file %s: %s", config_filename, strerror(errno));
@ -1793,7 +1803,7 @@ int git_config_rename_section_in_file(const char *config_filename,
if (!config_filename)
config_filename = filename_buf = git_pathdup("config");
lock = xcalloc(sizeof(struct lock_file), 1);
lock = xcalloc(1, sizeof(struct lock_file));
out_fd = hold_lock_file_for_update(lock, config_filename, 0);
if (out_fd < 0) {
ret = error("could not lock config file %s", config_filename);

View File

@ -97,6 +97,7 @@ ifeq ($(uname_S),Darwin)
HAVE_DEV_TTY = YesPlease
COMPAT_OBJS += compat/precompose_utf8.o
BASIC_CFLAGS += -DPRECOMPOSE_UNICODE
BASIC_CFLAGS += -DPROTECT_HFS_DEFAULT=1
endif
ifeq ($(uname_S),SunOS)
NEEDS_SOCKET = YesPlease
@ -157,7 +158,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
@ -362,6 +362,7 @@ ifeq ($(uname_S),Windows)
EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib invalidcontinue.obj
PTHREAD_LIBS =
lib =
BASIC_CFLAGS += -DPROTECT_NTFS_DEFAULT=1
ifndef DEBUG
BASIC_CFLAGS += -GL -Os -MT
BASIC_LDFLAGS += -LTCG
@ -502,6 +503,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
COMPAT_OBJS += compat/mingw.o compat/winansi.o \
compat/win32/pthread.o compat/win32/syslog.o \
compat/win32/dirent.o
BASIC_CFLAGS += -DPROTECT_NTFS_DEFAULT=1
BASIC_LDFLAGS += -Wl,--large-address-aware
EXTLIBS += -lws2_32
GITLIBS += git.res

View File

@ -64,9 +64,7 @@ static void parse_one_symref_info(struct string_list *symref, const char *val, i
if (!len)
return; /* just "symref" */
/* e.g. "symref=HEAD:refs/heads/master" */
sym = xmalloc(len + 1);
memcpy(sym, val, len);
sym[len] = '\0';
sym = xmemdupz(val, len);
target = strchr(sym, ':');
if (!target)
/* just "symref=something" */

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

@ -8,7 +8,8 @@ This test verifies the basic operation of the merge, pull, add
and split subcommands of git subtree.
'
export TEST_DIRECTORY=$(pwd)/../../../t
TEST_DIRECTORY=$(pwd)/../../../t
export TEST_DIRECTORY
. ../../../t/test-lib.sh

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)),

5
diff.c
View File

@ -1361,7 +1361,7 @@ static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat,
const char *name_b)
{
struct diffstat_file *x;
x = xcalloc(sizeof (*x), 1);
x = xcalloc(1, sizeof(*x));
ALLOC_GROW(diffstat->files, diffstat->nr + 1, diffstat->alloc);
diffstat->files[diffstat->nr++] = x;
if (name_b) {
@ -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)

32
dir.c
View File

@ -508,21 +508,25 @@ void clear_exclude_list(struct exclude_list *el)
static void trim_trailing_spaces(char *buf)
{
int i, last_space = -1, nr_spaces, len = strlen(buf);
for (i = 0; i < len; i++)
if (buf[i] == '\\')
i++;
else if (buf[i] == ' ') {
if (last_space == -1) {
last_space = i;
nr_spaces = 1;
} else
nr_spaces++;
} else
last_space = -1;
char *p, *last_space = NULL;
if (last_space != -1 && last_space + nr_spaces == len)
buf[last_space] = '\0';
for (p = buf; *p; p++)
switch (*p) {
case ' ':
if (!last_space)
last_space = p;
break;
case '\\':
p++;
if (!*p)
return;
/* fallthrough */
default:
last_space = NULL;
}
if (last_space)
*last_space = '\0';
}
int add_excludes_from_file_to_list(const char *fname,

View File

@ -64,6 +64,16 @@ int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
struct startup_info *startup_info;
unsigned long pack_size_limit_cfg;
#ifndef PROTECT_HFS_DEFAULT
#define PROTECT_HFS_DEFAULT 0
#endif
int protect_hfs = PROTECT_HFS_DEFAULT;
#ifndef PROTECT_NTFS_DEFAULT
#define PROTECT_NTFS_DEFAULT 0
#endif
int protect_ntfs = PROTECT_NTFS_DEFAULT;
/*
* The character that begins a commented line in user-editable file
* that is subject to stripspace.

18
fsck.c
View File

@ -6,6 +6,7 @@
#include "commit.h"
#include "tag.h"
#include "fsck.h"
#include "utf8.h"
static int fsck_walk_tree(struct tree *tree, fsck_walk_func walk, void *data)
{
@ -170,7 +171,9 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
has_empty_name |= !*name;
has_dot |= !strcmp(name, ".");
has_dotdot |= !strcmp(name, "..");
has_dotgit |= !strcmp(name, ".git");
has_dotgit |= (!strcmp(name, ".git") ||
is_hfs_dotgit(name) ||
is_ntfs_dotgit(name));
has_zero_pad |= *(char *)desc.buffer == '0';
update_tree_entry(&desc);
@ -276,9 +279,10 @@ static int fsck_ident(const char **ident, struct object *obj, fsck_error error_f
return 0;
}
static int fsck_commit(struct commit *commit, fsck_error error_func)
static int fsck_commit_buffer(struct commit *commit, const char *buffer,
fsck_error error_func)
{
const char *buffer = commit->buffer, *tmp;
const char *tmp;
unsigned char tree_sha1[20], sha1[20];
struct commit_graft *graft;
int parents = 0;
@ -336,6 +340,14 @@ static int fsck_commit(struct commit *commit, fsck_error error_func)
return 0;
}
static int fsck_commit(struct commit *commit, fsck_error error_func)
{
const char *buffer = get_commit_buffer(commit, NULL);
int ret = fsck_commit_buffer(commit, buffer, error_func);
unuse_commit_buffer(commit, buffer);
return ret;
}
static int fsck_tag(struct tag *tag, fsck_error error_func)
{
struct object *tagged = tag->tagged;

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

@ -332,7 +332,13 @@ while read commit parents; do
parentstr=
for parent in $parents; do
for reparent in $(map "$parent"); do
parentstr="$parentstr -p $reparent"
case "$parentstr " in
*" -p $reparent "*)
;;
*)
parentstr="$parentstr -p $reparent"
;;
esac
done
done
if [ "$filter_parent" ]; then

View File

@ -345,7 +345,17 @@ PidFile "$fqgitdir/pid"
Listen $bind$port
EOF
for mod in mime dir env log_config
for mod in mpm_event mpm_prefork mpm_worker
do
if test -e $module_path/mod_${mod}.so
then
echo "LoadModule ${mod}_module " \
"$module_path/mod_${mod}.so" >> "$conf"
# only one mpm module permitted
break
fi
done
for mod in mime dir env log_config authz_core
do
if test -e $module_path/mod_${mod}.so
then

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

@ -53,11 +53,12 @@ continue_merge () {
}
call_merge () {
cmt="$(cat "$state_dir/cmt.$1")"
msgnum="$1"
echo "$msgnum" >"$state_dir/msgnum"
cmt="$(cat "$state_dir/cmt.$msgnum")"
echo "$cmt" > "$state_dir/current"
hd=$(git rev-parse --verify HEAD)
cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
msgnum=$(cat "$state_dir/msgnum")
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
eval GITHEAD_$hd='$onto_name'
export GITHEAD_$cmt GITHEAD_$hd

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

@ -13,7 +13,8 @@ refspec="${GIT_REMOTE_TESTGIT_REFSPEC-$default_refspec}"
test -z "$refspec" && prefix="refs"
export GIT_DIR="$url/.git"
GIT_DIR="$url/.git"
export GIT_DIR
force=

View File

@ -94,7 +94,8 @@ create_stash () {
# ease of unpacking later.
u_commit=$(
untracked_files | (
export GIT_INDEX_FILE="$TMPindex"
GIT_INDEX_FILE="$TMPindex" &&
export GIT_INDEX_FILE &&
rm -f "$TMPindex" &&
git update-index -z --add --remove --stdin &&
u_tree=$(git write-tree) &&

View File

@ -607,9 +607,7 @@ int main(int argc, char **argv)
cmd = c;
n = out[0].rm_eo - out[0].rm_so;
cmd_arg = xmalloc(n);
memcpy(cmd_arg, dir + out[0].rm_so + 1, n-1);
cmd_arg[n-1] = '\0';
cmd_arg = xmemdupz(dir + out[0].rm_so + 1, n - 1);
dir[out[0].rm_so] = 0;
break;
}

View File

@ -199,7 +199,7 @@ static void curl_setup_http(CURL *curl, const char *url,
curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);
#ifndef NO_CURL_IOCTL
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, &buffer);
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer);
#endif
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn);
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
@ -1732,7 +1732,7 @@ int main(int argc, char **argv)
git_extract_argv0_path(argv[0]);
repo = xcalloc(sizeof(*repo), 1);
repo = xcalloc(1, sizeof(*repo));
argv++;
for (i = 1; i < argc; i++, argv++) {

View File

@ -951,7 +951,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc)
char *arg, *rsp;
int s = -1, preauth;
ctx = xcalloc(sizeof(*ctx), 1);
ctx = xcalloc(1, sizeof(*ctx));
ctx->imap = imap = xcalloc(sizeof(*imap), 1);
imap->buf.sock.fd[0] = imap->buf.sock.fd[1] = -1;

View File

@ -365,6 +365,7 @@ static void show_sig_lines(struct rev_info *opt, int status, const char *bol)
eol = strchrnul(bol, '\n');
printf("%s%.*s%s%s", color, (int)(eol - bol), bol, reset,
*eol ? "\n" : "");
graph_show_oneline(opt->graph);
bol = (*eol) ? (eol + 1) : eol;
}
}
@ -376,7 +377,7 @@ static void show_signature(struct rev_info *opt, struct commit *commit)
struct strbuf gpg_output = STRBUF_INIT;
int status;
if (parse_signed_commit(commit->object.sha1, &payload, &signature) <= 0)
if (parse_signed_commit(commit, &payload, &signature) <= 0)
goto out;
status = verify_signed_buffer(payload.buf, payload.len,
@ -446,16 +447,17 @@ static void show_one_mergetag(struct rev_info *opt,
payload_size = parse_signature(extra->value, extra->len);
status = -1;
if (extra->len > payload_size)
if (verify_signed_buffer(extra->value, payload_size,
extra->value + payload_size,
extra->len - payload_size,
&verify_message, NULL)) {
if (verify_message.len <= gpg_message_offset)
strbuf_addstr(&verify_message, "No signature\n");
else
status = 0;
}
if (extra->len > payload_size) {
/* could have a good signature */
if (!verify_signed_buffer(extra->value, payload_size,
extra->value + payload_size,
extra->len - payload_size,
&verify_message, NULL))
status = 0; /* good */
else if (verify_message.len <= gpg_message_offset)
strbuf_addstr(&verify_message, "No signature\n");
/* otherwise we couldn't verify, which is shown as bad */
}
show_sig_lines(opt, status, verify_message.buf);
strbuf_release(&verify_message);
@ -588,7 +590,7 @@ void show_log(struct rev_info *opt)
show_mergetag(opt, commit);
}
if (!commit->buffer)
if (!get_cached_commit_buffer(commit, NULL))
return;
if (opt->show_notes) {

View File

@ -40,7 +40,7 @@ static struct tree *shift_tree_object(struct tree *one, struct tree *two,
static struct commit *make_virtual_commit(struct tree *tree, const char *comment)
{
struct commit *commit = xcalloc(1, sizeof(struct commit));
struct commit *commit = alloc_commit_node();
struct merge_remote_desc *desc = xmalloc(sizeof(*desc));
desc->name = comment;
@ -190,9 +190,11 @@ static void output_commit_title(struct merge_options *o, struct commit *commit)
printf(_("(bad commit)\n"));
else {
const char *title;
int len = find_commit_subject(commit->buffer, &title);
const char *msg = get_commit_buffer(commit, NULL);
int len = find_commit_subject(msg, &title);
if (len)
printf("%.*s\n", len, title);
unuse_commit_buffer(commit, msg);
}
}
}
@ -589,6 +591,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

@ -48,7 +48,6 @@ int notes_cache_write(struct notes_cache *c)
{
unsigned char tree_sha1[20];
unsigned char commit_sha1[20];
struct strbuf msg = STRBUF_INIT;
if (!c || !c->tree.initialized || !c->tree.ref || !*c->tree.ref)
return -1;
@ -57,9 +56,8 @@ int notes_cache_write(struct notes_cache *c)
if (write_notes_tree(&c->tree, tree_sha1))
return -1;
strbuf_attach(&msg, c->validity,
strlen(c->validity), strlen(c->validity) + 1);
if (commit_tree(&msg, tree_sha1, NULL, commit_sha1, NULL, NULL) < 0)
if (commit_tree(c->validity, strlen(c->validity), tree_sha1, NULL,
commit_sha1, NULL, NULL) < 0)
return -1;
if (update_ref("update notes cache", c->tree.ref, commit_sha1, NULL,
0, QUIET_ON_ERR) < 0)

View File

@ -644,7 +644,8 @@ int notes_merge(struct notes_merge_options *o,
struct commit_list *parents = NULL;
commit_list_insert(remote, &parents); /* LIFO order */
commit_list_insert(local, &parents);
create_notes_commit(local_tree, parents, &o->commit_msg,
create_notes_commit(local_tree, parents,
o->commit_msg.buf, o->commit_msg.len,
result_sha1);
}
@ -671,8 +672,8 @@ int notes_merge_commit(struct notes_merge_options *o,
DIR *dir;
struct dirent *e;
struct strbuf path = STRBUF_INIT;
char *msg = strstr(partial_commit->buffer, "\n\n");
struct strbuf sb_msg = STRBUF_INIT;
const char *buffer = get_commit_buffer(partial_commit, NULL);
const char *msg = strstr(buffer, "\n\n");
int baselen;
strbuf_addstr(&path, git_path(NOTES_MERGE_WORKTREE));
@ -719,9 +720,9 @@ int notes_merge_commit(struct notes_merge_options *o,
strbuf_setlen(&path, baselen);
}
strbuf_attach(&sb_msg, msg, strlen(msg), strlen(msg) + 1);
create_notes_commit(partial_tree, partial_commit->parents, &sb_msg,
result_sha1);
create_notes_commit(partial_tree, partial_commit->parents,
msg, strlen(msg), result_sha1);
unuse_commit_buffer(partial_commit, buffer);
if (o->verbosity >= 4)
printf("Finalized notes merge commit: %s\n",
sha1_to_hex(result_sha1));

View File

@ -4,7 +4,8 @@
#include "notes-utils.h"
void create_notes_commit(struct notes_tree *t, struct commit_list *parents,
const struct strbuf *msg, unsigned char *result_sha1)
const char *msg, size_t msg_len,
unsigned char *result_sha1)
{
unsigned char tree_sha1[20];
@ -25,7 +26,7 @@ void create_notes_commit(struct notes_tree *t, struct commit_list *parents,
/* else: t->ref points to nothing, assume root/orphan commit */
}
if (commit_tree(msg, tree_sha1, parents, result_sha1, NULL, NULL))
if (commit_tree(msg, msg_len, tree_sha1, parents, result_sha1, NULL, NULL))
die("Failed to commit notes tree to database");
}
@ -46,7 +47,7 @@ void commit_notes(struct notes_tree *t, const char *msg)
if (buf.buf[buf.len - 1] != '\n')
strbuf_addch(&buf, '\n'); /* Make sure msg ends with newline */
create_notes_commit(t, NULL, &buf, commit_sha1);
create_notes_commit(t, NULL, buf.buf, buf.len, commit_sha1);
strbuf_insert(&buf, 0, "notes: ", 7); /* commit message starts at index 7 */
update_ref(buf.buf, t->ref, commit_sha1, NULL, 0, DIE_ON_ERR);

View File

@ -15,7 +15,7 @@
* The resulting commit SHA1 is stored in result_sha1.
*/
void create_notes_commit(struct notes_tree *t, struct commit_list *parents,
const struct strbuf *msg, unsigned char *result_sha1);
const char *msg, size_t msg_len, unsigned char *result_sha1);
void commit_notes(struct notes_tree *t, const char *msg);

View File

@ -303,7 +303,7 @@ static int note_tree_insert(struct notes_tree *t, struct int_node *tree,
free(entry);
return 0;
}
new_node = (struct int_node *) xcalloc(sizeof(struct int_node), 1);
new_node = (struct int_node *) xcalloc(1, sizeof(struct int_node));
ret = note_tree_insert(t, new_node, n + 1, l, GET_PTR_TYPE(*p),
combine_notes);
if (ret)
@ -443,7 +443,7 @@ static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
if (len <= 20) {
type = PTR_TYPE_NOTE;
l = (struct leaf_node *)
xcalloc(sizeof(struct leaf_node), 1);
xcalloc(1, sizeof(struct leaf_node));
hashcpy(l->key_sha1, object_sha1);
hashcpy(l->val_sha1, entry.sha1);
if (len < 20) {
@ -1003,7 +1003,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
if (!combine_notes)
combine_notes = combine_notes_concatenate;
t->root = (struct int_node *) xcalloc(sizeof(struct int_node), 1);
t->root = (struct int_node *) xcalloc(1, sizeof(struct int_node));
t->first_non_note = NULL;
t->prev_non_note = NULL;
t->ref = notes_ref ? xstrdup(notes_ref) : NULL;

View File

@ -141,13 +141,12 @@ static void grow_object_hash(void)
obj_hash_size = new_hash_size;
}
void *create_object(const unsigned char *sha1, int type, void *o)
void *create_object(const unsigned char *sha1, void *o)
{
struct object *obj = o;
obj->parsed = 0;
obj->used = 0;
obj->type = type;
obj->flags = 0;
hashcpy(obj->sha1, sha1);
@ -159,11 +158,30 @@ void *create_object(const unsigned char *sha1, int type, void *o)
return obj;
}
void *object_as_type(struct object *obj, enum object_type type, int quiet)
{
if (obj->type == type)
return obj;
else if (obj->type == OBJ_NONE) {
if (type == OBJ_COMMIT)
((struct commit *)obj)->index = alloc_commit_index();
obj->type = type;
return obj;
}
else {
if (!quiet)
error("object %s is a %s, not a %s",
sha1_to_hex(obj->sha1),
typename(obj->type), typename(type));
return NULL;
}
}
struct object *lookup_unknown_object(const unsigned char *sha1)
{
struct object *obj = lookup_object(sha1);
if (!obj)
obj = create_object(sha1, OBJ_NONE, alloc_object_node());
obj = create_object(sha1, alloc_object_node());
return obj;
}
@ -197,8 +215,8 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
if (commit) {
if (parse_commit_buffer(commit, buffer, size))
return NULL;
if (!commit->buffer) {
commit->buffer = buffer;
if (!get_cached_commit_buffer(commit, NULL)) {
set_commit_buffer(commit, buffer, size);
*eaten_p = 1;
}
obj = &commit->object;
@ -214,8 +232,6 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
warning("object %s has unknown type id %d", sha1_to_hex(sha1), type);
obj = NULL;
}
if (obj && obj->type == OBJ_NONE)
obj->type = type;
return obj;
}

View File

@ -79,7 +79,9 @@ extern struct object *get_indexed_object(unsigned int);
*/
struct object *lookup_object(const unsigned char *sha1);
extern void *create_object(const unsigned char *sha1, int type, void *obj);
extern void *create_object(const unsigned char *sha1, void *obj);
void *object_as_type(struct object *obj, enum object_type type, int quiet);
/*
* Returns the object, having parsed it to find out what it is.

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

@ -45,7 +45,7 @@ static void init_pack_revindex(void)
if (!num)
return;
pack_revindex_hashsz = num * 11;
pack_revindex = xcalloc(sizeof(*pack_revindex), pack_revindex_hashsz);
pack_revindex = xcalloc(pack_revindex_hashsz, sizeof(*pack_revindex));
for (p = packed_git; p; p = p->next) {
num = pack_revindex_ix(p);
num = - 1 - num;

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;
/*

37
path.c
View File

@ -249,9 +249,7 @@ int validate_headref(const char *path)
static struct passwd *getpw_str(const char *username, size_t len)
{
struct passwd *pw;
char *username_z = xmalloc(len + 1);
memcpy(username_z, username, len);
username_z[len] = '\0';
char *username_z = xmemdupz(username, len);
pw = getpwnam(username_z);
free(username_z);
return pw;
@ -830,3 +828,36 @@ int offset_1st_component(const char *path)
return 2 + is_dir_sep(path[2]);
return is_dir_sep(path[0]);
}
static int only_spaces_and_periods(const char *path, size_t len, size_t skip)
{
if (len < skip)
return 0;
len -= skip;
path += skip;
while (len-- > 0) {
char c = *(path++);
if (c != ' ' && c != '.')
return 0;
}
return 1;
}
int is_ntfs_dotgit(const char *name)
{
int len;
for (len = 0; ; len++)
if (!name[len] || name[len] == '\\' || is_dir_sep(name[len])) {
if (only_spaces_and_periods(name, len, 4) &&
!strncasecmp(name, ".git", 4))
return 1;
if (only_spaces_and_periods(name, len, 5) &&
!strncasecmp(name, "git~1", 5))
return 1;
if (name[len] != '\\')
return 0;
name += len + 1;
len = -1;
}
}

View File

@ -389,8 +389,7 @@ void parse_pathspec(struct pathspec *pathspec,
if (!(flags & PATHSPEC_PREFER_CWD))
die("BUG: PATHSPEC_PREFER_CWD requires arguments");
pathspec->items = item = xmalloc(sizeof(*item));
memset(item, 0, sizeof(*item));
pathspec->items = item = xcalloc(1, sizeof(*item));
item->match = prefix;
item->original = prefix;
item->nowildcard_len = item->len = strlen(prefix);

View File

@ -274,7 +274,7 @@ static void add_rfc822_quoted(struct strbuf *out, const char *s, int len)
enum rfc2047_type {
RFC2047_SUBJECT,
RFC2047_ADDRESS,
RFC2047_ADDRESS
};
static int is_rfc2047_special(char ch, enum rfc2047_type type)
@ -606,29 +606,16 @@ static char *replace_encoding_header(char *buf, const char *encoding)
return strbuf_detach(&tmp, NULL);
}
char *logmsg_reencode(const struct commit *commit,
char **commit_encoding,
const char *output_encoding)
const char *logmsg_reencode(const struct commit *commit,
char **commit_encoding,
const char *output_encoding)
{
static const char *utf8 = "UTF-8";
const char *use_encoding;
char *encoding;
char *msg = commit->buffer;
const char *msg = get_commit_buffer(commit, NULL);
char *out;
if (!msg) {
enum object_type type;
unsigned long size;
msg = read_sha1_file(commit->object.sha1, &type, &size);
if (!msg)
die("Cannot read commit object %s",
sha1_to_hex(commit->object.sha1));
if (type != OBJ_COMMIT)
die("Expected commit for '%s', got %s",
sha1_to_hex(commit->object.sha1), typename(type));
}
if (!output_encoding || !*output_encoding) {
if (commit_encoding)
*commit_encoding =
@ -652,12 +639,13 @@ char *logmsg_reencode(const struct commit *commit,
* Otherwise, we still want to munge the encoding header in the
* result, which will be done by modifying the buffer. If we
* are using a fresh copy, we can reuse it. But if we are using
* the cached copy from commit->buffer, we need to duplicate it
* to avoid munging commit->buffer.
* the cached copy from get_commit_buffer, we need to duplicate it
* to avoid munging the cached copy.
*/
out = msg;
if (out == commit->buffer)
out = xstrdup(out);
if (msg == get_cached_commit_buffer(commit, NULL))
out = xstrdup(msg);
else
out = (char *)msg;
}
else {
/*
@ -667,8 +655,8 @@ char *logmsg_reencode(const struct commit *commit,
* copy, we can free it.
*/
out = reencode_string(msg, output_encoding, use_encoding);
if (out && msg != commit->buffer)
free(msg);
if (out)
unuse_commit_buffer(commit, msg);
}
/*
@ -687,12 +675,6 @@ char *logmsg_reencode(const struct commit *commit,
return out ? out : msg;
}
void logmsg_free(char *msg, const struct commit *commit)
{
if (msg != commit->buffer)
free(msg);
}
static int mailmap_name(const char **email, size_t *email_len,
const char **name, size_t *name_len)
{
@ -796,7 +778,7 @@ struct format_commit_context {
struct signature_check signature_check;
enum flush_type flush_type;
enum trunc_type truncate;
char *message;
const char *message;
char *commit_encoding;
size_t width, indent1, indent2;
int auto_color;
@ -1267,6 +1249,8 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
if (c->signature_check.key)
strbuf_addstr(sb, c->signature_check.key);
break;
default:
return 0;
}
return 2;
}
@ -1506,13 +1490,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;
@ -1531,7 +1520,7 @@ void format_commit_message(const struct commit *commit,
}
free(context.commit_encoding);
logmsg_free(context.message, commit);
unuse_commit_buffer(commit, context.message);
free(context.signature_check.gpg_output);
free(context.signature_check.signer);
}
@ -1700,7 +1689,7 @@ void pretty_print_commit(struct pretty_print_context *pp,
unsigned long beginning_of_body;
int indent = 4;
const char *msg;
char *reencoded;
const char *reencoded;
const char *encoding;
int need_8bit_cte = pp->need_8bit_cte;
@ -1767,7 +1756,7 @@ void pretty_print_commit(struct pretty_print_context *pp,
if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body)
strbuf_addch(sb, '\n');
logmsg_free(reencoded, commit);
unuse_commit_buffer(commit, reencoded);
}
void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit,

View File

@ -14,6 +14,7 @@
#include "resolve-undo.h"
#include "strbuf.h"
#include "varint.h"
#include "utf8.h"
static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
unsigned int options);
@ -756,9 +757,10 @@ static int verify_dotfile(const char *rest)
* shares the path end test with the ".." case.
*/
case 'g':
if (rest[1] != 'i')
case 'G':
if (rest[1] != 'i' && rest[1] != 'I')
break;
if (rest[2] != 't')
if (rest[2] != 't' && rest[2] != 'T')
break;
rest += 2;
/* fallthrough */
@ -782,6 +784,10 @@ int verify_path(const char *path)
return 1;
if (is_dir_sep(c)) {
inside:
if (protect_hfs && is_hfs_dotgit(path))
return 0;
if (protect_ntfs && is_ntfs_dotgit(path))
return 0;
c = *path++;
if ((c == '.' && !verify_dotfile(path)) ||
is_dir_sep(c) || c == '\0')
@ -1477,6 +1483,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 +1767,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 +1830,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);

View File

@ -41,7 +41,7 @@ static int read_one_reflog(unsigned char *osha1, unsigned char *nsha1,
static struct complete_reflogs *read_complete_reflog(const char *ref)
{
struct complete_reflogs *reflogs =
xcalloc(sizeof(struct complete_reflogs), 1);
xcalloc(1, sizeof(struct complete_reflogs));
reflogs->ref = xstrdup(ref);
for_each_reflog_ent(ref, read_one_reflog, reflogs);
if (reflogs->nr == 0) {
@ -135,7 +135,7 @@ struct reflog_walk_info {
void init_reflog_walk(struct reflog_walk_info** info)
{
*info = xcalloc(sizeof(struct reflog_walk_info), 1);
*info = xcalloc(1, sizeof(struct reflog_walk_info));
}
int add_reflog_for_walk(struct reflog_walk_info *info,
@ -199,7 +199,7 @@ int add_reflog_for_walk(struct reflog_walk_info *info,
= reflogs;
}
commit_reflog = xcalloc(sizeof(struct commit_reflog), 1);
commit_reflog = xcalloc(1, sizeof(struct commit_reflog));
if (recno < 0) {
commit_reflog->recno = get_reflog_recno_by_time(reflogs, timestamp);
if (commit_reflog->recno < 0) {
@ -242,7 +242,7 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
return;
}
commit->parents = xcalloc(sizeof(struct commit_list), 1);
commit->parents = xcalloc(1, sizeof(struct commit_list));
commit->parents->item = commit_info->commit;
}

24
refs.c
View File

@ -1520,9 +1520,8 @@ static enum peel_status peel_object(const unsigned char *name, unsigned char *sh
if (o->type == OBJ_NONE) {
int type = sha1_object_info(name, NULL);
if (type < 0)
if (type < 0 || !object_as_type(o, type, 0))
return PEEL_INVALID;
o->type = type;
}
if (o->type != OBJ_TAG)
@ -1611,6 +1610,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 +1625,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 +1643,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 +2447,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 *);
/*

Some files were not shown because too many files have changed in this diff Show More