git pull而不在git目录中


git pull while not in a git directory

假设我有一个目录,/X/Y,它是一个git存储库。是否可以从/X内部调用类似git pull的命令,但目标是/X/Y目录?

编辑:我想我特别想知道:是否可以使用一个git命令,但不必更改目录?

注意:我接受了VONC的回答,因为它比以前的选项更优雅。对于运行1.8.5以上的git的人,请参阅下面的bstpiere答案。


从git 1.8.5(2013年第4季度)开始,您将能够"使用git命令,但不必更改目录"。

Just like"make -C ","git -C ..." tells Git to go there before doing anything else.

见Nazri Ramley提交的第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月),以及Karthik Nayak(KarthikNayak承诺的6A536E2,当为空时,git将把"git -C ''视为不允许。

    'git -C""' unhelpfully dies with error"Cannot change to ''", whereas the shell treats cd""' as a no-op.
    Taking the shell's behavior as a precedent, teach git to treat -C""' as a no-op, as well.


    编辑:

    或者是git pull有一个bug,或者你不能用这个命令来做你想做的事情。但是,您可以使用fetch和merge执行此操作:

    1
    2
    3
    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)

    Git手册页指定了一些看起来应该有用的变量(参见"Git存储库"),但我无法使它们正常工作(使用/tmp/ggg2中的存储库):

    1
    2
    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 is/tmp更新repo时运行下面的命令,但更新的文件显示在/tmp中,而不是工作树/tmp/ggg2中:

    1
    GIT_DIR=/tmp/ggg2/.git git pull

    另见一个类似问题的答案,它显示了--git-dir--work-tree标志。


    您可以用bash脚本或git别名包装它:

    1
    cd /X/Y && git pull && cd -


    这篇文章有点旧,所以可能有一个bug,它被修复了,但我只是这样做:

    1
    git --work-tree=/X/Y --git-dir=/X/Y/.git pull origin branch

    它奏效了。我花了一分钟的时间才发现它需要点文件和父目录(在标准设置中,这些总是父/子目录,但不是在所有设置中,因此需要显式指定它们。


    由于我的一些服务器使用的是旧的Ubuntu LTS版本,所以我无法轻松地将Git升级到最新版本(它支持一些答案中描述的-c选项)。

    这个技巧对我很有效,特别是因为它没有其他答案的副作用,这些答案会把你留在与你开始时不同的目录中。

    1
    2
    3
    pushd /X/Y
    git pull
    popd

    或者,作为一条直线:

    1
    pushd /X/Y; git pull; popd

    Linux和Windows都有pushd和popd命令。


    您可以编写这样的脚本:

    1
    2
    cd /X/Y
    git pull

    你可以把它命名为类似于gitpull。如果您希望它执行任意目录而不是/X/Y,请执行以下操作:

    1
    2
    cd $1
    git pull

    然后你可以用gitpull /X/Z来称呼它。最后,您可以尝试查找存储库。我有一个包含存储库的~/git文件夹,您可以使用它来提取所有存储库。

    1
    2
    3
    4
    5
    6
    7
    g=`find /X -name .git`
    for repo in ${g[@]}
    do
        cd ${repo}
        cd ..
        git pull
    done


    使用pushdgit pullpopd组合,我们可以实现以下功能:

    1
    pushd <path-to-git-repo> && git pull && popd

    例如:

    1
    pushd"E:\Fake Directory\gitrepo" && git pull && popd


    对于像我这样试图通过远程服务器上的drush(drupal shell)命令执行此操作的任何人,您将无法使用要求您CD到工作目录中的解决方案:

    相反,您需要使用将"拉入"拆分为"获取和合并"的解决方案:

    1
    2
    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

    这可能是一个类似的问题,但您也可以简单地将命令链起来。如

    在一条线上

    1
    cd ~/Sites/yourdir/web;git pull origin master

    或者通过SSH。

    1
    ssh [email protected] -t"cd ~/Sites/thedir/web;git pull origin master"