Re: [PATCH v1 2/2] worktree: make add dwim

2017-11-18 Thread Thomas Gummerer
On 11/15, Thomas Gummerer wrote:
> On 11/14, Eric Sunshine wrote:
> > On Tue, Nov 14, 2017 at 3:14 PM, Eric Sunshine  
> > wrote:
> > > For my own edification...
> > > [...]
> > > git worktree add ../topic
> > >
> > > * Correctly errors out, refusing to create a new branch named "topic",
> > > if "topic" is already a branch.
> > 
> > By the way, there's an additional DWIM that could be done here instead
> > of erroring out. Specifically, for "git worktree add ../topic":
> > 
> > * If branch "topic" exists, check it out (rather than refusing to
> > create a new branch named "topic").
> 
> I think this would be a good improvement either way as I suspect this
> is what users would hope for, and as it currently just dies there are
> less backwards compatibility worries.

While I still think this would be an improvement, after thinking about
it a bit more I think this is somewhat orthogonal to what I'm trying
to achieve with this patch series.  Therefore I didn't implement this
yet, but I'm still thinking of implementing this in a separate topic.

> > * If origin/topic exists, DWIM local "topic" branch into existence.
> > 
> > * Otherwise, create new local branch "topic".
> > 
> > > * Creates a new branch named "topic" if no such local branch exists.
> > >
> > > The desired new DWIMing would change the second bullet point to:
> > >
> > > * If no local branch named "topic" exists, DWIM it from "origin/topic"
> > > if possible, else create a new local branch named "topic".


Re: [PATCH v1 2/2] worktree: make add dwim

2017-11-15 Thread Eric Sunshine
On Wed, Nov 15, 2017 at 3:50 AM, Thomas Gummerer  wrote:
> On 11/14, Eric Sunshine wrote:
>> git worktree add ../topic
>> [...]
>> The desired new DWIMing would change the second bullet point to:
>>
>> * If no local branch named "topic" exists, DWIM it from "origin/topic"
>> if possible, else create a new local branch named "topic".
>>
>> But that's a behavior change since, with the existing implementation,
>> a newly created local "topic" has no relation to, and does not track,
>> any origin/topic branch. The proposed --guess option is to avoid users
>> being hit by this backward incompatibility, however, one could also
>> view the proposed DWIMing as some sort of bug fix since, at least
>> some, users would expect the DWIMing since it already takes place
>> elsewhere.
>
> I'm not sure we can call it a bug fix anymore, since as Junio pointed
> out the current behaviour of creating a new branch at HEAD is
> documented in the man page.
>
> However git-worktree is also still marked as experimental in the man
> page, so we could allow ourselves to be a little bit more lax when it
> comes to backwards compatibility, especially because it is easy to
> take corrective action after the new DWIMing happened.

Yep, my leaning toward making this new DWIMing default (without a
--guess or --track option) also is based in part on git-worktree still
being marked "experimental".

>> So, at least two options exist:
>>
>> * Just make the new DWIMing the default behavior, accepting that it
>> might bite a few people. Fallout can be mitigated somewhat by
>> prominently announcing that the DWIMing took place, in which case the
>> user can take corrective action (say, by choosing a different worktree
>> name); nothing is lost and no damage done since this is happening only
>> at worktree creation time.
>>
>> * Add a new option to enable DWIMing; perhaps name it -t/--track,
>> which is familiar terminology and still gives you a relatively short
>> and sweet "git worktree add -t ../topic".
>>
>> Given the mentioned mitigation factor and that some/many users likely
>> would expect it to DWIM "origin/topic -> topic" anyhow, I'd lean in
>> favor of the first option (but perhaps I'm too daring with other
>> people's workflows).
>
> Yeah, I'm leaning towards the first option as well, but I'm clearly
> biased as that's how I'd like it to behave, and others might want the
> other behaviour.  Unfortunately I don't know many worktree users, so I
> can't tell what the general consensus on this would be.

Aside from the mentioned mitigation factor, which somewhat eases my
worries about backward incompatibility, one genuine concern is
breaking existing scripts. At the very least, if the new DWIM becomes
default, there might need to be some escape hatch for scripts to opt
out of it.

> I guess the second option would be the safer one, and we can still
> switch that to be the default at some point if we wish to do so
> later.

The longer you wait, the less likely you'll have the chance since
git-worktree will (presumably) gain more users and be used in more
scripts as time passes. So, if the new DWIMing is to become the
default, better to do so earlier rather than later.

> tl;dr I have no idea which of the options would be better :)

I'm probably too cavalier and shortsighted (at least on this topic) to
make a well-informed decision about it. Junio probably has a better
feeling about whether such a change of behavior makes sense at this
late date, and, of course, it's his decision whether to accept such a
change into his tree.


Re: [PATCH v1 2/2] worktree: make add dwim

2017-11-15 Thread Thomas Gummerer
On 11/14, Eric Sunshine wrote:
> On Tue, Nov 14, 2017 at 3:14 PM, Eric Sunshine  
> wrote:
> > For my own edification...
> > [...]
> > git worktree add ../topic
> >
> > * Correctly errors out, refusing to create a new branch named "topic",
> > if "topic" is already a branch.
> 
> By the way, there's an additional DWIM that could be done here instead
> of erroring out. Specifically, for "git worktree add ../topic":
> 
> * If branch "topic" exists, check it out (rather than refusing to
> create a new branch named "topic").

I think this would be a good improvement either way as I suspect this
is what users would hope for, and as it currently just dies there are
less backwards compatibility worries.

> * If origin/topic exists, DWIM local "topic" branch into existence.
> 
> * Otherwise, create new local branch "topic".
> 
> > * Creates a new branch named "topic" if no such local branch exists.
> >
> > The desired new DWIMing would change the second bullet point to:
> >
> > * If no local branch named "topic" exists, DWIM it from "origin/topic"
> > if possible, else create a new local branch named "topic".


Re: [PATCH v1 2/2] worktree: make add dwim

2017-11-15 Thread Thomas Gummerer
On 11/14, Eric Sunshine wrote:
> On Tue, Nov 14, 2017 at 3:45 AM, Thomas Gummerer  wrote:
> > On 11/13, Junio C Hamano wrote:
> >> If so, as long as the new DWIM kicks in ONLY when "topic" does not
> >> exist, I suspect that there is no backward compatibility worries.
> >> The command line
> >>
> >> $ git worktree add ../a-new-worktree topic
> >>
> >> would just have failed because three was no 'topic' branch yet, no?
> >
> > Indeed, with this there would not be any backwards compatility
> > worries.
> >
> > Ideally I'd still like to make
> >
> > $ git worktree add ../topic
> >
> > work as described above, to avoid having to type 'topic' twice (the
> > directory name matches the branch name for the vast majority of my
> > worktrees) but that should then come behind a flag/config option?
> > Following your reasoning above it should probably be called something
> > other than --guess.
> >
> > Maybe --guess-remote and worktree.guessRemote would do?  I'm quite bad
> > at naming though, so other suggestions are very welcome.
> 
> For my own edification...
> 
> git worktree add ../dir branch
> 
> * Checks out branch into ../dir if branch exists.
> 
> * Errors out if branch does not exist. However, if we consider the
> history of the implementation of worktrees[*1*], then this really
> ought to try the "origin/branch -> branch" DWIM before erroring-out.
> Implementing this DWIM could be considered a regression fix according
> to [*1*] and, as Junio points out, should not pose backward
> compatibility worries.

Agreed, I think it is not very controversial that this would be an
improvement.

> git worktree add ../topic
> 
> * Correctly errors out, refusing to create a new branch named "topic",
> if "topic" is already a branch.
> 
> * Creates a new branch named "topic" if no such local branch exists.
> 
> The desired new DWIMing would change the second bullet point to:
> 
> * If no local branch named "topic" exists, DWIM it from "origin/topic"
> if possible, else create a new local branch named "topic".
> 
> But that's a behavior change since, with the existing implementation,
> a newly created local "topic" has no relation to, and does not track,
> any origin/topic branch. The proposed --guess option is to avoid users
> being hit by this backward incompatibility, however, one could also
> view the proposed DWIMing as some sort of bug fix since, at least
> some, users would expect the DWIMing since it already takes place
> elsewhere.

I'm not sure we can call it a bug fix anymore, since as Junio pointed
out the current behaviour of creating a new branch at HEAD is
documented in the man page.

However git-worktree is also still marked as experimental in the man
page, so we could allow ourselves to be a little bit more lax when it
comes to backwards compatibility, especially because it is easy to
take corrective action after the new DWIMing happened.

> So, at least two options exist:
> 
> * Just make the new DWIMing the default behavior, accepting that it
> might bite a few people. Fallout can be mitigated somewhat by
> prominently announcing that the DWIMing took place, in which case the
> user can take corrective action (say, by choosing a different worktree
> name); nothing is lost and no damage done since this is happening only
> at worktree creation time.
> 
> * Add a new option to enable DWIMing; perhaps name it -t/--track,
> which is familiar terminology and still gives you a relatively short
> and sweet "git worktree add -t ../topic".
> 
> Given the mentioned mitigation factor and that some/many users likely
> would expect it to DWIM "origin/topic -> topic" anyhow, I'd lean in
> favor of the first option (but perhaps I'm too daring with other
> people's workflows).

Yeah, I'm leaning towards the first option as well, but I'm clearly
biased as that's how I'd like it to behave, and others might want the
other behaviour.  Unfortunately I don't know many worktree users, so I
can't tell what the general consensus on this would be.

I guess the second option would be the safer one, and we can still
switch that to be the default at some point if we wish to do so
later.

tl;dr I have no idea which of the options would be better :)

> FOOTNOTES
> 
> [*1*]: When Duy first implemented worktree support, he incorporated it
> directly into the git-checkout command ("git checkout --to worktree
> ..."), which means that he got all the git-checkout features for free,
> including the "origin/branch -> branch" DWIM. When worktree support
> was later moved to git-worktree, it lost most of the features
> inherited implicitly from git-checkout, such as -b, -B, --detach, so
> those were added back to git-worktree explicitly. However, at that
> early stage, git-worktree was still piggy-backing atop git-checkout,
> thus likely was still getting the "origin/branch -> branch" DWIM for
> free. A final iteration converted git-worktree away from heavyweight
> git-checkout to lightweight git-reset, at which point he DWIMing was
> l

Re: [PATCH v1 2/2] worktree: make add dwim

2017-11-14 Thread Eric Sunshine
On Tue, Nov 14, 2017 at 3:14 PM, Eric Sunshine  wrote:
> For my own edification...
> [...]
> git worktree add ../topic
>
> * Correctly errors out, refusing to create a new branch named "topic",
> if "topic" is already a branch.

By the way, there's an additional DWIM that could be done here instead
of erroring out. Specifically, for "git worktree add ../topic":

* If branch "topic" exists, check it out (rather than refusing to
create a new branch named "topic").

* If origin/topic exists, DWIM local "topic" branch into existence.

* Otherwise, create new local branch "topic".

> * Creates a new branch named "topic" if no such local branch exists.
>
> The desired new DWIMing would change the second bullet point to:
>
> * If no local branch named "topic" exists, DWIM it from "origin/topic"
> if possible, else create a new local branch named "topic".


Re: [PATCH v1 2/2] worktree: make add dwim

2017-11-14 Thread Eric Sunshine
On Tue, Nov 14, 2017 at 3:45 AM, Thomas Gummerer  wrote:
> On 11/13, Junio C Hamano wrote:
>> If so, as long as the new DWIM kicks in ONLY when "topic" does not
>> exist, I suspect that there is no backward compatibility worries.
>> The command line
>>
>> $ git worktree add ../a-new-worktree topic
>>
>> would just have failed because three was no 'topic' branch yet, no?
>
> Indeed, with this there would not be any backwards compatility
> worries.
>
> Ideally I'd still like to make
>
> $ git worktree add ../topic
>
> work as described above, to avoid having to type 'topic' twice (the
> directory name matches the branch name for the vast majority of my
> worktrees) but that should then come behind a flag/config option?
> Following your reasoning above it should probably be called something
> other than --guess.
>
> Maybe --guess-remote and worktree.guessRemote would do?  I'm quite bad
> at naming though, so other suggestions are very welcome.

For my own edification...

git worktree add ../dir branch

* Checks out branch into ../dir if branch exists.

* Errors out if branch does not exist. However, if we consider the
history of the implementation of worktrees[*1*], then this really
ought to try the "origin/branch -> branch" DWIM before erroring-out.
Implementing this DWIM could be considered a regression fix according
to [*1*] and, as Junio points out, should not pose backward
compatibility worries.

git worktree add ../topic

* Correctly errors out, refusing to create a new branch named "topic",
if "topic" is already a branch.

* Creates a new branch named "topic" if no such local branch exists.

The desired new DWIMing would change the second bullet point to:

* If no local branch named "topic" exists, DWIM it from "origin/topic"
if possible, else create a new local branch named "topic".

But that's a behavior change since, with the existing implementation,
a newly created local "topic" has no relation to, and does not track,
any origin/topic branch. The proposed --guess option is to avoid users
being hit by this backward incompatibility, however, one could also
view the proposed DWIMing as some sort of bug fix since, at least
some, users would expect the DWIMing since it already takes place
elsewhere.

So, at least two options exist:

* Just make the new DWIMing the default behavior, accepting that it
might bite a few people. Fallout can be mitigated somewhat by
prominently announcing that the DWIMing took place, in which case the
user can take corrective action (say, by choosing a different worktree
name); nothing is lost and no damage done since this is happening only
at worktree creation time.

* Add a new option to enable DWIMing; perhaps name it -t/--track,
which is familiar terminology and still gives you a relatively short
and sweet "git worktree add -t ../topic".

Given the mentioned mitigation factor and that some/many users likely
would expect it to DWIM "origin/topic -> topic" anyhow, I'd lean in
favor of the first option (but perhaps I'm too daring with other
people's workflows).

FOOTNOTES

[*1*]: When Duy first implemented worktree support, he incorporated it
directly into the git-checkout command ("git checkout --to worktree
..."), which means that he got all the git-checkout features for free,
including the "origin/branch -> branch" DWIM. When worktree support
was later moved to git-worktree, it lost most of the features
inherited implicitly from git-checkout, such as -b, -B, --detach, so
those were added back to git-worktree explicitly. However, at that
early stage, git-worktree was still piggy-backing atop git-checkout,
thus likely was still getting the "origin/branch -> branch" DWIM for
free. A final iteration converted git-worktree away from heavyweight
git-checkout to lightweight git-reset, at which point he DWIMing was
lost. If you take this history into account, then loss of
"origin/branch -> branch" DWIMing is a regression, so restoring it
could be considered a bug fix.


Re: [PATCH v1 2/2] worktree: make add dwim

2017-11-14 Thread Thomas Gummerer
On 11/13, Junio C Hamano wrote:
> Thomas Gummerer  writes:
> 
> > I'm a bit torn about hiding his behind an additional flag in git
> > worktree add or not.  I would like to have the feature without the
> > additional flag, but it might break some peoples expectations, so
> > dunno.
> 
> Yeah, I agree with the sentiment.  But what expectation would we be
> breaking, I wonder (see below)?
> 
> At the conceptual level, it is even more unfortunate that "git
> worktree --help" says this for "git worktree add  []":
> 
> If `` is omitted and neither `-b` nor `-B` nor
> `--detach` used, then, as a convenience, a new branch based at
> HEAD is created automatically, as if `-b $(basename )` was
> specified.
> 
> which means that it already does a DWIM, namely "since you didn't
> say what branch to create to track what other branch, we'll fork one
> for you from the HEAD, and give a name to it".  That may be a useful
> DWIM for some existing users sometimes, and you may even find it
> useful some of the time but not always.  Different people mean
> different things in different situations, and there is no single
> definition for DWIMming that would fit all of them.
> 
> Which in turn means that the new variable name DWIM_NEW_BRANCH and
> the new option name GUESS are way underspecified.  You'd need to
> name them after the "kind" of dwim; otherwise, not only the future
> additions for new (third) kind of dwim would become cumbersome, but
> readers of the code would be confused if they are about the existing
> dwim (fork a new branch from HEAD and give it a name guessed by the
> pathname) or your new dwim.

Yeah I definitely agree with that.  I was mainly thinking about my
personal use case with --guess, and didn't fully think through that it
might mean different things to other people.

> This also needs a documentation update.  Unlike the existing DWIM,
> it is totally unclear when you are dwimming in absence of which
> option.

Sorry about that, I totally forgot about the documentation for this.
Will add in the next round.

> I am guessing that, when you do not have a branch "topic" but your
> upstream does, saying
> 
> $ git worktree add ../a-new-worktree topic
> 
> would create "refs/heads/topic" to build on top of
> "refs/remotes/origin/topic" just like "git checkout topic" would.
> 
> IOW, when fully spelled out:
> 
> $ git branch -t -b topic origin/topic
> $ git worktree add ../a-new-worktree topic
> 
> is what your DWIM does?  Am I following you correctly?

It's not quite what my DWIM does/what I originally intended my DWIM to
do.  What it does is when

$ git worktree add ../topic

and omitting the branch argument, it would behave the way you spelled
out, i.e.

$ git branch -t -b topic origin/topic
$ git worktree add ../topic topic

instead of just checking it out from HEAD.  I must confess I missed
the branch argument, so that still behaves the old way with my code,
while what you have above would make a lot more sense.

> If so, as long as the new DWIM kicks in ONLY when "topic" does not
> exist, I suspect that there is no backward compatibility worries.
> The command line
> 
> $ git worktree add ../a-new-worktree topic
> 
> would just have failed because three was no 'topic' branch yet, no?

Indeed, with this there would not be any backwards compatility
worries.

Ideally I'd still like to make

$ git worktree add ../topic

work as described above, to avoid having to type 'topic' twice (the
directory name matches the branch name for the vast majority of my
worktrees) but that should then come behind a flag/config option?
Following your reasoning above it should probably be called something
other than --guess.

Maybe --guess-remote and worktree.guessRemote would do?  I'm quite bad
at naming though, so other suggestions are very welcome.


Re: [PATCH v1 2/2] worktree: make add dwim

2017-11-12 Thread Junio C Hamano
Thomas Gummerer  writes:

> I'm a bit torn about hiding his behind an additional flag in git
> worktree add or not.  I would like to have the feature without the
> additional flag, but it might break some peoples expectations, so
> dunno.

Yeah, I agree with the sentiment.  But what expectation would we be
breaking, I wonder (see below)?

At the conceptual level, it is even more unfortunate that "git
worktree --help" says this for "git worktree add  []":

If `` is omitted and neither `-b` nor `-B` nor
`--detach` used, then, as a convenience, a new branch based at
HEAD is created automatically, as if `-b $(basename )` was
specified.

which means that it already does a DWIM, namely "since you didn't
say what branch to create to track what other branch, we'll fork one
for you from the HEAD, and give a name to it".  That may be a useful
DWIM for some existing users sometimes, and you may even find it
useful some of the time but not always.  Different people mean
different things in different situations, and there is no single
definition for DWIMming that would fit all of them.

Which in turn means that the new variable name DWIM_NEW_BRANCH and
the new option name GUESS are way underspecified.  You'd need to
name them after the "kind" of dwim; otherwise, not only the future
additions for new (third) kind of dwim would become cumbersome, but
readers of the code would be confused if they are about the existing
dwim (fork a new branch from HEAD and give it a name guessed by the
pathname) or your new dwim.

This also needs a documentation update.  Unlike the existing DWIM,
it is totally unclear when you are dwimming in absence of which
option.

I am guessing that, when you do not have a branch "topic" but your
upstream does, saying

$ git worktree add ../a-new-worktree topic

would create "refs/heads/topic" to build on top of
"refs/remotes/origin/topic" just like "git checkout topic" would.

IOW, when fully spelled out:

$ git branch -t -b topic origin/topic
$ git worktree add ../a-new-worktree topic

is what your DWIM does?  Am I following you correctly?

If so, as long as the new DWIM kicks in ONLY when "topic" does not
exist, I suspect that there is no backward compatibility worries.
The command line

$ git worktree add ../a-new-worktree topic

would just have failed because three was no 'topic' branch yet, no?



[PATCH v1 2/2] worktree: make add dwim

2017-11-12 Thread Thomas Gummerer
Currently git worktree add creates a new branch, that matches the HEAD
of whichever worktree we were on when calling "git worktree add".

Add a --guess flag to git worktree add, that makes it behave like the
dwim machinery in 'git checkout ', i.e. check if the new
branch name uniquely matches the branch name of a remote tracking
branch, and if so check out that branch, and set the upstream to the
remote tracking branch.

Signed-off-by: Thomas Gummerer 
---

I'm a bit torn about hiding his behind an additional flag in git
worktree add or not.  I would like to have the feature without the
additional flag, but it might break some peoples expectations, so
dunno.

 builtin/worktree.c  | 14 +-
 t/t2025-worktree-add.sh | 70 +
 2 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/builtin/worktree.c b/builtin/worktree.c
index 7b9307aa58..5740d1f8a3 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "checkout.h"
 #include "config.h"
 #include "builtin.h"
 #include "dir.h"
@@ -341,6 +342,7 @@ static int add(int ac, const char **av, const char *prefix)
const char *new_branch_force = NULL;
char *path;
const char *branch;
+   int dwim_new_branch = 0;
struct option options[] = {
OPT__FORCE(&opts.force, N_("checkout  even if already 
checked out in other worktree")),
OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
@@ -350,6 +352,7 @@ static int add(int ac, const char **av, const char *prefix)
OPT_BOOL(0, "detach", &opts.detach, N_("detach HEAD at named 
commit")),
OPT_BOOL(0, "checkout", &opts.checkout, N_("populate the new 
working tree")),
OPT_BOOL(0, "lock", &opts.keep_locked, N_("keep the new working 
tree locked")),
+   OPT_BOOL(0, "guess", &dwim_new_branch, N_("checkout upstream 
branch if there's a unique match")),
OPT_END()
};
 
@@ -363,6 +366,7 @@ static int add(int ac, const char **av, const char *prefix)
 
path = prefix_filename(prefix, av[0]);
branch = ac < 2 ? "HEAD" : av[1];
+   dwim_new_branch = ac < 2 ? dwim_new_branch : 0;
 
if (!strcmp(branch, "-"))
branch = "@{-1}";
@@ -387,13 +391,21 @@ static int add(int ac, const char **av, const char 
*prefix)
}
 
if (opts.new_branch) {
+   struct object_id oid;
+   const char *remote;
struct child_process cp = CHILD_PROCESS_INIT;
+
+   remote = unique_tracking_name(opts.new_branch, &oid);
+
cp.git_cmd = 1;
argv_array_push(&cp.args, "branch");
if (opts.force_new_branch)
argv_array_push(&cp.args, "--force");
argv_array_push(&cp.args, opts.new_branch);
-   argv_array_push(&cp.args, branch);
+   if (dwim_new_branch && remote)
+   argv_array_push(&cp.args, remote);
+   else
+   argv_array_push(&cp.args, branch);
if (run_command(&cp))
return -1;
branch = opts.new_branch;
diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh
index b5c47ac602..b37c279787 100755
--- a/t/t2025-worktree-add.sh
+++ b/t/t2025-worktree-add.sh
@@ -6,6 +6,16 @@ test_description='test git worktree add'
 
 . "$TEST_DIRECTORY"/lib-rebase.sh
 
+# Is branch "refs/heads/$1" set to pull from "$2/$3"?
+test_branch_upstream () {
+   printf "%s\n" "$2" "refs/heads/$3" >expect.upstream &&
+   {
+   git config "branch.$1.remote" &&
+   git config "branch.$1.merge"
+   } >actual.upstream &&
+   test_cmp expect.upstream actual.upstream
+}
+
 test_expect_success 'setup' '
test_commit init
 '
@@ -314,4 +324,64 @@ test_expect_success 'rename a branch under bisect not 
allowed' '
test_must_fail git branch -M under-bisect bisect-with-new-name
 '
 
+test_expect_success 'git worktree add does not dwim' '
+   test_when_finished rm -rf repo_a &&
+   test_when_finished rm -rf repo_b &&
+   test_when_finished rm -rf foo &&
+   git init repo_a &&
+   (
+   cd repo_a &&
+   test_commit a_master &&
+   git checkout -b foo &&
+   test_commit a_foo
+   ) &&
+   git init repo_b &&
+   (
+   cd repo_b &&
+   test_commit b_master &&
+   git remote add repo_a ../repo_a &&
+   git config remote.repo_a.fetch \
+   "+refs/heads/*:refs/remotes/other_a/*" &&
+   git fetch --all &&
+   git worktree add ../foo
+   ) &&
+   (
+   cd foo &&
+   ! test_branch_upstream foo repo_a foo &&
+   git rev-parse other_a/foo >expect &&
+   git rev-parse foo >actu