【问题标题】:Git: Add part of (changed) file to index *by line numbers*Git:将(更改的)文件的一部分添加到索引*按行号*
【发布时间】:2011-02-16 12:15:54
【问题描述】:

是否有 git 命令可以将行号范围内的差异添加到索引中?

我希望能够在我的编辑器中选择行并运行一个宏来将选择中的任何更改添加到索引中。

【问题讨论】:

  • 您对在编辑器内部而不是通过git add -i 执行此操作的想法有多重视?如果您真的想这样做,您可能会处理一些名为git diff 的东西,拉出触摸您选择的行的大块,然后将该补丁应用于索引...

标签: git


【解决方案1】:

如果您可以说服您的编辑编写您想要暂存的文件版本,您可以使用管道级 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 与该对象相关联。

这是一个示例,它在我的 repo 中对名为“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。它将更新“路径”处文件的索引内容,以便将行 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 会将 8-10 的三行替换为“HELLO WORLD”。

【讨论】:

    【解决方案2】:

    目前最简单的方法是在交互模式下使用git add

    git add -i path/to/file
    

    它将启动简单的 UI,您可以在其中选择要暂存的块,并允许您编辑任何块以删除您不想提交的行。

    【讨论】:

    • 这是我目前的做法,但是当我想要测试/提交的差异中有太多“噪音”时,我会感到困惑(由于缺乏上下文行等)。真的希望能够在这种情况下从我的编辑器中驱动它。
    【解决方案3】:

    根据我自己的经验,git-cola 在这方面做得非常出色。我希望它支持 Atom 集成...

    【讨论】:

    • 虽然理论上这可以回答这个问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。
    • 在 git-cola 中,选择行并从下拉列表中选择 Stage Selected Lines,或点击 H。它确实需要从常规编辑器切换到 git-cola 进行暂存,但两者可以同时运行,我没有发现它不方便。
    【解决方案4】:

    执行此类操作的最接近的预构建工具是git gui citool。它不能直接在您的编辑器中工作(并非所有编辑器都有有用的差异视图,我怀疑大多数人可能不关心自上次提交以来他们确切更改了哪些行,因此差异视图非常有用),但似乎就像它接近你想要的一样。

    git gui citool 可让您查看视图中的暂存和未暂存更改,它们分别相当于 git diff --cachedgit diff

    在查看未暂存的更改时,上下文菜单(右键单击)具有暂存选定行(如果没有选择,则为单击的行)的选项和暂存整个大块的选项。 同样,在查看分段更改时,上下文菜单具有取消分段行或大块的选项。

    要获得更多上下文,您可以使用“显示更多上下文”菜单项(或“显示更少上下文”,如果您想缩小大块)。

    在您准备好新内容后,您还可以编写提交消息并从 GUI 内部进行提交。

    我想有些人在这样的工作流程中使用git gui

    1. 使用 CLI 添加新的跟踪文件和删除旧文件(git add 的各种选项)。
    2. 在您喜欢的编辑器/环境中编辑跟踪的文件。
    3. git gui 中,选择“重新扫描”,查看更改,暂存/取消暂存部分,并最终提交。
    4. [重复]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-18
      • 2013-09-07
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 2019-10-15
      • 2015-05-09
      • 1970-01-01
      相关资源
      最近更新 更多