зеркало из https://github.com/microsoft/git.git
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:
Родитель
fab47d0575
Коммит
ed7a42a075
|
@ -1382,6 +1382,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
|||
int allow_fast_forward = 1;
|
||||
struct wt_status s;
|
||||
struct commit *current_head = NULL;
|
||||
struct commit_extra_header *extra = NULL;
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||
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);
|
||||
}
|
||||
|
||||
if (commit_tree(sb.buf, active_cache_tree->sha1, parents, sha1,
|
||||
author_ident.buf)) {
|
||||
if (amend)
|
||||
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();
|
||||
die(_("failed to write commit object"));
|
||||
}
|
||||
strbuf_release(&author_ident);
|
||||
free_commit_extra_headers(extra);
|
||||
|
||||
ref_lock = lock_any_ref_for_update("HEAD",
|
||||
!current_head
|
||||
|
|
67
commit.c
67
commit.c
|
@ -894,7 +894,72 @@ static void add_extra_header(struct strbuf *buffer,
|
|||
struct commit_extra_header *extra)
|
||||
{
|
||||
strbuf_addstr(buffer, extra->key);
|
||||
strbuf_add_lines(buffer, " ", extra->value, extra->len);
|
||||
if (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)
|
||||
|
|
3
commit.h
3
commit.h
|
@ -200,6 +200,9 @@ extern int commit_tree_extended(const char *msg, unsigned char *tree,
|
|||
const char *author,
|
||||
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);
|
||||
|
||||
struct merge_remote_desc {
|
||||
|
|
Загрузка…
Ссылка в новой задаче