mirror of
https://github.com/git/git
synced 2024-08-27 19:49:21 +00:00
![brian m. carlson](/assets/img/avatar_default.png)
Since we will likely be introducing a new hash function at some point, and that hash function might be longer than 40 hex characters, use the constant GIT_MAX_HEXSZ, which is designed to be suitable for allocations, instead of GIT_SHA1_HEXSZ. This will ease the transition down the line by distinguishing between places where we need to allocate memory suitable for the largest hash from those where we need to handle the current hash. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
111 lines
2.2 KiB
C
111 lines
2.2 KiB
C
#include "builtin.h"
|
|
#include "run-command.h"
|
|
|
|
static const char *pgm;
|
|
static int one_shot, quiet;
|
|
static int err;
|
|
|
|
static int merge_entry(int pos, const char *path)
|
|
{
|
|
int found;
|
|
const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
|
|
char hexbuf[4][GIT_MAX_HEXSZ + 1];
|
|
char ownbuf[4][60];
|
|
|
|
if (pos >= active_nr)
|
|
die("git merge-index: %s not in the cache", path);
|
|
found = 0;
|
|
do {
|
|
const struct cache_entry *ce = active_cache[pos];
|
|
int stage = ce_stage(ce);
|
|
|
|
if (strcmp(ce->name, path))
|
|
break;
|
|
found++;
|
|
oid_to_hex_r(hexbuf[stage], &ce->oid);
|
|
xsnprintf(ownbuf[stage], sizeof(ownbuf[stage]), "%o", ce->ce_mode);
|
|
arguments[stage] = hexbuf[stage];
|
|
arguments[stage + 4] = ownbuf[stage];
|
|
} while (++pos < active_nr);
|
|
if (!found)
|
|
die("git merge-index: %s not in the cache", path);
|
|
|
|
if (run_command_v_opt(arguments, 0)) {
|
|
if (one_shot)
|
|
err++;
|
|
else {
|
|
if (!quiet)
|
|
die("merge program failed");
|
|
exit(1);
|
|
}
|
|
}
|
|
return found;
|
|
}
|
|
|
|
static void merge_one_path(const char *path)
|
|
{
|
|
int pos = cache_name_pos(path, strlen(path));
|
|
|
|
/*
|
|
* If it already exists in the cache as stage0, it's
|
|
* already merged and there is nothing to do.
|
|
*/
|
|
if (pos < 0)
|
|
merge_entry(-pos-1, path);
|
|
}
|
|
|
|
static void merge_all(void)
|
|
{
|
|
int i;
|
|
for (i = 0; i < active_nr; i++) {
|
|
const struct cache_entry *ce = active_cache[i];
|
|
if (!ce_stage(ce))
|
|
continue;
|
|
i += merge_entry(i, ce->name)-1;
|
|
}
|
|
}
|
|
|
|
int cmd_merge_index(int argc, const char **argv, const char *prefix)
|
|
{
|
|
int i, force_file = 0;
|
|
|
|
/* Without this we cannot rely on waitpid() to tell
|
|
* what happened to our children.
|
|
*/
|
|
signal(SIGCHLD, SIG_DFL);
|
|
|
|
if (argc < 3)
|
|
usage("git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])");
|
|
|
|
read_cache();
|
|
|
|
i = 1;
|
|
if (!strcmp(argv[i], "-o")) {
|
|
one_shot = 1;
|
|
i++;
|
|
}
|
|
if (!strcmp(argv[i], "-q")) {
|
|
quiet = 1;
|
|
i++;
|
|
}
|
|
pgm = argv[i++];
|
|
for (; i < argc; i++) {
|
|
const char *arg = argv[i];
|
|
if (!force_file && *arg == '-') {
|
|
if (!strcmp(arg, "--")) {
|
|
force_file = 1;
|
|
continue;
|
|
}
|
|
if (!strcmp(arg, "-a")) {
|
|
merge_all();
|
|
continue;
|
|
}
|
|
die("git merge-index: unknown option %s", arg);
|
|
}
|
|
merge_one_path(arg);
|
|
}
|
|
if (err && !quiet)
|
|
die("merge program failed");
|
|
return err;
|
|
}
|