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
06d41826
Commit
06d41826
authored
Feb 28, 2014
by
Vicent Marti
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2146 from libgit2/rb/diff-b2b
Add git_diff_buffers and git_patch_from_buffers
parents
1574d388
6789b7a7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
300 additions
and
318 deletions
+300
-318
examples/diff.c
+11
-7
include/git2/diff.h
+33
-0
include/git2/patch.h
+28
-0
src/diff_file.c
+15
-34
src/diff_file.h
+11
-9
src/diff_patch.c
+112
-118
tests/diff/blob.c
+90
-150
No files found.
examples/diff.c
View file @
06d41826
...
...
@@ -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
);
}
include/git2/diff.h
View file @
06d41826
...
...
@@ -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 @
06d41826
...
...
@@ -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/diff_file.c
View file @
06d41826
...
...
@@ -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 @
06d41826
...
...
@@ -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 @
06d41826
...
...
@@ -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/diff/blob.c
View file @
06d41826
...
...
@@ -51,6 +51,20 @@ void test_diff_blob__cleanup(void)
cl_git_sandbox_cleanup
();
}
static
void
assert_one_modified
(
int
hunks
,
int
lines
,
int
ctxt
,
int
adds
,
int
dels
,
diff_expects
*
exp
)
{
cl_assert_equal_i
(
1
,
exp
->
files
);
cl_assert_equal_i
(
1
,
exp
->
file_status
[
GIT_DELTA_MODIFIED
]);
cl_assert_equal_i
(
0
,
exp
->
files_binary
);
cl_assert_equal_i
(
hunks
,
exp
->
hunks
);
cl_assert_equal_i
(
lines
,
exp
->
lines
);
cl_assert_equal_i
(
ctxt
,
exp
->
line_ctxt
);
cl_assert_equal_i
(
adds
,
exp
->
line_adds
);
cl_assert_equal_i
(
dels
,
exp
->
line_dels
);
}
void
test_diff_blob__can_compare_text_blobs
(
void
)
{
git_blob
*
a
,
*
b
,
*
c
;
...
...
@@ -71,79 +85,81 @@ void test_diff_blob__can_compare_text_blobs(void)
/* Doing the equivalent of a `git diff -U1` on these files */
/* diff on tests/resources/attr/root_test1 */
memset
(
&
expected
,
0
,
sizeof
(
expected
));
cl_git_pass
(
git_diff_blobs
(
a
,
NULL
,
b
,
NULL
,
&
opts
,
diff_file_cb
,
diff_hunk_cb
,
diff_line_cb
,
&
expected
));
assert_one_modified
(
1
,
6
,
1
,
5
,
0
,
&
expected
);
cl_assert_equal_i
(
1
,
expected
.
files
);
cl_assert_equal_i
(
1
,
expected
.
file_status
[
GIT_DELTA_MODIFIED
]);
cl_assert_equal_i
(
0
,
expected
.
files_binary
);
cl_assert_equal_i
(
1
,
expected
.
hunks
);
cl_assert_equal_i
(
6
,
expected
.
lines
);
cl_assert_equal_i
(
1
,
expected
.
line_ctxt
);
cl_assert_equal_i
(
5
,
expected
.
line_adds
);
cl_assert_equal_i
(
0
,
expected
.
line_dels
);
/* same diff but use direct buffers */
memset
(
&
expected
,
0
,
sizeof
(
expected
));
cl_git_pass
(
git_diff_buffers
(
git_blob_rawcontent
(
a
),
(
size_t
)
git_blob_rawsize
(
a
),
NULL
,
git_blob_rawcontent
(
b
),
(
size_t
)
git_blob_rawsize
(
b
),
NULL
,
&
opts
,
diff_file_cb
,
diff_hunk_cb
,
diff_line_cb
,
&
expected
));
assert_one_modified
(
1
,
6
,
1
,
5
,
0
,
&
expected
);
/* diff on tests/resources/attr/root_test2 */
memset
(
&
expected
,
0
,
sizeof
(
expected
));
cl_git_pass
(
git_diff_blobs
(
b
,
NULL
,
c
,
NULL
,
&
opts
,
diff_file_cb
,
diff_hunk_cb
,
diff_line_cb
,
&
expected
));
cl_assert_equal_i
(
1
,
expected
.
files
);
cl_assert_equal_i
(
1
,
expected
.
file_status
[
GIT_DELTA_MODIFIED
]);
cl_assert_equal_i
(
0
,
expected
.
files_binary
);
cl_assert_equal_i
(
1
,
expected
.
hunks
);
cl_assert_equal_i
(
15
,
expected
.
lines
);
cl_assert_equal_i
(
3
,
expected
.
line_ctxt
);
cl_assert_equal_i
(
9
,
expected
.
line_adds
);
cl_assert_equal_i
(
3
,
expected
.
line_dels
);
assert_one_modified
(
1
,
15
,
3
,
9
,
3
,
&
expected
);
/* diff on tests/resources/attr/root_test3 */
memset
(
&
expected
,
0
,
sizeof
(
expected
));
cl_git_pass
(
git_diff_blobs
(
a
,
NULL
,
c
,
NULL
,
&
opts
,
diff_file_cb
,
diff_hunk_cb
,
diff_line_cb
,
&
expected
));
cl_assert_equal_i
(
1
,
expected
.
files
);
cl_assert_equal_i
(
1
,
expected
.
file_status
[
GIT_DELTA_MODIFIED
]);
cl_assert_equal_i
(
0
,
expected
.
files_binary
);
cl_assert_equal_i
(
1
,
expected
.
hunks
);
cl_assert_equal_i
(
13
,
expected
.
lines
);
cl_assert_equal_i
(
0
,
expected
.
line_ctxt
);
cl_assert_equal_i
(
12
,
expected
.
line_adds
);
cl_assert_equal_i
(
1
,
expected
.
line_dels
);
assert_one_modified
(
1
,
13
,
0
,
12
,
1
,
&
expected
);
memset
(
&
expected
,
0
,
sizeof
(
expected
));
cl_git_pass
(
git_diff_blobs
(
c
,
NULL
,
d
,
NULL
,
&
opts
,
diff_file_cb
,
diff_hunk_cb
,
diff_line_cb
,
&
expected
));
cl_assert_equal_i
(
1
,
expected
.
files
);
cl_assert_equal_i
(
1
,
expected
.
file_status
[
GIT_DELTA_MODIFIED
]);
cl_assert_equal_i
(
0
,
expected
.
files_binary
);
cl_assert_equal_i
(
2
,
expected
.
hunks
);
cl_assert_equal_i
(
14
,
expected
.
lines
);
cl_assert_equal_i
(
4
,
expected
.
line_ctxt
);
cl_assert_equal_i
(
6
,
expected
.
line_adds
);
cl_assert_equal_i
(
4
,
expected
.
line_dels
);
assert_one_modified
(
2
,
14
,
4
,
6
,
4
,
&
expected
);
git_blob_free
(
a
);
git_blob_free
(
b
);
git_blob_free
(
c
);
}
static
void
assert_patch_matches_blobs
(
git_patch
*
p
,
git_blob
*
a
,
git_blob
*
b
,
int
hunks
,
int
l0
,
int
l1
,
int
ctxt
,
int
adds
,
int
dels
)
{
const
git_diff_delta
*
delta
;
size_t
tc
,
ta
,
td
;
cl_assert
(
p
!=
NULL
);
delta
=
git_patch_get_delta
(
p
);
cl_assert
(
delta
!=
NULL
);
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_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_sz
(
git_blob_rawsize
(
b
),
delta
->
new_file
.
size
);
cl_assert_equal_i
(
hunks
,
(
int
)
git_patch_num_hunks
(
p
));
if
(
hunks
>
0
)
cl_assert_equal_i
(
l0
,
git_patch_num_lines_in_hunk
(
p
,
0
));
if
(
hunks
>
1
)
cl_assert_equal_i
(
l1
,
git_patch_num_lines_in_hunk
(
p
,
1
));
cl_git_pass
(
git_patch_line_stats
(
&
tc
,
&
ta
,
&
td
,
p
));
cl_assert_equal_i
(
ctxt
,
(
int
)
tc
);
cl_assert_equal_i
(
adds
,
(
int
)
ta
);
cl_assert_equal_i
(
dels
,
(
int
)
td
);
}
void
test_diff_blob__can_compare_text_blobs_with_patch
(
void
)
{
git_blob
*
a
,
*
b
,
*
c
;
git_oid
a_oid
,
b_oid
,
c_oid
;
git_patch
*
p
;
const
git_diff_delta
*
delta
;
size_t
tc
,
ta
,
td
;
/* tests/resources/attr/root_test1 */
cl_git_pass
(
git_oid_fromstrn
(
&
a_oid
,
"45141a79"
,
8
));
...
...
@@ -161,92 +177,22 @@ void test_diff_blob__can_compare_text_blobs_with_patch(void)
/* diff on tests/resources/attr/root_test1 */
cl_git_pass
(
git_patch_from_blobs
(
&
p
,
a
,
NULL
,
b
,
NULL
,
&
opts
));
cl_assert
(
p
!=
NULL
);
delta
=
git_patch_get_delta
(
p
);
cl_assert
(
delta
!=
NULL
);
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_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_sz
(
git_blob_rawsize
(
b
),
delta
->
new_file
.
size
);
cl_assert_equal_i
(
1
,
(
int
)
git_patch_num_hunks
(
p
));
cl_assert_equal_i
(
6
,
git_patch_num_lines_in_hunk
(
p
,
0
));
cl_git_pass
(
git_patch_line_stats
(
&
tc
,
&
ta
,
&
td
,
p
));
cl_assert_equal_i
(
1
,
(
int
)
tc
);
cl_assert_equal_i
(
5
,
(
int
)
ta
);
cl_assert_equal_i
(
0
,
(
int
)
td
);
assert_patch_matches_blobs
(
p
,
a
,
b
,
1
,
6
,
0
,
1
,
5
,
0
);
git_patch_free
(
p
);
/* diff on tests/resources/attr/root_test2 */
cl_git_pass
(
git_patch_from_blobs
(
&
p
,
b
,
NULL
,
c
,
NULL
,
&
opts
));
cl_assert
(
p
!=
NULL
);
delta
=
git_patch_get_delta
(
p
);
cl_assert
(
delta
!=
NULL
);
cl_assert_equal_i
(
GIT_DELTA_MODIFIED
,
delta
->
status
);
cl_assert
(
git_oid_equal
(
git_blob_id
(
b
),
&
delta
->
old_file
.
id
));
cl_assert_equal_sz
(
git_blob_rawsize
(
b
),
delta
->
old_file
.
size
);
cl_assert
(
git_oid_equal
(
git_blob_id
(
c
),
&
delta
->
new_file
.
id
));
cl_assert_equal_sz
(
git_blob_rawsize
(
c
),
delta
->
new_file
.
size
);
cl_assert_equal_i
(
1
,
(
int
)
git_patch_num_hunks
(
p
));
cl_assert_equal_i
(
15
,
git_patch_num_lines_in_hunk
(
p
,
0
));
cl_git_pass
(
git_patch_line_stats
(
&
tc
,
&
ta
,
&
td
,
p
));
cl_assert_equal_i
(
3
,
(
int
)
tc
);
cl_assert_equal_i
(
9
,
(
int
)
ta
);
cl_assert_equal_i
(
3
,
(
int
)
td
);
assert_patch_matches_blobs
(
p
,
b
,
c
,
1
,
15
,
0
,
3
,
9
,
3
);
git_patch_free
(
p
);
/* diff on tests/resources/attr/root_test3 */
cl_git_pass
(
git_patch_from_blobs
(
&
p
,
a
,
NULL
,
c
,
NULL
,
&
opts
));
cl_assert
(
p
!=
NULL
);
delta
=
git_patch_get_delta
(
p
);
cl_assert
(
delta
!=
NULL
);
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_sz
(
git_blob_rawsize
(
a
),
delta
->
old_file
.
size
);
cl_assert
(
git_oid_equal
(
git_blob_id
(
c
),
&
delta
->
new_file
.
id
));
cl_assert_equal_sz
(
git_blob_rawsize
(
c
),
delta
->
new_file
.
size
);
cl_git_pass
(
git_patch_line_stats
(
&
tc
,
&
ta
,
&
td
,
p
));
cl_assert_equal_i
(
0
,
(
int
)
tc
);
cl_assert_equal_i
(
12
,
(
int
)
ta
);
cl_assert_equal_i
(
1
,
(
int
)
td
);
assert_patch_matches_blobs
(
p
,
a
,
c
,
1
,
13
,
0
,
0
,
12
,
1
);
git_patch_free
(
p
);
/* one more */
cl_git_pass
(
git_patch_from_blobs
(
&
p
,
c
,
NULL
,
d
,
NULL
,
&
opts
));
cl_assert
(
p
!=
NULL
);
delta
=
git_patch_get_delta
(
p
);
cl_assert
(
delta
!=
NULL
);
cl_assert_equal_i
(
GIT_DELTA_MODIFIED
,
delta
->
status
);
cl_assert
(
git_oid_equal
(
git_blob_id
(
c
),
&
delta
->
old_file
.
id
));
cl_assert_equal_sz
(
git_blob_rawsize
(
c
),
delta
->
old_file
.
size
);
cl_assert
(
git_oid_equal
(
git_blob_id
(
d
),
&
delta
->
new_file
.
id
));
cl_assert_equal_sz
(
git_blob_rawsize
(
d
),
delta
->
new_file
.
size
);
cl_assert_equal_i
(
2
,
(
int
)
git_patch_num_hunks
(
p
));
cl_assert_equal_i
(
5
,
git_patch_num_lines_in_hunk
(
p
,
0
));
cl_assert_equal_i
(
9
,
git_patch_num_lines_in_hunk
(
p
,
1
));
cl_git_pass
(
git_patch_line_stats
(
&
tc
,
&
ta
,
&
td
,
p
));
cl_assert_equal_i
(
4
,
(
int
)
tc
);
cl_assert_equal_i
(
6
,
(
int
)
ta
);
cl_assert_equal_i
(
4
,
(
int
)
td
);
assert_patch_matches_blobs
(
p
,
c
,
d
,
2
,
5
,
9
,
4
,
6
,
4
);
git_patch_free
(
p
);
git_blob_free
(
a
);
...
...
@@ -656,14 +602,7 @@ void test_diff_blob__can_compare_blob_to_buffer(void)
/* diff from blob a to content of b */
quick_diff_blob_to_str
(
a
,
NULL
,
b_content
,
0
,
NULL
);
cl_assert_equal_i
(
1
,
expected
.
files
);
cl_assert_equal_i
(
1
,
expected
.
file_status
[
GIT_DELTA_MODIFIED
]);
cl_assert_equal_i
(
0
,
expected
.
files_binary
);
cl_assert_equal_i
(
1
,
expected
.
hunks
);
cl_assert_equal_i
(
6
,
expected
.
lines
);
cl_assert_equal_i
(
1
,
expected
.
line_ctxt
);
cl_assert_equal_i
(
5
,
expected
.
line_adds
);
cl_assert_equal_i
(
0
,
expected
.
line_dels
);
assert_one_modified
(
1
,
6
,
1
,
5
,
0
,
&
expected
);
/* diff from blob a to content of a */
opts
.
flags
|=
GIT_DIFF_INCLUDE_UNMODIFIED
;
...
...
@@ -910,14 +849,7 @@ void test_diff_blob__using_path_and_attributes(void)
changed
=
"Hello from the root
\n
More lines
\n
And more
\n
Go here
\n
"
;
quick_diff_blob_to_str
(
nonbin
,
NULL
,
changed
,
0
,
NULL
);
cl_assert_equal_i
(
1
,
expected
.
files
);
cl_assert_equal_i
(
1
,
expected
.
file_status
[
GIT_DELTA_MODIFIED
]);
cl_assert_equal_i
(
0
,
expected
.
files_binary
);
cl_assert_equal_i
(
1
,
expected
.
hunks
);
cl_assert_equal_i
(
3
,
expected
.
lines
);
cl_assert_equal_i
(
0
,
expected
.
line_ctxt
);
cl_assert_equal_i
(
3
,
expected
.
line_adds
);
cl_assert_equal_i
(
0
,
expected
.
line_dels
);
assert_one_modified
(
1
,
3
,
0
,
3
,
0
,
&
expected
);
quick_diff_blob_to_str
(
nonbin
,
"foo/bar.binary"
,
changed
,
0
,
NULL
);
cl_assert_equal_i
(
1
,
expected
.
files
);
...
...
@@ -925,29 +857,12 @@ void test_diff_blob__using_path_and_attributes(void)
cl_assert_equal_i
(
1
,
expected
.
files_binary
);
cl_assert_equal_i
(
0
,
expected
.
hunks
);
cl_assert_equal_i
(
0
,
expected
.
lines
);
cl_assert_equal_i
(
0
,
expected
.
line_ctxt
);
cl_assert_equal_i
(
0
,
expected
.
line_adds
);
cl_assert_equal_i
(
0
,
expected
.
line_dels
);
quick_diff_blob_to_str
(
nonbin
,
"foo/bar.textary"
,
changed
,
0
,
NULL
);
cl_assert_equal_i
(
1
,
expected
.
files
);
cl_assert_equal_i
(
1
,
expected
.
file_status
[
GIT_DELTA_MODIFIED
]);
cl_assert_equal_i
(
0
,
expected
.
files_binary
);
cl_assert_equal_i
(
1
,
expected
.
hunks
);
cl_assert_equal_i
(
3
,
expected
.
lines
);
cl_assert_equal_i
(
0
,
expected
.
line_ctxt
);
cl_assert_equal_i
(
3
,
expected
.
line_adds
);
cl_assert_equal_i
(
0
,
expected
.
line_dels
);
assert_one_modified
(
1
,
3
,
0
,
3
,
0
,
&
expected
);
quick_diff_blob_to_str
(
nonbin
,
"foo/bar.alphary"
,
changed
,
0
,
NULL
);
cl_assert_equal_i
(
1
,
expected
.
files
);
cl_assert_equal_i
(
1
,
expected
.
file_status
[
GIT_DELTA_MODIFIED
]);
cl_assert_equal_i
(
0
,
expected
.
files_binary
);
cl_assert_equal_i
(
1
,
expected
.
hunks
);
cl_assert_equal_i
(
3
,
expected
.
lines
);
cl_assert_equal_i
(
0
,
expected
.
line_ctxt
);
cl_assert_equal_i
(
3
,
expected
.
line_adds
);
cl_assert_equal_i
(
0
,
expected
.
line_dels
);
assert_one_modified
(
1
,
3
,
0
,
3
,
0
,
&
expected
);
cl_git_pass
(
git_patch_from_blob_and_buffer
(
&
p
,
nonbin
,
"zzz.normal"
,
changed
,
strlen
(
changed
),
NULL
,
&
opts
));
...
...
@@ -1066,3 +981,28 @@ void test_diff_blob__using_path_and_attributes(void)
git_blob_free
(
nonbin
);
git_blob_free
(
bin
);
}
void
test_diff_blob__can_compare_buffer_to_buffer
(
void
)
{
const
char
*
a
=
"a
\n
b
\n
c
\n
d
\n
e
\n
f
\n
g
\n
h
\n
i
\n
j
\n
"
;
const
char
*
b
=
"a
\n
B
\n
c
\n
d
\n
E
\n
F
\n
h
\n
j
\n
k
\n
"
;
opts
.
interhunk_lines
=
0
;
opts
.
context_lines
=
0
;
memset
(
&
expected
,
0
,
sizeof
(
expected
));
cl_git_pass
(
git_diff_buffers
(
a
,
strlen
(
a
),
NULL
,
b
,
strlen
(
b
),
NULL
,
&
opts
,
diff_file_cb
,
diff_hunk_cb
,
diff_line_cb
,
&
expected
));
assert_one_modified
(
4
,
9
,
0
,
4
,
5
,
&
expected
);
opts
.
flags
^=
GIT_DIFF_REVERSE
;
memset
(
&
expected
,
0
,
sizeof
(
expected
));
cl_git_pass
(
git_diff_buffers
(
a
,
strlen
(
a
),
NULL
,
b
,
strlen
(
b
),
NULL
,
&
opts
,
diff_file_cb
,
diff_hunk_cb
,
diff_line_cb
,
&
expected
));
assert_one_modified
(
4
,
9
,
0
,
5
,
4
,
&
expected
);
}
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