void grep_source_init(struct grep_source *gs, enum grep_source_type type, const char *name, const char *path, const void *identifier) { gs->type = type; gs->name = xstrdup_or_null(name); gs->path = xstrdup_or_null(path); gs->buf = NULL; gs->size = 0; gs->driver = NULL; switch (type) { case GREP_SOURCE_FILE: gs->identifier = xstrdup(identifier); break; case GREP_SOURCE_SUBMODULE: if (!identifier) { gs->identifier = NULL; break; } /* * FALL THROUGH * If the identifier is non-NULL (in the submodule case) it * will be a SHA1 that needs to be copied. */ case GREP_SOURCE_OID: gs->identifier = oiddup(identifier); break; case GREP_SOURCE_BUF: gs->identifier = NULL; break; } }
int walker_targets_stdin(char ***target, const char ***write_ref) { int targets = 0, targets_alloc = 0; struct strbuf buf = STRBUF_INIT; *target = NULL; *write_ref = NULL; while (1) { char *rf_one = NULL; char *tg_one; if (strbuf_getline(&buf, stdin, '\n') == EOF) break; tg_one = buf.buf; rf_one = strchr(tg_one, '\t'); if (rf_one) *rf_one++ = 0; if (targets >= targets_alloc) { targets_alloc = targets_alloc ? targets_alloc * 2 : 64; REALLOC_ARRAY(*target, targets_alloc); REALLOC_ARRAY(*write_ref, targets_alloc); } (*target)[targets] = xstrdup(tg_one); (*write_ref)[targets] = xstrdup_or_null(rf_one); targets++; } strbuf_release(&buf); return targets; }
struct ref_update *ref_transaction_add_update( struct ref_transaction *transaction, const char *refname, unsigned int flags, const unsigned char *new_sha1, const unsigned char *old_sha1, const char *msg) { struct ref_update *update; if (transaction->state != REF_TRANSACTION_OPEN) die("BUG: update called for transaction that is not open"); if ((flags & REF_ISPRUNING) && !(flags & REF_NODEREF)) die("BUG: REF_ISPRUNING set without REF_NODEREF"); FLEX_ALLOC_STR(update, refname, refname); ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc); transaction->updates[transaction->nr++] = update; update->flags = flags; if (flags & REF_HAVE_NEW) hashcpy(update->new_sha1, new_sha1); if (flags & REF_HAVE_OLD) hashcpy(update->old_sha1, old_sha1); update->msg = xstrdup_or_null(msg); return update; }
void repo_set_gitdir(struct repository *repo, const char *root, const struct set_gitdir_args *o) { const char *gitfile = read_gitfile(root); /* * repo->gitdir is saved because the caller could pass "root" * that also points to repo->gitdir. We want to keep it alive * until after xstrdup(root). Then we can free it. */ char *old_gitdir = repo->gitdir; repo->gitdir = xstrdup(gitfile ? gitfile : root); free(old_gitdir); repo_set_commondir(repo, o->commondir); expand_base_dir(&repo->objects->objectdir, o->object_dir, repo->commondir, "objects"); free(repo->objects->alternate_db); repo->objects->alternate_db = xstrdup_or_null(o->alternate_db); expand_base_dir(&repo->graft_file, o->graft_file, repo->commondir, "info/grafts"); expand_base_dir(&repo->index_file, o->index_file, repo->gitdir, "index"); }
char *refs_resolve_refdup(struct ref_store *refs, const char *refname, int resolve_flags, unsigned char *sha1, int *flags) { const char *result; result = refs_resolve_ref_unsafe(refs, refname, resolve_flags, sha1, flags); return xstrdup_or_null(result); }
static void save_env_before_alias(void) { int i; assert(save_restore_env_balance == 0); save_restore_env_balance = 1; orig_cwd = xgetcwd(); for (i = 0; i < ARRAY_SIZE(env_names); i++) { orig_env[i] = getenv(env_names[i]); orig_env[i] = xstrdup_or_null(orig_env[i]); } }
static int receive_status(int in, struct ref *refs) { struct ref *hint; int ret; hint = NULL; ret = receive_unpack_status(in); while (1) { char *refname; char *msg; char *line = packet_read_line(in, NULL); if (!line) break; if (!starts_with(line, "ok ") && !starts_with(line, "ng ")) { error("invalid ref status from remote: %s", line); ret = -1; break; } refname = line + 3; msg = strchr(refname, ' '); if (msg) *msg++ = '\0'; /* first try searching at our hint, falling back to all refs */ if (hint) hint = find_ref_by_name(hint, refname); if (!hint) hint = find_ref_by_name(refs, refname); if (!hint) { warning("remote reported status on unknown ref: %s", refname); continue; } if (hint->status != REF_STATUS_EXPECTING_REPORT) { warning("remote reported status on unexpected ref: %s", refname); continue; } if (line[0] == 'o' && line[1] == 'k') hint->status = REF_STATUS_OK; else { hint->status = REF_STATUS_REMOTE_REJECT; ret = -1; } hint->remote_status = xstrdup_or_null(msg); /* start our next search from the next ref */ hint = hint->next; } return ret; }
void grep_source_init(struct grep_source *gs, enum grep_source_type type, const char *name, const char *path, const void *identifier) { gs->type = type; gs->name = xstrdup_or_null(name); gs->path = xstrdup_or_null(path); gs->buf = NULL; gs->size = 0; gs->driver = NULL; switch (type) { case GREP_SOURCE_FILE: gs->identifier = xstrdup(identifier); break; case GREP_SOURCE_SHA1: gs->identifier = xmalloc(20); hashcpy(gs->identifier, identifier); break; case GREP_SOURCE_BUF: gs->identifier = NULL; } }
static char * getAutoDirName (char *buffer) { char *dir = getUserCacheDir (); if (dir == NULL) return NULL; sprintf (buffer, "%s/autosave", dir); if (access (buffer, F_OK) == -1) if (GFileMkDirP (buffer) == -1) return NULL; dir = xstrdup_or_null (buffer); return dir; }
FontInstance *GDrawInstanciateFont(GWindow gw, FontRequest *rq) { struct font_instance *fi; if (gw == NULL) gw = GDrawGetRoot(NULL); if ( rq->point_size<0 ) /* It's in pixels, not points, convert to points */ rq->point_size = PixelToPoint(-rq->point_size, ((GXWindow) gw)->display->res); fi = xcalloc(1,sizeof(struct font_instance)); fi->rq = *rq; fi->rq.family_name = x_u32_strdup_or_null( fi->rq.family_name ); fi->rq.utf8_family_name = xstrdup_or_null( fi->rq.utf8_family_name ); return( fi ); }
char * GIO_PasswordCache (char *proto, char *host, char *username, char *password) { int i; #ifdef HAVE_PTHREAD_H static pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER; #endif if (proto == NULL || host == NULL || username == NULL) return (password); #ifdef HAVE_PTHREAD_H pthread_mutex_lock (&mymutex); #endif for (i = 0; i < pc_cnt; ++i) { if (strcasecmp (proto, pc[i].proto) == 0 && strcasecmp (host, pc[i].host) == 0 && strcmp (username, pc[i].username) == 0) { if (password == NULL) { password = xstrdup_or_null (pc[i].password); goto leave; } if (strcmp (password, pc[i].password) != 0) { free (pc[i].password); pc[i].password = xstrdup_or_null (password); } goto leave; } } if (password == NULL) goto leave; if (pc_cnt >= pc_max) pc = xrealloc (pc, (pc_max += 10) * sizeof (struct passwd_cache)); pc[pc_cnt].proto = xstrdup_or_null (proto); pc[pc_cnt].host = xstrdup_or_null (host); pc[pc_cnt].username = xstrdup_or_null (username); pc[pc_cnt].password = xstrdup_or_null (password); ++pc_cnt; leave: #ifdef HAVE_PTHREAD_H pthread_mutex_unlock (&mymutex); #endif return (password); }
void init_notes(struct notes_tree *t, const char *notes_ref, combine_notes_fn combine_notes, int flags) { struct object_id oid, object_oid; unsigned mode; struct leaf_node root_tree; if (!t) t = &default_notes_tree; assert(!t->initialized); if (!notes_ref) notes_ref = default_notes_ref(); if (!combine_notes) combine_notes = combine_notes_concatenate; t->root = (struct int_node *) xcalloc(1, sizeof(struct int_node)); t->first_non_note = NULL; t->prev_non_note = NULL; t->ref = xstrdup_or_null(notes_ref); t->update_ref = (flags & NOTES_INIT_WRITABLE) ? t->ref : NULL; t->combine_notes = combine_notes; t->initialized = 1; t->dirty = 0; if (flags & NOTES_INIT_EMPTY || !notes_ref || get_oid_treeish(notes_ref, &object_oid)) return; if (flags & NOTES_INIT_WRITABLE && read_ref(notes_ref, &object_oid)) die("Cannot use notes ref %s", notes_ref); if (get_tree_entry(&object_oid, "", &oid, &mode)) die("Failed to read notes tree referenced by %s (%s)", notes_ref, oid_to_hex(&object_oid)); oidclr(&root_tree.key_oid); oidcpy(&root_tree.val_oid, &oid); load_subtree(t, &root_tree, t->root, 0); }
static void MakeAutoSaveName (SplineFont *sf) { char buffer[1025]; char *autosavedir; static int cnt = 0; if (sf->autosavename) return; autosavedir = getAutoDirName (buffer); if (autosavedir == NULL) return; while (1) { sprintf (buffer, "%s/auto%06jx-%d.asfd", autosavedir, (uintmax_t) getpid (), ++cnt); if (access (buffer, F_OK) == -1) { sf->autosavename = xstrdup_or_null (buffer); return; } } }
static struct commit *find_single_final(struct rev_info *revs, const char **name_p) { int i; struct commit *found = NULL; const char *name = NULL; for (i = 0; i < revs->pending.nr; i++) { struct object *obj = revs->pending.objects[i].item; if (obj->flags & UNINTERESTING) continue; obj = deref_tag(obj, NULL, 0); if (obj->type != OBJ_COMMIT) die("Non commit %s?", revs->pending.objects[i].name); if (found) die("More than one commit to dig from %s and %s?", revs->pending.objects[i].name, name); found = (struct commit *)obj; name = revs->pending.objects[i].name; } if (name_p) *name_p = xstrdup_or_null(name); return found; }
void init_notes(struct notes_tree *t, const char *notes_ref, combine_notes_fn combine_notes, int flags) { unsigned char sha1[20], object_sha1[20]; unsigned mode; struct leaf_node root_tree; if (!t) t = &default_notes_tree; assert(!t->initialized); if (!notes_ref) notes_ref = default_notes_ref(); if (!combine_notes) combine_notes = combine_notes_concatenate; t->root = (struct int_node *) xcalloc(1, sizeof(struct int_node)); t->first_non_note = NULL; t->prev_non_note = NULL; t->ref = xstrdup_or_null(notes_ref); t->combine_notes = combine_notes; t->initialized = 1; t->dirty = 0; if (flags & NOTES_INIT_EMPTY || !notes_ref || read_ref(notes_ref, object_sha1)) return; if (get_tree_entry(object_sha1, "", sha1, &mode)) die("Failed to read notes tree referenced by %s (%s)", notes_ref, sha1_to_hex(object_sha1)); hashclr(root_tree.key_sha1); hashcpy(root_tree.val_sha1, sha1); load_subtree(t, &root_tree, t->root, 0); }
/* * If you want to, you can share the DB area with any number of branches. * That has advantages: you can save space by sharing all the SHA1 objects. * On the other hand, it might just make lookup slower and messier. You * be the judge. The default case is to have one DB per managed directory. */ int cmd_init_db(int argc, const char **argv, const char *prefix) { const char *git_dir; const char *real_git_dir = NULL; const char *work_tree; const char *template_dir = NULL; unsigned int flags = 0; const struct option init_db_options[] = { OPT_STRING(0, "template", &template_dir, N_("template-directory"), N_("directory from which templates will be used")), OPT_SET_INT(0, "bare", &is_bare_repository_cfg, N_("create a bare repository"), 1), { OPTION_CALLBACK, 0, "shared", &init_shared_repository, N_("permissions"), N_("specify that the git repository is to be shared amongst several users"), PARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0}, OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET), OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"), N_("separate git dir from working tree")), OPT_END() }; argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0); if (real_git_dir && !is_absolute_path(real_git_dir)) real_git_dir = real_pathdup(real_git_dir, 1); if (argc == 1) { int mkdir_tried = 0; retry: if (chdir(argv[0]) < 0) { if (!mkdir_tried) { int saved; /* * At this point we haven't read any configuration, * and we know shared_repository should always be 0; * but just in case we play safe. */ saved = get_shared_repository(); set_shared_repository(0); switch (safe_create_leading_directories_const(argv[0])) { case SCLD_OK: case SCLD_PERMS: break; case SCLD_EXISTS: errno = EEXIST; /* fallthru */ default: die_errno(_("cannot mkdir %s"), argv[0]); break; } set_shared_repository(saved); if (mkdir(argv[0], 0777) < 0) die_errno(_("cannot mkdir %s"), argv[0]); mkdir_tried = 1; goto retry; } die_errno(_("cannot chdir to %s"), argv[0]); } } else if (0 < argc) { usage(init_db_usage[0]); } if (is_bare_repository_cfg == 1) { char *cwd = xgetcwd(); setenv(GIT_DIR_ENVIRONMENT, cwd, argc > 0); free(cwd); } if (init_shared_repository != -1) set_shared_repository(init_shared_repository); /* * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR * without --bare. Catch the error early. */ git_dir = xstrdup_or_null(getenv(GIT_DIR_ENVIRONMENT)); work_tree = xstrdup_or_null(getenv(GIT_WORK_TREE_ENVIRONMENT)); if ((!git_dir || is_bare_repository_cfg == 1) && work_tree) die(_("%s (or --work-tree=<directory>) not allowed without " "specifying %s (or --git-dir=<directory>)"), GIT_WORK_TREE_ENVIRONMENT, GIT_DIR_ENVIRONMENT); /* * Set up the default .git directory contents */ if (!git_dir) git_dir = DEFAULT_GIT_DIR_ENVIRONMENT; if (is_bare_repository_cfg < 0) is_bare_repository_cfg = guess_repository_type(git_dir); if (!is_bare_repository_cfg) { const char *git_dir_parent = strrchr(git_dir, '/'); if (git_dir_parent) { char *rel = xstrndup(git_dir, git_dir_parent - git_dir); git_work_tree_cfg = real_pathdup(rel, 1); free(rel); } if (!git_work_tree_cfg) git_work_tree_cfg = xgetcwd(); if (work_tree) set_git_work_tree(work_tree); else set_git_work_tree(git_work_tree_cfg); if (access(get_git_work_tree(), X_OK)) die_errno (_("Cannot access work tree '%s'"), get_git_work_tree()); } else { if (work_tree) set_git_work_tree(work_tree); } UNLEAK(real_git_dir); UNLEAK(git_dir); UNLEAK(work_tree); flags |= INIT_DB_EXIST_OK; return init_db(git_dir, real_git_dir, template_dir, flags); }
int cmd_pull(int argc, const char **argv, const char *prefix) { const char *repo, **refspecs; struct oid_array merge_heads = OID_ARRAY_INIT; struct object_id orig_head, curr_head; struct object_id rebase_fork_point; int autostash; if (!getenv("GIT_REFLOG_ACTION")) set_reflog_message(argc, argv); git_config(git_pull_config, NULL); argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0); parse_repo_refspecs(argc, argv, &repo, &refspecs); if (!opt_ff) opt_ff = xstrdup_or_null(config_get_ff()); if (opt_rebase < 0) opt_rebase = config_get_rebase(); if (read_cache_unmerged()) die_resolve_conflict("pull"); if (file_exists(git_path_merge_head(the_repository))) die_conclude_merge(); if (get_oid("HEAD", &orig_head)) oidclr(&orig_head); if (!opt_rebase && opt_autostash != -1) die(_("--[no-]autostash option is only valid with --rebase.")); autostash = config_autostash; if (opt_rebase) { if (opt_autostash != -1) autostash = opt_autostash; if (is_null_oid(&orig_head) && !is_cache_unborn()) die(_("Updating an unborn branch with changes added to the index.")); if (!autostash) require_clean_work_tree(N_("pull with rebase"), _("please commit or stash them."), 1, 0); if (get_rebase_fork_point(&rebase_fork_point, repo, *refspecs)) oidclr(&rebase_fork_point); } if (run_fetch(repo, refspecs)) return 1; if (opt_dry_run) return 0; if (get_oid("HEAD", &curr_head)) oidclr(&curr_head); if (!is_null_oid(&orig_head) && !is_null_oid(&curr_head) && !oideq(&orig_head, &curr_head)) { /* * The fetch involved updating the current branch. * * The working tree and the index file are still based on * orig_head commit, but we are merging into curr_head. * Update the working tree to match curr_head. */ warning(_("fetch updated the current branch head.\n" "fast-forwarding your working tree from\n" "commit %s."), oid_to_hex(&orig_head)); if (checkout_fast_forward(&orig_head, &curr_head, 0)) die(_("Cannot fast-forward your working tree.\n" "After making sure that you saved anything precious from\n" "$ git diff %s\n" "output, run\n" "$ git reset --hard\n" "to recover."), oid_to_hex(&orig_head)); } get_merge_heads(&merge_heads); if (!merge_heads.nr) die_no_merge_candidates(repo, refspecs); if (is_null_oid(&orig_head)) { if (merge_heads.nr > 1) die(_("Cannot merge multiple branches into empty head.")); return pull_into_void(merge_heads.oid, &curr_head); } if (opt_rebase && merge_heads.nr > 1) die(_("Cannot rebase onto multiple branches.")); if (opt_rebase) { int ret = 0; if ((recurse_submodules == RECURSE_SUBMODULES_ON || recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) && submodule_touches_in_range(&rebase_fork_point, &curr_head)) die(_("cannot rebase with locally recorded submodule modifications")); if (!autostash) { struct commit_list *list = NULL; struct commit *merge_head, *head; head = lookup_commit_reference(the_repository, &orig_head); commit_list_insert(head, &list); merge_head = lookup_commit_reference(the_repository, &merge_heads.oid[0]); if (is_descendant_of(merge_head, list)) { /* we can fast-forward this without invoking rebase */ opt_ff = "--ff-only"; ret = run_merge(); } } ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point); if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON || recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)) ret = rebase_submodules(); return ret; } else { int ret = run_merge(); if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON || recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)) ret = update_submodules(); return ret; } }
int cmd_pull(int argc, const char **argv, const char *prefix) { const char *repo, **refspecs; struct sha1_array merge_heads = SHA1_ARRAY_INIT; unsigned char orig_head[GIT_SHA1_RAWSZ], curr_head[GIT_SHA1_RAWSZ]; unsigned char rebase_fork_point[GIT_SHA1_RAWSZ]; if (!getenv("GIT_REFLOG_ACTION")) set_reflog_message(argc, argv); argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0); parse_repo_refspecs(argc, argv, &repo, &refspecs); if (!opt_ff) opt_ff = xstrdup_or_null(config_get_ff()); if (opt_rebase < 0) opt_rebase = config_get_rebase(); git_config(git_pull_config, NULL); if (read_cache_unmerged()) die_resolve_conflict("Pull"); if (file_exists(git_path("MERGE_HEAD"))) die_conclude_merge(); if (get_sha1("HEAD", orig_head)) hashclr(orig_head); if (!opt_rebase && opt_autostash != -1) die(_("--[no-]autostash option is only valid with --rebase.")); if (opt_rebase) { int autostash = config_autostash; if (opt_autostash != -1) autostash = opt_autostash; if (is_null_sha1(orig_head) && !is_cache_unborn()) die(_("Updating an unborn branch with changes added to the index.")); if (!autostash) die_on_unclean_work_tree(prefix); if (get_rebase_fork_point(rebase_fork_point, repo, *refspecs)) hashclr(rebase_fork_point); } if (run_fetch(repo, refspecs)) return 1; if (opt_dry_run) return 0; if (get_sha1("HEAD", curr_head)) hashclr(curr_head); if (!is_null_sha1(orig_head) && !is_null_sha1(curr_head) && hashcmp(orig_head, curr_head)) { /* * The fetch involved updating the current branch. * * The working tree and the index file are still based on * orig_head commit, but we are merging into curr_head. * Update the working tree to match curr_head. */ warning(_("fetch updated the current branch head.\n" "fast-forwarding your working tree from\n" "commit %s."), sha1_to_hex(orig_head)); if (checkout_fast_forward(orig_head, curr_head, 0)) die(_("Cannot fast-forward your working tree.\n" "After making sure that you saved anything precious from\n" "$ git diff %s\n" "output, run\n" "$ git reset --hard\n" "to recover."), sha1_to_hex(orig_head)); } get_merge_heads(&merge_heads); if (!merge_heads.nr) die_no_merge_candidates(repo, refspecs); if (is_null_sha1(orig_head)) { if (merge_heads.nr > 1) die(_("Cannot merge multiple branches into empty head.")); return pull_into_void(*merge_heads.sha1, curr_head); } else if (opt_rebase) { if (merge_heads.nr > 1) die(_("Cannot rebase onto multiple branches.")); return run_rebase(curr_head, *merge_heads.sha1, rebase_fork_point); } else return run_merge(); }
char *resolve_refdup(const char *refname, int resolve_flags, unsigned char *sha1, int *flags) { return xstrdup_or_null(resolve_ref_unsafe(refname, resolve_flags, sha1, flags)); }
int validate_worktree(const struct worktree *wt, struct strbuf *errmsg, unsigned flags) { struct strbuf wt_path = STRBUF_INIT; char *path = NULL; int err, ret = -1; strbuf_addf(&wt_path, "%s/.git", wt->path); if (is_main_worktree(wt)) { if (is_directory(wt_path.buf)) { ret = 0; goto done; } /* * Main worktree using .git file to point to the * repository would make it impossible to know where * the actual worktree is if this function is executed * from another worktree. No .git file support for now. */ strbuf_addf_gently(errmsg, _("'%s' at main working tree is not the repository directory"), wt_path.buf); goto done; } /* * Make sure "gitdir" file points to a real .git file and that * file points back here. */ if (!is_absolute_path(wt->path)) { strbuf_addf_gently(errmsg, _("'%s' file does not contain absolute path to the working tree location"), git_common_path("worktrees/%s/gitdir", wt->id)); goto done; } if (flags & WT_VALIDATE_WORKTREE_MISSING_OK && !file_exists(wt->path)) { ret = 0; goto done; } if (!file_exists(wt_path.buf)) { strbuf_addf_gently(errmsg, _("'%s' does not exist"), wt_path.buf); goto done; } path = xstrdup_or_null(read_gitfile_gently(wt_path.buf, &err)); if (!path) { strbuf_addf_gently(errmsg, _("'%s' is not a .git file, error code %d"), wt_path.buf, err); goto done; } ret = fspathcmp(path, real_path(git_common_path("worktrees/%s", wt->id))); if (ret) strbuf_addf_gently(errmsg, _("'%s' does not point back to '%s'"), wt->path, git_common_path("worktrees/%s", wt->id)); done: free(path); strbuf_release(&wt_path); return ret; }
static int run_sequencer(int argc, const char **argv, struct replay_opts *opts) { const char * const * usage_str = revert_or_cherry_pick_usage(opts); const char *me = action_name(opts); int cmd = 0; struct option base_options[] = { OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'), OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'), OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'), OPT_BOOL('n', "no-commit", &opts->no_commit, N_("don't automatically commit")), OPT_BOOL('e', "edit", &opts->edit, N_("edit the commit message")), OPT_NOOP_NOARG('r', NULL), OPT_BOOL('s', "signoff", &opts->signoff, N_("add Signed-off-by:")), OPT_CALLBACK('m', "mainline", opts, N_("parent-number"), N_("select mainline parent"), option_parse_m), OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto), OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")), OPT_CALLBACK('X', "strategy-option", &opts, N_("option"), N_("option for merge strategy"), option_parse_x), { OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"), N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, OPT_END() }; struct option *options = base_options; if (opts->action == REPLAY_PICK) { struct option cp_extra[] = { OPT_BOOL('x', NULL, &opts->record_origin, N_("append commit name")), OPT_BOOL(0, "ff", &opts->allow_ff, N_("allow fast-forward")), OPT_BOOL(0, "allow-empty", &opts->allow_empty, N_("preserve initially empty commits")), OPT_BOOL(0, "allow-empty-message", &opts->allow_empty_message, N_("allow commits with empty messages")), OPT_BOOL(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")), OPT_END(), }; options = parse_options_concat(options, cp_extra); } argc = parse_options(argc, argv, NULL, options, usage_str, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN); /* implies allow_empty */ if (opts->keep_redundant_commits) opts->allow_empty = 1; /* Check for incompatible command line arguments */ if (cmd) { char *this_operation; if (cmd == 'q') this_operation = "--quit"; else if (cmd == 'c') this_operation = "--continue"; else { assert(cmd == 'a'); this_operation = "--abort"; } verify_opt_compatible(me, this_operation, "--no-commit", opts->no_commit, "--signoff", opts->signoff, "--mainline", opts->mainline, "--strategy", opts->strategy ? 1 : 0, "--strategy-option", opts->xopts ? 1 : 0, "-x", opts->record_origin, "--ff", opts->allow_ff, "--rerere-autoupdate", opts->allow_rerere_auto == RERERE_AUTOUPDATE, "--no-rerere-autoupdate", opts->allow_rerere_auto == RERERE_NOAUTOUPDATE, NULL); } if (opts->allow_ff) verify_opt_compatible(me, "--ff", "--signoff", opts->signoff, "--no-commit", opts->no_commit, "-x", opts->record_origin, "--edit", opts->edit, NULL); if (cmd) { opts->revs = NULL; } else { struct setup_revision_opt s_r_opt; opts->revs = xmalloc(sizeof(*opts->revs)); init_revisions(opts->revs, NULL); opts->revs->no_walk = REVISION_WALK_NO_WALK_UNSORTED; if (argc < 2) usage_with_options(usage_str, options); if (!strcmp(argv[1], "-")) argv[1] = "@{-1}"; memset(&s_r_opt, 0, sizeof(s_r_opt)); s_r_opt.assume_dashdash = 1; argc = setup_revisions(argc, argv, opts->revs, &s_r_opt); } if (argc > 1) usage_with_options(usage_str, options); /* These option values will be free()d */ opts->gpg_sign = xstrdup_or_null(opts->gpg_sign); opts->strategy = xstrdup_or_null(opts->strategy); if (cmd == 'q') { int ret = sequencer_remove_state(opts); if (!ret) remove_branch_state(); return ret; } if (cmd == 'c') return sequencer_continue(opts); if (cmd == 'a') return sequencer_rollback(opts); return sequencer_pick_revisions(opts); }
int cmd_ls_remote(int argc, const char **argv, const char *prefix) { const char *dest = NULL; unsigned flags = 0; int get_url = 0; int quiet = 0; int status = 0; int show_symref_target = 0; const char *uploadpack = NULL; const char **pattern = NULL; struct argv_array ref_prefixes = ARGV_ARRAY_INIT; int i; struct remote *remote; struct transport *transport; const struct ref *ref; struct ref_array ref_array; static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting; struct option options[] = { OPT__QUIET(&quiet, N_("do not print remote URL")), OPT_STRING(0, "upload-pack", &uploadpack, N_("exec"), N_("path of git-upload-pack on the remote host")), { OPTION_STRING, 0, "exec", &uploadpack, N_("exec"), N_("path of git-upload-pack on the remote host"), PARSE_OPT_HIDDEN }, OPT_BIT('t', "tags", &flags, N_("limit to tags"), REF_TAGS), OPT_BIT('h', "heads", &flags, N_("limit to heads"), REF_HEADS), OPT_BIT(0, "refs", &flags, N_("do not show peeled tags"), REF_NORMAL), OPT_BOOL(0, "get-url", &get_url, N_("take url.<base>.insteadOf into account")), OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"), N_("field name to sort on"), &parse_opt_ref_sorting), OPT_SET_INT_F(0, "exit-code", &status, N_("exit with exit code 2 if no matching refs are found"), 2, PARSE_OPT_NOCOMPLETE), OPT_BOOL(0, "symref", &show_symref_target, N_("show underlying ref in addition to the object pointed by it")), OPT_END() }; memset(&ref_array, 0, sizeof(ref_array)); argc = parse_options(argc, argv, prefix, options, ls_remote_usage, PARSE_OPT_STOP_AT_NON_OPTION); dest = argv[0]; if (argc > 1) { int i; pattern = xcalloc(argc, sizeof(const char *)); for (i = 1; i < argc; i++) { const char *glob; pattern[i - 1] = xstrfmt("*/%s", argv[i]); glob = strchr(argv[i], '*'); if (glob) argv_array_pushf(&ref_prefixes, "%.*s", (int)(glob - argv[i]), argv[i]); else expand_ref_prefix(&ref_prefixes, argv[i]); } } remote = remote_get(dest); if (!remote) { if (dest) die("bad repository '%s'", dest); die("No remote configured to list refs from."); } if (!remote->url_nr) die("remote %s has no configured URL", dest); if (get_url) { printf("%s\n", *remote->url); UNLEAK(sorting); return 0; } transport = transport_get(remote, NULL); if (uploadpack != NULL) transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack); ref = transport_get_remote_refs(transport, &ref_prefixes); if (transport_disconnect(transport)) { UNLEAK(sorting); return 1; } if (!dest && !quiet) fprintf(stderr, "From %s\n", *remote->url); for ( ; ref; ref = ref->next) { struct ref_array_item *item; if (!check_ref_type(ref, flags)) continue; if (!tail_match(pattern, ref->name)) continue; item = ref_array_push(&ref_array, ref->name, &ref->old_oid); item->symref = xstrdup_or_null(ref->symref); } if (sorting) ref_array_sort(sorting, &ref_array); for (i = 0; i < ref_array.nr; i++) { const struct ref_array_item *ref = ref_array.items[i]; if (show_symref_target && ref->symref) printf("ref: %s\t%s\n", ref->symref, ref->refname); printf("%s\t%s\n", oid_to_hex(&ref->objectname), ref->refname); status = 0; /* we found something */ } UNLEAK(sorting); UNLEAK(ref_array); return status; }