Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
b5212858
Commit
b5212858
authored
Mar 03, 2014
by
Miha
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'remotes/upstream/development' into development
parents
3536c168
494be429
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
372 additions
and
206 deletions
+372
-206
CONTRIBUTING.md
+1
-20
PROJECTS.md
+88
-0
README.md
+14
-11
examples/blame.c
+5
-0
examples/diff.c
+11
-7
git.git-authors
+0
-5
include/git2/blame.h
+3
-0
include/git2/diff.h
+33
-0
include/git2/patch.h
+28
-0
src/blame_git.c
+4
-2
src/branch.c
+13
-0
src/diff_file.c
+15
-34
src/diff_file.h
+11
-9
src/diff_patch.c
+112
-118
tests/blame/simple.c
+15
-0
tests/diff/blob.c
+0
-0
tests/refs/branches/create.c
+19
-0
No files found.
CONTRIBUTING.md
View file @
b5212858
...
...
@@ -101,23 +101,4 @@ at the
## Starter Projects
So, you want to start helping out with
`libgit2`
? That's fantastic? We
welcome contributions and we promise we'll try to be nice.
If you want to jump in, you can look at our issues list to see if there
are any unresolved issues to jump in on. Also, here is a list of some
smaller project ideas that could help you become familiar with the code
base and make a nice first step:
*
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
gaps right now and this helps demonstrate how to use the library.
*
Pick a Git command that is not emulates in
`examples/`
and write a new
example that mirrors the behavior. Examples don't have to be perfect
emulations, but should demonstrate how to use the libgit2 APIs to get
results that are similar to Git commands. This lets you (and us) easily
exercise a particular facet of the API and measure compatability and
feature parity with core git.
*
Submit a PR to clarify documentation! While we do try to document all of
the APIs, your fresh eyes on the documentation will find areas that are
confusing much more easily.
See our
[
projects list
](
https://github.com/libgit2/libgit2/blob/development/PROJECTS.md
)
.
PROJECTS.md
0 → 100644
View file @
b5212858
Projects For LibGit2
====================
So, you want to start helping out with
`libgit2`
? That's fantastic! We
welcome contributions and we promise we'll try to be nice.
This is a list of libgit2 related projects that new contributors can take
on. It includes a number of good starter projects and well as some larger
ideas that no one is actively working on.
## Before You Start
Please start by reading the README.md, CONTRIBUTING.md, and CONVENTIONS.md
files before diving into one of these projects. Those will explain our
work 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
repository, compile it, and run the tests successfully. That will make
sure that your development environment is set up correctly and you are
ready to start on libgit2 development.
## Starter Projects
These are good small projects to get started with libgit2.
*
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
gaps right now and this helps demonstrate how to use the library. Here
are some specific ideas:
*
Add the
`--minimal`
flag to
`examples/diff.c`
since the
`libgit2`
diff API now has a flag to support it
*
Add the
`--patience`
flag to
`examples/diff.c`
since it is also now
supported.
*
Add the
`--shortstat`
flag to
`examples/diff.c`
based on the work
that was done to add
`--numstat`
already.
*
Fix the
`examples/diff.c`
implementation of the
`-B`
(a.k.a.
`--break-rewrites`
) command line option to actually look for
the optional
`[<n>][/<m>]`
configuration values. There is an
existing comment that reads
`/* TODO: parse thresholds */`
. The
trick to this one will be doing it in a manner that is clean and
simple, but still handles the various cases correctly (e.g.
`-B/70%`
is apparently a legal setting).
*
Implement the
`--log-size`
option for
`examples/log.c`
. I think all
the data is available, you would just need to add the code into the
`print_commit()`
routine (along with a way of passing the option
into that function).
*
For
`examples/log.c`
, implement any one of
`--author=<...>`
,
`--committer=<...>`
, or
`--grep=<...>`
but just use simple string
match with
`strstr()`
instead of full regular expression
matching. (I.e. I'm suggesting implementing this as if
`--fixed-strings`
was always turned on, because it will be a simpler
project.)
*
As an extension to the matching idea for
`examples/log.c`
, add the
`-i`
option to use
`strcasestr()`
for matches.
*
For
`examples/log.c`
, implement the
`--first-parent`
option now that
libgit2 supports it in the revwalk API.
*
Pick a Git command that is not already emulated in
`examples/`
and write
a new example that mirrors the behavior. Examples don't have to be
perfect emulations, but should demonstrate how to use the libgit2 APIs
to get results that are similar to Git commands. This lets you (and us)
easily exercise a particular facet of the API and measure compatability
and feature parity with core git.
*
Submit a PR to clarify documentation! While we do try to document all of
the APIs, your fresh eyes on the documentation will find areas that are
confusing much more easily.
If none of these appeal to you, take a look at our issues list to see if
there are any unresolved issues you'd like to jump in on.
## Larger Projects
These are ideas for larger projects mostly taken from our backlog of
[
Issues
](
https://github.com/libgit2/libgit2/issues
)
. Please don't dive
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
projects above.
*
Port part of the Git test suite to run against the command line emulation
in examples/
*
Fix symlink support for files in the .git directory (i.e. don't overwrite
the symlinks when writing the file contents back out)
*
Implement a 'git describe' like API
*
Add hooks API to enumerate and manage hooks (not run them at this point)
*
Isolate logic of ignore evaluation into a standalone API
*
Upgrade internal libxdiff code to latest from core Git
*
Add a hashtable lookup for files in the index instead of binary search
every time
README.md
View file @
b5212858
...
...
@@ -4,9 +4,9 @@ libgit2 - the Git linkable library
[
![Build Status
](
https://secure.travis-ci.org/libgit2/libgit2.png?branch=development
)
](http://travis-ci.org/libgit2/libgit2)
[
![Coverity Scan Build Status
](
https://scan.coverity.com/projects/639/badge.svg
)
](https://scan.coverity.com/projects/639)
`libgit2`
is a portable, pure C implementation of the Git core methods
provided as a
re-entrant linkable library with a solid API, allowing you to write native
speed custom Git applications in any language with bindings.
`libgit2`
is a portable, pure C implementation of the Git core methods
provided as a re-entrant linkable library with a solid API, allowing you to
write native
speed custom Git applications in any language with bindings.
`libgit2`
is licensed under a
**very permissive license**
(GPLv2 with a special
Linking Exception). This basically means that you can link it (unmodified)
...
...
@@ -30,8 +30,9 @@ Additionally, the example code has been released to the public domain (see the
What It Can Do
==============
`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:
`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
...
...
@@ -199,14 +200,16 @@ we can add it to the list.
How Can I Contribute?
==================================
Check the [contribution guidelines](CONTRIBUTING.md).
Check the [contribution guidelines](CONTRIBUTING.md) to understand our
workflow, the libgit2 [coding conventions](CONVENTIONS.md), and out list of
[good starting projects](PROJECTS.md).
License
==================================
`
libgit2
`
is under GPL2
**with linking exemption**
. This means you
can link to and use the library from any program, proprietary or open source; paid
or gratis. However, you cannot modify libgit2 and distribute it without
`
libgit2
`
is under GPL2
**with linking exemption**
. This means you can link to
and use the library from any program, proprietary or open source; paid or
gratis. However, you cannot modify libgit2 and distribute it without
supplying the source.
See the
COPYING file
for the full license text.
See the
[
COPYING file
](
COPYING
)
for the full license text.
examples/blame.c
View file @
b5212858
...
...
@@ -31,6 +31,7 @@ struct opts {
int
M
;
int
start_line
;
int
end_line
;
int
F
;
};
static
void
parse_opts
(
struct
opts
*
o
,
int
argc
,
char
*
argv
[]);
...
...
@@ -52,6 +53,7 @@ int main(int argc, char *argv[])
parse_opts
(
&
o
,
argc
,
argv
);
if
(
o
.
M
)
blameopts
.
flags
|=
GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES
;
if
(
o
.
C
)
blameopts
.
flags
|=
GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES
;
if
(
o
.
F
)
blameopts
.
flags
|=
GIT_BLAME_FIRST_PARENT
;
/** Open the repository. */
check_lg2
(
git_repository_open_ext
(
&
repo
,
"."
,
0
,
NULL
),
"Couldn't open repository"
,
NULL
);
...
...
@@ -147,6 +149,7 @@ static void usage(const char *msg, const char *arg)
fprintf
(
stderr
,
" -L <n,m> process only line range n-m, counting from 1
\n
"
);
fprintf
(
stderr
,
" -M find line moves within and across files
\n
"
);
fprintf
(
stderr
,
" -C find line copies within and across files
\n
"
);
fprintf
(
stderr
,
" -F follow only the first parent commits
\n
"
);
fprintf
(
stderr
,
"
\n
"
);
exit
(
1
);
}
...
...
@@ -175,6 +178,8 @@ static void parse_opts(struct opts *o, int argc, char *argv[])
o
->
M
=
1
;
else
if
(
!
strcasecmp
(
a
,
"-C"
))
o
->
C
=
1
;
else
if
(
!
strcasecmp
(
a
,
"-F"
))
o
->
F
=
1
;
else
if
(
!
strcasecmp
(
a
,
"-L"
))
{
i
++
;
a
=
argv
[
i
];
if
(
i
>=
argc
)
fatal
(
"Not enough arguments to -L"
,
NULL
);
...
...
examples/diff.c
View file @
b5212858
...
...
@@ -269,19 +269,23 @@ static void diff_print_numstat(git_diff *diff)
{
git_patch
*
patch
;
const
git_diff_delta
*
delta
;
size_t
i
;
size_t
ndeltas
;
size_t
d
,
ndeltas
=
git_diff_num_deltas
(
diff
);
size_t
nadditions
,
ndeletions
;
ndeltas
=
git_diff_num_deltas
(
diff
);
for
(
i
=
0
;
i
<
ndeltas
;
i
++
){
for
(
d
=
0
;
d
<
ndeltas
;
d
++
){
check_lg2
(
git_patch_from_diff
(
&
patch
,
diff
,
i
),
git_patch_from_diff
(
&
patch
,
diff
,
d
),
"generating patch from diff"
,
NULL
);
check_lg2
(
git_patch_line_stats
(
NULL
,
&
nadditions
,
&
ndeletions
,
patch
),
"generating the number of additions and deletions"
,
NULL
);
delta
=
git_patch_get_delta
(
patch
);
printf
(
"%u
\t
%u
\t
%s
\n
"
,
nadditions
,
ndeletions
,
delta
->
new_file
.
path
);
printf
(
"%ld
\t
%ld
\t
%s
\n
"
,
(
long
)
nadditions
,
(
long
)
ndeletions
,
delta
->
new_file
.
path
);
git_patch_free
(
patch
);
}
git_patch_free
(
patch
);
}
git.git-authors
View file @
b5212858
...
...
@@ -28,9 +28,6 @@
# his/her consent on a patch-by-patch basis.
# "???" means the person is a prominent contributor who has
# not yet made his/her standpoint clear.
# "ign" means the authors consent is ignored for the purpose
# of libification. This is because the author has contributed
# to areas that aren't interesting for the library.
#
# Please try to keep the list alphabetically ordered. It will
# help in case we get all 600-ish git.git authors on it.
...
...
@@ -61,7 +58,6 @@ ok Linus Torvalds <torvalds@linux-foundation.org>
ok Lukas Sandström <lukass@etek.chalmers.se>
ok Matthieu Moy <Matthieu.Moy@imag.fr>
ok Michael Haggerty <mhagger@alum.mit.edu>
ign Mike McCormack <mike@codeweavers.com> (imap-send)
ok Nicolas Pitre <nico@fluxnic.net> <nico@cam.org>
ok Paolo Bonzini <bonzini@gnu.org>
ok Paul Kocher <paul@cryptography.com>
...
...
@@ -70,7 +66,6 @@ ok Petr Onderka <gsvick@gmail.com>
ok Pierre Habouzit <madcoder@debian.org>
ok Pieter de Bie <pdebie@ai.rug.nl>
ok René Scharfe <rene.scharfe@lsrfire.ath.cx>
ign Robert Shearman <rob@codeweavers.com> (imap-send)
ok Sebastian Schuberth <sschuberth@gmail.com>
ok Shawn O. Pearce <spearce@spearce.org>
ok Steffen Prohaska <prohaska@zib.de>
...
...
include/git2/blame.h
View file @
b5212858
...
...
@@ -40,6 +40,9 @@ typedef enum {
* commit (like `git blame -CCC`). Implies SAME_COMMIT_COPIES.
* NOT IMPLEMENTED. */
GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES
=
(
1
<<
3
),
/** Restrict the search of commits to those reachable following only the
* first parents. */
GIT_BLAME_FIRST_PARENT
=
(
1
<<
4
),
}
git_blame_flag_t
;
/**
...
...
include/git2/diff.h
View file @
b5212858
...
...
@@ -1013,6 +1013,39 @@ GIT_EXTERN(int) git_diff_blob_to_buffer(
git_diff_line_cb
line_cb
,
void
*
payload
);
/**
* Directly run a diff between two buffers.
*
* Even more than with `git_diff_blobs`, comparing two buffer lacks
* context, so the `git_diff_file` parameters to the callbacks will be
* faked a la the rules for `git_diff_blobs()`.
*
* @param old_buffer Raw data for old side of diff, or NULL for empty
* @param old_len Length of the raw data for old side of the diff
* @param old_as_path Treat old buffer as if it had this filename; can be NULL
* @param new_buffer Raw data for new side of diff, or NULL for empty
* @param new_len Length of raw data for new side of diff
* @param new_as_path Treat buffer as if it had this filename; can be NULL
* @param options Options for diff, or NULL for default options
* @param file_cb Callback for "file"; made once if there is a diff; can be NULL
* @param hunk_cb Callback for each hunk in diff; can be NULL
* @param line_cb Callback for each line in diff; can be NULL
* @param payload Payload passed to each callback function
* @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN
(
int
)
git_diff_buffers
(
const
void
*
old_buffer
,
size_t
old_len
,
const
char
*
old_as_path
,
const
void
*
new_buffer
,
size_t
new_len
,
const
char
*
new_as_path
,
const
git_diff_options
*
options
,
git_diff_file_cb
file_cb
,
git_diff_hunk_cb
hunk_cb
,
git_diff_line_cb
line_cb
,
void
*
payload
);
GIT_END_DECL
...
...
include/git2/patch.h
View file @
b5212858
...
...
@@ -106,6 +106,34 @@ GIT_EXTERN(int) git_patch_from_blob_and_buffer(
const
git_diff_options
*
opts
);
/**
* Directly generate a patch from the difference between two buffers.
*
* This is just like `git_diff_buffers()` except it generates a patch
* object for the difference instead of directly making callbacks. You can
* use the standard `git_patch` accessor functions to read the patch
* data, and you must call `git_patch_free()` on the patch when done.
*
* @param out The generated patch; NULL on error
* @param old_buffer Raw data for old side of diff, or NULL for empty
* @param old_len Length of the raw data for old side of the diff
* @param old_as_path Treat old buffer as if it had this filename; can be NULL
* @param new_buffer Raw data for new side of diff, or NULL for empty
* @param new_len Length of raw data for new side of diff
* @param new_as_path Treat buffer as if it had this filename; can be NULL
* @param opts Options for diff, or NULL for default options
* @return 0 on success or error code < 0
*/
GIT_EXTERN
(
int
)
git_patch_from_buffers
(
git_patch
**
out
,
const
void
*
old_buffer
,
size_t
old_len
,
const
char
*
old_as_path
,
const
char
*
new_buffer
,
size_t
new_len
,
const
char
*
new_as_path
,
const
git_diff_options
*
opts
);
/**
* Free a git_patch object.
*/
GIT_EXTERN
(
void
)
git_patch_free
(
git_patch
*
patch
);
...
...
src/blame_git.c
View file @
b5212858
...
...
@@ -485,12 +485,14 @@ static void pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt
git_blame__origin
*
sg_buf
[
16
];
git_blame__origin
*
porigin
,
**
sg_origin
=
sg_buf
;
GIT_UNUSED
(
opt
);
num_parents
=
git_commit_parentcount
(
commit
);
if
(
!
git_oid_cmp
(
git_commit_id
(
commit
),
&
blame
->
options
.
oldest_commit
))
/* Stop at oldest specified commit */
num_parents
=
0
;
else
if
(
opt
&
GIT_BLAME_FIRST_PARENT
&&
num_parents
>
1
)
/* Limit search to the first parent */
num_parents
=
1
;
if
(
!
num_parents
)
{
git_oid_cpy
(
&
blame
->
options
.
oldest_commit
,
git_commit_id
(
commit
));
goto
finish
;
...
...
src/branch.c
View file @
b5212858
...
...
@@ -58,6 +58,7 @@ int git_branch_create(
const
git_signature
*
signature
,
const
char
*
log_message
)
{
int
is_head
=
0
;
git_reference
*
branch
=
NULL
;
git_buf
canonical_branch_name
=
GIT_BUF_INIT
,
log_message_buf
=
GIT_BUF_INIT
;
...
...
@@ -65,7 +66,19 @@ int git_branch_create(
assert
(
branch_name
&&
commit
&&
ref_out
);
assert
(
git_object_owner
((
const
git_object
*
)
commit
)
==
repository
);
if
(
git_branch_lookup
(
&
branch
,
repository
,
branch_name
,
GIT_BRANCH_LOCAL
)
==
0
)
{
if
((
is_head
=
git_branch_is_head
(
branch
))
<
0
)
{
error
=
is_head
;
goto
cleanup
;
}
}
if
(
is_head
&&
force
)
{
giterr_set
(
GITERR_REFERENCE
,
"Cannot force update branch '%s' as it is "
"the current HEAD of the repository."
,
git_reference_name
(
branch
));
goto
cleanup
;
}
if
(
git_buf_joinpath
(
&
canonical_branch_name
,
GIT_REFS_HEADS_DIR
,
branch_name
)
<
0
)
goto
cleanup
;
...
...
src/diff_file.c
View file @
b5212858
...
...
@@ -127,57 +127,38 @@ int git_diff_file_content__init_from_diff(
return
diff_file_content_init_common
(
fc
,
&
diff
->
opts
);
}
int
git_diff_file_content__init_from_
blob
(
int
git_diff_file_content__init_from_
src
(
git_diff_file_content
*
fc
,
git_repository
*
repo
,
const
git_diff_options
*
opts
,
const
git_
blob
*
blob
,
const
git_
diff_file_content_src
*
src
,
git_diff_file
*
as_file
)
{
memset
(
fc
,
0
,
sizeof
(
*
fc
));
fc
->
repo
=
repo
;
fc
->
file
=
as_file
;
fc
->
blob
=
blob
;
fc
->
blob
=
src
->
blob
;
if
(
!
blob
)
{
if
(
!
src
->
blob
&&
!
src
->
buf
)
{
fc
->
flags
|=
GIT_DIFF_FLAG__NO_DATA
;
}
else
{
fc
->
flags
|=
GIT_DIFF_FLAG__LOADED
;
fc
->
file
->
flags
|=
GIT_DIFF_FLAG_VALID_ID
;
fc
->
file
->
size
=
git_blob_rawsize
(
blob
);
fc
->
file
->
mode
=
GIT_FILEMODE_BLOB
;
git_oid_cpy
(
&
fc
->
file
->
id
,
git_blob_id
(
blob
));
fc
->
map
.
len
=
(
size_t
)
fc
->
file
->
size
;
fc
->
map
.
data
=
(
char
*
)
git_blob_rawcontent
(
blob
);
}
if
(
src
->
blob
)
{
fc
->
file
->
size
=
git_blob_rawsize
(
src
->
blob
);
git_oid_cpy
(
&
fc
->
file
->
id
,
git_blob_id
(
src
->
blob
));
return
diff_file_content_init_common
(
fc
,
opts
);
}
fc
->
map
.
len
=
(
size_t
)
fc
->
file
->
size
;
fc
->
map
.
data
=
(
char
*
)
git_blob_rawcontent
(
src
->
blob
);
}
else
{
fc
->
file
->
size
=
src
->
buflen
;
git_odb_hash
(
&
fc
->
file
->
id
,
src
->
buf
,
src
->
buflen
,
GIT_OBJ_BLOB
);
int
git_diff_file_content__init_from_raw
(
git_diff_file_content
*
fc
,
git_repository
*
repo
,
const
git_diff_options
*
opts
,
const
char
*
buf
,
size_t
buflen
,
git_diff_file
*
as_file
)
{
memset
(
fc
,
0
,
sizeof
(
*
fc
));
fc
->
repo
=
repo
;
fc
->
file
=
as_file
;
if
(
!
buf
)
{
fc
->
flags
|=
GIT_DIFF_FLAG__NO_DATA
;
}
else
{
fc
->
flags
|=
GIT_DIFF_FLAG__LOADED
;
fc
->
file
->
flags
|=
GIT_DIFF_FLAG_VALID_ID
;
fc
->
file
->
size
=
buflen
;
fc
->
file
->
mode
=
GIT_FILEMODE_BLOB
;
git_odb_hash
(
&
fc
->
file
->
id
,
buf
,
buflen
,
GIT_OBJ_BLOB
);
fc
->
map
.
len
=
buflen
;
fc
->
map
.
data
=
(
char
*
)
buf
;
fc
->
map
.
len
=
src
->
buflen
;
fc
->
map
.
data
=
(
char
*
)
src
->
buf
;
}
}
return
diff_file_content_init_common
(
fc
,
opts
);
...
...
src/diff_file.h
View file @
b5212858
...
...
@@ -31,19 +31,21 @@ extern int git_diff_file_content__init_from_diff(
size_t
delta_index
,
bool
use_old
);
extern
int
git_diff_file_content__init_from_blob
(
git_diff_file_content
*
fc
,
git_repository
*
repo
,
const
git_diff_options
*
opts
,
const
git_blob
*
blob
,
git_diff_file
*
as_file
);
typedef
struct
{
const
git_blob
*
blob
;
const
void
*
buf
;
size_t
buflen
;
const
char
*
as_path
;
}
git_diff_file_content_src
;
#define GIT_DIFF_FILE_CONTENT_SRC__BLOB(BLOB,PATH) { (BLOB),NULL,0,(PATH) }
#define GIT_DIFF_FILE_CONTENT_SRC__BUF(BUF,LEN,PATH) { NULL,(BUF),(LEN),(PATH) }
extern
int
git_diff_file_content__init_from_
raw
(
extern
int
git_diff_file_content__init_from_
src
(
git_diff_file_content
*
fc
,
git_repository
*
repo
,
const
git_diff_options
*
opts
,
const
char
*
buf
,
size_t
buflen
,
const
git_diff_file_content_src
*
src
,
git_diff_file
*
as_file
);
/* this loads the blob/file-on-disk as needed */
...
...
src/diff_patch.c
View file @
b5212858
...
...
@@ -5,6 +5,7 @@
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "common.h"
#include "git2/blob.h"
#include "diff.h"
#include "diff_file.h"
#include "diff_driver.h"
...
...
@@ -334,38 +335,45 @@ static int diff_single_generate(diff_patch_with_delta *pd, git_xdiff_output *xo)
return
error
;
}
static
int
diff_patch_from_
blob
s
(
static
int
diff_patch_from_
source
s
(
diff_patch_with_delta
*
pd
,
git_xdiff_output
*
xo
,
const
git_blob
*
old_blob
,
const
char
*
old_path
,
const
git_blob
*
new_blob
,
const
char
*
new_path
,
git_diff_file_content_src
*
oldsrc
,
git_diff_file_content_src
*
newsrc
,
const
git_diff_options
*
opts
)
{
int
error
=
0
;
git_repository
*
repo
=
new_blob
?
git_object_owner
((
const
git_object
*
)
new_blob
)
:
old_blob
?
git_object_owner
((
const
git_object
*
)
old_blob
)
:
NULL
;
oldsrc
->
blob
?
git_blob_owner
(
oldsrc
->
blob
)
:
newsrc
->
blob
?
git_blob_owner
(
newsrc
->
blob
)
:
NULL
;
git_diff_file
*
lfile
=
&
pd
->
delta
.
old_file
,
*
rfile
=
&
pd
->
delta
.
new_file
;
git_diff_file_content
*
ldata
=
&
pd
->
patch
.
ofile
,
*
rdata
=
&
pd
->
patch
.
nfile
;
GITERR_CHECK_VERSION
(
opts
,
GIT_DIFF_OPTIONS_VERSION
,
"git_diff_options"
);
if
(
opts
&&
(
opts
->
flags
&
GIT_DIFF_REVERSE
)
!=
0
)
{
const
git_blob
*
tmp_blob
;
const
char
*
tmp_path
;
tmp_blob
=
old_blob
;
old_blob
=
new_blob
;
new_blob
=
tmp_blob
;
tmp_path
=
old_path
;
old_path
=
new_path
;
new_path
=
tmp_path
;
void
*
tmp
=
lfile
;
lfile
=
rfile
;
rfile
=
tmp
;
tmp
=
ldata
;
ldata
=
rdata
;
rdata
=
tmp
;
}
pd
->
patch
.
delta
=
&
pd
->
delta
;
pd
->
delta
.
old_file
.
path
=
old_path
;
pd
->
delta
.
new_file
.
path
=
new_path
;
if
(
!
oldsrc
->
as_path
)
{
if
(
newsrc
->
as_path
)
oldsrc
->
as_path
=
newsrc
->
as_path
;
else
oldsrc
->
as_path
=
newsrc
->
as_path
=
"file"
;
}
else
if
(
!
newsrc
->
as_path
)
newsrc
->
as_path
=
oldsrc
->
as_path
;
lfile
->
path
=
oldsrc
->
as_path
;
rfile
->
path
=
newsrc
->
as_path
;
if
((
error
=
git_diff_file_content__init_from_
blob
(
&
pd
->
patch
.
ofile
,
repo
,
opts
,
old_blob
,
&
pd
->
delta
.
old_
file
))
<
0
||
(
error
=
git_diff_file_content__init_from_
blob
(
&
pd
->
patch
.
nfile
,
repo
,
opts
,
new_blob
,
&
pd
->
delta
.
new_
file
))
<
0
)
if
((
error
=
git_diff_file_content__init_from_
src
(
ldata
,
repo
,
opts
,
oldsrc
,
l
file
))
<
0
||
(
error
=
git_diff_file_content__init_from_
src
(
rdata
,
repo
,
opts
,
newsrc
,
r
file
))
<
0
)
return
error
;
return
diff_single_generate
(
pd
,
xo
);
...
...
@@ -400,11 +408,9 @@ static int diff_patch_with_delta_alloc(
return
0
;
}
int
git_diff_blobs
(
const
git_blob
*
old_blob
,
const
char
*
old_path
,
const
git_blob
*
new_blob
,
const
char
*
new_path
,
static
int
diff_from_sources
(
git_diff_file_content_src
*
oldsrc
,
git_diff_file_content_src
*
newsrc
,
const
git_diff_options
*
opts
,
git_diff_file_cb
file_cb
,
git_diff_hunk_cb
hunk_cb
,
...
...
@@ -420,26 +426,19 @@ int git_diff_blobs(
&
xo
.
output
,
opts
,
file_cb
,
hunk_cb
,
data_cb
,
payload
);
git_xdiff_init
(
&
xo
,
opts
);
if
(
!
old_path
&&
new_path
)
old_path
=
new_path
;
else
if
(
!
new_path
&&
old_path
)
new_path
=
old_path
;
memset
(
&
pd
,
0
,
sizeof
(
pd
));
error
=
diff_patch_from_blobs
(
&
pd
,
&
xo
,
old_blob
,
old_path
,
new_blob
,
new_path
,
opts
);
error
=
diff_patch_from_sources
(
&
pd
,
&
xo
,
oldsrc
,
newsrc
,
opts
);
git_patch_free
(
&
pd
.
patch
);
return
error
;
}
int
git_patch_from_blob
s
(
static
int
patch_from_source
s
(
git_patch
**
out
,
const
git_blob
*
old_blob
,
const
char
*
old_path
,
const
git_blob
*
new_blob
,
const
char
*
new_path
,
git_diff_file_content_src
*
oldsrc
,
git_diff_file_content_src
*
newsrc
,
const
git_diff_options
*
opts
)
{
int
error
=
0
;
...
...
@@ -449,17 +448,15 @@ int git_patch_from_blobs(
assert
(
out
);
*
out
=
NULL
;
if
(
diff_patch_with_delta_alloc
(
&
pd
,
&
old_path
,
&
new_path
)
<
0
)
return
-
1
;
if
((
error
=
diff_patch_with_delta_alloc
(
&
pd
,
&
oldsrc
->
as_path
,
&
newsrc
->
as_path
))
<
0
)
return
error
;
memset
(
&
xo
,
0
,
sizeof
(
xo
));
diff_output_to_patch
(
&
xo
.
output
,
&
pd
->
patch
);
git_xdiff_init
(
&
xo
,
opts
);
error
=
diff_patch_from_blobs
(
pd
,
&
xo
,
old_blob
,
old_path
,
new_blob
,
new_path
,
opts
);
if
(
!
error
)
if
(
!
(
error
=
diff_patch_from_sources
(
pd
,
&
xo
,
oldsrc
,
newsrc
,
opts
)))
*
out
=
(
git_patch
*
)
pd
;
else
git_patch_free
((
git_patch
*
)
pd
);
...
...
@@ -467,46 +464,38 @@ int git_patch_from_blobs(
return
error
;
}
static
int
diff_patch_from_blob_and_buffer
(
diff_patch_with_delta
*
pd
,
git_xdiff_output
*
xo
,
int
git_diff_blobs
(
const
git_blob
*
old_blob
,
const
char
*
old_path
,
const
char
*
buf
,
size_t
buflen
,
const
char
*
buf_path
,
const
git_diff_options
*
opts
)
const
git_blob
*
new_blob
,
const
char
*
new_path
,
const
git_diff_options
*
opts
,
git_diff_file_cb
file_cb
,
git_diff_hunk_cb
hunk_cb
,
git_diff_line_cb
data_cb
,
void
*
payload
)
{
int
error
=
0
;
git_repository
*
repo
=
old_blob
?
git_object_owner
((
const
git_object
*
)
old_blob
)
:
NULL
;
GITERR_CHECK_VERSION
(
opts
,
GIT_DIFF_OPTIONS_VERSION
,
"git_diff_options"
);
pd
->
patch
.
delta
=
&
pd
->
delta
;
if
(
opts
&&
(
opts
->
flags
&
GIT_DIFF_REVERSE
)
!=
0
)
{
pd
->
delta
.
old_file
.
path
=
buf_path
;
pd
->
delta
.
new_file
.
path
=
old_path
;
if
(
!
(
error
=
git_diff_file_content__init_from_raw
(
&
pd
->
patch
.
ofile
,
repo
,
opts
,
buf
,
buflen
,
&
pd
->
delta
.
old_file
)))
error
=
git_diff_file_content__init_from_blob
(
&
pd
->
patch
.
nfile
,
repo
,
opts
,
old_blob
,
&
pd
->
delta
.
new_file
);
}
else
{
pd
->
delta
.
old_file
.
path
=
old_path
;
pd
->
delta
.
new_file
.
path
=
buf_path
;
if
(
!
(
error
=
git_diff_file_content__init_from_blob
(
&
pd
->
patch
.
ofile
,
repo
,
opts
,
old_blob
,
&
pd
->
delta
.
old_file
)))
error
=
git_diff_file_content__init_from_raw
(
&
pd
->
patch
.
nfile
,
repo
,
opts
,
buf
,
buflen
,
&
pd
->
delta
.
new_file
);
}
if
(
error
<
0
)
return
error
;
git_diff_file_content_src
osrc
=
GIT_DIFF_FILE_CONTENT_SRC__BLOB
(
old_blob
,
old_path
);
git_diff_file_content_src
nsrc
=
GIT_DIFF_FILE_CONTENT_SRC__BLOB
(
new_blob
,
new_path
);
return
diff_from_sources
(
&
osrc
,
&
nsrc
,
opts
,
file_cb
,
hunk_cb
,
data_cb
,
payload
);
}
return
diff_single_generate
(
pd
,
xo
);
int
git_patch_from_blobs
(
git_patch
**
out
,
const
git_blob
*
old_blob
,
const
char
*
old_path
,
const
git_blob
*
new_blob
,
const
char
*
new_path
,
const
git_diff_options
*
opts
)
{
git_diff_file_content_src
osrc
=
GIT_DIFF_FILE_CONTENT_SRC__BLOB
(
old_blob
,
old_path
);
git_diff_file_content_src
nsrc
=
GIT_DIFF_FILE_CONTENT_SRC__BLOB
(
new_blob
,
new_path
);
return
patch_from_sources
(
out
,
&
osrc
,
&
nsrc
,
opts
);
}
int
git_diff_blob_to_buffer
(
...
...
@@ -521,27 +510,12 @@ int git_diff_blob_to_buffer(
git_diff_line_cb
data_cb
,
void
*
payload
)
{
int
error
=
0
;
diff_patch_with_delta
pd
;
git_xdiff_output
xo
;
memset
(
&
xo
,
0
,
sizeof
(
xo
));
diff_output_init
(
&
xo
.
output
,
opts
,
file_cb
,
hunk_cb
,
data_cb
,
payload
);
git_xdiff_init
(
&
xo
,
opts
);
if
(
!
old_path
&&
buf_path
)
old_path
=
buf_path
;
else
if
(
!
buf_path
&&
old_path
)
buf_path
=
old_path
;
memset
(
&
pd
,
0
,
sizeof
(
pd
));
error
=
diff_patch_from_blob_and_buffer
(
&
pd
,
&
xo
,
old_blob
,
old_path
,
buf
,
buflen
,
buf_path
,
opts
);
git_patch_free
(
&
pd
.
patch
);
return
error
;
git_diff_file_content_src
osrc
=
GIT_DIFF_FILE_CONTENT_SRC__BLOB
(
old_blob
,
old_path
);
git_diff_file_content_src
nsrc
=
GIT_DIFF_FILE_CONTENT_SRC__BUF
(
buf
,
buflen
,
buf_path
);
return
diff_from_sources
(
&
osrc
,
&
nsrc
,
opts
,
file_cb
,
hunk_cb
,
data_cb
,
payload
);
}
int
git_patch_from_blob_and_buffer
(
...
...
@@ -553,29 +527,49 @@ int git_patch_from_blob_and_buffer(
const
char
*
buf_path
,
const
git_diff_options
*
opts
)
{
int
error
=
0
;
diff_patch_with_delta
*
pd
;
git_xdiff_output
xo
;
assert
(
out
);
*
out
=
NULL
;
if
(
diff_patch_with_delta_alloc
(
&
pd
,
&
old_path
,
&
buf_path
)
<
0
)
return
-
1
;
memset
(
&
xo
,
0
,
sizeof
(
xo
));
diff_output_to_patch
(
&
xo
.
output
,
&
pd
->
patch
);
git_xdiff_init
(
&
xo
,
opts
);
error
=
diff_patch_from_blob_and_buffer
(
pd
,
&
xo
,
old_blob
,
old_path
,
buf
,
buflen
,
buf_path
,
opts
);
git_diff_file_content_src
osrc
=
GIT_DIFF_FILE_CONTENT_SRC__BLOB
(
old_blob
,
old_path
);
git_diff_file_content_src
nsrc
=
GIT_DIFF_FILE_CONTENT_SRC__BUF
(
buf
,
buflen
,
buf_path
);
return
patch_from_sources
(
out
,
&
osrc
,
&
nsrc
,
opts
);
}
if
(
!
error
)
*
out
=
(
git_patch
*
)
pd
;
else
git_patch_free
((
git_patch
*
)
pd
);
int
git_diff_buffers
(
const
void
*
old_buf
,
size_t
old_len
,
const
char
*
old_path
,
const
void
*
new_buf
,
size_t
new_len
,
const
char
*
new_path
,
const
git_diff_options
*
opts
,
git_diff_file_cb
file_cb
,
git_diff_hunk_cb
hunk_cb
,
git_diff_line_cb
data_cb
,
void
*
payload
)
{
git_diff_file_content_src
osrc
=
GIT_DIFF_FILE_CONTENT_SRC__BUF
(
old_buf
,
old_len
,
old_path
);
git_diff_file_content_src
nsrc
=
GIT_DIFF_FILE_CONTENT_SRC__BUF
(
new_buf
,
new_len
,
new_path
);
return
diff_from_sources
(
&
osrc
,
&
nsrc
,
opts
,
file_cb
,
hunk_cb
,
data_cb
,
payload
);
}
return
error
;
int
git_patch_from_buffers
(
git_patch
**
out
,
const
void
*
old_buf
,
size_t
old_len
,
const
char
*
old_path
,
const
char
*
new_buf
,
size_t
new_len
,
const
char
*
new_path
,
const
git_diff_options
*
opts
)
{
git_diff_file_content_src
osrc
=
GIT_DIFF_FILE_CONTENT_SRC__BUF
(
old_buf
,
old_len
,
old_path
);
git_diff_file_content_src
nsrc
=
GIT_DIFF_FILE_CONTENT_SRC__BUF
(
new_buf
,
new_len
,
new_path
);
return
patch_from_sources
(
out
,
&
osrc
,
&
nsrc
,
opts
);
}
int
git_patch_from_diff
(
...
...
tests/blame/simple.c
View file @
b5212858
...
...
@@ -303,3 +303,18 @@ void test_blame_simple__can_restrict_to_newish_commits(void)
check_blame_hunk_index
(
g_repo
,
g_blame
,
0
,
1
,
1
,
1
,
"be3563a"
,
"branch_file.txt"
);
check_blame_hunk_index
(
g_repo
,
g_blame
,
1
,
2
,
1
,
0
,
"a65fedf"
,
"branch_file.txt"
);
}
void
test_blame_simple__can_restrict_to_first_parent_commits
(
void
)
{
git_blame_options
opts
=
GIT_BLAME_OPTIONS_INIT
;
opts
.
flags
|=
GIT_BLAME_FIRST_PARENT
;
cl_git_pass
(
git_repository_open
(
&
g_repo
,
cl_fixture
(
"blametest.git"
)));
cl_git_pass
(
git_blame_file
(
&
g_blame
,
g_repo
,
"b.txt"
,
&
opts
));
cl_assert_equal_i
(
4
,
git_blame_get_hunk_count
(
g_blame
));
check_blame_hunk_index
(
g_repo
,
g_blame
,
0
,
1
,
4
,
0
,
"da237394"
,
"b.txt"
);
check_blame_hunk_index
(
g_repo
,
g_blame
,
1
,
5
,
1
,
1
,
"b99f7ac0"
,
"b.txt"
);
check_blame_hunk_index
(
g_repo
,
g_blame
,
2
,
6
,
5
,
0
,
"63d671eb"
,
"b.txt"
);
check_blame_hunk_index
(
g_repo
,
g_blame
,
3
,
11
,
5
,
0
,
"bc7c5ac2"
,
"b.txt"
);
}
tests/diff/blob.c
View file @
b5212858
This diff is collapsed.
Click to expand it.
tests/refs/branches/create.c
View file @
b5212858
...
...
@@ -67,6 +67,25 @@ void test_refs_branches_create__can_force_create_over_an_existing_branch(void)
cl_assert_equal_s
(
"refs/heads/br2"
,
git_reference_name
(
branch
));
}
void
test_refs_branches_create__cannot_force_create_over_current_branch
(
void
)
{
const
git_oid
*
oid
;
git_reference
*
branch2
;
retrieve_known_commit
(
&
target
,
repo
);
cl_git_pass
(
git_branch_lookup
(
&
branch2
,
repo
,
"master"
,
GIT_BRANCH_LOCAL
));
cl_assert_equal_s
(
"refs/heads/master"
,
git_reference_name
(
branch2
));
cl_assert_equal_i
(
true
,
git_branch_is_head
(
branch2
));
oid
=
git_reference_target
(
branch2
);
cl_git_fail_with
(
-
1
,
git_branch_create
(
&
branch
,
repo
,
"master"
,
target
,
1
,
NULL
,
NULL
));
branch
=
NULL
;
cl_git_pass
(
git_branch_lookup
(
&
branch
,
repo
,
"master"
,
GIT_BRANCH_LOCAL
));
cl_assert_equal_s
(
"refs/heads/master"
,
git_reference_name
(
branch
));
cl_git_pass
(
git_oid_cmp
(
git_reference_target
(
branch
),
oid
));
git_reference_free
(
branch2
);
}
void
test_refs_branches_create__creating_a_branch_with_an_invalid_name_returns_EINVALIDSPEC
(
void
)
{
retrieve_known_commit
(
&
target
,
repo
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment