如何在git-add时避免指定绝对文件路径

66

当文件路径变得很长时,使用git add命令会变得繁琐。例如: git add src_test/com/abc/product/server/datasource/manager/aats/DSManger.java
是否有可能绕过指定绝对文件路径?也许可以使用某种模式或其他方法吗?

我知道我们可以使用git gui,但我想用命令行完成。

提前感谢您的输入。

6个回答

69

对于类Unix系统,您可以始终使用星号指向文件,例如:

 git add *DSManager.java

将包括从您的当前工作目录开始在您的源代码树中Git可以找到的所有DSManager.java文件。


3
显然,这仅添加新创建的文件,但跳过修改过的文件。有什么原因吗? - Vaman Kulkarni
5
对我而言,这也适用于修改过的文件。也许这取决于git版本、bash版本和操作系统。我不知道。我使用的是OSX 10.6,git 1.7.5.4以及bash 4.2.10(2)。 - Steffen
很抱歉,这只添加新文件而不是修改过的文件,在“Linux版本2.6.32 gcc版本4.4.7 Red Hat 4.4.7-17”(Godaddy Linux Hosting)上;git版本1.7.1。 - ᴍᴇʜᴏᴠ
这在Windows上通过git bash可以运行。 - ado387
可以在 Windows 上使用 PowerShell 运行。 - ado387

58

这里是另一种添加文件的方法。至少在git 1.7.1中支持。

$ git add -i
           staged     unstaged path
  1:    unchanged      +61/-61 a/very/long/path/that/we/really/dont/want/to/type.txt
  2:    unchanged        +1/-1 another/very/long/path/that/we/really/dont/want/to/type.txt

*** Commands ***
  1: status       2: update       3: revert       4: add untracked
  5: patch        6: diff         7: quit         8: help
What now> 2

按下 2 选择更新,或输入 u

           staged     unstaged path
  1:    unchanged      +61/-61 a/very/long/path/that/we/really/dont/want/to/type.txt
  2:    unchanged        +1/-1 another/very/long/path/that/we/really/dont/want/to/type.txt
Update>> 2

按对应的数字键来选择要暂存的文件。如果要选择多个文件,请用逗号分隔数字,例如:1,2

           staged     unstaged path
  1:    unchanged      +61/-61 a/very/long/path/that/we/really/dont/want/to/type.txt
* 2:    unchanged        +1/-1 another/very/long/path/that/we/really/dont/want/to/type.txt
Update>>

在这里只需按下[enter]键即可。

updated one path

*** Commands ***
  1: status       2: update       3: revert       4: add untracked
  5: patch        6: diff         7: quit         8: help
What now> q
Bye.

最后输入7q退出。


7
这是正确的答案。它不像通配符一样与shell有关。当文件名非常相似时,编写一个匹配你想添加的内容的好的通配符模式可能变得困难。 - anishpatel
1
这对我帮助很大;我的git版本是1.7.1,运行在一个共享托管账户上。 - ᴍᴇʜᴏᴠ
2
很好的提及,这很有帮助。 - fxrbfg
没有任何一个选项是“还原”,有什么原因吗?我想恢复三个文件,而不必针对每个文件都输入 /src/app/foo/bar/jemima/rhymer/filename.ts。即使使用制表符补全也很烦人。 - Rin and Len
这正是我寻找的,可以在每个路径很长的情况下仅添加特定文件。谢谢! - codingjeremy
显示剩余3条评论

36

使用Bash,您可以设置“globstar”(shopt -s globstar),然后执行:

git add **/DSManger.java

在当前目录下,添加所有名为DSManager.java的文件。

(**/匹配所有目录和子目录。)


这实际上是更好的解决方案,因为它只包括名为DSManager.java的文件,并省略名为OtherDSManager.java的文件。但是,您的shell必须支持globstar选项。 - Steffen

3
我不确定我是否理解了你的问题。
要添加所有尚未添加的文件,请使用以下命令:
git add .

如果你需要添加除一个文件之外的所有文件,你可以先添加所有文件,然后使用以下命令删除这些文件:
git reset HEAD <file>

您可以使用以下方式将子目录中的所有文件添加进去:
git add subdir/

我知道一件可能让人烦恼的事情是重命名文件时,需要添加新的文件名并且git rm旧的文件名。当重命名一个目录时,这可能会很麻烦。这个(仅适用于unix)git别名解决了这个问题(将其放在您的~/.gitconfig文件中:

[alias] ;add after this heading or create this heading if it does not exist
        addremove = !git add . && git ls-files --deleted | xargs --no-run-if-empty git rm

这将添加所有新文件并删除所有已删除的文件,并将其提交到索引中。

不难。重命名目录,然后执行 git add -A。 - Dmitriy

2
我相信只要您的终端窗口当前已经进入了正确的文件夹(src_test/com/abc/product/server/datasource/manager/aats),您就可以直接使用“git add DSManger.java”命令。因此,请执行以下操作:
cd src_test/com/abc/product/server/datasource/manager/aats
git add DSManger.java

否则,除非你创建一个单独的存储库,否则我想不到任何其他方法。enter image description here

2
好的。那应该可以工作。但要提交的文件来自不同的包,因此每次“cd”都会再次变得繁琐。 - Vaman Kulkarni

1
请看一下我为此目的创建的示例Bash脚本。Github仓库链接
#!/bin/bash
# Script Name: git-bash.sh
#
# Author: Krishnadas P.C<pckrishnadas88@gmail.com>
# Date : 05-05-2018
#
# Description: A simple script to manipulate git files.
# TODO add more options and add Error Handlers. 

#declare color variables
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`

#print the current git branch
echo "On Branch - $(git branch)"
#Get only staged files
gitstaged=($(git diff --name-only --cached))

#Get changes not staged for commit
gitnotstaged=($(git diff --name-only))

#Get only untracked files
gituntracked=($(git ls-files --others --exclude-standard))

if [ $# -ge 3 ];
then
   if [ $2 == "st" ];
   then
       git $1 ${gitstaged[$3]}
   elif [ $2 == "nt" ]; 
   then  
    git $1 ${gitnotstaged[$3]}
   elif [ $2 == "ut" ]; 
   then  
    git $1 ${gituntracked[$3]}
   else
     echo "Invalid input provied."
   fi     
fi
#Get the new status after the command has been executed.
gitstaged=($(git diff --name-only --cached))

#Get changes not staged for commit
gitnotstaged=($(git diff --name-only))

#Get only untracked files
gituntracked=($(git ls-files --others --exclude-standard))
#print the staged files.
for i in ${!gitstaged[@]}; do
   if [ $i -eq 0 ]; then 
    echo "Changes to be committed:" 
   fi
   echo "${green}st$i - ${gitstaged[$i]}${reset}"
done
#print the changes not staged files.
for i in ${!gitnotstaged[@]}; do
   if [ $i -eq 0 ]; then 
    echo "Changes not staged for commit:" 
   fi
   echo "${red}nt$i - ${gitnotstaged[$i]}${reset}"
done
#print the untracked files.
for i in ${!gituntracked[@]}; do
   if [ $i -eq 0 ]; then 
    echo "Untracked files:" 
   fi
  echo "${red}ut$i - ${gituntracked[$i]}${reset}"
done

: 'Example how to:
#$ ./git-bash.sh 
Untracked files
ut0 - git-bash.sh
ut1 - git-status.txt
ut2 - test
$./git-bash.sh add ut 0
Staged files
st0 - git-bash.sh
st1 - git-status.txt
Untracked files
ut0 - test
ut stands for untracked files.
nt stands for notstaged tracked files.
st stands for staged files.
'

示例输出

$ ./git-bash.sh 
On Branch - * master
Untracked files:
ut0 - git-bash.sh
ut1 - git-status.txt
ut2 - test

$ ./git-bash.sh add ut 2
On Branch - * master
Changes to be committed:
st0 - test
Untracked files:
ut0 - git-bash.sh
ut1 - git-status.txt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接