Git псевдоним для команды оболочки для cd в git root не работает как ожидалось

Я пытаюсь определить псевдоним cd me в корневом каталоге git с помощью git rev-parse --show-toplevel.

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

alias gitroot='cd "$(git rev-parse --show-toplevel)"'

Но я знаю, что вы можете запускать команды оболочки с помощью псевдонимов git, поэтому я подумал, что переместил команду в мой .gitconfig, чтобы сделать мои файлы немного более чистыми.

Проблема в том, что я не могу понять, почему мой псевдоним не работает. В настоящее время у меня это под [alias] в моем .gitconfig:

root = "!sh -c 'cd \"$(git rev-parse --show-toplevel)\"'"

Но когда я запускаю git root, я просто остаюсь в текущем каталоге.

Я экспериментировал с другими псевдонимами оболочки, и они работали, например. псевдоним say = "!sh -c 'echo \"$0\"'" работает просто отлично:

$ git say hello
hello

Хотя я заметил, что сбой аналогичной команды cd (cd = "!sh -c 'cd \"$0\"'"):

~/repos/myproject$ git cd /home/
~/repos/myproject$

Я не могу понять, связано ли это с моим синтаксисом или причудой алиасов git, что он не поддерживает команду cd или что-то еще полностью.

Если это помогает, я использую git 1.7.9.5.

Ответ 1

Ваша оболочка вызывает Git, а Git вызывает другую оболочку, в которой вы можете запустить команду cd. Эта команда выполнена успешно, и это изменяет рабочий каталог дочерней оболочки, но не изменяет рабочий каталог Git или родительской оболочки.

Для этого вам нужно запустить команду в текущей оболочке, а это значит, что вызов Git не сможет выполнить это. Вам придется продолжить использование псевдонима оболочки.


Чтобы проиллюстрировать, скажем, у вас есть следующая оболочка script, называемая up.sh:

#!/bin/sh
cd ..

Если вы выполните этот script как ./up.sh, то ничего не изменится с точки зрения вашей текущей оболочки, потому что cd был выполнен в новом экземпляре оболочки. Однако, если вы выполняете его как . up.sh, это указывает, что ваша текущая оболочка сама выполнит содержимое файла, не создавая подоболочку. В этом случае текущий рабочий каталог оболочки изменится.

Это ключевое различие здесь. Использование псевдонима Git аналогично методу ./up.sh, в то время как псевдоним оболочки похож на метод . up.sh.