13
#include "rerere.h"
14
#include "merge-recursive.h"
15
#include "refs.h"
16
+#include "argv-array.h"
17
18
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
19
252
return !clean;
253
}
254
255
+static int is_index_unchanged(void)
256
+{
257
+ unsigned char head_sha1[20];
258
+ struct commit *head_commit;
259
+
260
+ if (!resolve_ref_unsafe("HEAD", head_sha1, 1, NULL))
261
+ return error(_("Could not resolve HEAD commit\n"));
262
+
263
+ head_commit = lookup_commit(head_sha1);
264
+ if (!head_commit || parse_commit(head_commit))
265
+ return error(_("could not parse commit %s\n"),
266
+ sha1_to_hex(head_commit->object.sha1));
267
+
268
+ if (!active_cache_tree)
269
+ active_cache_tree = cache_tree();
270
+
271
+ if (!cache_tree_fully_valid(active_cache_tree))
272
+ if (cache_tree_update(active_cache_tree, active_cache,
273
+ active_nr, 0))
274
+ return error(_("Unable to update cache tree\n"));
275
+
276
+ return !hashcmp(active_cache_tree->sha1, head_commit->tree->object.sha1);
277
+}
278
+
279
/*
280
* If we are cherry-pick, and if the merge did not result in
281
* hand-editing, we will hit this commit and inherit the original
285
*/
286
static int run_git_commit(const char *defmsg, struct replay_opts *opts)
287
{
263
- /* 7 is max possible length of our args array including NULL */
264
- const char *args[7];
265
- int i = 0;
288
+ struct argv_array array;
289
+ int rc;
290
+
291
+ argv_array_init(&array);
292
+ argv_array_push(&array, "commit");
293
+ argv_array_push(&array, "-n");
294
267
- args[i++] = "commit";
268
- args[i++] = "-n";
295
if (opts->signoff)
270
- args[i++] = "-s";
296
+ argv_array_push(&array, "-s");
297
if (!opts->edit) {
272
- args[i++] = "-F";
273
- args[i++] = defmsg;
298
+ argv_array_push(&array, "-F");
299
+ argv_array_push(&array, defmsg);
300
}
301
+
302
if (opts->allow_empty)
276
- args[i++] = "--allow-empty";
303
+ argv_array_push(&array, "--allow-empty");
304
278
- args[i] = NULL;
305
+ rc = run_command_v_opt(array.argv, RUN_GIT_CMD);
306
+ argv_array_clear(&array);
307
+ return rc;
308
+}
309
+
310
+static int is_original_commit_empty(struct commit *commit)
311
+{
312
+ const unsigned char *ptree_sha1;
313
+
314
+ if (parse_commit(commit))
315
+ return error(_("Could not parse commit %s\n"),
316
+ sha1_to_hex(commit->object.sha1));
317
+ if (commit->parents) {
318
+ struct commit *parent = commit->parents->item;
319
+ if (parse_commit(parent))
320
+ return error(_("Could not parse parent commit %s\n"),
321
+ sha1_to_hex(parent->object.sha1));
322
+ ptree_sha1 = parent->tree->object.sha1;
323
+ } else {
324
+ ptree_sha1 = EMPTY_TREE_SHA1_BIN; /* commit is root */
325
+ }
326
280
- return run_command_v_opt(args, RUN_GIT_CMD);
327
+ return !hashcmp(ptree_sha1, commit->tree->object.sha1);
328
}
329
330
static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
336
char *defmsg = NULL;
337
struct strbuf msgbuf = STRBUF_INIT;
338
int res;
339
+ int empty_commit;
340
+ int index_unchanged;
341
342
if (opts->no_commit) {
343
/*
463
free_commit_list(remotes);
464
}
465
466
+ empty_commit = is_original_commit_empty(commit);
467
+ if (empty_commit < 0)
468
+ return empty_commit;
469
+
470
/*
471
* If the merge was clean or if it failed due to conflict, we write
472
* CHERRY_PICK_HEAD for the subsequent invocation of commit to use.
487
print_advice(res == 1, opts);
488
rerere(opts->allow_rerere_auto);
489
} else {
490
+ index_unchanged = is_index_unchanged();
491
+ /*
492
+ * If index_unchanged is less than 0, that indicates we either
493
+ * couldn't parse HEAD or the index, so error out here.
494
+ */
495
+ if (index_unchanged < 0)
496
+ return index_unchanged;
497
+
498
+ if (!empty_commit && !opts->keep_redundant_commits && index_unchanged)
499
+ /*
500
+ * The head tree and the index match
501
+ * meaning the commit is empty. Since it wasn't created
502
+ * empty (based on the previous test), we can conclude
503
+ * the commit has been made redundant. Since we don't
504
+ * want to keep redundant commits, we can just return
505
+ * here, skipping this commit
506
+ */
507
+ return 0;
508
+
509
if (!opts->no_commit)
510
res = run_git_commit(defmsg, opts);
511
}