假设我有一个目录/X/Y,它是一个git存储库。是否有可能从/X内部调用类似git pull的命令,但目标是/X/Y目录?
/X/Y
/X
git pull
编辑:我想我在想:是否有可能使用一个git命令来做到这一点,但不必改变目录?
注意:我已经接受了VonC的回答,因为它比以前的选项更优雅。对于运行1.8.5以上版本的Git的用户,请参见Bstpierre的回答如下。
你可以把它包装在bash脚本或git别名中:
cd /X/Y && git pull && cd -
你可以这样写一个脚本:
cd /X/Y git pull
你可以将它命名为gitpull 如果你想让它做任意目录而不是/X/Y:
gitpull
cd $1 git pull
gitpull /X/Z
~/git
g=`find /X -name .git` for repo in ${g[@]} do cd ${repo} cd .. git pull done
编辑:
要么git pull有bug,要么你不能用这个命令做你想做的事情。然而,你可以使用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)。
(cd /X/Y; git pull)
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时,运行以下命令更新该repo,但更新后的文件出现在/tmp中,而不是工作树/tmp/ggg2中:
GIT_DIR=/tmp/ggg2/.git git pull
另请参见这是一个类似问题的答案,其中演示了--git-dir和--work-tree标志。
--git-dir
--work-tree
对于像我这样试图在远程服务器上通过drush (Drupal shell)命令来做到这一点的人来说,你将无法使用需要你CD到工作目录的解决方案:
相反,你需要使用将pull分解为fetch &合并:
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
这篇文章有点旧了,所以可能有一个bug,但它已经修复了,但我只是这样做了:
git --work-tree=/X/Y --git-dir=/X/Y/.git pull origin branch
这招奏效了。我花了一分钟才弄清楚它想要的是dotfile和父目录(在标准设置中,这些总是父/子目录,但不是在ALL设置中,所以它们需要显式指定。
这可能是一个类似的问题,但是您也可以简单地链接您的命令。如
在一行上
cd ~/Sites/yourdir/web;git pull origin master
或者通过SSH。
ssh username@atyourserver.com -t "cd ~/Sites/thedir/web;git pull origin master"
从git 1.8.5(2013年第四季度)开始,你将能够“使用Git命令,但不需要更改目录”。
就像"make -C <directory>", “git -C <directory> ...”告诉Git在做任何其他事情之前去那里。
make -C <directory>
git -C <directory> ...
参见提交44 e1e4 by Nazri Ramliy:
在不离开当前目录的情况下调用不同目录下的Git命令需要更多按键: (cd ~/foo &&git状态)< br > git - git-dir = ~ / foo /。Git——work-tree=~/foo status . GIT_DIR = ~ / foo /。git GIT_WORK_TREE=~/foo git status . git (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命令需要更多按键:
(cd ~/foo &&git状态)< br > 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年3月)开始,以及Karthik Nayak (KarthikNayak)的提交6 a536e2, git将“git -C '<path>'”视为当<path>为空时no-op。
KarthikNayak
git
git -C '<path>'
<path>
'git -C ""'将无用地终止,错误为"Cannot change to ''",而shell将cd ""'视为无操作 以shell的行为为例,教导git将-C ""'也视为无操作
git -C ""
Cannot change to ''
四年后,Git 2.23(2019年Q3)记录了'git -C ""'可以工作并且不更改目录
它一直这样表现,因为6a536e2 (git:治疗"git -C '<path>'" 当<path>为空时作为no-op, 2015-03-06, Git v2.3.4)。< / p >
这意味着的文档现在(最终)包含:
如果'<path>'存在但为空,例如-C "",则当前工作目录保持不变。
-C ""
你可以看到git -C在Git 2.26 (Q1 2020)中使用,作为一个例子。
git -C
gitster
t1507: inline full_name() 签署人:Denton Liu 之前,我们运行的是test_must_fail full_name。但是,test_must_fail只能用于git命令 内联full_name(),以便我们可以直接在git命令上使用test_must_fail 当full_name()在28 fb84382b中引入时(“引入<branch>@{upstream}符号”,2009-09-10,Git v1.7.0-rc0——合并), git -C选项还不可用(因为它是在44 e1e4d67d中引入的(“git:运行在带有-C选项的目录中”,2013-09-09,Git v1.8.5-rc0——合并列在批# 5中) 因此,helper函数消除了每次手动cd的需要。然而,由于git -C现在可用,我们可以只使用它来代替,并内联full_name().
t1507
full_name()
签署人:Denton Liu
test_must_fail full_name
test_must_fail
<branch>@{upstream}
cd
由于我的一些服务器是在旧的Ubuntu LTS版本上,我不能轻易地将git升级到最新版本(如一些回答中所述,它支持-C选项)。
这个技巧对我来说很有效,尤其是因为它没有其他答案的副作用,这些答案会让你进入与你开始的目录不同的目录。
pushd /X/Y git pull popd
或者,把它写成一行代码:
pushd /X/Y; git pull; popd
Linux和Windows都有pushd和popd命令。
使用组合pushd, git pull和popd,我们可以实现这个功能:
pushd
popd
pushd <path-to-git-repo> && git pull && popd
例如:
pushd "E:\Fake Directory\gitrepo" && git pull && popd