Skip to content

Instantly share code, notes, and snippets.

@otakustay
Created September 19, 2017 07:53
Show Gist options
  • Select an option

  • Save otakustay/f14721806a3030a1c00f1b212a9f1968 to your computer and use it in GitHub Desktop.

Select an option

Save otakustay/f14721806a3030a1c00f1b212a9f1968 to your computer and use it in GitHub Desktop.
Git diff format

示例:

diff --git a/alice.txt b/alice.txt
old mode 100644
new mode 100755
index 2f4a4c8..a79f9ff
--- a/alice.txt
+++ b/alice.txt
@@ -1 +1,2 @@
 What the fuck
+OK
diff --git a/bar.js b/bar.js
index 536c117..5da9b06 100644
--- a/bar.js
+++ b/bar.js
@@ -3,8 +3,11 @@ import parseDiff from '../src/parse';
 self.addEventListener(
     'message',
     ({data: {jobID, diffText, nearbySequences}}) => {
+
+        const i = 0;
+        const j = 3;
+        console.log(i + j);
+
         const diff = parseDiff(diffText, {nearbySequences});
 
         self.postMessage({jobID, diff});
-    }
-);
diff --git a/c.zip b/c.zip
old mode 100644
new mode 100755
index 310af0f..3fcdc58
Binary files a/c.zip and b/c.zip differ
diff --git a/font.woff b/font.woff
new file mode 100644
index 0000000..6afece1
Binary files /dev/null and b/font.woff differ
diff --git a/foo.js b/foo1.js
similarity index 100%
copy from foo.js
copy to foo1.js
diff --git a/foo.js b/foo2.js
old mode 100644
new mode 100755
similarity index 42%
rename from foo.js
rename to foo2.js
index 8eda104..7a21d0c
--- a/foo.js
+++ b/foo2.js
@@ -1,4 +1,4 @@
 const i = 3;
 const j = 4;
 
-export default x => () => i + j;
+export default x => () => i + j + 3;

格式

Diff由若干个File组成,每个file格式如下:

{
    oldPath: {string} // 旧文件名
    newPath: {string} // 新文件名
    oldRevision: {string} // 旧版本号
    newRevision: {string} // 新版本号
    oldMode: {string} // 旧的chmod
    newMode: {string} // 旧的chmod
    isBinary: {boolean} // 是否二进制文件
    type: {string} // 修改的形式,包含添加(Add)、修改(Modify)、复制(Copy)、移动(Rename)、删除(Delete)
    similarity: {number} // 仅在Copy和Rename时出现,两个文件的相似度,0-100的数字
    hunks: [...]
}

一个文件下有多个块(Hunk),二进制文件(isBinary === true)下Hunk数组始终为空,每一个Hunk格式如下:

{
    oldStart: {number} // 旧版对应的开始行号
    newStart: {number} // 新版对应的开始行号
    oldLines: {number} // 旧版的行数
    newLines: {number} // 新版的行数
    headerLine: {string} // 修改起始行的内容
    changes: [...]
}

一个Hunk包含多个Change,格式如下:

{
    type: {string} // 类型,为insert、delete或者normal
    isInsert: {boolean} // 对应type === insert
    isDelete: {boolean} // 对应type === delete
    isNormal: {boolean} // 对应type === normal
    oldLineNumber: {number} // 仅在normal时出现,对应旧版的行号
    newLineNumber: {number} // 仅在normal时出现,对应新版的行号
    lineNumber: {number} // 在add和delete时出现,对应行号
    content: {string} // 具体的内容
}

文件

一个典型的文件内容如下:

diff --git a/foo.js b/foo2.js
old mode 100644
new mode 100755
similarity index 42%
rename from foo.js
rename to foo2.js
index 8eda104..7a21d0c
--- a/foo.js
+++ b/foo2.js
@@ -1,4 +1,4 @@
 const i = 3;
 const j = 4;
 
-export default x => () => i + j;
+export default x => () => i + j + 3;

从上往下:

diff --git a/foo.js b/foo2.js

这一行是文件的头,以diff --git来确定文件的开始,直到下一个diff --git为止都是同一个文件

old mode 100644
new mode 100755

当文件的chmod有变化时会出现这个,此时取2个数字串为oldModenewMode这2行可能不存在

similarity index 42%
rename from foo.js
rename to foo2.js

当文件为Rename时会出现,其中可以得到similarityoldPathnewPath这2行可能不存在

如果文件为Copy,也会有类似的内容:

similarity index 100%
copy from foo.js
copy to foo1.js

再往下:

index 8eda104..7a21d0c

这一行一定会存在,这一行index后面的部分用..分隔后,能得到�oldRevisionnewRevision

如果没有前面的old mode + new mode这行的时候,会变成这样:

index 536c117..5da9b06 100644

最后那个串就是oldModenewMode的值,既chmod没有发生变化

--- a/foo.js
+++ b/foo2.js

如果这是一个Modify、Add或Delete的文件,其中第一行去掉--- a/后是oldPath,第二行用同样方法能得到newPath二进制文件没有这2行Copy和Rename且内容没变的也没有这2行

@@ -1,4 +1,4 @@
 const i = 3;
 const j = 4;
 
-export default x => () => i + j;
+export default x => () => i + j + 3;

这是一个Hunk,一个文件可能有多个Hunk,一个Hunk继续分解下去:

@@ -1,4 +1,4 @@

Hunk的头部,一定是@@ -{oldStart},{oldLines} +{newStart},{newLines} @@的格式,直接从这里面取出4个属性来

在头以后,直到下一个Hunk头或者File头为止,每一行都是一个Change,一个Change的第1个字符只能是+- (空格)三种,分别对应insert、delete、normal,第2个字符开始是这个Change的内容

Change的oldLineNumbernewLineNumberlineNumber使用Hunk的oldStartnewStart与这个Change所在的位置计算即可

其它情况

二进制文件是不会有Change和Hunk的:

diff --git a/c.zip b/c.zip
old mode 100644
new mode 100755
index 310af0f..3fcdc58
Binary files a/c.zip and b/c.zip differ

二进制文件在index xxx..xxx这一行以后的内容为:

Binary files a/c.zip and b/c.zip differ

其格式为:

Binary files a/{oldPath} and b/{newPath} differ

从其中得到oldPathnewPath后,Hunk为空数组即可

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment