Code

Add stupid "git export" thing, which can export a git archive
authorLinus Torvalds <torvalds@ppc970.osdl.org.(none)>
Tue, 19 Apr 2005 21:00:34 +0000 (14:00 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org.(none)>
Tue, 19 Apr 2005 21:00:34 +0000 (14:00 -0700)
as a set of patches and commentary.

You'd want something like this if you are tracking a git archive
in another SCM format. Notably, we want something like that for
BK users.

Makefile
git-export.c [new file with mode: 0644]

index 390bd32639a241d648c84ae3b2b0893a029bdda8..57181be3676942744aff33796d52d417c80cdc61 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ AR=ar
 
 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 merge-cache unpack-file
+       check-files ls-tree merge-base merge-cache unpack-file git-export
 
 all: $(PROG)
 
@@ -81,6 +81,9 @@ merge-cache: merge-cache.o $(LIB_FILE)
 unpack-file: unpack-file.o $(LIB_FILE)
        $(CC) $(CFLAGS) -o unpack-file unpack-file.o $(LIBS)
 
+git-export: git-export.o $(LIB_FILE)
+       $(CC) $(CFLAGS) -o git-export git-export.o $(LIBS)
+
 blob.o: $(LIB_H)
 cat-file.o: $(LIB_H)
 check-files.o: $(LIB_H)
@@ -89,6 +92,7 @@ commit.o: $(LIB_H)
 commit-tree.o: $(LIB_H)
 diff-tree.o: $(LIB_H)
 fsck-cache.o: $(LIB_H)
+git_export.o: $(LIB_H)
 init-db.o: $(LIB_H)
 ls-tree.o: $(LIB_H)
 merge-base.o: $(LIB_H)
diff --git a/git-export.c b/git-export.c
new file mode 100644 (file)
index 0000000..cf40946
--- /dev/null
@@ -0,0 +1,81 @@
+#include "cache.h"
+#include "commit.h"
+
+/*
+ * Show one commit
+ */
+void show_commit(struct commit *commit)
+{
+       char cmdline[400];
+       char hex[100];
+
+       strcpy(hex, sha1_to_hex(commit->object.sha1));
+       printf("Id: %s\n", hex);
+       fflush(NULL);
+       sprintf(cmdline, "cat-file commit %s", hex);
+       system(cmdline);
+       if (commit->parents) {
+               char *against = sha1_to_hex(commit->parents->item->object.sha1);
+               printf("\n\n======== diff against %s ========\n", against);
+               fflush(NULL);
+               sprintf(cmdline, "git diff %s %s", against, hex);
+               system(cmdline);
+       }
+       printf("======== end ========\n\n");
+}
+
+/*
+ * Show all unseen commits, depth-first
+ */
+void show_unseen(struct commit *top)
+{
+       struct commit_list *parents;
+
+       if (top->object.flags & 2)
+               return;
+       top->object.flags |= 2;
+       parents = top->parents;
+       while (parents) {
+               show_unseen(parents->item);
+               parents = parents->next;
+       }
+       show_commit(top);
+}
+
+void export(struct commit *top, struct commit *base)
+{
+       mark_reachable(&top->object, 1);
+       if (base)
+               mark_reachable(&base->object, 2);
+       show_unseen(top);
+}
+
+struct commit *get_commit(unsigned char *sha1)
+{
+       struct commit *commit = lookup_commit(sha1);
+       if (!commit->object.parsed) {
+               struct commit_list *parents;
+
+               if (parse_commit(commit) < 0)
+                       die("unable to parse commit %s", sha1_to_hex(sha1));
+               parents = commit->parents;
+               while (parents) {
+                       get_commit(parents->item->object.sha1);
+                       parents = parents->next;
+               }
+       }
+       return commit;
+}
+
+int main(int argc, char **argv)
+{
+       unsigned char base_sha1[20];
+       unsigned char top_sha1[20];
+
+       if (argc < 2 || argc > 4 ||
+           get_sha1_hex(argv[1], top_sha1) ||
+           (argc == 3 && get_sha1_hex(argv[2], base_sha1)))
+               usage("git-export top [base]");
+       export(get_commit(top_sha1), argc==3 ? get_commit(base_sha1) : NULL);
+       return 0;
+}