mirror of
https://github.com/git/git.git
synced 2024-06-10 19:16:14 +02:00
Merge branch 'bc/append-signed-off-by'
Consolidate codepaths that inspect log-message-to-be and decide to add a new Signed-off-by line in various commands. * bc/append-signed-off-by: git-commit: populate the edit buffer with 2 blank lines before s-o-b Unify appending signoff in format-patch, commit and sequencer format-patch: update append_signoff prototype t4014: more tests about appending s-o-b lines sequencer.c: teach append_signoff to avoid adding a duplicate newline sequencer.c: teach append_signoff how to detect duplicate s-o-b sequencer.c: always separate "(cherry picked from" from commit body sequencer.c: require a conforming footer to be preceded by a blank line sequencer.c: recognize "(cherry picked from ..." as part of s-o-b footer t/t3511: add some tests of 'cherry-pick -s' functionality t/test-lib-functions.sh: allow to specify the tag name to test_commit commit, cherry-pick -s: remove broken support for multiline rfc2822 fields sequencer.c: rework search for start of footer to improve clarity
This commit is contained in:
commit
900c8ecb5c
|
@ -702,7 +702,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
|
||||||
previous = eol;
|
previous = eol;
|
||||||
}
|
}
|
||||||
|
|
||||||
append_signoff(&sb, ignore_footer);
|
append_signoff(&sb, ignore_footer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len)
|
if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len)
|
||||||
|
|
|
@ -1086,7 +1086,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||||
struct commit *origin = NULL, *head = NULL;
|
struct commit *origin = NULL, *head = NULL;
|
||||||
const char *in_reply_to = NULL;
|
const char *in_reply_to = NULL;
|
||||||
struct patch_ids ids;
|
struct patch_ids ids;
|
||||||
char *add_signoff = NULL;
|
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
int use_patch_format = 0;
|
int use_patch_format = 0;
|
||||||
int quiet = 0;
|
int quiet = 0;
|
||||||
|
@ -1193,16 +1192,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||||
rev.subject_prefix = strbuf_detach(&sprefix, NULL);
|
rev.subject_prefix = strbuf_detach(&sprefix, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_signoff) {
|
|
||||||
const char *committer;
|
|
||||||
const char *endpos;
|
|
||||||
committer = git_committer_info(IDENT_STRICT);
|
|
||||||
endpos = strchr(committer, '>');
|
|
||||||
if (!endpos)
|
|
||||||
die(_("bogus committer info %s"), committer);
|
|
||||||
add_signoff = xmemdupz(committer, endpos - committer + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < extra_hdr.nr; i++) {
|
for (i = 0; i < extra_hdr.nr; i++) {
|
||||||
strbuf_addstr(&buf, extra_hdr.items[i].string);
|
strbuf_addstr(&buf, extra_hdr.items[i].string);
|
||||||
strbuf_addch(&buf, '\n');
|
strbuf_addch(&buf, '\n');
|
||||||
|
@ -1393,7 +1382,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||||
total++;
|
total++;
|
||||||
start_number--;
|
start_number--;
|
||||||
}
|
}
|
||||||
rev.add_signoff = add_signoff;
|
rev.add_signoff = do_signoff;
|
||||||
while (0 <= --nr) {
|
while (0 <= --nr) {
|
||||||
int shown;
|
int shown;
|
||||||
commit = list[nr];
|
commit = list[nr];
|
||||||
|
|
92
log-tree.c
92
log-tree.c
|
@ -9,6 +9,7 @@
|
||||||
#include "string-list.h"
|
#include "string-list.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "gpg-interface.h"
|
#include "gpg-interface.h"
|
||||||
|
#include "sequencer.h"
|
||||||
|
|
||||||
struct decoration name_decoration = { "object names" };
|
struct decoration name_decoration = { "object names" };
|
||||||
|
|
||||||
|
@ -206,89 +207,6 @@ void show_decorations(struct rev_info *opt, struct commit *commit)
|
||||||
putchar(')');
|
putchar(')');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Search for "^[-A-Za-z]+: [^@]+@" pattern. It usually matches
|
|
||||||
* Signed-off-by: and Acked-by: lines.
|
|
||||||
*/
|
|
||||||
static int detect_any_signoff(char *letter, int size)
|
|
||||||
{
|
|
||||||
char *cp;
|
|
||||||
int seen_colon = 0;
|
|
||||||
int seen_at = 0;
|
|
||||||
int seen_name = 0;
|
|
||||||
int seen_head = 0;
|
|
||||||
|
|
||||||
cp = letter + size;
|
|
||||||
while (letter <= --cp && *cp == '\n')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
while (letter <= cp) {
|
|
||||||
char ch = *cp--;
|
|
||||||
if (ch == '\n')
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!seen_at) {
|
|
||||||
if (ch == '@')
|
|
||||||
seen_at = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!seen_colon) {
|
|
||||||
if (ch == '@')
|
|
||||||
return 0;
|
|
||||||
else if (ch == ':')
|
|
||||||
seen_colon = 1;
|
|
||||||
else
|
|
||||||
seen_name = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (('A' <= ch && ch <= 'Z') ||
|
|
||||||
('a' <= ch && ch <= 'z') ||
|
|
||||||
ch == '-') {
|
|
||||||
seen_head = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* no empty last line doesn't match */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return seen_head && seen_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void append_signoff(struct strbuf *sb, const char *signoff)
|
|
||||||
{
|
|
||||||
static const char signed_off_by[] = "Signed-off-by: ";
|
|
||||||
size_t signoff_len = strlen(signoff);
|
|
||||||
int has_signoff = 0;
|
|
||||||
char *cp;
|
|
||||||
|
|
||||||
cp = sb->buf;
|
|
||||||
|
|
||||||
/* First see if we already have the sign-off by the signer */
|
|
||||||
while ((cp = strstr(cp, signed_off_by))) {
|
|
||||||
|
|
||||||
has_signoff = 1;
|
|
||||||
|
|
||||||
cp += strlen(signed_off_by);
|
|
||||||
if (cp + signoff_len >= sb->buf + sb->len)
|
|
||||||
break;
|
|
||||||
if (strncmp(cp, signoff, signoff_len))
|
|
||||||
continue;
|
|
||||||
if (!isspace(cp[signoff_len]))
|
|
||||||
continue;
|
|
||||||
/* we already have him */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!has_signoff)
|
|
||||||
has_signoff = detect_any_signoff(sb->buf, sb->len);
|
|
||||||
|
|
||||||
if (!has_signoff)
|
|
||||||
strbuf_addch(sb, '\n');
|
|
||||||
|
|
||||||
strbuf_addstr(sb, signed_off_by);
|
|
||||||
strbuf_add(sb, signoff, signoff_len);
|
|
||||||
strbuf_addch(sb, '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int digits_in_number(unsigned int number)
|
static unsigned int digits_in_number(unsigned int number)
|
||||||
{
|
{
|
||||||
unsigned int i = 10, result = 1;
|
unsigned int i = 10, result = 1;
|
||||||
|
@ -669,8 +587,10 @@ void show_log(struct rev_info *opt)
|
||||||
/*
|
/*
|
||||||
* And then the pretty-printed message itself
|
* And then the pretty-printed message itself
|
||||||
*/
|
*/
|
||||||
if (ctx.need_8bit_cte >= 0)
|
if (ctx.need_8bit_cte >= 0 && opt->add_signoff)
|
||||||
ctx.need_8bit_cte = has_non_ascii(opt->add_signoff);
|
ctx.need_8bit_cte =
|
||||||
|
has_non_ascii(fmt_name(getenv("GIT_COMMITTER_NAME"),
|
||||||
|
getenv("GIT_COMMITTER_EMAIL")));
|
||||||
ctx.date_mode = opt->date_mode;
|
ctx.date_mode = opt->date_mode;
|
||||||
ctx.date_mode_explicit = opt->date_mode_explicit;
|
ctx.date_mode_explicit = opt->date_mode_explicit;
|
||||||
ctx.abbrev = opt->diffopt.abbrev;
|
ctx.abbrev = opt->diffopt.abbrev;
|
||||||
|
@ -683,7 +603,7 @@ void show_log(struct rev_info *opt)
|
||||||
pretty_print_commit(&ctx, commit, &msgbuf);
|
pretty_print_commit(&ctx, commit, &msgbuf);
|
||||||
|
|
||||||
if (opt->add_signoff)
|
if (opt->add_signoff)
|
||||||
append_signoff(&msgbuf, opt->add_signoff);
|
append_signoff(&msgbuf, 0, APPEND_SIGNOFF_DEDUP);
|
||||||
|
|
||||||
if ((ctx.fmt != CMIT_FMT_USERFORMAT) &&
|
if ((ctx.fmt != CMIT_FMT_USERFORMAT) &&
|
||||||
ctx.notes_message && *ctx.notes_message) {
|
ctx.notes_message && *ctx.notes_message) {
|
||||||
|
|
|
@ -138,7 +138,7 @@ struct rev_info {
|
||||||
int reroll_count;
|
int reroll_count;
|
||||||
char *message_id;
|
char *message_id;
|
||||||
struct string_list *ref_message_ids;
|
struct string_list *ref_message_ids;
|
||||||
const char *add_signoff;
|
int add_signoff;
|
||||||
const char *extra_headers;
|
const char *extra_headers;
|
||||||
const char *log_reencode;
|
const char *log_reencode;
|
||||||
const char *subject_prefix;
|
const char *subject_prefix;
|
||||||
|
|
192
sequencer.c
192
sequencer.c
|
@ -18,6 +18,89 @@
|
||||||
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
|
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
|
||||||
|
|
||||||
const char sign_off_header[] = "Signed-off-by: ";
|
const char sign_off_header[] = "Signed-off-by: ";
|
||||||
|
static const char cherry_picked_prefix[] = "(cherry picked from commit ";
|
||||||
|
|
||||||
|
static int is_rfc2822_line(const char *buf, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
int ch = buf[i];
|
||||||
|
if (ch == ':')
|
||||||
|
return 1;
|
||||||
|
if (!isalnum(ch) && ch != '-')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_cherry_picked_from_line(const char *buf, int len)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We only care that it looks roughly like (cherry picked from ...)
|
||||||
|
*/
|
||||||
|
return len > strlen(cherry_picked_prefix) + 1 &&
|
||||||
|
!prefixcmp(buf, cherry_picked_prefix) && buf[len - 1] == ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 0 for non-conforming footer
|
||||||
|
* Returns 1 for conforming footer
|
||||||
|
* Returns 2 when sob exists within conforming footer
|
||||||
|
* Returns 3 when sob exists within conforming footer as last entry
|
||||||
|
*/
|
||||||
|
static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob,
|
||||||
|
int ignore_footer)
|
||||||
|
{
|
||||||
|
char prev;
|
||||||
|
int i, k;
|
||||||
|
int len = sb->len - ignore_footer;
|
||||||
|
const char *buf = sb->buf;
|
||||||
|
int found_sob = 0;
|
||||||
|
|
||||||
|
/* footer must end with newline */
|
||||||
|
if (!len || buf[len - 1] != '\n')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
prev = '\0';
|
||||||
|
for (i = len - 1; i > 0; i--) {
|
||||||
|
char ch = buf[i];
|
||||||
|
if (prev == '\n' && ch == '\n') /* paragraph break */
|
||||||
|
break;
|
||||||
|
prev = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* require at least one blank line */
|
||||||
|
if (prev != '\n' || buf[i] != '\n')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* advance to start of last paragraph */
|
||||||
|
while (i < len - 1 && buf[i] == '\n')
|
||||||
|
i++;
|
||||||
|
|
||||||
|
for (; i < len; i = k) {
|
||||||
|
int found_rfc2822;
|
||||||
|
|
||||||
|
for (k = i; k < len && buf[k] != '\n'; k++)
|
||||||
|
; /* do nothing */
|
||||||
|
k++;
|
||||||
|
|
||||||
|
found_rfc2822 = is_rfc2822_line(buf + i, k - i - 1);
|
||||||
|
if (found_rfc2822 && sob &&
|
||||||
|
!strncmp(buf + i, sob->buf, sob->len))
|
||||||
|
found_sob = k;
|
||||||
|
|
||||||
|
if (!(found_rfc2822 ||
|
||||||
|
is_cherry_picked_from_line(buf + i, k - i - 1)))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (found_sob == i)
|
||||||
|
return 3;
|
||||||
|
if (found_sob)
|
||||||
|
return 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void remove_sequencer_state(void)
|
static void remove_sequencer_state(void)
|
||||||
{
|
{
|
||||||
|
@ -237,7 +320,7 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
|
||||||
rollback_lock_file(&index_lock);
|
rollback_lock_file(&index_lock);
|
||||||
|
|
||||||
if (opts->signoff)
|
if (opts->signoff)
|
||||||
append_signoff(msgbuf, 0);
|
append_signoff(msgbuf, 0, 0);
|
||||||
|
|
||||||
if (!clean) {
|
if (!clean) {
|
||||||
int i;
|
int i;
|
||||||
|
@ -496,7 +579,9 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts->record_origin) {
|
if (opts->record_origin) {
|
||||||
strbuf_addstr(&msgbuf, "(cherry picked from commit ");
|
if (!has_conforming_footer(&msgbuf, NULL, 0))
|
||||||
|
strbuf_addch(&msgbuf, '\n');
|
||||||
|
strbuf_addstr(&msgbuf, cherry_picked_prefix);
|
||||||
strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1));
|
strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1));
|
||||||
strbuf_addstr(&msgbuf, ")\n");
|
strbuf_addstr(&msgbuf, ")\n");
|
||||||
}
|
}
|
||||||
|
@ -1021,62 +1106,67 @@ int sequencer_pick_revisions(struct replay_opts *opts)
|
||||||
return pick_commits(todo_list, opts);
|
return pick_commits(todo_list, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ends_rfc2822_footer(struct strbuf *sb, int ignore_footer)
|
void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
|
||||||
{
|
|
||||||
int ch;
|
|
||||||
int hit = 0;
|
|
||||||
int i, j, k;
|
|
||||||
int len = sb->len - ignore_footer;
|
|
||||||
int first = 1;
|
|
||||||
const char *buf = sb->buf;
|
|
||||||
|
|
||||||
for (i = len - 1; i > 0; i--) {
|
|
||||||
if (hit && buf[i] == '\n')
|
|
||||||
break;
|
|
||||||
hit = (buf[i] == '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
while (i < len - 1 && buf[i] == '\n')
|
|
||||||
i++;
|
|
||||||
|
|
||||||
for (; i < len; i = k) {
|
|
||||||
for (k = i; k < len && buf[k] != '\n'; k++)
|
|
||||||
; /* do nothing */
|
|
||||||
k++;
|
|
||||||
|
|
||||||
if ((buf[k] == ' ' || buf[k] == '\t') && !first)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
first = 0;
|
|
||||||
|
|
||||||
for (j = 0; i + j < len; j++) {
|
|
||||||
ch = buf[i + j];
|
|
||||||
if (ch == ':')
|
|
||||||
break;
|
|
||||||
if (isalnum(ch) ||
|
|
||||||
(ch == '-'))
|
|
||||||
continue;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void append_signoff(struct strbuf *msgbuf, int ignore_footer)
|
|
||||||
{
|
{
|
||||||
|
unsigned no_dup_sob = flag & APPEND_SIGNOFF_DEDUP;
|
||||||
struct strbuf sob = STRBUF_INIT;
|
struct strbuf sob = STRBUF_INIT;
|
||||||
int i;
|
int has_footer;
|
||||||
|
|
||||||
strbuf_addstr(&sob, sign_off_header);
|
strbuf_addstr(&sob, sign_off_header);
|
||||||
strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
|
strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
|
||||||
getenv("GIT_COMMITTER_EMAIL")));
|
getenv("GIT_COMMITTER_EMAIL")));
|
||||||
strbuf_addch(&sob, '\n');
|
strbuf_addch(&sob, '\n');
|
||||||
for (i = msgbuf->len - 1 - ignore_footer; i > 0 && msgbuf->buf[i - 1] != '\n'; i--)
|
|
||||||
; /* do nothing */
|
/*
|
||||||
if (prefixcmp(msgbuf->buf + i, sob.buf)) {
|
* If the whole message buffer is equal to the sob, pretend that we
|
||||||
if (!i || !ends_rfc2822_footer(msgbuf, ignore_footer))
|
* found a conforming footer with a matching sob
|
||||||
strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0, "\n", 1);
|
*/
|
||||||
strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0, sob.buf, sob.len);
|
if (msgbuf->len - ignore_footer == sob.len &&
|
||||||
|
!strncmp(msgbuf->buf, sob.buf, sob.len))
|
||||||
|
has_footer = 3;
|
||||||
|
else
|
||||||
|
has_footer = has_conforming_footer(msgbuf, &sob, ignore_footer);
|
||||||
|
|
||||||
|
if (!has_footer) {
|
||||||
|
const char *append_newlines = NULL;
|
||||||
|
size_t len = msgbuf->len - ignore_footer;
|
||||||
|
|
||||||
|
if (!len) {
|
||||||
|
/*
|
||||||
|
* The buffer is completely empty. Leave foom for
|
||||||
|
* the title and body to be filled in by the user.
|
||||||
|
*/
|
||||||
|
append_newlines = "\n\n";
|
||||||
|
} else if (msgbuf->buf[len - 1] != '\n') {
|
||||||
|
/*
|
||||||
|
* Incomplete line. Complete the line and add a
|
||||||
|
* blank one so that there is an empty line between
|
||||||
|
* the message body and the sob.
|
||||||
|
*/
|
||||||
|
append_newlines = "\n\n";
|
||||||
|
} else if (len == 1) {
|
||||||
|
/*
|
||||||
|
* Buffer contains a single newline. Add another
|
||||||
|
* so that we leave room for the title and body.
|
||||||
|
*/
|
||||||
|
append_newlines = "\n";
|
||||||
|
} else if (msgbuf->buf[len - 2] != '\n') {
|
||||||
|
/*
|
||||||
|
* Buffer ends with a single newline. Add another
|
||||||
|
* so that there is an empty line between the message
|
||||||
|
* body and the sob.
|
||||||
|
*/
|
||||||
|
append_newlines = "\n";
|
||||||
|
} /* else, the buffer already ends with two newlines. */
|
||||||
|
|
||||||
|
if (append_newlines)
|
||||||
|
strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
|
||||||
|
append_newlines, strlen(append_newlines));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_footer != 3 && (!no_dup_sob || has_footer != 2))
|
||||||
|
strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
|
||||||
|
sob.buf, sob.len);
|
||||||
|
|
||||||
strbuf_release(&sob);
|
strbuf_release(&sob);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#define SEQ_TODO_FILE "sequencer/todo"
|
#define SEQ_TODO_FILE "sequencer/todo"
|
||||||
#define SEQ_OPTS_FILE "sequencer/opts"
|
#define SEQ_OPTS_FILE "sequencer/opts"
|
||||||
|
|
||||||
|
#define APPEND_SIGNOFF_DEDUP (1u << 0)
|
||||||
|
|
||||||
enum replay_action {
|
enum replay_action {
|
||||||
REPLAY_REVERT,
|
REPLAY_REVERT,
|
||||||
REPLAY_PICK
|
REPLAY_PICK
|
||||||
|
@ -48,6 +50,6 @@ int sequencer_pick_revisions(struct replay_opts *opts);
|
||||||
|
|
||||||
extern const char sign_off_header[];
|
extern const char sign_off_header[];
|
||||||
|
|
||||||
void append_signoff(struct strbuf *msgbuf, int ignore_footer);
|
void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,219 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test_description='Test cherry-pick -x and -s'
|
||||||
|
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
pristine_detach () {
|
||||||
|
git cherry-pick --quit &&
|
||||||
|
git checkout -f "$1^0" &&
|
||||||
|
git read-tree -u --reset HEAD &&
|
||||||
|
git clean -d -f -f -q -x
|
||||||
|
}
|
||||||
|
|
||||||
|
mesg_one_line='base: commit message'
|
||||||
|
|
||||||
|
mesg_no_footer="$mesg_one_line
|
||||||
|
|
||||||
|
OneWordBodyThatsNotA-S-o-B"
|
||||||
|
|
||||||
|
mesg_with_footer="$mesg_no_footer
|
||||||
|
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
||||||
|
Signed-off-by: A.U. Thor <author@example.com>
|
||||||
|
Signed-off-by: B.U. Thor <buthor@example.com>"
|
||||||
|
|
||||||
|
mesg_broken_footer="$mesg_no_footer
|
||||||
|
|
||||||
|
The signed-off-by string should begin with the words Signed-off-by followed
|
||||||
|
by a colon and space, and then the signers name and email address. e.g.
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
|
||||||
|
|
||||||
|
mesg_with_footer_sob="$mesg_with_footer
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
|
||||||
|
|
||||||
|
mesg_with_cherry_footer="$mesg_with_footer_sob
|
||||||
|
(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
|
||||||
|
Tested-by: C.U. Thor <cuthor@example.com>"
|
||||||
|
|
||||||
|
|
||||||
|
test_expect_success setup '
|
||||||
|
git config advice.detachedhead false &&
|
||||||
|
echo unrelated >unrelated &&
|
||||||
|
git add unrelated &&
|
||||||
|
test_commit initial foo a &&
|
||||||
|
test_commit "$mesg_one_line" foo b mesg-one-line &&
|
||||||
|
git reset --hard initial &&
|
||||||
|
test_commit "$mesg_no_footer" foo b mesg-no-footer &&
|
||||||
|
git reset --hard initial &&
|
||||||
|
test_commit "$mesg_broken_footer" foo b mesg-broken-footer &&
|
||||||
|
git reset --hard initial &&
|
||||||
|
test_commit "$mesg_with_footer" foo b mesg-with-footer &&
|
||||||
|
git reset --hard initial &&
|
||||||
|
test_commit "$mesg_with_footer_sob" foo b mesg-with-footer-sob &&
|
||||||
|
git reset --hard initial &&
|
||||||
|
test_commit "$mesg_with_cherry_footer" foo b mesg-with-cherry-footer &&
|
||||||
|
pristine_detach initial &&
|
||||||
|
test_commit conflicting unrelated
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -x inserts blank line after one line subject' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
sha1=`git rev-parse mesg-one-line^0` &&
|
||||||
|
git cherry-pick -x mesg-one-line &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_one_line
|
||||||
|
|
||||||
|
(cherry picked from commit $sha1)
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -s inserts blank line after one line subject' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
git cherry-pick -s mesg-one-line &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_one_line
|
||||||
|
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -s inserts blank line after non-conforming footer' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
git cherry-pick -s mesg-broken-footer &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_broken_footer
|
||||||
|
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -x inserts blank line when conforming footer not found' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
sha1=`git rev-parse mesg-no-footer^0` &&
|
||||||
|
git cherry-pick -x mesg-no-footer &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_no_footer
|
||||||
|
|
||||||
|
(cherry picked from commit $sha1)
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -s inserts blank line when conforming footer not found' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
git cherry-pick -s mesg-no-footer &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_no_footer
|
||||||
|
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -x -s inserts blank line when conforming footer not found' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
sha1=`git rev-parse mesg-no-footer^0` &&
|
||||||
|
git cherry-pick -x -s mesg-no-footer &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_no_footer
|
||||||
|
|
||||||
|
(cherry picked from commit $sha1)
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -s adds sob when last sob doesnt match committer' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
git cherry-pick -s mesg-with-footer &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_with_footer
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -x -s adds sob when last sob doesnt match committer' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
sha1=`git rev-parse mesg-with-footer^0` &&
|
||||||
|
git cherry-pick -x -s mesg-with-footer &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_with_footer
|
||||||
|
(cherry picked from commit $sha1)
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -s refrains from adding duplicate trailing sob' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
git cherry-pick -s mesg-with-footer-sob &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_with_footer_sob
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -x -s adds sob even when trailing sob exists for committer' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
sha1=`git rev-parse mesg-with-footer-sob^0` &&
|
||||||
|
git cherry-pick -x -s mesg-with-footer-sob &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_with_footer_sob
|
||||||
|
(cherry picked from commit $sha1)
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -x treats "(cherry picked from..." line as part of footer' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
sha1=`git rev-parse mesg-with-cherry-footer^0` &&
|
||||||
|
git cherry-pick -x mesg-with-cherry-footer &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_with_cherry_footer
|
||||||
|
(cherry picked from commit $sha1)
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -s treats "(cherry picked from..." line as part of footer' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
git cherry-pick -s mesg-with-cherry-footer &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_with_cherry_footer
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'cherry-pick -x -s treats "(cherry picked from..." line as part of footer' '
|
||||||
|
pristine_detach initial &&
|
||||||
|
sha1=`git rev-parse mesg-with-cherry-footer^0` &&
|
||||||
|
git cherry-pick -x -s mesg-with-cherry-footer &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
$mesg_with_cherry_footer
|
||||||
|
(cherry picked from commit $sha1)
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
||||||
|
EOF
|
||||||
|
git log -1 --pretty=format:%B >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
|
@ -972,6 +972,268 @@ test_expect_success 'empty subject prefix does not have extra space' '
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
append_signoff()
|
||||||
|
{
|
||||||
|
C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
|
||||||
|
git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
|
||||||
|
sed -n -e "1,/^---$/p" append_signoff.patch |
|
||||||
|
egrep -n "^Subject|Sign|^$"
|
||||||
|
}
|
||||||
|
|
||||||
|
test_expect_success 'signoff: commit with no body' '
|
||||||
|
append_signoff </dev/null >actual &&
|
||||||
|
cat <<\EOF | sed "s/EOL$//" >expected &&
|
||||||
|
4:Subject: [PATCH] EOL
|
||||||
|
8:
|
||||||
|
9:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: commit with only subject' '
|
||||||
|
echo subject | append_signoff >actual &&
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
9:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: commit with only subject that does not end with NL' '
|
||||||
|
printf subject | append_signoff >actual &&
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
9:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: no existing signoffs' '
|
||||||
|
append_signoff <<\EOF >actual &&
|
||||||
|
subject
|
||||||
|
|
||||||
|
body
|
||||||
|
EOF
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
10:
|
||||||
|
11:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: no existing signoffs and no trailing NL' '
|
||||||
|
printf "subject\n\nbody" | append_signoff >actual &&
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
10:
|
||||||
|
11:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: some random signoff' '
|
||||||
|
append_signoff <<\EOF >actual &&
|
||||||
|
subject
|
||||||
|
|
||||||
|
body
|
||||||
|
|
||||||
|
Signed-off-by: my@house
|
||||||
|
EOF
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
10:
|
||||||
|
11:Signed-off-by: my@house
|
||||||
|
12:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: misc conforming footer elements' '
|
||||||
|
append_signoff <<\EOF >actual &&
|
||||||
|
subject
|
||||||
|
|
||||||
|
body
|
||||||
|
|
||||||
|
Signed-off-by: my@house
|
||||||
|
(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
|
||||||
|
Tested-by: Some One <someone@example.com>
|
||||||
|
Bug: 1234
|
||||||
|
EOF
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
10:
|
||||||
|
11:Signed-off-by: my@house
|
||||||
|
15:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: some random signoff-alike' '
|
||||||
|
append_signoff <<\EOF >actual &&
|
||||||
|
subject
|
||||||
|
|
||||||
|
body
|
||||||
|
Fooled-by-me: my@house
|
||||||
|
EOF
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
11:
|
||||||
|
12:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: not really a signoff' '
|
||||||
|
append_signoff <<\EOF >actual &&
|
||||||
|
subject
|
||||||
|
|
||||||
|
I want to mention about Signed-off-by: here.
|
||||||
|
EOF
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
9:I want to mention about Signed-off-by: here.
|
||||||
|
10:
|
||||||
|
11:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: not really a signoff (2)' '
|
||||||
|
append_signoff <<\EOF >actual &&
|
||||||
|
subject
|
||||||
|
|
||||||
|
My unfortunate
|
||||||
|
Signed-off-by: example happens to be wrapped here.
|
||||||
|
EOF
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
10:Signed-off-by: example happens to be wrapped here.
|
||||||
|
11:
|
||||||
|
12:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
|
||||||
|
append_signoff <<\EOF >actual &&
|
||||||
|
subject
|
||||||
|
|
||||||
|
Signed-off-by: my@house
|
||||||
|
Signed-off-by: your@house
|
||||||
|
|
||||||
|
A lot of houses.
|
||||||
|
EOF
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
9:Signed-off-by: my@house
|
||||||
|
10:Signed-off-by: your@house
|
||||||
|
11:
|
||||||
|
13:
|
||||||
|
14:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: the same signoff at the end' '
|
||||||
|
append_signoff <<\EOF >actual &&
|
||||||
|
subject
|
||||||
|
|
||||||
|
body
|
||||||
|
|
||||||
|
Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
10:
|
||||||
|
11:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
|
||||||
|
printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
|
||||||
|
append_signoff >actual &&
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
9:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: the same signoff NOT at the end' '
|
||||||
|
append_signoff <<\EOF >actual &&
|
||||||
|
subject
|
||||||
|
|
||||||
|
body
|
||||||
|
|
||||||
|
Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
Signed-off-by: my@house
|
||||||
|
EOF
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
10:
|
||||||
|
11:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
12:Signed-off-by: my@house
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: detect garbage in non-conforming footer' '
|
||||||
|
append_signoff <<\EOF >actual &&
|
||||||
|
subject
|
||||||
|
|
||||||
|
body
|
||||||
|
|
||||||
|
Tested-by: my@house
|
||||||
|
Some Trash
|
||||||
|
Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
10:
|
||||||
|
13:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
14:
|
||||||
|
15:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
|
||||||
|
append_signoff <<\EOF >actual &&
|
||||||
|
subject
|
||||||
|
|
||||||
|
body
|
||||||
|
|
||||||
|
Reviewed-id: Noone
|
||||||
|
Tested-by: my@house
|
||||||
|
Change-id: Ideadbeef
|
||||||
|
Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
Bug: 1234
|
||||||
|
EOF
|
||||||
|
cat >expected <<\EOF &&
|
||||||
|
4:Subject: [PATCH] subject
|
||||||
|
8:
|
||||||
|
10:
|
||||||
|
14:Signed-off-by: C O Mitter <committer@example.com>
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'format patch ignores color.ui' '
|
test_expect_success 'format patch ignores color.ui' '
|
||||||
test_unconfig color.ui &&
|
test_unconfig color.ui &&
|
||||||
git format-patch --stdout -1 >expect &&
|
git format-patch --stdout -1 >expect &&
|
||||||
|
|
|
@ -424,6 +424,18 @@ test_expect_success 'A single-liner subject with a token plus colon is not a foo
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'commit -s places sob on third line after two empty lines' '
|
||||||
|
git commit -s --allow-empty --allow-empty-message &&
|
||||||
|
cat <<-EOF >expect &&
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
|
||||||
|
|
||||||
|
EOF
|
||||||
|
sed -e "/^#/d" -e "s/^:.*//" .git/COMMIT_EDITMSG >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
write_script .git/FAKE_EDITOR <<\EOF
|
write_script .git/FAKE_EDITOR <<\EOF
|
||||||
mv "$1" "$1.orig"
|
mv "$1" "$1.orig"
|
||||||
(
|
(
|
||||||
|
|
|
@ -135,12 +135,12 @@ test_pause () {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Call test_commit with the arguments "<message> [<file> [<contents>]]"
|
# Call test_commit with the arguments "<message> [<file> [<contents> [<tag>]]]"
|
||||||
#
|
#
|
||||||
# This will commit a file with the given contents and the given commit
|
# This will commit a file with the given contents and the given commit
|
||||||
# message. It will also add a tag with <message> as name.
|
# message, and tag the resulting commit with the given tag name.
|
||||||
#
|
#
|
||||||
# Both <file> and <contents> default to <message>.
|
# <file>, <contents>, and <tag> all default to <message>.
|
||||||
|
|
||||||
test_commit () {
|
test_commit () {
|
||||||
notick= &&
|
notick= &&
|
||||||
|
@ -168,7 +168,7 @@ test_commit () {
|
||||||
test_tick
|
test_tick
|
||||||
fi &&
|
fi &&
|
||||||
git commit $signoff -m "$1" &&
|
git commit $signoff -m "$1" &&
|
||||||
git tag "$1"
|
git tag "${4:-$1}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Call test_merge with the arguments "<message> <commit>", where <commit>
|
# Call test_merge with the arguments "<message> <commit>", where <commit>
|
||||||
|
|
Loading…
Reference in New Issue