0

I've been trying to create an alias of a long Git command. The command is of this format:

git clone "https://MyUserName@MyDomain.com/a/PathToRepo/RepoName" && (cd "RepoName" && mkdir -p .git/hooks && curl -Lo `git rev-parse --git-dir`/hooks/commit-msg https://MyUserName@MyDomain.com/tools/hooks/commit-msg; chmod +x `git rev-parse --git-dir`/hooks/commit-msg)

I am fine with either an alias or a bash function that can help me accomplish this.

halfer
  • 19,824
  • 17
  • 99
  • 186
AjB
  • 890
  • 13
  • 34

1 Answers1

4

Don't use aliases. They are in every aspect inferior to functions.

Writing this as a function also avoids the quoting errors you probably were bumping into when trying to create an alias (though it's not impossible to solve those, too; but if that's what you want, probably ask a new question with your actual attempt).

The following only has very small changes compared to your original (and to the extent that the original worked in the first place, it would have worked just as well without any changes at all).

func () {
    git clone "https://MyUserName@MyDomain.com/a/PathToRepo/RepoName" &&
    (
      cd "RepoName" &&
      mkdir -p .git/hooks &&
      curl -Lo "$(git rev-parse --git-dir)/hooks/commit-msg" "https://MyUserName@MyDomain.com/tools/hooks/commit-msg" &&
      chmod +x "$(git rev-parse --git-dir)/hooks/commit-msg"
    )
}

The switch from legacy `command substitution` syntax to modern $(command substitution) syntax is mainly for aesthetic reasons. The addition of double quotes is crucial for handling file names with spaces or other shell metacharacters in them. Adding && instead of ; before chmod +x seemed to make sense for consistency.

Personally, I would calling git rev-parse --git-dir twice, and just create a variable with the name of the directory:

func () {
    git clone "https://MyUserName@MyDomain.com/a/PathToRepo/RepoName" &&
    local hookdir=RepoName/$(git -C "RepoName" rev-parse --git-dir)/hooks &&
    mkdir -p "$hookdir" &&
    curl -Lo "$hookdir/commit-msg" "https://MyUserName@MyDomain.com/tools/hooks/commit-msg" &&
    chmod +x "$hookdir/commit-msg"
}

If you want to make the repository name and/or the URL configurable parameters, I would suggest to make the repo name the first parameter and the base URL the second, but this obviously depends on your use case.

func () {
    git clone "${2-https://MyUserName@MyDomain.com/a/PathToRepo}/$1" &&
    local hookdir="$1"/$(git -C "$1" rev-parse --git-dir)/hooks &&
    mkdir -p "$hookdir" &&
    curl -Lo "$hookdir/commit-msg" "https://MyUserName@MyDomain.com/tools/hooks/commit-msg" &&
    chmod +x "$hookdir/commit-msg"
}

The syntax ${2-default} falls back to default if $2 is unset.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • What about `git -C "RepoName" rev-parse --git-dir` instead of `cd "RepoName" && git rev-parse --git-dir`? And wouldn't `${2:-default}` be a bit safer than `${2-default}`? – Renaud Pacalet Dec 13 '21 at 08:43
  • 1
    Thanks for the suggestion with `-C`; that is indeed an improvement. I find it hard to imagine that the user would explicitly pass in an empty string and expect it to be replaced with the default so I'll pass on that suggestion. – tripleee Dec 13 '21 at 08:49
  • Well, the user could simply write `func RepoName "$ulr"` instead of `func RepoName "$url"`... – Renaud Pacalet Dec 13 '21 at 08:51
  • 1
    Silently failing to do what they want seems worse than failing with an error. – tripleee Dec 13 '21 at 08:52
  • That's right. You convinced me, `${2-default}` is definitely better. Thanks. – Renaud Pacalet Dec 13 '21 at 08:54