说我正在执行此操作:

cd subdir
git init
cd ../


是否有一种方法可以用一个或两个命令来执行此操作,而不必移入移出

(不是寻找特定于git的解决方案;这只是一个示例。)

#1 楼

这通常是最好的方法:



( cd dir ; git init )


它很短且易于输入。它确实启动了一个子外壳,因此您不能从那里修改您的环境,但这在这里似乎不是问题。

评论


而且,如果您确实需要设置一个或两个环境变量,只需在开头将其添加为另一个命令即可。

–河马
2012年12月24日上午11:18

@CraigMcQueen:并非如此。 $?将包含在子外壳程序中运行的最后一个命令的退出代码。如果使用&&变体(通常应该这样做),那么您将获得第一个失败的命令的退出代码(如果一切正常,则返回0)。

–垫子
15年7月20日在5:12

我认为括号是可选的

– Francis.Beauchamp
16年5月5日在13:10

@ Francis.Beauchamp:如果省略括号,则将位于命令后的子目录中,而不是返回开始的位置。

–垫子
16年5月5日在13:19

在Windows上如何做到这一点?

–卡尔·莫里森(Karl Morrison)
19年7月19日在6:08

#2 楼

我一直在寻找一种从路径执行git命令并在其他路径中对存储库进行更改的方法。因此,我在这里遇到了这个问题。

但是对于我的特定需求,既不能接受已接受的答案,也不能帮助其他任何人。

我需要使用sudo -u USER /usr/bin/git运行git命令(另一个运行它的用户)。正如您可能知道的那样,sudo不允许我运行cd命令,因此我无法进入存储库目录。

因此,我进入了git的手册页。在这些选项中,我看到了--git-dir=<path>:--git-dir =

设置存储库的路径。也可以通过设置GIT_DIR环境变量来控制。它可以是当前工作目录的绝对路径或相对路径。


因此,如果它可以帮助某人,您仍然可以使用路径中的git并对存储库进行“远非您”。只需使用:

git --git-dir=/path/to/repository GIT_COMMAND


,或以其他用户身份运行它,请执行以下操作:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository GIT_COMMAND


同样来自git-init的手册页:


如果设置了$ GIT_DIR环境变量,则它将指定用于存储库基础的路径,而不是./.git。 />

因此,如果要在通常的.git文件夹下初始化存储库,则需要将其与--git-dir选项一起指定。例如:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository/.git init


在初始化/path/to/repo/.git上的存储库后,所有其他命令都应具有选项--work-tree=<path>,如git的手册页所述:


--work-tree =

设置工作树的路径。它可以是绝对路径,也可以是相对于当前工作目录的路径。也可以通过设置GIT_WORK_TREE环境变量和core.worktree配置变量来控制(有关详细讨论,请参见git-config(1)中的core.worktree)。


所以,以另一个用户身份运行git并初始化新存储库的正确命令是:

echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir=/path/to/repository/.git init
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' add /path/to/repository/*
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' commit -m 'MESSAGE'
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' remote add origin user@domain.com:path
echo USER_PASSWORD | sudo -u USER_LOGIN -S /usr/bin/git --git-dir='/path/to/repository/.git' --work-tree='/path/to/repository' push -u origin master


评论


如果您是通过交互方式而不是通过脚本使用sudo,则只需执行sudo -i或sudo su即可获得交互式root shell。

– Bugster
18年8月28日在23:03

我无法想象为什么(cd subdir && sudo -u USER / usr / bin / git init)无法正常工作。

–斯科特
19年6月23日在17:30

如果我没有访问subdir的权限怎么办?

– dmmd
19年6月24日在12:40

#3 楼

不完全是您要问的问题(您在子shell上有实际答案),请查看pushdpopd

评论


我用cd &&尝试了maven,但没有用,但通过push和popd可以完美地完成工作。谢谢

–拉杜·图德(Radu Toader)
15年6月25日在17:47

#4 楼

您有几种选择。您可以使用&&;将命令分组。像这样:

cd subdir && git init && cd ..




cd subdir; git init; cd ..


两者之间的区别在于,在第一个示例中,如果其中一个命令失败,它将不执行其余命令。在第二个示例中,无论如何,所有命令都将运行。

另一个选择是定义一个函数并使用它,例如:

function cdinit() {
    cd 
    git init
    cd ..
}


然后您可以运行命令:

cdinit subdir


,它将自动在该目录中git init并移出该目录。

如果您有一堆目录,并希望使用一个命令对它们进行git init编码,也可以使用函数来做更复杂的解决方案。

function cdinit() {
    for arg in $@
    do
        cd $arg
        git init
        cd ..
    done
}


然后可以运行此命令使用:

cdinit subdir1 subdir2 subdir3


它将执行git initsubdir1subdir2中的subdir3

评论


谢谢。我知道&&和;,但是希望有一些更优雅的东西。听起来写脚本是我最好的选择。

–特雷弗·伯纳姆
2011年4月17日下午16:21

更正:这个答案很好,但是Mat的答案更适合我的特殊需求。

–特雷弗·伯纳姆
2011年4月17日在16:36

您认为您的cdinit函数可以推广到任意命令吗?我尝试仅使用参数,但这没有用。

–车丹·巴辛(Chetan Bhasin)
19年4月23日在12:01

(1)换行符等效于;,因此三行功能等效于cd $ 1; git init; cd ...(2)应该引用变量:“ $ 1”,“ $ @”和“ $ arg”。或者,您可以将forargin“ $ @”缩写为forarg。

–斯科特
19年6月23日在17:29

#5 楼

如果是git(至少在2.7.0版中),则可以利用-C选项,该选项使git表现得就像在给定目录中启动一样。因此,您的解决方案可能看起来像:

> git -C subdir init
Initialized empty Git repository in /some/path/subdir/.git/


引用文档:

Run as if git was started in <path> instead of the current working directory. When multiple -C options are given, each subsequent non-absolute -C
<path> is interpreted relative to the preceding -C <path>.

This option affects options that expect path name like --git-dir and --work-tree in that their interpretations of the path names would be made
relative to the working directory caused by the -C option. 


#6 楼

您可以使用&&将命令分组,即

cd subdir && git init && cd ../


如果您不想依赖每个命令的退出代码,则可以使用;相反,即:

cd subdir ; git init ; cd ../


评论


或与;这样它们就不会依赖于前一个的返回码。

–slhck
2011年4月17日在16:14

(1)cd子目录&& git init; cd ..实际上可能最有意义。如果用户想在子目录中运行gitinit命令,那么他们可能不想在当前目录中运行该命令;也就是说,如果(第一个)CD失败,他们不想运行它。 (尽管由于我们已经在子目录中,所以thecd可能会失败,但是这种情况更糟。)。…(续)

–斯科特
19年6月23日在17:29

(续)…但是,如果用户想将三个命令块作为一个单元进行处理,即使gitinit命令失败,他们也可能希望将其恢复到起始目录。 (或者,他们可能希望保留在子目录中并诊断命令失败。)(2)您不需要在后面加上/。

–斯科特
19年6月23日在17:29

#7 楼

如果命令没有文件名或目录名称参数,则必须跳到目标目录。

但是您可以编写一个以目标目录和命令为参数的bash脚本。 br为此,您可以看一下push和popd:http://ss64.com/bash/pushd.html

我会为您编写一个小脚本,但是我没有一个Linux盒子在这里:)

评论


刚刚看到Mark Szymanski的回答。您可以只为命令实现第二个参数(并重命名命令),然后您便拥有了所需的内容。

– wullxz
2011年4月17日在16:25

#8 楼

程序使用不同的方式处理参数,因此有些程序将具有-folder = name选项。除了该例外,即使在MS DOS上,该标准也很简单

$ program subdir

有时您需要

$ program subdir /

程序将打开该文件夹,以与处理文件相同的方式使用该文件夹,完成后,将控制权返回到指向原始原始目录的shell。
处理的程序这样,确实会出现错误输出(例如核心转储)进入外壳程序当前目录(而不是子目录)中的文件的问题。除非程序具有可用于指定的命令开关,否则没有解决方法一个不同的地方。一些程序员在“调用目录程序”和“告诉程序程序在其中工作”之间取得了艺术上的许可。