101

Скажи, что я делаю это:

cd subdir
git init
cd ../

Есть ли способ сделать это с помощью одной команды или, возможно, двух, вместо того, чтобы входить и выходить из каталога, чтобы выполнить там команду?

(Не искать специфическое для git решение; это всего лишь пример.)

8 ответов8

178

Часто это лучший способ:

( cd dir ; git init )

или же

( cd dir && git init )

Это довольно короткий и легко набрать. Он запускает под-оболочку, поэтому вы не можете изменить свою среду, но это, похоже, не проблема.

21

Я искал способ выполнить команду git из пути и внести изменения в хранилище по другому пути. Так что я оказался в этом вопросе здесь.

Но для моих конкретных нужд не помог ни принятый ответ, ни какой-либо другой.

Мне нужно было запускать команды git с помощью sudo -u USER /usr/bin/git (другой пользователь запускал его). И, как вы, возможно, знаете, sudo не позволяет мне запускать команду cd , поэтому я не могу находиться в каталоге репозитория.

Итак, я пошел на страницу руководства Git. И среди вариантов я увидел --git-dir=<path>:

--git-Dir =

Установите путь к хранилищу. Это также можно контролировать, устанавливая переменную среды GIT_DIR. Это может быть абсолютный или относительный путь к текущему рабочему каталогу.

Так что, если это кому-то поможет, вы все равно можете использовать git с пути и вносить изменения в хранилище "далеко от вас". Просто используйте:

git --git-dir=/path/to/repository GIT_COMMAND

или, чтобы запустить его от имени другого пользователя, сделайте что-то вроде:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository GIT_COMMAND

Также со справочной страницы git-init:

Если установлена переменная среды $ GIT_DIR, то она указывает путь для использования вместо./.git для базы хранилища.

Итак, если вы хотите запустить репозиторий из обычной папки .git, вам нужно будет указать его вместе с параметром --git-dir . например:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository/.git init

После инициализации репозитория в /path/to/repo/.git все последующие команды должны иметь параметр --work-tree=<path> , как описано на справочной странице git:

--work дерево =

Установите путь к рабочему дереву. Это может быть абсолютный путь или путь относительно текущего рабочего каталога. Это также можно контролировать, задав переменную среды GIT_WORK_TREE и конфигурационную переменную core.worktree (для более подробного обсуждения см. Core.worktree в git-config (1)).

Итак, правильная команда для запуска git от имени другого пользователя и инициализации нового репозитория:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository/.git init
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' add /path/to/repository/*
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' commit -m 'MESSAGE'
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' remote add origin user@domain.com:path
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' push -u origin master
13

Не совсем то, что вы спрашиваете (у вас есть реальные ответы выше с subshell), но посмотрите на pushd и popd

6

У вас есть несколько вариантов. Вы можете сгруппировать команды с помощью && или ; , Как это:

cd subdir && git init && cd ..

или же

cd subdir; git init; cd ..

Разница между ними заключается в том, что в первом примере, если одна из команд не выполнена, остальные не будут выполнены. Во втором примере все команды будут выполняться независимо от того, что.

Другой вариант - определить функцию и использовать ее, например:

function cdinit() {
    cd $1
    git init
    cd ..
}

Затем вы можете запустить команду:

cdinit subdir

И он автоматически git init в этом каталоге и выйдет из него.

Вы также можете сделать более сложное решение, используя функцию, если у вас есть несколько каталогов и вы хотите, чтобы git init их одной командой.

function cdinit() {
    for arg in $@
    do
        cd $arg
        git init
        cd ..
    done
}

Затем вы можете запустить это с:

cdinit subdir1 subdir2 subdir3

И это будет делать git init в subdir1 , subdir2 и subdir3 .

5

В случае git (по крайней мере, в версии 2.7.0) вы можете использовать опцию -C которая заставляет git вести себя так, как если бы он был запущен в данном каталоге. Таким образом, ваше решение может выглядеть так:

> git -C subdir init
Initialized empty Git repository in /some/path/subdir/.git/

Цитирование документации:

Run as if git was started in <path> instead of the current working directory. When multiple -C options are given, each subsequent non-absolute -C
<path> is interpreted relative to the preceding -C <path>.

This option affects options that expect path name like --git-dir and --work-tree in that their interpretations of the path names would be made
relative to the working directory caused by the -C option. 
2

Вы можете сгруппировать команды с &&, т.е.

cd subdir && git init && cd ../

Если вы не хотите никакой зависимости от кода выхода каждой команды, вы можете использовать; вместо этого, то есть:

cd subdir ; git init ; cd ../
2

Вы должны перейти в целевой каталог, если команда не имеет имени файла или параметра имени каталога.

Но вы можете написать bash-скрипт, который принимает целевой каталог и команду в качестве параметров. Для этого вы можете взглянуть на pushd и popd: http://ss64.com/bash/pushd.html

Я написал бы этот маленький сценарий для вас, но у меня нет коробки с Linux здесь :)

1

Программы имеют разные способы обработки аргументов, поэтому некоторые из них будут иметь эквивалентный параметр -folder = name . Помимо этого, стандарт, даже на MS DOS, просто

$ program subdir

Иногда нужно

$ program subdir/

Программа откроет папку, будет работать с ней так же, как вы работаете с файлом, и после ее завершения вернете управление вашей оболочке, которая указана в исходном стандартном каталоге. Программы, которые обрабатываются таким образом, ДЕЙСТВИТЕЛЬНО имеют проблему с тем, что выходные сообщения об ошибках (например, дампы ядра) направляются в файл в текущем каталоге вашей оболочки (а не в подкаталог ).

Обходного пути нет, если в программе не доступны переключатели команд для указания другого места. Некоторые программисты берут художественную лицензию между «директорией была вызвана программа» и «директивной программой было приказано работать ».

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