是否有一个git命令可以将在一系列行号中添加到索引中?
我希望能够在我的编辑器中选择行并运行宏来将选择中的任何更改添加到索引中。
答案 0 :(得分:17)
如果您可以说服编辑器编写要暂存的文件版本,则可以使用plumbing-level git命令将其添加到正确名称下的索引中。你需要绕过“git add”,它总是将工作树中的路径X与索引中的路径X相关联(据我所知)。
如果您要将要写入的内容写入某个临时文件$ tempfile,请运行git hash-object -w $tempfile
- 这会将对象写入.git / objects并输出blob id。然后使用git update-index --cacheinfo 100644 $blobid $path
将此blob id提供给索引,以将路径$ path与该对象相关联。
这是一个示例,它在我的仓库中对一个名为“post_load”的脚本进行更改,而不会覆盖文件本身(也证明您可以不使用临时文件):
git update-index --cacheinfo 100755 $(perl -lne 'print unless (/^#/)' post_load \
| git hash-object -w --stdin) post_load
您没有提到您计划从哪个编辑器执行此操作,因此很难建议您如何集成此编辑器。正如我所提到的,你需要以某种方式呈现git与文件,因为你希望它被暂存(记住,git不处理存储更改)。如果你可以写一个宏只是将文件保存为“$ file.tmp”,那么使用类似上面的内容git update-index --cacheinfo $the_mode $(git hash-object -w $file.tmp) $file
(获取$ the_mode作为练习:p),删除$ file.tmp和将编辑器缓冲区恢复为$ file,基本上可以满足您的要求。
例如,以下脚本有三个参数:M N path
。它将在“path”更新文件的索引内容,以便将行M到N(包括)替换为来自stdin的内容:
#!/bin/sh
start_line=$1
end_line=$2
path=$3
mode=$(git ls-files -s $path | awk '{print $1}')
blob_id=$(
(
head -n $(expr $start_line - 1) $path
cat
tail -n +$(expr $end_line + 1) $path
) | git hash-object -w --stdin
)
exec git update-index --cacheinfo $mode $blob_id $path
例如echo "HELLO WORLD" | ./stage-part 8 10 post_load
将仅用“HELLO WORLD”替换8-10中的三行。
答案 1 :(得分:3)
目前最简单的方法是在交互模式下使用git add
:
git add -i path/to/file
它将启动简单的UI,您可以在其中选择要暂存的块,并允许您编辑任何块以删除您不想提交的行。
答案 2 :(得分:2)
根据我自己的经验,git-cola在此方面做得非常出色。我希望它支持Atom集成......
答案 3 :(得分:0)
最接近预先构建的工具是git gui citool
。它不能直接在您的编辑器中工作(并非所有编辑都有有用的差异视图,我怀疑大多数人可能并不关心自上次提交后他们确切改变了哪些行,因此差异视图非常有用),但似乎喜欢它接近你想要的。
git gui citool
可让您分别查看相当于git diff --cached
和git diff
的视图中的暂存和非暂停更改。
在查看未分级的更改时,上下文菜单(右键单击)具有选项以分段选定的行(如果没有选择则显示单击的行)以及用于暂存整个大块的选项。 同样,在查看分阶段更改时,上下文菜单可以选择取消分段行或大块。
要获得更多上下文,您可以使用“显示更多上下文”菜单项(如果您想缩小数据,则可以使用“显示更少上下文”)。
一旦您的新内容暂停,您还可以撰写提交消息并从GUI内部进行提交。
我想有些人在这样的工作流程中使用git gui
:
git add
的各种选项)。git gui
中,选择“重新扫描”,查看更改,暂存/取消暂停,最后提交。