Skip to content

Commit

Permalink
Merge pull request #2261 from jacquesg/format-patch
Browse files Browse the repository at this point in the history
Support for format-patch
  • Loading branch information
Vicent Marti committed Apr 16, 2014
2 parents 3b2d14a + 39206ca commit c5cacc4
Show file tree
Hide file tree
Showing 102 changed files with 1,893 additions and 6 deletions.
173 changes: 173 additions & 0 deletions include/git2/diff.h
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,179 @@ GIT_EXTERN(int) git_diff_buffers(
git_diff_line_cb line_cb,
void *payload);

/**
* This is an opaque structure which is allocated by `git_diff_get_stats`.
* You are responsible for releasing the object memory when done, using the
* `git_diff_stats_free()` function.
*/
typedef struct git_diff_stats git_diff_stats;

/**
* Formatting options for diff stats
*/
typedef enum {
/** No stats*/
GIT_DIFF_STATS_NONE = 0,

/** Full statistics, equivalent of `--stat` */
GIT_DIFF_STATS_FULL = (1u << 0),

/** Short statistics, equivalent of `--shortstat` */
GIT_DIFF_STATS_SHORT = (1u << 1),

/** Number statistics, equivalent of `--numstat` */
GIT_DIFF_STATS_NUMBER = (1u << 2),

/** Extended header information such as creations, renames and mode changes, equivalent of `--summary` */
GIT_DIFF_STATS_INCLUDE_SUMMARY = (1u << 3),
} git_diff_stats_format_t;

/**
* Accumlate diff statistics for all patches.
*
* @param out Structure containg the diff statistics.
* @param diff A git_diff generated by one of the above functions.
* @return 0 on success; non-zero on error
*/
GIT_EXTERN(int) git_diff_get_stats(
git_diff_stats **out,
git_diff *diff);

/**
* Get the total number of files changed in a diff
*
* @param stats A `git_diff_stats` generated by one of the above functions.
* @return total number of files changed in the diff
*/
GIT_EXTERN(size_t) git_diff_stats_files_changed(
const git_diff_stats *stats);

/**
* Get the total number of insertions in a diff
*
* @param stats A `git_diff_stats` generated by one of the above functions.
* @return total number of insertions in the diff
*/
GIT_EXTERN(size_t) git_diff_stats_insertions(
const git_diff_stats *stats);

/**
* Get the total number of deletions in a diff
*
* @param stats A `git_diff_stats` generated by one of the above functions.
* @return total number of deletions in the diff
*/
GIT_EXTERN(size_t) git_diff_stats_deletions(
const git_diff_stats *stats);

/**
* Print diff statistics to a `git_buf`.
*
* @param out buffer to store the formatted diff statistics in.
* @param stats A `git_diff_stats` generated by one of the above functions.
* @param format Formatting option.
* @return 0 on success; non-zero on error
*/
GIT_EXTERN(int) git_diff_stats_to_buf(
git_buf *out,
const git_diff_stats *stats,
git_diff_stats_format_t format);

/**
* Deallocate a `git_diff_stats`.
*
* @param stats The previously created statistics object;
* cannot be used after free.
*/
GIT_EXTERN(void) git_diff_stats_free(git_diff_stats *stats);

/**
* Formatting options for diff e-mail generation
*/
typedef enum {
/** Normal patch, the default */
GIT_DIFF_FORMAT_EMAIL_NONE = 0,

/** Don't insert "[PATCH]" in the subject header*/
GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER = (1 << 0),

} git_diff_format_email_flags_t;

/**
* Options for controlling the formatting of the generated e-mail.
*/
typedef struct {
unsigned int version;

git_diff_format_email_flags_t flags;

/** This patch number */
size_t patch_no;

/** Total number of patches in this series */
size_t total_patches;

/** id to use for the commit */
const git_oid *id;

/** Summary of the change */
const char *summary;

/** Author of the change */
const git_signature *author;
} git_diff_format_email_options;

#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION 1
#define GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT {GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION, 0, 1, 1, NULL, NULL, NULL}

/**
* Create an e-mail ready patch from a diff.
*
* @param out buffer to store the e-mail patch in
* @param diff containing the commit
* @param opts structure with options to influence content and formatting.
* @return 0 or an error code
*/
GIT_EXTERN(int) git_diff_format_email(
git_buf *out,
git_diff *diff,
const git_diff_format_email_options *opts);

/**
* Create an e-mail ready patch for a commit.
*
* Does not support creating patches for merge commits (yet).
*
* @param out buffer to store the e-mail patch in
* @param repo containing the commit
* @param commit pointer to up commit
* @param patch_no patch number of the commit
* @param total_patches total number of patches in the patch set
* @param flags determines the formatting of the e-mail
* @param diff_opts structure with options to influence diff or NULL for defaults.
* @return 0 or an error code
*/
GIT_EXTERN(int) git_diff_commit_as_email(
git_buf *out,
git_repository *repo,
git_commit *commit,
size_t patch_no,
size_t total_patches,
git_diff_format_email_flags_t flags,
const git_diff_options *diff_opts);

/**
* Initializes a `git_diff_format_email_options` with default values. Equivalent to
* creating an instance with GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT.
*
* @param opts the `git_diff_format_email_options` instance to initialize.
* @param version the version of the struct; you should pass
* `GIT_DIFF_FORMAT_EMAIL_OPTIONS_VERSION` here.
* @return Zero on success; -1 on failure.
*/
GIT_EXTERN(int) git_diff_format_email_init_options(
git_diff_format_email_options *opts,
int version);

GIT_END_DECL

Expand Down
6 changes: 3 additions & 3 deletions include/git2/patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,12 @@ GIT_EXTERN(void) git_patch_free(git_patch *patch);
/**
* Get the delta associated with a patch
*/
GIT_EXTERN(const git_diff_delta *) git_patch_get_delta(git_patch *patch);
GIT_EXTERN(const git_diff_delta *) git_patch_get_delta(const git_patch *patch);

/**
* Get the number of hunks in a patch
*/
GIT_EXTERN(size_t) git_patch_num_hunks(git_patch *patch);
GIT_EXTERN(size_t) git_patch_num_hunks(const git_patch *patch);

/**
* Get line counts of each type in a patch.
Expand Down Expand Up @@ -197,7 +197,7 @@ GIT_EXTERN(int) git_patch_get_hunk(
* @return Number of lines in hunk or -1 if invalid hunk index
*/
GIT_EXTERN(int) git_patch_num_lines_in_hunk(
git_patch *patch,
const git_patch *patch,
size_t hunk_idx);

/**
Expand Down
9 changes: 9 additions & 0 deletions src/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ int git_buf_putc(git_buf *buf, char c)
return 0;
}

int git_buf_putcn(git_buf *buf, char c, size_t len)
{
ENSURE_SIZE(buf, buf->size + len + 1);
memset(buf->ptr + buf->size, c, len);
buf->size += len;
buf->ptr[buf->size] = '\0';
return 0;
}

int git_buf_put(git_buf *buf, const char *data, size_t len)
{
ENSURE_SIZE(buf, buf->size + len + 1);
Expand Down
1 change: 1 addition & 0 deletions src/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ GIT_INLINE(bool) git_buf_oom(const git_buf *buf)
*/
int git_buf_sets(git_buf *buf, const char *string);
int git_buf_putc(git_buf *buf, char c);
int git_buf_putcn(git_buf *buf, char c, size_t len);
int git_buf_put(git_buf *buf, const char *data, size_t len);
int git_buf_puts(git_buf *buf, const char *string);
int git_buf_printf(git_buf *buf, const char *format, ...) GIT_FORMAT_PRINTF(2, 3);
Expand Down
28 changes: 28 additions & 0 deletions src/date.c
Original file line number Diff line number Diff line change
Expand Up @@ -874,3 +874,31 @@ int git__date_parse(git_time_t *out, const char *date)
*out = approxidate_str(date, time_sec, &error_ret);
return error_ret;
}

int git__date_rfc2822_fmt(char *out, size_t len, const git_time *date)
{
int written;
struct tm gmt;
time_t t;

assert(out && date);

t = (time_t) (date->time + date->offset * 60);

if (p_gmtime_r (&t, &gmt) == NULL)
return -1;

written = p_snprintf(out, len, "%.3s, %u %.3s %.4u %02u:%02u:%02u %+03d%02d",
weekday_names[gmt.tm_wday],
gmt.tm_mday,
month_names[gmt.tm_mon],
gmt.tm_year + 1900,
gmt.tm_hour, gmt.tm_min, gmt.tm_sec,
date->offset / 60, date->offset % 60);

if (written < 0 || (written > (int) len - 1))
return -1;

return 0;
}

0 comments on commit c5cacc4

Please sign in to comment.