我找到了一个类似的问题,但我不确定如何从正则表达式类型搜索构建临时文件。
patchutils 提供了一个命令grepdiff
,可用于实现此功能。
# check that the regex search correctly matches the changes you want.
git diff -U0 | grepdiff 'regex search' --output-matching=hunk
# then apply the changes to the index
git diff -U0 | grepdiff 'regex search' --output-matching=hunk | git apply --cached --unidiff-zero
我在 diff 命令中使用了 -U0
参数,以避免出现无关的更改。你可能需要根据自己的情况调整此值。
hunk
如果你修改了不匹配正则表达式的相邻行,就不能提供足够的细化程度。 - arcyqwertygit status -v
查看已暂存的内容,使用 git diff
查看所有未暂存的内容。如果一切看起来正确,那么就提交吧。 - Gerrygit apply --reverse
撤销工作目录中的某些更改也非常方便。 - Joshua Goldberggit add -p
命令,并利用/
选项搜索差异以添加补丁。虽然不是完全自动化,但比其他我找到的替代方案更容易。git add -p <file>
命令的作用,大致上是这样的:
tmpfile=$(mktemp)
tf2=$(mktemp)
tf3=$(mktemp)
git diff <file> > $tmpfile
while [ -s $tmpfile ]; do
extract first diff hunk from $tmpfile to $tf2 and rest to $tf3
show you $tf2, ask if you want to include this hunk
(with options to edit the hunk, etc); repeat until ready
if you say to *add* the hunk, run git apply --cached $tf2
cat < $tf3 > $tf2
done
rm -f $tmpfile $tf2 $tf3
也就是说,git add -p
使用的是 git apply --cached
(一种特殊的子变体,它忽略了文件的 工作树 副本的 git apply --index
)。你需要从上面得出的关键信息是:有三个版本的文件!
HEAD
提交中。git diff
用作“旧版本”的。git diff
用作“新版本”的。Git 允许你接受或跳过的补丁只是比较“旧”(索引)和“新”(工作树)版本的结果。如果你接受了某个补丁,Git 将通过应用该补丁来更新索引中的副本。
因此,如果工作树版本中有一些行(比如说从第100行到110行)是你想用来替换索引版本中的另一组行(比如说从第90行到92行),那么构建的方法是:git show
或git cat-file -p
与文件的索引版本名称。如果文件名为path/to/file
,则索引版本的名称为:path/to/file
(简写为:0:path/to/file
:我们希望在槽零中有副本;不能在槽1、2或3中有副本,以便在槽0中有副本;您可以尝试从槽零读取它,如果失败,则假定该文件不在索引中或存在冲突)。$tf
的临时文件中(作为shell变量),要更新索引副本,您必须首先确保存在适当的blob哈希ID:hash=$(git hash-object -w -t blob --path="$path" -- "$tf")
git update-index --cacheinfo "$mode,$hash,$path"
其中$mode
为文件的相应模式,可以是100644
或100755
。如果您不想更改该模式,则可以使用git ls-files --cached
或类似命令读取以前的模式。否则,如果core.fileMode
为true
,则从文件的工作树副本中读取模式,以与git add
的行为匹配:将“具有任何可执行位”转换为100755
,“无可执行位”转换为100644
。当core.fileMode
为false
时,请使用git config --get --type bool core.filemode
命令进行阅读。对于这种add-patch情况下,git add
使用现有的模式)。
你可以先运行:
git status | \grep "your_pattern"
git add $(git status | \grep "your_pattern")
git status
显示了被修改的文件,但并没有显示哪些代码行发生了变化。我不明白这如何回答问题。 - Alexgit status
显示已更改的文件,而不是更改的代码行。我不明白这如何回答问题。 - Alex我找到了一个答案。
以下是一些步骤:
git status --porcelain
以易于解析的格式为脚本(如 grep)提供 git 状态。
sed s/^...//
从第3个字符切片到行尾。
xargs
使您能够逐行运行脚本。
在我的情况下,使用需要忽略迁移的django,我的脚本是 git status --porcelain | sed s/^...// | grep -v migrations | xargs git add
。
您可以定制grep选项以适合自己的需求。
文档
$ git status
On branch Bug_#292400_buggy
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: the/path/to/the/file333.NO
modified: the/path/to/the/file334.NO
modified: the/path/to/the/file1.ok
modified: the/path/to/the/file2.ok
modified: the/path/to/the/file3.ok
modified: the/path/to/the/file4.ok
....................................
modified: the/path/to/the/file666.ok
首先,我检查了文件选择是否符合我的要求:
$ git status | grep ok
modified: the/path/to/the/file1.ok
modified: the/path/to/the/file2.ok
modified: the/path/to/the/file3.ok
modified: the/path/to/the/file4.ok
....................................
modified: the/path/to/the/file666.ok
我尝试了一个在这个论坛中描述的想法,以便将相同的文件列表添加到git中,如下:
$ git add $(git status | \grep "your_pattern")
但对我不起作用(记住:在Windows10上使用Git-Bash)
至少,我尝试了一种直接的方式,它很好用:
$ git add *ok
$ git status
On branch Bug_#292400_buggy
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: the/path/to/the/file1.ok
modified: the/path/to/the/file2.ok
modified: the/path/to/the/file3.ok
modified: the/path/to/the/file4.ok
....................................
modified: the/path/to/the/file666.ok
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: the/path/to/the/file333.NO
modified: the/path/to/the/file334.NO
准备好提交了,所以。
xargs 是你要找的。尝试这个:
grep -irl 'regex_term_to_find' * | xargs -I FILE git add FILE
在管道符号|
之前是用于搜索所有文件*
的标准grep命令。选项包括:
i
- 不区分大小写r
- 递归搜索子目录l
- 仅列出文件名在语句的xargs
部分,FILE
是用于每个参数/匹配项的变量名称,由grep命令传递。然后使用变量输入所需的命令。
git add
之后使用-p
参数,但我不确定它在xargs中如何工作,因为补丁过程是由你完成的(即选择应该添加什么和不应该添加什么)。 - RDL
-p
或-i
进行添加,这样您就可以选择要添加到索引的文件的特定部分(非常酷)。 - eftshift0