Commit Graph

150 Commits

Author SHA1 Message Date
Jakob Pfender
b74c867a1a blob: Stat path inside git_blob_create_fromfile
00582bc introduced a change that required the caller of
git_blob_create_fromfile() to pass a struct stat with the stat
information for the file. Several developers pointed out that this would
make life hard for the bindings developers as struct stat isn't widely
supported by other languages.

Make git_blob_create_fromfile() stat the path itself, eliminating the
need for the file to be stat'ed by the caller. This makes
index_init_entry() more costly as the file will be stat'ed twice but
makes life easier for everyone else.
2011-06-07 12:54:43 +02:00
Jakob Pfender
c1a2a14e02 index: Correctly write entry mode
The entry mode flags for an entry created from a path name were not
correctly written if the entry was a symlink. The st_mode of a statted
symlink is 0120777, however git requires the mode to read 0120000,
because it does not care about permissions of symlinks.

Introduce index_create_mode() that correctly writes the mode flags in
the form expected by git.
2011-06-07 12:54:37 +02:00
Jakob Pfender
1869b31e0c index/fileops: Correctly process symbolic links
gitfo_exists() used to error out if the given file was a symbolic link,
due to access() returning an error code. This is not expected behaviour,
as gitfo_exists() should only check whether the file itself exists, not
its link target if it is a symbolic link.

Fix this by calling gitfo_lstat() instead, which is just a wrapper for
lstat().

Also fix the same error in index_init_entry().
2011-06-07 12:54:37 +02:00
Jakob Pfender
4d7905c579 blob: Require stat information for git_blob_create_fromfile()
In order to be able to write symlinks with git_blob_create_fromfile(),
we need to check whether the file to be written is a symbolic link or
not. Since the calling function of git_blob_create_fromfile() is likely to have
stated the file before calling, we make it pass the stat.

The reason for this is that writing symbolic link blobs is significantly
different from writing ordinary files - we do not want to open the link
destination but instead want to write the link itself, regardless of
whether it exists or not.

Previously, index_init_entry() used to error out if the file to be added
was a symlink that pointed to a nonexistent file. Fix this behaviour to
add the file regardless of whether it exists. This mimics git.git's
behaviour.
2011-06-07 12:54:36 +02:00
Romain Geissler
f11e079733 Index: API uniformisation: Use unsigned int for all index number.
Feature Added: Search an unmerged entry by path (git_index_get_unmerged
renamed to git_index_get_unmerged_bypath) or by index (git_index_get_unmerged_byindex).
2011-06-05 21:19:03 +02:00
Vicent Marti
3a42e0a370 index: Add git_index_entry_stage method
As suggested by Romain-Geissler
2011-06-03 21:38:55 +02:00
Vicent Martí
a7fdce6206 Merge pull request #223 from carlosmn/valgrind
Plug a leak in the index unmerged entries vector
2011-06-01 12:53:16 -07:00
Vicent Marti
786ad84fa9 index: Cleanup tree parsing 2011-06-01 18:54:56 +02:00
Carlos Martín Nieto
a02fc2cd16 index: correctly parse invalidated TREE extensions
A TREE extension with an entry count of -1 means that it was
invalidated and we should ignore it. Do so instead of returning an
error.

This fixes issue #202

Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
2011-06-01 18:54:56 +02:00
Carlos Martín Nieto
cdd9fd473e Allow read_tree_internal to return an error code
There are two reasons why read_tree_internal might return a NULL
tree. The first one is a corrupt index, but the second one is an
invalidated TREE extension. Up to now, its only way to communicate
with its caller was through the return value being NULL or not.

Allow read_tree_internal to report its exit status independently from
the tree pointer.

Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
2011-06-01 18:54:56 +02:00
Vicent Marti
f7e59c4dcf index: Change the memory management for repo indexes
The `git_repository_index` call now returns a brand new index that must
be manually free'd.
2011-06-01 18:54:47 +02:00
Carlos Martín Nieto
71da57aefd Plug a leak in the index unmerged entries vector
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
2011-05-31 16:49:15 +02:00
Vicent Marti
8146fe7cb9 index: Fix unused error messages 2011-05-23 21:41:13 +03:00
Jakob Pfender
d320c52d3b index.c: Move to new error handling mechanism 2011-05-23 21:39:56 +03:00
Vicent Marti
f4e2aca29c index: Fix issues in the unmerged entries API 2011-05-19 20:38:17 +03:00
Jakob Pfender
9d27fd3bee index.c: Fix typo
git__rethrow was missing an underscore.
2011-05-17 16:51:37 +02:00
Jakob Pfender
c90bfec7aa Move index.c to new error handling mechanism 2011-05-17 16:21:14 +02:00
Jakob Pfender
050e8877dd Merge branch 'development' into unmerged 2011-05-17 15:31:05 +02:00
Jason R. McNeil
773bc20dd3 Fix misspelling of git_index_append2 (was git_index_apppend2). 2011-05-03 22:22:42 -07:00
Vicent Marti
1648fbd344 Re-apply missing patches 2011-05-02 01:12:53 +03:00
Jakob Pfender
e3c7786b22 index.c: Remove duplicate function declaration
read_unmerged_internal() was present twice.
2011-04-28 17:31:13 +02:00
Vicent Marti
f7a5058aaf index: Refactor add/replace methods
Removed the optional `replace` argument, we now have 4 add methods:

	`git_index_add`: add or update from path
	`git_index_add2`: add or update from struct
	`git_index_append`: add without replacing from path
	`git_index_append2`: add without replacing from struct

Yes, this breaks the bindings.
2011-04-24 00:31:43 +03:00
Jakob Pfender
4c0b6a6dac index: Add API for unmerged entries
New external functions:
	- git_index_unmerged_entrycount: Counts the unmerged entries in
	  the index
	- git_index_get_unmerged: Gets an unmerged entry from the index
	  by name

New internal functions:
	- read_unmerged: Wrapper for read_unmerged_internal
	- read_unmerged_internal: Reads unmerged entries from the index
	  if the index has the INDEX_EXT_UNMERGED_SIG set
	- unmerged_srch: Search function for unmerged vector
	- unmerged_cmp: Compare function for unmerged vector

New data structures:
	- git_index now contains a git_vector unmerged that stores
	  unmerged entries
	- git_index_entry_unmerged: Representation of an unmerged file
	  entry. It represents all three versions of the file at the
	  same time, with one name, three modes and three OIDs
2011-04-21 10:54:54 +02:00
Jakob Pfender
729b6f4900 index: Allow user to toggle whether to replace an index entry
When in the middle of a merge, the index needs to contain several files
with the same name. git_index_insert() used to prevent this by not adding a new entry if an entry with the same name already existed.
2011-04-21 10:40:54 +02:00
Vicent Marti
c6e65acae6 Properly check strtol for errors
We are now using a custom `strtol` implementation to make sure we're not
missing any overflow errors.
2011-04-09 15:22:11 -07:00
schu
683581a3e9 index.c: Fix tiny typos 2011-03-28 17:59:13 +02:00
Jakob Pfender
3bdc0d4c8c index.c: Read index after initialization
The current behaviour of git_index_open{bare,inrepo}() is unexpected.
When an index is opened, an in-memory index object is created that is
linked to the index discovered by git_repository_open(). However, this
index object is empty, as the on-disk index is not read. To fully open
the on-disk index file, git_index_read() has to be called. This leads to
confusing behaviour. Consider the following code:

	git_index *idx;
	git_index_open_inrepo(&idx, repo);
	git_index_write(idx);

You would expect this to have no effect, as the index is never
ostensibly manipulated. However, what actually happens is that the index
entries are removed from the on-disk index because the empty in-memory
index object created by open_inrepo() is written back to the disk.

This patch reads the index after opening it.
2011-03-25 00:49:47 +02:00
nulltoken
56d8ca266c Switch from time_t to git_time_t
git_time_t is defined as a signed 64 integer. This allows a true predictable multiplatform behavior.
2011-03-23 00:07:58 +02:00
Vicent Marti
72a3fe42fb I broke your bindings
Hey. Apologies in advance -- I broke your bindings.

This is a major commit that includes a long-overdue redesign of the
whole object-database structure. This is expected to be the last major
external API redesign of the library until the first non-alpha release.

Please get your bindings up to date with these changes. They will be
included in the next minor release. Sorry again!

Major features include:

	- Real caching and refcounting on parsed objects
	- Real caching and refcounting on objects read from the ODB
	- Streaming writes & reads from the ODB
	- Single-method writes for all object types
	- The external API is now partially thread-safe

The speed increases are significant in all aspects, specially when
reading an object several times from the ODB (revwalking) and when
writing big objects to the ODB.

Here's a full changelog for the external API:

blob.h
------

	- Remove `git_blob_new`
	- Remove `git_blob_set_rawcontent`
	- Remove `git_blob_set_rawcontent_fromfile`
	- Rename `git_blob_writefile` -> `git_blob_create_fromfile`
	- Change `git_blob_create_fromfile`:
		The `path` argument is now relative to the repository's working dir
	- Add `git_blob_create_frombuffer`

commit.h
--------

	- Remove `git_commit_new`
	- Remove `git_commit_add_parent`
	- Remove `git_commit_set_message`
	- Remove `git_commit_set_committer`
	- Remove `git_commit_set_author`
	- Remove `git_commit_set_tree`

	- Add `git_commit_create`
	- Add `git_commit_create_v`
	- Add `git_commit_create_o`
	- Add `git_commit_create_ov`

tag.h
-----

	- Remove `git_tag_new`
	- Remove `git_tag_set_target`
	- Remove `git_tag_set_name`
	- Remove `git_tag_set_tagger`
	- Remove `git_tag_set_message`

	- Add `git_tag_create`
	- Add `git_tag_create_o`

tree.h
------

	- Change `git_tree_entry_2object`:
		New signature is `(git_object **object_out, git_repository *repo, git_tree_entry *entry)`

	- Remove `git_tree_new`
	- Remove `git_tree_add_entry`
	- Remove `git_tree_remove_entry_byindex`
	- Remove `git_tree_remove_entry_byname`
	- Remove `git_tree_clearentries`
	- Remove `git_tree_entry_set_id`
	- Remove `git_tree_entry_set_name`
	- Remove `git_tree_entry_set_attributes`

object.h
------------

	- Remove `git_object_new
	- Remove `git_object_write`

	- Change `git_object_close`:
		This method is now *mandatory*. Not closing an object causes a
		memory leak.

odb.h
-----

	- Remove type `git_rawobj`
	- Remove `git_rawobj_close`
	- Rename `git_rawobj_hash` -> `git_odb_hash`
	- Change `git_odb_hash`:
		New signature is `(git_oid *id, const void *data, size_t len, git_otype type)`

	- Add type `git_odb_object`
	- Add `git_odb_object_close`

	- Change `git_odb_read`:
		New signature is `(git_odb_object **out, git_odb *db, const git_oid *id)`
	- Change `git_odb_read_header`:
		New signature is `(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id)`
	- Remove `git_odb_write`
	- Add `git_odb_open_wstream`
	- Add `git_odb_open_rstream`

odb_backend.h
-------------

	- Change type `git_odb_backend`:
		New internal signatures are as follows

			int (* read)(void **, size_t *, git_otype *, struct git_odb_backend *, const git_oid *)
			int (* read_header)(size_t *, git_otype *, struct git_odb_backend *, const git_oid *)
			int (* writestream)(struct git_odb_stream **, struct git_odb_backend *, size_t, git_otype)
			int (* readstream)( struct git_odb_stream **, struct git_odb_backend *, const git_oid *)

	- Add type `git_odb_stream`
	- Add enum `git_odb_streammode`

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2011-03-20 21:45:11 +02:00
Vicent Marti
971c90befe Do not free the index if it's owned by a repository
Signed-off-by: Vicent Marti <tanoku@gmail.com>
2011-03-03 20:23:52 +02:00
Vicent Marti
86d7e1ca6f Fix searching in git_vector
We now store only one sorting callback that does entry comparison. This
is used when sorting the entries using a quicksort, and when looking for
a specific entry with the new search methods.

The following search methods now exist:

	git_vector_search(vector, entry)
	git_vector_search2(vector, custom_search_callback, key)

	git_vector_bsearch(vector, entry)
	git_vector_bsearch2(vector, custom_search_callback, key)

The sorting state of the vector is now stored internally.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2011-03-03 20:23:52 +02:00
Vicent Marti
817c28201e Rewrite all file IO for more performance
The new `git_filebuf` structure provides atomic high-performance writes
to disk by using a write cache, and optionally a double-buffered scheme
through a worker thread (not enabled yet).

Writes can be done 3-layered, like in git.git (user code -> write cache
-> disk), or 2-layered, by writing directly on the cache. This makes
index writing considerably faster.

The `git_filebuf` structure contains all the old functionality of
`git_filelock` for atomic file writes and reads. The `git_filelock`
structure has been removed.

Additionally, the `git_filebuf` API allows to automatically hash (SHA1)
all the data as it is written to disk (hashing is done smartly on big
chunks to improve performance).

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2011-02-21 18:13:43 +02:00
Vicent Marti
e822508a05 Disable threaded index writing by default
The interlocking on the write threads was not being done properly (index
entries were sometimes written out of order). With proper interlocking,
the threaded write is only marginally faster on big index files, and
slower on the smaller ones because of the overhead when creating
threads.

The threaded index writing has been temporarily disabled; after more
accurate benchmarks, if might be possible to enable it again only when
writing very large index files (> 1000 entries).

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2011-02-18 10:29:55 +02:00
Vicent Marti
084c193562 Fix type truncation in index entries
64-bit types stored in memory have to be truncated into 32 bits when
writing to disk. Was causing warnings in MSVC.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2011-02-17 23:32:22 +02:00
Vicent Marti
348c7335dd Improve the performance when writing Index files
In response to issue #60 (git_index_write really slow), the write_index
function has been rewritten to improve its performance -- it should now
be in par with the performance of git.git.

On top of that, if Posix Threads are available when compiling libgit2, a
new threaded writing system will be used (3 separate threads take care
of solving byte-endianness, hashing the contents of the index and
writing to disk, respectively). For very long Index files, this method
is up to 3x times faster than git.git.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2011-02-17 23:20:47 +02:00
Vicent Marti
995f9c34a5 Use the new git__joinpath to build paths in methods
The `git__joinpath` function has been changed to use a statically
allocated buffer; we assume the buffer to be 4096 bytes, because fuck
you.

The new method also supports an arbritrary number of paths to join,
which may come in handy in the future.

Some methods which were manually joining paths with `strcpy` now use the
new function, namely those in `index.c` and `refs.c`.

Based on Emeric Fermas' original patch, which was using the old
`git__joinpath` because I'm stupid. Thanks!

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2011-02-09 12:43:19 +02:00
Alex Budovski
f0bde7fac0 Revised platform types to use 'best supported' size.
This will allow graceful migration to 64 bit file sizes and timestamps should
git's binary interface be extended to allow this.
2011-01-11 18:31:55 +11:00
Alex Budovski
0a3bcad07e Fix Windows build with forced bit truncation.
Windows uses a 64 bit time_t by default and assigning to unsigned int causes a
64 -> 32 bit truncation warning. This change forces the truncation,
acknowledging the implications detailed in the file comments. Also, blobs are
limited to 32 bit file sizes for the same reason (on all platforms).
2011-01-10 15:12:29 +11:00
Vicent Marti
a44fc1d413 Fix type-conversion warnings
The types in the git_index_entry struct are now system-defaults, and get
truncated to uint32_t's when written back on the index.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2010-12-06 23:36:21 +02:00
Vicent Marti
44908fe763 Change the library include file
Libgit2 is now officially include as

	#include "<git2.h>"

or indidividual files may be included as

	#include <git2/index.h>

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2010-12-06 23:03:16 +02:00
nulltoken
6f02c3bad8 Small source code readability improvements.
Replaced magic number "0" with GIT_SUCCESS constant wherever it made sense.
2010-12-05 20:18:56 +01:00
Vicent Marti
c4034e63f3 Refactor all 'vector' functions into common code
All the operations on the 'git_index_entry' array and the
'git_tree_entry' array have been refactored into common code in the
src/vector.c file.

The new vector methods support:
	- insertion:	O(1) (avg)
	- deletion:		O(n)
	- searching:	O(logn)
	- sorting:		O(logn)
	- r. access:	O(1)

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2010-12-02 04:31:54 +02:00
Vicent Marti
91e8894150 Properly write Index Entry 'flags_extended'
Always write the 'flags_extended' attribute to disk if it's available.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2010-11-29 18:06:22 +02:00
Vicent Marti
c3dd69a9e1 Fix resizing the index array
No longer segfaults when resizing an empty array.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2010-11-17 05:16:32 +02:00
Vicent Marti
c3a20d5cab Add support for 'index add'
Actually add files to the index by creating their corresponding blob and
storing it on the repository, then getting the hash and updating the
index file.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2010-11-16 02:59:28 +02:00
Scott Chacon
0be421994e accessor for index entry count 2010-11-11 03:28:46 +02:00
Vicent Marti
3f43678e88 Make the Index API public
Several private methods of the Index API are now public, including the
methods to remove, get and add index entries.

All the methods only take an integer value for the position of the entry
to get/remove. To get or remove entries based on their path names, look
them up first using the git_index_find method.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2010-11-07 01:24:45 +02:00
Vicent Marti
1795f87952 Improve error handling
All initialization functions now return error codes instead of pointers.
Error codes are now properly propagated on most functions. Several new
and more specific error codes have been added in common.h

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2010-11-05 03:20:17 +02:00
Vicent Marti
6fd195d76c Change git_repository initialization to use a path
The constructor to git_repository is now called

	'git_repository_open(path)'

and takes a path to a git repository instead of an existing ODB object.
Unit tests have been updated accordingly and the two test repositories
have been merged into one.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2010-11-02 18:42:42 +02:00
Vicent Marti
68535125b3 Add support for git index files
The new 'git_index' structure is an in-memory representation
of a git index on disk; the 'git_index_entry' structures represent
each one of the file entries on the index.

The following calls for index instantiation have been added:

	git_index_alloc(): instantiate a new index structure
	git_index_free(): free an existing index
	git_index_clear(): clear all the entires in an existing file

The following calls for index reading and writing have been added:

	git_index_read(): update the contents of the index structure from
					  its file on disk.

		Internally implemented through:
			git_index__parse()

	Index files are stored on disk in network byte order; all integer fields
	inside them are properly converted to the machine's byte order when
	loading them in memory. The parsing engine also distinguishes
	between normal index entries and extended entries with 2 extra bytes
	of flags.

	The 'TREE' extension for index entries is also loaded into memory:
	Tree caches stored in Index files are loaded into the
	'git_index_tree' structure pointed by the 'tree' pointer inside
	'git_index'.

	'index->tree' points to the root node of the tree cache; the full tree
	can be traversed through each of the node's 'tree->children'.

	Index files can be written back to disk through:

	git_index_write(): atomic writing of existing index objects
		backed by internal method git_index__write()

The following calls for entry manipulation have been added:

	git_index_add(): insert an empty entry to the index

	git_index_find(): search an entry by its path name

	git_index__append(): appends a new index entry to the end of the
						 list, resizing the entries array if required

	New index entries are always inserted at the end of the array; since the
	index entries must be sorted for it to be internally consistent, the
	index object is only sorted once, and if required, before accessing the
	whole entriea array (e.g. before writing to disk, before traversing,
	etc).

	git_index__remove_pos(): remove an index entry in a specific position

	git_index__sort(): sort the entries in the array by path name

	The entries array is sorted stably and in place using an
	insertion sort, which ought to be the most efficient approach
	since the entries array is always mostly-sorted.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
2010-08-12 18:49:04 +02:00