summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 74b2428)
raw | patch | inline | side by side (parent: 74b2428)
author | Linus Torvalds <torvalds@ppc970.osdl.org> | |
Mon, 18 Apr 2005 02:52:54 +0000 (19:52 -0700) | ||
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | |
Mon, 18 Apr 2005 02:52:54 +0000 (19:52 -0700) |
any unmerged files.
This one doesn't actually do the merging, but it makes it
easy to script the programs that do using it.
This one doesn't actually do the merging, but it makes it
easy to script the programs that do using it.
Makefile | patch | blob | history | |
merge-cache.c | [new file with mode: 0644] | patch | blob |
diff --git a/Makefile b/Makefile
index 871c0bb0411c4b54c25dd660d0c5297e9603d61c..76c4f7ca4f56e7c9a508fc5c6216db56a22a56c4 100644 (file)
--- a/Makefile
+++ b/Makefile
PROG= update-cache show-diff init-db write-tree read-tree commit-tree \
cat-file fsck-cache checkout-cache diff-tree rev-tree show-files \
- check-files ls-tree merge-base
+ check-files ls-tree merge-base merge-cache
all: $(PROG)
merge-base: merge-base.o read-cache.o
$(CC) $(CFLAGS) -o merge-base merge-base.o read-cache.o $(LIBS)
+merge-cache: merge-cache.o read-cache.o
+ $(CC) $(CFLAGS) -o merge-cache merge-cache.o read-cache.o $(LIBS)
+
read-cache.o: cache.h
show-diff.o: cache.h
diff --git a/merge-cache.c b/merge-cache.c
--- /dev/null
+++ b/merge-cache.c
@@ -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;
+}