From: Thomas Gummerer <hidden> Date: 2016-06-15 23:08:14
In builtin/remote.c there are a few cases which check whether a remote
exists or not. These checks are however done inconsistently, and in a
few cases they don't check anything at all. This patch series tries
to improve the situation.
I stumbled upon this when I mistyped the remote name in git remote rm,
and got a cryptic error message, and thought the other cases might be
worth fixing as well.
There is one such check left in get_remote_ref_states, but I'm not
quite sure what to do about that one. That function gets called in
git remote show/set-head/prune, where it might make sense for the user
to provide a url, or a local repository, at least in the git remote
show case.
I think we have the following options there:
(1) just remove the check, as nobody seems to have noticed until now,
and the check doesn't actually do anything (get_remote() is never
called with NULL, so it will never return NULL). In this case
git dies when a non-existent remote is encountered, e.g. git
remote show nonexistent existent will die immediately, while git
remote show existent nonexistent will show info about the
existing remote, and die afterwards.
(2) add an option not to die in the transport function, and let the
caller of get_remote_ref_states handle the error i.e. show the
error and keep going with the next remote.
(3) anything I might be missing?
Thomas Gummerer (4):
remote: use skip_prefix
remote: simplify remote_is_configured()
remote: actually check if remote exits
remote: use remote_is_configured() for add and rename
builtin/fetch.c | 5 ++---
builtin/remote.c | 23 ++++++++++-------------
remote.c | 22 +++++-----------------
remote.h | 4 ++--
t/t5505-remote.sh | 36 ++++++++++++++++++++++++++++++++++++
5 files changed, 55 insertions(+), 35 deletions(-)
--
2.7.1.410.g6faf27b
From: Thomas Gummerer <hidden> Date: 2016-06-15 23:08:14
95b567c7 ("use skip_prefix to avoid repeating strings") transformed
calls using starts_with() and then skipping the length of the prefix to
skip_prefix() calls. In remote.c there are a few calls like:
if (starts_with(foo, "bar"))
foo += 3
These calls weren't touched by the commit mentioned above, but can
benefit from the same treatment to avoid magic numbers.
Signed-off-by: Thomas Gummerer <redacted>
---
remote.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
From: Thomas Gummerer <hidden> Date: 2016-06-15 23:08:14
The remote_is_configured() function allows checking whether a remote
exists or not. The function however only works if remote_get() wasn't
called before calling it. In addition, it only checks the configuration
for remotes, but not remotes or branches files.
Make use of the origin member of struct remote instead, which indicates
where the remote comes from. It will be set to some value if the remote
is configured in any file in the repository, but is initialized to 0 if
the remote is only created in make_remote().
Signed-off-by: Thomas Gummerer <redacted>
---
builtin/fetch.c | 5 ++---
builtin/remote.c | 12 ++++++------
remote.c | 13 ++-----------
remote.h | 4 ++--
4 files changed, 12 insertions(+), 22 deletions(-)
From: Thomas Gummerer <hidden> Date: 2016-06-15 23:08:14
When converting the git remote command to a builtin in 211c89 ("Make
git-remote a builtin"), a few calls to check if a remote exists were
converted from:
if (!exists $remote->{$name}) {
[...]
to:
remote = remote_get(argv[1]);
if (!remote)
[...]
The new check is not quite correct, because remote_get() never returns
NULL if a name is given. This leaves us with the somewhat cryptic error
message "error: Could not remove config section 'remote.test'", if we
are trying to remove a remote that does not exist, or a similar error if
we try to rename a remote.
Use the remote_is_configured() function to check whether the remote
actually exists, and die with a more sensible error message ("No such
remote: $remotename") instead if it doesn't.
Signed-off-by: Thomas Gummerer <redacted>
---
builtin/remote.c | 4 ++--
t/t5505-remote.sh | 18 ++++++++++++++++++
2 files changed, 20 insertions(+), 2 deletions(-)
@@ -139,6 +139,24 @@ test_expect_success 'remove remote protects local branches' ')'+test_expect_success'remove errors out early when deleting non-existent branch''+(+cdtest&&+echo"fatal: No such remote: foo">expect&&+test_must_failgitremotermfoo2>actual&&+test_i18ncmpexpectactual+)+'++test_expect_success'rename errors out early when deleting non-existent branch''+(+cdtest&&+echo"fatal: No such remote: foo">expect&&+test_must_failgitremoterenamefoobar2>actual&&+test_i18ncmpexpectactual+)+'+ cat>test/expect<<EOF *remoteoriginFetchURL:$(pwd)/one
From: Thomas Gummerer <hidden> Date: 2016-06-15 23:08:14
Both remote add and remote rename use a slightly different hand-rolled
check if the remote exits. The hand-rolled check may have some subtle
cases in which it might fail to detect when a remote already exists.
One such case was fixed in fb86e32 ("git remote: allow adding remotes
agreeing with url.<...>.insteadOf"). Another case is when a remote is
configured as follows:
[remote "foo"]
vcs = bar
If we try to run `git remote add foo bar` with the above remote
configuration, git segfaults. This change fixes it.
In addition, git remote rename $existing foo with the configuration for
foo as above silently succeeds, even though foo already exists,
modifying its configuration. With this patch it fails with "remote foo
already exists".
Signed-off-by: Thomas Gummerer <redacted>
---
builtin/remote.c | 7 ++-----
t/t5505-remote.sh | 18 ++++++++++++++++++
2 files changed, 20 insertions(+), 5 deletions(-)
From: Jeff King <hidden> Date: 2016-06-15 23:08:14
On Mon, Feb 15, 2016 at 06:42:27PM +0100, Thomas Gummerer wrote:
95b567c7 ("use skip_prefix to avoid repeating strings") transformed
calls using starts_with() and then skipping the length of the prefix to
skip_prefix() calls. In remote.c there are a few calls like:
if (starts_with(foo, "bar"))
foo += 3
These calls weren't touched by the commit mentioned above, but can
benefit from the same treatment to avoid magic numbers.
This is definitely an improvement, but I think we can actually go a step
further here, and use parse_config_key. Like:
From: Jeff King <hidden> Date: 2016-06-15 23:08:14
On Mon, Feb 15, 2016 at 06:42:28PM +0100, Thomas Gummerer wrote:
The remote_is_configured() function allows checking whether a remote
exists or not. The function however only works if remote_get() wasn't
called before calling it. In addition, it only checks the configuration
for remotes, but not remotes or branches files.
Make use of the origin member of struct remote instead, which indicates
where the remote comes from. It will be set to some value if the remote
is configured in any file in the repository, but is initialized to 0 if
the remote is only created in make_remote().
Makes sense. I wonder if we would want to give this an explicit slot in
the enum. I.e.:
From: Jeff King <hidden> Date: 2016-06-15 23:08:14
On Mon, Feb 15, 2016 at 06:42:29PM +0100, Thomas Gummerer wrote:
When converting the git remote command to a builtin in 211c89 ("Make
git-remote a builtin"), a few calls to check if a remote exists were
converted from:
if (!exists $remote->{$name}) {
[...]
to:
remote = remote_get(argv[1]);
if (!remote)
[...]
The new check is not quite correct, because remote_get() never returns
NULL if a name is given. This leaves us with the somewhat cryptic error
message "error: Could not remove config section 'remote.test'", if we
are trying to remove a remote that does not exist, or a similar error if
we try to rename a remote.
Use the remote_is_configured() function to check whether the remote
actually exists, and die with a more sensible error message ("No such
remote: $remotename") instead if it doesn't.
Signed-off-by: Thomas Gummerer <redacted>
---
builtin/remote.c | 4 ++--
t/t5505-remote.sh | 18 ++++++++++++++++++
2 files changed, 20 insertions(+), 2 deletions(-)
Nice. Very cleanly explained and implemented.
-Peff
From: Jeff King <hidden> Date: 2016-06-15 23:08:14
On Mon, Feb 15, 2016 at 06:42:30PM +0100, Thomas Gummerer wrote:
Both remote add and remote rename use a slightly different hand-rolled
check if the remote exits. The hand-rolled check may have some subtle
cases in which it might fail to detect when a remote already exists.
One such case was fixed in fb86e32 ("git remote: allow adding remotes
agreeing with url.<...>.insteadOf"). Another case is when a remote is
configured as follows:
[remote "foo"]
vcs = bar
If we try to run `git remote add foo bar` with the above remote
configuration, git segfaults. This change fixes it.
In addition, git remote rename $existing foo with the configuration for
foo as above silently succeeds, even though foo already exists,
modifying its configuration. With this patch it fails with "remote foo
already exists".
Checking is_configured() certainly sounds like a better test, but...
This original is quite confusing. I thought at first that there was
perhaps something going on with allowing repeated re-configuration of
the same remote, as long as some parameters matched. I.e., I am
wondering if there is a case here that does _not_ segfault, that we
would be breaking.
But reading over fb86e32dcc, I think I have convinced myself that it was
merely an ad-hoc check for "is_configured", and using that function is a
better replacement.
-Peff
From: Eric Sunshine <hidden> Date: 2016-06-15 23:08:14
On Mon, Feb 15, 2016 at 1:18 PM, Jeff King [off-list ref] wrote:
This is definitely an improvement, but I think we can actually go a step
further here, and use parse_config_key. Like:
- if (starts_with(key, "branch.")) {
- name = key + 7;
- subkey = strrchr(name, '.');
- if (!subkey)
+ if (starts_with(key, "branch", &name, &namelen, &subkey)) {
I guess you meant: s/starts_with/parse_config_key/
quoted hunk
+ if (!name) return 0;- branch = make_branch(name, subkey - name);+ branch = make_branch(name, namelen); if (!strcmp(subkey, ".remote")) { return git_config_string(&branch->remote_name, key, value); } else if (!strcmp(subkey, ".pushremote")) {
From: Jeff King <hidden> Date: 2016-06-15 23:08:14
On Mon, Feb 15, 2016 at 01:35:03PM -0500, Eric Sunshine wrote:
On Mon, Feb 15, 2016 at 1:18 PM, Jeff King [off-list ref] wrote:
quoted
This is definitely an improvement, but I think we can actually go a step
further here, and use parse_config_key. Like:
- if (starts_with(key, "branch.")) {
- name = key + 7;
- subkey = strrchr(name, '.');
- if (!subkey)
+ if (starts_with(key, "branch", &name, &namelen, &subkey)) {
I guess you meant: s/starts_with/parse_config_key/
Whoops, yeah. I'll belatedly add a "not even compile-tested" disclaimer.
:)
-Peff
From: Thomas Gummerer <hidden> Date: 2016-06-15 23:08:14
On 02/15, Jeff King wrote:
On Mon, Feb 15, 2016 at 06:42:27PM +0100, Thomas Gummerer wrote:
quoted
95b567c7 ("use skip_prefix to avoid repeating strings") transformed
calls using starts_with() and then skipping the length of the prefix to
skip_prefix() calls. In remote.c there are a few calls like:
if (starts_with(foo, "bar"))
foo += 3
These calls weren't touched by the commit mentioned above, but can
benefit from the same treatment to avoid magic numbers.
This is definitely an improvement, but I think we can actually go a step
further here, and use parse_config_key. Like:
Thanks, I had no idea about this function :) It makes the diff a lot
noisier, but I do think the end result is better.
From: Thomas Gummerer <hidden> Date: 2016-06-15 23:08:14
On 02/15, Jeff King wrote:
On Mon, Feb 15, 2016 at 06:42:28PM +0100, Thomas Gummerer wrote:
quoted
The remote_is_configured() function allows checking whether a remote
exists or not. The function however only works if remote_get() wasn't
called before calling it. In addition, it only checks the configuration
for remotes, but not remotes or branches files.
Make use of the origin member of struct remote instead, which indicates
where the remote comes from. It will be set to some value if the remote
is configured in any file in the repository, but is initialized to 0 if
the remote is only created in make_remote().
Makes sense. I wonder if we would want to give this an explicit slot in
the enum. I.e.:
From: Thomas Gummerer <hidden> Date: 2016-06-15 23:08:14
On 02/15, Jeff King wrote:
On Mon, Feb 15, 2016 at 06:42:30PM +0100, Thomas Gummerer wrote:
quoted
Both remote add and remote rename use a slightly different hand-rolled
check if the remote exits. The hand-rolled check may have some subtle
cases in which it might fail to detect when a remote already exists.
One such case was fixed in fb86e32 ("git remote: allow adding remotes
agreeing with url.<...>.insteadOf"). Another case is when a remote is
configured as follows:
[remote "foo"]
vcs = bar
If we try to run `git remote add foo bar` with the above remote
configuration, git segfaults. This change fixes it.
In addition, git remote rename $existing foo with the configuration for
foo as above silently succeeds, even though foo already exists,
modifying its configuration. With this patch it fails with "remote foo
already exists".
Checking is_configured() certainly sounds like a better test, but...
This original is quite confusing. I thought at first that there was
perhaps something going on with allowing repeated re-configuration of
the same remote, as long as some parameters matched. I.e., I am
wondering if there is a case here that does _not_ segfault, that we
would be breaking.
But reading over fb86e32dcc, I think I have convinced myself that it was
merely an ad-hoc check for "is_configured", and using that function is a
better replacement.
It took me a while too to convince myself there is nothing strange
going on. But I could neither find anything in the history, nor could
I think of any case that we could break.
Thanks for your review!
From: Johannes Schindelin <hidden> Date: 2016-06-15 23:08:17
Hi Peff & Thomas,
On Mon, 15 Feb 2016, Jeff King wrote:
On Mon, Feb 15, 2016 at 06:42:30PM +0100, Thomas Gummerer wrote:
quoted
Both remote add and remote rename use a slightly different hand-rolled
check if the remote exits. The hand-rolled check may have some subtle
cases in which it might fail to detect when a remote already exists.
One such case was fixed in fb86e32 ("git remote: allow adding remotes
agreeing with url.<...>.insteadOf"). Another case is when a remote is
configured as follows:
[remote "foo"]
vcs = bar
If we try to run `git remote add foo bar` with the above remote
configuration, git segfaults. This change fixes it.
In addition, git remote rename $existing foo with the configuration for
foo as above silently succeeds, even though foo already exists,
modifying its configuration. With this patch it fails with "remote foo
already exists".
Checking is_configured() certainly sounds like a better test, but...
This original is quite confusing. I thought at first that there was
perhaps something going on with allowing repeated re-configuration of
the same remote, as long as some parameters matched. I.e., I am
wondering if there is a case here that does _not_ segfault, that we
would be breaking.
But reading over fb86e32dcc, I think I have convinced myself that it was
merely an ad-hoc check for "is_configured", and using that function is a
better replacement.
Yes, yes, yes. Y'all are absolutely correct. I shoulda added a test case
right away, to make sure not only that what I fixed does not get broken in
the future, but also to document *what* was fixed, exactly.
So, belatedly, here goes a patch that verifies what that commit was
supposed to fix, and yes, it passes with Thomas' changes (Junio, would you
please apply this on top of tg/git-remote?):
-- snipsnap --
From: Johannes Schindelin <redacted>
Date: Wed, 17 Feb 2016 14:45:59 +0100
Subject: [PATCH] t5505: 'remote add x y' should work when url.y.insteadOf = x
This is the test missing from fb86e32 (git remote: allow adding
remotes agreeing with url.<...>.insteadOf, 2014-12-23): we should
allow adding a remote with the URL when it agrees with the
url.<...>.insteadOf setting.
Signed-off-by: Johannes Schindelin <redacted>
---
t/t5505-remote.sh | 5 +++++
1 file changed, 5 insertions(+)
@@ -51,6 +51,11 @@ test_expect_success setup 'gitcloneonetest'+test_expect_success'add remote whose URL agrees with url.<...>.insteadOf''+gitconfigurl.git@host.com:team/repo.git.insteadOfmyremote&&+gitremoteaddmyremotegit@host.com:team/repo.git+'+ test_expect_successC_LOCALE_OUTPUT'remote information for the origin''(cdtest&&
From: Thomas Gummerer <hidden> Date: 2016-06-15 23:08:17
On 02/17, Johannes Schindelin wrote:
Hi Peff & Thomas,
On Mon, 15 Feb 2016, Jeff King wrote:
quoted
This original is quite confusing. I thought at first that there was
perhaps something going on with allowing repeated re-configuration of
the same remote, as long as some parameters matched. I.e., I am
wondering if there is a case here that does _not_ segfault, that we
would be breaking.
But reading over fb86e32dcc, I think I have convinced myself that it was
merely an ad-hoc check for "is_configured", and using that function is a
better replacement.
Yes, yes, yes. Y'all are absolutely correct. I shoulda added a test case
right away, to make sure not only that what I fixed does not get broken in
the future, but also to document *what* was fixed, exactly.
Thanks for confirming and the test case so we don't break it again.
quoted hunk
So, belatedly, here goes a patch that verifies what that commit was
supposed to fix, and yes, it passes with Thomas' changes (Junio, would you
please apply this on top of tg/git-remote?):
-- snipsnap --
From: Johannes Schindelin <redacted>
Date: Wed, 17 Feb 2016 14:45:59 +0100
Subject: [PATCH] t5505: 'remote add x y' should work when url.y.insteadOf = x
This is the test missing from fb86e32 (git remote: allow adding
remotes agreeing with url.<...>.insteadOf, 2014-12-23): we should
allow adding a remote with the URL when it agrees with the
url.<...>.insteadOf setting.
Signed-off-by: Johannes Schindelin <redacted>
---
t/t5505-remote.sh | 5 +++++
1 file changed, 5 insertions(+)
Minor nit: I think we should use test_config here.
+ git remote add myremote git@host.com:team/repo.git
+'
+
test_expect_success C_LOCALE_OUTPUT 'remote information for the origin' '
(
cd test &&
--
2.7.1.windows.2
Minor nit: I think we should use test_config here.
Good point.
-- snipsnap --
From: Johannes Schindelin <redacted>
Date: Wed, 17 Feb 2016 14:45:59 +0100
Subject: [PATCH] t5505: 'remote add x y' should work when url.y.insteadOf = x
This is the test missing from fb86e32 (git remote: allow adding
remotes agreeing with url.<...>.insteadOf, 2014-12-23): we should
allow adding a remote with the URL when it agrees with the
url.<...>.insteadOf setting.
Signed-off-by: Johannes Schindelin <redacted>
---
t/t5505-remote.sh | 5 +++++
1 file changed, 5 insertions(+)
@@ -51,6 +51,11 @@ test_expect_success setup 'gitcloneonetest'+test_expect_success'add remote whose URL agrees with url.<...>.insteadOf''+test_configurl.git@host.com:team/repo.git.insteadOfmyremote&&+gitremoteaddmyremotegit@host.com:team/repo.git+'+ test_expect_successC_LOCALE_OUTPUT'remote information for the origin''(cdtest&&