5

In git, it is possible to handle a remote name with - character star.

For example, we can add a remote which begins with -, update it by just using the option -- in the git command (-- separate between command option and the remote name).

But it doesn't work on :

git pull -- "-myremotename" "master"

And, I get this error message :

error: unknown switch `y'
usage: git fetch [<options>] [<repository> [<refspec>...]]

I think that -- option doesn't work in git pull, because pull is a combination of git fetch followed by git merge, and -- isn't used when making this 2 commands.

Any idea to fix it ?

yacine
  • 151
  • 1
  • 4
  • In your `git pull` line you're using triple-dashes (`---`) instead of double-dashes (`--`). Is that only a typo in the post, or did you really make that typo on the command line? – sschuberth Jan 04 '17 at 13:34
  • @sschuberth I'm using double-dashes (`--`), and I get also an error. – yacine Jan 04 '17 at 13:41
  • I think your guess is correct. Try fetch and merge manually. If it worked then your guess is probably probably on point – Dima Ogurtsov Jan 04 '17 at 13:49
  • This would have been easier to fix when `git pull` was still just a shell script. (Though I note you don't mention your Git version.) I'd advise avoiding remote names starting with `-`, in general, though. – torek Jan 04 '17 at 22:53
  • @torek I'm using `v2.8.0` of git on Mac. – yacine Jan 05 '17 at 10:14
  • @yacine: Just FYI, anything 2.6.0 or later has it rewritten in C. – torek Jan 05 '17 at 11:31
  • @torek perhaps I should create an issue on the github repository of git. – yacine Jan 05 '17 at 13:16
  • The GitHub Git repo is a read-only entity, I'm not sure anyone pays any attention to items filed there. I also doubt you'll get a lot of sympathy :-) as it's really easy just to avoid remotes named `-whatever`. – torek Jan 05 '17 at 18:36
  • If you want to report this as a bug or just discuss it with the Git developers and Git community, it looks like [their mailing list and their IRC channel would be the right place](https://git-scm.com/community) for that. – das-g May 20 '17 at 10:40

1 Answers1

1

Any idea to fix it ?

Prefix the remote name with the word safe

$ git remote rename {,safe}-myremotename

You can then use it again

$ git pull safe-myremotename 
Successfully rebased and updated refs/heads/develop

As remote names land in the file-system and also are prone to injection as your question shows, please consider the following:

  • Use only characters from the 3.282 Portable Filename Character Set

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    a b c d e f g h i j k l m n o p q r s t u v w x y z
    0 1 2 3 4 5 6 7 8 9 . _ -
    
  • Do not use the dash - as first character. (ref)

  • Do not use any of the digits 0-9 and letters a-f/A-F within the remote name only (if the name is longer than three characters). Otherwise a remote name may become refused by git(1) in the future of your repository. (ref)

And additional and more in general:

  • Consider to not start names with a digit 0-9.
  • Consider to not start nor end names with punctuation, here ., _ or -.
  • Consider to use only one case, either lower a-z or upper A-Z.
  • Consider to keep the remote name as long as needed while as short as possible, not shorter than three letters. Eight characters is normally a good maximum.

And thanks for asking. It is exactly as you wrote that git-pull(1) allows to specify the remote name after -- while that in the git-fetch(1) invocation by it, the remote name is passed verbatim into the arguments list.

It does not look like an ordinary injection that allows to get ownage of the whole bakery. The only thing that can be injected to git-fetch(1) is a single parameter by the configured remote.<name>.

E.g. with a single remote named --all we can send git-pull(1) (and, via), git-fetch(1) into child recursion. That is fun but also spams tty

Example

Name of the remote: --all

Process tree of git pull -- --all (limited to 6 lines):

 121540 Ss+  00:00:00 -/bin/sh
 122011 T    00:00:00  \_ git pull -- --all
 122012 T    00:00:00      \_ /usr/lib/git-core/git fetch --update-head-ok --all
 122023 T    00:00:00          \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --update-head-ok --all
 122034 T    00:00:00              \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --update-head-ok --all
 122045 T    00:00:00                  \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --update-head-ok --all

Does git-fetch(1) tricks itself here already? Sort of, but only if --jobs=1. With --jobs=2 or higher than 2, git-fetch(2) does process the option more sequentially and not all-over and again and again. But only if there are at least two remotes.

 121540 Ss+  00:00:00 -/bin/sh
 127528 T    00:00:00  \_ git fetch --all
 127539 T    00:00:00      \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
 127550 T    00:00:00          \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
 127561 T    00:00:00              \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
 127572 T    00:00:00                  \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
 127583 T    00:00:00                      \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
 127594 T    00:00:00                          \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
 127605 T    00:00:00                              \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all
 127616 T    00:00:00                                  \_ /usr/lib/git-core/git fetch --append --no-auto-gc --no-write-commit-graph --all

Well, looks like. git-fetch --all has no sanity check to detect if it is re-entrant for the same remote name nor seems to have an option with its own argument to denote the remote (either by name or URL) which could prevent that.

(git version 2.25.1)

hakre
  • 193,403
  • 52
  • 435
  • 836
  • additional referecenes: [Which characters are illegal within a branch name?](https://stackoverflow.com/a/3651867/367456) (for refname reference); [Git 2.24 release notes](https://public-inbox.org/git/xmqq7e4gyzgt.fsf@gitster-ct.c.googlers.com/) (Nov 2019) for introducing `--end-of-options` (is necessary on some git commands using the commonly known end of options delimiter `--` between _revs_ and _pathspec_) – hakre Jun 12 '23 at 09:11