Browse Source
any unmerged files. This one doesn't actually do the merging, but it makes it easy to script the programs that do using it.maint
Linus Torvalds
20 years ago
2 changed files with 131 additions and 1 deletions
@ -0,0 +1,127 @@
@@ -0,0 +1,127 @@
|
||||
#include <sys/types.h> |
||||
#include <sys/wait.h> |
||||
|
||||
#include "cache.h" |
||||
|
||||
static const char *pgm = NULL; |
||||
static const char *arguments[5]; |
||||
|
||||
static void run_program(void) |
||||
{ |
||||
int pid = fork(), status; |
||||
|
||||
if (pid < 0) |
||||
die("unable to fork"); |
||||
if (!pid) { |
||||
execlp(pgm, arguments[0], |
||||
arguments[1], |
||||
arguments[2], |
||||
arguments[3], |
||||
arguments[4], |
||||
NULL); |
||||
die("unable to execute '%s'", pgm); |
||||
} |
||||
if (waitpid(pid, &status, 0) < 0 || !WIFEXITED(status) || WEXITSTATUS(status)) |
||||
die("merge program failed"); |
||||
} |
||||
|
||||
static char *create_temp_file(int stage, unsigned char *sha1) |
||||
{ |
||||
static char template[4][50]; |
||||
char *path = template[stage]; |
||||
void *buf; |
||||
char type[100]; |
||||
unsigned long size; |
||||
int fd; |
||||
|
||||
buf = read_sha1_file(sha1, type, &size); |
||||
if (!buf || strcmp(type, "blob")) |
||||
die("unable to read blob object %s", sha1_to_hex(sha1)); |
||||
|
||||
strcpy(path, ".merge_file_XXXXXX"); |
||||
fd = mkstemp(path); |
||||
if (fd < 0) |
||||
die("unable to create temp-file"); |
||||
if (write(fd, buf, size) != size) |
||||
die("unable to write temp-file"); |
||||
close(fd); |
||||
return path; |
||||
} |
||||
|
||||
static int merge_entry(int pos, const char *path) |
||||
{ |
||||
int found; |
||||
|
||||
if (pos >= active_nr) |
||||
die("merge-cache: %s not in the cache", path); |
||||
arguments[0] = pgm; |
||||
arguments[1] = ""; |
||||
arguments[2] = ""; |
||||
arguments[3] = ""; |
||||
arguments[4] = path; |
||||
found = 0; |
||||
do { |
||||
struct cache_entry *ce = active_cache[pos]; |
||||
int stage = ce_stage(ce); |
||||
|
||||
if (strcmp(ce->name, path)) |
||||
break; |
||||
found++; |
||||
arguments[stage] = create_temp_file(stage, ce->sha1); |
||||
} while (++pos < active_nr); |
||||
if (!found) |
||||
die("merge-cache: %s not in the cache", path); |
||||
run_program(); |
||||
return found; |
||||
} |
||||
|
||||
static void merge_file(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++) { |
||||
struct cache_entry *ce = active_cache[i]; |
||||
if (!ce_stage(ce)) |
||||
continue; |
||||
i += merge_entry(i, ce->name)-1; |
||||
} |
||||
} |
||||
|
||||
int main(int argc, char **argv) |
||||
{ |
||||
int i, force_file = 0; |
||||
|
||||
if (argc < 3) |
||||
usage("merge-cache <merge-program> (-a | <filename>*)"); |
||||
|
||||
read_cache(); |
||||
|
||||
pgm = argv[1]; |
||||
for (i = 2; i < argc; i++) { |
||||
char *arg = argv[i]; |
||||
if (!force_file && *arg == '-') { |
||||
if (!strcmp(arg, "--")) { |
||||
force_file = 1; |
||||
continue; |
||||
} |
||||
if (!strcmp(arg, "-a")) { |
||||
merge_all(); |
||||
continue; |
||||
} |
||||
die("merge-cache: unknown option %s", arg); |
||||
} |
||||
merge_file(arg); |
||||
} |
||||
return 0; |
||||
} |
Loading…
Reference in new issue