Git вытащить, не находясь в каталоге git
Скажем, у меня есть каталог, /X/Y
, который представляет собой репозиторий git. Возможно ли каким-то образом вызвать команду git pull
изнутри /X
, но нацелиться на каталог /X/Y
?
EDIT: Я думаю, мне было интересно: возможно ли это сделать с помощью команды git, но без необходимости менять каталоги?
ПРИМЕЧАНИЕ. Я принял ответ VonC, поскольку он намного более изящный, чем предыдущие. Для людей, работающих под управлением git старше 1.8.5, см. Ниже ответ bstpierre.
Ответы
Ответ 1
Начиная с git 1.8.5 (4 квартал 2013 года), вы сможете "использовать команду Git, но без необходимости менять каталоги".
Так же, как " make -C <directory>
", " git -C <directory>...
" говорит Git идти туда, прежде чем делать что-либо еще.
Смотрите коммит 44e1e4 от Назри Рамлия:
Требуется больше нажатий клавиш для вызова команды Git в другом каталоге, не выходя из текущего каталога:
-
(cd ~/foo && git status)
git --git-dir=~/foo/.git --work-tree=~/foo status
GIT_DIR=~/foo/.git GIT_WORK_TREE=~/foo git status
-
(cd../..; git grep foo)
-
for d in d1 d2 d3; do (cd $d && git svn rebase); done
Методы, показанные выше, приемлемы для сценариев, но слишком громоздки для быстрых вызовов командной строки.
С помощью этой новой опции, вышеупомянутое может быть сделано с меньшим количеством нажатий клавиш:
-
git -C ~/foo status
-
git -C../.. grep foo
-
for d in d1 d2 d3; do git -C $d svn rebase; done
Начиная с Git 2.3.4 (март 2015 г.) и коммитом 6a536e2 от Karthik Nayak (KarthikNayak
), git
будет обрабатывать " git -C '<path>'
" как git -C '<path>'
когда <path>
пуст.
' git -C ""
"бесполезно умирает с ошибкой" Cannot change to ''
", в то время как оболочка рассматривает cd" "" как no-op.
Принимая поведение оболочки в качестве прецедента, научите git
обращаться с -C "" 'также как с запретом.
Спустя 4 года Git 2.23 (Q3 2019) документирует, что git -C ""
" работает и не меняет каталог
Он ведет себя так с 6a536e2 (git
: обрабатывать " git -C '<path>'
" как git -C '<path>'
когда <path>
пуст, 2015-03-06, Git v2.3.4).
Это означает, что документация теперь (наконец) включает в себя:
Если ' <path>
' присутствует, но пуст, например, -C ""
, то текущий рабочий каталог остается без изменений.
Ответ 2
Редактировать:
Там либо ошибка с git pull
, либо вы не можете делать то, что пытаетесь сделать с этой командой. Однако вы можете сделать это с помощью fetch и merge:
cd /X
git --git-dir=/X/Y/.git fetch
git --git-dir=/X/Y/.git --work-tree=/X/Y merge origin/master
Оригинальный ответ:
Предполагая, что вы используете bash или что-то подобное, вы можете это сделать (cd/X/Y; git pull)
.
Страница man git определяет некоторые переменные (см. "Репозиторий git"), которые, похоже, должны помочь, но я не могу заставить их работать правильно (с моим репозиторием в /tmp/ggg2):
GIT_WORK_TREE=/tmp/ggg2 GIT_DIR=/tmp/ggg2/.git git pull
fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.
Выполнение команды ниже, в то время как мой cwd является /tmp, обновляет этот репозиторий, но обновленный файл появляется в /tmp вместо рабочего дерева /tmp/ggg2:
GIT_DIR=/tmp/ggg2/.git git pull
Смотрите также этот ответ на аналогичный вопрос, который демонстрирует --git-dir
и --work-tree
.
Ответ 3
Вы можете обернуть его в псевдоним bash script или git:
cd /X/Y && git pull && cd -
Ответ 4
Эта запись немного устарела, так что может быть ошибка, и она была исправлена, но я просто сделал это:
git --work-tree=/X/Y --git-dir=/X/Y/.git pull origin branch
И это сработало. Потребовал мне минуту, чтобы понять, что ему нужен dotfile и родительский каталог (в стандартной настройке они всегда являются родительскими/дочерними, но не во всех установках, поэтому они должны быть указаны явно.
Ответ 5
Как некоторые из моих серверов находятся на старых версиях Ubuntu LTS, я не могу легко обновить git до последней версии (которая поддерживает параметр -C, как описано в некоторых ответах).
Этот трюк хорошо работает для меня, особенно потому, что у него нет побочного эффекта некоторых других ответов, которые оставляют вас в другом каталоге, откуда вы начали.
pushd /X/Y
git pull
popd
Или, сделав это как однострочный:
pushd /X/Y; git pull; popd
В Linux и Windows есть команды pushd и popd.
Ответ 6
Вы можете написать script следующим образом:
cd /X/Y
git pull
Вы можете называть его чем-то вроде gitpull
.
Если вы предпочитаете использовать произвольные каталоги вместо /X/Y
:
cd $1
git pull
Затем вы можете позвонить ему с помощью gitpull /X/Z
Наконец, вы можете попробовать найти репозитории. У меня есть папка ~/git
, которая содержит репозитории, и вы можете использовать ее, чтобы сделать все возможное.
g=`find /X -name .git`
for repo in ${g[@]}
do
cd ${repo}
cd ..
git pull
done
Ответ 7
Для таких, как я, которые пытались сделать это с помощью команды drush (Drupal shell) на удаленном сервере, вы не сможете использовать решение, требующее, чтобы CD в рабочий каталог:
Вместо этого вам нужно использовать решение, которое разбивает вытягивание на выборку и слияние:
drush @remote exec git --git-dir=/REPO/PATH --work-tree=/REPO/WORKDIR-PATH fetch origin
drush @remote exec git --git-dir=/REPO/PATH --work-tree=/REPO/WORKDIR-PATH merge origin/branch
Ответ 8
Используя комбинацию pushd
, git pull
и popd
, мы можем добиться этой функциональности:
pushd <path-to-git-repo> && git pull && popd
Например:
pushd "E:\Fake Directory\gitrepo" && git pull && popd
Ответ 9
Это может быть аналогичная проблема, но вы также можете просто объединить свои команды. например,
В одной строке
cd ~/Sites/yourdir/web;git pull origin master
Или через SSH.
ssh [email protected] -t "cd ~/Sites/thedir/web;git pull origin master"