As we no longer expose the transport functions, this is now the only
way to connect to a remote when given an URL instead of a remote name
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
Sockets on Windows are unsigned, so define a type GIT_SOCKET which is
signed or unsigned depending on the platform.
Thanks to Em for his patience with this.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
GCC produces several -Wuninitialized warnings. Most of them can be fixed
if we make visible for gcc that git__throw() and git__rethrow() always
return first argument.
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Some servers take a long time to answer and expect us to keep sending
want lines; otherwise they close the connection. Avoid this by waiting
for one second for the server to answer. If the timeout runs out,
treat is as a NAK and keep sending want lines.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
Only signal that we need a pack if we do need it and don't send a want
just because it's the first. If we don't need to download the pack,
then we can skip all of the negotiation and just return success.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
There are many ways how a transport might negotiate with the server,
so instead of making it fit into the smart protocol model, let the
transport do its thing. For now, the git protocol limits itself to
send only 160 "have" lines so we don't flood the server.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
The original was written before any code was written and had nothing
to do with the way things are actually done.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
There is no need to inspect what the local repository is like. Only
check whether the objects exist locally.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
Make sure we only try to download the pack if we find the pack header
in the stream, and not if the server takes a bit longer to send us the
last NAK.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
This function updates the references in the local reference storage to
match the ones in the remote.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
When indexing a file with ref deltas, a temporary cache for the
offsets has to be built, as we don't have an index file yet. If the
user takes the responsiblity for filling the cache, the packing code
will look there first when it finds a ref delta.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
Provide the git_remote_download function to instruct the library to
downlad the packfile and let the user know the temporary location.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
Move the generation of the want-list to be done from the negotiate
function, and keep the filtered references inside the remote
structure.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
Configurations when taken from a repository and remotes should be
identifiable as coming from a particular repository. This allows us to
reduce the amount of variables that the user has to keep track of.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
We need to do an unsigned comparison, as otherwise UTF-8 characters
might look like they have the sign bit set and the check will fail.
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
git_signature_new() and git_signature_now() currently don't return error
codes. Change the API to return error codes and not pointers to let the
user handle errors properly.
Signed-off-by: schu <schu-github@schulog.org>
The callers immediately throw away the offset, so we don't need any
logical changes in any of them. This will be useful for the indexer,
as it does need to know where the compressed data ends.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
This code is useful for more things than just the packfile handling
code. Factor it out so it can be reused.
Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
z_stream.next_in is non-const. Although currently Zlib doesn't modify
buffer content on deflate(), it might be change in the future. gzwrite()
already modify it.
To avoid this let's change signature of git_filebuf.write and rework
git_filebuf_write() accordingly.
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
index_init_entry() renamed to index_entry_init(). Now it allocates entry
on its own.
git_index_add() and git_index_append() reworked accordingly.
This commit fixes warning:
/home/kas/git/public/libgit2/src/index.c: In function ‘index_init_entry’:
/home/kas/git/public/libgit2/src/index.c:452:14: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
/home/kas/git/public/libgit2/src/index.c: In function ‘git_index_clear’:
/home/kas/git/public/libgit2/src/index.c:228:8: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
/home/kas/git/public/libgit2/src/index.c:235:8: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
/home/kas/git/public/libgit2/src/index.c: In function ‘index_insert’:
/home/kas/git/public/libgit2/src/index.c:392:7: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
/home/kas/git/public/libgit2/src/index.c:399:7: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
/home/kas/git/public/libgit2/src/index.c: In function ‘read_unmerged’:
/home/kas/git/public/libgit2/src/index.c:681:35: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
/home/kas/git/public/libgit2/src/index.c: In function ‘read_entry’:
/home/kas/git/public/libgit2/src/index.c:716:33: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
/home/kas/git/public/libgit2/src/refs.c: In function ‘normalize_name’:
/home/kas/git/public/libgit2/src/refs.c:1681:12: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
/home/kas/git/public/libgit2/src/tree.c: In function ‘entry_search_cmp’:
/home/kas/git/public/libgit2/src/tree.c:47:36: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
/home/kas/git/public/libgit2/src/tree.c: In function ‘git_treebuilder_remove’:
/home/kas/git/public/libgit2/src/tree.c:443:31: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
/home/kas/git/public/libgit2/src/revwalk.c: In function ‘object_table_hash’:
/home/kas/git/public/libgit2/src/revwalk.c:120:7: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
home/kas/git/public/libgit2/src/transport_local.c: In function ‘cmp_refs’:
/home/kas/git/public/libgit2/src/transport_local.c:19:22: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
/home/kas/git/public/libgit2/src/transport_local.c:20:22: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
/home/kas/git/public/libgit2/src/reflog.c: In function ‘reflog_parse’:
/home/kas/git/public/libgit2/src/reflog.c:148:17: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
/home/kas/git/public/libgit2/src/commit.c: In function ‘commit_parse_buffer’:
/home/kas/git/public/libgit2/src/commit.c:186:23: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
/home/kas/git/public/libgit2/src/commit.c:187:27: warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
In reference_read we stat a file and then call futils which stats it
again. Use git_futils_readbuffer_updated to avoid the extra stat
call. This introduces another parameter which is used to tell the
caller whether the file was read or not.
Modify the callers to take advantage of this new feature. This change
removes ~140 stat calls from the test suite.
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
This extends the git_fuitls_readbuffer function to only read in if the
file's modification date is later than the given one. Some code paths
want to check a file's modification date in order to decide whether
they should read it or not. If they do want to read it, another stat
call is done by futils. This function combines these two operations so
we avoid one stat call each time we read a new or updated file.
The git_futils_readbuffer functions is now a wrapper around the new
function.
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
Current implementation of git_reference_rename() removes 'ref' from
loose cache, but not frees it. In result 'ref' is not reachable any more
and we have got memory leak.
Let's re-add 'ref' with corrected name to loose cache instead of
'new_ref' and free 'new_ref' properly.
'rollback' path seems leak too. git_reference_rename() need to be rewritten
for proper resource management.
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
It's not obvious that recurse_tree_entries or recurse_tree_entry
should free a resource that wasn't allocated by them. Do this
explicitely and plug a leak while we're at it.
Signed-off-by: Carlos Martín Nieto <cmn@elego.de>
The old matcher was returning fake matches when given stupid entry
names. E.g.
`git2` could be matched by `git2 /`, `git2/foobar`, git2/////`
and other stupid stuff
Fixes#127 (that was quite an outstanding issue).
Rationale:
The tree objects on Git are stored and read following a very specific
sorting algorithm that places folders before files. That original sort
was the sort we were storing on memory, but this sort was being queried
with a binary search that used a simple `strcmp` for comparison, so
there were many instances where the search was failing.
Obviously, the most straightforward way to fix this is changing the
binary search CB to use the same comparison method as the sorting CB.
The problem with this is that the binary search callback compares a path
and an entry, so there is no way to know if the given path is a folder
or a standard file.
How do we work around this? Instead of splitting the `entry_byname`
method in two (one for searching directories and one for searching
normal files), we just assume that the path we are searching for is of
the same kind as the path it's being compared at the moment.
return git_futils_cmp_path(
ksearch->filename, ksearch->filename_len, entry->attr & 040000,
entry->filename, entry->filename_len, entry->attr & 040000);
Since there cannot be a folder and a regular file with the same name on
the same tree, the most basic equality check will always fail
for all comparsions, until our path is compared with the actual entry we
are looking for; in this case, the matching will succeed with the file
type of the entry -- whatever it was initially.
I hope that makes sense.
PS: While I was at it, I switched the cmp methods to use cached values
for the length of each filename. That makes searches and sorts
retardedly fast -- I was wondering the reason of the performance hiccups
on massive trees; it's because of 2*strlen for each comparsion call.
mode field of git_index_entry_unmerged is array of unsigned ints. It's
unsafe to cast pointer to an element of the array to long int *. It may
cause overflow in git_strtol32().
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Type casting usually points to some trick or bug. It's better not hide
it between useless type castings.
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
The `hashfile` function has been moved to ODB, next to `git_odb_hash`.
Global state has been removed from the dirent call in `status.c`,
because global state is killing the rainforest and causing global
warming.
Add git_status_hashfile() to get blob's object id for a file without adding
it to the object database or needing a repository at all.
This functionality is similar to `git hash-object` without '-w'.
The direct-writes commit left some (slow) internals methods that
were no longer needed. These have been removed.
Also, the Reflog code was using the old `git_signature__write`, so
it has been rewritten to use a normal buffer and the new `writebuf`
signature writer. It's now slightly simpler and faster.
DIRECT WRITES ARE BACK AND FASTER THAN EVER. The streaming writer to the
ODB was an overkill for the smaller objects like Commit and Tags; most
of the streaming logic was taking too long.
This commit makes Commits, Tags and Trees to be built-up in memory, and
then written to disk in 2 pushes (header + data), instead of streaming
everything.
This is *always* faster, even for big files (since the git_filebuf class
still does streaming writes when the memory cache overflows). This is
also a gazillion lines of code smaller, because we don't have to
precompute the final size of the object before starting the stream (this
was kind of defeating the point of streaming, anyway).
Blobs are still written with full streaming instead of loading them in
memory, since this is still the fastest way.
A new `git_buf` class has been added. It's missing some features, but
it'll get there.