summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt15
-rw-r--r--CONTRIBUTING.md13
-rw-r--r--README.md19
-rw-r--r--include/git2/object.h2
-rw-r--r--include/git2/remote.h8
-rw-r--r--include/git2/tree.h2
-rw-r--r--src/diff_tform.c4
-rw-r--r--src/index.c12
-rw-r--r--src/indexer.c2
-rw-r--r--src/merge.c4
-rw-r--r--src/odb.c1
-rw-r--r--src/pack-objects.c4
-rw-r--r--src/pack.c4
-rw-r--r--src/remote.c6
-rw-r--r--src/repository.c6
-rw-r--r--src/revparse.c13
-rw-r--r--tests-clar/refs/revparse.c41
17 files changed, 124 insertions, 32 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1086005c3..c937ba93c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -30,16 +30,13 @@ OPTION( ENABLE_TRACE "Enables tracing support" OFF )
OPTION( LIBGIT2_FILENAME "Name of the produced binary" OFF )
IF(MSVC)
- # This option is only availalbe when building with MSVC. By default,
- # libgit2 is build using the stdcall calling convention, as that's what
- # the CLR expects by default and how the Windows API is built.
+ # This option is only available when building with MSVC. By default, libgit2
+ # is build using the cdecl calling convention, which is useful if you're
+ # writing C. However, the CLR and Win32 API both expect stdcall.
#
- # If you are writing a C or C++ program and want to link to libgit2, you
- # have to either:
- # - Add /Gz to the compiler options of _your_ program / library.
- # - Turn this off by invoking CMake with the "-DSTDCALL=Off" argument.
- #
- OPTION( STDCALL "Build libgit2 with the __stdcall convention" ON )
+ # If you are writing a CLR program and want to link to libgit2, you'll want
+ # to turn this on by invoking CMake with the "-DSTDCALL=ON" argument.
+ OPTION( STDCALL "Build libgit2 with the __stdcall convention" OFF )
# This option must match the settings used in your program, in particular if you
# are linking statically
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 28ef27f42..5c2eaec5e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -48,6 +48,12 @@ Please include a nice description of your changes with 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 working on a particular area then feel free to submit a PR that
+highlights your work in progress (and flag in the PR title that it's not
+ready to merge). This 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.
+
## Porting Code From Other Open-Source Projects
`libgit2` is licensed under the terms of the GPL v2 with a linking
@@ -57,14 +63,17 @@ The most common case is porting code from core Git. Git is a pure GPL
project, which means that in order to port code to this project, we need the
explicit permission of the author. Check the
[`git.git-authors`](https://github.com/libgit2/libgit2/blob/development/git.git-authors)
-file for authors who have already consented; feel free to add someone if
-you've obtained their consent.
+file for authors who have already consented.
Other licenses have other requirements; check the license of the library
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
license typically doesn't work due to GPL incompatibility.
+If you are pulling in code from core Git, another project or code you've pulled from
+a forum / Stack Overflow then please flag this in your PR and also make sure you've
+given proper credit to the original author in the code snippet.
+
## Style Guide
`libgit2` is written in [ANSI C](http://en.wikipedia.org/wiki/ANSI_C)
diff --git a/README.md b/README.md
index a2a18765a..3e08ac3ea 100644
--- a/README.md
+++ b/README.md
@@ -11,20 +11,23 @@ libgit2 is licensed under a **very permissive license** (GPLv2 with a special Li
This basically means that you can link it (unmodified) with any kind of software without having to
release its source code.
-* Mailing list: ~~<libgit2@librelist.org>~~
- The libgit2 mailing list has
- traditionally been hosted in Librelist, but Librelist is and has always
- been a shitshow. We encourage you to [open an issue](https://github.com/libgit2/libgit2/issues)
- on GitHub instead for any questions regarding the library.
- * Archives: <http://librelist.com/browser/libgit2/>
* Website: <http://libgit2.github.com>
+* StackOverflow Tag: [libgit2](http://stackoverflow.com/questions/tagged/libgit2)
+* Issues: <https://github.com/libgit2/libgit2/issues>
* API documentation: <http://libgit2.github.com/libgit2>
* IRC: #libgit2 on irc.freenode.net.
+* Mailing list: The libgit2 mailing list was
+ traditionally hosted in Librelist but has been deprecated. We encourage you to
+ [use StackOverflow](http://stackoverflow.com/questions/tagged/libgit2) or [open an issue](https://github.com/libgit2/libgit2/issues)
+ on GitHub instead for any questions regarding the library. The mailing list archives are still available at
+ <http://librelist.com/browser/libgit2/>.
+
What It Can Do
==================================
-libgit2 is already very usable.
+libgit2 is already very usable and is being used in production for many applications including the GitHub.com site, in Plastic SCM
+and also powering Microsoft's Visual Studio tools for Git. The library provides:
* SHA conversions, formatting and shortening
* abstracted ODB backend system
@@ -128,8 +131,8 @@ Here are the bindings to libgit2 that are currently available:
* Lua
* luagit2 <https://github.com/libgit2/luagit2>
* .NET
- * libgit2net, low level bindings <https://github.com/txdv/libgit2net>
* libgit2sharp <https://github.com/libgit2/libgit2sharp>
+ * libgit2net, low level bindings superceeded by libgit2sharp <https://github.com/txdv/libgit2net>
* Node.js
* node-gitteh <https://github.com/libgit2/node-gitteh>
* nodegit <https://github.com/tbranyen/nodegit>
diff --git a/include/git2/object.h b/include/git2/object.h
index b91b04dba..f74f3dfd1 100644
--- a/include/git2/object.h
+++ b/include/git2/object.h
@@ -36,7 +36,7 @@ GIT_BEGIN_DECL
* @param repo the repository to look up the object
* @param id the unique identifier for the object
* @param type the type of the object
- * @return a reference to the object
+ * @return 0 or an error code
*/
GIT_EXTERN(int) git_object_lookup(
git_object **object,
diff --git a/include/git2/remote.h b/include/git2/remote.h
index 45d15d0a3..13b04367c 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -96,6 +96,14 @@ GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const ch
GIT_EXTERN(int) git_remote_save(const git_remote *remote);
/**
+ * Get the remote's repository
+ *
+ * @param remote the remote
+ * @return a pointer to the repository
+ */
+GIT_EXTERN(git_repository *) git_remote_owner(const git_remote *remote);
+
+/**
* Get the remote's name
*
* @param remote the remote
diff --git a/include/git2/tree.h b/include/git2/tree.h
index 65d8cc16e..f1e7d0899 100644
--- a/include/git2/tree.h
+++ b/include/git2/tree.h
@@ -208,7 +208,7 @@ GIT_EXTERN(git_filemode_t) git_tree_entry_filemode(const git_tree_entry *entry);
GIT_EXTERN(int) git_tree_entry_cmp(const git_tree_entry *e1, const git_tree_entry *e2);
/**
- * Convert a tree entry to the git_object it points too.
+ * Convert a tree entry to the git_object it points to.
*
* You must call `git_object_free()` on the object when you are done with it.
*
diff --git a/src/diff_tform.c b/src/diff_tform.c
index b137bd319..ac5356a8c 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -590,11 +590,13 @@ static bool is_rename_target(
return false;
case GIT_DELTA_UNTRACKED:
- case GIT_DELTA_IGNORED:
if (!FLAG_SET(opts, GIT_DIFF_FIND_FOR_UNTRACKED))
return false;
break;
+ case GIT_DELTA_IGNORED:
+ return false;
+
default: /* all other status values should be checked */
break;
}
diff --git a/src/index.c b/src/index.c
index bd5e192f3..0610eb5b9 100644
--- a/src/index.c
+++ b/src/index.c
@@ -1409,14 +1409,18 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
if (git__strtol32(&tmp, buffer, &endptr, 8) < 0 ||
!endptr || endptr == buffer || *endptr ||
- (unsigned)tmp > UINT_MAX)
+ (unsigned)tmp > UINT_MAX) {
+ index_entry_reuc_free(lost);
return index_error_invalid("reading reuc entry stage");
+ }
lost->mode[i] = tmp;
len = (endptr + 1) - buffer;
- if (size <= len)
+ if (size <= len) {
+ index_entry_reuc_free(lost);
return index_error_invalid("reading reuc entry stage");
+ }
size -= len;
buffer += len;
@@ -1426,8 +1430,10 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
for (i = 0; i < 3; i++) {
if (!lost->mode[i])
continue;
- if (size < 20)
+ if (size < 20) {
+ index_entry_reuc_free(lost);
return index_error_invalid("reading reuc entry oid");
+ }
git_oid_fromraw(&lost->oid[i], (const unsigned char *) buffer);
size -= 20;
diff --git a/src/indexer.c b/src/indexer.c
index 1b638cd8a..09f962934 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -325,7 +325,7 @@ static int hash_and_save(git_indexer_stream *idx, git_rawobj *obj, git_off_t ent
/* FIXME: Parse the object instead of hashing it */
if (git_odb__hashobj(&oid, obj) < 0) {
giterr_set(GITERR_INDEXER, "Failed to hash object");
- return -1;
+ goto on_error;
}
pentry = git__calloc(1, sizeof(struct git_pack_entry));
diff --git a/src/merge.c b/src/merge.c
index 82d2e6f37..2e94ce1cd 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -1902,8 +1902,10 @@ static int write_merge_msg(
entries = git__calloc(heads_len, sizeof(struct merge_msg_entry));
GITERR_CHECK_ALLOC(entries);
- if (git_vector_init(&matching, heads_len, NULL) < 0)
+ if (git_vector_init(&matching, heads_len, NULL) < 0) {
+ git__free(entries);
return -1;
+ }
for (i = 0; i < heads_len; i++)
entries[i].merge_head = heads[i];
diff --git a/src/odb.c b/src/odb.c
index 8e62efd00..23eb4e12e 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -232,6 +232,7 @@ int git_odb__hashlink(git_oid *out, const char *path)
link_data[size] = '\0';
if (read_len != (ssize_t)size) {
giterr_set(GITERR_OS, "Failed to read symlink data for '%s'", path);
+ git__free(link_data);
return -1;
}
diff --git a/src/pack-objects.c b/src/pack-objects.c
index 500104c55..7f427e3bd 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -505,8 +505,10 @@ static git_pobject **compute_write_order(git_packbuilder *pb)
/*
* Mark objects that are at the tip of tags.
*/
- if (git_tag_foreach(pb->repo, &cb_tag_foreach, pb) < 0)
+ if (git_tag_foreach(pb->repo, &cb_tag_foreach, pb) < 0) {
+ git__free(wo);
return NULL;
+ }
/*
* Give the objects in the original recency order until
diff --git a/src/pack.c b/src/pack.c
index 7ce7099e0..497db38e8 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -329,8 +329,10 @@ static int pack_index_open(struct git_pack_file *p)
memcpy(idx_name, p->pack_name, base_len);
memcpy(idx_name + base_len, ".idx", sizeof(".idx"));
- if ((error = git_mutex_lock(&p->lock)) < 0)
+ if ((error = git_mutex_lock(&p->lock)) < 0) {
+ git__free(idx_name);
return error;
+ }
if (p->index_version == -1)
error = pack_index_check(idx_name, p);
diff --git a/src/remote.c b/src/remote.c
index 0e8354a11..158f3e938 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -467,6 +467,12 @@ const char *git_remote_name(const git_remote *remote)
return remote->name;
}
+git_repository *git_remote_owner(const git_remote *remote)
+{
+ assert(remote);
+ return remote->repo;
+}
+
const char *git_remote_url(const git_remote *remote)
{
assert(remote);
diff --git a/src/repository.c b/src/repository.c
index bd7ef5476..99ac56ef9 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -1500,12 +1500,12 @@ int git_repository_is_empty(git_repository *repo)
if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0)
return -1;
- if (!(error = git_reference_type(head) == GIT_REF_SYMBOLIC))
+ if (!((error = git_reference_type(head)) == GIT_REF_SYMBOLIC))
goto cleanup;
- if (!(error = strcmp(
+ if (!(error = (strcmp(
git_reference_symbolic_target(head),
- GIT_REFS_HEADS_DIR "master") == 0))
+ GIT_REFS_HEADS_DIR "master") == 0)))
goto cleanup;
error = repo_contains_no_reference(repo);
diff --git a/src/revparse.c b/src/revparse.c
index bcfb0843f..d21f08b53 100644
--- a/src/revparse.c
+++ b/src/revparse.c
@@ -685,6 +685,8 @@ int revparse__ext(
git_reference *reference = NULL;
git_object *base_rev = NULL;
+ bool should_return_reference = true;
+
assert(object_out && reference_out && repo && spec);
*object_out = NULL;
@@ -693,6 +695,8 @@ int revparse__ext(
while (spec[pos]) {
switch (spec[pos]) {
case '^':
+ should_return_reference = false;
+
if ((error = ensure_base_rev_loaded(&base_rev, &reference, spec, identifier_len, repo, false)) < 0)
goto cleanup;
@@ -725,6 +729,8 @@ int revparse__ext(
{
git_object *temp_object = NULL;
+ should_return_reference = false;
+
if ((error = extract_how_many(&n, spec, &pos)) < 0)
goto cleanup;
@@ -743,6 +749,8 @@ int revparse__ext(
{
git_object *temp_object = NULL;
+ should_return_reference = false;
+
if ((error = extract_path(&buf, spec, &pos)) < 0)
goto cleanup;
@@ -807,6 +815,11 @@ int revparse__ext(
if ((error = ensure_base_rev_loaded(&base_rev, &reference, spec, identifier_len, repo, false)) < 0)
goto cleanup;
+ if (!should_return_reference) {
+ git_reference_free(reference);
+ reference = NULL;
+ }
+
*object_out = base_rev;
*reference_out = reference;
*identifier_len_out = identifier_len;
diff --git a/tests-clar/refs/revparse.c b/tests-clar/refs/revparse.c
index 69d92745c..9657054de 100644
--- a/tests-clar/refs/revparse.c
+++ b/tests-clar/refs/revparse.c
@@ -738,4 +738,45 @@ void test_refs_revparse__ext_can_expand_short_reference_names(void)
"master",
"a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
"refs/heads/master");
+
+ test_object_and_ref(
+ "HEAD",
+ "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+ "refs/heads/master");
+
+ test_object_and_ref(
+ "tags/test",
+ "b25fa35b38051e4ae45d4222e795f9df2e43f1d1",
+ "refs/tags/test");
+}
+
+void test_refs_revparse__ext_returns_NULL_reference_when_expression_points_at_a_revision(void)
+{
+ test_object_and_ref(
+ "HEAD~3",
+ "4a202b346bb0fb0db7eff3cffeb3c70babbd2045",
+ NULL);
+
+ test_object_and_ref(
+ "HEAD~0",
+ "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+ NULL);
+
+ test_object_and_ref(
+ "HEAD^0",
+ "a65fedf39aefe402d3bb6e24df4d4f5fe4547750",
+ NULL);
+
+ test_object_and_ref(
+ "@{-1}@{0}",
+ "a4a7dce85cf63874e984719f4fdd239f5145052f",
+ NULL);
+}
+
+void test_refs_revparse__ext_returns_NULL_reference_when_expression_points_at_a_tree_content(void)
+{
+ test_object_and_ref(
+ "tags/test:readme.txt",
+ "0266163a49e280c4f5ed1e08facd36a2bd716bcf",
+ NULL);
}