如何读取git diff的输出? [英] How to read the output from git diff?

查看:129
本文介绍了如何读取git diff的输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

git-diff 的手册页相当长,并解释了许多初学者似乎不需要的情况。例如:

  git diff origin / master 


解决方案

让我们看一下git历史记录中的高级差异示例(在git.git存储库中提交1088261f ):

  diff --git a / builtin -http-fetch.cb / http-fetch.c 
相似索引95%
从builtin-http-fetch.c重命名
重命名为http-fetch.c
index f3e63d7..e8f44ba 100644
--- a / builtin -http-fetch.c
+++ b / http-fetch.c
@ @ -1,8 +1,9 @@
#includecache.h
#includewalker.h

-int cmd_http_fetch(int argc,const char ** argv,const char *前缀)
+ int main(int argc,const char ** argv)
{
+ const char * prefix;
struct walker * walker;
int commits_on_stdin = 0;
int提交;
@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc,const char ** argv,const char * prefix)
int get_verbosely = 0;
int get_recover = 0;

+ prefix = setup_git_directory();
+
git_config(git_default_config,NULL);

while(arg< argc& argv [arg] [0] ==' - '){

让我们一行一行地分析这个补丁。




  • 第一行

     diff --git a / builtin -http-fetch.cb / http-fetch.c 

    是一个git diff头文件,格式为 diff --git a / file1 b / file2 。除非涉及重命名/复制(如我们的情况),否则 a / b / 文件名是相同的。 - git 表示diff是以gitdiff格式。

  • 下一页是一个或多个扩展标题行。前三个

    相似索引95%
    从builtin-http-fetch.c重命名
    重命名为http-fetch.c

    告诉我们该文件是重命名为 builtin-http-fetch.c http-fetch.c ,并且这两个文件是95%相同的(用于检测这个重命名)。

    扩展差异头文件的最后一行,它是

     index f3e63d7..e8f44ba 100644 

    介绍关于模式给定文件( 100644 意味着它是普通文件而不是例如符号链接,并且它没有可执行权限位),以及关于preimage的缩短哈希文件更改前)和postimage(更改后的文件版本)。如果补丁无法自行应用,则此行由 git am --3way 尝试执行3路合并。


  • 接下来是两行统一差异标头

     --- a / builtin -http-fetch.c 
    +++ b / http- fetch.c

    diff -U 结果相比,它没有从文件修改时间到文件修改时间源(preimage)和目标(postimage)文件名。如果创建了文件,源文件是 / dev / null ;如果文件被删除,目标是 / dev / null
    如果你设置 diff.mnemonicPrefix 配置变量为true,代替 a / b / 前缀在这个两行标题中,您可以改为 c / i / w / o / 作为前缀,分别与您比较的内容;请参阅 git-config(1)


  • 接下来是一个或多个区别的区别;每个大块显示文件不同的一个区域。统一格式的hunks以像

     @@ -1,8 +1,9 @@ 

     @@ -18,6 +19,8 @ @ int cmd_http_fetch(int argc,const char ** argv,... 

    格式为 @@ from-file-range to-file-range @@ [header ] 。源文件范围的形式为 - < start line>,<行数> ,并且对文件范围是 +<起始行>,<行数> 。起始行和行数都是指在原像中的位置和长度postimage,如果行数未显示,则表示它为0。

    可选标题显示每个更改发生的C函数,如果它是C文件(例如GNU diff中的 -p 选项),或者其他类型文件的等效文件(如果有的话)。

  • 接下来介绍文件的不同位置,两个文件的共同行以空格字符开头,两个文件之间实际不同的行具有以下其中一个指示符cha在左侧列的栏位中:


    • '+' - 一行被添加到第一个文件中。

    • ' - ' - 一行从第一个文件中移除。



    ,第一个块

      #includecache.h
    #includewalker.h

    -int cmd_http_fetch(int argc,const char ** argv,const char * prefix)
    + int main(int argc,const char ** argv)
    {
    + const char *字首;
    struct walker * walker;
    int commits_on_stdin = 0;
    int提交;

    表示 cmd_http_fetch main ,并添加了 const char *前缀; 行。



    <换句话说,在更改之前,builtin-http-fetch.c文件的相应片段如下所示:

      #includewalker.h

    int cmd_http_fetch(int argc,const char ** argv,const char * prefix)
    {
    struct walker * walker;
    int commits_on_stdin = 0;
    int提交;

    现在'http-fetch.c'文件的这个片段变成这样:

      #includecache.h
    #includewalker.h

    int main(int argc,const char ** argv)
    {
    const char * prefix;
    struct walker * walker;
    int commits_on_stdin = 0;
    int提交;


  • 可能有

     \ \\ / pre>行存在(它不在示例差异中)。
  • https://stackoverflow.com/questions/2529441/how-to-work-with-diff-representation-in-git/2529633#2529633\"> Donal Fellows says 最好是实践阅读差异,生活的例子,你知道你已经改变了什么。



    参考文献:

  • git-diff(1)联机帮助页生成补丁与-p

  • (diff.info)Detailed Unified 节点,统一格式的详细描述。


The man page for git-diff is rather long, and explains many cases which don't seem to be necessary for a beginner. For example:

git diff origin/master

解决方案

Lets take a look at example advanced diff from git history (in commit 1088261f in git.git repository):

diff --git a/builtin-http-fetch.c b/http-fetch.c
similarity index 95%
rename from builtin-http-fetch.c
rename to http-fetch.c
index f3e63d7..e8f44ba 100644
--- a/builtin-http-fetch.c
+++ b/http-fetch.c
@@ -1,8 +1,9 @@
 #include "cache.h"
 #include "walker.h"

-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
+int main(int argc, const char **argv)
 {
+       const char *prefix;
        struct walker *walker;
        int commits_on_stdin = 0;
        int commits;
@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
        int get_verbosely = 0;
        int get_recover = 0;

+       prefix = setup_git_directory();
+
        git_config(git_default_config, NULL);

        while (arg < argc && argv[arg][0] == '-') {

Lets analyze this patch line by line.

  • The first line

    diff --git a/builtin-http-fetch.c b/http-fetch.c

    is a "git diff" header in the form diff --git a/file1 b/file2. The a/ and b/ filenames are the same unless rename/copy is involved (like in our case). The --git is to mean that diff is in the "git" diff format.

  • Next are one or more extended header lines. The first three

    similarity index 95%
    rename from builtin-http-fetch.c
    rename to http-fetch.c

    tell us that the file was renamed from builtin-http-fetch.c to http-fetch.c and that those two files are 95% identical (which was used to detect this rename).

    The last line in extended diff header, which is

    index f3e63d7..e8f44ba 100644

    tell us about mode of given file (100644 means that it is ordinary file and not e.g. symlink, and that it doesn't have executable permission bit), and about shortened hash of preimage (the version of file before given change) and postimage (the version of file after change). This line is used by git am --3way to try to do a 3-way merge if patch cannot be applied itself.

  • Next is two-line unified diff header

    --- a/builtin-http-fetch.c
    +++ b/http-fetch.c

    Compared to diff -U result it doesn't have from-file-modification-time nor to-file-modification-time after source (preimage) and destination (postimage) file names. If file was created the source is /dev/null; if file was deleted, the target is /dev/null.
    If you set diff.mnemonicPrefix configuration variable to true, in place of a/ and b/ prefixes in this two-line header you can have instead c/, i/, w/ and o/ as prefixes, respectively to what you compare; see git-config(1)

  • Next come one or more hunks of differences; each hunk shows one area where the files differ. Unified format hunks starts with line like

    @@ -1,8 +1,9 @@

    or

    @@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, ...

    It is in the format @@ from-file-range to-file-range @@ [header]. The from-file-range is in the form -<start line>,<number of lines>, and to-file-range is +<start line>,<number of lines>. Both start-line and number-of-lines refer to position and length of hunk in preimage and postimage, respectively. If number-of-lines not shown it means that it is 0.

    The optional header shows the C function where each change occurs, if it is a C file (like -p option in GNU diff), or the equivalent, if any, for other types of files.

  • Next comes the description of where files differ. The lines common to both files begin with a space character. The lines that actually differ between the two files have one of the following indicator characters in the left print column:

    • '+' -- A line was added here to the first file.
    • '-' -- A line was removed here from the first file.


    So, for example, first chunk

     #include "cache.h"
     #include "walker.h"
    
    -int cmd_http_fetch(int argc, const char **argv, const char *prefix)
    +int main(int argc, const char **argv)
     {
    +       const char *prefix;
            struct walker *walker;
            int commits_on_stdin = 0;
            int commits;
    

    means that cmd_http_fetch was replaced by main, and that const char *prefix; line was added.

    In other words, before the change, the appropriate fragment of then 'builtin-http-fetch.c' file looked like this:

    #include "cache.h"
    #include "walker.h"
    
    int cmd_http_fetch(int argc, const char **argv, const char *prefix)
    {
           struct walker *walker;
           int commits_on_stdin = 0;
           int commits;
    

    After the change this fragment of now 'http-fetch.c' file looks like this instead:

    #include "cache.h"
    #include "walker.h"
    
    int main(int argc, const char **argv)
    {
           const char *prefix;
           struct walker *walker;
           int commits_on_stdin = 0;
           int commits;
    

  • There might be

    \ No newline at end of file

    line present (it is not in example diff).

As Donal Fellows said it is best to practice reading diffs on real-life examples, where you know what you have changed.

References:

这篇关于如何读取git diff的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆