6

Я пытаюсь создать псевдоним git, который объединяет текущую извлеченную ветку с главной веткой. В частности, я бы хотел, чтобы моя ветвь мастера быстро освоилась с тем, над чем я работаю. У меня есть следующее:

[alias]
    co = checkout
    ff = !git co master && git merge work && git co work

Однако я хотел бы, чтобы псевдоним знал, в какой ветке он был, и возвращался к нему. Я попытался добавить $1 но, к сожалению, я получаю сообщение об ошибке при последней проверке в псевдониме:

# with
[alias]
    co = checkout
    ff = !git co master && git merge $1 && git co $1

> git ff work
Switched to branch 'master'
Already up-to-date.
error: pathspec 'work' did not match any file(s) known to git.

Кто-нибудь знает, почему он это делает? (Кстати, я на Mac)

3 ответа3

7

Если вы собираетесь использовать позиционные параметры в псевдонимах git, обязательно укажите sh -c . Следующее работало для меня локально:

ff = !sh -c 'git checkout master && git merge "$1" && git checkout "$1"' -

"Почему" относится к тому, как git анализирует команды псевдонимов и суммируется в этом потоке gmane.

- в конце командных сигналов sh , что обработка закончена опция. От man sh:

A - сигнализирует об окончании опций и отключает дальнейшую обработку опций. Любые аргументы после - обрабатываются как имена файлов и аргументы. Аргумент - эквивалентен -.

Если бы этого не было, это привело бы к ошибке в псевдониме, рассматривая $1 как параметр команды sh вместо позиционного аргумента. Рассмотрим этот тривиальный пример:

$ sh -c 'echo $1' foo          # equivalent to 'echo' without argument

$ sh -c 'echo $1' - foo        # will pass 'foo' to the string as $1
foo

В первом случае 'foo' использовался sh как опция. Во втором это правильно интерпретируется как $1 в строке.

3

Вот версия, с которой вам не нужно указывать текущую ветку и вы можете выбрать любую целевую ветку:

merge-into = !sh -c '_CURRENT_BRANCH=$(git symbolic-ref --short HEAD) && git checkout $1 && git merge $_CURRENT_BRANCH && git checkout $_CURRENT_BRANCH' -

Использование (из моей ветки):

git merge-into master
0

Благодаря ответам в этой теме, я обновил некоторые псевдонимы, которые я использовал:

  • git fold <target> [source] - объединить ветку <target> в текущую (с сохранением истории), дополнительно указав ветку source отличную от текущей; mff это еще одна стенография

    fold = !sh -c '_CURRB=$(git symbolic-ref --short HEAD) && git checkout $1 && git merge --no-ff ${2-$_CURRB} -e' - ; per suggestion http://nvie.com/posts/a-successful-git-branching-model/ + https://superuser.com/questions/435744/git-alias-for-merging-current-branch-with-master
        mff = "!git fold"
    
  • git foldback <target> [source] - то же самое, что и fold , но переключается обратно на ветку source (current)

    foldback = !sh -c '_CURRB=$(git symbolic-ref --short HEAD) && git fold $1 ${2-$_CURRB} && git checkout ${2-$_CURRB}' -
    
  • git fuse <target> [source] - то же самое, что и fold , но удаляет исходную ветвь (т.е. когда вы закончите работу над объектом)

    fuse = !sh -c '_CURRB=$(git symbolic-ref --short HEAD) && git fold $1 $2 && git branch -d ${2-$_CURRB}' - ; per suggestion http://nvie.com/posts/a-successful-git-branching-model/
    

Я недостаточно разбираюсь в оболочке, чтобы узнать, как лучше использовать _CURRB ; какие-либо предложения?

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .