From: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
To: Junio C Hamano <gitster@pobox.com>,
Shourya Shukla <shouryashukla.oo@gmail.com>
Cc: git@vger.kernel.org, christian.couder@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: [GSoC][PATCH] submodule: port submodule subcommand 'add' from shell to C
Date: Tue, 25 Aug 2020 02:00:16 +0530 [thread overview]
Message-ID: <43337924c09119d43c74fdad3f00d4dab76edb51.camel@gmail.com> (raw)
In-Reply-To: <xmqq8se36gev.fsf@gitster.c.googlers.com>
On Mon, 2020-08-24 at 11:35 -0700, Junio C Hamano wrote:
> Shourya Shukla <shouryashukla.oo@gmail.com> writes:
>
> > if test -z "$force"
> > then
> > git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 &&
> > die "$(eval_gettext "'\$sm_path' already exists in the index")"
> > else
> > git ls-files -s "$sm_path" | sane_grep -v "^160000" > /dev/null 2>&1 &&
> > die "$(eval_gettext "'\$sm_path' already exists in the index and is not a submodule")"
> > fi
>
> Hmph. So,
>
> - if we are not being 'force'd, we see if there is anything in the
> index for the path and error out, whether it is a gitlink or not.
>
Right.
> - if there is 'force' option, we see what the given path is in the
> index, and if it is already a gitlink, then die. That sort of
> makes sense, as long as the remainder of the code deals with the
> path that is not a submodule in a sensible way.
>
With `force, I think it's the opposite of what you describe. That is:
- if there is 'force' option, we see what the given path is in the
index, and if it is **not** already a gitlink, then die.
Note the `-v` passed to sane_grep.
> > This is what I have done in C:
> >
> > if (!force) {
> > if (is_directory(path) && submodule_from_path(the_repository, &null_oid, path))
> > die(_("'%s' already exists in the index"), path);
>
> The shell version would error out with anything in the index, so I'd
> expect that a faithful conversion would not call is_directory() nor
> submodule_from_path() at all---it would just look path up in the_index
> and complains if anything is found. For example, the quoted part in
> the original above is what gives the error message when I do
>
> $ git submodule add ./Makefile
> 'Makefile' already exists in the index.
>
> I think. And the above code won't trigger the "already exists" at
> all because 'path' is not a directory.
>
> > } else {
> > int err;
> > if (index_name_pos(&the_index, path, strlen(path)) >= 0 &&
> > !is_submodule_populated_gently(path, &err))
> > die(_("'%s' already exists in the index and is not a "
> > "submodule"), path);
>
> Likewise. The above does much more than the original.
>
> The original was checking if the found cache entry has 160000 mode
> bit, so the second test would not be is_submodule_populated_gently()
> but more like !S_ISGITLINK(ce->ce_mode)
>
Yeah, the C version does need a more proper check in both cases.
> Now it is a different question if the original is correct to begin
> with ;-).
>
By looking at commit message of 619acfc78c (submodule add: extend force
flag to add existing repos, 2016-10-06), I'm assuming it's correct.
There are chances I might be missing something, though.
Speaking of correctness, I'm surprised how the port passed the
following test t7400.63 despite the incorrect check.
-- 8< --
$ ./t7400-submodule-basic.sh
... snip ...
ok 62 - add submodules without specifying an explicit path
ok 63 - add should fail when path is used by a file
ok 64 - add should fail when path is used by an existing directory
... snip ...
-- >8 --
Most likely it passed because it slipped through the incorrect check
and failed later in the code[1]. That's not good, of course.
> > }
> >
> > Is this part correct? I am not very sure about this. This particular
> > part is not covered in any test or test script, so, I do not have a
> > solid method of knowing the correctness of this segment.
> > Feedback and reviews are appreciated.
> +static int add_submodule(struct add_data *info)
> +{
> + /* perhaps the path exists and is already a git repo, else clone it */
> + if (is_directory(info->sm_path)) {
> + char *sub_git_path = xstrfmt("%s/.git", info->sm_path);
> + if (is_directory(sub_git_path) || file_exists(sub_git_path))
> + printf(_("Adding existing repo at '%s' to the index\n"),
> + info->sm_path);
> + else
> + die(_("'%s' already exists and is not a valid git repo"),
> + info->sm_path);
> + free(sub_git_path);
> + } else {
> + struct strvec clone_args = STRVEC_INIT;
> + struct child_process cp = CHILD_PROCESS_INIT;
> + char *submodule_git_dir = xstrfmt(".git/modules/%s", info->sm_name);
> +
> + if (is_directory(submodule_git_dir)) {
> + if (!info->force) {
> + struct child_process cp_rem = CHILD_PROCESS_INIT;
> + struct strbuf sb_rem = STRBUF_INIT;
> + cp_rem.git_cmd = 1;
> + fprintf(stderr, _("A git directory for '%s' is "
> + "found locally with remote(s):\n"),
> + info->sm_name);
> + strvec_pushf(&cp_rem.env_array,
> + "GIT_DIR=%s", submodule_git_dir);
> + strvec_push(&cp_rem.env_array, "GIT_WORK_TREE=.");
> + strvec_pushl(&cp_rem.args, "remote", "-v", NULL);
> + if (!capture_command(&cp_rem, &sb_rem, 0)) {
> + modify_remote_v(&sb_rem);
> + }
> + error(_("If you want to reuse this local git "
> + "directory instead of cloning again from\n "
> + " %s\n"
> + "use the '--force' option. If the local "
> + "git directory is not the correct repo\n"
> + "or you are unsure what this means choose "
> + "another name with the '--name' option."),
> + info->realrepo);
> + return 1;
> + } else {
> + printf(_("Reactivating local git directory for "
> + "submodule '%s'."), info->sm_path);
> + }
> + }
> + free(submodule_git_dir);
This part results in a difference in error message in shell and C
versions.
-- 8< --
$ # Shell version
$ git submodule add ../subm1 sub
A git directory for 'sub' is found locally with remote(s):
origin /me/subm1
If you want to reuse this local git directory instead of cloning again from
/me/subm1
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.
$
$ # C version
$ git submodule add ../subm1 sub
A git directory for 'sub' is found locally with remote(s):
origin /me/subm1
error: If you want to reuse this local git directory instead of cloning again from
/me/subm1
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.
-- >8 --
Note how the third line is oddly prefixed by a `error` unlike the rest
of the lines. It would be nice if we could weed out that inconsistency.
We could probably use `advise()` for printing the last four lines and
`error()` for the lines above them.
Footnote
---
[1]: Looks like not checking for the error message when a command fails
has it's own downsides x-(
--
Sivaraam
next prev parent reply other threads:[~2020-08-24 20:30 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-24 9:03 [GSoC][PATCH] submodule: port submodule subcommand 'add' from shell to C Shourya Shukla
2020-08-24 18:35 ` Junio C Hamano
2020-08-24 20:30 ` Kaartic Sivaraam [this message]
2020-08-24 20:46 ` Junio C Hamano
2020-08-26 9:27 ` Shourya Shukla
2020-08-26 10:54 ` Kaartic Sivaraam
2020-08-26 9:15 ` Shourya Shukla
2020-08-30 19:58 ` Kaartic Sivaraam
2020-08-31 13:04 ` Shourya Shukla
2020-09-01 20:35 ` Kaartic Sivaraam
2020-09-02 12:04 ` Shourya Shukla
2020-09-03 8:46 ` Kaartic Sivaraam
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=43337924c09119d43c74fdad3f00d4dab76edb51.camel@gmail.com \
--to=kaartic.sivaraam@gmail.com \
--cc=chriscool@tuxfamily.org \
--cc=christian.couder@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=johannes.schindelin@gmx.de \
--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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).