Re: [PATCH] When a remote is added but not fetched, tell the user.

Previous thread: [PATCH] (parsecvs) avoid "git mktag" failure with newer git by Jim Meyering on Wednesday, April 9, 2008 - 3:01 am. (1 message)

Next thread: [PATCH] Re: git clean removes directories when not asked to by Joachim B Haga on Wednesday, April 9, 2008 - 10:04 am. (12 messages)
From: Ingo Molnar
Date: Wednesday, April 9, 2008 - 3:14 am

i just had a rather annoying session with git - here's the dump and 
commentary, in case anyone is interested in usability fineprint.

it was with git-core-1.5.4.3-2.fc8 - so if it's all fixed/improved in 
1.5.5, or if this is blatant user error for which i deserve to be 
punished then my apologies!

usually i just have a single git repo that tracks everything 
interesting, but this time i did something i rarely do: i tried to merge 
one local tree of mine into another local tree of mine. So i had no 
commands (or even concepts) cached in my short-term memory that would 
achieve this goal, i just tried the commands that i thought to be 
'obvious', without applying much (or any) IQ to those commands:

 $ cd linux-2.6-sched-devel.git

 $ git-remote add ~/linux-2.6-x86.git

 $ git-remote show x86
  * remote x86
    URL: /home/mingo/linux-2.6-x86.git
  New remote branches (next fetch will store in remotes/x86)
  base for-akpm for-linus latest master testing

 $ git-merge x86/latest
 x86/latest - not something we can merge

 #
 # ho hum. Not something 'we' can merge. Do i care? :-) There's no 
 # actionable reference given to the user about how to resolve this 
 # problem. So i kept on trying:
 #

 $ git-fetch x86/latest
 fatal: 'x86/latest': unable to chdir or not a git archive
 fatal: The remote end hung up unexpectedly

 $ git-pull x86/latest
 fatal: 'x86/latest': unable to chdir or not a git archive
 fatal: The remote end hung up unexpectedly

 #
 # hm. two fatal messages, suggesting that there's something really 
 # wrong while there's nothing wrong.
 #

what got me going after experimenting around some more was this exact 
command:

 $ git-pull x86 latest

(that fetch+merge went problem-free.)

but it was a PITA and all of git's messages about the problem were not 
only unhelpful, they confused me into looking for problems where there 
were none IMO. I was starting to wonder whether i have to have some git 
daemon running on that box for example. But ...
From: Gabriel
Date: Thursday, April 10, 2008 - 4:25 pm

A helpful message tells the user when a remote was added
without being fetched, and how to fetch it.

Our default of not fetching is breaking the users' workflow
in the common "let me access this repo" use case.
This message alleviates the problem.

Signed-off-by: Gabriel <g2p.code@gmail.com>
---
 builtin-remote.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/builtin-remote.c b/builtin-remote.c
index d77f10a..044215a 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -111,8 +111,16 @@ static int add(int argc, const char **argv)
 			return 1;
 	}
 
-	if (fetch && fetch_remote(name))
-		return 1;
+	if (fetch) {
+		if (fetch_remote(name))
+			return 1;
+	}
+	else {
+		printf ("Added remote repository `%s' without fetching it.\n"
+			"Before accessing the branches of this "
+			"remote, run `git fetch %s' "
+			"or `git remote update'.\n", name, name);
+	}
 
 	if (master) {
 		strbuf_reset(&buf);
-- 
1.5.5.24.geb27

--

From: Johannes Schindelin
Date: Friday, April 11, 2008 - 8:21 am

Hi,


Is this really, really necessary?  I was quite happy when a few people 
made Git less chatty, recently.

Ciao,
Dscho

--

From: Gabriel
Date: Friday, April 11, 2008 - 11:35 am

Le Fri, 11 Apr 2008 16:21:45 +0100 (BST),

Not necessary, but a real usability improvement.

I think the transcript that started the thread makes it clear that
having "git remote add" not fetching is not the right default.
The user wants to use a remote repository, and has learned these are
called "remotes". So he does not have too much trouble
finding/remembering the command "git remote add <name> <url>". Now with
the user's goal in mind, it makes no sense to add a remote and then not
fetch it, because the user definitely wants to do something with the
remote. By not fetching it, we are surprising the user (this is
apparent in the transcript), maybe we are making him go through some
documentation, and he will have to go through a mental
checklist "did I add the remote? yes. did I fetch it? yes" later on.

The best solution is a patch that makes --fetch default to yes for git
remote add and discuss that.

In case the remote wasn't fetched, adding some documentation at a place
where it _will_ be needed does no harm. This is not an operation as
frequent as git status or git checkout, so the three lines it takes in
a terminal aren't expensive. A more experienced user that usually runs
"git remote add -f", will not see it either.

-- 
Gabriel
--

From: Gabriel
Date: Friday, April 11, 2008 - 11:39 am

This is what the user wants in 99% of cases.

Signed-off-by: Gabriel <g2p.code@gmail.com>
---
 Documentation/git-remote.txt |    4 ++--
 builtin-remote.c             |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 2cbd1f7..04de972 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -10,7 +10,7 @@ SYNOPSIS
 --------
 [verse]
 'git-remote'
-'git-remote' add [-t <branch>] [-m <master>] [-f] [--mirror] <name> <url>
+'git-remote' add [-t <branch>] [-m <master>] [--no-fetch] [--mirror] <name> <url>
 'git-remote' rm <name>
 'git-remote' show <name>
 'git-remote' prune <name>
@@ -34,7 +34,7 @@ Adds a remote named <name> for the repository at
 <url>.  The command `git fetch <name>` can then be used to create and
 update remote-tracking branches <name>/<branch>.
 +
-With `-f` option, `git fetch <name>` is run immediately after
+Without the `--no-fetch` option, `git fetch <name>` is run immediately after
 the remote information is set up.
 +
 With `-t <branch>` option, instead of the default glob
diff --git a/builtin-remote.c b/builtin-remote.c
index 044215a..c0d7d96 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -54,7 +54,7 @@ static int fetch_remote(const char *name)
 
 static int add(int argc, const char **argv)
 {
-	int fetch = 0, mirror = 0;
+	int fetch = 1, mirror = 0;
 	struct path_list track = { NULL, 0, 0 };
 	const char *master = NULL;
 	struct remote *remote;
-- 
1.5.5.25.g17ee

--

From: Stephen Sinclair
Date: Friday, April 11, 2008 - 12:17 pm

Where did you get these magical statistics?
I, for one, have never expected this behaviour.

Steve
--

From: Johannes Schindelin
Date: Saturday, April 12, 2008 - 7:33 am

Hi,


This is wrong, at least in my experience.  Do not make up statistics if 
you want to be taken seriously.

Ciao,
Dscho
--

From: Gabriel
Date: Saturday, April 12, 2008 - 8:13 am

On Sat, 12 Apr 2008 15:33:30 +0100 (BST),

This is obviously not a real statistic, and poor wording on my part. It
was meant to summarise the justification that I gave in the parent
mail; that justification was certainly up to discussion, and it turns
out I was wrong.

Which leaves us with the other suggestion of the previous patch, that
others have discussed. Now that we have the maintainer's opinion, this
is also settled.

Anyway, it's easy to get into subjective arguments on usability, and
I'll be more careful about this. Which shouldn't prevent us from
improving git usability.
--

From: Johannes Schindelin
Date: Saturday, April 12, 2008 - 8:24 am

Hi,


Thanks for ignoring my opinion.

Have a nice life,
Dscho

--

From: Gabriel
Date: Friday, April 11, 2008 - 12:29 pm

This is what the user wants in 99% of cases.

Signed-off-by: Gabriel <g2p.code@gmail.com>
---

Also update some tests; disregard the previous patch.

 Documentation/git-remote.txt |    4 ++--
 builtin-remote.c             |    2 +-
 t/t5503-tagfollow.sh         |    2 +-
 t/t5512-ls-remote.sh         |    2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 2cbd1f7..04de972 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -10,7 +10,7 @@ SYNOPSIS
 --------
 [verse]
 'git-remote'
-'git-remote' add [-t <branch>] [-m <master>] [-f] [--mirror] <name> <url>
+'git-remote' add [-t <branch>] [-m <master>] [--no-fetch] [--mirror] <name> <url>
 'git-remote' rm <name>
 'git-remote' show <name>
 'git-remote' prune <name>
@@ -34,7 +34,7 @@ Adds a remote named <name> for the repository at
 <url>.  The command `git fetch <name>` can then be used to create and
 update remote-tracking branches <name>/<branch>.
 +
-With `-f` option, `git fetch <name>` is run immediately after
+Without the `--no-fetch` option, `git fetch <name>` is run immediately after
 the remote information is set up.
 +
 With `-t <branch>` option, instead of the default glob
diff --git a/builtin-remote.c b/builtin-remote.c
index 044215a..c0d7d96 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -54,7 +54,7 @@ static int fetch_remote(const char *name)
 
 static int add(int argc, const char **argv)
 {
-	int fetch = 0, mirror = 0;
+	int fetch = 1, mirror = 0;
 	struct path_list track = { NULL, 0, 0 };
 	const char *master = NULL;
 	struct remote *remote;
diff --git a/t/t5503-tagfollow.sh b/t/t5503-tagfollow.sh
index 86e5b9b..fd075d9 100755
--- a/t/t5503-tagfollow.sh
+++ b/t/t5503-tagfollow.sh
@@ -134,7 +134,7 @@ test_expect_success 'new clone fetch master and tags' '
 		mkdir clone2 &&
 		cd clone2 &&
 		git init &&
-		git remote add origin .. &&
+		git remote add origin .. --no-fetch ...
From: Wincent Colaiuta
Date: Friday, April 11, 2008 - 12:36 pm

Not sure about that. I often add a remote then push, not fetch.

Cheers,
Wincent


--

From: Teemu Likonen
Date: Friday, April 11, 2008 - 12:08 pm

Hmm, I'm quite newbie but I have never expected "git remote add" to
fetch anything. I wouldn't want it to do it automatically. From the
beginning I saw "git remote" as a _configuration_ tool. No doubt it's
common to fetch after configuring a remote but in my mind they are two
logically different steps (configure, fetch/pull) which I think should
be kept separate. Once I have configured something I may want to check
that I did the right thing, then configure some more remotes and maybe
fetch tomorrow. Maybe I don't want to fetch at all but only pull from
that remote. So let's not build ready workflows for users, only
convenient, logical tools.

That said, I don't mind short messages like "use 'git fetch' to obtain
branches" but I don't think that is necessary.
--

From: Junio C Hamano
Date: Friday, April 11, 2008 - 2:39 pm

Good student ;-).

Not only that fetch-after-add is _not_ a common nor majority thing at all
(contrary to what Gabriel assumed), the "fetch" step is conceptually an
unrelated operation from the primary point of "remote add"; "-f" option is
a mere convenience feature and we stop at making it conveniently
available, never making it a default nor overly advertising it.

If the user tells you not to fetch, the command should not bother the user
with excess messages, unless the user explicitly asks to, either.
--

From: Sverre Rabbelier
Date: Friday, April 11, 2008 - 3:35 pm

I fully agree here, but is there a way for the user to do so?
Especially the beginning user? Perhaps in the form of a -v(erbose)
switch, but for that to be useful it would have to be present across
most/all commands and have the same (type of) result. That is, it
should provide the user with additional information on what they did
wrong/what they likely want to do from here.
In this case though I agree that, as Teemu pointed out, 'git remote
add' is a config tool. 'man git remote add' points this out more than
clearly enough for regular use. Maybe keep it in mind for the to-be
"git mind reading" functionality.

Cheers,

Sverre Rabbelier
--

From: Junio C Hamano
Date: Friday, April 11, 2008 - 4:15 pm

Yeah, I am not sure if that should be called --verbose, but a "training
wheel" mode of operation somebody else mentioned the other day that echoes
back what the command thinks it was told to do by the user, together with
help text that explains what other things the user could have told to the
command to enrich its operation, might be an interesting addition.


--

From: Sverre Rabbelier
Date: Friday, April 11, 2008 - 4:20 pm

Hmmm, I'm not sure about '--verbose' as a name either, but it -is-
usually used to display more information about the command(s) being
executed. E.g.:
-v, --verbose
	      explain what is being done
http://unixhelp.ed.ac.uk/CGI/man-cgi?mv
Sounds pretty much like what we're doing, explaining what command we
thing is being executed. The extra text OTOH with 'possible other
workflow suggestions' doesn't quite fit in the '--verbose' picture.
Perhaps a different kind of command, like '--newbie' (or, less
humiliating, '--explain') would be more appropriate.
--

From: Miles Bader
Date: Monday, April 14, 2008 - 8:15 pm

I agree.

An automatic fetch would be ... surprising.

-Miles

-- 
"Don't just question authority,
Don't forget to question me."
-- Jello Biafra
--

From: Björn
Date: Wednesday, April 9, 2008 - 3:41 am

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I gues that's key here. The remote was added, but you don't actually
have fetched the branches yet. Thus the merge fails, but the pull with


The syntax is "git pull <repository> <refspec>"

So you're trying to fetch/pull from a repository in "x86/latest", that
path doesn't exist and that is pretty fatal as you cannot fetch/pull


AFAIK merge cannot handle stuff that's outside your repo. To merge stuff
from another repo without adding a remote, you have to use pull (or
manually do the fetch+merge dance), ie.:

git pull ~/linux-2.6-x86.git latest

should do.

Björn
--

From: Jeff King
Date: Wednesday, April 9, 2008 - 7:57 am

As you figured out later, the problem was that "git remote add" doesn't
actually fetch the remote's contents: it just sets up the remote. There
is a "-f" option which does the fetch automagically after adding.

In this case, had "-f" been the default, it would have Just Worked for
you. So that's something for us to consider, but I'm not sure if we

This is another place where we might have DWYM, by seeing that your
repository name started with "<name of a remote>/" and splitting it into
"<remote> <branch>". This could affect current usage, but it seems
unlikely that people have remote names which are exact prefixes (with
trailing slash) of non-remote repositories they are trying to fetch.

Reading "git help fetch" should show you the synopsis:

  git-fetch <options> <repository> <refspec>

which maybe gives a clue about the syntax. But I think the problem here
is that there are two different syntaxes for what is _almost_ the same
thing. The ref refs/remotes/x86/latest, which you can call "x86/latest"

Unless you are planning on merging this remote a lot, the common usage
is probably to just forget the remote stuff and do:


Yes, just showing the remotes would be consistent with what other

That is an annoying message. Perhaps we could notice that it looks like
a file path (because it begins with '.') and suggest "maybe you wanted
to "git pull ..."?

-Peff
--

From: Jeff King
Date: Wednesday, April 9, 2008 - 8:15 am

Many other commands use the "no arguments" form to show a
list (e.g., git-branch, git-tag). While we did show all
remotes for just "git remote", we displayed a usage error
for "git remote show" with no arguments. This is
counterintuitive, since by giving it _more_ information, we
get _less_ result.

The usage model can now be thought of as:

  - "git remote show <remote>": show a remote
  - "git remote show": show all remotes
  - "git remote": assume "show"; i.e., shorthand for "git remote show"

Signed-off-by: Jeff King <peff@peff.net>
---

And here it is.

 builtin-remote.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/builtin-remote.c b/builtin-remote.c
index d77f10a..06d33e5 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -19,6 +19,8 @@ static const char * const builtin_remote_usage[] = {
 
 static int verbose;
 
+static int show_all(void);
+
 static inline int postfixcmp(const char *string, const char *postfix)
 {
 	int len1 = strlen(string), len2 = strlen(postfix);
@@ -380,8 +382,11 @@ static int show_or_prune(int argc, const char **argv, int prune)
 
 	argc = parse_options(argc, argv, options, builtin_remote_usage, 0);
 
-	if (argc < 1)
+	if (argc < 1) {
+		if (!prune)
+			return show_all();
 		usage_with_options(builtin_remote_usage, options);
+	}
 
 	memset(&states, 0, sizeof(states));
 	for (; argc; argc--, argv++) {
-- 
1.5.5.1.g272c

--

From: Ingo Molnar
Date: Wednesday, April 9, 2008 - 1:07 pm

cool, thanks!

	Ingo
--

From: Ingo Molnar
Date: Thursday, April 10, 2008 - 12:59 pm

btw., another suggestion: because i use 'git-remote show' rather 
frequently, i recently typoed "git-bisect show" and then realized that 
it was "git-bisect visualize". Shouldnt there be a "git-bisect show" 
alias?

I think using 'show' for all such 'display state' things would be rather 
intuitive, if it was applied consistently all across the board. 
('visualize' could still remain indefinitely, for compatibility - and 
'git-bisect log' would still do the log of the bisection decisions that 
were entered.)

Or is there some purpose behind this deviation that i missed?

	Ingo
--

From: Johannes Schindelin
Date: Wednesday, April 9, 2008 - 9:54 am

Hi,


Acked-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>

Ciao,
Dscho

--

From: Junio C Hamano
Date: Thursday, April 10, 2008 - 3:56 am

Applied, thanks.
--

From: Teemu Likonen
Date: Wednesday, April 9, 2008 - 1:08 pm

I have found this refs/heads/*:refs/remotes/* stuff quite confusing, but
I'm starting to understand them. I know my way with them but still they
seem quite unnecessary hackerish. Pull and push work pretty nicely
without knowing about any refs/* stuff; they can be operated with simple
branch names. Fetch is another story. Some ideas:

  $ git fetch <URL>

would be equivalent to

  $ git fetch <URL> +refs/heads/*:refs/remotes/<name>/*

In other words, fetch all the branches from remote repo and store them
locally as remote tracking branches to <name>/ hieararchy. The <name> is
the last component taken from the <URL> (maybe "origin" if it can't be
detected). 

Currently "git fetch <URL>" does not seem to do anything useful for
non-git-hackers. It seems to fetch objects but not create any branches
referring to them. As a comparison, let's configure a remote and run
similar fetch command without any refspecs explicitly named:

  $ git remote add <name> <URL>
  $ git fetch <name>

Now this fetch really creates all the branches (as defined in
remote.<name>.fetch) which is nice and the way Git currently works.

So would it be any good if "git fetch <URL>" without refpecs would use
+refs/heads/*:refs/remotes/<name>/* ? In any case the current behaviour
seems quite unfriendly.

Some more ideas for simple refspecs:

  $ git fetch <URL|name> <branch>

would be equivalent to

  $ git fetch <URL|name> +refs/heads/<branch>:refs/remotes/<name>/<branch>

Again the same behaviour with <URL> and configured remote <name>. In the
<URL> case the <name> is the last component of the <URL>.

  $ git fetch <URL|name> <Rbranch>:<Lbranch>

would be equivalent to

  $ git fetch <URL|name> +refs/heads/<Rbranch>:refs/remotes/<Lbranch>

Note that by giving the destination branch (the right side of colon) the
new remote tracking branch would be created directly to the
refs/remotes/ hierarchy, not to refs/remotes/<name>/ hierarchy like in
previous examples. This lets user a bit more ...
From: Jeff King
Date: Wednesday, April 9, 2008 - 1:34 pm

This has been discussed before and rejected, because the point of doing
a fetch of a URL (rather than a remote name) is to do a "one-off" thing.
IOW, you don't _want_ the tracking branches, as they will just clutter
your branch space (plus choosing the last component is a bad heuristic;
lots of people must ask Linus to pull from their .../linux-2.6
repository).

Almost nobody says "git fetch <URL>"; it is just a subpart of "git
pull <URL>" which is intended for one-off merges (i.e., you are not
tracking somebody over the long term, you just want to grab their work

It does; it puts the refs into FETCH_HEAD. Maybe a status table like the
usual one would be more informative, like:

  From git://host/path/to/repo
   * [new branch]      foo -> FETCH_HEAD

though again, it would help if we could see a workflow that uses "git
fetch <URL>" for something. I think the simplest answer in your case is

Sure. There is an explicit design decision that "because you gave this
thing a nickname, you are probably interested in keeping its tracking

It would probably be nice if "git fetch name foo" saved the remote
tracking branch remotes/name/foo, which it doesn't currently. But
whether to do it with a URL is orthogonal; it depends on whether we use

We almost have that. It's actually spelled:

  git fetch <URL|name> <Rbranch>:remotes/<Lbranch>

But again, what is the workflow? There are generally two ways of
fetching:

  1. I am tracking some remote with multiple branches. I give it a
     remote name (either by editing the config file or by using
     git-remote). When i want to get updates, I do "git fetch <name>",
     and then I can work with the <name>/* branches as I want (diffing,
     merging, etc).

  2. "Somehow" I found out about something interesting in a particular
     branch of a particular repo. I want to pull that in to see the
     work, so I use "git pull <repo> <branch>". Alternatively, if I
     prefer to fetch and examine before pulling (even though the ...
From: Teemu Likonen
Date: Wednesday, April 9, 2008 - 3:25 pm

First, thank you for such a detailed information and giving somewhat
different point of view from mine.

Ok, "git fetch <URL>" has its own "point", as you noted, and no doubt
it's for good reasons. I just had partially misunderstood its point. See

Hmm, maybe. I recently wanted to join two purely local repos together.
Both of them had just one branch. Totally different histories so no
actual mergin would happen; just two branches in the same repo. I don't
know why but "git fetch /the/other/repo/" just happened to be the one
I tried first. I saw it fetched something but as no new branch appeared
and I had never heard of this FETCH_HEAD thing it was a "didn't work,

would be really good. At least to me this would have been enough
information. As I'm starting to see the "point of doing fetch <URL>"
I take back what I proposed. Just a bit more information would be nice.

I have to agree with Ingo Molnar that sometimes Git is a bit un- or even
disinformative about what happened. One example is this "git fetch
<URL>". Maybe it's not a "sane thing to do" but users are like this. We
just try something and learn from it. To me "git fetch <URL>" was
a broken command (UI-wise) until I read your message (thanks again!). If
Git had told me that it created FETCH_HEAD I had learned fetch's habits
myself and likely wouldn't have come up with this "broken command"
conclusion.

Another thing I spoke of was this refs/ stuff. I know my way around with
them now, so maybe they are not actually confusing to me anymore. It's
just that I have noticed a pattern: I always use refs/heads/... in
certain places and refs/remotes/ in certain places. If such a pattern is
very common (well, I don't know if it is) one starts to think that maybe
the pattern can/should be hidden and made part of the tool. Just
thoughts.
--

From: Jeff King
Date: Wednesday, April 9, 2008 - 3:51 pm

Ah, OK. In that case, I think the right thing to do would not be to set
up a remote, but to fetch explicitly into a local branch. I assume when
you say "joining" you mean "so I can get rid of the individual ones".
So something like:

  cd repo1
  git fetch ../repo2 master:repo2-topic

which creates refs/heads/repo2 in repo1, and you can safely delete
repo2.

If you _did_ want to keep repo2 around indefinitely, and you are
"joining" so that you can do diffs, then you probably do want a remote
with tracking branches.

  cd repo1
  git remote add repo2 ../repo2
  git fetch repo2

I wonder if people like Linus who do a lot of one-off pulls would find

Sure. In my other message I talked about workflows not to imply "how
dare you explore the commands!" but rather to see where you were coming
from. I agree that a lot of git messages could be improved. So I think
the take-away lesson is not that there needs to be some huge change in
behavior or what input is accepted, but that git-fetch without tracking

I almost never use refs/remotes/ or refs/heads/. Some effort has been
put into doing the right thing with partial refnames (which you can of
course override by being more specific). Do you have specific examples
of where you use the full refname? I suspect it is either not required
(and documentation may be out of date), or it is a bug we could fix. :)

-Peff
--

From: Jeff King
Date: Wednesday, April 9, 2008 - 5:03 pm

As it turns out, there is already code to do this very thing, but:

  1. it was broken ;)

  2. you need to specify "-v"erbose mode to see it

Here is a patch that fixes the breakage, which should be done either
way. If people think this is a good thing to show in general (and I do,
but then I am not a very frequent user of "fetch without tracking
branches"), then there is an obvious one-liner to make it always show.

-- >8 --
git-fetch: fix status output when not storing tracking ref

There was code in update_local_ref for handling this case,
but it never actually got called. It assumed that storing in
FETCH_HEAD meant a blank peer_ref name, but we actually have
a NULL peer_ref in this case, so we never even made it to
the update_local_ref function.

On top of that, the display formatting was different from
all of the other cases, probably owing to the fact that
nobody had ever actually seen the output.

This patch harmonizes the output with the other cases and
moves the detection of this case into store_updated_refs,
where we can actually trigger it.

Signed-off-by: Jeff King <peff@peff.net>
---
 builtin-fetch.c |   28 +++++++++++++---------------
 1 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/builtin-fetch.c b/builtin-fetch.c
index 5841b3e..139a6b1 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -215,13 +215,6 @@ static int update_local_ref(struct ref *ref,
 	if (type < 0)
 		die("object %s not found", sha1_to_hex(ref->new_sha1));
 
-	if (!*ref->name) {
-		/* Not storing */
-		if (verbose)
-			sprintf(display, "* branch %s -> FETCH_HEAD", remote);
-		return 0;
-	}
-
 	if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
 		if (verbose)
 			sprintf(display, "= %-*s %-*s -> %s", SUMMARY_WIDTH,
@@ -365,16 +358,21 @@ static int store_updated_refs(const char *url, struct ref *ref_map)
 			rm->merge ? "" : "not-for-merge",
 			note);
 
-		if (ref) {
+		if (ref)
 			update_local_ref(ref, what, verbose, note);
-			if (*note) {
-				if ...
From: Jeff King
Date: Wednesday, April 9, 2008 - 5:11 pm

And here is that one-liner, in case there is interest. The only negative
I can think of is that git-pull will now produce two extra lines of
output mentioning FETCH_HEAD (which I actually think is a positive, but
I can see that people might consider it clutter).

-- >8 --
git-fetch: always show status of non-tracking-ref fetches

Previously, a fetch like:

  git fetch git://some/url

would show no ref status output (just the object downloading
status, if there was any), leading to some confusion.

With this patch, we now show the usual ref table, with
remote refs going into FETCH_HEAD. Previously this output
was shown only if "-v"erbose was specified.

Signed-off-by: Jeff King <peff@peff.net>
---
 builtin-fetch.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/builtin-fetch.c b/builtin-fetch.c
index 139a6b1..e4486e4 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -360,12 +360,10 @@ static int store_updated_refs(const char *url, struct ref *ref_map)
 
 		if (ref)
 			update_local_ref(ref, what, verbose, note);
-		else if (verbose)
+		else
 			sprintf(note, "* %-*s %-*s -> FETCH_HEAD",
 				SUMMARY_WIDTH, *kind ? kind : "branch",
 				 REFCOL_WIDTH, *what ? what : "HEAD");
-		else
-			*note = '\0';
 		if (*note) {
 			if (!shown_url) {
 				fprintf(stderr, "From %.*s\n",
-- 
1.5.5.26.g8c565.dirty

--

From: Junio C Hamano
Date: Thursday, April 10, 2008 - 12:51 am

Thanks for bringing this issue up and proposing a pair of improvements.

I am very inclined to apply [1/2] to maint.  I am not convinced if [2/2]
is a good idea in general but if it is silent on pull and verbose on
one-off fetch without local store, it probably is an improvement.



--

From: Jeff King
Date: Thursday, April 10, 2008 - 1:03 am

I think that is the right behavior for 2/2; I was just being a little
lazy earlier. I will try to work up an improved 2/2, but I will probably
be out of touch for a few days. Maybe we will see some comments from the
list in the meantime.

-Peff
--

From: Teemu Likonen
Date: Sunday, April 13, 2008 - 2:31 am

In real work I have used refs/heads/...:refs/remotes/... only once or
maybe twice (I just quite recently started using Git). But when
I studied Git and the workflows it supports I tried all kinds of
fetching, pulling and pushing, back and forth, between test repos. There
I used refs/ paths a lot, almost all the time actually. At first it was
very much just trying to see how they work and this is where I found
this common pattern: local refs start with refs/heads/ and remote
tracking ones with refs/remotes/ . Thoughts like "why not simplify them,
like L: for local and R: for remote" (or something) started to develop.

Now it seems that I have been too much attached to the full refspec
form. My guide have been the config remote.<name>.fetch as "git remote
add" adds those long refspecs. Now I learnt that almost all refspecs can
be written as "branch:another" or "branch:remotes/another" for example.
So the "friendly refspecs" are pretty much already there! Well, I've
been stupid. :)

(I understand that in real work when constantly dealing with same remote
repos one just adds a remote config and can forget about URLs and
probably most of the refspecs too.)

Ok, this was partly an RTFM error but even after reading man pages of
fetch, pull and push it isn't quite clear how to use these short and
nice and friendly refspecs. I thought about it and decided to add some
more examples to fetch manual (see my patch in the next message). My
English may not be manual-writing quality but I wanted to do something
useful anyway. Somebody needs to proof read my text though. Of course
there may be some inaccuracies too. Anyway, I think that concrete
examples in manuals help people to understand Git better.

There is still one thing (at least) that I don't quite understand. It's
about "git push". When I do

  $ git push <remote> <branch>

the refs/heads/<branch> is updated or created on the remote side. But if
I do

  $ git push <remote> <branch1>:<branch2>

the refs/heads/<branch2> is not ...
From: Teemu Likonen
Date: Sunday, April 13, 2008 - 2:34 am

This commit adds examples which intend to cover the various ways of
using 'git fetch'.

Signed-off-by: Teemu Likonen <tlikonen@iki.fi>
---
 Documentation/git-fetch.txt |   43 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index d982f96..d5b1c9f 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -37,9 +37,50 @@ include::pull-fetch-param.txt[]
 
 include::urls-remotes.txt[]
 
+EXAMPLES
+--------
+
+git fetch git://host.xz/repo.git/ master:pu::
+	Fetch branch `master` from given repository URL and store it locally
+	as `pu`.
+
+git fetch git://host.xz/repo.git/ master:remotes/pu::
+	Fetch branch `master` from given repository URL and store it locally as
+	remote tracking branch `pu`.
+
+git fetch git://host.xz/repo.git/ master::
+	Fetch branch `master` from given repository URL but do not create the
+	branch locally. Only the temporary pointer FETCH_HEAD is set to refer
+	to the fetched branch.
+
+git fetch /home/bob/tmp/repo.git::
+	Fetch the currently active branch from given local repository and set
+	the temporary pointer FETCH_HEAD for the fetched branch.
+
+git fetch alice master:remotes/alice/pu::
+	Fetch branch `master` from remote named `alice` and store it locally as
+	remote tracking branch `alice/pu`. See linkgit:git-remote[1] for more
+	information on configuring remotes.
+
+git fetch alice +master:remotes/alice/pu::
+	The same as above but the remote tracking branch `alice/pu` is updated
+	even if it does not result in a fast forward update.
+
+git fetch alice +master:pu maint:tmp::
+	Fetch branches `master` and `maint` from remote named `alice` and store
+	them locally as `pu` and `tmp` respectively. The branch `pu` is updated
+	even if it does not result in a fast forward update.
+
+git fetch origin::
+	From the remote named `origin` fetch and store all branches as
+	configured in ...
From: Junio C Hamano
Date: Sunday, April 13, 2008 - 11:56 am

While this may technically be correct (and I'll say upfront that all of
your "examples" may technically be correct), I would suggest strongly
against putting this into EXAMPLES section.  People look at examples
section to look up something they need to do often; the section should
describe the best practices we can suggest them in real life.

The above command line is a _great_ way to explain what happens under the
hood when you have the matching configuration in .git/config for the
remote, so that people would know how to update .git/config entries from
what git-clone and "git-remote add" give them by default to suit their
needs (e.g. instead of storing all branches in remotes/origin/*, you can
configure to only fetch and store a few selected branches).  But, fetching
from somewhere and storing it explicitly _from the command line_ like your
example command line is something you would _never_ do in real life if you

And this example is even worse, as the common example is to have remote

This one is a fine example of a one-shot command to look at what they
have without actually affecting your own history.  Use of this form in

This is a wrong example on multiple counts (this is one of the worst one
in your change, so I'll explain in more detail than for others).

First of all, think about the reason _why_ the convention is to use a
separate namespace under remotes/ per remote.  It is to allow us to use
the names that correspond to what the remote repository uses without
having to worry about name collisions, and the reason we took pains to
implement the mechanism to allow you to use such corresponding names is to
avoid having to remember "what she calls master is what I call pu".

"I want to make sure I can tell my master and her master apart without
confusing myself, so I'd call mine master and call hers alice/master" is
the recommended use pattern which "git clone" and "git remote add" give
the user.  An EXAMPLE that deviates from it without explaining why/when it
is a ...
From: Matt Graham
Date: Sunday, April 13, 2008 - 12:48 pm

As a recent CVS emigrant, I'm finding the refspecs one of the more
confusing areas of git.  I think having good, basic examples might be
more helpful than experienced users expect.  In my case at least, this
is a helpful example.
--

From: Teemu Likonen
Date: Sunday, April 13, 2008 - 1:05 pm

Thanks for your explanations, they made a lot of sense. I see, I gave
examples of various ways of using "git fetch" but they may not reflect
real life usage patterns very well. I still feel that refspecs need more
explaining (for newbies, that is) so I may later bring another patch
hopefully with better examples and applicable to real workflows.
--

From: Junio C Hamano
Date: Sunday, April 13, 2008 - 6:02 pm

Perhaps.  The basic syntax is "src colon dst" and they are used to copy
what's in src to dst, and that is pretty much what's there to it.  Some
details such as how the wildcard matching works may be missing from the
description part of the manual, and filling them in would be a good idea.

I however strongly suspect that what new people need to get explained may
not be what the mechanism does (e.g. copies the object name recorded as
the src ref to the dst ref), nor the syntax you use to tell the mechanism
what to copy where (e.g. src is LHS, dst is RHS, copying "emptyness" into
dst means deleting dst).  I actually think that is an easier part.

What is more important is the basic concepts like what a ref is, how they
can be used and what you can do with them --- understanding of which would
be essential in being able to decide when and how you maywant to keep a
copy of ref you get from elsewhere and under what name.  I think tutorial
is the best place, and then the description section of the manual the
second best one, to document that kind of things.
--

From: Jeff King
Date: Tuesday, April 15, 2008 - 8:48 pm

This happens because "git push <remote> <branch>" is expanded locally to
"git push <remote> <branch>:<branch>", but <branch> is first expanded
into refs/heads/<branch>.

The latter uses the explicit refspec <branch2> which doesn't get
expanded, since it doesn't exist at all, and so we can't deduce the type
(e.g., refs/heads versus refs/tags).

ISTR some discussion in the past few months about using the type of
<branch1> to guess the type of <branch2>, but it seems not to have gone
anywhere.

Daniel, were you working on this?

-Peff
--

From: Jeff King
Date: Tuesday, April 15, 2008 - 9:25 pm

Hmm. Here is a quick patch I worked up, but it causes t5516:14 (push
with ambiguity) to fail. However, I'm not sure the test is right: it
looks like it's trying to find ambiguity between remotes/origin/master
and remotes/frotz/master, but in fact matches _neither_ of them. So it
was failing before as we expected, but for the wrong reason.

---
 remote.c              |   23 +++++++++++++++++++----
 t/t5516-fetch-push.sh |    8 ++++++++
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/remote.c b/remote.c
index 08af7f9..2f5d062 100644
--- a/remote.c
+++ b/remote.c
@@ -851,10 +851,25 @@ static int match_explicit(struct ref *src, struct ref *dst,
 	case 0:
 		if (!memcmp(dst_value, "refs/", 5))
 			matched_dst = make_linked_ref(dst_value, dst_tail);
-		else
-			error("dst refspec %s does not match any "
-			      "existing ref on the remote and does "
-			      "not start with refs/.", dst_value);
+		else {
+			/*
+			 * We don't have a full ref name for the dst and
+			 * it doesn't exist, so let's assume it's the same
+			 * type as our src.
+			 */
+			struct strbuf tmp = STRBUF_INIT;
+			const char *c;
+			int slashes;
+			for (c = matched_src->name, slashes = 0;
+					*c && slashes < 2; c++) {
+				strbuf_addch(&tmp, *c);
+				if (*c == '/')
+					slashes++;
+			}
+			strbuf_addstr(&tmp, dst_value);
+			dst_value = strbuf_detach(&tmp, NULL);
+			matched_dst = make_linked_ref(dst_value, dst_tail);
+		}
 		break;
 	default:
 		matched_dst = NULL;
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 793ffc6..370f79a 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -285,6 +285,14 @@ test_expect_success 'push with colon-less refspec (4)' '
 
 '
 
+test_expect_success 'push with non-existant, incomplete dest' '
+
+	mk_test &&
+	git push testrepo master:brandnewbranch &&
+	check_push_result $the_commit heads/brandnewbranch
+
+'
+
 test_expect_success 'push with HEAD' '
 
 	mk_test heads/master &&
-- ...
From: Junio C Hamano
Date: Tuesday, April 15, 2008 - 9:41 pm

Eh, there is no way unless you force an assumption of a particular
workflow to everybody else.

What you would say on the second command is not literally "<branch2>" but
something like "work-in-progress", or "crap".  Even an AI would not be
able to guess if you wanted to create a branch on the other side, or
wanted to put a lightweight tag to let people know where you are (possibly
with the intention of removing it once you are done), and git is not an AI.

--

From: Jeff King
Date: Tuesday, April 15, 2008 - 9:47 pm

Of course it can't guess all cases. But right now you have the option
of:

  1. specifying the full destination manually
  2. having git complain, and then doing (1)

I think changing (2) to "having git make a reasonable guess" is a better
behavior. And I think it is a reasonable guess to use the _same_ type,
just as we do with "git push <branch>".

-Peff
--

From: Daniel Barkalow
Date: Wednesday, April 16, 2008 - 8:42 am

I was only working on making "HEAD" expand to HEAD:<current branch>. I 
think that the matching type is only most likely what you want, not 
certainly enough to just do it. I'd say that push should suggest it, but 
not actually do it automatically, or possibly require -f to do it without 
the full name.

	-Daniel
*This .sig left intentionally blank*
--

From: Avery Pennarun
Date: Wednesday, April 9, 2008 - 1:32 pm

But what should <name> be if you didn't provide it by doing
git-remote-add?  I think the lack of an obvious name for them is
exactly why the branch names don't get created automatically.

Avery
--

From: Junio C Hamano
Date: Wednesday, April 9, 2008 - 2:21 pm

Teemu Likonen <tlikonen@iki.fi> writes:

[By the way, please never redirect the response to your messages away from
you with:

    Mail-Followup-To: Jeff King <peff@peff.net>, Ingo Molnar <mingo@elte.hu>,
            git@vger.kernel.org

You wasted 30 seconds of my (and anybody who potentially wanted to give
advice to you) time by forcing me fix the To: header while composing this
response.  I know Jeff understands what I am going to mention, and I do

I'd suggest you to study:

  http://thread.gmane.org/gmane.comp.version-control.git/31351/focus=31634

Not everybody wants remote tracking.
--

From: Teemu Likonen
Date: Thursday, April 10, 2008 - 12:38 am

Sorry, didn't even know such header existed. After consulting Mutt's
manual and some googling I think I understand it now. I'm a subscriber
to git list (and my Mutt knows that) and Mail-Followup-To told
everyone's MUAs to not include me in recipient list since I get
everything through the list. But this is configurable and generating

Thanks, and I agree. Me neither always want remote tracking. Git's
current behaviour to only create/update FETCH_HEAD seems actually better
- now that I know what it does. I think it's a good idea to show "[new
branch] foo -> FETCH_HEAD" after fetching.
--

From: Avery Pennarun
Date: Wednesday, April 9, 2008 - 10:08 am

My co-workers frequently get confused by this too.  The problem is
that "x86/latest" is a locally existing remote branch ref, while "x86
latest" is supposed to be a branch ref on a remote system.

I think the real problem here is that you can't refer to a
remote+branch as a single "word".  If you could, then people could
just learn to use that everywhere and never get confused.

For example, in svn you can talk about
svn+ssh://reposerver/path/to/repo/branches/foo@1234; it's a single
"word" that refers to a particular revision on a particular branch of
a particular server.  It therefore makes sense to talk about copying
from one branch to another, etc, using exactly one word for the source
and one for the destination.

Imagine if "git pull ~/linux/2.6-x86.git:latest" would work; then it
could mean exactly the same thing as "git merge
~/linux/2.6-x86.git:latest" (which would presumably switch to 'pull'
mode automatically).  Or even "git diff master..x86:latest", which
could diff my local master with an auto-fetched x86:latest.

Naturally we'd have to find a new punctuation mark for this, since all
the obvious ones are already used :)

Have fun,

Avery
--

From: Karl
Date: Thursday, April 10, 2008 - 1:41 am

Heh, not really. Subversion actually makes this even more confusing
than git does.

The @rev is called a "peg revision", and is different from the
"operative revision" specified with the -r flag. The peg revision is
used in conjunction with a path to specify the file (or directory) you
want, and the operative revision is used to specify which revision of
that file you mean. (This complexity is needed because subversion has
a concept of file identity.)

So

  $ svn cp -r 4711 $REPO/foo@1234 somewhere-else

means "find the file (or directory) that was called 'foo' in revision
1234, then copy revision 4711 of that file to somewhere-else".

See http://svnbook.red-bean.com/en/1.4/svn.advanced.pegrevs.html for
the full story.

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle
--

From: Avery Pennarun
Date: Thursday, April 10, 2008 - 8:05 am

Yes, but I believe you get the one from @rev if you don't specify -r.

For example, I can ask for an "svn diff svn://blahblah@56
svn://blahblah@59" and it'll feed it to me as expected.

This is nearly the same as "svn diff -r56:59 svn://blahblah", except
that it might look for blahblah in different places, as you say.  I

File renames make diffing and merging complicated no matter whether
you track them or not.

svn's tracking of file identity is additional, but doesn't increase
the (UI) complexity in the common case.  At least with svn, a newbie
can even get real work done without even knowing about -r *or*
@notation.

Compare that to arbitrary differences in behaviour between "git-fetch"
vs "git-fetch a" vs "git-fetch a b", or the difference between HEAD^
and HEAD~1 and HEAD@1.  git is very powerful, but also definitely more
complex for beginners.

Have fun,

Avery
--

From: Karl
Date: Friday, April 11, 2008 - 12:00 am

Clearly, I need to use Subversion more, and not fool around with git

I don't quite agree with you here. Subversion stores extra state, and
that state needs to be considered (in the general case) when
predicting what Subversion will do. There are a large number of simple
cases where the user doesn't have to care, as you say, but every so
often there's a case that's not so simple, and in those cases I

Oh, I'm not arguing on that point. I like git because it's beutiful on
the _inside_.

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle
--

From: Ingo Molnar
Date: Thursday, April 10, 2008 - 4:47 am

Ok, just in case i dont bore people with "stupid user" experiences and 
logs of sessions of confusion, here's another session i just had with 
Git.

This time it's with our good friend git-bisect - which i thought to 
master pretty well and which i already used successfully to bisect 
kernel bugs up to a hundred times already (at least).

The 'v' repository is a vanilla clone of Linus's upstream linux-2.6.git 
kernel tree with no other modifications done to it.
 
 dione:~> git-clone v linux-tmp4
 Initialized empty Git repository in /home/mingo/linux-tmp4/.git/
 0 blocks
 Checking out files: 100% (23809/23809), done.
 dione:~> cd linux-tmp4/
 dione:~/linux-tmp4> ls
 COPYING        MAINTAINERS     arch     fs       kernel  samples   usr
 CREDITS        Makefile        block    include  lib     scripts   virt
 Documentation  README          crypto   init     mm      security
 Kbuild         REPORTING-BUGS  drivers  ipc      net     sound

 #
 # ok, so far so good. done this a thousand times before.
 #
 # Now lets check out v2.6.24 and check whether the bug i'm interested 
 # in triggers on v2.6.24. I dont create an extra branch for it, because 
 # this is pure temporary work, i use a plain git-checkout as a 
 # throwaway temporary branch:
 #

 dione:~/linux-tmp4> git-checkout v2.6.24
 Note: moving to "v2.6.24" which isn't a local branch
 If you want to create a new branch from this checkout, you may do so
 (now or later) by using -b with the checkout command again. Example:
   git checkout -b <new_branch_name>
 HEAD is now at 4991408... Linux 2.6.24

 #
 # i build that kernel and boot it - the bug doesnt trigger - good. 
 # We've got all prerequisites for a bisection session - a 'good' kernel 
 # [v2.6.24] and a 'bad' kernel [HEAD].
 #
 #

 dione:~/linux-tmp4> git-bisect start
 fatal: ref HEAD is not a symbolic ref
 won't bisect on seeked tree

 #
 # Hm. It's not a symbolic ref, and git-bisect just wont do it. Ok but 
 # then what, and what can the user do to ...
From: Christian Couder
Date: Thursday, April 10, 2008 - 10:41 pm

Yeah, it seems that this is a left over from cogito. 
There has been some work on it lately but it seems not enough. See:


This seems to work for me with git 1.5.5 on the git tree:

$ git checkout master
Switched to branch "master"
Your branch is ahead of the tracked remote branch 'origin/master' by 4 
commits.
$ git bisect start
$              




This is really bad, because, as you can see from the man page or "git 
bisect -h" (see also the patch I just sent), "git bisect good" can take 
many known good revisions: 

git bisect good [<rev>...]
        mark <rev>... known-good revisions.

So you marked also "bad" and HEAD as "good".

This is really strange, because here I get for example:

$ git-bisect good bad HEAD
Bad rev input: bad HEAD

So you must have something tagged as "bad" or have a "bad" branch, and 
that's why the command works for you but does the wrong thing.

If you wanted to do it all in one command you could have done:

$ git bisect start HEAD v2.6.24

That would have marked HEAD as "bad" and v2.6.24 as "good":

git bisect start [<bad> [<good>...]] [--] [<pathspec>...]

Right, we probably need to have at look at this more closely, maybe warn if 

This marked "good" as "bad" and "v2.6.24" as "good".

Again this should "work" only if you have a "good" tag or branch in your 


This marked "v2.6.24" as "bad", and "good", "master" and "bad" as "good".

That's much better but you didn't "reset" or "start" again before giving it 
correctly the good and bad revs, so there are still some wrong left over 


I cannot comment on "git fsck" but I think it has nothing to do with 


"git bisect start" also does a "restart" if a bisect is already started.
But yes, we could add "stop" as a synonym for "reset" and "restart" as a 
synonym for "start".

Thanks,


--

From: Ingo Molnar
Date: Friday, April 11, 2008 - 4:41 am

git-core-1.5.4.3-2.fc8, like for the previous report.

and it worked for me too in a later tree - so the condition seems 

no, there are no 'bad' braches or revisions.

and ... if "git-bisect good X bad Y" is invalid syntax it should be 
detected by the tool ... I did not think up that syntax myself, i think 
i saw it somewhere else mentioned by someone and found it logical. 

it probably didnt - i was just grasping at straws because there was no 
reassuring feedback about what happened so my confidence about my 
_assumptions_ what was happening in the background gradually eroded so i 
went in larger and larger circles around the problem dropping more and 
more assumptions and re-checking them.

But i pasted this directly from that session so the "-1" is definitely 
not imaginery and it is anomalous.

	Ingo
--

From: Christian Couder
Date: Friday, April 11, 2008 - 11:56 pm

Yes, it probably depends on what you have done before.
I didn't look at it yet, but I will have a look soon.
Anyway as Junio said, there have been some improvements in 1.5.5 so it might 

You are right, we have got some bugs here I think.

In my case bad and HEAD were neither proper revs, that's why I got an error.
But I realized that as long as there is one proper rev in what you give 
to "git bisect good" it will ignore bad revs and mark as good the proper 
rev you gave it.

I just sent a patch to fix this, but I am not sure it's the right fix.
More work is probably needed. Ooops I just spotted one bug in my patch.

Yes.

Thanks again,
Christian.

--

From: Junio C Hamano
Date: Thursday, April 10, 2008 - 10:56 pm

Enough people were unhappy with this historical wart and we stopped
refusing to "bisect on seeked tree" since b577bb9 (Eliminate confusing
"won't bisect on seeked tree" failure, 2008-02-23); you should find it as
part of the 1.5.5 release.

The disturbing "fatal: ref HEAD not a symref" is still there even though
it should be harmless.  The message should be squelched.
--

From: Luciano Rocha
Date: Friday, April 11, 2008 - 3:15 am

Another inconsistency:
$ git remote prune
usage: git remote
   or: git remote add <name> <url>
   or: git remote rm <name>
   or: git remote show <name>
   or: git remote prune <name>
   or: git remote update [group]

show specific options
    -n, --dry-run         dry run

It took me a while to parse the "show specific options" properly.

Wouldn't "specific options for show" be better?

--=20
Luciano Rocha <luciano@eurotux.com>
Eurotux Inform=E1tica, S.A. <http://www.eurotux.com/>
From: Wincent Colaiuta
Date: Friday, April 11, 2008 - 3:27 am

Yes, or failing that: "show-specific options:"

Without the hyphen "show specific options" reads as "verb adjective  
noun".

Cheers,
Wincent

--

From: Junio C Hamano
Date: Wednesday, April 9, 2008 - 2:04 pm

Thanks.  It is always enlightening to see this kind of walkthru session to
learn where the UI warts are.  The ones with concrete suggestions for

You told git that "I'll interact with this other repository from now on,
so please help me with some extra settings to do so.  Namely I do not want
to keep typing it in full URL all the time so I want an abbreviated way to
tell you I am talking about this remote repository, and also I want to
have set of remote tracking branches for this one".

Maybe "remote add" is not quite the right name to convey the above


You told git "I want to merge a commit into the current branch, and that
commit is called x86/latest".  Alas, no such commit exists in your
repository (yet).  Should we be saying "no such commit exists, you need to

"Not a git archive" should be clear enough.  You already said "remote show
x86" correctly above, and it makes me wonder why you are now saying
"x86/latest", not "x86" without "latest".

In other words, "git fetch x86".

With that, you would tell git "Hey, I've already told you what I want you
to do with this short-hand name "x86". It is the name for the long URL
I've previously given you and I want you to fetch from that repository,
and I want its branches to be stored in remote tracking branches in my
repository".

But you didn't.  You are not taking advantage of your previous "git remote
add".

I am suspecting that a cause of this confusion is partly because earlier
in 1.3.0 days we tried to make things easy for CVS migrants where they
always interact with a single "upstream" repository and with _the_ single
branch, and we were _too_ successful in doing so.

That made us allowing the users to type "git pull" and "git fetch" without
parameters.  This is generally a good thing: shorter to type for doing
common things is always good, as long as the user knows what he is doing.

But at the same time, this allowed docs and cheat-sheets that mention only
the form without parameters and not the normative ...
From: Jeff King
Date: Wednesday, April 9, 2008 - 2:45 pm

For me personally, I think this bottom-up approach makes the most sense
to learning (this may look familiar from the commit message to a patch I
sent earlier):

  1. here is what "git pull $repo $branch" means
  2. here is a way to shorten it to "git pull $repo" (set up remote
     $repo)
  3. here is a way to shorten it to "git pull" (default to origin)

But I think there are people who will get to the list and say "why
didn't you just tell me 'git pull' in the first place?" That is, the
complaints we have seen in the past reveal _too many_ low level details
too quickly.

Maybe we have stepped too far towards "top down workflow
descriptions" and need to go back. I dunno.

Another way of thinking about it is that we need two sets of
documentation with the same information (heresy, I know!): one bottom-up
and one top-down. I think the manpages tend to be "bottom up"
references. Bruce's user manual is more "top down" describing workflows.
I wonder which one(s) Ingo read, and which helped the most.

-Peff
--

From: Jon Loeliger
Date: Wednesday, April 9, 2008 - 2:39 pm

Hey Junio,

I'm hearing you here! :-)

I think a furtherance of this notion is to
teach "git fetch ; git merge" before "git pull".

Thanks,
jdl
--

From: Nicolas Pitre
Date: Wednesday, April 9, 2008 - 4:45 pm

Amen!


Nicolas
--

From: Jean-Christian de Rivaz
Date: Wednesday, April 9, 2008 - 11:08 pm

A possible way it to, by default, make git print the full form of the 
command when a short form is used. So the user see the concept without 
having to read the documentation and learn it gradually. I personally 
like tools that act this way. It permit to make a basic and easy 
tutorial with short commands that let know the general concept and show 
the full potential of the tool.

A "short form" flag in a user (not repository) configuration file should 
allow to suppress the long form printout for the comfort of the users 
that don't want it.

--
Jean-Christian de Rivaz
--

From: Sverre Rabbelier
Date: Thursday, April 10, 2008 - 1:19 am

I think this would be a very nice solution, not only do you allow the
user to realize what it is they are doing, you also provide them with
an easy way to be more verbose. Perhaps they wish to switch from the
default short behavior to a somewhat different form (e.g., change a
default 'master' argument to another branch). When writing out the
full form each time the user gets an intuitive and gradual
introduction into the rest of git, without limiting them or more

Or perhaps, as I mentioned in the thread on "friendly refspecs", a
"newbie" config option or command that turns on the informative
verboseness options. As such, perhaps a "long form" flag would be more
desired instead, to prevent existing developers from being spammed
with information they do not are interested in.

Cheers,

Sverre Rabbelier
--

From: André Goddard Rosa
Date: Wednesday, April 9, 2008 - 4:56 pm

Something along the lines of:

Error description
Why it happened
How to solve/Sugestion

-- 
[]s,
André Goddard
--

From: Govind Salinas
Date: Thursday, April 10, 2008 - 12:45 pm

On Wed, Apr 9, 2008 at 6:56 PM, André Goddard Rosa

Hi,

This actually touches on one of my main purposes  behind Pyrite.  I intend to
do the following things to help the situation and I was wondering what the
git community's reaction is.

1) Since it will be designed for end users I intend to remove the options not
designed for end users.  This will also shorten up the help so that the entire
help can be shown to the user when they encounter an error.

2) No unnamed options.  I think this would have helped the above case
although it would have required a *bit* more typing.  The command would
have looked like "pyt pull/fetch -r x86 -b latest"  Combined with the above
the command would have spit out the help and a message stating what was
missing.

3) No syntax.  Git has a lot of syntax.  It has refspecs, revision ranges,
symbolic names (although i do like these) that a user has to learn.  I
think this
is one of the most error prone parts of the git for new users.
Hopefully, I will
be able to find simple and straightforward ways for the user to supply
this info.

Any comments/suggestions will be appreciated.

Thanks,
Govind.
--

From: Daniel Barkalow
Date: Wednesday, April 9, 2008 - 12:21 pm

Git is missing the fact that, while refs/remotes/x86/latest doesn't exist, 
there is a fetch rule that would create it. It should suggest "git fetch 
x86" or "git fetch x86 latest". This is a bit tricky, because you've used 
a shorthand for something that doesn't exist, so there isn't a unique 
answer for which full name you're looking for, but there is a unique 
solution (in this case) for which one could be created by a pattern you 

The right error message here would probably be:

/home/mingo/linux-2.6-sched-devel.git/x86/latest: No such file or directory

That should at least tell you what git thinks, incorrectly, that you want 

I'm not sure we can figure out what the user actually meant in this case; 
there's just too much overlap in namespaces to determine reliably that you 
were giving it a remote repository on the local filesystem rather than 
anything else.

	-Daniel
*This .sig left intentionally blank*
--

From: Ingo Molnar
Date: Wednesday, April 9, 2008 - 1:41 pm

well, current git got to /home/mingo/linux-2.6-x86.git/ which is a local 
path. (it is printing it in the error message above) So i think it was 
rather unambiguous what i meant and Git knew about it, right?

but even if it _was_ ambiguous, i think tools should generally default 
to a minimal amount of hassle for new users and should try to pick 
reasonable "action" versus any "inaction". (as long as the behavior is 
still deterministic and reasonable even to the long-time user)

but more importantly, i think this whole problem area has to be handled 
with a slightly different kind of mindset than other, more technical 
aspects of Git.

Humans, and in particular males, when they see or learn new things, are 
very emotion-driven. The first 1-2 minutes (often just the first few 
seconds) have a very strong influence on whether that person 'likes' a 
new topic, tool or gizmo he is checking out - or not. Males often think 
of themselves as being objective when shopping new items - while in 
reality more than 90% of their purchasing decisions are emotion-driven 
and it's all set and done in the first 10 seconds of visual contact. 
(this ration is far higher than for females)

Command-line tools like Git are at heavy natural disadvantage compared 
to say GUI tools because the "first impression" is so minimalistic and 
relatively unremarkable. A GUI can get people hooked by making the first 
10% look easy just via old-fashioned, dishonest visual deception.

so basically for 90% of the new users, we've got 2-3 shots or we lose 
their "sympathy". Starting with an error message is bad. Being 
uninformative about what happened is bad. Making the user wait without 
signalling why he is waiting is bad. Etc. etc. I think this experience 
of mine was a reasonable simulation of a first-time user reaction (by 
virtue of me having forgotten certain Git details).

And the moment a negative first-time impression has settled in it's very 
hard to overcome that emotional mindset and barrier. ...
From: Daniel Barkalow
Date: Thursday, April 10, 2008 - 7:08 am

Actually, your shell did that. I don't think git can tell that the user 
typed something different and the shell converted it because it's a local 

It's hard to evaluate proposals for extending cases from inaction to some 
action because in trying to keep it deterministic, you have to decide 
whether future, possibly more compelling, extensions might want to overlap 
the space of commands. It's more conservative to have the command suggest 
some things the user might have meant, even if that's sometimes a list of 
one, so that the user doesn't come to rely on behavior that is only 

I think that it's far enough along before a user types "git merge ..." 
that we've got a chance to give a suggestive error message instead of just 
doing something, particularly if the thing we might do might be wrong and 
either annoying to clean up or slow. (OTOH, "git clone ..." had better 
work, and I think it does)

And I agree strongly with the need for the error messages in the cases 

On the other hand, there's a conflict between having git do what the user 
seems to want it to do and having git's commands delineated by concepts 
that users need to know, such that users will be assisted in learning 
those concepts (and therefore have an easier time getting the results they 
expect from git consistantly). For example, "merge" works on information 
you have within the repository, and "fetch" brings information into the 
repository. In some cases, we could guess that the user has typed "merge" 
but wants to bring information into the repository, but we won't always be 

I think the market segment that most git developers would really like to 
get is the projects that they work on aside from git. There's a 
substantial itch to make git sufficiently compelling that nobody would 
make them use CVS/SVN/Perforce/ClearCase/etc. This has a significant 
usability-to-new-users component, and so there's more attention to that 
than in projects where use of the project doesn't require getting ...
Previous thread: [PATCH] (parsecvs) avoid "git mktag" failure with newer git by Jim Meyering on Wednesday, April 9, 2008 - 3:01 am. (1 message)

Next thread: [PATCH] Re: git clean removes directories when not asked to by Joachim B Haga on Wednesday, April 9, 2008 - 10:04 am. (12 messages)