Junio C Hamano [off-list ref] writes:
But that is not what is happening at all. What goes on is far
simpler than that.
- the shell sees '*', matches it against working tree files, to
obtain "f1" and "f2";
- the shell tells "git" to "checkout e6f935e -- f1 f2";
- "git" looks into the tree of e6f935e to find paths that match
"f1" and "f2".
When "git" is run by the shell in the last step, it has _no_ clue
that the end user typed "*" from the shell. It only sees "f1" and
"f2" on the command line. There is no "set T" to be intersected
with "set W", so stop thinking in those terms, and you will be fine.
Now the question is, _you_ will be fine, but can the documentation
be updated in such a way so that it will help _others_ to also stop
thinking about "intersection between set W and set T"? I do not
have a good answer to that.
Let's do this. I do not want a shell tutorial in "git checkout"
documentation, but this would fit better in the documentation for
the CLI convention.
-- >8 --
gitcli: contrast wildcard given to shell and to git
People who are not used to working with shell may intellectually
understand how the command line argument is massaged by the shell
but still have a hard time visualizing the difference between
letting the shell expand fileglobs and having Git see the fileglob
to use as a pathspec.
Signed-off-by: Junio C Hamano <redacted>
---
Documentation/gitcli.txt | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git c/Documentation/gitcli.txt w/Documentation/gitcli.txt
index ea17f7a..220621b 100644
--- c/Documentation/gitcli.txt
+++ w/Documentation/gitcli.txt
@@ -38,6 +38,22 @@ arguments. Here are the rules:
you have to say either `git diff HEAD --` or `git diff -- HEAD` to
disambiguate.
+ * Many commands allow wildcards in paths, but you need to protect
+them from getting globbed by the shell. These two mean different things:
++
+--------------------------------
+$ git checkout -- *.c
+$ git checkout -- \*.c
+--------------------------------
++
+The former lets your shell expand the fileglob, and you are asking
+the dot-C files in your working tree to be overwritten with the version
+in the index. The latter passes the `*.c` to Git, and you are asking
+the paths in the index that match the pattern to be checked out to your
+working tree. After running `git add hello.c; rm hello.c`, you will _not_
+see `hello.c` in your working tree with the former, but with the latter
+you will.
+
When writing a script that is expected to handle random user-input, it is
a good practice to make it explicit which arguments are which by placing
disambiguating `--` at appropriate places.
From: "Junio C Hamano" <redacted>
Sent: Friday, September 07, 2012 9:49 PM
Junio C Hamano [off-list ref] writes:
quoted
But that is not what is happening at all. What goes on is far
simpler than that.
- the shell sees '*', matches it against working tree files, to
obtain "f1" and "f2";
- the shell tells "git" to "checkout e6f935e -- f1 f2";
- "git" looks into the tree of e6f935e to find paths that match
"f1" and "f2".
When "git" is run by the shell in the last step, it has _no_ clue
that the end user typed "*" from the shell. It only sees "f1" and
"f2" on the command line. There is no "set T" to be intersected
with "set W", so stop thinking in those terms, and you will be fine.
Now the question is, _you_ will be fine, but can the documentation
be updated in such a way so that it will help _others_ to also stop
thinking about "intersection between set W and set T"? I do not
have a good answer to that.
Let's do this. I do not want a shell tutorial in "git checkout"
documentation, but this would fit better in the documentation for
the CLI convention.
The difficulty with putting it in gitcli is that it is referenced from
almost nowhere, so won't provide help to the user.
Having said that, it would therefore be better to point folk at gitcli
in a few more places, not just the 'see also' line at the very end of
the general 'git' page, and buried within rev-parse.
quoted hunk
-- >8 --
gitcli: contrast wildcard given to shell and to git
People who are not used to working with shell may intellectually
understand how the command line argument is massaged by the shell
but still have a hard time visualizing the difference between
letting the shell expand fileglobs and having Git see the fileglob
to use as a pathspec.
Signed-off-by: Junio C Hamano <redacted>
---
Documentation/gitcli.txt | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git c/Documentation/gitcli.txt w/Documentation/gitcli.txt
index ea17f7a..220621b 100644
--- c/Documentation/gitcli.txt
+++ w/Documentation/gitcli.txt
@@ -38,6 +38,22 @@ arguments. Here are the rules:
you have to say either `git diff HEAD --` or `git diff -- HEAD` to
disambiguate.
+ * Many commands allow wildcards in paths, but you need to protect
+them from getting globbed by the shell. These two mean different
things:
++
+--------------------------------
+$ git checkout -- *.c
+$ git checkout -- \*.c
+--------------------------------
++
+The former lets your shell expand the fileglob, and you are asking
+the dot-C files in your working tree to be overwritten with the
version
+in the index. The latter passes the `*.c` to Git, and you are asking
+the paths in the index that match the pattern to be checked out to
your
+working tree. After running `git add hello.c; rm hello.c`, you will
_not_
+see `hello.c` in your working tree with the former, but with the
latter
+you will.
+
When writing a script that is expected to handle random user-input, it
is
a good practice to make it explicit which arguments are which by
placing
disambiguating `--` at appropriate places.
On Fri, Sep 07, 2012 at 01:49:15PM -0700, Junio C Hamano wrote:
-- >8 --
gitcli: contrast wildcard given to shell and to git
People who are not used to working with shell may intellectually
understand how the command line argument is massaged by the shell
but still have a hard time visualizing the difference between
letting the shell expand fileglobs and having Git see the fileglob
to use as a pathspec.
I think this is an improvement, but...
quoted hunk
diff --git c/Documentation/gitcli.txt w/Documentation/gitcli.txt
index ea17f7a..220621b 100644
--- c/Documentation/gitcli.txt
+++ w/Documentation/gitcli.txt
@@ -38,6 +38,22 @@ arguments. Here are the rules:
you have to say either `git diff HEAD --` or `git diff -- HEAD` to
disambiguate.
+ * Many commands allow wildcards in paths, but you need to protect
+them from getting globbed by the shell. These two mean different things:
++
+--------------------------------
+$ git checkout -- *.c
+$ git checkout -- \*.c
+--------------------------------
++
+The former lets your shell expand the fileglob, and you are asking
+the dot-C files in your working tree to be overwritten with the version
+in the index. The latter passes the `*.c` to Git, and you are asking
+the paths in the index that match the pattern to be checked out to your
+working tree. After running `git add hello.c; rm hello.c`, you will _not_
+see `hello.c` in your working tree with the former, but with the latter
+you will.
+
When writing a script that is expected to handle random user-input, it is
a good practice to make it explicit which arguments are which by placing
disambiguating `--` at appropriate places.
Look at the paragraph below your addition. It is typographically outside
of the bulleted list you are adding to, but it really makes sense
directly after the prior two bullet points, which are explicitly about
disambiguation between revisions and paths. Your addition splits them
apart.
Does it make sense to join that final paragraph into what is now the
third bullet, and then add your new text (the fourth bullet) after?
-Peff