int fmt_merge_msg(struct strbuf *in, struct strbuf *out, struct fmt_merge_msg_opts *opts) { int i = 0, pos = 0; unsigned char head_sha1[20]; const char *current_branch; void *current_branch_to_free; /* get current branch */ current_branch = current_branch_to_free = resolve_refdup("HEAD", head_sha1, 1, NULL); if (!current_branch) die("No current branch"); if (!prefixcmp(current_branch, "refs/heads/")) current_branch += 11; /* get a line */ while (pos < in->len) { int len; char *newline, *p = in->buf + pos; newline = strchr(p, '\n'); len = newline ? newline - p : strlen(p); pos += len + !!newline; i++; p[len] = 0; if (handle_line(p)) die ("Error in line %d: %.*s", i, len, p); } if (opts->add_title && srcs.nr) fmt_merge_msg_title(out, current_branch); if (origins.nr) fmt_merge_msg_sigs(out); if (opts->shortlog_len) { struct commit *head; struct rev_info rev; head = lookup_commit_or_die(head_sha1, "HEAD"); init_revisions(&rev, NULL); rev.commit_format = CMIT_FMT_ONELINE; rev.ignore_merges = 1; rev.limited = 1; if (suffixcmp(out->buf, "\n")) strbuf_addch(out, '\n'); for (i = 0; i < origins.nr; i++) shortlog(origins.items[i].string, origins.items[i].util, head, &rev, opts->shortlog_len, out); } strbuf_complete_line(out); free(current_branch_to_free); return 0; }
int cmd_merge_recursive(int argc, const char **argv, const char *prefix) { const unsigned char *bases[21]; unsigned bases_count = 0; int i, failed; unsigned char h1[20], h2[20]; struct merge_options o; struct commit *result; init_merge_options(&o); if (argv[0] && !suffixcmp(argv[0], "-subtree")) o.subtree_shift = ""; if (argc < 4) usagef(builtin_merge_recursive_usage, argv[0]); for (i = 1; i < argc; ++i) { const char *arg = argv[i]; if (!prefixcmp(arg, "--")) { if (!arg[2]) break; if (parse_merge_opt(&o, arg + 2)) die("Unknown option %s", arg); continue; } if (bases_count < ARRAY_SIZE(bases)-1) { unsigned char *sha = xmalloc(20); if (get_sha1(argv[i], sha)) die("Could not parse object '%s'", argv[i]); bases[bases_count++] = sha; } else warning("Cannot handle more than %d bases. " "Ignoring %s.", (int)ARRAY_SIZE(bases)-1, argv[i]); } if (argc - i != 3) /* "--" "<head>" "<remote>" */ die("Not handling anything other than two heads merge."); o.branch1 = argv[++i]; o.branch2 = argv[++i]; if (get_sha1(o.branch1, h1)) die("Could not resolve ref '%s'", o.branch1); if (get_sha1(o.branch2, h2)) die("Could not resolve ref '%s'", o.branch2); o.branch1 = better_branch_name(o.branch1); o.branch2 = better_branch_name(o.branch2); if (o.verbosity >= 3) printf("Merging %s with %s\n", o.branch1, o.branch2); failed = merge_recursive_generic(&o, h1, h2, bases_count, bases, &result); if (failed < 0) return 128; /* die() error code */ return failed; }
const char *get_java_home(void) { const char *result; if (absolute_java_home) return absolute_java_home; result = !relative_java_home ? NULL : ij_path(relative_java_home); if (result && is_java_home(result)) return result; if (result && (!suffixcmp(result, -1, "/jre") || !suffixcmp(result, -1, "/jre/")) && is_jre_home(result)) { char *new_eol = (char *)(result + strlen(result) - 4); *new_eol = '\0'; return result; } result = get_java_home_env(); if (result) return result; return discover_system_java_home(); }
static void write_followtags(const struct ref *refs, const char *msg) { const struct ref *ref; for (ref = refs; ref; ref = ref->next) { if (prefixcmp(ref->name, "refs/tags/")) continue; if (!suffixcmp(ref->name, "^{}")) continue; if (!has_sha1_file(ref->old_sha1)) continue; update_ref(msg, ref->name, ref->old_sha1, NULL, 0, DIE_ON_ERR); } }
static enum status_code add_to_refs(const char *id, size_t idlen, char *name, size_t namelen, struct ref_opt *opt) { struct ref *ref = NULL; enum reference_type type = REFERENCE_BRANCH; void **ref_slot = NULL; if (!prefixcmp(name, "refs/tags/")) { type = REFERENCE_TAG; if (!suffixcmp(name, namelen, "^{}")) { namelen -= 3; name[namelen] = 0; } else { type = REFERENCE_LOCAL_TAG; } namelen -= STRING_SIZE("refs/tags/"); name += STRING_SIZE("refs/tags/"); } else if (!prefixcmp(name, "refs/remotes/")) { type = REFERENCE_REMOTE; namelen -= STRING_SIZE("refs/remotes/"); name += STRING_SIZE("refs/remotes/"); if (!strcmp(opt->remote, name)) type = REFERENCE_TRACKED_REMOTE; } else if (!prefixcmp(name, "refs/replace/")) { type = REFERENCE_REPLACE; id = name + strlen("refs/replace/"); idlen = namelen - strlen("refs/replace/"); name = "replaced"; namelen = strlen(name); } else if (!prefixcmp(name, "refs/heads/")) { namelen -= STRING_SIZE("refs/heads/"); name += STRING_SIZE("refs/heads/"); if (strlen(opt->head) == namelen && !strncmp(opt->head, name, namelen)) type = REFERENCE_HEAD; } else if (!strcmp(name, "HEAD")) { /* Handle the case of HEAD not being a symbolic ref, * i.e. during a rebase. */ if (*opt->head) return SUCCESS; type = REFERENCE_HEAD; } /* If we are reloading or it's an annotated tag, replace the * previous SHA1 with the resolved commit id; relies on the fact * git-ls-remote lists the commit id of an annotated tag right * before the commit id it points to. */ if (type == REFERENCE_REPLACE) { ref = string_map_remove(&refs_by_id, id); } else { ref_slot = string_map_put_to(&refs_by_name, name); if (!ref_slot) return ERROR_OUT_OF_MEMORY; ref = *ref_slot; } if (!ref) { ref = calloc(1, sizeof(*ref) + namelen); if (!ref) return ERROR_OUT_OF_MEMORY; strncpy(ref->name, name, namelen); if (ref_slot) *ref_slot = ref; } if (strncmp(ref->id, id, idlen) || ref->type != type) { opt->changed |= WATCH_REFS; if (*ref->id) remove_ref_from_id_map(ref); } ref->valid = true; ref->type = type; string_ncopy_do(ref->id, SIZEOF_REV, id, idlen); if (type == REFERENCE_HEAD) { if (!refs_head || (refs_head != ref && memcmp(refs_head, ref, sizeof(*ref)))) opt->changed |= WATCH_HEAD; refs_head = ref; } if (type == REFERENCE_TAG) refs_tags++; return add_ref_to_id_map(ref); }
static int add_to_refs(const char *id, size_t idlen, char *name, size_t namelen, struct ref_opt *opt) { struct ref *ref = NULL; enum reference_type type = REFERENCE_BRANCH; int pos; if (!prefixcmp(name, "refs/tags/")) { type = REFERENCE_TAG; if (!suffixcmp(name, namelen, "^{}")) { namelen -= 3; name[namelen] = 0; } else { type = REFERENCE_LOCAL_TAG; } namelen -= STRING_SIZE("refs/tags/"); name += STRING_SIZE("refs/tags/"); } else if (!prefixcmp(name, "refs/remotes/")) { type = REFERENCE_REMOTE; namelen -= STRING_SIZE("refs/remotes/"); name += STRING_SIZE("refs/remotes/"); if (!strcmp(opt->remote, name)) type = REFERENCE_TRACKED_REMOTE; } else if (!prefixcmp(name, "refs/replace/")) { type = REFERENCE_REPLACE; id = name + strlen("refs/replace/"); idlen = namelen - strlen("refs/replace/"); name = "replaced"; namelen = strlen(name); } else if (!prefixcmp(name, "refs/heads/")) { namelen -= STRING_SIZE("refs/heads/"); name += STRING_SIZE("refs/heads/"); if (strlen(opt->head) == namelen && !strncmp(opt->head, name, namelen)) type = REFERENCE_HEAD; } else if (!strcmp(name, "HEAD")) { /* Handle the case of HEAD not being a symbolic ref, * i.e. during a rebase. */ if (*opt->head) return OK; type = REFERENCE_HEAD; } /* If we are reloading or it's an annotated tag, replace the * previous SHA1 with the resolved commit id; relies on the fact * git-ls-remote lists the commit id of an annotated tag right * before the commit id it points to. */ for (pos = 0; pos < refs_size; pos++) { int cmp = type == REFERENCE_REPLACE ? strcmp(id, refs[pos]->id) : strcmp(name, refs[pos]->name); if (!cmp) { ref = refs[pos]; break; } } if (!ref) { if (!realloc_refs(&refs, refs_size, 1)) return ERR; ref = calloc(1, sizeof(*ref) + namelen); if (!ref) return ERR; refs[refs_size++] = ref; strncpy(ref->name, name, namelen); } if (strncmp(ref->id, id, idlen)) opt->changed |= WATCH_REFS; ref->valid = TRUE; ref->type = type; string_ncopy_do(ref->id, SIZEOF_REV, id, idlen); if (type == REFERENCE_HEAD) { if (!refs_head || (refs_head != ref && memcmp(refs_head, ref, sizeof(*ref)))) opt->changed |= WATCH_HEAD; refs_head = ref; } return OK; }
static void find_non_local_tags(struct transport *transport, struct ref **head, struct ref ***tail) { struct string_list existing_refs = { NULL, 0, 0, 0 }; struct string_list remote_refs = { NULL, 0, 0, 0 }; struct tag_data data = {head, tail}; const struct ref *ref; struct string_list_item *item = NULL; for_each_ref(add_existing, &existing_refs); for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) { if (prefixcmp(ref->name, "refs/tags")) continue; /* * The peeled ref always follows the matching base * ref, so if we see a peeled ref that we don't want * to fetch then we can mark the ref entry in the list * as one to ignore by setting util to NULL. */ if (!suffixcmp(ref->name, "^{}")) { if (item && !has_sha1_file(ref->old_sha1) && !will_fetch(head, ref->old_sha1) && !has_sha1_file(item->util) && !will_fetch(head, item->util)) item->util = NULL; item = NULL; continue; } /* * If item is non-NULL here, then we previously saw a * ref not followed by a peeled reference, so we need * to check if it is a lightweight tag that we want to * fetch. */ if (item && !has_sha1_file(item->util) && !will_fetch(head, item->util)) item->util = NULL; item = NULL; /* skip duplicates and refs that we already have */ if (string_list_has_string(&remote_refs, ref->name) || string_list_has_string(&existing_refs, ref->name)) continue; item = string_list_insert(ref->name, &remote_refs); item->util = (void *)ref->old_sha1; } string_list_clear(&existing_refs, 0); /* * We may have a final lightweight tag that needs to be * checked to see if it needs fetching. */ if (item && !has_sha1_file(item->util) && !will_fetch(head, item->util)) item->util = NULL; /* * For all the tags in the remote_refs string list, call * add_to_tail to add them to the list of refs to be fetched */ for_each_string_list(add_to_tail, &remote_refs, &data); string_list_clear(&remote_refs, 0); }
static int add_to_refs(const char *id, size_t idlen, char *name, size_t namelen, struct ref_opt *opt) { struct ref *ref = NULL; bool tag = FALSE; bool ltag = FALSE; bool remote = FALSE; bool replace = FALSE; bool tracked = FALSE; bool head = FALSE; int pos; if (!prefixcmp(name, "refs/tags/")) { if (!suffixcmp(name, namelen, "^{}")) { namelen -= 3; name[namelen] = 0; } else { ltag = TRUE; } tag = TRUE; namelen -= STRING_SIZE("refs/tags/"); name += STRING_SIZE("refs/tags/"); } else if (!prefixcmp(name, "refs/remotes/")) { remote = TRUE; namelen -= STRING_SIZE("refs/remotes/"); name += STRING_SIZE("refs/remotes/"); tracked = !strcmp(opt->remote, name); } else if (!prefixcmp(name, "refs/replace/")) { replace = TRUE; id = name + strlen("refs/replace/"); idlen = namelen - strlen("refs/replace/"); name = "replaced"; namelen = strlen(name); } else if (!prefixcmp(name, "refs/heads/")) { namelen -= STRING_SIZE("refs/heads/"); name += STRING_SIZE("refs/heads/"); head = strlen(opt->head) == namelen && !strncmp(opt->head, name, namelen); } else if (!strcmp(name, "HEAD")) { /* Handle the case of HEAD not being a symbolic ref, * i.e. during a rebase. */ if (*opt->head) return OK; head = TRUE; } /* If we are reloading or it's an annotated tag, replace the * previous SHA1 with the resolved commit id; relies on the fact * git-ls-remote lists the commit id of an annotated tag right * before the commit id it points to. */ for (pos = 0; pos < refs_size; pos++) { int cmp = replace ? strcmp(id, refs[pos]->id) : strcmp(name, refs[pos]->name); if (!cmp) { ref = refs[pos]; break; } } if (!ref) { if (!realloc_refs(&refs, refs_size, 1)) return ERR; ref = calloc(1, sizeof(*ref) + namelen); if (!ref) return ERR; refs[refs_size++] = ref; strncpy(ref->name, name, namelen); } ref->valid = TRUE; ref->head = head; ref->tag = tag; ref->ltag = ltag; ref->remote = remote; ref->replace = replace; ref->tracked = tracked; string_ncopy_do(ref->id, SIZEOF_REV, id, idlen); if (head) refs_head = ref; return OK; }
char *discover_system_java_home(void) { #ifdef WIN32 HKEY key; HRESULT result; const char *key_root = "SOFTWARE\\JavaSoft\\Java Development Kit"; struct string *string; char buffer[PATH_MAX]; DWORD valuelen = sizeof(buffer); result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key_root, 0, KEY_READ, &key); if (ERROR_SUCCESS != result) return NULL; result = RegQueryValueEx(key, "CurrentVersion", NULL, NULL, (LPBYTE)buffer, &valuelen); RegCloseKey(key); if (ERROR_SUCCESS != result) { error(get_win_error()); return NULL; } string = string_initf("%s\\%s", key_root, buffer); result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, string->buffer, 0, KEY_READ, &key); if (ERROR_SUCCESS != result) return NULL; valuelen = sizeof(buffer); result = RegQueryValueEx(key, "JavaHome", NULL, NULL, (LPBYTE)buffer, &valuelen); RegCloseKey(key); if (ERROR_SUCCESS != result) return NULL; return strdup(buffer); #else const char *java_executable = find_in_path(get_java_command(), 0); #ifdef __APPLE__ int len = strlen(java_executable); if (len > 14 && !suffixcmp(java_executable, len, "/Commands/java")) { /* * Containing folder is not a JRE or JDK, it's an Apple Framework. Bah! * For example, the path: * * /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands * * does not actually contain a proper JRE. It is merely a Framework * for the current version of Apple Java on the system. * * Unfortunately, on OS X, /usr/bin/java is typically symlinked to * /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java, * with Current symlinked to A, resulting in a failure of this PATH-based * strategy to find the actual JRE. So we simply give up in that case. */ if (debug) error("Ignoring Apple Framework java executable: '%s'", java_executable); return NULL; } #endif if (java_executable) { char *path = strdup(java_executable); const char *suffixes[] = { "java", "\\", "/", "bin", "\\", "/", NULL }; int len = strlen(path), i; for (i = 0; suffixes[i]; i++) if (!suffixcmp(path, len, suffixes[i])) { len -= strlen(suffixes[i]); path[len] = '\0'; } return path; } return NULL; #endif }
const char *get_jre_home(void) { const char *result; int len; static struct string *jre; static int initialized; if (jre) return jre->buffer; if (initialized) return NULL; initialized = 1; /* ImageJ 1.x ships the JRE in <ij.dir>/jre/ */ result = legacy_jre_path ? legacy_jre_path->buffer : ij_path("jre"); if (dir_exists(result)) { struct string *libjvm = string_initf("%s/%s", result, default_library_path); if (!file_exists(libjvm->buffer)) { if (debug) error("Invalid jre/: '%s' does not exist!", libjvm->buffer); } else if (!is_native_library(libjvm->buffer)) { if (debug) error("Invalid jre/: '%s' is not a %s library!", libjvm->buffer, get_platform()); } else { string_release(libjvm); jre = string_initf("%s", result); if (debug) error("JRE found in '%s'", jre->buffer); return jre->buffer; } string_release(libjvm); } else { if (debug) error("JRE not found in '%s'", result); } result = get_java_home(); if (!result) { const char *jre_home = getenv("JRE_HOME"); if (jre_home && *jre_home && is_jre_home(jre_home)) { jre = string_copy(jre_home); if (debug) error("Found a JRE in JRE_HOME: %s", jre->buffer); return jre->buffer; } jre_home = getenv("JAVA_HOME"); if (jre_home && *jre_home && is_jre_home(jre_home)) { jre = string_copy(jre_home); if (debug) error("Found a JRE in JAVA_HOME: %s", jre->buffer); return jre->buffer; } if (debug) error("No JRE was found in default locations"); return NULL; } len = strlen(result); if (len > 4 && !suffixcmp(result, len, "/jre")) { jre = string_copy(result); if (debug) error("JAVA_HOME points to a JRE: '%s'", result); return jre->buffer; } jre = string_initf("%s/jre", result); if (dir_exists(jre->buffer)) { if (debug) error("JAVA_HOME contains a JRE: '%s'", jre->buffer); return jre->buffer; } string_set(jre, result); if (debug) error("JAVA_HOME appears to be a JRE: '%s'", jre->buffer); return jre->buffer; }