Commit 7d0ab0fa by Alan Rogers

Merge remote-tracking branch 'origin/master' into fix-git-status-list-new-unreadable-folder

parents e824e63d 091165c5
...@@ -46,10 +46,11 @@ after_success: ...@@ -46,10 +46,11 @@ after_success:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install valgrind; fi - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install valgrind; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then valgrind --leak-check=full --show-reachable=yes --suppressions=./libgit2_clar.supp _build/libgit2_clar -ionline; fi - if [ "$TRAVIS_OS_NAME" = "linux" ]; then valgrind --leak-check=full --show-reachable=yes --suppressions=./libgit2_clar.supp _build/libgit2_clar -ionline; fi
# Only watch the development branch # Only watch the development and master branches
branches: branches:
only: only:
- development - development
- master
# Notify development list when needed # Notify development list when needed
notifications: notifications:
......
v0.21 + 1
------
* File unlocks are atomic again via rename. Read-only files on Windows are
made read-write if necessary.
* Share open packfiles across repositories to share descriptors and mmaps.
* Use a map for the treebuilder, making insertion O(1)
* LF -> CRLF filter refuses to handle mixed-EOL files
* LF -> CRLF filter now runs when * text = auto (with Git for Windows 1.9.4)
* The git_remote_set_transport function now sets a transport factory function,
rather than a pre-existing transport instance.
* A factory function for ssh has been added which allows to change the
path of the programs to execute for receive-pack and upload-pack on
the server, git_transport_ssh_with_paths.
* The git_clone_options struct no longer provides the ignore_cert_errors or
remote_name members for remote customization.
Instead, the git_clone_options struct has two new members, remote_cb and
remote_cb_payload, which allow the caller to completely override the remote
creation process. If needed, the caller can use this callback to give their
remote a name other than the default (origin) or disable cert checking.
The remote_callbacks member has been preserved for convenience, although it
is not used when a remote creation callback is supplied.
* The git_clone_options struct now provides repository_cb and
repository_cb_payload to allow the user to create a repository with
custom options.
* git_clone_into and git_clone_local_into have been removed from the
public API in favour of git_clone callbacks
* Add support for refspecs with the asterisk in the middle of a
pattern.
...@@ -22,17 +22,25 @@ Also, feel free to open an ...@@ -22,17 +22,25 @@ Also, feel free to open an
about any concerns you have. We like to use Issues for that so there is an about any concerns you have. We like to use Issues for that so there is an
easily accessible permanent record of the conversation. easily accessible permanent record of the conversation.
## Libgit2 Versions
The `master` branch is the main branch where development happens.
Releases are tagged
(e.g. [v0.21.0](https://github.com/libgit2/libgit2/releases/tag/v0.21.0) )
and when a critical bug fix needs to be backported, it will be done on a
`<tag>-maint` maintenance branch.
## Reporting Bugs ## Reporting Bugs
First, know which version of libgit2 your problem is in and include it in First, know which version of libgit2 your problem is in and include it in
your bug report. This can either be a tag (e.g. your bug report. This can either be a tag (e.g.
[v0.17.0](https://github.com/libgit2/libgit2/tree/v0.17.0) ) or a commit [v0.17.0](https://github.com/libgit2/libgit2/releases/tag/v0.17.0) ) or a
SHA (e.g. commit SHA (e.g.
[01be7863](https://github.com/libgit2/libgit2/commit/01be786319238fd6507a08316d1c265c1a89407f) [01be7863](https://github.com/libgit2/libgit2/commit/01be786319238fd6507a08316d1c265c1a89407f)
). Using [`git describe`](http://git-scm.com/docs/git-describe) is a great ). Using [`git describe`](http://git-scm.com/docs/git-describe) is a
way to tell us what version you're working with. great way to tell us what version you're working with.
If you're not running against the latest `development` branch version, If you're not running against the latest `master` branch version,
please compile and test against that to avoid re-reporting an issue that's please compile and test against that to avoid re-reporting an issue that's
already been fixed. already been fixed.
...@@ -44,25 +52,33 @@ out a way to help you. ...@@ -44,25 +52,33 @@ out a way to help you.
## Pull Requests ## Pull Requests
Our work flow is a typical GitHub flow, where contributors fork the Our work flow is a [typical GitHub flow](https://guides.github.com/introduction/flow/index.html),
[libgit2 repository](https://github.com/libgit2/libgit2), make their changes where contributors fork the [libgit2 repository](https://github.com/libgit2/libgit2),
on branch, and submit a make their changes on branch, and submit a
[Pull Request](https://help.github.com/articles/using-pull-requests) [Pull Request](https://help.github.com/articles/using-pull-requests) (a.k.a. "PR").
(a.k.a. "PR"). Pull requests should usually be targeted at the `master` branch.
Life will be a lot easier for you (and us) if you follow this pattern Life will be a lot easier for you (and us) if you follow this pattern
(i.e. fork, named branch, submit PR). If you use your fork's `development` (i.e. fork, named branch, submit PR). If you use your fork's `master`
branch, things can get messy. branch directly, things can get messy.
Please include a nice description of your changes when you submit your PR;
if we have to read the whole diff to figure out why you're contributing
in the first place, you're less likely to get feedback and have your change
merged in.
If you are starting to work on a particular area, feel free to submit a PR
that highlights your work in progress (and note in the PR title that it's
not ready to merge). These early PRs are welcome and will help in getting
visibility for your fix, allow others to comment early on the changes and
also let others know that you are currently working on something.
Please include a nice description of your changes with your PR; if we have Before wrapping up a PR, you should be sure to:
to read the whole diff to figure out why you're contributing in the first
place, you're less likely to get feedback and have your change merged in.
If you are working on a particular area then feel free to submit a PR that * Write tests to cover any functional changes (ideally tests that would
highlights your work in progress (and flag in the PR title that it's not have failed before the PR and now pass)
ready to merge). This will help in getting visibility for your fix, allow * Update documentation for any changed public APIs
others to comment early on the changes and also let others know that you * Add to the [`CHANGELOG.md`](CHANGELOG.md) file describing any major changes
are currently working on something.
## Porting Code From Other Open-Source Projects ## Porting Code From Other Open-Source Projects
...@@ -80,10 +96,10 @@ you're porting code *from* to see what you need to do. As a general rule, ...@@ -80,10 +96,10 @@ you're porting code *from* to see what you need to do. As a general rule,
MIT and BSD (3-clause) licenses are typically no problem. Apache 2.0 MIT and BSD (3-clause) licenses are typically no problem. Apache 2.0
license typically doesn't work due to GPL incompatibility. license typically doesn't work due to GPL incompatibility.
If you are pulling in code from core Git, another project or code you've If your pull request uses code from core Git, another project, or code
pulled from a forum / Stack Overflow then please flag this in your PR and from a forum / Stack Overflow, then *please* flag this in your PR and make
also make sure you've given proper credit to the original author in the sure you've given proper credit to the original author in the code
code snippet. snippet.
## Style Guide ## Style Guide
......
...@@ -10,10 +10,11 @@ ideas that no one is actively working on. ...@@ -10,10 +10,11 @@ ideas that no one is actively working on.
## Before You Start ## Before You Start
Please start by reading the README.md, CONTRIBUTING.md, and CONVENTIONS.md Please start by reading the [README.md](README.md),
files before diving into one of these projects. Those will explain our [CONTRIBUTING.md](CONTRIBUTING.md), and [CONVENTIONS.md](CONVENTIONS.md)
work flow and coding conventions to help ensure that your work will be files before diving into one of these projects. Those explain our work
easily integrated into libgit2. flow and coding conventions to help ensure that your work will be easily
integrated into libgit2.
Next, work through the build instructions and make sure you can clone the Next, work through the build instructions and make sure you can clone the
repository, compile it, and run the tests successfully. That will make repository, compile it, and run the tests successfully. That will make
...@@ -27,7 +28,7 @@ These are good small projects to get started with libgit2. ...@@ -27,7 +28,7 @@ These are good small projects to get started with libgit2.
* Look at the `examples/` programs, find an existing one that mirrors a * Look at the `examples/` programs, find an existing one that mirrors a
core Git command and add a missing command-line option. There are many core Git command and add a missing command-line option. There are many
gaps right now and this helps demonstrate how to use the library. Here gaps right now and this helps demonstrate how to use the library. Here
are some specific ideas: are some specific ideas (though there are many more):
* Fix the `examples/diff.c` implementation of the `-B` * Fix the `examples/diff.c` implementation of the `-B`
(a.k.a. `--break-rewrites`) command line option to actually look for (a.k.a. `--break-rewrites`) command line option to actually look for
the optional `[<n>][/<m>]` configuration values. There is an the optional `[<n>][/<m>]` configuration values. There is an
...@@ -67,19 +68,44 @@ into one of these as a first project for libgit2 - we'd rather get to ...@@ -67,19 +68,44 @@ into one of these as a first project for libgit2 - we'd rather get to
know you first by successfully shipping your work on one of the smaller know you first by successfully shipping your work on one of the smaller
projects above. projects above.
Some of these projects are broken down into subprojects and/or have
some incremental steps listed towards the larger goal. Those steps
might make good smaller projects by themselves.
* Port part of the Git test suite to run against the command line emulation * Port part of the Git test suite to run against the command line emulation
in examples/ in examples/
* Pick a Git command that is emulated in our examples/ area
* Extract the Git tests that exercise that command
* Convert the tests to call our emulation
* These tests could go in examples/tests/...
* Fix symlink support for files in the .git directory (i.e. don't overwrite * Fix symlink support for files in the .git directory (i.e. don't overwrite
the symlinks when writing the file contents back out) the symlinks when writing the file contents back out)
* Implement a 'git describe' like API * Implement a 'git describe' like API
* Add hooks API to enumerate and manage hooks (not run them at this point) * Add hooks API to enumerate and manage hooks (not run them at this point)
* Enumeration of available hooks
* Lookup API to see which hooks have a script and get the script
* Read/write API to load a hook script and write a hook script
* Eventually, callback API to invoke a hook callback when libgit2
executes the action in question
* Isolate logic of ignore evaluation into a standalone API * Isolate logic of ignore evaluation into a standalone API
* Upgrade internal libxdiff code to latest from core Git * Upgrade internal libxdiff code to latest from core Git
* Add a hashtable lookup for files in the index instead of binary search * Improve index internals with hashtable lookup for files instead of
every time using binary search every time
* Make the index write the cache out to disk (with tests to gain * Make the index write the cache out to disk (with tests to gain
confidence that the caching invalidation works correctly) confidence that the caching invalidation works correctly)
* Have the tree builder use a hash table when building instead of a * Tree builder improvements:
list. * Use a hash table when building instead of a list
* Extend to allow building a tree hierarchy
* Move the tagopt mechanism to the newer git 1.9 interpretation of * Move the tagopt mechanism to the newer git 1.9 interpretation of
--tags [#2120](https://github.com/libgit2/libgit2/issues/2120) --tags [#2120](https://github.com/libgit2/libgit2/issues/2120)
* Apply-patch API
* Add a patch editing API to enable "git add -p" type operations
* Textconv API to filter binary data before generating diffs (something
like the current Filter API, probably).
* Performance profiling and improvement
* Build in handling of "empty tree" and "empty blob" SHAs
* Support "git replace" ref replacements
* Include conflicts in diff results and in status
* GIT_DELTA_CONFLICT for items in conflict (with multiple files)
* Appropriate flags for status
* Support sparse checkout (i.e. "core.sparsecheckout" and ".git/info/sparse-checkout")
...@@ -182,7 +182,7 @@ Here are the bindings to libgit2 that are currently available: ...@@ -182,7 +182,7 @@ Here are the bindings to libgit2 that are currently available:
* Parrot Virtual Machine * Parrot Virtual Machine
* parrot-libgit2 <https://github.com/letolabs/parrot-libgit2> * parrot-libgit2 <https://github.com/letolabs/parrot-libgit2>
* Perl * Perl
* Git-Raw <https://github.com/ghedo/p5-Git-Raw> * Git-Raw <https://github.com/jacquesg/p5-Git-Raw>
* PHP * PHP
* php-git <https://github.com/libgit2/php-git> * php-git <https://github.com/libgit2/php-git>
* PowerShell * PowerShell
......
/* adler32.c -- compute the Adler-32 checksum of a data stream /* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-2007 Mark Adler * Copyright (C) 1995-2011 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
#define local static #define local static
local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
#define BASE 65521UL /* largest prime smaller than 65536 */ #define BASE 65521 /* largest prime smaller than 65536 */
#define NMAX 5552 #define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
...@@ -21,39 +21,44 @@ local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); ...@@ -21,39 +21,44 @@ local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8); #define DO16(buf) DO8(buf,0); DO8(buf,8);
/* use NO_DIVIDE if your processor does not do division in hardware */ /* use NO_DIVIDE if your processor does not do division in hardware --
try it both ways to see which is faster */
#ifdef NO_DIVIDE #ifdef NO_DIVIDE
# define MOD(a) \ /* note that this assumes BASE is 65521, where 65536 % 65521 == 15
(thank you to John Reiser for pointing this out) */
# define CHOP(a) \
do { \
unsigned long tmp = a >> 16; \
a &= 0xffffUL; \
a += (tmp << 4) - tmp; \
} while (0)
# define MOD28(a) \
do { \ do { \
if (a >= (BASE << 16)) a -= (BASE << 16); \ CHOP(a); \
if (a >= (BASE << 15)) a -= (BASE << 15); \
if (a >= (BASE << 14)) a -= (BASE << 14); \
if (a >= (BASE << 13)) a -= (BASE << 13); \
if (a >= (BASE << 12)) a -= (BASE << 12); \
if (a >= (BASE << 11)) a -= (BASE << 11); \
if (a >= (BASE << 10)) a -= (BASE << 10); \
if (a >= (BASE << 9)) a -= (BASE << 9); \
if (a >= (BASE << 8)) a -= (BASE << 8); \
if (a >= (BASE << 7)) a -= (BASE << 7); \
if (a >= (BASE << 6)) a -= (BASE << 6); \
if (a >= (BASE << 5)) a -= (BASE << 5); \
if (a >= (BASE << 4)) a -= (BASE << 4); \
if (a >= (BASE << 3)) a -= (BASE << 3); \
if (a >= (BASE << 2)) a -= (BASE << 2); \
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \ if (a >= BASE) a -= BASE; \
} while (0) } while (0)
# define MOD4(a) \ # define MOD(a) \
do { \ do { \
if (a >= (BASE << 4)) a -= (BASE << 4); \ CHOP(a); \
if (a >= (BASE << 3)) a -= (BASE << 3); \ MOD28(a); \
if (a >= (BASE << 2)) a -= (BASE << 2); \ } while (0)
if (a >= (BASE << 1)) a -= (BASE << 1); \ # define MOD63(a) \
do { /* this assumes a is not negative */ \
z_off64_t tmp = a >> 32; \
a &= 0xffffffffL; \
a += (tmp << 8) - (tmp << 5) + tmp; \
tmp = a >> 16; \
a &= 0xffffL; \
a += (tmp << 4) - tmp; \
tmp = a >> 16; \
a &= 0xffffL; \
a += (tmp << 4) - tmp; \
if (a >= BASE) a -= BASE; \ if (a >= BASE) a -= BASE; \
} while (0) } while (0)
#else #else
# define MOD(a) a %= BASE # define MOD(a) a %= BASE
# define MOD4(a) a %= BASE # define MOD28(a) a %= BASE
# define MOD63(a) a %= BASE
#endif #endif
/* ========================================================================= */ /* ========================================================================= */
...@@ -92,7 +97,7 @@ uLong ZEXPORT adler32(adler, buf, len) ...@@ -92,7 +97,7 @@ uLong ZEXPORT adler32(adler, buf, len)
} }
if (adler >= BASE) if (adler >= BASE)
adler -= BASE; adler -= BASE;
MOD4(sum2); /* only added so many BASE's */ MOD28(sum2); /* only added so many BASE's */
return adler | (sum2 << 16); return adler | (sum2 << 16);
} }
...@@ -137,8 +142,13 @@ local uLong adler32_combine_(adler1, adler2, len2) ...@@ -137,8 +142,13 @@ local uLong adler32_combine_(adler1, adler2, len2)
unsigned long sum2; unsigned long sum2;
unsigned rem; unsigned rem;
/* for negative len, return invalid adler32 as a clue for debugging */
if (len2 < 0)
return 0xffffffffUL;
/* the derivation of this formula is left as an exercise for the reader */ /* the derivation of this formula is left as an exercise for the reader */
rem = (unsigned)(len2 % BASE); MOD63(len2); /* assumes len2 >= 0 */
rem = (unsigned)len2;
sum1 = adler1 & 0xffff; sum1 = adler1 & 0xffff;
sum2 = rem * sum1; sum2 = rem * sum1;
MOD(sum2); MOD(sum2);
......
/* crc32.c -- compute the CRC-32 of a data stream /* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-2006, 2010 Mark Adler * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
* *
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
first call get_crc_table() to initialize the tables before allowing more than first call get_crc_table() to initialize the tables before allowing more than
one thread to use crc32(). one thread to use crc32().
DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
*/ */
#ifdef MAKECRCH #ifdef MAKECRCH
...@@ -30,31 +32,11 @@ ...@@ -30,31 +32,11 @@
#define local static #define local static
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
#ifndef NOBYFOUR
# ifdef STDC /* need ANSI C limits.h to determine sizes */
# include <limits.h>
# define BYFOUR
# if (UINT_MAX == 0xffffffffUL)
typedef unsigned int u4;
# else
# if (ULONG_MAX == 0xffffffffUL)
typedef unsigned long u4;
# else
# if (USHRT_MAX == 0xffffffffUL)
typedef unsigned short u4;
# else
# undef BYFOUR /* can't find a four-byte integer type! */
# endif
# endif
# endif
# endif /* STDC */
#endif /* !NOBYFOUR */
/* Definitions for doing the crc four data bytes at a time. */ /* Definitions for doing the crc four data bytes at a time. */
#if !defined(NOBYFOUR) && defined(Z_U4)
# define BYFOUR
#endif
#ifdef BYFOUR #ifdef BYFOUR
# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
local unsigned long crc32_little OF((unsigned long, local unsigned long crc32_little OF((unsigned long,
const unsigned char FAR *, unsigned)); const unsigned char FAR *, unsigned));
local unsigned long crc32_big OF((unsigned long, local unsigned long crc32_big OF((unsigned long,
...@@ -68,16 +50,16 @@ ...@@ -68,16 +50,16 @@
local unsigned long gf2_matrix_times OF((unsigned long *mat, local unsigned long gf2_matrix_times OF((unsigned long *mat,
unsigned long vec)); unsigned long vec));
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
#ifdef DYNAMIC_CRC_TABLE #ifdef DYNAMIC_CRC_TABLE
local volatile int crc_table_empty = 1; local volatile int crc_table_empty = 1;
local unsigned long FAR crc_table[TBLS][256]; local z_crc_t FAR crc_table[TBLS][256];
local void make_crc_table OF((void)); local void make_crc_table OF((void));
#ifdef MAKECRCH #ifdef MAKECRCH
local void write_table OF((FILE *, const unsigned long FAR *)); local void write_table OF((FILE *, const z_crc_t FAR *));
#endif /* MAKECRCH */ #endif /* MAKECRCH */
/* /*
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
...@@ -107,9 +89,9 @@ local void make_crc_table OF((void)); ...@@ -107,9 +89,9 @@ local void make_crc_table OF((void));
*/ */
local void make_crc_table() local void make_crc_table()
{ {
unsigned long c; z_crc_t c;
int n, k; int n, k;
unsigned long poly; /* polynomial exclusive-or pattern */ z_crc_t poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */ /* terms of polynomial defining this crc (except x^32): */
static volatile int first = 1; /* flag to limit concurrent making */ static volatile int first = 1; /* flag to limit concurrent making */
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
...@@ -121,13 +103,13 @@ local void make_crc_table() ...@@ -121,13 +103,13 @@ local void make_crc_table()
first = 0; first = 0;
/* make exclusive-or pattern from polynomial (0xedb88320UL) */ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
poly = 0UL; poly = 0;
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
poly |= 1UL << (31 - p[n]); poly |= (z_crc_t)1 << (31 - p[n]);
/* generate a crc for every 8-bit value */ /* generate a crc for every 8-bit value */
for (n = 0; n < 256; n++) { for (n = 0; n < 256; n++) {
c = (unsigned long)n; c = (z_crc_t)n;
for (k = 0; k < 8; k++) for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1; c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[0][n] = c; crc_table[0][n] = c;
...@@ -138,11 +120,11 @@ local void make_crc_table() ...@@ -138,11 +120,11 @@ local void make_crc_table()
and then the byte reversal of those as well as the first table */ and then the byte reversal of those as well as the first table */
for (n = 0; n < 256; n++) { for (n = 0; n < 256; n++) {
c = crc_table[0][n]; c = crc_table[0][n];
crc_table[4][n] = REV(c); crc_table[4][n] = ZSWAP32(c);
for (k = 1; k < 4; k++) { for (k = 1; k < 4; k++) {
c = crc_table[0][c & 0xff] ^ (c >> 8); c = crc_table[0][c & 0xff] ^ (c >> 8);
crc_table[k][n] = c; crc_table[k][n] = c;
crc_table[k + 4][n] = REV(c); crc_table[k + 4][n] = ZSWAP32(c);
} }
} }
#endif /* BYFOUR */ #endif /* BYFOUR */
...@@ -164,7 +146,7 @@ local void make_crc_table() ...@@ -164,7 +146,7 @@ local void make_crc_table()
if (out == NULL) return; if (out == NULL) return;
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
fprintf(out, "local const unsigned long FAR "); fprintf(out, "local const z_crc_t FAR ");
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
write_table(out, crc_table[0]); write_table(out, crc_table[0]);
# ifdef BYFOUR # ifdef BYFOUR
...@@ -184,12 +166,13 @@ local void make_crc_table() ...@@ -184,12 +166,13 @@ local void make_crc_table()
#ifdef MAKECRCH #ifdef MAKECRCH
local void write_table(out, table) local void write_table(out, table)
FILE *out; FILE *out;
const unsigned long FAR *table; const z_crc_t FAR *table;
{ {
int n; int n;
for (n = 0; n < 256; n++) for (n = 0; n < 256; n++)
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
(unsigned long)(table[n]),
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
} }
#endif /* MAKECRCH */ #endif /* MAKECRCH */
...@@ -204,13 +187,13 @@ local void write_table(out, table) ...@@ -204,13 +187,13 @@ local void write_table(out, table)
/* ========================================================================= /* =========================================================================
* This function can be used by asm versions of crc32() * This function can be used by asm versions of crc32()
*/ */
const unsigned long FAR * ZEXPORT get_crc_table() const z_crc_t FAR * ZEXPORT get_crc_table()
{ {
#ifdef DYNAMIC_CRC_TABLE #ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty) if (crc_table_empty)
make_crc_table(); make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */ #endif /* DYNAMIC_CRC_TABLE */
return (const unsigned long FAR *)crc_table; return (const z_crc_t FAR *)crc_table;
} }
/* ========================================================================= */ /* ========================================================================= */
...@@ -232,7 +215,7 @@ unsigned long ZEXPORT crc32(crc, buf, len) ...@@ -232,7 +215,7 @@ unsigned long ZEXPORT crc32(crc, buf, len)
#ifdef BYFOUR #ifdef BYFOUR
if (sizeof(void *) == sizeof(ptrdiff_t)) { if (sizeof(void *) == sizeof(ptrdiff_t)) {
u4 endian; z_crc_t endian;
endian = 1; endian = 1;
if (*((unsigned char *)(&endian))) if (*((unsigned char *)(&endian)))
...@@ -266,17 +249,17 @@ local unsigned long crc32_little(crc, buf, len) ...@@ -266,17 +249,17 @@ local unsigned long crc32_little(crc, buf, len)
const unsigned char FAR *buf; const unsigned char FAR *buf;
unsigned len; unsigned len;
{ {
register u4 c; register z_crc_t c;
register const u4 FAR *buf4; register const z_crc_t FAR *buf4;
c = (u4)crc; c = (z_crc_t)crc;
c = ~c; c = ~c;
while (len && ((ptrdiff_t)buf & 3)) { while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
len--; len--;
} }
buf4 = (const u4 FAR *)(const void FAR *)buf; buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
while (len >= 32) { while (len >= 32) {
DOLIT32; DOLIT32;
len -= 32; len -= 32;
...@@ -306,17 +289,17 @@ local unsigned long crc32_big(crc, buf, len) ...@@ -306,17 +289,17 @@ local unsigned long crc32_big(crc, buf, len)
const unsigned char FAR *buf; const unsigned char FAR *buf;
unsigned len; unsigned len;
{ {
register u4 c; register z_crc_t c;
register const u4 FAR *buf4; register const z_crc_t FAR *buf4;
c = REV((u4)crc); c = ZSWAP32((z_crc_t)crc);
c = ~c; c = ~c;
while (len && ((ptrdiff_t)buf & 3)) { while (len && ((ptrdiff_t)buf & 3)) {
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
len--; len--;
} }
buf4 = (const u4 FAR *)(const void FAR *)buf; buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
buf4--; buf4--;
while (len >= 32) { while (len >= 32) {
DOBIG32; DOBIG32;
...@@ -333,7 +316,7 @@ local unsigned long crc32_big(crc, buf, len) ...@@ -333,7 +316,7 @@ local unsigned long crc32_big(crc, buf, len)
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
} while (--len); } while (--len);
c = ~c; c = ~c;
return (unsigned long)(REV(c)); return (unsigned long)(ZSWAP32(c));
} }
#endif /* BYFOUR */ #endif /* BYFOUR */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Generated automatically by crc32.c * Generated automatically by crc32.c
*/ */
local const unsigned long FAR crc_table[TBLS][256] = local const z_crc_t FAR crc_table[TBLS][256] =
{ {
{ {
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
......
/* deflate.h -- internal compression state /* deflate.h -- internal compression state
* Copyright (C) 1995-2010 Jean-loup Gailly * Copyright (C) 1995-2012 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -48,6 +48,9 @@ ...@@ -48,6 +48,9 @@
#define MAX_BITS 15 #define MAX_BITS 15
/* All codes must not exceed MAX_BITS bits */ /* All codes must not exceed MAX_BITS bits */
#define Buf_size 16
/* size of bit buffer in bi_buf */
#define INIT_STATE 42 #define INIT_STATE 42
#define EXTRA_STATE 69 #define EXTRA_STATE 69
#define NAME_STATE 73 #define NAME_STATE 73
...@@ -101,7 +104,7 @@ typedef struct internal_state { ...@@ -101,7 +104,7 @@ typedef struct internal_state {
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
gz_headerp gzhead; /* gzip header information to write */ gz_headerp gzhead; /* gzip header information to write */
uInt gzindex; /* where in extra, name, or comment */ uInt gzindex; /* where in extra, name, or comment */
Byte method; /* STORED (for zip only) or DEFLATED */ Byte method; /* can only be DEFLATED */
int last_flush; /* value of flush param for previous deflate call */ int last_flush; /* value of flush param for previous deflate call */
/* used by deflate.c: */ /* used by deflate.c: */
...@@ -188,7 +191,7 @@ typedef struct internal_state { ...@@ -188,7 +191,7 @@ typedef struct internal_state {
int nice_match; /* Stop searching when current match exceeds this */ int nice_match; /* Stop searching when current match exceeds this */
/* used by trees.c: */ /* used by trees.c: */
/* Didn't use ct_data typedef below to supress compiler warning */ /* Didn't use ct_data typedef below to suppress compiler warning */
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
...@@ -244,7 +247,7 @@ typedef struct internal_state { ...@@ -244,7 +247,7 @@ typedef struct internal_state {
ulg opt_len; /* bit length of current block with optimal trees */ ulg opt_len; /* bit length of current block with optimal trees */
ulg static_len; /* bit length of current block with static trees */ ulg static_len; /* bit length of current block with static trees */
uInt matches; /* number of string matches in current block */ uInt matches; /* number of string matches in current block */
int last_eob_len; /* bit length of EOB code for last block */ uInt insert; /* bytes at end of window left to insert */
#ifdef DEBUG #ifdef DEBUG
ulg compressed_len; /* total bit length of compressed file mod 2^32 */ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
...@@ -294,6 +297,7 @@ void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); ...@@ -294,6 +297,7 @@ void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
ulg stored_len, int last)); ulg stored_len, int last));
void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
ulg stored_len, int last)); ulg stored_len, int last));
......
/* inffast.c -- fast decoding /* inffast.c -- fast decoding
* Copyright (C) 1995-2008, 2010 Mark Adler * Copyright (C) 1995-2008, 2010, 2013 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -69,8 +69,8 @@ z_streamp strm; ...@@ -69,8 +69,8 @@ z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */ unsigned start; /* inflate()'s starting value for strm->avail_out */
{ {
struct inflate_state FAR *state; struct inflate_state FAR *state;
unsigned char FAR *in; /* local strm->next_in */ z_const unsigned char FAR *in; /* local strm->next_in */
unsigned char FAR *last; /* while in < last, enough input available */ z_const unsigned char FAR *last; /* have enough input while in < last */
unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */ unsigned char FAR *end; /* while out < end, enough space available */
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
* Generated automatically by makefixed(). * Generated automatically by makefixed().
*/ */
/* WARNING: this file should *not* be used by applications. It /* WARNING: this file should *not* be used by applications.
is part of the implementation of the compression library and It is part of the implementation of this library and is
is subject to change. Applications should only use zlib.h. subject to change. Applications should only use zlib.h.
*/ */
static const code lenfix[512] = { static const code lenfix[512] = {
......
/* inftrees.c -- generate Huffman trees for efficient decoding /* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2010 Mark Adler * Copyright (C) 1995-2013 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#define MAXBITS 15 #define MAXBITS 15
const char inflate_copyright[] = const char inflate_copyright[] =
" inflate 1.2.5 Copyright 1995-2010 Mark Adler "; " inflate 1.2.8 Copyright 1995-2013 Mark Adler ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot in the documentation of your product. If for some reason you cannot
...@@ -62,7 +62,7 @@ unsigned short FAR *work; ...@@ -62,7 +62,7 @@ unsigned short FAR *work;
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
...@@ -208,8 +208,8 @@ unsigned short FAR *work; ...@@ -208,8 +208,8 @@ unsigned short FAR *work;
mask = used - 1; /* mask for comparing low */ mask = used - 1; /* mask for comparing low */
/* check available table space */ /* check available table space */
if ((type == LENS && used >= ENOUGH_LENS) || if ((type == LENS && used > ENOUGH_LENS) ||
(type == DISTS && used >= ENOUGH_DISTS)) (type == DISTS && used > ENOUGH_DISTS))
return 1; return 1;
/* process all codes and make table entries */ /* process all codes and make table entries */
...@@ -277,8 +277,8 @@ unsigned short FAR *work; ...@@ -277,8 +277,8 @@ unsigned short FAR *work;
/* check for enough space */ /* check for enough space */
used += 1U << curr; used += 1U << curr;
if ((type == LENS && used >= ENOUGH_LENS) || if ((type == LENS && used > ENOUGH_LENS) ||
(type == DISTS && used >= ENOUGH_DISTS)) (type == DISTS && used > ENOUGH_DISTS))
return 1; return 1;
/* point entry in root table to sub-table */ /* point entry in root table to sub-table */
...@@ -289,38 +289,14 @@ unsigned short FAR *work; ...@@ -289,38 +289,14 @@ unsigned short FAR *work;
} }
} }
/* /* fill in remaining table entry if code is incomplete (guaranteed to have
Fill in rest of table for incomplete codes. This loop is similar to the at most one remaining entry, since if the code is incomplete, the
loop above in incrementing huff for table indices. It is assumed that maximum code length that was allowed to get this far is one bit) */
len is equal to curr + drop, so there is no loop needed to increment if (huff != 0) {
through high index bits. When the current sub-table is filled, the loop here.op = (unsigned char)64; /* invalid code marker */
drops back to the root table to fill in any remaining entries there. here.bits = (unsigned char)(len - drop);
*/ here.val = (unsigned short)0;
here.op = (unsigned char)64; /* invalid code marker */ next[huff] = here;
here.bits = (unsigned char)(len - drop);
here.val = (unsigned short)0;
while (huff != 0) {
/* when done with sub-table, drop back to root table */
if (drop != 0 && (huff & mask) != low) {
drop = 0;
len = root;
next = *table;
here.bits = (unsigned char)len;
}
/* put invalid code marker in table */
next[huff >> drop] = here;
/* backwards increment the len-bit code huff */
incr = 1U << (len - 1);
while (huff & incr)
incr >>= 1;
if (incr != 0) {
huff &= incr - 1;
huff += incr;
}
else
huff = 0;
} }
/* set return parameters */ /* set return parameters */
......
/* trees.c -- output deflated data using Huffman coding /* trees.c -- output deflated data using Huffman coding
* Copyright (C) 1995-2010 Jean-loup Gailly * Copyright (C) 1995-2012 Jean-loup Gailly
* detect_data_type() function provided freely by Cosmin Truta, 2006 * detect_data_type() function provided freely by Cosmin Truta, 2006
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -74,11 +74,6 @@ local const uch bl_order[BL_CODES] ...@@ -74,11 +74,6 @@ local const uch bl_order[BL_CODES]
* probability, to avoid transmitting the lengths for unused bit length codes. * probability, to avoid transmitting the lengths for unused bit length codes.
*/ */
#define Buf_size (8 * 2*sizeof(char))
/* Number of bits used within bi_buf. (bi_buf might be implemented on
* more than 16 bits on some systems.)
*/
/* =========================================================================== /* ===========================================================================
* Local data. These are initialized only once. * Local data. These are initialized only once.
*/ */
...@@ -151,8 +146,8 @@ local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); ...@@ -151,8 +146,8 @@ local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
local int build_bl_tree OF((deflate_state *s)); local int build_bl_tree OF((deflate_state *s));
local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
int blcodes)); int blcodes));
local void compress_block OF((deflate_state *s, ct_data *ltree, local void compress_block OF((deflate_state *s, const ct_data *ltree,
ct_data *dtree)); const ct_data *dtree));
local int detect_data_type OF((deflate_state *s)); local int detect_data_type OF((deflate_state *s));
local unsigned bi_reverse OF((unsigned value, int length)); local unsigned bi_reverse OF((unsigned value, int length));
local void bi_windup OF((deflate_state *s)); local void bi_windup OF((deflate_state *s));
...@@ -399,7 +394,6 @@ void ZLIB_INTERNAL _tr_init(s) ...@@ -399,7 +394,6 @@ void ZLIB_INTERNAL _tr_init(s)
s->bi_buf = 0; s->bi_buf = 0;
s->bi_valid = 0; s->bi_valid = 0;
s->last_eob_len = 8; /* enough lookahead for inflate */
#ifdef DEBUG #ifdef DEBUG
s->compressed_len = 0L; s->compressed_len = 0L;
s->bits_sent = 0L; s->bits_sent = 0L;
...@@ -883,15 +877,17 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) ...@@ -883,15 +877,17 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
} }
/* =========================================================================== /* ===========================================================================
* Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
*/
void ZLIB_INTERNAL _tr_flush_bits(s)
deflate_state *s;
{
bi_flush(s);
}
/* ===========================================================================
* Send one empty static block to give enough lookahead for inflate. * Send one empty static block to give enough lookahead for inflate.
* This takes 10 bits, of which 7 may remain in the bit buffer. * This takes 10 bits, of which 7 may remain in the bit buffer.
* The current inflate code requires 9 bits of lookahead. If the
* last two codes for the previous block (real code plus EOB) were coded
* on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
* the last real code. In this case we send two empty static blocks instead
* of one. (There are no problems if the previous block is stored or fixed.)
* To simplify the code, we assume the worst case of last real code encoded
* on one bit only.
*/ */
void ZLIB_INTERNAL _tr_align(s) void ZLIB_INTERNAL _tr_align(s)
deflate_state *s; deflate_state *s;
...@@ -902,20 +898,6 @@ void ZLIB_INTERNAL _tr_align(s) ...@@ -902,20 +898,6 @@ void ZLIB_INTERNAL _tr_align(s)
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
#endif #endif
bi_flush(s); bi_flush(s);
/* Of the 10 bits for the empty block, we have already sent
* (10 - bi_valid) bits. The lookahead for the last real code (before
* the EOB of the previous block) was thus at least one plus the length
* of the EOB plus what we have just sent of the empty static block.
*/
if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
send_bits(s, STATIC_TREES<<1, 3);
send_code(s, END_BLOCK, static_ltree);
#ifdef DEBUG
s->compressed_len += 10L;
#endif
bi_flush(s);
}
s->last_eob_len = 7;
} }
/* =========================================================================== /* ===========================================================================
...@@ -990,7 +972,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) ...@@ -990,7 +972,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
#endif #endif
send_bits(s, (STATIC_TREES<<1)+last, 3); send_bits(s, (STATIC_TREES<<1)+last, 3);
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); compress_block(s, (const ct_data *)static_ltree,
(const ct_data *)static_dtree);
#ifdef DEBUG #ifdef DEBUG
s->compressed_len += 3 + s->static_len; s->compressed_len += 3 + s->static_len;
#endif #endif
...@@ -998,7 +981,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) ...@@ -998,7 +981,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
send_bits(s, (DYN_TREES<<1)+last, 3); send_bits(s, (DYN_TREES<<1)+last, 3);
send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
max_blindex+1); max_blindex+1);
compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); compress_block(s, (const ct_data *)s->dyn_ltree,
(const ct_data *)s->dyn_dtree);
#ifdef DEBUG #ifdef DEBUG
s->compressed_len += 3 + s->opt_len; s->compressed_len += 3 + s->opt_len;
#endif #endif
...@@ -1075,8 +1059,8 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc) ...@@ -1075,8 +1059,8 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
*/ */
local void compress_block(s, ltree, dtree) local void compress_block(s, ltree, dtree)
deflate_state *s; deflate_state *s;
ct_data *ltree; /* literal tree */ const ct_data *ltree; /* literal tree */
ct_data *dtree; /* distance tree */ const ct_data *dtree; /* distance tree */
{ {
unsigned dist; /* distance of matched string */ unsigned dist; /* distance of matched string */
int lc; /* match length or unmatched char (if dist == 0) */ int lc; /* match length or unmatched char (if dist == 0) */
...@@ -1118,7 +1102,6 @@ local void compress_block(s, ltree, dtree) ...@@ -1118,7 +1102,6 @@ local void compress_block(s, ltree, dtree)
} while (lx < s->last_lit); } while (lx < s->last_lit);
send_code(s, END_BLOCK, ltree); send_code(s, END_BLOCK, ltree);
s->last_eob_len = ltree[END_BLOCK].Len;
} }
/* =========================================================================== /* ===========================================================================
...@@ -1226,7 +1209,6 @@ local void copy_block(s, buf, len, header) ...@@ -1226,7 +1209,6 @@ local void copy_block(s, buf, len, header)
int header; /* true if block header must be written */ int header; /* true if block header must be written */
{ {
bi_windup(s); /* align on byte boundary */ bi_windup(s); /* align on byte boundary */
s->last_eob_len = 8; /* enough lookahead for inflate */
if (header) { if (header) {
put_short(s, (ush)len); put_short(s, (ush)len);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* forms, we didn't write zlib */ * forms, we didn't write zlib */
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning( disable : 4131 ) # pragma warning( disable : 4131 )
# pragma warning( disable : 4142 ) /* benign redefinition of type */
#endif #endif
/* Maximum value for memLevel in deflateInit2 */ /* Maximum value for memLevel in deflateInit2 */
...@@ -33,10 +34,12 @@ ...@@ -33,10 +34,12 @@
# define FAR # define FAR
#endif #endif
#define OF(args) args #define OF(args) args
#define Z_ARG(args) args
typedef unsigned char Byte; /* 8 bits */ typedef unsigned char Byte; /* 8 bits */
typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */ typedef unsigned long uLong; /* 32 bits or more */
typedef unsigned long z_crc_t;
typedef Byte FAR Bytef; typedef Byte FAR Bytef;
typedef char FAR charf; typedef char FAR charf;
...@@ -50,5 +53,6 @@ typedef void *voidp; ...@@ -50,5 +53,6 @@ typedef void *voidp;
#define z_off_t git_off_t #define z_off_t git_off_t
#define z_off64_t z_off_t #define z_off64_t z_off_t
#define z_const const
#endif /* ZCONF_H */ #endif /* ZCONF_H */
/* zutil.c -- target dependent utility functions for the compression library /* zutil.c -- target dependent utility functions for the compression library
* Copyright (C) 1995-2005, 2010 Jean-loup Gailly. * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
struct internal_state {int dummy;}; /* for buggy compilers */ struct internal_state {int dummy;}; /* for buggy compilers */
#endif #endif
const char * const z_errmsg[10] = { z_const char * const z_errmsg[10] = {
"need dictionary", /* Z_NEED_DICT 2 */ "need dictionary", /* Z_NEED_DICT 2 */
"stream end", /* Z_STREAM_END 1 */ "stream end", /* Z_STREAM_END 1 */
"", /* Z_OK 0 */ "", /* Z_OK 0 */
...@@ -85,27 +85,27 @@ uLong ZEXPORT zlibCompileFlags() ...@@ -85,27 +85,27 @@ uLong ZEXPORT zlibCompileFlags()
#ifdef FASTEST #ifdef FASTEST
flags += 1L << 21; flags += 1L << 21;
#endif #endif
#ifdef STDC #if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifdef NO_vsnprintf # ifdef NO_vsnprintf
flags += 1L << 25; flags += 1L << 25;
# ifdef HAS_vsprintf_void # ifdef HAS_vsprintf_void
flags += 1L << 26; flags += 1L << 26;
# endif # endif
# else # else
# ifdef HAS_vsnprintf_void # ifdef HAS_vsnprintf_void
flags += 1L << 26; flags += 1L << 26;
# endif # endif
# endif # endif
#else #else
flags += 1L << 24; flags += 1L << 24;
# ifdef NO_snprintf # ifdef NO_snprintf
flags += 1L << 25; flags += 1L << 25;
# ifdef HAS_sprintf_void # ifdef HAS_sprintf_void
flags += 1L << 26; flags += 1L << 26;
# endif # endif
# else # else
# ifdef HAS_snprintf_void # ifdef HAS_snprintf_void
flags += 1L << 26; flags += 1L << 26;
# endif # endif
# endif # endif
#endif #endif
...@@ -181,6 +181,7 @@ void ZLIB_INTERNAL zmemzero(dest, len) ...@@ -181,6 +181,7 @@ void ZLIB_INTERNAL zmemzero(dest, len)
} }
#endif #endif
#ifndef Z_SOLO
#ifdef SYS16BIT #ifdef SYS16BIT
...@@ -316,3 +317,5 @@ void ZLIB_INTERNAL zcfree (opaque, ptr) ...@@ -316,3 +317,5 @@ void ZLIB_INTERNAL zcfree (opaque, ptr)
} }
#endif /* MY_ZCALLOC */ #endif /* MY_ZCALLOC */
#endif /* !Z_SOLO */
/* zutil.h -- internal interface and configuration of the compression library /* zutil.h -- internal interface and configuration of the compression library
* Copyright (C) 1995-2010 Jean-loup Gailly. * Copyright (C) 1995-2013 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#ifndef ZUTIL_H #ifndef ZUTIL_H
#define ZUTIL_H #define ZUTIL_H
#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) #ifdef HAVE_HIDDEN
# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) # define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
#else #else
# define ZLIB_INTERNAL # define ZLIB_INTERNAL
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include "zlib.h" #include "zlib.h"
#ifdef STDC #if defined(STDC) && !defined(Z_SOLO)
# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) # if !(defined(_WIN32_WCE) && defined(_MSC_VER))
# include <stddef.h> # include <stddef.h>
# endif # endif
...@@ -29,6 +29,10 @@ ...@@ -29,6 +29,10 @@
# include <stdlib.h> # include <stdlib.h>
#endif #endif
#ifdef Z_SOLO
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
#endif
#ifndef local #ifndef local
# define local static # define local static
#endif #endif
...@@ -40,13 +44,13 @@ typedef unsigned short ush; ...@@ -40,13 +44,13 @@ typedef unsigned short ush;
typedef ush FAR ushf; typedef ush FAR ushf;
typedef unsigned long ulg; typedef unsigned long ulg;
extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */ /* (size given to avoid silly warnings with Visual C++) */
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
#define ERR_RETURN(strm,err) \ #define ERR_RETURN(strm,err) \
return (strm->msg = (char*)ERR_MSG(err), (err)) return (strm->msg = ERR_MSG(err), (err))
/* To be used only when the state is known to be valid */ /* To be used only when the state is known to be valid */
/* common constants */ /* common constants */
...@@ -78,16 +82,18 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ ...@@ -78,16 +82,18 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
# define OS_CODE 0x00 # define OS_CODE 0x00
# if defined(__TURBOC__) || defined(__BORLANDC__) # ifndef Z_SOLO
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) # if defined(__TURBOC__) || defined(__BORLANDC__)
/* Allow compilation with ANSI keywords only enabled */ # if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
void _Cdecl farfree( void *block ); /* Allow compilation with ANSI keywords only enabled */
void *_Cdecl farmalloc( unsigned long nbytes ); void _Cdecl farfree( void *block );
# else void *_Cdecl farmalloc( unsigned long nbytes );
# include <alloc.h> # else
# include <alloc.h>
# endif
# else /* MSC or DJGPP */
# include <malloc.h>
# endif # endif
# else /* MSC or DJGPP */
# include <malloc.h>
# endif # endif
#endif #endif
...@@ -107,18 +113,20 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ ...@@ -107,18 +113,20 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#ifdef OS2 #ifdef OS2
# define OS_CODE 0x06 # define OS_CODE 0x06
# ifdef M_I86 # if defined(M_I86) && !defined(Z_SOLO)
# include <malloc.h> # include <malloc.h>
# endif # endif
#endif #endif
#if defined(MACOS) || defined(TARGET_OS_MAC) #if defined(MACOS) || defined(TARGET_OS_MAC)
# define OS_CODE 0x07 # define OS_CODE 0x07
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # ifndef Z_SOLO
# include <unix.h> /* for fdopen */ # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
# else # include <unix.h> /* for fdopen */
# ifndef fdopen # else
# define fdopen(fd,mode) NULL /* No fdopen() */ # ifndef fdopen
# define fdopen(fd,mode) NULL /* No fdopen() */
# endif
# endif # endif
# endif # endif
#endif #endif
...@@ -153,14 +161,15 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ ...@@ -153,14 +161,15 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# endif # endif
#endif #endif
#if defined(__BORLANDC__) #if defined(__BORLANDC__) && !defined(MSDOS)
#pragma warn -8004 #pragma warn -8004
#pragma warn -8008 #pragma warn -8008
#pragma warn -8066 #pragma warn -8066
#endif #endif
/* provide prototypes for these when building zlib without LFS */ /* provide prototypes for these when building zlib without LFS */
#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 #if !defined(_WIN32) && \
(!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
#endif #endif
...@@ -177,42 +186,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ ...@@ -177,42 +186,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* functions */ /* functions */
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) #if defined(pyr) || defined(Z_SOLO)
# ifndef HAVE_VSNPRINTF
# define HAVE_VSNPRINTF
# endif
#endif
#if defined(__CYGWIN__)
# ifndef HAVE_VSNPRINTF
# define HAVE_VSNPRINTF
# endif
#endif
#ifndef HAVE_VSNPRINTF
# ifdef MSDOS
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
but for now we just assume it doesn't. */
# define NO_vsnprintf
# endif
# ifdef __TURBOC__
# define NO_vsnprintf
# endif
# ifdef WIN32
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
# define vsnprintf _vsnprintf
# endif
# endif
# endif
# ifdef __SASC
# define NO_vsnprintf
# endif
#endif
#ifdef VMS
# define NO_vsnprintf
#endif
#if defined(pyr)
# define NO_MEMCPY # define NO_MEMCPY
#endif #endif
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
...@@ -261,14 +235,19 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ ...@@ -261,14 +235,19 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# define Tracecv(c,x) # define Tracecv(c,x)
#endif #endif
#ifndef Z_SOLO
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
unsigned size)); unsigned size));
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
#endif
#define ZALLOC(strm, items, size) \ #define ZALLOC(strm, items, size) \
(*((strm)->zalloc))((strm)->opaque, (items), (size)) (*((strm)->zalloc))((strm)->opaque, (items), (size))
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} #define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
/* Reverse the bytes in a 32-bit value */
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
#endif /* ZUTIL_H */ #endif /* ZUTIL_H */
...@@ -76,25 +76,28 @@ GIT_BEGIN_DECL ...@@ -76,25 +76,28 @@ GIT_BEGIN_DECL
*/ */
#define GIT_ATTR_HAS_VALUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_T) #define GIT_ATTR_HAS_VALUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_T)
/**
* Possible states for an attribute
*/
typedef enum { typedef enum {
GIT_ATTR_UNSPECIFIED_T = 0, GIT_ATTR_UNSPECIFIED_T = 0, /**< The attribute has been left unspecified */
GIT_ATTR_TRUE_T, GIT_ATTR_TRUE_T, /**< The attribute has been set */
GIT_ATTR_FALSE_T, GIT_ATTR_FALSE_T, /**< The attribute has been unset */
GIT_ATTR_VALUE_T, GIT_ATTR_VALUE_T, /**< This attribute has a value */
} git_attr_t; } git_attr_t;
/* /**
* Return the value type for a given attribute. * Return the value type for a given attribute.
* *
* This can be either `TRUE`, `FALSE`, `UNSPECIFIED` (if the attribute * This can be either `TRUE`, `FALSE`, `UNSPECIFIED` (if the attribute
* was not set at all), or `VALUE`, if the attribute was set to * was not set at all), or `VALUE`, if the attribute was set to an
* an actual string. * actual string.
* *
* If the attribute has a `VALUE` string, it can be accessed normally * If the attribute has a `VALUE` string, it can be accessed normally
* as a NULL-terminated C string. * as a NULL-terminated C string.
* *
* @param attr The attribute * @param attr The attribute
* @return the value type for the attribute * @return the value type for the attribute
*/ */
GIT_EXTERN(git_attr_t) git_attr_value(const char *attr); GIT_EXTERN(git_attr_t) git_attr_value(const char *attr);
......
...@@ -105,6 +105,22 @@ GIT_EXTERN(int) git_buf_grow(git_buf *buffer, size_t target_size); ...@@ -105,6 +105,22 @@ GIT_EXTERN(int) git_buf_grow(git_buf *buffer, size_t target_size);
GIT_EXTERN(int) git_buf_set( GIT_EXTERN(int) git_buf_set(
git_buf *buffer, const void *data, size_t datalen); git_buf *buffer, const void *data, size_t datalen);
/**
* Check quickly if buffer looks like it contains binary data
*
* @param buf Buffer to check
* @return 1 if buffer looks like non-text data
*/
GIT_EXTERN(int) git_buf_is_binary(const git_buf *buf);
/**
* Check quickly if buffer contains a NUL byte
*
* @param buf Buffer to check
* @return 1 if buffer contains a NUL byte
*/
GIT_EXTERN(int) git_buf_contains_nul(const git_buf *buf);
GIT_END_DECL GIT_END_DECL
/** @} */ /** @} */
......
...@@ -233,18 +233,18 @@ typedef void (*git_checkout_progress_cb)( ...@@ -233,18 +233,18 @@ typedef void (*git_checkout_progress_cb)(
typedef struct git_checkout_options { typedef struct git_checkout_options {
unsigned int version; unsigned int version;
unsigned int checkout_strategy; /** default will be a dry run */ unsigned int checkout_strategy; /**< default will be a dry run */
int disable_filters; /** don't apply filters like CRLF conversion */ int disable_filters; /**< don't apply filters like CRLF conversion */
unsigned int dir_mode; /** default is 0755 */ unsigned int dir_mode; /**< default is 0755 */
unsigned int file_mode; /** default is 0644 or 0755 as dictated by blob */ unsigned int file_mode; /**< default is 0644 or 0755 as dictated by blob */
int file_open_flags; /** default is O_CREAT | O_TRUNC | O_WRONLY */ int file_open_flags; /**< default is O_CREAT | O_TRUNC | O_WRONLY */
unsigned int notify_flags; /** see `git_checkout_notify_t` above */ unsigned int notify_flags; /**< see `git_checkout_notify_t` above */
git_checkout_notify_cb notify_cb; git_checkout_notify_cb notify_cb;
void *notify_payload; void *notify_payload;
/* Optional callback to notify the consumer of checkout progress. */ /** Optional callback to notify the consumer of checkout progress. */
git_checkout_progress_cb progress_cb; git_checkout_progress_cb progress_cb;
void *progress_payload; void *progress_payload;
...@@ -254,13 +254,13 @@ typedef struct git_checkout_options { ...@@ -254,13 +254,13 @@ typedef struct git_checkout_options {
*/ */
git_strarray paths; git_strarray paths;
git_tree *baseline; /** expected content of workdir, defaults to HEAD */ git_tree *baseline; /**< expected content of workdir, defaults to HEAD */
const char *target_directory; /** alternative checkout path to workdir */ const char *target_directory; /**< alternative checkout path to workdir */
const char *ancestor_label; /** the name of the common ancestor side of conflicts */ const char *ancestor_label; /**< the name of the common ancestor side of conflicts */
const char *our_label; /** the name of the "our" side of conflicts */ const char *our_label; /**< the name of the "our" side of conflicts */
const char *their_label; /** the name of the "their" side of conflicts */ const char *their_label; /**< the name of the "their" side of conflicts */
} git_checkout_options; } git_checkout_options;
#define GIT_CHECKOUT_OPTIONS_VERSION 1 #define GIT_CHECKOUT_OPTIONS_VERSION 1
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "indexer.h" #include "indexer.h"
#include "checkout.h" #include "checkout.h"
#include "remote.h" #include "remote.h"
#include "transport.h"
/** /**
...@@ -52,6 +53,47 @@ typedef enum { ...@@ -52,6 +53,47 @@ typedef enum {
} git_clone_local_t; } git_clone_local_t;
/** /**
* The signature of a function matching git_remote_create, with an additional
* void* as a callback payload.
*
* Callers of git_clone may provide a function matching this signature to override
* the remote creation and customization process during a clone operation.
*
* @param out the resulting remote
* @param repo the repository in which to create the remote
* @param name the remote's name
* @param url the remote's url
* @param payload an opaque payload
* @return 0, GIT_EINVALIDSPEC, GIT_EEXISTS or an error code
*/
typedef int (*git_remote_create_cb)(
git_remote **out,
git_repository *repo,
const char *name,
const char *url,
void *payload);
/**
* The signature of a function matchin git_repository_init, with an
* aditional void * as callback payload.
*
* Callers of git_clone my provide a function matching this signature
* to override the repository creation and customization process
* during a clone operation.
*
* @param out the resulting repository
* @param path path in which to create the repository
* @param bare whether the repository is bare. This is the value from the clone options
* @param payload payload specified by the options
* @return 0, or a negative value to indicate error
*/
typedef int (*git_repository_create_cb)(
git_repository **out,
const char *path,
int bare,
void *payload);
/**
* Clone options structure * Clone options structure
* *
* Use the GIT_CLONE_OPTIONS_INIT to get the default settings, like this: * Use the GIT_CLONE_OPTIONS_INIT to get the default settings, like this:
...@@ -72,7 +114,11 @@ typedef struct git_clone_options { ...@@ -72,7 +114,11 @@ typedef struct git_clone_options {
git_checkout_options checkout_opts; git_checkout_options checkout_opts;
/** /**
* Callbacks to use for reporting fetch progress. * Callbacks to use for reporting fetch progress, and for acquiring
* credentials in the event they are needed. This parameter is ignored if
* the remote_cb parameter is set; if you provide a remote creation
* callback, then you have the opportunity to configure remote callbacks in
* provided function.
*/ */
git_remote_callbacks remote_callbacks; git_remote_callbacks remote_callbacks;
...@@ -83,23 +129,11 @@ typedef struct git_clone_options { ...@@ -83,23 +129,11 @@ typedef struct git_clone_options {
int bare; int bare;
/** /**
* Set to 1 if errors validating the remote host's certificate
* should be ignored.
*/
int ignore_cert_errors;
/**
* Whether to use a fetch or copy the object database. * Whether to use a fetch or copy the object database.
*/ */
git_clone_local_t local; git_clone_local_t local;
/** /**
* The name to be given to the remote that will be
* created. The default is "origin".
*/
const char *remote_name;
/**
* The name of the branch to checkout. NULL means use the * The name of the branch to checkout. NULL means use the
* remote's default branch. * remote's default branch.
*/ */
...@@ -110,6 +144,33 @@ typedef struct git_clone_options { ...@@ -110,6 +144,33 @@ typedef struct git_clone_options {
* use the default signature using the config. * use the default signature using the config.
*/ */
git_signature *signature; git_signature *signature;
/**
* A callback used to create the new repository into which to
* clone. If NULL, the 'bare' field will be used to determine
* whether to create a bare repository.
*/
git_repository_create_cb repository_cb;
/**
* An opaque payload to pass to the git_repository creation callback.
* This parameter is ignored unless repository_cb is non-NULL.
*/
void *repository_cb_payload;
/**
* A callback used to create the git_remote, prior to its being
* used to perform the clone operation. See the documentation for
* git_remote_create_cb for details. This parameter may be NULL,
* indicating that git_clone should provide default behavior.
*/
git_remote_create_cb remote_cb;
/**
* An opaque payload to pass to the git_remote creation callback.
* This parameter is ignored unless remote_cb is non-NULL.
*/
void *remote_cb_payload;
} git_clone_options; } git_clone_options;
#define GIT_CLONE_OPTIONS_VERSION 1 #define GIT_CLONE_OPTIONS_VERSION 1
...@@ -130,9 +191,9 @@ GIT_EXTERN(int) git_clone_init_options( ...@@ -130,9 +191,9 @@ GIT_EXTERN(int) git_clone_init_options(
/** /**
* Clone a remote repository. * Clone a remote repository.
* *
* This version handles the simple case. If you'd like to create the * By default this creates its repository and initial remote to match
* repository or remote with non-default settings, you can create and * git's defaults. You can use the options in the callback to
* configure them and then use `git_clone_into()`. * customize how these are created.
* *
* @param out pointer that will receive the resulting repository object * @param out pointer that will receive the resulting repository object
* @param url the remote repository to clone * @param url the remote repository to clone
...@@ -149,59 +210,6 @@ GIT_EXTERN(int) git_clone( ...@@ -149,59 +210,6 @@ GIT_EXTERN(int) git_clone(
const char *local_path, const char *local_path,
const git_clone_options *options); const git_clone_options *options);
/**
* Clone into a repository
*
* After creating the repository and remote and configuring them for
* paths and callbacks respectively, you can call this function to
* perform the clone operation and optionally checkout files.
*
* @param repo the repository to use
* @param remote the remote repository to clone from
* @param co_opts options to use during checkout
* @param branch the branch to checkout after the clone, pass NULL for the
* remote's default branch
* @param signature The identity used when updating the reflog.
* @return 0 on success, any non-zero return value from a callback
* function, or a negative value to indicate an error (use
* `giterr_last` for a detailed error message)
*/
GIT_EXTERN(int) git_clone_into(
git_repository *repo,
git_remote *remote,
const git_checkout_options *co_opts,
const char *branch,
const git_signature *signature);
/**
* Perform a local clone into a repository
*
* A "local clone" bypasses any git-aware protocols and simply copies
* over the object database from the source repository. It is often
* faster than a git-aware clone, but no verification of the data is
* performed, and can copy over too much data.
*
* @param repo the repository to use
* @param remote the remote repository to clone from
* @param co_opts options to use during checkout
* @param branch the branch to checkout after the clone, pass NULL for the
* remote's default branch
* @param link wether to use hardlinks instead of copying
* objects. This is only possible if both repositories are on the same
* filesystem.
* @param signature the identity used when updating the reflog
* @return 0 on success, any non-zero return value from a callback
* function, or a negative value to indicate an error (use
* `giterr_last` for a detailed error message)
*/
GIT_EXTERN(int) git_clone_local_into(
git_repository *repo,
git_remote *remote,
const git_checkout_options *co_opts,
const char *branch,
int link,
const git_signature *signature);
/** @} */ /** @} */
GIT_END_DECL GIT_END_DECL
#endif #endif
...@@ -419,20 +419,19 @@ GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo); ...@@ -419,20 +419,19 @@ GIT_EXTERN(int) git_remote_list(git_strarray *out, git_repository *repo);
GIT_EXTERN(void) git_remote_check_cert(git_remote *remote, int check); GIT_EXTERN(void) git_remote_check_cert(git_remote *remote, int check);
/** /**
* Sets a custom transport for the remote. The caller can use this function * Sets a custom transport factory for the remote. The caller can use this
* to bypass the automatic discovery of a transport by URL scheme (i.e. * function to override the transport used for this remote when performing
* http://, https://, git://) and supply their own transport to be used * network operations.
* instead. After providing the transport to a remote using this function,
* the transport object belongs exclusively to that remote, and the remote will
* free it when it is freed with git_remote_free.
* *
* @param remote the remote to configure * @param remote the remote to configure
* @param transport the transport object for the remote to use * @param transport_cb the function to use to create a transport
* @param payload opaque parameter passed to transport_cb
* @return 0 or an error code * @return 0 or an error code
*/ */
GIT_EXTERN(int) git_remote_set_transport( GIT_EXTERN(int) git_remote_set_transport(
git_remote *remote, git_remote *remote,
git_transport *transport); git_transport_cb transport_cb,
void *payload);
/** /**
* Argument to the completion callback which tells it which operation * Argument to the completion callback which tells it which operation
......
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
#ifndef INCLUDE_git_reset_h__ #ifndef INCLUDE_git_reset_h__
#define INCLUDE_git_reset_h__ #define INCLUDE_git_reset_h__
#include "common.h"
#include "types.h"
#include "strarray.h"
/** /**
* @file git2/reset.h * @file git2/reset.h
* @brief Git reset management routines * @brief Git reset management routines
......
...@@ -59,7 +59,7 @@ GIT_EXTERN(int) git_revert_init_options( ...@@ -59,7 +59,7 @@ GIT_EXTERN(int) git_revert_init_options(
* @param merge_options the merge options (or null for defaults) * @param merge_options the merge options (or null for defaults)
* @return zero on success, -1 on failure. * @return zero on success, -1 on failure.
*/ */
int git_revert_commit( GIT_EXTERN(int) git_revert_commit(
git_index **out, git_index **out,
git_repository *repo, git_repository *repo,
git_commit *revert_commit, git_commit *revert_commit,
......
...@@ -11,10 +11,6 @@ ...@@ -11,10 +11,6 @@
#include "net.h" #include "net.h"
#include "types.h" #include "types.h"
#ifdef GIT_SSH
#include <libssh2.h>
#endif
/** /**
* @file git2/transport.h * @file git2/transport.h
* @brief Git transport interfaces and functions * @brief Git transport interfaces and functions
...@@ -61,14 +57,20 @@ typedef struct { ...@@ -61,14 +57,20 @@ typedef struct {
char *password; char *password;
} git_cred_userpass_plaintext; } git_cred_userpass_plaintext;
#ifdef GIT_SSH
typedef LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*git_cred_sign_callback)); /*
typedef LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*git_cred_ssh_interactive_callback)); * If the user hasn't included libssh2.h before git2.h, we need to
#else * define a few types for the callback signatures.
typedef int (*git_cred_sign_callback)(void *, ...); */
typedef int (*git_cred_ssh_interactive_callback)(void *, ...); #ifndef LIBSSH2_VERSION
typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT LIBSSH2_USERAUTH_KBDINT_PROMPT;
typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE LIBSSH2_USERAUTH_KBDINT_RESPONSE;
#endif #endif
typedef int (*git_cred_sign_callback)(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract);
typedef void (*git_cred_ssh_interactive_callback)(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract);
/** /**
* A ssh key from disk * A ssh key from disk
*/ */
...@@ -334,6 +336,22 @@ GIT_EXTERN(int) git_transport_init( ...@@ -334,6 +336,22 @@ GIT_EXTERN(int) git_transport_init(
*/ */
GIT_EXTERN(int) git_transport_new(git_transport **out, git_remote *owner, const char *url); GIT_EXTERN(int) git_transport_new(git_transport **out, git_remote *owner, const char *url);
/**
* Create an ssh transport with custom git command paths
*
* This is a factory function suitable for setting as the transport
* callback in a remote (or for a clone in the options).
*
* The payload argument must be a strarray pointer with the paths for
* the `git-upload-pack` and `git-receive-pack` at index 0 and 1.
*
* @param out the resulting transport
* @param owner the owning remote
* @param payload a strarray with the paths
* @return 0 or an error code
*/
GIT_EXTERN(int) git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *payload);
/* Signature of a function which creates a transport */ /* Signature of a function which creates a transport */
typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param); typedef int (*git_transport_cb)(git_transport **out, git_remote *owner, void *param);
......
...@@ -301,8 +301,10 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get( ...@@ -301,8 +301,10 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(
* If an entry named `filename` already exists, its attributes * If an entry named `filename` already exists, its attributes
* will be updated with the given ones. * will be updated with the given ones.
* *
* The optional pointer `out` can be used to retrieve a pointer to * The optional pointer `out` can be used to retrieve a pointer to the
* the newly created/updated entry. Pass NULL if you do not need it. * newly created/updated entry. Pass NULL if you do not need it. The
* pointer may not be valid past the next operation in this
* builder. Duplicate the entry if you want to keep it.
* *
* No attempt is being made to ensure that the provided oid points * No attempt is being made to ensure that the provided oid points
* to an existing git object in the object database, nor that the * to an existing git object in the object database, nor that the
......
...@@ -34,5 +34,8 @@ export GITTEST_REMOTE_SSH_PUBKEY="$HOME/.ssh/id_rsa.pub" ...@@ -34,5 +34,8 @@ export GITTEST_REMOTE_SSH_PUBKEY="$HOME/.ssh/id_rsa.pub"
export GITTEST_REMOTE_SSH_PASSPHRASE="" export GITTEST_REMOTE_SSH_PASSPHRASE=""
if [ -e ./libgit2_clar ]; then if [ -e ./libgit2_clar ]; then
./libgit2_clar -sonline::push -sonline::clone::cred_callback_failure ./libgit2_clar -sonline::push -sonline::clone::cred_callback_failure &&
rm -rf $HOME/_temp/test.git &&
git init --bare $HOME/_temp/test.git && # create an empty one
./libgit2_clar -sonline::clone::ssh_with_paths
fi fi
...@@ -123,9 +123,13 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src) ...@@ -123,9 +123,13 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
for (; next; scan = next + 1, next = memchr(scan, '\n', end - scan)) { for (; next; scan = next + 1, next = memchr(scan, '\n', end - scan)) {
size_t copylen = next - scan; size_t copylen = next - scan;
/* don't convert existing \r\n to \r\r\n */ size_t needsize = tgt->size + copylen + 2 + 1;
size_t extralen = (next > start && next[-1] == '\r') ? 1 : 2;
size_t needsize = tgt->size + copylen + extralen + 1; /* if we find mixed line endings, bail */
if (next > start && next[-1] == '\r') {
git_buf_free(tgt);
return GIT_PASSTHROUGH;
}
if (tgt->asize < needsize && git_buf_grow(tgt, needsize) < 0) if (tgt->asize < needsize && git_buf_grow(tgt, needsize) < 0)
return -1; return -1;
...@@ -134,8 +138,8 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src) ...@@ -134,8 +138,8 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
memcpy(tgt->ptr + tgt->size, scan, copylen); memcpy(tgt->ptr + tgt->size, scan, copylen);
tgt->size += copylen; tgt->size += copylen;
} }
if (extralen == 2)
tgt->ptr[tgt->size++] = '\r'; tgt->ptr[tgt->size++] = '\r';
tgt->ptr[tgt->size++] = '\n'; tgt->ptr[tgt->size++] = '\n';
} }
......
...@@ -56,9 +56,10 @@ GIT_INLINE(int) git_buf_text_puts_escape_regex(git_buf *buf, const char *string) ...@@ -56,9 +56,10 @@ GIT_INLINE(int) git_buf_text_puts_escape_regex(git_buf *buf, const char *string)
extern void git_buf_text_unescape(git_buf *buf); extern void git_buf_text_unescape(git_buf *buf);
/** /**
* Replace all \r\n with \n. Does not modify \r without trailing \n. * Replace all \r\n with \n.
* *
* @return 0 on success, -1 on memory error * @return 0 on success, -1 on memory error, GIT_PASSTHROUGH if the
* source buffer has mixed line endings.
*/ */
extern int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src); extern int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "buffer.h" #include "buffer.h"
#include "posix.h" #include "posix.h"
#include "git2/buffer.h" #include "git2/buffer.h"
#include "buf_text.h"
#include <ctype.h> #include <ctype.h>
/* Used as default value for git_buf->ptr so that people can always /* Used as default value for git_buf->ptr so that people can always
...@@ -141,6 +142,16 @@ int git_buf_set(git_buf *buf, const void *data, size_t len) ...@@ -141,6 +142,16 @@ int git_buf_set(git_buf *buf, const void *data, size_t len)
return 0; return 0;
} }
int git_buf_is_binary(const git_buf *buf)
{
return git_buf_text_is_binary(buf);
}
int git_buf_contains_nul(const git_buf *buf)
{
return git_buf_text_contains_nul(buf);
}
int git_buf_sets(git_buf *buf, const char *string) int git_buf_sets(git_buf *buf, const char *string)
{ {
return git_buf_set(buf, string, string ? strlen(string) : 0); return git_buf_set(buf, string, string ? strlen(string) : 0);
......
...@@ -171,7 +171,7 @@ int git_cherry_pick( ...@@ -171,7 +171,7 @@ int git_cherry_pick(
char commit_oidstr[GIT_OID_HEXSZ + 1]; char commit_oidstr[GIT_OID_HEXSZ + 1];
const char *commit_msg, *commit_summary; const char *commit_msg, *commit_summary;
git_buf their_label = GIT_BUF_INIT; git_buf their_label = GIT_BUF_INIT;
git_index *index_new = NULL, *index_repo = NULL; git_index *index_new = NULL;
int error = 0; int error = 0;
assert(repo && commit); assert(repo && commit);
...@@ -196,12 +196,10 @@ int git_cherry_pick( ...@@ -196,12 +196,10 @@ int git_cherry_pick(
(error = git_repository_head(&our_ref, repo)) < 0 || (error = git_repository_head(&our_ref, repo)) < 0 ||
(error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 || (error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 ||
(error = git_cherry_pick_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 || (error = git_cherry_pick_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
(error = git_merge__indexes(repo, index_new)) < 0 || (error = git_merge__check_result(repo, index_new)) < 0 ||
(error = git_repository_index(&index_repo, repo)) < 0 || (error = git_merge__append_conflicts_to_merge_msg(repo, index_new)) < 0 ||
(error = git_merge__append_conflicts_to_merge_msg(repo, index_repo)) < 0 || (error = git_checkout_index(repo, index_new, &opts.checkout_opts)) < 0)
(error = git_checkout_index(repo, index_repo, &opts.checkout_opts)) < 0)
goto on_error; goto on_error;
goto done; goto done;
on_error: on_error:
...@@ -209,7 +207,6 @@ on_error: ...@@ -209,7 +207,6 @@ on_error:
done: done:
git_index_free(index_new); git_index_free(index_new);
git_index_free(index_repo);
git_commit_free(our_commit); git_commit_free(our_commit);
git_reference_free(our_ref); git_reference_free(our_ref);
git_buf_free(&their_label); git_buf_free(&their_label);
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "repository.h" #include "repository.h"
#include "odb.h" #include "odb.h"
static int clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature);
static int create_branch( static int create_branch(
git_reference **branch, git_reference **branch,
git_repository *repo, git_repository *repo,
...@@ -229,6 +231,29 @@ cleanup: ...@@ -229,6 +231,29 @@ cleanup:
return retcode; return retcode;
} }
static int default_repository_create(git_repository **out, const char *path, int bare, void *payload)
{
GIT_UNUSED(payload);
return git_repository_init(out, path, bare);
}
static int default_remote_create(
git_remote **out,
git_repository *repo,
const char *name,
const char *url,
void *payload)
{
int error;
git_remote_callbacks *callbacks = payload;
if ((error = git_remote_create(out, repo, name, url)) < 0)
return error;
return git_remote_set_callbacks(*out, callbacks);
}
/* /*
* submodules? * submodules?
*/ */
...@@ -241,8 +266,9 @@ static int create_and_configure_origin( ...@@ -241,8 +266,9 @@ static int create_and_configure_origin(
{ {
int error; int error;
git_remote *origin = NULL; git_remote *origin = NULL;
const char *name;
char buf[GIT_PATH_MAX]; char buf[GIT_PATH_MAX];
git_remote_create_cb remote_create = options->remote_cb;
void *payload = options->remote_cb_payload;
/* If the path exists and is a dir, the url should be the absolute path */ /* If the path exists and is a dir, the url should be the absolute path */
if (git_path_root(url) < 0 && git_path_exists(url) && git_path_isdir(url)) { if (git_path_root(url) < 0 && git_path_exists(url) && git_path_isdir(url)) {
...@@ -252,14 +278,12 @@ static int create_and_configure_origin( ...@@ -252,14 +278,12 @@ static int create_and_configure_origin(
url = buf; url = buf;
} }
name = options->remote_name ? options->remote_name : "origin"; if (!remote_create) {
if ((error = git_remote_create(&origin, repo, name, url)) < 0) remote_create = default_remote_create;
goto on_error; payload = (void *)&options->remote_callbacks;
}
if (options->ignore_cert_errors)
git_remote_check_cert(origin, 0);
if ((error = git_remote_set_callbacks(origin, &options->remote_callbacks)) < 0) if ((error = remote_create(&origin, repo, "origin", url, payload)) < 0)
goto on_error; goto on_error;
if ((error = git_remote_save(origin)) < 0) if ((error = git_remote_save(origin)) < 0)
...@@ -307,7 +331,7 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c ...@@ -307,7 +331,7 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c
return error; return error;
} }
int git_clone_into(git_repository *repo, git_remote *_remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature) static int clone_into(git_repository *repo, git_remote *_remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature)
{ {
int error; int error;
git_buf reflog_message = GIT_BUF_INIT; git_buf reflog_message = GIT_BUF_INIT;
...@@ -347,27 +371,30 @@ cleanup: ...@@ -347,27 +371,30 @@ cleanup:
return error; return error;
} }
int git_clone__should_clone_local(const char *url, git_clone_local_t local) int git_clone__should_clone_local(const char *url_or_path, git_clone_local_t local)
{ {
const char *path; git_buf fromurl = GIT_BUF_INIT;
int is_url; const char *path = url_or_path;
bool is_url, is_local;
if (local == GIT_CLONE_NO_LOCAL) if (local == GIT_CLONE_NO_LOCAL)
return false; return 0;
is_url = !git__prefixcmp(url, "file://");
if (is_url && local != GIT_CLONE_LOCAL && local != GIT_CLONE_LOCAL_NO_LINKS ) if ((is_url = git_path_is_local_file_url(url_or_path)) != 0) {
return false; if (git_path_fromurl(&fromurl, url_or_path) < 0) {
is_local = -1;
goto done;
}
path = url; path = fromurl.ptr;
if (is_url) }
path = url + strlen("file://");
if ((git_path_exists(path) && git_path_isdir(path)) && local != GIT_CLONE_NO_LOCAL) is_local = (!is_url || local != GIT_CLONE_LOCAL_AUTO) &&
return true; git_path_isdir(path);
return false; done:
git_buf_free(&fromurl);
return is_local;
} }
int git_clone( int git_clone(
...@@ -381,6 +408,7 @@ int git_clone( ...@@ -381,6 +408,7 @@ int git_clone(
git_remote *origin; git_remote *origin;
git_clone_options options = GIT_CLONE_OPTIONS_INIT; git_clone_options options = GIT_CLONE_OPTIONS_INIT;
uint32_t rmdir_flags = GIT_RMDIR_REMOVE_FILES; uint32_t rmdir_flags = GIT_RMDIR_REMOVE_FILES;
git_repository_create_cb repository_cb;
assert(out && url && local_path); assert(out && url && local_path);
...@@ -400,20 +428,28 @@ int git_clone( ...@@ -400,20 +428,28 @@ int git_clone(
if (git_path_exists(local_path)) if (git_path_exists(local_path))
rmdir_flags |= GIT_RMDIR_SKIP_ROOT; rmdir_flags |= GIT_RMDIR_SKIP_ROOT;
if ((error = git_repository_init(&repo, local_path, options.bare)) < 0) if (options.repository_cb)
repository_cb = options.repository_cb;
else
repository_cb = default_repository_create;
if ((error = repository_cb(&repo, local_path, options.bare, options.repository_cb_payload)) < 0)
return error; return error;
if (!(error = create_and_configure_origin(&origin, repo, url, &options))) { if (!(error = create_and_configure_origin(&origin, repo, url, &options))) {
if (git_clone__should_clone_local(url, options.local)) { int clone_local = git_clone__should_clone_local(url, options.local);
int link = options.local != GIT_CLONE_LOCAL_NO_LINKS; int link = options.local != GIT_CLONE_LOCAL_NO_LINKS;
error = git_clone_local_into(
if (clone_local == 1)
error = clone_local_into(
repo, origin, &options.checkout_opts, repo, origin, &options.checkout_opts,
options.checkout_branch, link, options.signature); options.checkout_branch, link, options.signature);
} else { else if (clone_local == 0)
error = git_clone_into( error = clone_into(
repo, origin, &options.checkout_opts, repo, origin, &options.checkout_opts,
options.checkout_branch, options.signature); options.checkout_branch, options.signature);
} else
error = -1;
git_remote_free(origin); git_remote_free(origin);
} }
...@@ -470,7 +506,7 @@ static bool can_link(const char *src, const char *dst, int link) ...@@ -470,7 +506,7 @@ static bool can_link(const char *src, const char *dst, int link)
#endif #endif
} }
int git_clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature) static int clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature)
{ {
int error, flags; int error, flags;
git_repository *src; git_repository *src;
......
...@@ -1522,6 +1522,9 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p ...@@ -1522,6 +1522,9 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
git_filebuf_write(&file, reader->buffer.ptr, reader->buffer.size); git_filebuf_write(&file, reader->buffer.ptr, reader->buffer.size);
if (reader->buffer.size > 0 && *(reader->buffer.ptr + reader->buffer.size - 1) != '\n')
git_filebuf_write(&file, "\n", 1);
/* And now if we just need to add a variable */ /* And now if we just need to add a variable */
if (!section_matches && write_section(&file, section) < 0) if (!section_matches && write_section(&file, section) < 0)
goto rewrite_fail; goto rewrite_fail;
...@@ -1536,9 +1539,6 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p ...@@ -1536,9 +1539,6 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
} }
/* If we are here, there is at least a section line */ /* If we are here, there is at least a section line */
if (reader->buffer.size > 0 && *(reader->buffer.ptr + reader->buffer.size - 1) != '\n')
git_filebuf_write(&file, "\n", 1);
q = quotes_for_value(value); q = quotes_for_value(value);
git_filebuf_printf(&file, "\t%s = %s%s%s\n", name, q, value, q); git_filebuf_printf(&file, "\t%s = %s%s%s\n", name, q, value, q);
} }
......
...@@ -286,7 +286,8 @@ static int crlf_check( ...@@ -286,7 +286,8 @@ static int crlf_check(
if (error < 0) if (error < 0)
return error; return error;
if (ca.auto_crlf == GIT_AUTO_CRLF_FALSE) if (ca.crlf_action == GIT_CRLF_GUESS &&
ca.auto_crlf == GIT_AUTO_CRLF_FALSE)
return GIT_PASSTHROUGH; return GIT_PASSTHROUGH;
if (ca.auto_crlf == GIT_AUTO_CRLF_INPUT && if (ca.auto_crlf == GIT_AUTO_CRLF_INPUT &&
......
...@@ -334,8 +334,6 @@ int git_filebuf_commit(git_filebuf *file) ...@@ -334,8 +334,6 @@ int git_filebuf_commit(git_filebuf *file)
file->fd = -1; file->fd = -1;
p_unlink(file->path_original);
if (p_rename(file->path_lock, file->path_original) < 0) { if (p_rename(file->path_lock, file->path_original) < 0) {
giterr_set(GITERR_OS, "Failed to rename lockfile to '%s'", file->path_original); giterr_set(GITERR_OS, "Failed to rename lockfile to '%s'", file->path_original);
goto on_error; goto on_error;
......
...@@ -291,7 +291,13 @@ static git_global_st __state; ...@@ -291,7 +291,13 @@ static git_global_st __state;
int git_threads_init(void) int git_threads_init(void)
{ {
init_ssl(); static int ssl_inited = 0;
if (!ssl_inited) {
init_ssl();
ssl_inited = 1;
}
git_atomic_inc(&git__n_inits); git_atomic_inc(&git__n_inits);
return 0; return 0;
} }
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include "oidmap.h" #include "oidmap.h"
#include "zstream.h" #include "zstream.h"
extern git_mutex git__mwindow_mutex;
#define UINT31_MAX (0x7FFFFFFF) #define UINT31_MAX (0x7FFFFFFF)
struct entry { struct entry {
...@@ -433,6 +435,8 @@ static int write_at(git_indexer *idx, const void *data, git_off_t offset, size_t ...@@ -433,6 +435,8 @@ static int write_at(git_indexer *idx, const void *data, git_off_t offset, size_t
git_map map; git_map map;
int error; int error;
assert(data && size);
/* the offset needs to be at the beginning of the a page boundary */ /* the offset needs to be at the beginning of the a page boundary */
page_start = (offset / page_size) * page_size; page_start = (offset / page_size) * page_size;
page_offset = offset - page_start; page_offset = offset - page_start;
...@@ -451,9 +455,12 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size) ...@@ -451,9 +455,12 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size)
{ {
git_off_t current_size = idx->pack->mwf.size; git_off_t current_size = idx->pack->mwf.size;
if (!size)
return 0;
/* add the extra space we need at the end */ /* add the extra space we need at the end */
if (p_ftruncate(idx->pack->mwf.fd, current_size + size) < 0) { if (p_ftruncate(idx->pack->mwf.fd, current_size + size) < 0) {
giterr_system_set(errno); giterr_set(GITERR_OS, "Failed to increase size of pack file '%s'", idx->pack->pack_name);
return -1; return -1;
} }
...@@ -1044,6 +1051,11 @@ void git_indexer_free(git_indexer *idx) ...@@ -1044,6 +1051,11 @@ void git_indexer_free(git_indexer *idx)
} }
git_vector_free_deep(&idx->deltas); git_vector_free_deep(&idx->deltas);
git_packfile_free(idx->pack);
if (!git_mutex_lock(&git__mwindow_mutex)) {
git_packfile_free(idx->pack);
git_mutex_unlock(&git__mwindow_mutex);
}
git__free(idx); git__free(idx);
} }
...@@ -2226,64 +2226,6 @@ static int merge_normalize_checkout_opts( ...@@ -2226,64 +2226,6 @@ static int merge_normalize_checkout_opts(
return error; return error;
} }
static int merge_affected_paths(git_vector *paths, git_repository *repo, git_index *index_new)
{
git_tree *head_tree = NULL;
git_iterator *iter_head = NULL, *iter_new = NULL;
git_diff *merged_list = NULL;
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_delta *delta;
size_t i;
const git_index_entry *e;
char *path;
int error = 0;
if ((error = git_repository_head_tree(&head_tree, repo)) < 0 ||
(error = git_iterator_for_tree(&iter_head, head_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
(error = git_iterator_for_index(&iter_new, index_new, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
(error = git_diff__from_iterators(&merged_list, repo, iter_head, iter_new, &opts)) < 0)
goto done;
git_vector_foreach(&merged_list->deltas, i, delta) {
path = git__strdup(delta->new_file.path);
GITERR_CHECK_ALLOC(path);
if ((error = git_vector_insert(paths, path)) < 0)
goto on_error;
}
for (i = 0; i < git_index_entrycount(index_new); i++) {
e = git_index_get_byindex(index_new, i);
if (git_index_entry_stage(e) != 0 &&
(git_vector_last(paths) == NULL ||
strcmp(git_vector_last(paths), e->path) != 0)) {
path = git__strdup(e->path);
GITERR_CHECK_ALLOC(path);
if ((error = git_vector_insert(paths, path)) < 0)
goto on_error;
}
}
goto done;
on_error:
git_vector_foreach(paths, i, path)
git__free(path);
git_vector_clear(paths);
done:
git_tree_free(head_tree);
git_iterator_free(iter_head);
git_iterator_free(iter_new);
git_diff_free(merged_list);
return error;
}
static int merge_check_index(size_t *conflicts, git_repository *repo, git_index *index_new, git_vector *merged_paths) static int merge_check_index(size_t *conflicts, git_repository *repo, git_index *index_new, git_vector *merged_paths)
{ {
git_tree *head_tree = NULL; git_tree *head_tree = NULL;
...@@ -2372,99 +2314,58 @@ done: ...@@ -2372,99 +2314,58 @@ done:
return error; return error;
} }
int git_merge__indexes(git_repository *repo, git_index *index_new) int git_merge__check_result(git_repository *repo, git_index *index_new)
{ {
git_index *index_repo = NULL; git_tree *head_tree = NULL;
int index_repo_caps = 0; git_iterator *iter_head = NULL, *iter_new = NULL;
git_diff *merged_list = NULL;
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_delta *delta;
git_vector paths = GIT_VECTOR_INIT; git_vector paths = GIT_VECTOR_INIT;
size_t index_conflicts = 0, wd_conflicts = 0, conflicts, i; size_t i, index_conflicts = 0, wd_conflicts = 0, conflicts;
char *path;
const git_index_entry *e; const git_index_entry *e;
const git_index_name_entry *name;
const git_index_reuc_entry *reuc;
int error = 0; int error = 0;
if ((error = git_repository_index(&index_repo, repo)) < 0) if ((error = git_repository_head_tree(&head_tree, repo)) < 0 ||
goto done; (error = git_iterator_for_tree(&iter_head, head_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
(error = git_iterator_for_index(&iter_new, index_new, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
/* Set the index to case sensitive to handle the merge */ (error = git_diff__from_iterators(&merged_list, repo, iter_head, iter_new, &opts)) < 0)
index_repo_caps = git_index_caps(index_repo);
if ((error = git_index_set_caps(index_repo, (index_repo_caps & ~GIT_INDEXCAP_IGNORE_CASE))) < 0)
goto done;
/* Make sure the index and workdir state do not prevent merging */
if ((error = merge_affected_paths(&paths, repo, index_new)) < 0 ||
(error = merge_check_index(&index_conflicts, repo, index_new, &paths)) < 0 ||
(error = merge_check_workdir(&wd_conflicts, repo, index_new, &paths)) < 0)
goto done;
if ((conflicts = index_conflicts + wd_conflicts) > 0) {
giterr_set(GITERR_MERGE, "%d uncommitted change%s would be overwritten by merge",
conflicts, (conflicts != 1) ? "s" : "");
error = GIT_EMERGECONFLICT;
goto done; goto done;
}
/* Remove removed items from the index */
git_vector_foreach(&paths, i, path) {
if (git_index_get_bypath(index_new, path, 0) == NULL) {
if ((error = git_index_remove(index_repo, path, 0)) < 0 &&
error != GIT_ENOTFOUND)
goto done;
}
}
/* Add updated items to the index */ git_vector_foreach(&merged_list->deltas, i, delta) {
git_vector_foreach(&paths, i, path) { if ((error = git_vector_insert(&paths, (char *)delta->new_file.path)) < 0)
if ((e = git_index_get_bypath(index_new, path, 0)) != NULL) { goto done;
if ((error = git_index_add(index_repo, e)) < 0)
goto done;
}
} }
/* Add conflicts */
git_index_conflict_cleanup(index_repo);
for (i = 0; i < git_index_entrycount(index_new); i++) { for (i = 0; i < git_index_entrycount(index_new); i++) {
e = git_index_get_byindex(index_new, i); e = git_index_get_byindex(index_new, i);
if (git_index_entry_stage(e) != 0 && if (git_index_entry_stage(e) != 0 &&
(error = git_index_add(index_repo, e)) < 0) (git_vector_last(&paths) == NULL ||
goto done; strcmp(git_vector_last(&paths), e->path) != 0)) {
}
/* Add name entries */
git_index_name_clear(index_repo);
for (i = 0; i < git_index_name_entrycount(index_new); i++) { if ((error = git_vector_insert(&paths, (char *)e->path)) < 0)
name = git_index_name_get_byindex(index_new, i); goto done;
}
if ((error = git_index_name_add(index_repo,
name->ancestor, name->ours, name->theirs)) < 0)
goto done;
} }
/* Add the reuc */ /* Make sure the index and workdir state do not prevent merging */
git_index_reuc_clear(index_repo); if ((error = merge_check_index(&index_conflicts, repo, index_new, &paths)) < 0 ||
(error = merge_check_workdir(&wd_conflicts, repo, index_new, &paths)) < 0)
for (i = 0; i < git_index_reuc_entrycount(index_new); i++) { goto done;
reuc = (git_index_reuc_entry *)git_index_reuc_get_byindex(index_new, i);
if ((error = git_index_reuc_add(index_repo, reuc->path, if ((conflicts = index_conflicts + wd_conflicts) > 0) {
reuc->mode[0], &reuc->oid[0], giterr_set(GITERR_MERGE, "%d uncommitted change%s would be overwritten by merge",
reuc->mode[1], &reuc->oid[1], conflicts, (conflicts != 1) ? "s" : "");
reuc->mode[2], &reuc->oid[2])) < 0) error = GIT_EMERGECONFLICT;
goto done;
} }
done: done:
if (index_repo != NULL) git_vector_free(&paths);
git_index_set_caps(index_repo, index_repo_caps); git_tree_free(head_tree);
git_iterator_free(iter_head);
git_index_free(index_repo); git_iterator_free(iter_new);
git_vector_free_deep(&paths); git_diff_free(merged_list);
return error; return error;
} }
...@@ -2479,12 +2380,14 @@ int git_merge__append_conflicts_to_merge_msg( ...@@ -2479,12 +2380,14 @@ int git_merge__append_conflicts_to_merge_msg(
size_t i; size_t i;
int error; int error;
if (!git_index_has_conflicts(index))
return 0;
if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 || if ((error = git_buf_joinpath(&file_path, repo->path_repository, GIT_MERGE_MSG_FILE)) < 0 ||
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_APPEND, GIT_MERGE_FILE_MODE)) < 0) (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_APPEND, GIT_MERGE_FILE_MODE)) < 0)
goto cleanup; goto cleanup;
if (git_index_has_conflicts(index)) git_filebuf_printf(&file, "\nConflicts:\n");
git_filebuf_printf(&file, "\nConflicts:\n");
for (i = 0; i < git_index_entrycount(index); i++) { for (i = 0; i < git_index_entrycount(index); i++) {
const git_index_entry *e = git_index_get_byindex(index, i); const git_index_entry *e = git_index_get_byindex(index, i);
...@@ -2509,7 +2412,6 @@ cleanup: ...@@ -2509,7 +2412,6 @@ cleanup:
return error; return error;
} }
static int merge_state_cleanup(git_repository *repo) static int merge_state_cleanup(git_repository *repo)
{ {
const char *state_files[] = { const char *state_files[] = {
...@@ -2657,7 +2559,7 @@ int git_merge( ...@@ -2657,7 +2559,7 @@ int git_merge(
git_checkout_options checkout_opts; git_checkout_options checkout_opts;
git_merge_head *ancestor_head = NULL, *our_head = NULL; git_merge_head *ancestor_head = NULL, *our_head = NULL;
git_tree *ancestor_tree = NULL, *our_tree = NULL, **their_trees = NULL; git_tree *ancestor_tree = NULL, *our_tree = NULL, **their_trees = NULL;
git_index *index_new = NULL, *index_repo = NULL; git_index *index_new = NULL;
size_t i; size_t i;
int error = 0; int error = 0;
...@@ -2697,10 +2599,9 @@ int git_merge( ...@@ -2697,10 +2599,9 @@ int git_merge(
/* TODO: recursive, octopus, etc... */ /* TODO: recursive, octopus, etc... */
if ((error = git_merge_trees(&index_new, repo, ancestor_tree, our_tree, their_trees[0], merge_opts)) < 0 || if ((error = git_merge_trees(&index_new, repo, ancestor_tree, our_tree, their_trees[0], merge_opts)) < 0 ||
(error = git_merge__indexes(repo, index_new)) < 0 || (error = git_merge__check_result(repo, index_new)) < 0 ||
(error = git_repository_index(&index_repo, repo)) < 0 || (error = git_merge__append_conflicts_to_merge_msg(repo, index_new)) < 0 ||
(error = git_merge__append_conflicts_to_merge_msg(repo, index_repo)) < 0 || (error = git_checkout_index(repo, index_new, &checkout_opts)) < 0)
(error = git_checkout_index(repo, index_repo, &checkout_opts)) < 0)
goto on_error; goto on_error;
goto done; goto done;
...@@ -2710,7 +2611,6 @@ on_error: ...@@ -2710,7 +2611,6 @@ on_error:
done: done:
git_index_free(index_new); git_index_free(index_new);
git_index_free(index_repo);
git_tree_free(ancestor_tree); git_tree_free(ancestor_tree);
git_tree_free(our_tree); git_tree_free(our_tree);
......
...@@ -149,7 +149,7 @@ int git_merge__setup( ...@@ -149,7 +149,7 @@ int git_merge__setup(
const git_merge_head *heads[], const git_merge_head *heads[],
size_t heads_len); size_t heads_len);
int git_merge__indexes(git_repository *repo, git_index *index_new); int git_merge__check_result(git_repository *repo, git_index *index_new);
int git_merge__append_conflicts_to_merge_msg(git_repository *repo, git_index *index); int git_merge__append_conflicts_to_merge_msg(git_repository *repo, git_index *index);
......
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
#include "fileops.h" #include "fileops.h"
#include "map.h" #include "map.h"
#include "global.h" #include "global.h"
#include "strmap.h"
#include "pack.h"
GIT__USE_STRMAP;
#define DEFAULT_WINDOW_SIZE \ #define DEFAULT_WINDOW_SIZE \
(sizeof(void*) >= 8 \ (sizeof(void*) >= 8 \
...@@ -26,20 +30,127 @@ size_t git_mwindow__mapped_limit = DEFAULT_MAPPED_LIMIT; ...@@ -26,20 +30,127 @@ size_t git_mwindow__mapped_limit = DEFAULT_MAPPED_LIMIT;
/* Whenever you want to read or modify this, grab git__mwindow_mutex */ /* Whenever you want to read or modify this, grab git__mwindow_mutex */
static git_mwindow_ctl mem_ctl; static git_mwindow_ctl mem_ctl;
/* /* Global list of mwindow files, to open packs once across repos */
* Free all the windows in a sequence, typically because we're done git_strmap *git__pack_cache = NULL;
* with the file
/**
* Run under mwindow lock
*/ */
void git_mwindow_free_all(git_mwindow_file *mwf) int git_mwindow_files_init(void)
{ {
git_mwindow_ctl *ctl = &mem_ctl; if (git__pack_cache)
size_t i; return 0;
return git_strmap_alloc(&git__pack_cache);
}
void git_mwindow_files_free(void)
{
git_strmap *tmp = git__pack_cache;
git__pack_cache = NULL;
git_strmap_free(tmp);
}
int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
{
int error;
char *packname;
git_strmap_iter pos;
struct git_pack_file *pack;
if ((error = git_packfile__name(&packname, path)) < 0)
return error;
if (git_mutex_lock(&git__mwindow_mutex) < 0) {
giterr_set(GITERR_OS, "failed to lock mwindow mutex");
return -1;
}
if (git_mwindow_files_init() < 0) {
git_mutex_unlock(&git__mwindow_mutex);
git__free(packname);
return -1;
}
pos = git_strmap_lookup_index(git__pack_cache, packname);
git__free(packname);
if (git_strmap_valid_index(git__pack_cache, pos)) {
pack = git_strmap_value_at(git__pack_cache, pos);
git_atomic_inc(&pack->refcount);
git_mutex_unlock(&git__mwindow_mutex);
*out = pack;
return 0;
}
/* If we didn't find it, we need to create it */
if ((error = git_packfile_alloc(&pack, path)) < 0) {
git_mutex_unlock(&git__mwindow_mutex);
return error;
}
git_atomic_inc(&pack->refcount);
git_strmap_insert(git__pack_cache, pack->pack_name, pack, error);
git_mutex_unlock(&git__mwindow_mutex);
if (error < 0) {
git_packfile_free(pack);
return -1;
}
*out = pack;
return 0;
}
void git_mwindow_put_pack(struct git_pack_file *pack)
{
int count;
git_strmap_iter pos;
if (git_mutex_lock(&git__mwindow_mutex) < 0)
return;
/* put before get would be a corrupted state */
assert(git__pack_cache);
pos = git_strmap_lookup_index(git__pack_cache, pack->pack_name);
/* if we cannot find it, the state is corrupted */
assert(git_strmap_valid_index(git__pack_cache, pos));
count = git_atomic_dec(&pack->refcount);
if (count == 0) {
git_strmap_delete_at(git__pack_cache, pos);
git_packfile_free(pack);
}
git_mutex_unlock(&git__mwindow_mutex);
return;
}
void git_mwindow_free_all(git_mwindow_file *mwf)
{
if (git_mutex_lock(&git__mwindow_mutex)) { if (git_mutex_lock(&git__mwindow_mutex)) {
giterr_set(GITERR_THREAD, "unable to lock mwindow mutex"); giterr_set(GITERR_THREAD, "unable to lock mwindow mutex");
return; return;
} }
git_mwindow_free_all_locked(mwf);
git_mutex_unlock(&git__mwindow_mutex);
}
/*
* Free all the windows in a sequence, typically because we're done
* with the file
*/
void git_mwindow_free_all_locked(git_mwindow_file *mwf)
{
git_mwindow_ctl *ctl = &mem_ctl;
size_t i;
/* /*
* Remove these windows from the global list * Remove these windows from the global list
*/ */
...@@ -67,8 +178,6 @@ void git_mwindow_free_all(git_mwindow_file *mwf) ...@@ -67,8 +178,6 @@ void git_mwindow_free_all(git_mwindow_file *mwf)
mwf->windows = w->next; mwf->windows = w->next;
git__free(w); git__free(w);
} }
git_mutex_unlock(&git__mwindow_mutex);
} }
/* /*
......
...@@ -36,10 +36,18 @@ typedef struct git_mwindow_ctl { ...@@ -36,10 +36,18 @@ typedef struct git_mwindow_ctl {
} git_mwindow_ctl; } git_mwindow_ctl;
int git_mwindow_contains(git_mwindow *win, git_off_t offset); int git_mwindow_contains(git_mwindow *win, git_off_t offset);
void git_mwindow_free_all(git_mwindow_file *mwf); void git_mwindow_free_all(git_mwindow_file *mwf); /* locks */
void git_mwindow_free_all_locked(git_mwindow_file *mwf); /* run under lock */
unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, git_off_t offset, size_t extra, unsigned int *left); unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, git_off_t offset, size_t extra, unsigned int *left);
int git_mwindow_file_register(git_mwindow_file *mwf); int git_mwindow_file_register(git_mwindow_file *mwf);
void git_mwindow_file_deregister(git_mwindow_file *mwf); void git_mwindow_file_deregister(git_mwindow_file *mwf);
void git_mwindow_close(git_mwindow **w_cursor); void git_mwindow_close(git_mwindow **w_cursor);
int git_mwindow_files_init(void);
void git_mwindow_files_free(void);
struct git_pack_file; /* just declaration to avoid cyclical includes */
int git_mwindow_get_pack(struct git_pack_file **out, const char *path);
void git_mwindow_put_pack(struct git_pack_file *pack);
#endif #endif
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
# include <netinet/in.h> # include <netinet/in.h>
# include <arpa/inet.h> # include <arpa/inet.h>
#else #else
# include <winsock2.h>
# include <ws2tcpip.h> # include <ws2tcpip.h>
# ifdef _MSC_VER # ifdef _MSC_VER
# pragma comment(lib, "ws2_32") # pragma comment(lib, "ws2_32")
...@@ -717,6 +718,9 @@ int gitno_extract_url_parts( ...@@ -717,6 +718,9 @@ int gitno_extract_url_parts(
if (u.field_set & (1 << UF_PATH)) { if (u.field_set & (1 << UF_PATH)) {
*path = git__substrdup(_path, u.field_data[UF_PATH].len); *path = git__substrdup(_path, u.field_data[UF_PATH].len);
GITERR_CHECK_ALLOC(*path); GITERR_CHECK_ALLOC(*path);
} else {
giterr_set(GITERR_NET, "invalid url, missing path");
return GIT_EINVALIDSPEC;
} }
if (u.field_set & (1 << UF_USERINFO)) { if (u.field_set & (1 << UF_USERINFO)) {
......
...@@ -210,7 +210,7 @@ static int packfile_load__cb(void *data, git_buf *path) ...@@ -210,7 +210,7 @@ static int packfile_load__cb(void *data, git_buf *path)
return 0; return 0;
} }
error = git_packfile_alloc(&pack, path->ptr); error = git_mwindow_get_pack(&pack, path->ptr);
/* ignore missing .pack file as git does */ /* ignore missing .pack file as git does */
if (error == GIT_ENOTFOUND) { if (error == GIT_ENOTFOUND) {
...@@ -605,7 +605,7 @@ static void pack_backend__free(git_odb_backend *_backend) ...@@ -605,7 +605,7 @@ static void pack_backend__free(git_odb_backend *_backend)
for (i = 0; i < backend->packs.length; ++i) { for (i = 0; i < backend->packs.length; ++i) {
struct git_pack_file *p = git_vector_get(&backend->packs, i); struct git_pack_file *p = git_vector_get(&backend->packs, i);
git_packfile_free(p); git_mwindow_put_pack(p);
} }
git_vector_free(&backend->packs); git_vector_free(&backend->packs);
...@@ -647,7 +647,7 @@ int git_odb_backend_one_pack(git_odb_backend **backend_out, const char *idx) ...@@ -647,7 +647,7 @@ int git_odb_backend_one_pack(git_odb_backend **backend_out, const char *idx)
if (pack_backend__alloc(&backend, 1) < 0) if (pack_backend__alloc(&backend, 1) < 0)
return -1; return -1;
if (git_packfile_alloc(&packfile, idx) < 0 || if (git_mwindow_get_pack(&packfile, idx) < 0 ||
git_vector_insert(&backend->packs, packfile) < 0) git_vector_insert(&backend->packs, packfile) < 0)
{ {
pack_backend__free((git_odb_backend *)backend); pack_backend__free((git_odb_backend *)backend);
...@@ -664,6 +664,9 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir) ...@@ -664,6 +664,9 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
struct pack_backend *backend = NULL; struct pack_backend *backend = NULL;
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
if (git_mwindow_files_init() < 0)
return -1;
if (pack_backend__alloc(&backend, 8) < 0) if (pack_backend__alloc(&backend, 8) < 0)
return -1; return -1;
......
...@@ -968,10 +968,10 @@ void git_packfile_free(struct git_pack_file *p) ...@@ -968,10 +968,10 @@ void git_packfile_free(struct git_pack_file *p)
cache_free(&p->bases); cache_free(&p->bases);
git_mwindow_free_all(&p->mwf); if (p->mwf.fd >= 0) {
git_mwindow_free_all_locked(&p->mwf);
if (p->mwf.fd >= 0)
p_close(p->mwf.fd); p_close(p->mwf.fd);
}
pack_index_free(p); pack_index_free(p);
...@@ -1063,6 +1063,23 @@ cleanup: ...@@ -1063,6 +1063,23 @@ cleanup:
return -1; return -1;
} }
int git_packfile__name(char **out, const char *path)
{
size_t path_len;
git_buf buf = GIT_BUF_INIT;
path_len = strlen(path);
if (path_len < strlen(".idx"))
return git_odb__error_notfound("invalid packfile path", NULL);
if (git_buf_printf(&buf, "%.*s.pack", (int)(path_len - strlen(".idx")), path) < 0)
return -1;
*out = git_buf_detach(&buf);
return 0;
}
int git_packfile_alloc(struct git_pack_file **pack_out, const char *path) int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
{ {
struct stat st; struct stat st;
......
...@@ -90,6 +90,7 @@ struct git_pack_file { ...@@ -90,6 +90,7 @@ struct git_pack_file {
git_mwindow_file mwf; git_mwindow_file mwf;
git_map index_map; git_map index_map;
git_mutex lock; /* protect updates to mwf and index_map */ git_mutex lock; /* protect updates to mwf and index_map */
git_atomic refcount;
uint32_t num_objects; uint32_t num_objects;
uint32_t num_bad_objects; uint32_t num_bad_objects;
...@@ -123,6 +124,8 @@ typedef struct git_packfile_stream { ...@@ -123,6 +124,8 @@ typedef struct git_packfile_stream {
size_t git_packfile__object_header(unsigned char *hdr, size_t size, git_otype type); size_t git_packfile__object_header(unsigned char *hdr, size_t size, git_otype type);
int git_packfile__name(char **out, const char *path);
int git_packfile_unpack_header( int git_packfile_unpack_header(
size_t *size_p, size_t *size_p,
git_otype *type_p, git_otype *type_p,
......
...@@ -377,26 +377,33 @@ static int error_invalid_local_file_uri(const char *uri) ...@@ -377,26 +377,33 @@ static int error_invalid_local_file_uri(const char *uri)
return -1; return -1;
} }
int git_path_fromurl(git_buf *local_path_out, const char *file_url) static int local_file_url_prefixlen(const char *file_url)
{ {
int offset = 0, len; int len = -1;
assert(local_path_out && file_url); if (git__prefixcmp(file_url, "file://") == 0) {
if (file_url[7] == '/')
len = 8;
else if (git__prefixcmp(file_url + 7, "localhost/") == 0)
len = 17;
}
if (git__prefixcmp(file_url, "file://") != 0) return len;
return error_invalid_local_file_uri(file_url); }
offset += 7; bool git_path_is_local_file_url(const char *file_url)
len = (int)strlen(file_url); {
return (local_file_url_prefixlen(file_url) > 0);
}
if (offset < len && file_url[offset] == '/') int git_path_fromurl(git_buf *local_path_out, const char *file_url)
offset++; {
else if (offset < len && git__prefixcmp(file_url + offset, "localhost/") == 0) int offset;
offset += 10;
else
return error_invalid_local_file_uri(file_url);
if (offset >= len || file_url[offset] == '/') assert(local_path_out && file_url);
if ((offset = local_file_url_prefixlen(file_url)) < 0 ||
file_url[offset] == '\0' || file_url[offset] == '/')
return error_invalid_local_file_uri(file_url); return error_invalid_local_file_uri(file_url);
#ifndef GIT_WIN32 #ifndef GIT_WIN32
...@@ -404,7 +411,6 @@ int git_path_fromurl(git_buf *local_path_out, const char *file_url) ...@@ -404,7 +411,6 @@ int git_path_fromurl(git_buf *local_path_out, const char *file_url)
#endif #endif
git_buf_clear(local_path_out); git_buf_clear(local_path_out);
return git__percent_decode(local_path_out, file_url + offset); return git__percent_decode(local_path_out, file_url + offset);
} }
...@@ -1138,18 +1144,8 @@ int git_path_dirload_with_stat( ...@@ -1138,18 +1144,8 @@ int git_path_dirload_with_stat(
int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path) int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path)
{ {
int error; if (git_path_is_local_file_url(url_or_path))
return git_path_fromurl(local_path_out, url_or_path);
/* If url_or_path begins with file:// treat it as a URL */ else
if (!git__prefixcmp(url_or_path, "file://")) { return git_buf_sets(local_path_out, url_or_path);
if ((error = git_path_fromurl(local_path_out, url_or_path)) < 0) {
return error;
}
} else { /* We assume url_or_path is already a path */
if ((error = git_buf_sets(local_path_out, url_or_path)) < 0) {
return error;
}
}
return 0;
} }
...@@ -439,6 +439,7 @@ extern int git_path_iconv(git_path_iconv_t *ic, char **in, size_t *inlen); ...@@ -439,6 +439,7 @@ extern int git_path_iconv(git_path_iconv_t *ic, char **in, size_t *inlen);
extern bool git_path_does_fs_decompose_unicode(const char *root); extern bool git_path_does_fs_decompose_unicode(const char *root);
/* Used for paths to repositories on the filesystem */ /* Used for paths to repositories on the filesystem */
extern bool git_path_is_local_file_url(const char *file_url);
extern int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path); extern int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path);
#endif #endif
...@@ -146,7 +146,7 @@ GIT_INLINE(void) pool_remove_page( ...@@ -146,7 +146,7 @@ GIT_INLINE(void) pool_remove_page(
void *git_pool_malloc(git_pool *pool, uint32_t items) void *git_pool_malloc(git_pool *pool, uint32_t items)
{ {
git_pool_page *scan = pool->open, *prev; git_pool_page *scan = pool->open, *prev;
uint32_t size = items * pool->item_size; uint32_t size = ((items * pool->item_size) + 7) & ~7;
void *ptr = NULL; void *ptr = NULL;
pool->has_string_alloc = 0; pool->has_string_alloc = 0;
......
...@@ -63,7 +63,7 @@ struct git_reference { ...@@ -63,7 +63,7 @@ struct git_reference {
} target; } target;
git_oid peel; git_oid peel;
char name[0]; char name[GIT_FLEX_ARRAY];
}; };
git_reference *git_reference__set_name(git_reference *ref, const char *name); git_reference *git_reference__set_name(git_reference *ref, const char *name);
......
...@@ -181,39 +181,63 @@ int git_refspec_dst_matches(const git_refspec *refspec, const char *refname) ...@@ -181,39 +181,63 @@ int git_refspec_dst_matches(const git_refspec *refspec, const char *refname)
static int refspec_transform( static int refspec_transform(
git_buf *out, const char *from, const char *to, const char *name) git_buf *out, const char *from, const char *to, const char *name)
{ {
size_t to_len = to ? strlen(to) : 0; const char *from_star, *to_star;
size_t from_len = from ? strlen(from) : 0; const char *name_slash, *from_slash;
size_t name_len = name ? strlen(name) : 0; size_t replacement_len, star_offset;
git_buf_sanitize(out); git_buf_sanitize(out);
git_buf_clear(out);
if (git_buf_set(out, to, to_len) < 0) /*
return -1; * There are two parts to each side of a refspec, the bit
* before the star and the bit after it. The star can be in
* the middle of the pattern, so we need to look at each bit
* individually.
*/
from_star = strchr(from, '*');
to_star = strchr(to, '*');
if (to_len > 0) { assert(from_star && to_star);
/* No '*' at the end of 'to' means that refspec is mapped to one
* specific branch, so no actual transformation is needed. /* star offset, both in 'from' and in 'name' */
*/ star_offset = from_star - from;
if (out->ptr[to_len - 1] != '*')
return 0; /* the first half is copied over */
git_buf_shorten(out, 1); /* remove trailing '*' copied from 'to' */ git_buf_put(out, to, to_star - to);
}
/* then we copy over the replacement, from the star's offset to the next slash in 'name' */
name_slash = strchr(name + star_offset, '/');
if (!name_slash)
name_slash = strrchr(name, '\0');
if (from_len > 0) /* ignore trailing '*' from 'from' */ /* if there is no slash after the star in 'from', we want to copy everything over */
from_len--; from_slash = strchr(from + star_offset, '/');
if (from_len > name_len) if (!from_slash)
from_len = name_len; name_slash = strrchr(name, '\0');
return git_buf_put(out, name + from_len, name_len - from_len); replacement_len = (name_slash - name) - star_offset;
git_buf_put(out, name + star_offset, replacement_len);
return git_buf_puts(out, to_star + 1);
} }
int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name) int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name)
{ {
git_buf_sanitize(out);
if (!spec->pattern)
return git_buf_puts(out, spec->dst);
return refspec_transform(out, spec->src, spec->dst, name); return refspec_transform(out, spec->src, spec->dst, name);
} }
int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name) int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name)
{ {
git_buf_sanitize(out);
if (!spec->pattern)
return git_buf_puts(out, spec->src);
return refspec_transform(out, spec->dst, spec->src, name); return refspec_transform(out, spec->dst, spec->src, name);
} }
......
...@@ -267,9 +267,11 @@ int git_remote_dup(git_remote **dest, git_remote *source) ...@@ -267,9 +267,11 @@ int git_remote_dup(git_remote **dest, git_remote *source)
if (source->pushurl != NULL) { if (source->pushurl != NULL) {
remote->pushurl = git__strdup(source->pushurl); remote->pushurl = git__strdup(source->pushurl);
GITERR_CHECK_ALLOC(remote->pushurl); GITERR_CHECK_ALLOC(remote->pushurl);
} }
remote->transport_cb = source->transport_cb;
remote->transport_cb_payload = source->transport_cb_payload;
remote->repo = source->repo; remote->repo = source->repo;
remote->download_tags = source->download_tags; remote->download_tags = source->download_tags;
remote->check_cert = source->check_cert; remote->check_cert = source->check_cert;
...@@ -659,8 +661,14 @@ int git_remote_connect(git_remote *remote, git_direction direction) ...@@ -659,8 +661,14 @@ int git_remote_connect(git_remote *remote, git_direction direction)
return -1; return -1;
} }
/* A transport could have been supplied in advance with /* If we don't have a transport object yet, and the caller specified a
* git_remote_set_transport */ * custom transport factory, use that */
if (!t && remote->transport_cb &&
(error = remote->transport_cb(&t, remote, remote->transport_cb_payload)) < 0)
return error;
/* If we still don't have a transport, then use the global
* transport registrations which map URI schemes to transport factories */
if (!t && (error = git_transport_new(&t, remote, url)) < 0) if (!t && (error = git_transport_new(&t, remote, url)) < 0)
return error; return error;
...@@ -1262,18 +1270,20 @@ const git_remote_callbacks *git_remote_get_callbacks(git_remote *remote) ...@@ -1262,18 +1270,20 @@ const git_remote_callbacks *git_remote_get_callbacks(git_remote *remote)
return &remote->callbacks; return &remote->callbacks;
} }
int git_remote_set_transport(git_remote *remote, git_transport *transport) int git_remote_set_transport(
git_remote *remote,
git_transport_cb transport_cb,
void *payload)
{ {
assert(remote && transport); assert(remote);
GITERR_CHECK_VERSION(transport, GIT_TRANSPORT_VERSION, "git_transport");
if (remote->transport) { if (remote->transport) {
giterr_set(GITERR_NET, "A transport is already bound to this remote"); giterr_set(GITERR_NET, "A transport is already bound to this remote");
return -1; return -1;
} }
remote->transport = transport; remote->transport_cb = transport_cb;
remote->transport_cb_payload = payload;
return 0; return 0;
} }
......
...@@ -22,6 +22,8 @@ struct git_remote { ...@@ -22,6 +22,8 @@ struct git_remote {
git_vector refs; git_vector refs;
git_vector refspecs; git_vector refspecs;
git_vector active_refspecs; git_vector active_refspecs;
git_transport_cb transport_cb;
void *transport_cb_payload;
git_transport *transport; git_transport *transport;
git_repository *repo; git_repository *repo;
git_remote_callbacks callbacks; git_remote_callbacks callbacks;
......
...@@ -174,7 +174,7 @@ int git_revert( ...@@ -174,7 +174,7 @@ int git_revert(
char commit_oidstr[GIT_OID_HEXSZ + 1]; char commit_oidstr[GIT_OID_HEXSZ + 1];
const char *commit_msg; const char *commit_msg;
git_buf their_label = GIT_BUF_INIT; git_buf their_label = GIT_BUF_INIT;
git_index *index_new = NULL, *index_repo = NULL; git_index *index_new = NULL;
int error; int error;
assert(repo && commit); assert(repo && commit);
...@@ -199,10 +199,9 @@ int git_revert( ...@@ -199,10 +199,9 @@ int git_revert(
(error = git_repository_head(&our_ref, repo)) < 0 || (error = git_repository_head(&our_ref, repo)) < 0 ||
(error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 || (error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 ||
(error = git_revert_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 || (error = git_revert_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
(error = git_merge__indexes(repo, index_new)) < 0 || (error = git_merge__check_result(repo, index_new)) < 0 ||
(error = git_repository_index(&index_repo, repo)) < 0 || (error = git_merge__append_conflicts_to_merge_msg(repo, index_new)) < 0 ||
(error = git_merge__append_conflicts_to_merge_msg(repo, index_repo)) < 0 || (error = git_checkout_index(repo, index_new, &opts.checkout_opts)) < 0)
(error = git_checkout_index(repo, index_repo, &opts.checkout_opts)) < 0)
goto on_error; goto on_error;
goto done; goto done;
...@@ -212,7 +211,6 @@ on_error: ...@@ -212,7 +211,6 @@ on_error:
done: done:
git_index_free(index_new); git_index_free(index_new);
git_index_free(index_repo);
git_commit_free(our_commit); git_commit_free(our_commit);
git_reference_free(our_ref); git_reference_free(our_ref);
git_buf_free(&their_label); git_buf_free(&their_label);
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
#ifndef INCLUDE_strlen_h__ #ifndef INCLUDE_strlen_h__
#define INCLUDE_strlen_h__ #define INCLUDE_strlen_h__
#if defined(__MINGW32__) || defined(__sun) || defined(__APPLE__) || defined(__MidnightBSD__) #if defined(__MINGW32__) || defined(__sun) || defined(__APPLE__) || defined(__MidnightBSD__) ||\
(defined(_MSC_VER) && _MSC_VER < 1500)
# define NO_STRNLEN # define NO_STRNLEN
#endif #endif
......
...@@ -53,12 +53,6 @@ typedef struct { ...@@ -53,12 +53,6 @@ typedef struct {
#endif #endif
#if defined(GIT_WIN32)
#define git_thread_yield() Sleep(0)
#else
#define git_thread_yield() sched_yield()
#endif
/* Pthreads Mutex */ /* Pthreads Mutex */
#define git_mutex pthread_mutex_t #define git_mutex pthread_mutex_t
#define git_mutex_init(a) pthread_mutex_init(a, NULL) #define git_mutex_init(a) pthread_mutex_init(a, NULL)
...@@ -186,7 +180,6 @@ GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend) ...@@ -186,7 +180,6 @@ GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend)
#define git_thread unsigned int #define git_thread unsigned int
#define git_thread_create(thread, attr, start_routine, arg) 0 #define git_thread_create(thread, attr, start_routine, arg) 0
#define git_thread_join(id, status) (void)0 #define git_thread_join(id, status) (void)0
#define git_thread_yield() (void)0
/* Pthreads Mutex */ /* Pthreads Mutex */
#define git_mutex unsigned int #define git_mutex unsigned int
......
...@@ -46,8 +46,16 @@ GIT_INLINE(void) git_trace__write_fmt( ...@@ -46,8 +46,16 @@ GIT_INLINE(void) git_trace__write_fmt(
#else #else
GIT_INLINE(void) git_trace__null(
git_trace_level_t level,
const char *fmt, ...)
{
GIT_UNUSED(level);
GIT_UNUSED(fmt);
}
#define git_trace_level() ((void)0) #define git_trace_level() ((void)0)
#define git_trace(lvl, ...) ((void)0) #define git_trace git_trace__null
#endif #endif
......
...@@ -133,10 +133,11 @@ int git_transport_new(git_transport **out, git_remote *owner, const char *url) ...@@ -133,10 +133,11 @@ int git_transport_new(git_transport **out, git_remote *owner, const char *url)
return -1; return -1;
} }
error = fn(&transport, owner, param); if ((error = fn(&transport, owner, param)) < 0)
if (error < 0)
return error; return error;
GITERR_CHECK_VERSION(transport, GIT_TRANSPORT_VERSION, "git_transport");
*out = transport; *out = transport;
return 0; return 0;
......
...@@ -592,7 +592,9 @@ int git_smart__download_pack( ...@@ -592,7 +592,9 @@ int git_smart__download_pack(
} }
} else if (pkt->type == GIT_PKT_DATA) { } else if (pkt->type == GIT_PKT_DATA) {
git_pkt_data *p = (git_pkt_data *) pkt; git_pkt_data *p = (git_pkt_data *) pkt;
error = writepack->append(writepack, p->data, p->len, stats);
if (p->len)
error = writepack->append(writepack, p->data, p->len, stats);
} else if (pkt->type == GIT_PKT_FLUSH) { } else if (pkt->type == GIT_PKT_FLUSH) {
/* A flush indicates the end of the packfile */ /* A flush indicates the end of the packfile */
git__free(pkt); git__free(pkt);
......
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
* a Linking Exception. For full terms see the included COPYING file. * a Linking Exception. For full terms see the included COPYING file.
*/ */
#ifdef GIT_SSH
#include <libssh2.h>
#endif
#include "git2.h" #include "git2.h"
#include "buffer.h" #include "buffer.h"
#include "netops.h" #include "netops.h"
...@@ -12,8 +16,6 @@ ...@@ -12,8 +16,6 @@
#ifdef GIT_SSH #ifdef GIT_SSH
#include <libssh2.h>
#define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport) #define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport)
static const char prefix_ssh[] = "ssh://"; static const char prefix_ssh[] = "ssh://";
...@@ -35,6 +37,8 @@ typedef struct { ...@@ -35,6 +37,8 @@ typedef struct {
transport_smart *owner; transport_smart *owner;
ssh_stream *current_stream; ssh_stream *current_stream;
git_cred *cred; git_cred *cred;
char *cmd_uploadpack;
char *cmd_receivepack;
} ssh_subtransport; } ssh_subtransport;
static void ssh_error(LIBSSH2_SESSION *session, const char *errmsg) static void ssh_error(LIBSSH2_SESSION *session, const char *errmsg)
...@@ -132,11 +136,22 @@ static int ssh_stream_write( ...@@ -132,11 +136,22 @@ static int ssh_stream_write(
size_t len) size_t len)
{ {
ssh_stream *s = (ssh_stream *)stream; ssh_stream *s = (ssh_stream *)stream;
size_t off = 0;
ssize_t ret = 0;
if (!s->sent_command && send_command(s) < 0) if (!s->sent_command && send_command(s) < 0)
return -1; return -1;
if (libssh2_channel_write(s->channel, buffer, len) < LIBSSH2_ERROR_NONE) { do {
ret = libssh2_channel_write(s->channel, buffer + off, len - off);
if (ret < 0)
break;
off += ret;
} while (off < len);
if (ret < 0) {
ssh_error(s->session, "SSH could not write data"); ssh_error(s->session, "SSH could not write data");
return -1; return -1;
} }
...@@ -491,7 +506,9 @@ static int ssh_uploadpack_ls( ...@@ -491,7 +506,9 @@ static int ssh_uploadpack_ls(
const char *url, const char *url,
git_smart_subtransport_stream **stream) git_smart_subtransport_stream **stream)
{ {
if (_git_ssh_setup_conn(t, url, cmd_uploadpack, stream) < 0) const char *cmd = t->cmd_uploadpack ? t->cmd_uploadpack : cmd_uploadpack;
if (_git_ssh_setup_conn(t, url, cmd, stream) < 0)
return -1; return -1;
return 0; return 0;
...@@ -518,7 +535,9 @@ static int ssh_receivepack_ls( ...@@ -518,7 +535,9 @@ static int ssh_receivepack_ls(
const char *url, const char *url,
git_smart_subtransport_stream **stream) git_smart_subtransport_stream **stream)
{ {
if (_git_ssh_setup_conn(t, url, cmd_receivepack, stream) < 0) const char *cmd = t->cmd_receivepack ? t->cmd_receivepack : cmd_receivepack;
if (_git_ssh_setup_conn(t, url, cmd, stream) < 0)
return -1; return -1;
return 0; return 0;
...@@ -583,6 +602,8 @@ static void _ssh_free(git_smart_subtransport *subtransport) ...@@ -583,6 +602,8 @@ static void _ssh_free(git_smart_subtransport *subtransport)
assert(!t->current_stream); assert(!t->current_stream);
git__free(t->cmd_uploadpack);
git__free(t->cmd_receivepack);
git__free(t); git__free(t);
} }
#endif #endif
...@@ -615,3 +636,46 @@ int git_smart_subtransport_ssh( ...@@ -615,3 +636,46 @@ int git_smart_subtransport_ssh(
return -1; return -1;
#endif #endif
} }
int git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *payload)
{
#ifdef GIT_SSH
git_strarray *paths = (git_strarray *) payload;
git_transport *transport;
transport_smart *smart;
ssh_subtransport *t;
int error;
git_smart_subtransport_definition ssh_definition = {
git_smart_subtransport_ssh,
0, /* no RPC */
};
if (paths->count != 2) {
giterr_set(GITERR_SSH, "invalid ssh paths, must be two strings");
return GIT_EINVALIDSPEC;
}
if ((error = git_transport_smart(&transport, owner, &ssh_definition)) < 0)
return error;
smart = (transport_smart *) transport;
t = (ssh_subtransport *) smart->wrapped;
t->cmd_uploadpack = git__strdup(paths->strings[0]);
GITERR_CHECK_ALLOC(t->cmd_uploadpack);
t->cmd_receivepack = git__strdup(paths->strings[1]);
GITERR_CHECK_ALLOC(t->cmd_receivepack);
*out = transport;
return 0;
#else
GIT_UNUSED(owner);
GIT_UNUSED(payload);
assert(out);
*out = NULL;
giterr_set(GITERR_INVALID, "Cannot create SSH transport. Library was built without SSH support");
return -1;
#endif
}
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#define DEFAULT_TREE_SIZE 16 #define DEFAULT_TREE_SIZE 16
#define MAX_FILEMODE_BYTES 6 #define MAX_FILEMODE_BYTES 6
GIT__USE_STRMAP;
static bool valid_filemode(const int filemode) static bool valid_filemode(const int filemode)
{ {
return (filemode == GIT_FILEMODE_TREE return (filemode == GIT_FILEMODE_TREE
...@@ -365,7 +367,8 @@ size_t git_tree_entrycount(const git_tree *tree) ...@@ -365,7 +367,8 @@ size_t git_tree_entrycount(const git_tree *tree)
unsigned int git_treebuilder_entrycount(git_treebuilder *bld) unsigned int git_treebuilder_entrycount(git_treebuilder *bld)
{ {
assert(bld); assert(bld);
return (unsigned int)bld->entrycount;
return git_strmap_num_entries(bld->map);
} }
static int tree_error(const char *str, const char *path) static int tree_error(const char *str, const char *path)
...@@ -450,6 +453,7 @@ static int append_entry( ...@@ -450,6 +453,7 @@ static int append_entry(
git_filemode_t filemode) git_filemode_t filemode)
{ {
git_tree_entry *entry; git_tree_entry *entry;
int error = 0;
if (!valid_entry_name(filename)) if (!valid_entry_name(filename))
return tree_error("Failed to insert entry. Invalid name for a tree entry", filename); return tree_error("Failed to insert entry. Invalid name for a tree entry", filename);
...@@ -460,12 +464,13 @@ static int append_entry( ...@@ -460,12 +464,13 @@ static int append_entry(
git_oid_cpy(&entry->oid, id); git_oid_cpy(&entry->oid, id);
entry->attr = (uint16_t)filemode; entry->attr = (uint16_t)filemode;
if (git_vector_insert_sorted(&bld->entries, entry, NULL) < 0) { git_strmap_insert(bld->map, entry->filename, entry, error);
git__free(entry); if (error < 0) {
git_tree_entry_free(entry);
giterr_set(GITERR_TREE, "failed to append entry %s to the tree builder", filename);
return -1; return -1;
} }
bld->entrycount++;
return 0; return 0;
} }
...@@ -610,18 +615,17 @@ int git_tree__write_index( ...@@ -610,18 +615,17 @@ int git_tree__write_index(
int git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source) int git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source)
{ {
git_treebuilder *bld; git_treebuilder *bld;
size_t i, source_entries = DEFAULT_TREE_SIZE; size_t i;
assert(builder_p); assert(builder_p);
bld = git__calloc(1, sizeof(git_treebuilder)); bld = git__calloc(1, sizeof(git_treebuilder));
GITERR_CHECK_ALLOC(bld); GITERR_CHECK_ALLOC(bld);
if (source != NULL) if (git_strmap_alloc(&bld->map) < 0) {
source_entries = source->entries.length; git__free(bld);
return -1;
if (git_vector_init(&bld->entries, source_entries, entry_sort_cmp) < 0) }
goto on_error;
if (source != NULL) { if (source != NULL) {
git_tree_entry *entry_src; git_tree_entry *entry_src;
...@@ -651,7 +655,8 @@ int git_treebuilder_insert( ...@@ -651,7 +655,8 @@ int git_treebuilder_insert(
git_filemode_t filemode) git_filemode_t filemode)
{ {
git_tree_entry *entry; git_tree_entry *entry;
size_t pos; int error;
git_strmap_iter pos;
assert(bld && id && filename); assert(bld && id && filename);
...@@ -661,22 +666,20 @@ int git_treebuilder_insert( ...@@ -661,22 +666,20 @@ int git_treebuilder_insert(
if (!valid_entry_name(filename)) if (!valid_entry_name(filename))
return tree_error("Failed to insert entry. Invalid name for a tree entry", filename); return tree_error("Failed to insert entry. Invalid name for a tree entry", filename);
if (!tree_key_search(&pos, &bld->entries, filename, strlen(filename))) { pos = git_strmap_lookup_index(bld->map, filename);
entry = git_vector_get(&bld->entries, pos); if (git_strmap_valid_index(bld->map, pos)) {
if (entry->removed) { entry = git_strmap_value_at(bld->map, pos);
entry->removed = 0;
bld->entrycount++;
}
} else { } else {
entry = alloc_entry(filename); entry = alloc_entry(filename);
GITERR_CHECK_ALLOC(entry); GITERR_CHECK_ALLOC(entry);
if (git_vector_insert_sorted(&bld->entries, entry, NULL) < 0) { git_strmap_insert(bld->map, entry->filename, entry, error);
git__free(entry);
if (error < 0) {
git_tree_entry_free(entry);
giterr_set(GITERR_TREE, "failed to insert %s", filename);
return -1; return -1;
} }
bld->entrycount++;
} }
git_oid_cpy(&entry->oid, id); git_oid_cpy(&entry->oid, id);
...@@ -690,17 +693,14 @@ int git_treebuilder_insert( ...@@ -690,17 +693,14 @@ int git_treebuilder_insert(
static git_tree_entry *treebuilder_get(git_treebuilder *bld, const char *filename) static git_tree_entry *treebuilder_get(git_treebuilder *bld, const char *filename)
{ {
size_t idx; git_tree_entry *entry = NULL;
git_tree_entry *entry; git_strmap_iter pos;
assert(bld && filename); assert(bld && filename);
if (tree_key_search(&idx, &bld->entries, filename, strlen(filename)) < 0) pos = git_strmap_lookup_index(bld->map, filename);
return NULL; if (git_strmap_valid_index(bld->map, pos))
entry = git_strmap_value_at(bld->map, pos);
entry = git_vector_get(&bld->entries, idx);
if (entry->removed)
return NULL;
return entry; return entry;
} }
...@@ -712,35 +712,44 @@ const git_tree_entry *git_treebuilder_get(git_treebuilder *bld, const char *file ...@@ -712,35 +712,44 @@ const git_tree_entry *git_treebuilder_get(git_treebuilder *bld, const char *file
int git_treebuilder_remove(git_treebuilder *bld, const char *filename) int git_treebuilder_remove(git_treebuilder *bld, const char *filename)
{ {
git_tree_entry *remove_ptr = treebuilder_get(bld, filename); git_tree_entry *entry = treebuilder_get(bld, filename);
if (remove_ptr == NULL || remove_ptr->removed) if (entry == NULL)
return tree_error("Failed to remove entry. File isn't in the tree", filename); return tree_error("Failed to remove entry. File isn't in the tree", filename);
remove_ptr->removed = 1; git_strmap_delete(bld->map, filename);
bld->entrycount--; git_tree_entry_free(entry);
return 0; return 0;
} }
int git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld) int git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld)
{ {
int error = 0; int error = 0;
size_t i; size_t i, entrycount;
git_buf tree = GIT_BUF_INIT; git_buf tree = GIT_BUF_INIT;
git_odb *odb; git_odb *odb;
git_tree_entry *entry;
git_vector entries;
assert(bld); assert(bld);
git_vector_sort(&bld->entries); entrycount = git_strmap_num_entries(bld->map);
if (git_vector_init(&entries, entrycount, entry_sort_cmp) < 0)
return -1;
/* Grow the buffer beforehand to an estimated size */ git_strmap_foreach_value(bld->map, entry, {
error = git_buf_grow(&tree, bld->entries.length * 72); if (git_vector_insert(&entries, entry) < 0)
return -1;
});
for (i = 0; i < bld->entries.length && !error; ++i) { git_vector_sort(&entries);
git_tree_entry *entry = git_vector_get(&bld->entries, i);
/* Grow the buffer beforehand to an estimated size */
error = git_buf_grow(&tree, entrycount * 72);
if (entry->removed) for (i = 0; i < entries.length && !error; ++i) {
continue; git_tree_entry *entry = git_vector_get(&entries, i);
git_buf_printf(&tree, "%o ", entry->attr); git_buf_printf(&tree, "%o ", entry->attr);
git_buf_put(&tree, entry->filename, entry->filename_len + 1); git_buf_put(&tree, entry->filename, entry->filename_len + 1);
...@@ -750,6 +759,8 @@ int git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *b ...@@ -750,6 +759,8 @@ int git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *b
error = -1; error = -1;
} }
git_vector_free(&entries);
if (!error && if (!error &&
!(error = git_repository_odb__weakptr(&odb, repo))) !(error = git_repository_odb__weakptr(&odb, repo)))
error = git_odb_write(oid, odb, tree.ptr, tree.size, GIT_OBJ_TREE); error = git_odb_write(oid, odb, tree.ptr, tree.size, GIT_OBJ_TREE);
...@@ -763,31 +774,27 @@ void git_treebuilder_filter( ...@@ -763,31 +774,27 @@ void git_treebuilder_filter(
git_treebuilder_filter_cb filter, git_treebuilder_filter_cb filter,
void *payload) void *payload)
{ {
size_t i; const char *filename;
git_tree_entry *entry; git_tree_entry *entry;
assert(bld && filter); assert(bld && filter);
git_vector_foreach(&bld->entries, i, entry) { git_strmap_foreach(bld->map, filename, entry, {
if (!entry->removed && filter(entry, payload)) { if (filter(entry, payload)) {
entry->removed = 1; git_strmap_delete(bld->map, filename);
bld->entrycount--; git_tree_entry_free(entry);
} }
} });
} }
void git_treebuilder_clear(git_treebuilder *bld) void git_treebuilder_clear(git_treebuilder *bld)
{ {
size_t i;
git_tree_entry *e; git_tree_entry *e;
assert(bld); assert(bld);
git_vector_foreach(&bld->entries, i, e) git_strmap_foreach_value(bld->map, e, git_tree_entry_free(e));
git_tree_entry_free(e); git_strmap_clear(bld->map);
git_vector_clear(&bld->entries);
bld->entrycount = 0;
} }
void git_treebuilder_free(git_treebuilder *bld) void git_treebuilder_free(git_treebuilder *bld)
...@@ -796,7 +803,7 @@ void git_treebuilder_free(git_treebuilder *bld) ...@@ -796,7 +803,7 @@ void git_treebuilder_free(git_treebuilder *bld)
return; return;
git_treebuilder_clear(bld); git_treebuilder_clear(bld);
git_vector_free(&bld->entries); git_strmap_free(bld->map);
git__free(bld); git__free(bld);
} }
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
#include "repository.h" #include "repository.h"
#include "odb.h" #include "odb.h"
#include "vector.h" #include "vector.h"
#include "strmap.h"
struct git_tree_entry { struct git_tree_entry {
uint16_t removed;
uint16_t attr; uint16_t attr;
git_oid oid; git_oid oid;
size_t filename_len; size_t filename_len;
...@@ -26,8 +26,7 @@ struct git_tree { ...@@ -26,8 +26,7 @@ struct git_tree {
}; };
struct git_treebuilder { struct git_treebuilder {
git_vector entries; git_strmap *map;
size_t entrycount; /* vector may contain "removed" entries */
}; };
GIT_INLINE(bool) git_tree_entry__is_tree(const struct git_tree_entry *e) GIT_INLINE(bool) git_tree_entry__is_tree(const struct git_tree_entry *e)
......
...@@ -613,7 +613,8 @@ void git__qsort_r( ...@@ -613,7 +613,8 @@ void git__qsort_r(
defined(__OpenBSD__) || defined(__NetBSD__) || \ defined(__OpenBSD__) || defined(__NetBSD__) || \
defined(__gnu_hurd__) || defined(__ANDROID_API__) || \ defined(__gnu_hurd__) || defined(__ANDROID_API__) || \
defined(__sun) || defined(__CYGWIN__) || \ defined(__sun) || defined(__CYGWIN__) || \
(__GLIBC__ == 2 && __GLIBC_MINOR__ < 8) (__GLIBC__ == 2 && __GLIBC_MINOR__ < 8) || \
(defined(_MSC_VER) && _MSC_VER < 1500)
git__insertsort_r(els, nel, elsize, NULL, cmp, payload); git__insertsort_r(els, nel, elsize, NULL, cmp, payload);
#elif defined(GIT_WIN32) #elif defined(GIT_WIN32)
git__qsort_r_glue glue = { cmp, payload }; git__qsort_r_glue glue = { cmp, payload };
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
# define R_OK 4 /* read mode check */ # define R_OK 4 /* read mode check */
# define lseek _lseeki64 # define lseek _lseeki64
# define stat _stat64 # define stat __stat64
# define fstat _fstat64 # define fstat _fstat64
/* stat: file mode type testing macros */ /* stat: file mode type testing macros */
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
typedef SSIZE_T ssize_t; typedef SSIZE_T ssize_t;
/* define snprintf using variadic macro support if available */ /* define snprintf using variadic macro support if available */
#if _MSC_VER >= 1400 #if _MSC_VER >= 1500
# define snprintf(BUF, SZ, FMT, ...) _snprintf_s(BUF, SZ, _TRUNCATE, FMT, __VA_ARGS__) # define snprintf(BUF, SZ, FMT, ...) _snprintf_s(BUF, SZ, _TRUNCATE, FMT, __VA_ARGS__)
#else #else
# define snprintf _snprintf # define snprintf _snprintf
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
# define EAFNOSUPPORT (INT_MAX-1) # define EAFNOSUPPORT (INT_MAX-1)
#endif #endif
#ifdef _MSC_VER #if defined(_MSC_VER) && _MSC_VER >= 1500
# define p_ftruncate(fd, sz) _chsize_s(fd, sz) # define p_ftruncate(fd, sz) _chsize_s(fd, sz)
#else /* MinGW */ #else /* MinGW */
# define p_ftruncate(fd, sz) _chsize(fd, sz) # define p_ftruncate(fd, sz) _chsize(fd, sz)
......
...@@ -19,6 +19,10 @@ ...@@ -19,6 +19,10 @@
# define FILE_NAME_NORMALIZED 0 # define FILE_NAME_NORMALIZED 0
#endif #endif
#ifndef IO_REPARSE_TAG_SYMLINK
#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
#endif
/* Options which we always provide to _wopen. /* Options which we always provide to _wopen.
* *
* _O_BINARY - Raw access; no translation of CR or LF characters * _O_BINARY - Raw access; no translation of CR or LF characters
...@@ -543,7 +547,7 @@ char *p_realpath(const char *orig_path, char *buffer) ...@@ -543,7 +547,7 @@ char *p_realpath(const char *orig_path, char *buffer)
int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr) int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
{ {
#ifdef _MSC_VER #if defined(_MSC_VER) && _MSC_VER >= 1500
int len; int len;
if (count == 0 || if (count == 0 ||
...@@ -570,7 +574,7 @@ int p_snprintf(char *buffer, size_t count, const char *format, ...) ...@@ -570,7 +574,7 @@ int p_snprintf(char *buffer, size_t count, const char *format, ...)
int p_mkstemp(char *tmp_path) int p_mkstemp(char *tmp_path)
{ {
#if defined(_MSC_VER) #if defined(_MSC_VER) && _MSC_VER >= 1500
if (_mktemp_s(tmp_path, strlen(tmp_path) + 1) != 0) if (_mktemp_s(tmp_path, strlen(tmp_path) + 1) != 0)
return -1; return -1;
#else #else
...@@ -591,6 +595,31 @@ int p_access(const char* path, mode_t mode) ...@@ -591,6 +595,31 @@ int p_access(const char* path, mode_t mode)
return _waccess(buf, mode); return _waccess(buf, mode);
} }
static int ensure_writable(wchar_t *fpath)
{
DWORD attrs;
attrs = GetFileAttributesW(fpath);
if (attrs == INVALID_FILE_ATTRIBUTES) {
if (GetLastError() == ERROR_FILE_NOT_FOUND)
return 0;
giterr_set(GITERR_OS, "failed to get attributes");
return -1;
}
if (!(attrs & FILE_ATTRIBUTE_READONLY))
return 0;
attrs &= ~FILE_ATTRIBUTE_READONLY;
if (!SetFileAttributesW(fpath, attrs)) {
giterr_set(GITERR_OS, "failed to set attributes");
return -1;
}
return 0;
}
int p_rename(const char *from, const char *to) int p_rename(const char *from, const char *to)
{ {
git_win32_path wfrom; git_win32_path wfrom;
...@@ -602,12 +631,13 @@ int p_rename(const char *from, const char *to) ...@@ -602,12 +631,13 @@ int p_rename(const char *from, const char *to)
if (utf8_to_16_with_errno(wfrom, from) < 0 || if (utf8_to_16_with_errno(wfrom, from) < 0 ||
utf8_to_16_with_errno(wto, to) < 0) utf8_to_16_with_errno(wto, to) < 0)
return -1; return -1;
/* wait up to 50ms if file is locked by another thread or process */ /* wait up to 50ms if file is locked by another thread or process */
rename_tries = 0; rename_tries = 0;
rename_succeeded = 0; rename_succeeded = 0;
while (rename_tries < 10) { while (rename_tries < 10) {
if (MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) != 0) { if (ensure_writable(wto) == 0 &&
MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) != 0) {
rename_succeeded = 1; rename_succeeded = 1;
break; break;
} }
......
...@@ -48,7 +48,7 @@ void check_blame_hunk_index(git_repository *repo, git_blame *blame, int idx, ...@@ -48,7 +48,7 @@ void check_blame_hunk_index(git_repository *repo, git_blame *blame, int idx,
actual, expected); actual, expected);
} }
cl_assert_equal_s(actual, expected); cl_assert_equal_s(actual, expected);
cl_assert_equal_i(git_oid_cmp(&hunk->final_commit_id, &hunk->orig_commit_id), 0); cl_assert_equal_oid(&hunk->final_commit_id, &hunk->orig_commit_id);
if (strcmp(hunk->orig_path, orig_path)) { if (strcmp(hunk->orig_path, orig_path)) {
......
...@@ -37,12 +37,12 @@ static void execute_test(void) ...@@ -37,12 +37,12 @@ static void execute_test(void)
/* Verify that the lenna.jpg file was checked out correctly */ /* Verify that the lenna.jpg file was checked out correctly */
cl_git_pass(git_oid_fromstr(&check, "8ab005d890fe53f65eda14b23672f60d9f4ec5a1")); cl_git_pass(git_oid_fromstr(&check, "8ab005d890fe53f65eda14b23672f60d9f4ec5a1"));
cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/lenna.jpg", GIT_OBJ_BLOB)); cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/lenna.jpg", GIT_OBJ_BLOB));
cl_assert(git_oid_equal(&oid, &check)); cl_assert_equal_oid(&oid, &check);
/* Verify that the text file was checked out correctly */ /* Verify that the text file was checked out correctly */
cl_git_pass(git_oid_fromstr(&check, "965b223880dd4249e2c66a0cc0b4cffe1dc40f5a")); cl_git_pass(git_oid_fromstr(&check, "965b223880dd4249e2c66a0cc0b4cffe1dc40f5a"));
cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/utf16_withbom_noeol_crlf.txt", GIT_OBJ_BLOB)); cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/utf16_withbom_noeol_crlf.txt", GIT_OBJ_BLOB));
cl_assert(git_oid_equal(&oid, &check)); cl_assert_equal_oid(&oid, &check);
} }
void test_checkout_binaryunicode__noautocrlf(void) void test_checkout_binaryunicode__noautocrlf(void)
......
...@@ -156,7 +156,7 @@ static void ensure_workdir_oid(const char *path, const char *oid_str) ...@@ -156,7 +156,7 @@ static void ensure_workdir_oid(const char *path, const char *oid_str)
cl_git_pass(git_oid_fromstr(&expected, oid_str)); cl_git_pass(git_oid_fromstr(&expected, oid_str));
cl_git_pass(git_repository_hashfile(&actual, g_repo, path, GIT_OBJ_BLOB, NULL)); cl_git_pass(git_repository_hashfile(&actual, g_repo, path, GIT_OBJ_BLOB, NULL));
cl_assert(git_oid_cmp(&expected, &actual) == 0); cl_assert_equal_oid(&expected, &actual);
} }
static void ensure_workdir_mode(const char *path, int mode) static void ensure_workdir_mode(const char *path, int mode)
...@@ -169,7 +169,7 @@ static void ensure_workdir_mode(const char *path, int mode) ...@@ -169,7 +169,7 @@ static void ensure_workdir_mode(const char *path, int mode)
git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path)); git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path));
cl_git_pass(p_stat(git_buf_cstr(&fullpath), &st)); cl_git_pass(p_stat(git_buf_cstr(&fullpath), &st));
cl_assert_equal_i(mode, st.st_mode); cl_assert_equal_i((mode & S_IRWXU), (st.st_mode & S_IRWXU));
git_buf_free(&fullpath); git_buf_free(&fullpath);
#endif #endif
......
...@@ -79,10 +79,7 @@ void test_checkout_crlf__more_lf_autocrlf_true(void) ...@@ -79,10 +79,7 @@ void test_checkout_crlf__more_lf_autocrlf_true(void)
git_checkout_head(g_repo, &opts); git_checkout_head(g_repo, &opts);
if (GIT_EOL_NATIVE == GIT_EOL_LF) check_file_contents("./crlf/more-lf", MORE_LF_TEXT_RAW);
check_file_contents("./crlf/more-lf", MORE_LF_TEXT_RAW);
else
check_file_contents("./crlf/more-lf", MORE_LF_TEXT_AS_CRLF);
} }
void test_checkout_crlf__more_crlf_autocrlf_true(void) void test_checkout_crlf__more_crlf_autocrlf_true(void)
...@@ -94,10 +91,7 @@ void test_checkout_crlf__more_crlf_autocrlf_true(void) ...@@ -94,10 +91,7 @@ void test_checkout_crlf__more_crlf_autocrlf_true(void)
git_checkout_head(g_repo, &opts); git_checkout_head(g_repo, &opts);
if (GIT_EOL_NATIVE == GIT_EOL_LF) check_file_contents("./crlf/more-crlf", MORE_CRLF_TEXT_RAW);
check_file_contents("./crlf/more-crlf", MORE_CRLF_TEXT_RAW);
else
check_file_contents("./crlf/more-crlf", MORE_CRLF_TEXT_AS_CRLF);
} }
void test_checkout_crlf__all_crlf_autocrlf_true(void) void test_checkout_crlf__all_crlf_autocrlf_true(void)
...@@ -285,8 +279,13 @@ void test_checkout_crlf__autocrlf_false_text_auto_attr(void) ...@@ -285,8 +279,13 @@ void test_checkout_crlf__autocrlf_false_text_auto_attr(void)
git_checkout_head(g_repo, &opts); git_checkout_head(g_repo, &opts);
check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW); if (GIT_EOL_NATIVE == GIT_EOL_CRLF) {
check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW); check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF);
check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_AS_CRLF);
} else {
check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
}
} }
void test_checkout_crlf__autocrlf_true_text_auto_attr(void) void test_checkout_crlf__autocrlf_true_text_auto_attr(void)
......
...@@ -471,7 +471,7 @@ void clar__assert_equal_file( ...@@ -471,7 +471,7 @@ void clar__assert_equal_file(
buf, sizeof(buf), "file content mismatch at byte %d", buf, sizeof(buf), "file content mismatch at byte %d",
(int)(total_bytes + pos)); (int)(total_bytes + pos));
p_close(fd); p_close(fd);
clar__fail(file, line, buf, path, 1); clar__fail(file, line, path, buf, 1);
} }
expected_data += bytes; expected_data += bytes;
......
...@@ -78,6 +78,24 @@ void clar__assert_equal_file( ...@@ -78,6 +78,24 @@ void clar__assert_equal_file(
const char *file, const char *file,
int line); int line);
GIT_INLINE(void) clar__assert_equal_oid(
const char *file, int line, const char *desc,
const git_oid *one, const git_oid *two)
{
if (git_oid_cmp(one, two)) {
char err[] = "\"........................................\" != \"........................................\"";
git_oid_fmt(&err[1], one);
git_oid_fmt(&err[47], two);
clar__fail(file, line, desc, err, 1);
}
}
#define cl_assert_equal_oid(one, two) \
clar__assert_equal_oid(__FILE__, __LINE__, \
"OID mismatch: " #one " != " #two, (one), (two))
/* /*
* Some utility macros for building long strings * Some utility macros for building long strings
*/ */
......
...@@ -7,55 +7,78 @@ ...@@ -7,55 +7,78 @@
#include "posix.h" #include "posix.h"
#include "fileops.h" #include "fileops.h"
static int file_url(git_buf *buf, const char *host, const char *path)
{
if (path[0] == '/')
path++;
git_buf_clear(buf);
return git_buf_printf(buf, "file://%s/%s", host, path);
}
void test_clone_local__should_clone_local(void) void test_clone_local__should_clone_local(void)
{ {
git_buf buf = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT;
const char *path;
/* we use a fixture path because it needs to exist for us to want to clone */ /* we use a fixture path because it needs to exist for us to want to clone */
const char *path = cl_fixture("testrepo.git");
cl_git_pass(git_buf_printf(&buf, "file://%s", cl_fixture("testrepo.git")));
cl_assert_equal_i(false, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO)); cl_git_pass(file_url(&buf, "", path));
cl_assert_equal_i(true, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL)); cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
cl_assert_equal_i(true, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS)); cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
cl_assert_equal_i(false, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL)); cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
git_buf_free(&buf); cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
cl_git_pass(file_url(&buf, "localhost", path));
cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
cl_git_pass(file_url(&buf, "other-host.mycompany.com", path));
cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
/* Ensure that file:/// urls are percent decoded: .git == %2e%67%69%74 */
cl_git_pass(file_url(&buf, "", path));
git_buf_shorten(&buf, 4);
cl_git_pass(git_buf_puts(&buf, "%2e%67%69%74"));
cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_NO_LOCAL));
cl_assert_equal_i(1, git_clone__should_clone_local(path, GIT_CLONE_LOCAL_AUTO));
cl_assert_equal_i(1, git_clone__should_clone_local(path, GIT_CLONE_LOCAL));
cl_assert_equal_i(1, git_clone__should_clone_local(path, GIT_CLONE_LOCAL_NO_LINKS));
cl_assert_equal_i(0, git_clone__should_clone_local(path, GIT_CLONE_NO_LOCAL));
path = cl_fixture("testrepo.git"); git_buf_free(&buf);
cl_assert_equal_i(true, git_clone__should_clone_local(path, GIT_CLONE_LOCAL_AUTO));
cl_assert_equal_i(true, git_clone__should_clone_local(path, GIT_CLONE_LOCAL));
cl_assert_equal_i(true, git_clone__should_clone_local(path, GIT_CLONE_LOCAL_NO_LINKS));
cl_assert_equal_i(false, git_clone__should_clone_local(path, GIT_CLONE_NO_LOCAL));
} }
void test_clone_local__hardlinks(void) void test_clone_local__hardlinks(void)
{ {
git_repository *repo; git_repository *repo;
git_remote *remote; git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
git_signature *sig;
git_buf buf = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT;
struct stat st; struct stat st;
/* /*
* In this first clone, we just copy over, since the temp dir * In this first clone, we just copy over, since the temp dir
* will often be in a different filesystem, so we cannot * will often be in a different filesystem, so we cannot
* link. It also allows us to control the number of links * link. It also allows us to control the number of links
*/ */
cl_git_pass(git_repository_init(&repo, "./clone.git", true)); opts.bare = true;
cl_git_pass(git_remote_create(&remote, repo, "origin", cl_fixture("testrepo.git"))); opts.local = GIT_CLONE_LOCAL_NO_LINKS;
cl_git_pass(git_signature_now(&sig, "foo", "bar")); cl_git_pass(git_clone(&repo, cl_fixture("testrepo.git"), "./clone.git", &opts));
cl_git_pass(git_clone_local_into(repo, remote, NULL, NULL, false, sig));
git_remote_free(remote);
git_repository_free(repo); git_repository_free(repo);
/* This second clone is in the same filesystem, so we can hardlink */ /* This second clone is in the same filesystem, so we can hardlink */
cl_git_pass(git_repository_init(&repo, "./clone2.git", true)); opts.local = GIT_CLONE_LOCAL;
cl_git_pass(git_buf_puts(&buf, cl_git_path_url("clone.git"))); cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone2.git", &opts));
cl_git_pass(git_remote_create(&remote, repo, "origin", buf.ptr));
cl_git_pass(git_clone_local_into(repo, remote, NULL, NULL, true, sig));
#ifndef GIT_WIN32 #ifndef GIT_WIN32
git_buf_clear(&buf); git_buf_clear(&buf);
...@@ -65,14 +88,11 @@ void test_clone_local__hardlinks(void) ...@@ -65,14 +88,11 @@ void test_clone_local__hardlinks(void)
cl_assert_equal_i(2, st.st_nlink); cl_assert_equal_i(2, st.st_nlink);
#endif #endif
git_remote_free(remote);
git_repository_free(repo); git_repository_free(repo);
git_buf_clear(&buf); git_buf_clear(&buf);
cl_git_pass(git_repository_init(&repo, "./clone3.git", true)); opts.local = GIT_CLONE_LOCAL_NO_LINKS;
cl_git_pass(git_buf_puts(&buf, cl_git_path_url("clone.git"))); cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone3.git", &opts));
cl_git_pass(git_remote_create(&remote, repo, "origin", buf.ptr));
cl_git_pass(git_clone_local_into(repo, remote, NULL, NULL, false, sig));
git_buf_clear(&buf); git_buf_clear(&buf);
cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125")); cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
...@@ -80,7 +100,6 @@ void test_clone_local__hardlinks(void) ...@@ -80,7 +100,6 @@ void test_clone_local__hardlinks(void)
cl_git_pass(p_stat(buf.ptr, &st)); cl_git_pass(p_stat(buf.ptr, &st));
cl_assert_equal_i(1, st.st_nlink); cl_assert_equal_i(1, st.st_nlink);
git_remote_free(remote);
git_repository_free(repo); git_repository_free(repo);
/* this one should automatically use links */ /* this one should automatically use links */
...@@ -95,7 +114,6 @@ void test_clone_local__hardlinks(void) ...@@ -95,7 +114,6 @@ void test_clone_local__hardlinks(void)
#endif #endif
git_buf_free(&buf); git_buf_free(&buf);
git_signature_free(sig);
git_repository_free(repo); git_repository_free(repo);
cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES)); cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
......
...@@ -110,12 +110,25 @@ void test_clone_nonetwork__fail_with_already_existing_but_non_empty_directory(vo ...@@ -110,12 +110,25 @@ void test_clone_nonetwork__fail_with_already_existing_but_non_empty_directory(vo
cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
} }
int custom_origin_name_remote_create(
git_remote **out,
git_repository *repo,
const char *name,
const char *url,
void *payload)
{
GIT_UNUSED(name);
GIT_UNUSED(payload);
return git_remote_create(out, repo, "my_origin", url);
}
void test_clone_nonetwork__custom_origin_name(void) void test_clone_nonetwork__custom_origin_name(void)
{ {
g_options.remote_name = "my_origin"; g_options.remote_cb = custom_origin_name_remote_create;
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
cl_git_pass(git_remote_load(&g_remote, g_repo, "my_origin")); cl_git_pass(git_remote_load(&g_remote, g_repo, "my_origin"));
} }
void test_clone_nonetwork__defaults(void) void test_clone_nonetwork__defaults(void)
...@@ -228,7 +241,7 @@ void test_clone_nonetwork__can_detached_head(void) ...@@ -228,7 +241,7 @@ void test_clone_nonetwork__can_detached_head(void)
cl_assert(git_repository_head_detached(cloned)); cl_assert(git_repository_head_detached(cloned));
cl_git_pass(git_repository_head(&cloned_head, cloned)); cl_git_pass(git_repository_head(&cloned_head, cloned));
cl_assert(!git_oid_cmp(git_object_id(obj), git_reference_target(cloned_head))); cl_assert_equal_oid(git_object_id(obj), git_reference_target(cloned_head));
cl_git_pass(git_reflog_read(&log, cloned, "HEAD")); cl_git_pass(git_reflog_read(&log, cloned, "HEAD"));
entry = git_reflog_entry_byindex(log, 0); entry = git_reflog_entry_byindex(log, 0);
...@@ -266,23 +279,6 @@ void test_clone_nonetwork__clone_updates_reflog_properly(void) ...@@ -266,23 +279,6 @@ void test_clone_nonetwork__clone_updates_reflog_properly(void)
assert_correct_reflog("refs/heads/master"); assert_correct_reflog("refs/heads/master");
} }
void test_clone_nonetwork__clone_into_updates_reflog_properly(void)
{
git_remote *remote;
git_signature *sig;
cl_git_pass(git_signature_now(&sig, "Me", "foo@example.com"));
cl_git_pass(git_repository_init(&g_repo, "./foo", false));
cl_git_pass(git_remote_create(&remote, g_repo, "origin", cl_git_fixture_url("testrepo.git")));
cl_git_pass(git_clone_into(g_repo, remote, NULL, NULL, sig));
assert_correct_reflog("HEAD");
assert_correct_reflog("refs/heads/master");
git_remote_free(remote);
git_signature_free(sig);
}
static void cleanup_repository(void *path) static void cleanup_repository(void *path)
{ {
if (g_repo) { if (g_repo) {
......
#include "clar_libgit2.h"
#include "git2/clone.h"
#include "git2/transport.h"
#include "fileops.h"
static int custom_transport(
git_transport **out,
git_remote *owner,
void *payload)
{
*((int*)payload) = 1;
return git_transport_local(out, owner, payload);
}
static int custom_transport_remote_create(
git_remote **out,
git_repository *repo,
const char *name,
const char *url,
void *payload)
{
int error;
if ((error = git_remote_create(out, repo, name, url)) < 0)
return error;
if ((error = git_remote_set_transport(*out, custom_transport, payload)) < 0)
return error;
return 0;
}
void test_clone_transport__custom_transport(void)
{
git_repository *repo;
git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
int custom_transport_used = 0;
clone_opts.remote_cb = custom_transport_remote_create;
clone_opts.remote_cb_payload = &custom_transport_used;
cl_git_pass(git_clone(&repo, cl_fixture("testrepo.git"), "./custom_transport.git", &clone_opts));
git_repository_free(repo);
cl_git_pass(git_futils_rmdir_r("./custom_transport.git", NULL, GIT_RMDIR_REMOVE_FILES));
cl_assert(custom_transport_used == 1);
}
...@@ -43,7 +43,7 @@ void test_commit_commit__create_unexisting_update_ref(void) ...@@ -43,7 +43,7 @@ void test_commit_commit__create_unexisting_update_ref(void)
NULL, "some msg", tree, 1, (const git_commit **) &commit)); NULL, "some msg", tree, 1, (const git_commit **) &commit));
cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/foo/bar")); cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/foo/bar"));
cl_assert(!git_oid_cmp(&oid, git_reference_target(ref))); cl_assert_equal_oid(&oid, git_reference_target(ref));
git_tree_free(tree); git_tree_free(tree);
git_commit_free(commit); git_commit_free(commit);
......
...@@ -145,7 +145,7 @@ void test_commit_write__root(void) ...@@ -145,7 +145,7 @@ void test_commit_write__root(void)
cl_assert(git_commit_parentcount(commit) == 0); cl_assert(git_commit_parentcount(commit) == 0);
cl_git_pass(git_reference_lookup(&branch, g_repo, branch_name)); cl_git_pass(git_reference_lookup(&branch, g_repo, branch_name));
branch_oid = git_reference_target(branch); branch_oid = git_reference_target(branch);
cl_git_pass(git_oid_cmp(branch_oid, &commit_id)); cl_assert_equal_oid(branch_oid, &commit_id);
cl_assert_equal_s(root_commit_message, git_commit_message(commit)); cl_assert_equal_s(root_commit_message, git_commit_message(commit));
cl_git_pass(git_reflog_read(&log, g_repo, branch_name)); cl_git_pass(git_reflog_read(&log, g_repo, branch_name));
......
...@@ -229,6 +229,22 @@ void test_config_write__add_value_at_file_with_no_clrf_at_the_end(void) ...@@ -229,6 +229,22 @@ void test_config_write__add_value_at_file_with_no_clrf_at_the_end(void)
git_config_free(cfg); git_config_free(cfg);
} }
void test_config_write__add_section_at_file_with_no_clrf_at_the_end(void)
{
git_config *cfg;
int i;
cl_git_pass(git_config_open_ondisk(&cfg, "config17"));
cl_git_pass(git_config_set_int32(cfg, "diff.context", 10));
git_config_free(cfg);
cl_git_pass(git_config_open_ondisk(&cfg, "config17"));
cl_git_pass(git_config_get_int32(&i, cfg, "diff.context"));
cl_assert_equal_i(10, i);
git_config_free(cfg);
}
void test_config_write__add_value_which_needs_quotes(void) void test_config_write__add_value_which_needs_quotes(void)
{ {
git_config *cfg; git_config *cfg;
......
...@@ -1034,18 +1034,14 @@ void test_core_buffer__lf_and_crlf_conversions(void) ...@@ -1034,18 +1034,14 @@ void test_core_buffer__lf_and_crlf_conversions(void)
git_buf_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n"); git_buf_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n");
cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
check_buf("crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n", tgt);
check_buf(src.ptr, tgt);
cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
check_buf("crlf\ncrlf\ncrlf\ncrlf\n", tgt); check_buf("crlf\ncrlf\ncrlf\ncrlf\n", tgt);
git_buf_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf"); git_buf_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf");
cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
check_buf("\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf", tgt);
check_buf(src.ptr, tgt);
cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
check_buf("\ncrlf\ncrlf\ncrlf\ncrlf\ncrlf", tgt); check_buf("\ncrlf\ncrlf\ncrlf\ncrlf\ncrlf", tgt);
...@@ -1054,8 +1050,7 @@ void test_core_buffer__lf_and_crlf_conversions(void) ...@@ -1054,8 +1050,7 @@ void test_core_buffer__lf_and_crlf_conversions(void)
git_buf_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n"); git_buf_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n");
cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
check_buf("\r\nlf\r\nlf\r\ncrlf\r\nlf\r\nlf\r\ncrlf\r\n", tgt);
cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
check_buf("\nlf\nlf\ncrlf\nlf\nlf\ncrlf\n", tgt); check_buf("\nlf\nlf\ncrlf\nlf\nlf\ncrlf\n", tgt);
...@@ -1063,8 +1058,7 @@ void test_core_buffer__lf_and_crlf_conversions(void) ...@@ -1063,8 +1058,7 @@ void test_core_buffer__lf_and_crlf_conversions(void)
git_buf_sets(&src, "\ncrlf\r\ncrlf\r\nlf\ncrlf\r\ncrlf"); git_buf_sets(&src, "\ncrlf\r\ncrlf\r\nlf\ncrlf\r\ncrlf");
cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
check_buf("\r\ncrlf\r\ncrlf\r\nlf\r\ncrlf\r\ncrlf", tgt);
cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
check_buf("\ncrlf\ncrlf\nlf\ncrlf\ncrlf", tgt); check_buf("\ncrlf\ncrlf\nlf\ncrlf\ncrlf", tgt);
...@@ -1072,8 +1066,7 @@ void test_core_buffer__lf_and_crlf_conversions(void) ...@@ -1072,8 +1066,7 @@ void test_core_buffer__lf_and_crlf_conversions(void)
git_buf_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r"); git_buf_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r");
cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
check_buf("\rcrlf\r\nlf\r\nlf\r\ncr\rcrlf\r\nlf\r\ncr\r", tgt);
cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
check_buf("\rcrlf\nlf\nlf\ncr\rcrlf\nlf\ncr\r", tgt); check_buf("\rcrlf\nlf\nlf\ncr\rcrlf\nlf\ncr\r", tgt);
...@@ -1089,8 +1082,7 @@ void test_core_buffer__lf_and_crlf_conversions(void) ...@@ -1089,8 +1082,7 @@ void test_core_buffer__lf_and_crlf_conversions(void)
/* blob correspondence tests */ /* blob correspondence tests */
git_buf_sets(&src, ALL_CRLF_TEXT_RAW); git_buf_sets(&src, ALL_CRLF_TEXT_RAW);
cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
check_buf(ALL_CRLF_TEXT_AS_CRLF, tgt);
cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
check_buf(ALL_CRLF_TEXT_AS_LF, tgt); check_buf(ALL_CRLF_TEXT_AS_LF, tgt);
git_buf_free(&src); git_buf_free(&src);
...@@ -1105,16 +1097,14 @@ void test_core_buffer__lf_and_crlf_conversions(void) ...@@ -1105,16 +1097,14 @@ void test_core_buffer__lf_and_crlf_conversions(void)
git_buf_free(&tgt); git_buf_free(&tgt);
git_buf_sets(&src, MORE_CRLF_TEXT_RAW); git_buf_sets(&src, MORE_CRLF_TEXT_RAW);
cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
check_buf(MORE_CRLF_TEXT_AS_CRLF, tgt);
cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
check_buf(MORE_CRLF_TEXT_AS_LF, tgt); check_buf(MORE_CRLF_TEXT_AS_LF, tgt);
git_buf_free(&src); git_buf_free(&src);
git_buf_free(&tgt); git_buf_free(&tgt);
git_buf_sets(&src, MORE_LF_TEXT_RAW); git_buf_sets(&src, MORE_LF_TEXT_RAW);
cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src)); cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
check_buf(MORE_LF_TEXT_AS_CRLF, tgt);
cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src)); cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
check_buf(MORE_LF_TEXT_AS_LF, tgt); check_buf(MORE_LF_TEXT_AS_LF, tgt);
git_buf_free(&src); git_buf_free(&src);
......
...@@ -38,19 +38,19 @@ void test_core_pool__1(void) ...@@ -38,19 +38,19 @@ void test_core_pool__1(void)
cl_assert(git_pool_malloc(&p, i) != NULL); cl_assert(git_pool_malloc(&p, i) != NULL);
/* with fixed page size, allocation must end up with these values */ /* with fixed page size, allocation must end up with these values */
cl_assert(git_pool__open_pages(&p) == 1); cl_assert_equal_i(1, git_pool__open_pages(&p));
cl_assert(git_pool__full_pages(&p) == 505); cl_assert_equal_i(507, git_pool__full_pages(&p));
git_pool_clear(&p); git_pool_clear(&p);
cl_git_pass(git_pool_init(&p, 1, 4100)); cl_git_pass(git_pool_init(&p, 1, 4120));
for (i = 2010; i > 0; i--) for (i = 2010; i > 0; i--)
cl_assert(git_pool_malloc(&p, i) != NULL); cl_assert(git_pool_malloc(&p, i) != NULL);
/* with fixed page size, allocation must end up with these values */ /* with fixed page size, allocation must end up with these values */
cl_assert(git_pool__open_pages(&p) == 1); cl_assert_equal_i(1, git_pool__open_pages(&p));
cl_assert(git_pool__full_pages(&p) == 492); cl_assert_equal_i(492, git_pool__full_pages(&p));
git_pool_clear(&p); git_pool_clear(&p);
} }
......
...@@ -137,9 +137,9 @@ static void assert_patch_matches_blobs( ...@@ -137,9 +137,9 @@ static void assert_patch_matches_blobs(
cl_assert(delta != NULL); cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_MODIFIED, delta->status); cl_assert_equal_i(GIT_DELTA_MODIFIED, delta->status);
cl_assert(git_oid_equal(git_blob_id(a), &delta->old_file.id)); cl_assert_equal_oid(git_blob_id(a), &delta->old_file.id);
cl_assert_equal_sz(git_blob_rawsize(a), delta->old_file.size); cl_assert_equal_sz(git_blob_rawsize(a), delta->old_file.size);
cl_assert(git_oid_equal(git_blob_id(b), &delta->new_file.id)); cl_assert_equal_oid(git_blob_id(b), &delta->new_file.id);
cl_assert_equal_sz(git_blob_rawsize(b), delta->new_file.size); cl_assert_equal_sz(git_blob_rawsize(b), delta->new_file.size);
cl_assert_equal_i(hunks, (int)git_patch_num_hunks(p)); cl_assert_equal_i(hunks, (int)git_patch_num_hunks(p));
...@@ -274,7 +274,7 @@ void test_diff_blob__can_compare_against_null_blobs_with_patch(void) ...@@ -274,7 +274,7 @@ void test_diff_blob__can_compare_against_null_blobs_with_patch(void)
delta = git_patch_get_delta(p); delta = git_patch_get_delta(p);
cl_assert(delta != NULL); cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_DELETED, delta->status); cl_assert_equal_i(GIT_DELTA_DELETED, delta->status);
cl_assert(git_oid_equal(git_blob_id(d), &delta->old_file.id)); cl_assert_equal_oid(git_blob_id(d), &delta->old_file.id);
cl_assert_equal_sz(git_blob_rawsize(d), delta->old_file.size); cl_assert_equal_sz(git_blob_rawsize(d), delta->old_file.size);
cl_assert(git_oid_iszero(&delta->new_file.id)); cl_assert(git_oid_iszero(&delta->new_file.id));
cl_assert_equal_sz(0, delta->new_file.size); cl_assert_equal_sz(0, delta->new_file.size);
...@@ -301,7 +301,7 @@ void test_diff_blob__can_compare_against_null_blobs_with_patch(void) ...@@ -301,7 +301,7 @@ void test_diff_blob__can_compare_against_null_blobs_with_patch(void)
cl_assert_equal_i(GIT_DELTA_ADDED, delta->status); cl_assert_equal_i(GIT_DELTA_ADDED, delta->status);
cl_assert(git_oid_iszero(&delta->old_file.id)); cl_assert(git_oid_iszero(&delta->old_file.id));
cl_assert_equal_sz(0, delta->old_file.size); cl_assert_equal_sz(0, delta->old_file.size);
cl_assert(git_oid_equal(git_blob_id(d), &delta->new_file.id)); cl_assert_equal_oid(git_blob_id(d), &delta->new_file.id);
cl_assert_equal_sz(git_blob_rawsize(d), delta->new_file.size); cl_assert_equal_sz(git_blob_rawsize(d), delta->new_file.size);
cl_assert_equal_i(1, (int)git_patch_num_hunks(p)); cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
...@@ -392,9 +392,9 @@ void test_diff_blob__can_compare_identical_blobs_with_patch(void) ...@@ -392,9 +392,9 @@ void test_diff_blob__can_compare_identical_blobs_with_patch(void)
cl_assert(delta != NULL); cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_UNMODIFIED, delta->status); cl_assert_equal_i(GIT_DELTA_UNMODIFIED, delta->status);
cl_assert_equal_sz(delta->old_file.size, git_blob_rawsize(d)); cl_assert_equal_sz(delta->old_file.size, git_blob_rawsize(d));
cl_assert(git_oid_equal(git_blob_id(d), &delta->old_file.id)); cl_assert_equal_oid(git_blob_id(d), &delta->old_file.id);
cl_assert_equal_sz(delta->new_file.size, git_blob_rawsize(d)); cl_assert_equal_sz(delta->new_file.size, git_blob_rawsize(d));
cl_assert(git_oid_equal(git_blob_id(d), &delta->new_file.id)); cl_assert_equal_oid(git_blob_id(d), &delta->new_file.id);
cl_assert_equal_i(0, (int)git_patch_num_hunks(p)); cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
git_patch_free(p); git_patch_free(p);
......
...@@ -380,7 +380,7 @@ static void index_iterator_test( ...@@ -380,7 +380,7 @@ static void index_iterator_test(
if (expected_oids != NULL) { if (expected_oids != NULL) {
git_oid oid; git_oid oid;
cl_git_pass(git_oid_fromstr(&oid, expected_oids[count])); cl_git_pass(git_oid_fromstr(&oid, expected_oids[count]));
cl_assert_equal_i(git_oid_cmp(&oid, &entry->id), 0); cl_assert_equal_oid(&oid, &entry->id);
} }
count++; count++;
......
...@@ -120,7 +120,7 @@ static int fetchhead_ref_cb(const char *name, const char *url, ...@@ -120,7 +120,7 @@ static int fetchhead_ref_cb(const char *name, const char *url,
expected = git_vector_get(cb_data->fetchhead_vector, cb_data->idx); expected = git_vector_get(cb_data->fetchhead_vector, cb_data->idx);
cl_assert(git_oid_cmp(&expected->oid, oid) == 0); cl_assert_equal_oid(&expected->oid, oid);
cl_assert(expected->is_merge == is_merge); cl_assert(expected->is_merge == is_merge);
if (expected->ref_name) if (expected->ref_name)
...@@ -174,7 +174,7 @@ static int read_old_style_cb(const char *name, const char *url, ...@@ -174,7 +174,7 @@ static int read_old_style_cb(const char *name, const char *url,
cl_assert(name == NULL); cl_assert(name == NULL);
cl_assert(url == NULL); cl_assert(url == NULL);
cl_assert(git_oid_cmp(&expected, oid) == 0); cl_assert_equal_oid(&expected, oid);
cl_assert(is_merge == 1); cl_assert(is_merge == 1);
return 0; return 0;
...@@ -201,7 +201,7 @@ static int read_type_missing(const char *ref_name, const char *remote_url, ...@@ -201,7 +201,7 @@ static int read_type_missing(const char *ref_name, const char *remote_url,
cl_assert_equal_s("name", ref_name); cl_assert_equal_s("name", ref_name);
cl_assert_equal_s("remote_url", remote_url); cl_assert_equal_s("remote_url", remote_url);
cl_assert(git_oid_cmp(&expected, oid) == 0); cl_assert_equal_oid(&expected, oid);
cl_assert(is_merge == 0); cl_assert(is_merge == 0);
return 0; return 0;
...@@ -228,7 +228,7 @@ static int read_name_missing(const char *ref_name, const char *remote_url, ...@@ -228,7 +228,7 @@ static int read_name_missing(const char *ref_name, const char *remote_url,
cl_assert(ref_name == NULL); cl_assert(ref_name == NULL);
cl_assert_equal_s("remote_url", remote_url); cl_assert_equal_s("remote_url", remote_url);
cl_assert(git_oid_cmp(&expected, oid) == 0); cl_assert_equal_oid(&expected, oid);
cl_assert(is_merge == 0); cl_assert(is_merge == 0);
return 0; return 0;
......
...@@ -107,13 +107,13 @@ void test_index_conflicts__get(void) ...@@ -107,13 +107,13 @@ void test_index_conflicts__get(void)
cl_assert_equal_s("conflicts-one.txt", conflict_entry[0]->path); cl_assert_equal_s("conflicts-one.txt", conflict_entry[0]->path);
git_oid_fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID); git_oid_fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID);
cl_assert(git_oid_cmp(&conflict_entry[0]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
git_oid_fromstr(&oid, CONFLICTS_ONE_OUR_OID); git_oid_fromstr(&oid, CONFLICTS_ONE_OUR_OID);
cl_assert(git_oid_cmp(&conflict_entry[1]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
git_oid_fromstr(&oid, CONFLICTS_ONE_THEIR_OID); git_oid_fromstr(&oid, CONFLICTS_ONE_THEIR_OID);
cl_assert(git_oid_cmp(&conflict_entry[2]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1],
&conflict_entry[2], repo_index, "conflicts-two.txt")); &conflict_entry[2], repo_index, "conflicts-two.txt"));
...@@ -121,13 +121,13 @@ void test_index_conflicts__get(void) ...@@ -121,13 +121,13 @@ void test_index_conflicts__get(void)
cl_assert_equal_s("conflicts-two.txt", conflict_entry[0]->path); cl_assert_equal_s("conflicts-two.txt", conflict_entry[0]->path);
git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID); git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID);
cl_assert(git_oid_cmp(&conflict_entry[0]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID); git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID);
cl_assert(git_oid_cmp(&conflict_entry[1]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID); git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID);
cl_assert(git_oid_cmp(&conflict_entry[2]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
} }
void test_index_conflicts__iterate(void) void test_index_conflicts__iterate(void)
...@@ -141,29 +141,29 @@ void test_index_conflicts__iterate(void) ...@@ -141,29 +141,29 @@ void test_index_conflicts__iterate(void)
cl_git_pass(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator)); cl_git_pass(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator));
git_oid_fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID); git_oid_fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID);
cl_assert(git_oid_cmp(&conflict_entry[0]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0);
git_oid_fromstr(&oid, CONFLICTS_ONE_OUR_OID); git_oid_fromstr(&oid, CONFLICTS_ONE_OUR_OID);
cl_assert(git_oid_cmp(&conflict_entry[1]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0);
git_oid_fromstr(&oid, CONFLICTS_ONE_THEIR_OID); git_oid_fromstr(&oid, CONFLICTS_ONE_THEIR_OID);
cl_assert(git_oid_cmp(&conflict_entry[2]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0);
cl_git_pass(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator)); cl_git_pass(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator));
git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID); git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID);
cl_assert(git_oid_cmp(&conflict_entry[0]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0);
git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID); git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID);
cl_assert(git_oid_cmp(&conflict_entry[1]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0);
git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID); git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID);
cl_assert(git_oid_cmp(&conflict_entry[2]->id, &oid) == 0); cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0); cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0);
cl_assert(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator) == GIT_ITEROVER); cl_assert(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator) == GIT_ITEROVER);
...@@ -281,7 +281,7 @@ void test_index_conflicts__partial(void) ...@@ -281,7 +281,7 @@ void test_index_conflicts__partial(void)
cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1],
&conflict_entry[2], repo_index, "test-one.txt")); &conflict_entry[2], repo_index, "test-one.txt"));
cl_assert(git_oid_cmp(&ancestor_entry.id, &conflict_entry[0]->id) == 0); cl_assert_equal_oid(&ancestor_entry.id, &conflict_entry[0]->id);
cl_assert(conflict_entry[1] == NULL); cl_assert(conflict_entry[1] == NULL);
cl_assert(conflict_entry[2] == NULL); cl_assert(conflict_entry[2] == NULL);
} }
...@@ -41,7 +41,7 @@ void test_index_crlf__autocrlf_false_no_attrs(void) ...@@ -41,7 +41,7 @@ void test_index_crlf__autocrlf_false_no_attrs(void)
cl_git_pass(git_oid_fromstr(&oid, cl_git_pass(git_oid_fromstr(&oid,
(GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_OID_CRLF : FILE_OID_LF)); (GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_OID_CRLF : FILE_OID_LF));
cl_assert(git_oid_cmp(&oid, &entry->id) == 0); cl_assert_equal_oid(&oid, &entry->id);
} }
void test_index_crlf__autocrlf_true_no_attrs(void) void test_index_crlf__autocrlf_true_no_attrs(void)
...@@ -58,7 +58,7 @@ void test_index_crlf__autocrlf_true_no_attrs(void) ...@@ -58,7 +58,7 @@ void test_index_crlf__autocrlf_true_no_attrs(void)
entry = git_index_get_bypath(g_index, "newfile.txt", 0); entry = git_index_get_bypath(g_index, "newfile.txt", 0);
cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
cl_assert(git_oid_cmp(&oid, &entry->id) == 0); cl_assert_equal_oid(&oid, &entry->id);
} }
void test_index_crlf__autocrlf_input_no_attrs(void) void test_index_crlf__autocrlf_input_no_attrs(void)
...@@ -75,7 +75,7 @@ void test_index_crlf__autocrlf_input_no_attrs(void) ...@@ -75,7 +75,7 @@ void test_index_crlf__autocrlf_input_no_attrs(void)
entry = git_index_get_bypath(g_index, "newfile.txt", 0); entry = git_index_get_bypath(g_index, "newfile.txt", 0);
cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
cl_assert(git_oid_cmp(&oid, &entry->id) == 0); cl_assert_equal_oid(&oid, &entry->id);
} }
void test_index_crlf__autocrlf_false_text_auto_attr(void) void test_index_crlf__autocrlf_false_text_auto_attr(void)
...@@ -94,7 +94,7 @@ void test_index_crlf__autocrlf_false_text_auto_attr(void) ...@@ -94,7 +94,7 @@ void test_index_crlf__autocrlf_false_text_auto_attr(void)
entry = git_index_get_bypath(g_index, "newfile.txt", 0); entry = git_index_get_bypath(g_index, "newfile.txt", 0);
cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
cl_assert(git_oid_cmp(&oid, &entry->id) == 0); cl_assert_equal_oid(&oid, &entry->id);
} }
void test_index_crlf__autocrlf_true_text_auto_attr(void) void test_index_crlf__autocrlf_true_text_auto_attr(void)
...@@ -113,7 +113,7 @@ void test_index_crlf__autocrlf_true_text_auto_attr(void) ...@@ -113,7 +113,7 @@ void test_index_crlf__autocrlf_true_text_auto_attr(void)
entry = git_index_get_bypath(g_index, "newfile.txt", 0); entry = git_index_get_bypath(g_index, "newfile.txt", 0);
cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
cl_assert(git_oid_cmp(&oid, &entry->id) == 0); cl_assert_equal_oid(&oid, &entry->id);
} }
void test_index_crlf__autocrlf_input_text_auto_attr(void) void test_index_crlf__autocrlf_input_text_auto_attr(void)
...@@ -132,7 +132,7 @@ void test_index_crlf__autocrlf_input_text_auto_attr(void) ...@@ -132,7 +132,7 @@ void test_index_crlf__autocrlf_input_text_auto_attr(void)
entry = git_index_get_bypath(g_index, "newfile.txt", 0); entry = git_index_get_bypath(g_index, "newfile.txt", 0);
cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF));
cl_assert(git_oid_cmp(&oid, &entry->id) == 0); cl_assert_equal_oid(&oid, &entry->id);
} }
void test_index_crlf__safecrlf_true_no_attrs(void) void test_index_crlf__safecrlf_true_no_attrs(void)
......
...@@ -37,7 +37,7 @@ void test_index_read_tree__read_write_involution(void) ...@@ -37,7 +37,7 @@ void test_index_read_tree__read_write_involution(void)
git_tree_free(tree); git_tree_free(tree);
cl_git_pass(git_index_write_tree(&tree_oid, index)); cl_git_pass(git_index_write_tree(&tree_oid, index));
cl_assert(git_oid_cmp(&expected, &tree_oid) == 0); cl_assert_equal_oid(&expected, &tree_oid);
git_index_free(index); git_index_free(index);
git_repository_free(repo); git_repository_free(repo);
......
...@@ -27,7 +27,7 @@ void test_index_rename__single_file(void) ...@@ -27,7 +27,7 @@ void test_index_rename__single_file(void)
cl_assert(!git_index_find(&position, index, "lame.name.txt")); cl_assert(!git_index_find(&position, index, "lame.name.txt"));
entry = git_index_get_byindex(index, position); entry = git_index_get_byindex(index, position);
cl_assert(git_oid_cmp(&expected, &entry->id) == 0); cl_assert_equal_oid(&expected, &entry->id);
/* This removes the entry from the index, but not from the object database */ /* This removes the entry from the index, but not from the object database */
cl_git_pass(git_index_remove(index, "lame.name.txt", 0)); cl_git_pass(git_index_remove(index, "lame.name.txt", 0));
...@@ -41,7 +41,7 @@ void test_index_rename__single_file(void) ...@@ -41,7 +41,7 @@ void test_index_rename__single_file(void)
cl_assert(!git_index_find(&position, index, "fancy.name.txt")); cl_assert(!git_index_find(&position, index, "fancy.name.txt"));
entry = git_index_get_byindex(index, position); entry = git_index_get_byindex(index, position);
cl_assert(git_oid_cmp(&expected, &entry->id) == 0); cl_assert_equal_oid(&expected, &entry->id);
git_index_free(index); git_index_free(index);
git_repository_free(repo); git_repository_free(repo);
......
...@@ -53,9 +53,9 @@ void test_index_reuc__add(void) ...@@ -53,9 +53,9 @@ void test_index_reuc__add(void)
cl_assert(reuc->mode[0] == 0100644); cl_assert(reuc->mode[0] == 0100644);
cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[1] == 0100644);
cl_assert(reuc->mode[2] == 0100644); cl_assert(reuc->mode[2] == 0100644);
cl_assert(git_oid_cmp(&reuc->oid[0], &ancestor_oid) == 0); cl_assert_equal_oid(&reuc->oid[0], &ancestor_oid);
cl_assert(git_oid_cmp(&reuc->oid[1], &our_oid) == 0); cl_assert_equal_oid(&reuc->oid[1], &our_oid);
cl_assert(git_oid_cmp(&reuc->oid[2], &their_oid) == 0); cl_assert_equal_oid(&reuc->oid[2], &their_oid);
} }
void test_index_reuc__add_no_ancestor(void) void test_index_reuc__add_no_ancestor(void)
...@@ -78,9 +78,9 @@ void test_index_reuc__add_no_ancestor(void) ...@@ -78,9 +78,9 @@ void test_index_reuc__add_no_ancestor(void)
cl_assert(reuc->mode[0] == 0); cl_assert(reuc->mode[0] == 0);
cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[1] == 0100644);
cl_assert(reuc->mode[2] == 0100644); cl_assert(reuc->mode[2] == 0100644);
cl_assert(git_oid_cmp(&reuc->oid[0], &ancestor_oid) == 0); cl_assert_equal_oid(&reuc->oid[0], &ancestor_oid);
cl_assert(git_oid_cmp(&reuc->oid[1], &our_oid) == 0); cl_assert_equal_oid(&reuc->oid[1], &our_oid);
cl_assert(git_oid_cmp(&reuc->oid[2], &their_oid) == 0); cl_assert_equal_oid(&reuc->oid[2], &their_oid);
} }
void test_index_reuc__read_bypath(void) void test_index_reuc__read_bypath(void)
...@@ -97,11 +97,11 @@ void test_index_reuc__read_bypath(void) ...@@ -97,11 +97,11 @@ void test_index_reuc__read_bypath(void)
cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[1] == 0100644);
cl_assert(reuc->mode[2] == 0100644); cl_assert(reuc->mode[2] == 0100644);
git_oid_fromstr(&oid, TWO_ANCESTOR_OID); git_oid_fromstr(&oid, TWO_ANCESTOR_OID);
cl_assert(git_oid_cmp(&reuc->oid[0], &oid) == 0); cl_assert_equal_oid(&reuc->oid[0], &oid);
git_oid_fromstr(&oid, TWO_OUR_OID); git_oid_fromstr(&oid, TWO_OUR_OID);
cl_assert(git_oid_cmp(&reuc->oid[1], &oid) == 0); cl_assert_equal_oid(&reuc->oid[1], &oid);
git_oid_fromstr(&oid, TWO_THEIR_OID); git_oid_fromstr(&oid, TWO_THEIR_OID);
cl_assert(git_oid_cmp(&reuc->oid[2], &oid) == 0); cl_assert_equal_oid(&reuc->oid[2], &oid);
cl_assert(reuc = git_index_reuc_get_bypath(repo_index, "one.txt")); cl_assert(reuc = git_index_reuc_get_bypath(repo_index, "one.txt"));
...@@ -110,11 +110,11 @@ void test_index_reuc__read_bypath(void) ...@@ -110,11 +110,11 @@ void test_index_reuc__read_bypath(void)
cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[1] == 0100644);
cl_assert(reuc->mode[2] == 0100644); cl_assert(reuc->mode[2] == 0100644);
git_oid_fromstr(&oid, ONE_ANCESTOR_OID); git_oid_fromstr(&oid, ONE_ANCESTOR_OID);
cl_assert(git_oid_cmp(&reuc->oid[0], &oid) == 0); cl_assert_equal_oid(&reuc->oid[0], &oid);
git_oid_fromstr(&oid, ONE_OUR_OID); git_oid_fromstr(&oid, ONE_OUR_OID);
cl_assert(git_oid_cmp(&reuc->oid[1], &oid) == 0); cl_assert_equal_oid(&reuc->oid[1], &oid);
git_oid_fromstr(&oid, ONE_THEIR_OID); git_oid_fromstr(&oid, ONE_THEIR_OID);
cl_assert(git_oid_cmp(&reuc->oid[2], &oid) == 0); cl_assert_equal_oid(&reuc->oid[2], &oid);
} }
void test_index_reuc__ignore_case(void) void test_index_reuc__ignore_case(void)
...@@ -142,11 +142,11 @@ void test_index_reuc__ignore_case(void) ...@@ -142,11 +142,11 @@ void test_index_reuc__ignore_case(void)
cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[1] == 0100644);
cl_assert(reuc->mode[2] == 0100644); cl_assert(reuc->mode[2] == 0100644);
git_oid_fromstr(&oid, TWO_ANCESTOR_OID); git_oid_fromstr(&oid, TWO_ANCESTOR_OID);
cl_assert(git_oid_cmp(&reuc->oid[0], &oid) == 0); cl_assert_equal_oid(&reuc->oid[0], &oid);
git_oid_fromstr(&oid, TWO_OUR_OID); git_oid_fromstr(&oid, TWO_OUR_OID);
cl_assert(git_oid_cmp(&reuc->oid[1], &oid) == 0); cl_assert_equal_oid(&reuc->oid[1], &oid);
git_oid_fromstr(&oid, TWO_THEIR_OID); git_oid_fromstr(&oid, TWO_THEIR_OID);
cl_assert(git_oid_cmp(&reuc->oid[2], &oid) == 0); cl_assert_equal_oid(&reuc->oid[2], &oid);
} }
void test_index_reuc__read_byindex(void) void test_index_reuc__read_byindex(void)
...@@ -163,11 +163,11 @@ void test_index_reuc__read_byindex(void) ...@@ -163,11 +163,11 @@ void test_index_reuc__read_byindex(void)
cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[1] == 0100644);
cl_assert(reuc->mode[2] == 0100644); cl_assert(reuc->mode[2] == 0100644);
git_oid_fromstr(&oid, ONE_ANCESTOR_OID); git_oid_fromstr(&oid, ONE_ANCESTOR_OID);
cl_assert(git_oid_cmp(&reuc->oid[0], &oid) == 0); cl_assert_equal_oid(&reuc->oid[0], &oid);
git_oid_fromstr(&oid, ONE_OUR_OID); git_oid_fromstr(&oid, ONE_OUR_OID);
cl_assert(git_oid_cmp(&reuc->oid[1], &oid) == 0); cl_assert_equal_oid(&reuc->oid[1], &oid);
git_oid_fromstr(&oid, ONE_THEIR_OID); git_oid_fromstr(&oid, ONE_THEIR_OID);
cl_assert(git_oid_cmp(&reuc->oid[2], &oid) == 0); cl_assert_equal_oid(&reuc->oid[2], &oid);
cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 1)); cl_assert(reuc = git_index_reuc_get_byindex(repo_index, 1));
...@@ -176,11 +176,11 @@ void test_index_reuc__read_byindex(void) ...@@ -176,11 +176,11 @@ void test_index_reuc__read_byindex(void)
cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[1] == 0100644);
cl_assert(reuc->mode[2] == 0100644); cl_assert(reuc->mode[2] == 0100644);
git_oid_fromstr(&oid, TWO_ANCESTOR_OID); git_oid_fromstr(&oid, TWO_ANCESTOR_OID);
cl_assert(git_oid_cmp(&reuc->oid[0], &oid) == 0); cl_assert_equal_oid(&reuc->oid[0], &oid);
git_oid_fromstr(&oid, TWO_OUR_OID); git_oid_fromstr(&oid, TWO_OUR_OID);
cl_assert(git_oid_cmp(&reuc->oid[1], &oid) == 0); cl_assert_equal_oid(&reuc->oid[1], &oid);
git_oid_fromstr(&oid, TWO_THEIR_OID); git_oid_fromstr(&oid, TWO_THEIR_OID);
cl_assert(git_oid_cmp(&reuc->oid[2], &oid) == 0); cl_assert_equal_oid(&reuc->oid[2], &oid);
} }
void test_index_reuc__updates_existing(void) void test_index_reuc__updates_existing(void)
...@@ -216,11 +216,11 @@ void test_index_reuc__updates_existing(void) ...@@ -216,11 +216,11 @@ void test_index_reuc__updates_existing(void)
cl_assert_equal_s("TWO.txt", reuc->path); cl_assert_equal_s("TWO.txt", reuc->path);
git_oid_fromstr(&oid, TWO_OUR_OID); git_oid_fromstr(&oid, TWO_OUR_OID);
cl_assert(git_oid_cmp(&reuc->oid[0], &oid) == 0); cl_assert_equal_oid(&reuc->oid[0], &oid);
git_oid_fromstr(&oid, TWO_THEIR_OID); git_oid_fromstr(&oid, TWO_THEIR_OID);
cl_assert(git_oid_cmp(&reuc->oid[1], &oid) == 0); cl_assert_equal_oid(&reuc->oid[1], &oid);
git_oid_fromstr(&oid, TWO_ANCESTOR_OID); git_oid_fromstr(&oid, TWO_ANCESTOR_OID);
cl_assert(git_oid_cmp(&reuc->oid[2], &oid) == 0); cl_assert_equal_oid(&reuc->oid[2], &oid);
} }
void test_index_reuc__remove(void) void test_index_reuc__remove(void)
...@@ -242,11 +242,11 @@ void test_index_reuc__remove(void) ...@@ -242,11 +242,11 @@ void test_index_reuc__remove(void)
cl_assert(reuc->mode[1] == 0100644); cl_assert(reuc->mode[1] == 0100644);
cl_assert(reuc->mode[2] == 0100644); cl_assert(reuc->mode[2] == 0100644);
git_oid_fromstr(&oid, TWO_ANCESTOR_OID); git_oid_fromstr(&oid, TWO_ANCESTOR_OID);
cl_assert(git_oid_cmp(&reuc->oid[0], &oid) == 0); cl_assert_equal_oid(&reuc->oid[0], &oid);
git_oid_fromstr(&oid, TWO_OUR_OID); git_oid_fromstr(&oid, TWO_OUR_OID);
cl_assert(git_oid_cmp(&reuc->oid[1], &oid) == 0); cl_assert_equal_oid(&reuc->oid[1], &oid);
git_oid_fromstr(&oid, TWO_THEIR_OID); git_oid_fromstr(&oid, TWO_THEIR_OID);
cl_assert(git_oid_cmp(&reuc->oid[2], &oid) == 0); cl_assert_equal_oid(&reuc->oid[2], &oid);
} }
void test_index_reuc__write(void) void test_index_reuc__write(void)
......
...@@ -243,11 +243,11 @@ void test_index_tests__add(void) ...@@ -243,11 +243,11 @@ void test_index_tests__add(void)
entry = git_index_get_byindex(index, 0); entry = git_index_get_byindex(index, 0);
/* And the built-in hashing mechanism worked as expected */ /* And the built-in hashing mechanism worked as expected */
cl_assert(git_oid_cmp(&id1, &entry->id) == 0); cl_assert_equal_oid(&id1, &entry->id);
/* Test access by path instead of index */ /* Test access by path instead of index */
cl_assert((entry = git_index_get_bypath(index, "test.txt", 0)) != NULL); cl_assert((entry = git_index_get_bypath(index, "test.txt", 0)) != NULL);
cl_assert(git_oid_cmp(&id1, &entry->id) == 0); cl_assert_equal_oid(&id1, &entry->id);
git_index_free(index); git_index_free(index);
git_repository_free(repo); git_repository_free(repo);
...@@ -283,14 +283,14 @@ void test_index_tests__add_issue_1397(void) ...@@ -283,14 +283,14 @@ void test_index_tests__add_issue_1397(void)
/* Make sure the initial SHA-1 is correct */ /* Make sure the initial SHA-1 is correct */
cl_assert((entry = git_index_get_bypath(index, "crlf_file.txt", 0)) != NULL); cl_assert((entry = git_index_get_bypath(index, "crlf_file.txt", 0)) != NULL);
cl_assert_(git_oid_cmp(&id1, &entry->id) == 0, "first oid check"); cl_assert_equal_oid(&id1, &entry->id);
/* Update the index */ /* Update the index */
cl_git_pass(git_index_add_bypath(index, "crlf_file.txt")); cl_git_pass(git_index_add_bypath(index, "crlf_file.txt"));
/* Check the new SHA-1 */ /* Check the new SHA-1 */
cl_assert((entry = git_index_get_bypath(index, "crlf_file.txt", 0)) != NULL); cl_assert((entry = git_index_get_bypath(index, "crlf_file.txt", 0)) != NULL);
cl_assert_(git_oid_cmp(&id1, &entry->id) == 0, "second oid check"); cl_assert_equal_oid(&id1, &entry->id);
git_index_free(index); git_index_free(index);
} }
......
...@@ -259,7 +259,7 @@ void test_merge_trees_trivial__13(void) ...@@ -259,7 +259,7 @@ void test_merge_trees_trivial__13(void)
cl_assert(entry = git_index_get_bypath(result, "modified-in-13.txt", 0)); cl_assert(entry = git_index_get_bypath(result, "modified-in-13.txt", 0));
cl_git_pass(git_oid_fromstr(&expected_oid, "1cff9ec6a47a537380dedfdd17c9e76d74259a2b")); cl_git_pass(git_oid_fromstr(&expected_oid, "1cff9ec6a47a537380dedfdd17c9e76d74259a2b"));
cl_assert(git_oid_cmp(&entry->id, &expected_oid) == 0); cl_assert_equal_oid(&expected_oid, &entry->id);
cl_assert(git_index_reuc_entrycount(result) == 0); cl_assert(git_index_reuc_entrycount(result) == 0);
cl_assert(merge_trivial_conflict_entrycount(result) == 0); cl_assert(merge_trivial_conflict_entrycount(result) == 0);
......
...@@ -97,7 +97,7 @@ static int merge_branch(void) ...@@ -97,7 +97,7 @@ static int merge_branch(void)
cl_git_pass(git_oid_fromstr(&their_oids[0], MERGE_BRANCH_OID)); cl_git_pass(git_oid_fromstr(&their_oids[0], MERGE_BRANCH_OID));
cl_git_pass(git_merge_head_from_id(&their_heads[0], repo, &their_oids[0])); cl_git_pass(git_merge_head_from_id(&their_heads[0], repo, &their_oids[0]));
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_ALLOW_CONFLICTS; checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
error = git_merge(repo, (const git_merge_head **)their_heads, 1, &merge_opts, &checkout_opts); error = git_merge(repo, (const git_merge_head **)their_heads, 1, &merge_opts, &checkout_opts);
git_merge_head_free(their_heads[0]); git_merge_head_free(their_heads[0]);
......
...@@ -87,28 +87,43 @@ void test_network_fetchlocal__partial(void) ...@@ -87,28 +87,43 @@ void test_network_fetchlocal__partial(void)
git_remote_free(origin); git_remote_free(origin);
} }
void test_network_fetchlocal__clone_into_mirror(void) static int remote_mirror_cb(git_remote **out, git_repository *repo,
const char *name, const char *url, void *payload)
{ {
git_buf path = GIT_BUF_INIT; int error;
git_repository *repo;
git_remote *remote; git_remote *remote;
git_reference *head;
cl_git_pass(git_repository_init(&repo, "./foo.git", true)); GIT_UNUSED(payload);
cl_git_pass(git_remote_create(&remote, repo, "origin", cl_git_fixture_url("testrepo.git")));
if ((error = git_remote_create(&remote, repo, name, url)) < 0)
return error;
git_remote_clear_refspecs(remote); git_remote_clear_refspecs(remote);
cl_git_pass(git_remote_add_fetch(remote, "+refs/*:refs/*"));
cl_git_pass(git_clone_into(repo, remote, NULL, NULL, NULL)); if ((error = git_remote_add_fetch(remote, "+refs/*:refs/*")) < 0) {
git_remote_free(remote);
return error;
}
*out = remote;
return 0;
}
void test_network_fetchlocal__clone_into_mirror(void)
{
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
git_repository *repo;
git_reference *head;
opts.bare = true;
opts.remote_cb = remote_mirror_cb;
cl_git_pass(git_clone(&repo, cl_git_fixture_url("testrepo.git"), "./foo.git", &opts));
cl_git_pass(git_reference_lookup(&head, repo, "HEAD")); cl_git_pass(git_reference_lookup(&head, repo, "HEAD"));
cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head)); cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head)); cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
git_remote_free(remote);
git_reference_free(head); git_reference_free(head);
git_repository_free(repo); git_repository_free(repo);
git_buf_free(&path);
cl_fixture_cleanup("./foo.git"); cl_fixture_cleanup("./foo.git");
} }
...@@ -84,4 +84,27 @@ void test_network_refspecs__parsing(void) ...@@ -84,4 +84,27 @@ void test_network_refspecs__parsing(void)
assert_refspec(GIT_DIRECTION_FETCH, "master", true); assert_refspec(GIT_DIRECTION_FETCH, "master", true);
assert_refspec(GIT_DIRECTION_PUSH, "master", true); assert_refspec(GIT_DIRECTION_PUSH, "master", true);
assert_refspec(GIT_DIRECTION_FETCH, "refs/pull/*/head:refs/remotes/origin/pr/*", true);
}
void assert_transform(const char *refspec, const char *name, const char *result)
{
git_refspec spec;
git_buf buf = GIT_BUF_INIT;
git_refspec__parse(&spec, refspec, true);
cl_git_pass(git_refspec_transform(&buf, &spec, name));
cl_assert_equal_s(result, buf.ptr);
git_buf_free(&buf);
git_refspec__free(&spec);
}
void test_network_refspecs__transform_mid_star(void)
{
assert_transform("refs/pull/*/head:refs/remotes/origin/pr/*", "refs/pull/23/head", "refs/remotes/origin/pr/23");
assert_transform("refs/heads/*:refs/remotes/origin/*", "refs/heads/master", "refs/remotes/origin/master");
assert_transform("refs/heads/*:refs/heads/*", "refs/heads/master", "refs/heads/master");
assert_transform("refs/*:refs/*", "refs/heads/master", "refs/heads/master");
} }
...@@ -72,18 +72,17 @@ void test_network_remote_remotes__error_when_not_found(void) ...@@ -72,18 +72,17 @@ void test_network_remote_remotes__error_when_not_found(void)
void test_network_remote_remotes__error_when_no_push_available(void) void test_network_remote_remotes__error_when_no_push_available(void)
{ {
git_remote *r; git_remote *r;
git_transport *t;
git_push *p; git_push *p;
cl_git_pass(git_remote_create_anonymous(&r, _repo, cl_fixture("testrepo.git"), NULL)); cl_git_pass(git_remote_create_anonymous(&r, _repo, cl_fixture("testrepo.git"), NULL));
cl_git_pass(git_transport_local(&t,r,NULL)); cl_git_pass(git_remote_set_transport(r, git_transport_local, NULL));
cl_git_pass(git_remote_connect(r, GIT_DIRECTION_PUSH));
/* Make sure that push is really not available */ /* Make sure that push is really not available */
t->push = NULL; r->transport->push = NULL;
cl_git_pass(git_remote_set_transport(r, t));
cl_git_pass(git_remote_connect(r, GIT_DIRECTION_PUSH));
cl_git_pass(git_push_new(&p, r)); cl_git_pass(git_push_new(&p, r));
cl_git_pass(git_push_add_refspec(p, "refs/heads/master")); cl_git_pass(git_push_add_refspec(p, "refs/heads/master"));
cl_git_fail_with(git_push_finish(p), GIT_ERROR); cl_git_fail_with(git_push_finish(p), GIT_ERROR);
...@@ -438,27 +437,6 @@ void test_network_remote_remotes__returns_ENOTFOUND_when_neither_url_nor_pushurl ...@@ -438,27 +437,6 @@ void test_network_remote_remotes__returns_ENOTFOUND_when_neither_url_nor_pushurl
git_remote_load(&remote, _repo, "no-remote-url"), GIT_ENOTFOUND); git_remote_load(&remote, _repo, "no-remote-url"), GIT_ENOTFOUND);
} }
void test_network_remote_remotes__check_structure_version(void)
{
git_transport transport = GIT_TRANSPORT_INIT;
const git_error *err;
git_remote_free(_remote);
_remote = NULL;
cl_git_pass(git_remote_create_anonymous(&_remote, _repo, "test-protocol://localhost", NULL));
transport.version = 0;
cl_git_fail(git_remote_set_transport(_remote, &transport));
err = giterr_last();
cl_assert_equal_i(GITERR_INVALID, err->klass);
giterr_clear();
transport.version = 1024;
cl_git_fail(git_remote_set_transport(_remote, &transport));
err = giterr_last();
cl_assert_equal_i(GITERR_INVALID, err->klass);
}
void assert_cannot_create_remote(const char *name, int expected_error) void assert_cannot_create_remote(const char *name, int expected_error)
{ {
git_remote *remote = NULL; git_remote *remote = NULL;
......
...@@ -33,6 +33,24 @@ void test_network_urlparse__trivial(void) ...@@ -33,6 +33,24 @@ void test_network_urlparse__trivial(void)
cl_assert_equal_p(pass, NULL); cl_assert_equal_p(pass, NULL);
} }
void test_network_urlparse__root(void)
{
cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
"http://example.com/", "8080"));
cl_assert_equal_s(host, "example.com");
cl_assert_equal_s(port, "8080");
cl_assert_equal_s(path, "/");
cl_assert_equal_p(user, NULL);
cl_assert_equal_p(pass, NULL);
}
void test_network_urlparse__just_hostname(void)
{
cl_git_fail_with(GIT_EINVALIDSPEC,
gitno_extract_url_parts(&host, &port, &path, &user, &pass,
"http://example.com", "8080"));
}
void test_network_urlparse__encoded_password(void) void test_network_urlparse__encoded_password(void)
{ {
cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass, cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment