From: Linus Torvalds Date: Tue, 19 Apr 2005 21:00:34 +0000 (-0700) Subject: Add stupid "git export" thing, which can export a git archive X-Git-Tag: v0.99~808 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=c9823a427a0a7aabc4f840a90e82548e91f9bdd6;p=git.git Add stupid "git export" thing, which can export a git archive 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. --- diff --git a/Makefile b/Makefile index 390bd3263..57181be36 100644 --- 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 index 000000000..cf40946cf --- /dev/null +++ b/git-export.c @@ -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; +}