假设我有一个目录/X/Y,这是一个git存储库。是否有可能以某种方式调用命令,比如git从/X内部拉,但目标是/X/Y目录?
编辑:我想我特别想知道:是否有可能使用一个git命令来做到这一点,但不必改变目录?
注意:我接受了VonC的答案,因为它比以前的选项更优雅。对于运行1.8.5以上版本的Git的用户,请参阅下面bstpierre的回答。
假设我有一个目录/X/Y,这是一个git存储库。是否有可能以某种方式调用命令,比如git从/X内部拉,但目标是/X/Y目录?
编辑:我想我特别想知道:是否有可能使用一个git命令来做到这一点,但不必改变目录?
注意:我接受了VonC的答案,因为它比以前的选项更优雅。对于运行1.8.5以上版本的Git的用户,请参阅下面bstpierre的回答。
你可以这样写一个脚本:
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
编辑:
要么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拉)。
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标志。
对于像我这样试图在远程服务器上通过drush (Drupal shell)命令来做到这一点的人来说,你将无法使用需要你CD到工作目录的解决方案:
相反,你需要使用将pull分解为fetch & merge的解决方案:
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年Q4)开始,您将能够“使用git命令,但无需更改目录”。
就像"make -C <directory>"一样,"git -C <directory>…"告诉git在做其他事情之前先去那里。
参见Nazri Ramliy的commit 44e1e4:
It takes more keypresses to invoke Git command in a different directory without leaving the current directory: (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 The methods shown above are acceptable for scripting but are too cumbersome for quick command line invocations. With this new option, the above can be done with fewer keystrokes: 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月)开始,并由KarthikNayak (KarthikNayak)提交6a536e2,当<path>为空时,Git将“Git -C '<path>'”视为无操作。
'git -C ""'会毫无帮助地终止,并提示错误"不能更改为"",而shell将cd ""'视为无操作。 以shell的行为为例,教git把-C ""'也当作一个no-op。
四年后,Git 2.23(2019年第三季度)记录了' Git -C ""'可以工作,并且不会更改目录
它的行为是这样的,因为6a536e2 (git: treat "git -C '<路径>'" 当<path>为空时,作为no-op, 2015-03-06, Git v2.3.4)。
这意味着现在(最终)的文档包括:
如果'<path>'存在但为空,例如-C "",则当前工作目录保持不变。
你可以看到git 2.26 (Q1 2020)中使用的git -C,作为一个例子。
参见Denton Liu (Denton- l)的commit b441717、commit 9291e63、commit 5236fce、commit 10812c2、commit 62d58cd、commit b87b02c、commit 9b92070、commit 3595d10、commit f511bc0、commit f6041ab、commit f46c243、commit 99c049b、commit 3738439、commit 7717242、commit b8afb90(2019年12月20日)。 (由Junio C Hamano—gitster—在commit 381e8e9中合并,2020年2月5日)
t1507: inline full_name() Signed-off-by: Denton Liu Before, we were running test_must_fail full_name. However, test_must_fail should only be used on git commands. Inline full_name() so that we can use test_must_fail on the git command directly. When full_name() was introduced in 28fb84382b ("Introduce <branch>@{upstream} notation", 2009-09-10, Git v1.7.0-rc0 -- merge), the git -C option wasn't available yet (since it was introduced in 44e1e4d67d ("git: run in a directory given with -C option", 2013-09-09, Git v1.8.5-rc0 -- merge listed in batch #5)). As a result, the helper function removed the need to manually cd each time. However, since git -C is available now, we can just use that instead and inline full_name().
由于我的一些服务器是在旧的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 <path-to-git-repo> && git pull && popd
例如:
pushd "E:\Fake Directory\gitrepo" && git pull && popd