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
e30a6ee3
Commit
e30a6ee3
authored
Mar 20, 2017
by
Patrick Steinhardt
Committed by
GitHub
Mar 20, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4160 from pks-t/pks/diff-fixes
Diff fixes
parents
44b3b9fe
c0eba379
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
120 additions
and
82 deletions
+120
-82
src/diff.c
+35
-0
src/diff_parse.c
+3
-1
src/patch_generate.c
+8
-79
src/patch_parse.c
+3
-2
tests/diff/parse.c
+71
-0
No files found.
src/diff.c
View file @
e30a6ee3
...
...
@@ -120,6 +120,41 @@ int git_diff_get_perfdata(git_diff_perfdata *out, const git_diff *diff)
return
0
;
}
int
git_diff_foreach
(
git_diff
*
diff
,
git_diff_file_cb
file_cb
,
git_diff_binary_cb
binary_cb
,
git_diff_hunk_cb
hunk_cb
,
git_diff_line_cb
data_cb
,
void
*
payload
)
{
int
error
=
0
;
git_diff_delta
*
delta
;
size_t
idx
;
assert
(
diff
);
git_vector_foreach
(
&
diff
->
deltas
,
idx
,
delta
)
{
git_patch
*
patch
;
/* check flags against patch status */
if
(
git_diff_delta__should_skip
(
&
diff
->
opts
,
delta
))
continue
;
if
((
error
=
git_patch_from_diff
(
&
patch
,
diff
,
idx
))
!=
0
)
break
;
error
=
git_patch__invoke_callbacks
(
patch
,
file_cb
,
binary_cb
,
hunk_cb
,
data_cb
,
payload
);
git_patch_free
(
patch
);
if
(
error
)
break
;
}
return
error
;
}
int
git_diff_format_email__append_header_tobuf
(
git_buf
*
out
,
const
git_oid
*
id
,
...
...
src/diff_parse.c
View file @
e30a6ee3
...
...
@@ -37,7 +37,6 @@ static git_diff_parsed *diff_parsed_alloc(void)
GIT_REFCOUNT_INC
(
diff
);
diff
->
base
.
type
=
GIT_DIFF_TYPE_PARSED
;
diff
->
base
.
opts
.
flags
&=
~
GIT_DIFF_IGNORE_CASE
;
diff
->
base
.
strcomp
=
git__strcmp
;
diff
->
base
.
strncomp
=
git__strncmp
;
diff
->
base
.
pfxcomp
=
git__prefixcmp
;
...
...
@@ -45,6 +44,9 @@ static git_diff_parsed *diff_parsed_alloc(void)
diff
->
base
.
patch_fn
=
git_patch_parsed_from_diff
;
diff
->
base
.
free_fn
=
diff_parsed_free
;
git_diff_init_options
(
&
diff
->
base
.
opts
,
GIT_DIFF_OPTIONS_VERSION
);
diff
->
base
.
opts
.
flags
&=
~
GIT_DIFF_IGNORE_CASE
;
git_pool_init
(
&
diff
->
base
.
pool
,
1
);
if
(
git_vector_init
(
&
diff
->
patches
,
0
,
NULL
)
<
0
||
...
...
src/patch_generate.c
View file @
e30a6ee3
...
...
@@ -206,35 +206,14 @@ static int patch_generated_load(git_patch_generated *patch, git_patch_generated_
((
patch
->
nfile
.
flags
&
GIT_DIFF_FLAG__NO_DATA
)
!=
0
||
(
patch
->
nfile
.
file
->
flags
&
GIT_DIFF_FLAG_VALID_ID
)
!=
0
));
/* always try to load workdir content first because filtering may
* need 2x data size and this minimizes peak memory footprint
*/
if
(
patch
->
ofile
.
src
==
GIT_ITERATOR_TYPE_WORKDIR
)
{
if
((
error
=
git_diff_file_content__load
(
&
patch
->
ofile
,
&
patch
->
base
.
diff_opts
))
<
0
||
should_skip_binary
(
patch
,
patch
->
ofile
.
file
))
goto
cleanup
;
}
if
(
patch
->
nfile
.
src
==
GIT_ITERATOR_TYPE_WORKDIR
)
{
if
((
error
=
git_diff_file_content__load
(
&
patch
->
nfile
,
&
patch
->
base
.
diff_opts
))
<
0
||
should_skip_binary
(
patch
,
patch
->
nfile
.
file
))
goto
cleanup
;
}
/* once workdir has been tried, load other data as needed */
if
(
patch
->
ofile
.
src
!=
GIT_ITERATOR_TYPE_WORKDIR
)
{
if
((
error
=
git_diff_file_content__load
(
&
patch
->
ofile
,
&
patch
->
base
.
diff_opts
))
<
0
||
should_skip_binary
(
patch
,
patch
->
ofile
.
file
))
goto
cleanup
;
}
if
(
patch
->
nfile
.
src
!=
GIT_ITERATOR_TYPE_WORKDIR
)
{
if
((
error
=
git_diff_file_content__load
(
&
patch
->
nfile
,
&
patch
->
base
.
diff_opts
))
<
0
||
should_skip_binary
(
patch
,
patch
->
nfile
.
file
))
goto
cleanup
;
}
if
((
error
=
git_diff_file_content__load
(
&
patch
->
ofile
,
&
patch
->
base
.
diff_opts
))
<
0
||
should_skip_binary
(
patch
,
patch
->
ofile
.
file
))
goto
cleanup
;
if
((
error
=
git_diff_file_content__load
(
&
patch
->
nfile
,
&
patch
->
base
.
diff_opts
))
<
0
||
should_skip_binary
(
patch
,
patch
->
nfile
.
file
))
goto
cleanup
;
/* if previously missing an oid, and now that we have it the two sides
* are the same (and not submodules), update MODIFIED -> UNMODIFIED
...
...
@@ -421,56 +400,6 @@ static int diff_required(git_diff *diff, const char *action)
return
-
1
;
}
int
git_diff_foreach
(
git_diff
*
diff
,
git_diff_file_cb
file_cb
,
git_diff_binary_cb
binary_cb
,
git_diff_hunk_cb
hunk_cb
,
git_diff_line_cb
data_cb
,
void
*
payload
)
{
int
error
=
0
;
git_xdiff_output
xo
;
size_t
idx
;
git_patch_generated
patch
;
if
((
error
=
diff_required
(
diff
,
"git_diff_foreach"
))
<
0
)
return
error
;
memset
(
&
xo
,
0
,
sizeof
(
xo
));
memset
(
&
patch
,
0
,
sizeof
(
patch
));
diff_output_init
(
&
xo
.
output
,
&
diff
->
opts
,
file_cb
,
binary_cb
,
hunk_cb
,
data_cb
,
payload
);
git_xdiff_init
(
&
xo
,
&
diff
->
opts
);
git_vector_foreach
(
&
diff
->
deltas
,
idx
,
patch
.
base
.
delta
)
{
/* check flags against patch status */
if
(
git_diff_delta__should_skip
(
&
diff
->
opts
,
patch
.
base
.
delta
))
continue
;
if
(
binary_cb
||
hunk_cb
||
data_cb
)
{
if
((
error
=
patch_generated_init
(
&
patch
,
diff
,
idx
))
!=
0
||
(
error
=
patch_generated_load
(
&
patch
,
&
xo
.
output
))
!=
0
)
{
git_patch_free
(
&
patch
.
base
);
return
error
;
}
}
if
((
error
=
patch_generated_invoke_file_callback
(
&
patch
,
&
xo
.
output
))
==
0
)
{
if
(
binary_cb
||
hunk_cb
||
data_cb
)
error
=
patch_generated_create
(
&
patch
,
&
xo
.
output
);
}
git_patch_free
(
&
patch
.
base
);
if
(
error
)
break
;
}
return
error
;
}
typedef
struct
{
git_patch_generated
patch
;
git_diff_delta
delta
;
...
...
src/patch_parse.c
View file @
e30a6ee3
...
...
@@ -562,8 +562,9 @@ static int parse_hunk_body(
int
newlines
=
hunk
->
hunk
.
new_lines
;
for
(;
ctx
->
remain_len
>
4
&&
(
oldlines
||
newlines
)
&&
memcmp
(
ctx
->
line
,
"@@ -"
,
4
)
!=
0
;
ctx
->
remain_len
>
1
&&
(
oldlines
||
newlines
)
&&
(
ctx
->
remain_len
<=
4
||
memcmp
(
ctx
->
line
,
"@@ -"
,
4
)
!=
0
);
parse_advance_line
(
ctx
))
{
int
origin
;
...
...
tests/diff/parse.c
View file @
e30a6ee3
...
...
@@ -196,3 +196,74 @@ void test_diff_parse__get_patch_from_diff(void)
cl_git_sandbox_cleanup
();
}
static
int
file_cb
(
const
git_diff_delta
*
delta
,
float
progress
,
void
*
payload
)
{
int
*
called
=
(
int
*
)
payload
;
GIT_UNUSED
(
delta
);
GIT_UNUSED
(
progress
);
(
*
called
)
++
;
return
0
;
}
void
test_diff_parse__foreach_works_with_parsed_patch
(
void
)
{
const
char
patch
[]
=
"diff --git a/obj1 b/obj2
\n
"
"index 1234567..7654321 10644
\n
"
"--- a/obj1
\n
"
"+++ b/obj2
\n
"
"@@ -1 +1 @@
\n
"
"-abcde
\n
"
"+12345
\n
"
;
int
called
=
0
;
git_diff
*
diff
;
cl_git_pass
(
git_diff_from_buffer
(
&
diff
,
patch
,
strlen
(
patch
)));
cl_git_pass
(
git_diff_foreach
(
diff
,
file_cb
,
NULL
,
NULL
,
NULL
,
&
called
));
cl_assert_equal_i
(
called
,
1
);
git_diff_free
(
diff
);
}
void
test_diff_parse__parsing_minimal_patch_succeeds
(
void
)
{
const
char
patch
[]
=
"diff --git a/obj1 b/obj2
\n
"
"index 1234567..7654321 10644
\n
"
"--- a/obj1
\n
"
"+++ b/obj2
\n
"
"@@ -1 +1 @@
\n
"
"-a
\n
"
"+
\n
"
;
git_buf
buf
=
GIT_BUF_INIT
;
git_diff
*
diff
;
cl_git_pass
(
git_diff_from_buffer
(
&
diff
,
patch
,
strlen
(
patch
)));
cl_git_pass
(
git_diff_to_buf
(
&
buf
,
diff
,
GIT_DIFF_FORMAT_PATCH
));
cl_assert_equal_s
(
patch
,
buf
.
ptr
);
git_diff_free
(
diff
);
git_buf_free
(
&
buf
);
}
void
test_diff_parse__patch_roundtrip_succeeds
(
void
)
{
const
char
buf1
[]
=
"a
\n
"
,
buf2
[]
=
"b
\n
"
;
git_buf
patchbuf
=
GIT_BUF_INIT
,
diffbuf
=
GIT_BUF_INIT
;
git_patch
*
patch
;
git_diff
*
diff
;
cl_git_pass
(
git_patch_from_buffers
(
&
patch
,
buf1
,
strlen
(
buf1
),
"obj1"
,
buf2
,
strlen
(
buf2
),
"obj2"
,
NULL
));
cl_git_pass
(
git_patch_to_buf
(
&
patchbuf
,
patch
));
cl_git_pass
(
git_diff_from_buffer
(
&
diff
,
patchbuf
.
ptr
,
patchbuf
.
size
));
cl_git_pass
(
git_diff_to_buf
(
&
diffbuf
,
diff
,
GIT_DIFF_FORMAT_PATCH
));
cl_assert_equal_s
(
patchbuf
.
ptr
,
diffbuf
.
ptr
);
git_patch_free
(
patch
);
git_diff_free
(
diff
);
git_buf_free
(
&
patchbuf
);
git_buf_free
(
&
diffbuf
);
}
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