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
5f9f69d9
Commit
5f9f69d9
authored
Jan 30, 2013
by
Vicent Martí
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1297 from arrbee/diff-patch-line-totals
Add helper API for diff line stats from patch
parents
a8182d49
3bf68be4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
129 additions
and
1 deletions
+129
-1
include/git2/diff.h
+22
-0
src/buffer.h
+7
-0
src/diff_output.c
+33
-1
tests-clar/diff/patch.c
+67
-0
No files found.
include/git2/diff.h
View file @
5f9f69d9
...
...
@@ -704,6 +704,28 @@ GIT_EXTERN(size_t) git_diff_patch_num_hunks(
git_diff_patch
*
patch
);
/**
* Get line counts of each type in a patch.
*
* This helps imitate a diff --numstat type of output. For that purpose,
* you only need the `total_additions` and `total_deletions` values, but we
* include the `total_context` line count in case you want the total number
* of lines of diff output that will be generated.
*
* All outputs are optional. Pass NULL if you don't need a particular count.
*
* @param total_context Count of context lines in output, can be NULL.
* @param total_additions Count of addition lines in output, can be NULL.
* @param total_deletions Count of deletion lines in output, can be NULL.
* @param patch The git_diff_patch object
* @return Number of lines in hunk or -1 if invalid hunk index
*/
GIT_EXTERN
(
int
)
git_diff_patch_line_stats
(
size_t
*
total_context
,
size_t
*
total_additions
,
size_t
*
total_deletions
,
const
git_diff_patch
*
patch
);
/**
* Get the information about a hunk in a patch
*
* Given a patch and a hunk index into the patch, this returns detailed
...
...
src/buffer.h
View file @
5f9f69d9
...
...
@@ -134,6 +134,13 @@ GIT_INLINE(ssize_t) git_buf_rfind(git_buf *buf, char ch)
return
idx
;
}
GIT_INLINE
(
ssize_t
)
git_buf_find
(
git_buf
*
buf
,
char
ch
)
{
size_t
idx
=
0
;
while
(
idx
<
buf
->
size
&&
buf
->
ptr
[
idx
]
!=
ch
)
idx
++
;
return
(
idx
==
buf
->
size
)
?
-
1
:
(
ssize_t
)
idx
;
}
/* Remove whitespace from the end of the buffer */
void
git_buf_rtrim
(
git_buf
*
buf
);
...
...
src/diff_output.c
View file @
5f9f69d9
...
...
@@ -1501,6 +1501,39 @@ size_t git_diff_patch_num_hunks(git_diff_patch *patch)
return
patch
->
hunks_size
;
}
int
git_diff_patch_line_stats
(
size_t
*
total_ctxt
,
size_t
*
total_adds
,
size_t
*
total_dels
,
const
git_diff_patch
*
patch
)
{
size_t
totals
[
3
],
idx
;
memset
(
totals
,
0
,
sizeof
(
totals
));
for
(
idx
=
0
;
idx
<
patch
->
lines_size
;
++
idx
)
{
switch
(
patch
->
lines
[
idx
].
origin
)
{
case
GIT_DIFF_LINE_CONTEXT
:
totals
[
0
]
++
;
break
;
case
GIT_DIFF_LINE_ADDITION
:
totals
[
1
]
++
;
break
;
case
GIT_DIFF_LINE_DELETION
:
totals
[
2
]
++
;
break
;
default:
/* diff --stat and --numstat don't count EOFNL marks because
* they will always be paired with a ADDITION or DELETION line.
*/
break
;
}
}
if
(
total_ctxt
)
*
total_ctxt
=
totals
[
0
];
if
(
total_adds
)
*
total_adds
=
totals
[
1
];
if
(
total_dels
)
*
total_dels
=
totals
[
2
];
return
0
;
}
int
git_diff_patch_get_hunk
(
const
git_diff_range
**
range
,
const
char
**
header
,
...
...
@@ -1706,4 +1739,3 @@ int git_diff__paired_foreach(
return
0
;
}
tests-clar/diff/patch.c
View file @
5f9f69d9
...
...
@@ -235,3 +235,70 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
git_diff_list_free
(
diff
);
git_tree_free
(
head
);
}
static
void
check_single_patch_stats
(
git_repository
*
repo
,
size_t
hunks
,
size_t
adds
,
size_t
dels
)
{
git_diff_list
*
diff
;
git_diff_patch
*
patch
;
const
git_diff_delta
*
delta
;
size_t
actual_adds
,
actual_dels
;
cl_git_pass
(
git_diff_index_to_workdir
(
&
diff
,
repo
,
NULL
,
NULL
));
cl_assert_equal_i
(
1
,
(
int
)
git_diff_num_deltas
(
diff
));
cl_git_pass
(
git_diff_get_patch
(
&
patch
,
&
delta
,
diff
,
0
));
cl_assert_equal_i
(
GIT_DELTA_MODIFIED
,
(
int
)
delta
->
status
);
cl_assert_equal_i
(
hunks
,
(
int
)
git_diff_patch_num_hunks
(
patch
));
cl_git_pass
(
git_diff_patch_line_stats
(
NULL
,
&
actual_adds
,
&
actual_dels
,
patch
));
cl_assert_equal_i
(
adds
,
actual_adds
);
cl_assert_equal_i
(
dels
,
actual_dels
);
git_diff_patch_free
(
patch
);
git_diff_list_free
(
diff
);
}
void
test_diff_patch__line_counts_with_eofnl
(
void
)
{
git_buf
content
=
GIT_BUF_INIT
;
const
char
*
end
;
git_index
*
index
;
g_repo
=
cl_git_sandbox_init
(
"renames"
);
cl_git_pass
(
git_futils_readbuffer
(
&
content
,
"renames/songofseven.txt"
));
/* remove first line */
end
=
git_buf_cstr
(
&
content
)
+
git_buf_find
(
&
content
,
'\n'
)
+
1
;
git_buf_consume
(
&
content
,
end
);
cl_git_rewritefile
(
"renames/songofseven.txt"
,
content
.
ptr
);
check_single_patch_stats
(
g_repo
,
1
,
0
,
1
);
/* remove trailing whitespace */
git_buf_rtrim
(
&
content
);
cl_git_rewritefile
(
"renames/songofseven.txt"
,
content
.
ptr
);
check_single_patch_stats
(
g_repo
,
2
,
1
,
2
);
/* add trailing whitespace */
cl_git_pass
(
git_repository_index
(
&
index
,
g_repo
));
cl_git_pass
(
git_index_add_bypath
(
index
,
"songofseven.txt"
));
cl_git_pass
(
git_index_write
(
index
));
git_index_free
(
index
);
cl_git_pass
(
git_buf_putc
(
&
content
,
'\n'
));
cl_git_rewritefile
(
"renames/songofseven.txt"
,
content
.
ptr
);
check_single_patch_stats
(
g_repo
,
1
,
1
,
1
);
git_buf_free
(
&
content
);
}
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