From: Junio C Hamano <gitster@pobox.com> To: Shourya Shukla <shouryashukla.oo@gmail.com> Cc: git@vger.kernel.org, christian.couder@gmail.com, kaartic.sivaraam@gmail.com, Johannes.Schindelin@gmx.de, liu.denton@gmail.com, Prathamesh Chavan <pc44800@gmail.com>, Christian Couder <chriscool@tuxfamily.org>, Stefan Beller <stefanbeller@gmail.com> Subject: Re: [PATCH v2 2/3] submodule: port submodule subcommand 'add' from shell to C Date: Thu, 08 Oct 2020 10:19:14 -0700 Message-ID: <xmqqimbky6st.fsf@gitster.c.googlers.com> (raw) In-Reply-To: <20201007074538.25891-3-shouryashukla.oo@gmail.com> (Shourya Shukla's message of "Wed, 7 Oct 2020 13:15:37 +0530") Shourya Shukla <shouryashukla.oo@gmail.com> writes: > +static void config_added_submodule(struct add_data *info) > +{ This one I may take a look at later, but won't review in this message. > +} > + > +static int module_add(int argc, const char **argv, const char *prefix) > +{ > + const char *branch = NULL, *custom_name = NULL, *realrepo = NULL; > + const char *reference_path = NULL, *repo = NULL, *name = NULL; > + char *path; > + int force = 0, quiet = 0, depth = -1, progress = 0, dissociate = 0; > + struct add_data info = ADD_DATA_INIT; > + struct strbuf sb = STRBUF_INIT; > + > + struct option options[] = { > + OPT_STRING('b', "branch", &branch, N_("branch"), > + N_("branch of repository to add as submodule")), > + OPT_BOOL('f', "force", &force, N_("allow adding an otherwise " > + "ignored submodule path")), > + OPT__QUIET(&quiet, N_("print only error messages")), > + OPT_BOOL(0, "progress", &progress, N_("force cloning progress")), > + OPT_STRING(0, "reference", &reference_path, N_("repository"), > + N_("reference repository")), > + OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")), > + OPT_STRING(0, "name", &custom_name, N_("name"), > + N_("sets the submodule’s name to the given string " > + "instead of defaulting to its path")), > + OPT_INTEGER(0, "depth", &depth, N_("depth for shallow clones")), > + OPT_END() > + }; > + > + const char *const usage[] = { > + N_("git submodule--helper add [<options>] [--] [<path>]"), > + NULL > + }; > + > + argc = parse_options(argc, argv, prefix, options, usage, 0); > + > + if (!is_writing_gitmodules_ok()) > + die(_("please make sure that the .gitmodules file is in the working tree")); > + > + if (reference_path && !is_absolute_path(reference_path) && prefix) Checking "*prefix" lets us avoid an unnecessary allocation, i.e. if (prefix && *prefix && reference_path && !is_absolute_path(reference_path)) > + reference_path = xstrfmt("%s%s", prefix, reference_path); > + > + if (argc == 0 || argc > 2) { Nice that you are checking excess args, which the original didn't do. > + usage_with_options(usage, options); > + } else if (argc == 1) { > + repo = argv[0]; > + path = guess_dir_name(repo); We've reviewed the function already. Good. > + } else { > + repo = argv[0]; > + path = xstrdup(argv[1]); OK. So after this if/else if/else cascade, path is an allocated piece of memory we could later free() whichever branch is taken. > + } > + > + if (!is_absolute_path(path) && prefix) > + path = xstrfmt("%s%s", prefix, path); This also makes path freeable, but the original path is leaked. if (prefix && *prefix && !is_absolute_path(path)) { free(path); path = xstrfmt(...); } Is there a reason (does not have to be a strong reason) why we use 'path', not 'sm_path', as the variable name that corresponds to $sm_path in the original, by the way? > + /* assure repo is absolute or relative to parent */ > + if (starts_with_dot_dot_slash(repo) || starts_with_dot_slash(repo)) { > + char *remote = get_default_remote(); > + char *remoteurl; > + struct strbuf sb = STRBUF_INIT; > + > + if (prefix) > + die(_("relative path can only be used from the toplevel " > + "of the working tree")); This is 'git submodule--helper resolve-relative-url "$repo"' in the original. > + /* dereference source url relative to parent's url */ > + strbuf_addf(&sb, "remote.%s.url", remote); > + if (git_config_get_string(sb.buf, &remoteurl)) > + remoteurl = xgetcwd(); > + realrepo = relative_url(remoteurl, repo, NULL); And this is copied-and-pasted from resolve_relative_url() function found in builtins/submodule--helper.c. relative_url() returns an allocated memory so we can free() realrepo if we took this branch. > + free(remoteurl); > + free(remote); > + } else if (is_dir_sep(repo[0]) || strchr(repo, ':')) { > + realrepo = repo; This repo came from argv[0] so we cannot free realrepo if we took this branch. Are we willing to leak realrepo we obtained from the other branch? > + } else { > + die(_("repo URL: '%s' must be absolute or begin with ./|../"), > + repo); > + } > + > + /* > + * normalize path: > + * multiple //; leading ./; /./; /../; > + */ > + normalize_path_copy(path, path); It's nice that a handy (almost) equivalent helper is already available ;-) > + /* strip trailing '/' */ > + if (is_dir_sep(path[strlen(path) -1])) > + path[strlen(path) - 1] = '\0'; The original dealt with multiple trailing '/' but this one does not. Shouldn't it loop starting at the end? > + if (check_sm_exists(force, path)) > + return 1; OK. I think we reviewed the function. Seeing it in the context of the calling site makes us realize that it has a wrong name. "check submodule exists" sounds as if we expect a submodule to exist at the path, and it is an error for a submodule not to be there, but that is not what this caller (which is the only caller of the helper) wants to check. And more importantly, the helper reacts to anything sitting at the path, not just submoudle. So what does the helper really do? I think it checks if it is OK to create a submodule there. IOW, "exists" part of the name is what makes it a misnomer. Perhaps "can_create_submodule()"? > + strbuf_addstr(&sb, path); > + if (is_nonbare_repository_dir(&sb)) { > + struct object_id oid; > + if (resolve_gitlink_ref(path, "HEAD", &oid) < 0) > + die(_("'%s' does not have a commit checked out"), path); > + } > + > + if (!force) { > + struct strbuf sb = STRBUF_INIT; > + struct child_process cp = CHILD_PROCESS_INIT; > + cp.git_cmd = 1; > + cp.no_stdout = 1; > + strvec_pushl(&cp.args, "add", "--dry-run", "--ignore-missing", > + "--no-warn-embedded-repo", path, NULL); > + if (pipe_command(&cp, NULL, 0, NULL, 0, &sb, 0)) { > + fprintf(stderr, _("%s"), sb.buf); Sorry, but I cannot guess what this _("%s") is trying to achieve. Shouldn't it be strbuf_complete_line(&sb); fputs(sb.buf, stderr); instead? > + return 1; The original honors the exit code from the dry-run and relays it to the user. Is this a regression, or nobody care what exit status they get as long as it is not zero? > + } > + strbuf_release(&sb); > + } > + > + name = custom_name ? custom_name : path; > + if (check_submodule_name(name)) > + die(_("'%s' is not a valid submodule name"), name); > + > + info.prefix = prefix; > + info.sm_name = name; > + info.sm_path = path; > + info.repo = repo; > + info.realrepo = realrepo; > + info.reference_path = reference_path; > + info.branch = branch; > + info.depth = depth; > + info.progress = !!progress; > + info.dissociate = !!dissociate; > + info.force = !!force; > + info.quiet = !!quiet; > + > + if (add_submodule(&info)) > + return 1; I think we've reviewed this funciton already. > + config_added_submodule(&info); > + > + free(path); Looking a bit uneven wrt to leak handling. > + return 0; > +} Thanks.
next prev parent reply other threads:[~2020-10-08 17:19 UTC|newest] Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-10-07 7:45 [PATCH v2 0/3] submodule: port subcommand add " Shourya Shukla 2020-10-07 7:45 ` [PATCH v2 1/3] dir: change the scope of function 'directory_exists_in_index()' Shourya Shukla 2020-10-07 18:05 ` Junio C Hamano 2020-10-12 10:11 ` Shourya Shukla 2020-11-18 23:25 ` Emily Shaffer 2020-10-07 7:45 ` [PATCH v2 2/3] submodule: port submodule subcommand 'add' from shell to C Shourya Shukla 2020-10-07 18:37 ` Junio C Hamano 2020-10-07 22:19 ` Junio C Hamano 2020-10-08 17:19 ` Junio C Hamano [this message] 2020-10-09 5:09 ` Junio C Hamano 2020-11-18 23:13 ` Jonathan Tan 2020-11-19 7:44 ` Ævar Arnfjörð Bjarmason 2020-11-19 12:38 ` Johannes Schindelin 2020-11-19 20:37 ` Junio C Hamano 2020-10-07 7:45 ` [PATCH v2 3/3] t7400: add test to check 'submodule add' for tracked paths Shourya Shukla 2020-11-19 0:03 ` [PATCH v2 0/3] submodule: port subcommand add from shell to C Josh Steadmon
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style List information: http://vger.kernel.org/majordomo-info.html * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=xmqqimbky6st.fsf@gitster.c.googlers.com \ --to=gitster@pobox.com \ --cc=Johannes.Schindelin@gmx.de \ --cc=chriscool@tuxfamily.org \ --cc=christian.couder@gmail.com \ --cc=git@vger.kernel.org \ --cc=kaartic.sivaraam@gmail.com \ --cc=liu.denton@gmail.com \ --cc=pc44800@gmail.com \ --cc=shouryashukla.oo@gmail.com \ --cc=stefanbeller@gmail.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
git@vger.kernel.org list mirror (unofficial, one of many) This inbox may be cloned and mirrored by anyone: git clone --mirror https://public-inbox.org/git git clone --mirror http://ou63pmih66umazou.onion/git git clone --mirror http://czquwvybam4bgbro.onion/git git clone --mirror http://hjrcffqmbrq6wope.onion/git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V1 git git/ https://public-inbox.org/git \ git@vger.kernel.org public-inbox-index git Example config snippet for mirrors. Newsgroups are available over NNTP: nntp://news.public-inbox.org/inbox.comp.version-control.git nntp://ou63pmih66umazou.onion/inbox.comp.version-control.git nntp://czquwvybam4bgbro.onion/inbox.comp.version-control.git nntp://hjrcffqmbrq6wope.onion/inbox.comp.version-control.git nntp://news.gmane.io/gmane.comp.version-control.git note: .onion URLs require Tor: https://www.torproject.org/ code repositories for the project(s) associated with this inbox: https://80x24.org/mirrors/git.git AGPL code for this site: git clone https://public-inbox.org/public-inbox.git