commit: teach --amend to carry forward extra headers
After running "git pull $there for-linus" to merge a signed tag, the integrator may need to amend the resulting merge commit to fix typoes in it. Teach --amend option to read the existing extra headers, and carry them forward. Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
fab47d0575
commit
ed7a42a075
@ -1382,6 +1382,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
|||||||
int allow_fast_forward = 1;
|
int allow_fast_forward = 1;
|
||||||
struct wt_status s;
|
struct wt_status s;
|
||||||
struct commit *current_head = NULL;
|
struct commit *current_head = NULL;
|
||||||
|
struct commit_extra_header *extra = NULL;
|
||||||
|
|
||||||
if (argc == 2 && !strcmp(argv[1], "-h"))
|
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||||
usage_with_options(builtin_commit_usage, builtin_commit_options);
|
usage_with_options(builtin_commit_usage, builtin_commit_options);
|
||||||
@ -1483,12 +1484,16 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commit_tree(sb.buf, active_cache_tree->sha1, parents, sha1,
|
if (amend)
|
||||||
author_ident.buf)) {
|
extra = read_commit_extra_headers(current_head);
|
||||||
|
|
||||||
|
if (commit_tree_extended(sb.buf, active_cache_tree->sha1, parents, sha1,
|
||||||
|
author_ident.buf, extra)) {
|
||||||
rollback_index_files();
|
rollback_index_files();
|
||||||
die(_("failed to write commit object"));
|
die(_("failed to write commit object"));
|
||||||
}
|
}
|
||||||
strbuf_release(&author_ident);
|
strbuf_release(&author_ident);
|
||||||
|
free_commit_extra_headers(extra);
|
||||||
|
|
||||||
ref_lock = lock_any_ref_for_update("HEAD",
|
ref_lock = lock_any_ref_for_update("HEAD",
|
||||||
!current_head
|
!current_head
|
||||||
|
65
commit.c
65
commit.c
@ -894,7 +894,72 @@ static void add_extra_header(struct strbuf *buffer,
|
|||||||
struct commit_extra_header *extra)
|
struct commit_extra_header *extra)
|
||||||
{
|
{
|
||||||
strbuf_addstr(buffer, extra->key);
|
strbuf_addstr(buffer, extra->key);
|
||||||
|
if (extra->len)
|
||||||
strbuf_add_lines(buffer, " ", extra->value, extra->len);
|
strbuf_add_lines(buffer, " ", extra->value, extra->len);
|
||||||
|
else
|
||||||
|
strbuf_addch(buffer, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
struct commit_extra_header *read_commit_extra_headers(struct commit *commit)
|
||||||
|
{
|
||||||
|
struct commit_extra_header *extra = NULL;
|
||||||
|
unsigned long size;
|
||||||
|
enum object_type type;
|
||||||
|
char *buffer = read_sha1_file(commit->object.sha1, &type, &size);
|
||||||
|
if (buffer && type == OBJ_COMMIT)
|
||||||
|
extra = read_commit_extra_header_lines(buffer, size);
|
||||||
|
free(buffer);
|
||||||
|
return extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int standard_header_field(const char *field, size_t len)
|
||||||
|
{
|
||||||
|
return ((len == 4 && !memcmp(field, "tree ", 5)) ||
|
||||||
|
(len == 6 && !memcmp(field, "parent ", 7)) ||
|
||||||
|
(len == 6 && !memcmp(field, "author ", 7)) ||
|
||||||
|
(len == 9 && !memcmp(field, "committer ", 10)) ||
|
||||||
|
(len == 8 && !memcmp(field, "encoding ", 9)));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct commit_extra_header *read_commit_extra_header_lines(const char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
struct commit_extra_header *extra = NULL, **tail = &extra, *it = NULL;
|
||||||
|
const char *line, *next, *eof, *eob;
|
||||||
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
|
||||||
|
for (line = buffer, eob = line + size;
|
||||||
|
line < eob && *line != '\n';
|
||||||
|
line = next) {
|
||||||
|
next = memchr(line, '\n', eob - line);
|
||||||
|
next = next ? next + 1 : eob;
|
||||||
|
if (*line == ' ') {
|
||||||
|
/* continuation */
|
||||||
|
if (it)
|
||||||
|
strbuf_add(&buf, line + 1, next - (line + 1));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (it)
|
||||||
|
it->value = strbuf_detach(&buf, &it->len);
|
||||||
|
strbuf_reset(&buf);
|
||||||
|
it = NULL;
|
||||||
|
|
||||||
|
eof = strchr(line, ' ');
|
||||||
|
if (next <= eof)
|
||||||
|
eof = next;
|
||||||
|
|
||||||
|
if (standard_header_field(line, eof - line))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
it = xcalloc(1, sizeof(*it));
|
||||||
|
it->key = xmemdupz(line, eof-line);
|
||||||
|
*tail = it;
|
||||||
|
tail = &it->next;
|
||||||
|
if (eof + 1 < next)
|
||||||
|
strbuf_add(&buf, eof + 1, next - (eof + 1));
|
||||||
|
}
|
||||||
|
if (it)
|
||||||
|
it->value = strbuf_detach(&buf, &it->len);
|
||||||
|
return extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_commit_extra_headers(struct commit_extra_header *extra)
|
void free_commit_extra_headers(struct commit_extra_header *extra)
|
||||||
|
3
commit.h
3
commit.h
@ -200,6 +200,9 @@ extern int commit_tree_extended(const char *msg, unsigned char *tree,
|
|||||||
const char *author,
|
const char *author,
|
||||||
struct commit_extra_header *);
|
struct commit_extra_header *);
|
||||||
|
|
||||||
|
extern struct commit_extra_header *read_commit_extra_headers(struct commit *);
|
||||||
|
extern struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len);
|
||||||
|
|
||||||
extern void free_commit_extra_headers(struct commit_extra_header *extra);
|
extern void free_commit_extra_headers(struct commit_extra_header *extra);
|
||||||
|
|
||||||
struct merge_remote_desc {
|
struct merge_remote_desc {
|
||||||
|
Loading…
Reference in New Issue
Block a user