From: Junio C Hamano Date: Sun, 8 Jan 2006 22:22:19 +0000 (-0800) Subject: GIT 1.1.0 X-Git-Tag: v1.1.0^0 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/5a2282de13c4da13f979185e652c8a08e2481fd1?ds=inline;hp=-c GIT 1.1.0 --- 5a2282de13c4da13f979185e652c8a08e2481fd1 diff --combined Makefile index 1b6caf85bb,119a45f7bc..c9c15b5ff2 --- a/Makefile +++ b/Makefile @@@ -55,9 -55,7 +55,9 @@@ all # Define USE_STDEV below if you want git to care about the underlying device # change being considered an inode change from the update-cache perspective. -GIT_VERSION = 1.0.8 +GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE + @sh ./GIT-VERSION-GEN +-include GIT-VERSION-FILE # CFLAGS and LDFLAGS are for the users to override from the command line. @@@ -137,8 -135,7 +137,8 @@@ PROGRAMS = git-unpack-objects$X git-update-index$X git-update-server-info$X \ git-upload-pack$X git-verify-pack$X git-write-tree$X \ git-update-ref$X git-symbolic-ref$X git-check-ref-format$X \ - git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X + git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \ + git-describe$X # what 'all' will build and 'install' will install. ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) git$X @@@ -371,7 -368,7 +371,7 @@@ all: $(ALL_PROGRAMS all: $(MAKE) -C templates -git$X: git.c $(LIB_FILE) Makefile +git$X: git.c $(LIB_FILE) $(CC) -DGIT_EXEC_PATH='"$(bindir)"' -DGIT_VERSION='"$(GIT_VERSION)"' \ $(CFLAGS) $(COMPAT_CFLAGS) -o $@ $(filter %.c,$^) $(LIB_FILE) @@@ -400,12 -397,8 +400,12 @@@ $(patsubst %.py,%,$(SCRIPT_PYTHON)) : git-cherry-pick: git-revert cp $< $@ -# format-patch records GIT_VERSION -git-format-patch: Makefile +# These can record GIT_VERSION +git$X git.spec \ + $(patsubst %.sh,%,$(SCRIPT_SH)) \ + $(patsubst %.perl,%,$(SCRIPT_PERL)) \ + $(patsubst %.py,%,$(SCRIPT_PYTHON)) \ + : GIT-VERSION-FILE %.o: %.c $(CC) -o $*.o -c $(ALL_CFLAGS) $< @@@ -481,7 -474,7 +481,7 @@@ install-doc ### Maintainer's dist rules -git.spec: git.spec.in Makefile +git.spec: git.spec.in sed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@ GIT_TARNAME=git-$(GIT_VERSION) @@@ -496,12 -489,6 +496,6 @@@ dist: git.spec git-tar-tre rpm: dist $(RPMBUILD) -ta $(GIT_TARNAME).tar.gz - deb: dist - rm -rf $(GIT_TARNAME) - $(TAR) zxf $(GIT_TARNAME).tar.gz - dpkg-source -b $(GIT_TARNAME) - cd $(GIT_TARNAME) && fakeroot debian/rules binary - ### Cleaning rules clean: @@@ -511,13 -498,7 +505,11 @@@ rm -f *.spec *.pyc *.pyo */*.pyc */*.pyo rm -rf $(GIT_TARNAME) rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz - rm -f git-core_$(GIT_VERSION)-*.dsc - rm -f git-*_$(GIT_VERSION)-*.deb $(MAKE) -C Documentation/ clean $(MAKE) -C templates clean $(MAKE) -C t/ clean + rm -f GIT-VERSION-FILE + +.PHONY: all install clean +.PHONY: .FORCE-GIT-VERSION-FILE diff --combined cache.h index a99fb3ce7d,5fd2687636..29c9e819d6 --- a/cache.h +++ b/cache.h @@@ -81,7 -81,7 +81,7 @@@ struct cache_entry unsigned int ce_size; unsigned char sha1[20]; unsigned short ce_flags; - char name[0]; + char name[FLEX_ARRAY]; /* more */ }; #define CE_NAMEMASK (0x0fff) @@@ -159,7 -159,6 +159,7 @@@ extern void rollback_index_file(struct extern int trust_executable_bit; extern int only_use_symrefs; extern int diff_rename_limit_default; +extern int shared_repository; #define GIT_REPO_VERSION 0 extern int repository_format_version; @@@ -184,7 -183,6 +184,7 @@@ extern const unsigned char null_sha1[20 int git_mkstemp(char *path, size_t n, const char *template); +int adjust_shared_perm(const char *path); int safe_create_leading_directories(char *path); char *safe_strncpy(char *, const char *, size_t); char *enter_repo(char *path, int strict); @@@ -259,7 -257,7 +259,7 @@@ extern int checkout_entry(struct cache_ extern struct alternate_object_database { struct alternate_object_database *next; char *name; - char base[0]; /* more */ + char base[FLEX_ARRAY]; /* more */ } *alt_odb_list; extern void prepare_alt_odb(void); @@@ -273,7 -271,8 +273,8 @@@ extern struct packed_git unsigned int pack_use_cnt; int pack_local; unsigned char sha1[20]; - char pack_name[0]; /* something like ".git/objects/pack/xxxxx.pack" */ + /* something like ".git/objects/pack/xxxxx.pack" */ + char pack_name[FLEX_ARRAY]; /* more */ } *packed_git; struct pack_entry { @@@ -288,7 -287,7 +289,7 @@@ struct ref unsigned char new_sha1[20]; unsigned char force; struct ref *peer_ref; /* when renaming */ - char name[0]; + char name[FLEX_ARRAY]; /* more */ }; extern int git_connect(int fd[2], char *url, const char *prog); diff --combined commit.c index e9a29caa27,fb02ba609b..56efc69f1f --- a/commit.c +++ b/commit.c @@@ -1,6 -1,6 +1,6 @@@ + #include "cache.h" #include "tag.h" #include "commit.h" - #include "cache.h" int save_commit_buffer = 1; @@@ -352,19 -352,6 +352,19 @@@ struct commit *pop_most_recent_commit(s return ret; } +void clear_commit_marks(struct commit *commit, unsigned int mark) +{ + struct commit_list *parents; + + parents = commit->parents; + commit->object.flags &= ~mark; + while (parents) { + if (parents->item && parents->item->object.parsed) + clear_commit_marks(parents->item, mark); + parents = parents->next; + } +} + /* * Generic support for pretty-printing the header */ diff --combined describe.c index 00fa02adcc,0000000000..a0180f548e mode 100644,000000..100644 --- a/describe.c +++ b/describe.c @@@ -1,164 -1,0 +1,164 @@@ +#include "cache.h" +#include "commit.h" +#include "tag.h" +#include "refs.h" + +#define SEEN (1u << 0) + +static const char describe_usage[] = +"git-describe [--all] [--tags] [--abbrev=] *"; + +static int all = 0; /* Default to annotated tags only */ +static int tags = 0; /* But allow any tags if --tags is specified */ + +#define DEFAULT_ABBREV 8 /* maybe too many */ +static int abbrev = DEFAULT_ABBREV; + +static int names = 0, allocs = 0; +static struct commit_name { + const struct commit *commit; + int prio; /* annotated tag = 2, tag = 1, head = 0 */ - char path[]; ++ char path[FLEX_ARRAY]; /* more */ +} **name_array = NULL; + +static struct commit_name *match(struct commit *cmit) +{ + int i = names; + struct commit_name **p = name_array; + + while (i-- > 0) { + struct commit_name *n = *p++; + if (n->commit == cmit) + return n; + } + return NULL; +} + +static void add_to_known_names(const char *path, + const struct commit *commit, + int prio) +{ + int idx; + int len = strlen(path)+1; + struct commit_name *name = xmalloc(sizeof(struct commit_name) + len); + + name->commit = commit; + name->prio = prio; + memcpy(name->path, path, len); + idx = names; + if (idx >= allocs) { + allocs = (idx + 50) * 3 / 2; + name_array = xrealloc(name_array, allocs*sizeof(*name_array)); + } + name_array[idx] = name; + names = ++idx; +} + +static int get_name(const char *path, const unsigned char *sha1) +{ + struct commit *commit = lookup_commit_reference_gently(sha1, 1); + struct object *object; + int prio; + + if (!commit) + return 0; + object = parse_object(sha1); + /* If --all, then any refs are used. + * If --tags, then any tags are used. + * Otherwise only annotated tags are used. + */ + if (!strncmp(path, "refs/tags/", 10)) { + if (object->type == tag_type) + prio = 2; + else + prio = 1; + } + else + prio = 0; + + if (!all) { + if (!prio) + return 0; + if (!tags && prio < 2) + return 0; + } + add_to_known_names(all ? path + 5 : path + 10, commit, prio); + return 0; +} + +static int compare_names(const void *_a, const void *_b) +{ + struct commit_name *a = *(struct commit_name **)_a; + struct commit_name *b = *(struct commit_name **)_b; + unsigned long a_date = a->commit->date; + unsigned long b_date = b->commit->date; + + if (a->prio != b->prio) + return b->prio - a->prio; + return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1; +} + +static void describe(struct commit *cmit) +{ + struct commit_list *list; + static int initialized = 0; + struct commit_name *n; + + if (!initialized) { + initialized = 1; + for_each_ref(get_name); + qsort(name_array, names, sizeof(*name_array), compare_names); + } + + n = match(cmit); + if (n) { + printf("%s\n", n->path); + return; + } + + list = NULL; + commit_list_insert(cmit, &list); + while (list) { + struct commit *c = pop_most_recent_commit(&list, SEEN); + n = match(c); + if (n) { + printf("%s-g%s\n", n->path, + find_unique_abbrev(cmit->object.sha1, abbrev)); + break; + } + } + clear_commit_marks(cmit, SEEN); +} + +int main(int argc, char **argv) +{ + int i; + + for (i = 1; i < argc; i++) { + const char *arg = argv[i]; + unsigned char sha1[20]; + struct commit *cmit; + + if (!strcmp(arg, "--all")) { + all = 1; + continue; + } + if (!strcmp(arg, "--tags")) { + tags = 1; + continue; + } + if (!strncmp(arg, "--abbrev=", 9)) { + abbrev = strtoul(arg + 9, NULL, 10); + if (abbrev < 4 || 40 <= abbrev) + abbrev = DEFAULT_ABBREV; + continue; + } + if (get_sha1(arg, sha1) < 0) + usage(describe_usage); + cmit = lookup_commit_reference(sha1); + if (!cmit) + usage(describe_usage); + describe(cmit); + } + return 0; +} diff --combined ls-files.c index b29fe1be7e,74ec8c0aee..6af3b091b0 --- a/ls-files.c +++ b/ls-files.c @@@ -19,7 -19,6 +19,7 @@@ static int show_stage = 0 static int show_unmerged = 0; static int show_modified = 0; static int show_killed = 0; +static int show_other_directories = 0; static int line_terminator = '\n'; static int prefix_len = 0, prefix_offset = 0; @@@ -209,7 -208,7 +209,7 @@@ static int excluded(const char *pathnam struct nond_on_fs { int len; - char name[0]; + char name[FLEX_ARRAY]; /* more */ }; static struct nond_on_fs **dir; @@@ -234,17 -233,6 +234,17 @@@ static void add_name(const char *pathna dir[nr_dir++] = ent; } +static int dir_exists(const char *dirname, int len) +{ + int pos = cache_name_pos(dirname, len); + if (pos >= 0) + return 1; + pos = -pos-1; + if (pos >= active_nr) /* can't */ + return 0; + return !strncmp(active_cache[pos]->name, dirname, len); +} + /* * Read a directory tree. We currently ignore anything but * directories, regular files and symlinks. That's because git @@@ -293,12 -281,8 +293,12 @@@ static void read_directory(const char * /* fallthrough */ case DT_DIR: memcpy(fullname + baselen + len, "/", 2); + len++; + if (show_other_directories && + !dir_exists(fullname, baselen + len)) + break; read_directory(fullname, fullname, - baselen + len + 1); + baselen + len); continue; case DT_REG: case DT_LNK: @@@ -638,10 -622,6 +638,10 @@@ int main(int argc, const char **argv show_killed = 1; continue; } + if (!strcmp(arg, "--directory")) { + show_other_directories = 1; + continue; + } if (!strcmp(arg, "-u") || !strcmp(arg, "--unmerged")) { /* There's no point in showing unmerged unless * you also show the stage information. diff --combined receive-pack.c index e79de917b5,ce986fe11c..f847ec2b54 --- a/receive-pack.c +++ b/receive-pack.c @@@ -8,36 -8,23 +8,36 @@@ static const char receive_pack_usage[] static const char unpacker[] = "git-unpack-objects"; +static int report_status = 0; + +static char capabilities[] = "report-status"; +static int capabilities_sent = 0; + static int show_ref(const char *path, const unsigned char *sha1) { - packet_write(1, "%s %s\n", sha1_to_hex(sha1), path); + if (capabilities_sent) + packet_write(1, "%s %s\n", sha1_to_hex(sha1), path); + else + packet_write(1, "%s %s%c%s\n", + sha1_to_hex(sha1), path, 0, capabilities); + capabilities_sent = 1; return 0; } static void write_head_info(void) { for_each_ref(show_ref); + if (!capabilities_sent) + show_ref("capabilities^{}", null_sha1); + } struct command { struct command *next; - unsigned char updated; + const char *error_string; unsigned char old_sha1[20]; unsigned char new_sha1[20]; - char ref_name[0]; + char ref_name[FLEX_ARRAY]; /* more */ }; static struct command *commands = NULL; @@@ -84,37 -71,33 +84,37 @@@ static int run_update_hook(const char * case 0: return 0; case -ERR_RUN_COMMAND_FORK: - die("hook fork failed"); + return error("hook fork failed"); case -ERR_RUN_COMMAND_EXEC: - die("hook execute failed"); + return error("hook execute failed"); case -ERR_RUN_COMMAND_WAITPID: - die("waitpid failed"); + return error("waitpid failed"); case -ERR_RUN_COMMAND_WAITPID_WRONG_PID: - die("waitpid is confused"); + return error("waitpid is confused"); case -ERR_RUN_COMMAND_WAITPID_SIGNAL: - fprintf(stderr, "%s died of signal\n", update_hook); - return -1; + return error("%s died of signal\n", update_hook); case -ERR_RUN_COMMAND_WAITPID_NOEXIT: - die("%s died strangely", update_hook); + return error("%s died strangely", update_hook); default: error("%s exited with error code %d", update_hook, -code); return -code; } } -static int update(const char *name, - unsigned char *old_sha1, unsigned char *new_sha1) +static int update(struct command *cmd) { + const char *name = cmd->ref_name; + unsigned char *old_sha1 = cmd->old_sha1; + unsigned char *new_sha1 = cmd->new_sha1; char new_hex[60], *old_hex, *lock_name; int newfd, namelen, written; - if (!strncmp(name, "refs/", 5) && check_ref_format(name + 5)) + cmd->error_string = NULL; + if (!strncmp(name, "refs/", 5) && check_ref_format(name + 5)) { + cmd->error_string = "funny refname"; return error("refusing to create funny ref '%s' locally", name); + } namelen = strlen(name); lock_name = xmalloc(namelen + 10); @@@ -123,19 -106,16 +123,19 @@@ strcpy(new_hex, sha1_to_hex(new_sha1)); old_hex = sha1_to_hex(old_sha1); - if (!has_sha1_file(new_sha1)) + if (!has_sha1_file(new_sha1)) { + cmd->error_string = "bad pack"; return error("unpack should have generated %s, " "but I can't find it!", new_hex); - + } safe_create_leading_directories(lock_name); newfd = open(lock_name, O_CREAT | O_EXCL | O_WRONLY, 0666); - if (newfd < 0) + if (newfd < 0) { + cmd->error_string = "can't lock"; return error("unable to create %s (%s)", lock_name, strerror(errno)); + } /* Write the ref with an ending '\n' */ new_hex[40] = '\n'; @@@ -147,22 -127,18 +147,22 @@@ close(newfd); if (written != 41) { unlink(lock_name); + cmd->error_string = "can't write"; return error("unable to write %s", lock_name); } if (verify_old_ref(name, old_hex) < 0) { unlink(lock_name); + cmd->error_string = "raced"; return error("%s changed during push", name); } if (run_update_hook(name, old_hex, new_hex)) { unlink(lock_name); + cmd->error_string = "hook declined"; return error("hook declined to update %s\n", name); } else if (rename(lock_name, name) < 0) { unlink(lock_name); + cmd->error_string = "can't rename"; return error("unable to replace %s", name); } else { @@@ -182,7 -158,7 +182,7 @@@ static void run_update_post_hook(struc if (access(update_post_hook, X_OK) < 0) return; for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) { - if (!cmd_p->updated) + if (cmd_p->error_string) continue; argc++; } @@@ -190,7 -166,7 +190,7 @@@ argv[0] = update_post_hook; for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) { - if (!cmd_p->updated) + if (cmd_p->error_string) continue; argv[argc] = xmalloc(strlen(cmd_p->ref_name) + 1); strcpy(argv[argc], cmd_p->ref_name); @@@ -209,7 -185,8 +209,7 @@@ static void execute_commands(void struct command *cmd = commands; while (cmd) { - cmd->updated = !update(cmd->ref_name, - cmd->old_sha1, cmd->new_sha1); + update(cmd); cmd = cmd->next; } run_update_post_hook(commands); @@@ -222,8 -199,7 +222,8 @@@ static void read_head_info(void static char line[1000]; unsigned char old_sha1[20], new_sha1[20]; struct command *cmd; - int len; + char *refname; + int len, reflen; len = packet_read_line(0, line, sizeof(line)); if (!len) @@@ -235,66 -211,38 +235,66 @@@ line[81] != ' ' || get_sha1_hex(line, old_sha1) || get_sha1_hex(line + 41, new_sha1)) - die("protocol error: expected old/new/ref, got '%s'", line); + die("protocol error: expected old/new/ref, got '%s'", + line); + + refname = line + 82; + reflen = strlen(refname); + if (reflen + 82 < len) { + if (strstr(refname + reflen + 1, "report-status")) + report_status = 1; + } cmd = xmalloc(sizeof(struct command) + len - 80); memcpy(cmd->old_sha1, old_sha1, 20); memcpy(cmd->new_sha1, new_sha1, 20); memcpy(cmd->ref_name, line + 82, len - 81); + cmd->error_string = "n/a (unpacker error)"; cmd->next = NULL; *p = cmd; p = &cmd->next; } } -static void unpack(void) +static const char *unpack(int *error_code) { int code = run_command(unpacker, NULL); + + *error_code = 0; switch (code) { case 0: - return; + return NULL; case -ERR_RUN_COMMAND_FORK: - die("unpack fork failed"); + return "unpack fork failed"; case -ERR_RUN_COMMAND_EXEC: - die("unpack execute failed"); + return "unpack execute failed"; case -ERR_RUN_COMMAND_WAITPID: - die("waitpid failed"); + return "waitpid failed"; case -ERR_RUN_COMMAND_WAITPID_WRONG_PID: - die("waitpid is confused"); + return "waitpid is confused"; case -ERR_RUN_COMMAND_WAITPID_SIGNAL: - die("%s died of signal", unpacker); + return "unpacker died of signal"; case -ERR_RUN_COMMAND_WAITPID_NOEXIT: - die("%s died strangely", unpacker); + return "unpacker died strangely"; default: - die("%s exited with error code %d", unpacker, -code); + *error_code = -code; + return "unpacker exited with error code"; + } +} + +static void report(const char *unpack_status) +{ + struct command *cmd; + packet_write(1, "unpack %s\n", + unpack_status ? unpack_status : "ok"); + for (cmd = commands; cmd; cmd = cmd->next) { + if (!cmd->error_string) + packet_write(1, "ok %s\n", + cmd->ref_name); + else + packet_write(1, "ng %s %s\n", + cmd->ref_name, cmd->error_string); } + packet_flush(1); } int main(int argc, char **argv) @@@ -327,12 -275,8 +327,12 @@@ read_head_info(); if (commands) { - unpack(); - execute_commands(); + int code; + const char *unpack_status = unpack(&code); + if (!unpack_status) + execute_commands(); + if (report_status) + report(unpack_status); } return 0; }