19
21
static void cmd_log_init(int argc, const char **argv, const char *prefix,
20
22
struct rev_info *rev)
22
26
rev->abbrev = DEFAULT_ABBREV;
23
27
rev->commit_format = CMIT_FMT_DEFAULT;
24
28
rev->verbose_header = 1;
29
rev->show_root_diff = default_show_root;
25
30
argc = setup_revisions(argc, argv, rev, "HEAD");
26
31
if (rev->diffopt.pickaxe || rev->diffopt.filter)
27
32
rev->always_show_header = 0;
29
die("unrecognized argument: %s", argv[1]);
33
for (i = 1; i < argc; i++) {
34
const char *arg = argv[i];
35
if (!prefixcmp(arg, "--encoding=")) {
37
if (strcmp(arg, "none"))
38
git_log_output_encoding = xstrdup(arg);
40
git_log_output_encoding = "";
43
die("unrecognized argument: %s", arg);
32
47
static int cmd_log_walk(struct rev_info *rev)
36
51
prepare_revision_walk(rev);
37
52
while ((commit = get_revision(rev)) != NULL) {
38
53
log_tree_commit(rev, commit);
40
commit->buffer = NULL;
54
if (!rev->reflog_info) {
55
/* we allow cycles in reflog ancestry */
57
commit->buffer = NULL;
41
59
free_commit_list(commit->parents);
42
60
commit->parents = NULL;
65
static int git_log_config(const char *var, const char *value)
67
if (!strcmp(var, "log.showroot")) {
68
default_show_root = git_config_bool(var, value);
71
return git_diff_ui_config(var, value);
47
74
int cmd_whatchanged(int argc, const char **argv, const char *prefix)
49
76
struct rev_info rev;
51
git_config(git_diff_ui_config);
78
git_config(git_log_config);
52
79
init_revisions(&rev, prefix);
54
81
rev.diffopt.recursive = 1;
59
86
return cmd_log_walk(&rev);
89
static int show_object(const unsigned char *sha1, int suppress_header)
92
enum object_type type;
93
char *buf = read_sha1_file(sha1, &type, &size);
97
return error("Could not read object %s", sha1_to_hex(sha1));
100
while (offset < size && buf[offset++] != '\n') {
101
int new_offset = offset;
102
while (new_offset < size && buf[new_offset++] != '\n')
108
fwrite(buf + offset, size - offset, 1, stdout);
113
static int show_tree_object(const unsigned char *sha1,
114
const char *base, int baselen,
115
const char *pathname, unsigned mode, int stage)
117
printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
62
121
int cmd_show(int argc, const char **argv, const char *prefix)
64
123
struct rev_info rev;
124
struct object_array_entry *objects;
125
int i, count, ret = 0;
66
git_config(git_diff_ui_config);
127
git_config(git_log_config);
67
128
init_revisions(&rev, prefix);
69
130
rev.diffopt.recursive = 1;
73
134
rev.ignore_merges = 0;
75
136
cmd_log_init(argc, argv, prefix, &rev);
138
count = rev.pending.nr;
139
objects = rev.pending.objects;
140
for (i = 0; i < count && !ret; i++) {
141
struct object *o = objects[i].item;
142
const char *name = objects[i].name;
145
ret = show_object(o->sha1, 0);
148
struct tag *t = (struct tag *)o;
150
printf("%stag %s%s\n\n",
151
diff_get_color(rev.diffopt.color_diff,
154
diff_get_color(rev.diffopt.color_diff,
156
ret = show_object(o->sha1, 1);
157
objects[i].item = (struct object *)t->tagged;
162
printf("%stree %s%s\n\n",
163
diff_get_color(rev.diffopt.color_diff,
166
diff_get_color(rev.diffopt.color_diff,
168
read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
172
rev.pending.nr = rev.pending.alloc = 0;
173
rev.pending.objects = NULL;
174
add_object_array(o, name, &rev.pending);
175
ret = cmd_log_walk(&rev);
178
ret = error("Unknown type: %d", o->type);
186
* This is equivalent to "git log -g --abbrev-commit --pretty=oneline"
188
int cmd_log_reflog(int argc, const char **argv, const char *prefix)
192
git_config(git_log_config);
193
init_revisions(&rev, prefix);
194
init_reflog_walk(&rev.reflog_info);
195
rev.abbrev_commit = 1;
196
rev.verbose_header = 1;
197
cmd_log_init(argc, argv, prefix, &rev);
200
* This means that we override whatever commit format the user gave
201
* on the cmd line. Sad, but cmd_log_init() currently doesn't
202
* allow us to set a different default.
204
rev.commit_format = CMIT_FMT_ONELINE;
205
rev.always_show_header = 1;
208
* We get called through "git reflog", so unlike the other log
209
* routines, we need to set up our pager manually..
76
213
return cmd_log_walk(&rev);
81
218
struct rev_info rev;
83
git_config(git_diff_ui_config);
220
git_config(git_log_config);
84
221
init_revisions(&rev, prefix);
85
222
rev.always_show_header = 1;
86
223
cmd_log_init(argc, argv, prefix, &rev);
87
224
return cmd_log_walk(&rev);
228
#define FORMAT_PATCH_NAME_MAX 64
90
230
static int istitlechar(char c)
92
232
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
96
236
static char *extra_headers = NULL;
97
237
static int extra_headers_size = 0;
238
static const char *fmt_patch_suffix = ".patch";
99
240
static int git_format_config(const char *var, const char *value)
101
242
if (!strcmp(var, "format.headers")) {
102
int len = strlen(value);
246
die("format.headers without value");
103
248
extra_headers_size += len + 1;
104
249
extra_headers = xrealloc(extra_headers, extra_headers_size);
105
250
extra_headers[extra_headers_size - len - 1] = 0;
106
251
strcat(extra_headers, value);
109
if (!strcmp(var, "diff.color")) {
112
return git_diff_ui_config(var, value);
254
if (!strcmp(var, "format.suffix")) {
256
die("format.suffix without value");
257
fmt_patch_suffix = xstrdup(value);
260
if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
263
return git_log_config(var, value);
116
267
static FILE *realstdout = NULL;
117
268
static const char *output_directory = NULL;
119
static void reopen_stdout(struct commit *commit, int nr, int keep_subject)
270
static int reopen_stdout(struct commit *commit, int nr, int keep_subject)
272
char filename[PATH_MAX];
275
int suffix_len = strlen(fmt_patch_suffix) + 1;
125
277
if (output_directory) {
126
strlcpy(filename, output_directory, 1010);
278
if (strlen(output_directory) >=
279
sizeof(filename) - FORMAT_PATCH_NAME_MAX - suffix_len)
280
return error("name of output directory is too long");
281
strlcpy(filename, output_directory, sizeof(filename) - suffix_len);
127
282
len = strlen(filename);
128
283
if (filename[len - 1] != '/')
129
284
filename[len++] = '/';
163
322
while (filename[len - 1] == '.' || filename[len - 1] == '-')
166
strcpy(filename + len, ".txt");
326
if (len + suffix_len >= sizeof(filename))
327
return error("Patch pathname too long");
328
strcpy(filename + len, fmt_patch_suffix);
167
329
fprintf(realstdout, "%s\n", filename);
168
freopen(filename, "w", stdout);
330
if (freopen(filename, "w", stdout) == NULL)
331
return error("Cannot open patch file %s",filename);
171
336
static int get_patch_id(struct commit *commit, struct diff_options *options,
233
398
static void gen_message_id(char *dest, unsigned int length, char *base)
235
const char *committer = git_committer_info(1);
400
const char *committer = git_committer_info(-1);
236
401
const char *email_start = strrchr(committer, '<');
237
402
const char *email_end = strrchr(committer, '>');
238
403
if(!email_start || !email_end || email_start > email_end - 1)
284
448
else if (!strcmp(argv[i], "-n") ||
285
449
!strcmp(argv[i], "--numbered"))
287
else if (!strncmp(argv[i], "--start-number=", 15))
451
else if (!prefixcmp(argv[i], "--start-number="))
288
452
start_number = strtol(argv[i] + 15, NULL, 10);
289
453
else if (!strcmp(argv[i], "--start-number")) {
318
482
memcpy(add_signoff, committer, endpos - committer + 1);
319
483
add_signoff[endpos - committer + 1] = 0;
321
else if (!strcmp(argv[i], "--attach"))
322
rev.mime_boundary = git_version_string;
323
else if (!strncmp(argv[i], "--attach=", 9))
324
rev.mime_boundary = argv[i] + 9;
485
else if (!strcmp(argv[i], "--attach")) {
486
rev.mime_boundary = git_version_string;
489
else if (!prefixcmp(argv[i], "--attach=")) {
490
rev.mime_boundary = argv[i] + 9;
493
else if (!strcmp(argv[i], "--inline")) {
494
rev.mime_boundary = git_version_string;
497
else if (!prefixcmp(argv[i], "--inline=")) {
498
rev.mime_boundary = argv[i] + 9;
325
501
else if (!strcmp(argv[i], "--ignore-if-in-upstream"))
326
502
ignore_if_in_upstream = 1;
327
503
else if (!strcmp(argv[i], "--thread"))
329
else if (!strncmp(argv[i], "--in-reply-to=", 14))
505
else if (!prefixcmp(argv[i], "--in-reply-to="))
330
506
in_reply_to = argv[i] + 14;
331
507
else if (!strcmp(argv[i], "--in-reply-to")) {
349
527
die ("unrecognized argument: %s", argv[1]);
351
529
if (!rev.diffopt.output_format)
352
rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_PATCH;
354
if (!output_directory)
530
rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
532
if (!rev.diffopt.text)
533
rev.diffopt.binary = 1;
535
if (!output_directory && !use_stdout)
355
536
output_directory = prefix;
357
538
if (output_directory) {
365
546
if (rev.pending.nr == 1) {
366
rev.pending.objects[0].item->flags |= UNINTERESTING;
547
if (rev.max_count < 0) {
548
rev.pending.objects[0].item->flags |= UNINTERESTING;
551
/* Otherwise, it is "format-patch -22 HEAD", and
552
* get_revision() would return only the specified count.
370
556
if (ignore_if_in_upstream)
412
598
rev.message_id = message_id;
415
reopen_stdout(commit, rev.nr, keep_subject);
601
if (reopen_stdout(commit, rev.nr, keep_subject))
602
die("Failed to create output files");
416
603
shown = log_tree_commit(&rev, commit);
417
604
free(commit->buffer);
418
605
commit->buffer = NULL;