mirror of
https://github.com/git-for-windows/git.git
synced 2026-03-31 12:16:11 -05:00
A ton of Git commands simply do not read (or at least parse) the core.* settings. This is not good, as Git for Windows relies on the core.longPaths setting to be read quite early on. So let's just make sure that all commands read the config and give platform_core_config() a chance. This patch teaches tons of Git commands to respect the config setting `core.longPaths = true`, including `pack-refs`, thereby fixing https://github.com/git-for-windows/git/issues/1218 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
120 lines
2.5 KiB
C
120 lines
2.5 KiB
C
#define USE_THE_INDEX_COMPATIBILITY_MACROS
|
|
#include "builtin.h"
|
|
#include "run-command.h"
|
|
#include "config.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;
|
|
/* TODO: audit for interaction with sparse-index. */
|
|
ensure_full_index(&the_index);
|
|
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);
|
|
|
|
git_config(git_default_config, NULL);
|
|
|
|
if (argc < 3)
|
|
usage("git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])");
|
|
|
|
read_cache();
|
|
|
|
/* TODO: audit for interaction with sparse-index. */
|
|
ensure_full_index(&the_index);
|
|
|
|
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;
|
|
}
|