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 в другом каталоге, не выходя из текущего каталога:

  1. (cd ~/foo && git status)
    git --git-dir=~/foo/.git --work-tree=~/foo status
    GIT_DIR=~/foo/.git GIT_WORK_TREE=~/foo git status
  2. (cd../..; git grep foo)
  3. for d in d1 d2 d3; do (cd $d && git svn rebase); done

Методы, показанные выше, приемлемы для сценариев, но слишком громоздки для быстрых вызовов командной строки.

С помощью этой новой опции, вышеупомянутое может быть сделано с меньшим количеством нажатий клавиш:

  1. git -C ~/foo status
  2. git -C../.. grep foo
  3. 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"