pico
cmds
checkout latest patchset:
ssh pr.pico.sh print 19 | git am -3checkout any patchset in a patch request:
ssh pr.pico.sh print 19.[rev] | git am -3add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add 19set PR to open (enables RSS notifications):
ssh pr.pico.sh pr open 19set PR to draft (stops RSS notifications):
ssh pr.pico.sh pr draft 19
Patchset
19.2
feat: range diff
Eric Bower
2024-07-23T15:59:25ZSemantic diff summary
19 added,
6 modified,
0 signature changed,
1 removed
across 6 analyzed files
(10 files skipped: unsupported file type)
range_diff.go
-
type_declarationPatchRangeadded -
function_declarationNewPatchRangeadded -
function_declarationoutputadded -
function_declarationoutputPairHeaderadded -
function_declarationRangeDiffadded -
function_declarationdiffsizeadded -
function_declarationcomputeAssignmentadded -
function_declarationfindExactMatchesadded -
function_declarationcreateMatrixadded -
function_declarationgetCorrespondencesadded
range_diff_test.go
-
function_declarationcmpadded -
function_declarationfailadded -
function_declarationTestRangeDiffUnmodifiedadded -
function_declarationTestRangeDiffTrivialReorderingadded -
function_declarationTestRangeDiffRemovedCommitadded -
function_declarationTestRangeDiffAddedCommitadded -
function_declarationTestRangeDiffChangedCommitadded -
function_declarationbailadded
+6
-0
db.go
#
| ... | ... | @@ -67,6 +68,11 @@ type Patch struct { | |
| 67 | 68 | BaseCommitSha sql.NullString `db:"base_commit_sha"` | |
| 68 | 69 | RawText string `db:"raw_text"` | |
| 69 | 70 | CreatedAt time.Time `db:"created_at"` | |
| 71 | + | Files []*gitdiff.File | |
| 72 | + | } | |
| 73 | + | ||
| 74 | + | func (p *Patch) CalcDiff() string { | |
| 75 | + | return p.RawText | |
| 70 | 76 | } | |
| 71 | 77 | ||
| 72 | 78 | // EventLog is a event log for RSS or other notification systems. |
+31
-0
fixtures/a_b.patch
#
| ... | ... | @@ -0,0 +1,31 @@ | |
| 1 | + | From 33c682ac27479f501924cf159d0a75ad91deb589 Mon Sep 17 00:00:00 2001 | |
| 2 | + | From: Eric Bower <me@erock.io> | |
| 3 | + | Date: Tue, 23 Jul 2024 10:07:57 -0400 | |
| 4 | + | Subject: [PATCH] chore: add torch and create random tensor | |
| 5 | + | ||
| 6 | + | --- | |
| 7 | + | requirements.txt | 1 + | |
| 8 | + | train.py | 3 +++ | |
| 9 | + | 2 files changed, 4 insertions(+) | |
| 10 | + | create mode 100644 requirements.txt | |
| 11 | + | ||
| 12 | + | diff --git a/requirements.txt b/requirements.txt | |
| 13 | + | new file mode 100644 | |
| 14 | + | index 0000000..4968a39 | |
| 15 | + | --- /dev/null | |
| 16 | + | +++ b/requirements.txt | |
| 17 | + | @@ -0,0 +1 @@ | |
| 18 | + | +torch==2.3.1 | |
| 19 | + | diff --git a/train.py b/train.py | |
| 20 | + | index 5c027f4..d21dac3 100644 | |
| 21 | + | --- a/train.py | |
| 22 | + | +++ b/train.py | |
| 23 | + | @@ -1,2 +1,5 @@ | |
| 24 | + | +import torch | |
| 25 | + | + | |
| 26 | + | if __name__ == "__main__": | |
| 27 | + | print("train!") | |
| 28 | + | + torch.rand(3,6) | |
| 29 | + | -- | |
| 30 | + | 2.45.2 | |
| 31 | + |
+55
-0
fixtures/a_b_reorder.patch
#
| ... | ... | @@ -0,0 +1,55 @@ | |
| 1 | + | From 33c682ac27479f501924cf159d0a75ad91deb589 Mon Sep 17 00:00:00 2001 | |
| 2 | + | From: Eric Bower <me@erock.io> | |
| 3 | + | Date: Tue, 23 Jul 2024 10:07:57 -0400 | |
| 4 | + | Subject: [PATCH 1/2] chore: add torch and create random tensor | |
| 5 | + | ||
| 6 | + | --- | |
| 7 | + | requirements.txt | 1 + | |
| 8 | + | train.py | 3 +++ | |
| 9 | + | 2 files changed, 4 insertions(+) | |
| 10 | + | create mode 100644 requirements.txt | |
| 11 | + | ||
| 12 | + | diff --git a/requirements.txt b/requirements.txt | |
| 13 | + | new file mode 100644 | |
| 14 | + | index 0000000..4968a39 | |
| 15 | + | --- /dev/null | |
| 16 | + | +++ b/requirements.txt | |
| 17 | + | @@ -0,0 +1 @@ | |
| 18 | + | +torch==2.3.1 | |
| 19 | + | diff --git a/train.py b/train.py | |
| 20 | + | index 5c027f4..d21dac3 100644 | |
| 21 | + | --- a/train.py | |
| 22 | + | +++ b/train.py | |
| 23 | + | @@ -1,2 +1,5 @@ | |
| 24 | + | +import torch | |
| 25 | + | + | |
| 26 | + | if __name__ == "__main__": | |
| 27 | + | print("train!") | |
| 28 | + | + torch.rand(3,6) | |
| 29 | + | -- | |
| 30 | + | 2.45.2 | |
| 31 | + | ||
| 32 | + | ||
| 33 | + | From 22dde1259c34a166d5a9335ebe5236e79541cc63 Mon Sep 17 00:00:00 2001 | |
| 34 | + | From: Eric Bower <me@erock.io> | |
| 35 | + | Date: Tue, 23 Jul 2024 10:14:37 -0400 | |
| 36 | + | Subject: [PATCH 2/2] docs: readme | |
| 37 | + | ||
| 38 | + | --- | |
| 39 | + | README.md | 4 +++- | |
| 40 | + | 1 file changed, 3 insertions(+), 1 deletion(-) | |
| 41 | + | ||
| 42 | + | diff --git a/README.md b/README.md | |
| 43 | + | index 8f3a780..3043953 100644 | |
| 44 | + | --- a/README.md | |
| 45 | + | +++ b/README.md | |
| 46 | + | @@ -1,3 +1,5 @@ | |
| 47 | + | # Let's build an RNN | |
| 48 | + | ||
| 49 | + | -This repo demonstrates building an RNN using `pytorch` | |
| 50 | + | +This repo demonstrates building an RNN using `pytorch`. | |
| 51 | + | + | |
| 52 | + | +Here is some more readme information. | |
| 53 | + | -- | |
| 54 | + | 2.45.2 | |
| 55 | + |
+33
-0
fixtures/a_c.patch
#
| ... | ... | @@ -0,0 +1,33 @@ | |
| 1 | + | From 166848469e0b954c2e14233233f3824a46dcddb8 Mon Sep 17 00:00:00 2001 | |
| 2 | + | From: Eric Bower <me@erock.io> | |
| 3 | + | Date: Tue, 23 Jul 2024 10:06:00 -0400 | |
| 4 | + | Subject: [PATCH] chore: add torch and create random tensor | |
| 5 | + | ||
| 6 | + | --- | |
| 7 | + | requirements.txt | 1 + | |
| 8 | + | train.py | 3 +++ | |
| 9 | + | 2 files changed, 4 insertions(+) | |
| 10 | + | create mode 100644 requirements.txt | |
| 11 | + | ||
| 12 | + | diff --git a/requirements.txt b/requirements.txt | |
| 13 | + | new file mode 100644 | |
| 14 | + | index 0000000..4968a39 | |
| 15 | + | --- /dev/null | |
| 16 | + | +++ b/requirements.txt | |
| 17 | + | @@ -0,0 +1 @@ | |
| 18 | + | +torch==2.3.1 | |
| 19 | + | diff --git a/train.py b/train.py | |
| 20 | + | index 5c027f4..d21dac3 100644 | |
| 21 | + | --- a/train.py | |
| 22 | + | +++ b/train.py | |
| 23 | + | @@ -1,2 +1,5 @@ | |
| 24 | + | +import torch | |
| 25 | + | + | |
| 26 | + | if __name__ == "__main__": | |
| 27 | + | print("train!") | |
| 28 | + | + torch.rand(3,6) | |
| 29 | + | ||
| 30 | + | base-commit: 59456574a0bfee9f71c91c13046173c820152346 | |
| 31 | + | -- | |
| 32 | + | 2.45.2 | |
| 33 | + |
+80
-0
fixtures/a_c_added_commit.patch
#
| ... | ... | @@ -0,0 +1,80 @@ | |
| 1 | + | From 33c682ac27479f501924cf159d0a75ad91deb589 Mon Sep 17 00:00:00 2001 | |
| 2 | + | From: Eric Bower <me@erock.io> | |
| 3 | + | Date: Tue, 23 Jul 2024 10:07:57 -0400 | |
| 4 | + | Subject: [PATCH 1/3] chore: add torch and create random tensor | |
| 5 | + | ||
| 6 | + | --- | |
| 7 | + | requirements.txt | 1 + | |
| 8 | + | train.py | 3 +++ | |
| 9 | + | 2 files changed, 4 insertions(+) | |
| 10 | + | create mode 100644 requirements.txt | |
| 11 | + | ||
| 12 | + | diff --git a/requirements.txt b/requirements.txt | |
| 13 | + | new file mode 100644 | |
| 14 | + | index 0000000..4968a39 | |
| 15 | + | --- /dev/null | |
| 16 | + | +++ b/requirements.txt | |
| 17 | + | @@ -0,0 +1 @@ | |
| 18 | + | +torch==2.3.1 | |
| 19 | + | diff --git a/train.py b/train.py | |
| 20 | + | index 5c027f4..d21dac3 100644 | |
| 21 | + | --- a/train.py | |
| 22 | + | +++ b/train.py | |
| 23 | + | @@ -1,2 +1,5 @@ | |
| 24 | + | +import torch | |
| 25 | + | + | |
| 26 | + | if __name__ == "__main__": | |
| 27 | + | print("train!") | |
| 28 | + | + torch.rand(3,6) | |
| 29 | + | -- | |
| 30 | + | 2.45.2 | |
| 31 | + | ||
| 32 | + | ||
| 33 | + | From 22dde1259c34a166d5a9335ebe5236e79541cc63 Mon Sep 17 00:00:00 2001 | |
| 34 | + | From: Eric Bower <me@erock.io> | |
| 35 | + | Date: Tue, 23 Jul 2024 10:14:37 -0400 | |
| 36 | + | Subject: [PATCH 2/3] docs: readme | |
| 37 | + | ||
| 38 | + | --- | |
| 39 | + | README.md | 4 +++- | |
| 40 | + | 1 file changed, 3 insertions(+), 1 deletion(-) | |
| 41 | + | ||
| 42 | + | diff --git a/README.md b/README.md | |
| 43 | + | index 8f3a780..3043953 100644 | |
| 44 | + | --- a/README.md | |
| 45 | + | +++ b/README.md | |
| 46 | + | @@ -1,3 +1,5 @@ | |
| 47 | + | # Let's build an RNN | |
| 48 | + | ||
| 49 | + | -This repo demonstrates building an RNN using `pytorch` | |
| 50 | + | +This repo demonstrates building an RNN using `pytorch`. | |
| 51 | + | + | |
| 52 | + | +Here is some more readme information. | |
| 53 | + | -- | |
| 54 | + | 2.45.2 | |
| 55 | + | ||
| 56 | + | ||
| 57 | + | From b248060488df529b850060b3c86417bb87d490cc Mon Sep 17 00:00:00 2001 | |
| 58 | + | From: Eric Bower <me@erock.io> | |
| 59 | + | Date: Tue, 23 Jul 2024 10:20:44 -0400 | |
| 60 | + | Subject: [PATCH 3/3] chore: make tensor 6x6 | |
| 61 | + | ||
| 62 | + | --- | |
| 63 | + | train.py | 4 +++- | |
| 64 | + | 1 file changed, 3 insertions(+), 1 deletion(-) | |
| 65 | + | ||
| 66 | + | diff --git a/train.py b/train.py | |
| 67 | + | index d21dac3..8cd47e0 100644 | |
| 68 | + | --- a/train.py | |
| 69 | + | +++ b/train.py | |
| 70 | + | @@ -2,4 +2,6 @@ import torch | |
| 71 | + | ||
| 72 | + | if __name__ == "__main__": | |
| 73 | + | print("train!") | |
| 74 | + | - torch.rand(3,6) | |
| 75 | + | + # let's create a 6x6 tensor! | |
| 76 | + | + tensor = torch.rand(6,6) | |
| 77 | + | + print(tensor) | |
| 78 | + | -- | |
| 79 | + | 2.45.2 | |
| 80 | + |
+60
-0
fixtures/a_c_changed_commit.patch
#
| ... | ... | @@ -0,0 +1,60 @@ | |
| 1 | + | From 33c682ac27479f501924cf159d0a75ad91deb589 Mon Sep 17 00:00:00 2001 | |
| 2 | + | From: Eric Bower <me@erock.io> | |
| 3 | + | Date: Tue, 23 Jul 2024 10:07:57 -0400 | |
| 4 | + | Subject: [PATCH 1/2] chore: add torch and create random tensor | |
| 5 | + | ||
| 6 | + | --- | |
| 7 | + | requirements.txt | 1 + | |
| 8 | + | train.py | 3 +++ | |
| 9 | + | 2 files changed, 4 insertions(+) | |
| 10 | + | create mode 100644 requirements.txt | |
| 11 | + | ||
| 12 | + | diff --git a/requirements.txt b/requirements.txt | |
| 13 | + | new file mode 100644 | |
| 14 | + | index 0000000..4968a39 | |
| 15 | + | --- /dev/null | |
| 16 | + | +++ b/requirements.txt | |
| 17 | + | @@ -0,0 +1 @@ | |
| 18 | + | +torch==2.3.1 | |
| 19 | + | diff --git a/train.py b/train.py | |
| 20 | + | index 5c027f4..d21dac3 100644 | |
| 21 | + | --- a/train.py | |
| 22 | + | +++ b/train.py | |
| 23 | + | @@ -1,2 +1,5 @@ | |
| 24 | + | +import torch | |
| 25 | + | + | |
| 26 | + | if __name__ == "__main__": | |
| 27 | + | print("train!") | |
| 28 | + | + torch.rand(3,6) | |
| 29 | + | -- | |
| 30 | + | 2.45.2 | |
| 31 | + | ||
| 32 | + | ||
| 33 | + | From dce20e70280d92aeb88c3d603ad67043ead772fb Mon Sep 17 00:00:00 2001 | |
| 34 | + | From: Eric Bower <me@erock.io> | |
| 35 | + | Date: Tue, 23 Jul 2024 10:14:37 -0400 | |
| 36 | + | Subject: [PATCH 2/2] docs: readme | |
| 37 | + | ||
| 38 | + | --- | |
| 39 | + | README.md | 9 ++++++++- | |
| 40 | + | 1 file changed, 8 insertions(+), 1 deletion(-) | |
| 41 | + | ||
| 42 | + | diff --git a/README.md b/README.md | |
| 43 | + | index 8f3a780..ba0293b 100644 | |
| 44 | + | --- a/README.md | |
| 45 | + | +++ b/README.md | |
| 46 | + | @@ -1,3 +1,10 @@ | |
| 47 | + | # Let's build an RNN | |
| 48 | + | ||
| 49 | + | -This repo demonstrates building an RNN using `pytorch` | |
| 50 | + | +This repo demonstrates building an RNN using `pytorch`. | |
| 51 | + | + | |
| 52 | + | +Here is some more readme information. | |
| 53 | + | + | |
| 54 | + | +Here is how to run this project locally: | |
| 55 | + | + | |
| 56 | + | +- install python and pip | |
| 57 | + | +- `pip install -r requirements.txt` | |
| 58 | + | -- | |
| 59 | + | 2.45.2 | |
| 60 | + |
+55
-0
fixtures/a_c_reorder.patch
#
| ... | ... | @@ -0,0 +1,55 @@ | |
| 1 | + | From 7dbb94ca1bc8cadf1ce17dacb89172217d88de07 Mon Sep 17 00:00:00 2001 | |
| 2 | + | From: Eric Bower <me@erock.io> | |
| 3 | + | Date: Tue, 23 Jul 2024 10:15:23 -0400 | |
| 4 | + | Subject: [PATCH 1/2] docs: readme | |
| 5 | + | ||
| 6 | + | --- | |
| 7 | + | README.md | 4 +++- | |
| 8 | + | 1 file changed, 3 insertions(+), 1 deletion(-) | |
| 9 | + | ||
| 10 | + | diff --git a/README.md b/README.md | |
| 11 | + | index 8f3a780..3043953 100644 | |
| 12 | + | --- a/README.md | |
| 13 | + | +++ b/README.md | |
| 14 | + | @@ -1,3 +1,5 @@ | |
| 15 | + | # Let's build an RNN | |
| 16 | + | ||
| 17 | + | -This repo demonstrates building an RNN using `pytorch` | |
| 18 | + | +This repo demonstrates building an RNN using `pytorch`. | |
| 19 | + | + | |
| 20 | + | +Here is some more readme information. | |
| 21 | + | -- | |
| 22 | + | 2.45.2 | |
| 23 | + | ||
| 24 | + | ||
| 25 | + | From ad175875e2bf320859554bae73743675cc5ce444 Mon Sep 17 00:00:00 2001 | |
| 26 | + | From: Eric Bower <me@erock.io> | |
| 27 | + | Date: Tue, 23 Jul 2024 10:06:00 -0400 | |
| 28 | + | Subject: [PATCH 2/2] chore: add torch and create random tensor | |
| 29 | + | ||
| 30 | + | --- | |
| 31 | + | requirements.txt | 1 + | |
| 32 | + | train.py | 3 +++ | |
| 33 | + | 2 files changed, 4 insertions(+) | |
| 34 | + | create mode 100644 requirements.txt | |
| 35 | + | ||
| 36 | + | diff --git a/requirements.txt b/requirements.txt | |
| 37 | + | new file mode 100644 | |
| 38 | + | index 0000000..4968a39 | |
| 39 | + | --- /dev/null | |
| 40 | + | +++ b/requirements.txt | |
| 41 | + | @@ -0,0 +1 @@ | |
| 42 | + | +torch==2.3.1 | |
| 43 | + | diff --git a/train.py b/train.py | |
| 44 | + | index 5c027f4..d21dac3 100644 | |
| 45 | + | --- a/train.py | |
| 46 | + | +++ b/train.py | |
| 47 | + | @@ -1,2 +1,5 @@ | |
| 48 | + | +import torch | |
| 49 | + | + | |
| 50 | + | if __name__ == "__main__": | |
| 51 | + | print("train!") | |
| 52 | + | + torch.rand(3,6) | |
| 53 | + | -- | |
| 54 | + | 2.45.2 | |
| 55 | + |
+23
-0
fixtures/a_c_rm_commit.patch
#
| ... | ... | @@ -0,0 +1,23 @@ | |
| 1 | + | From 7dbb94ca1bc8cadf1ce17dacb89172217d88de07 Mon Sep 17 00:00:00 2001 | |
| 2 | + | From: Eric Bower <me@erock.io> | |
| 3 | + | Date: Tue, 23 Jul 2024 10:15:23 -0400 | |
| 4 | + | Subject: [PATCH] docs: readme | |
| 5 | + | ||
| 6 | + | --- | |
| 7 | + | README.md | 4 +++- | |
| 8 | + | 1 file changed, 3 insertions(+), 1 deletion(-) | |
| 9 | + | ||
| 10 | + | diff --git a/README.md b/README.md | |
| 11 | + | index 8f3a780..3043953 100644 | |
| 12 | + | --- a/README.md | |
| 13 | + | +++ b/README.md | |
| 14 | + | @@ -1,3 +1,5 @@ | |
| 15 | + | # Let's build an RNN | |
| 16 | + | ||
| 17 | + | -This repo demonstrates building an RNN using `pytorch` | |
| 18 | + | +This repo demonstrates building an RNN using `pytorch`. | |
| 19 | + | + | |
| 20 | + | +Here is some more readme information. | |
| 21 | + | -- | |
| 22 | + | 2.45.2 | |
| 23 | + |
+11
-0
fixtures/expected_commit_changed.txt
#
| ... | ... | @@ -0,0 +1,11 @@ | |
| 1 | + | 1: 33c682a = 1: 33c682a chore: add torch and create random tensor | |
| 2 | + | 2: 22dde12 ! 2: 0185f34 docs: readme | |
| 3 | + | @@ README.md | |
| 4 | + | +This repo demonstrates building an RNN using `pytorch`. | |
| 5 | + | + | |
| 6 | + | +Here is some more readme information. | |
| 7 | + | ++ | |
| 8 | + | ++Here is how to run this project locally: | |
| 9 | + | ++ | |
| 10 | + | ++- install python and pip | |
| 11 | + | ++- `pip install -r requirements.txt` |
+1
-0
go.mod
#
| ... | ... | @@ -14,6 +14,7 @@ require ( | |
| 14 | 14 | github.com/knadh/koanf/providers/env v0.1.0 | |
| 15 | 15 | github.com/knadh/koanf/providers/file v1.0.0 | |
| 16 | 16 | github.com/knadh/koanf/v2 v2.1.1 | |
| 17 | + | github.com/sergi/go-diff v1.1.0 | |
| 17 | 18 | github.com/urfave/cli/v2 v2.27.2 | |
| 18 | 19 | golang.org/x/crypto v0.21.0 | |
| 19 | 20 | modernc.org/sqlite v1.27.0 |
+13
-2
go.sum
#
| ... | ... | @@ -8,8 +8,6 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI | |
| 8 | 8 | github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= | |
| 9 | 9 | github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= | |
| 10 | 10 | github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= | |
| 11 | - | github.com/bluekeyes/go-gitdiff v0.7.2 h1:42jrcVZdjjxXtVsFNYTo/I6T1ZvIiQL+iDDLiH904hw= | |
| 12 | - | github.com/bluekeyes/go-gitdiff v0.7.2/go.mod h1:QpfYYO1E0fTVHVZAZKiRjtSGY9823iCdvGXBcEzHGbM= | |
| 13 | 11 | github.com/bluekeyes/go-gitdiff v0.7.4-0.20240715034416-0a4e55f9a190 h1:k6Ep4yQtmsoP/St4bf7ofXyWc6ITB/FyGy9ewaAn5os= | |
| 14 | 12 | github.com/bluekeyes/go-gitdiff v0.7.4-0.20240715034416-0a4e55f9a190/go.mod h1:QpfYYO1E0fTVHVZAZKiRjtSGY9823iCdvGXBcEzHGbM= | |
| 15 | 13 | github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= |
| ... | ... | @@ -36,6 +34,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lV | |
| 36 | 34 | github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= | |
| 37 | 35 | github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= | |
| 38 | 36 | github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= | |
| 37 | + | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | |
| 39 | 38 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | |
| 40 | 39 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | |
| 41 | 40 | github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= |
| ... | ... | @@ -74,8 +73,11 @@ github.com/knadh/koanf/providers/file v1.0.0 h1:DtPvSQBeF+N0QLPMz0yf2bx0nFSxUcnc | |
| 74 | 73 | github.com/knadh/koanf/providers/file v1.0.0/go.mod h1:/faSBcv2mxPVjFrXck95qeoyoZ5myJ6uxN8OOVNJJCI= | |
| 75 | 74 | github.com/knadh/koanf/v2 v2.1.1 h1:/R8eXqasSTsmDCsAyYj+81Wteg8AqrV9CP6gvsTsOmM= | |
| 76 | 75 | github.com/knadh/koanf/v2 v2.1.1/go.mod h1:4mnTRbZCK+ALuBXHZMjDfG9y714L7TykVnZkXbMU3Es= | |
| 76 | + | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | |
| 77 | 77 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | |
| 78 | 78 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= | |
| 79 | + | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | |
| 80 | + | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | |
| 79 | 81 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | |
| 80 | 82 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | |
| 81 | 83 | github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= |
| ... | ... | @@ -107,6 +109,7 @@ github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo | |
| 107 | 109 | github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= | |
| 108 | 110 | github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= | |
| 109 | 111 | github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= | |
| 112 | + | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | |
| 110 | 113 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= | |
| 111 | 114 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | |
| 112 | 115 | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= |
| ... | ... | @@ -119,6 +122,10 @@ github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDN | |
| 119 | 122 | github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= | |
| 120 | 123 | github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= | |
| 121 | 124 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | |
| 125 | + | github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= | |
| 126 | + | github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= | |
| 127 | + | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | |
| 128 | + | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | |
| 122 | 129 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= | |
| 123 | 130 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | |
| 124 | 131 | github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI= |
| ... | ... | @@ -143,6 +150,10 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= | |
| 143 | 150 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= | |
| 144 | 151 | golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= | |
| 145 | 152 | golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= | |
| 153 | + | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |
| 154 | + | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |
| 155 | + | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | |
| 156 | + | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | |
| 146 | 157 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | |
| 147 | 158 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | |
| 148 | 159 | lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= |
+2
-2
pr.go
#
+219
-0
range_diff.go
#
| ... | ... | @@ -0,0 +1,219 @@ | |
| 1 | + | package git | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "fmt" | |
| 5 | + | "math" | |
| 6 | + | ||
| 7 | + | "github.com/sergi/go-diff/diffmatchpatch" | |
| 8 | + | ) | |
| 9 | + | ||
| 10 | + | var COST_MAX = 65536 | |
| 11 | + | var RANGE_DIFF_CREATION_FACTOR_DEFAULT = 60 | |
| 12 | + | ||
| 13 | + | type PatchRange struct { | |
| 14 | + | *Patch | |
| 15 | + | Matching int | |
| 16 | + | Diff string | |
| 17 | + | DiffSize int | |
| 18 | + | Shown bool | |
| 19 | + | } | |
| 20 | + | ||
| 21 | + | func NewPatchRange(patch *Patch) *PatchRange { | |
| 22 | + | diff := patch.CalcDiff() | |
| 23 | + | return &PatchRange{ | |
| 24 | + | Patch: patch, | |
| 25 | + | Matching: -1, | |
| 26 | + | Diff: diff, | |
| 27 | + | DiffSize: len(diff), | |
| 28 | + | Shown: false, | |
| 29 | + | } | |
| 30 | + | } | |
| 31 | + | ||
| 32 | + | func output(a []*PatchRange, b []*PatchRange) string { | |
| 33 | + | out := "" | |
| 34 | + | for i, patchA := range a { | |
| 35 | + | if patchA.Matching == -1 { | |
| 36 | + | out += outputPairHeader(patchA, nil, i+1, -1) | |
| 37 | + | } | |
| 38 | + | } | |
| 39 | + | ||
| 40 | + | for j, patchB := range b { | |
| 41 | + | if patchB.Matching == -1 { | |
| 42 | + | out += outputPairHeader(nil, patchB, -1, j+1) | |
| 43 | + | continue | |
| 44 | + | } | |
| 45 | + | patchA := a[patchB.Matching] | |
| 46 | + | if patchB.ContentSha == patchA.ContentSha { | |
| 47 | + | out += outputPairHeader(patchA, patchB, patchB.Matching+1, patchA.Matching+1) | |
| 48 | + | } | |
| 49 | + | } | |
| 50 | + | return out | |
| 51 | + | } | |
| 52 | + | ||
| 53 | + | func outputPairHeader(a *PatchRange, b *PatchRange, aIndex, bIndex int) string { | |
| 54 | + | if a == nil { | |
| 55 | + | return fmt.Sprintf("-: ------- > %d: %s %s\n", bIndex, truncateSha(b.CommitSha), b.Title) | |
| 56 | + | } | |
| 57 | + | if b == nil { | |
| 58 | + | return fmt.Sprintf("%d: %s < -: ------- %s\n", aIndex, truncateSha(a.CommitSha), a.Title) | |
| 59 | + | } | |
| 60 | + | return fmt.Sprintf("%d: %s = %d: %s %s\n", aIndex, truncateSha(a.CommitSha), bIndex, truncateSha(b.CommitSha), a.Title) | |
| 61 | + | } | |
| 62 | + | ||
| 63 | + | func RangeDiff(a []*Patch, b []*Patch) string { | |
| 64 | + | aPatches := []*PatchRange{} | |
| 65 | + | for _, patch := range a { | |
| 66 | + | aPatches = append(aPatches, NewPatchRange(patch)) | |
| 67 | + | } | |
| 68 | + | bPatches := []*PatchRange{} | |
| 69 | + | for _, patch := range b { | |
| 70 | + | bPatches = append(bPatches, NewPatchRange(patch)) | |
| 71 | + | } | |
| 72 | + | findExactMatches(aPatches, bPatches) | |
| 73 | + | getCorrespondences(aPatches, bPatches, RANGE_DIFF_CREATION_FACTOR_DEFAULT) | |
| 74 | + | return output(aPatches, bPatches) | |
| 75 | + | } | |
| 76 | + | ||
| 77 | + | func findExactMatches(a []*PatchRange, b []*PatchRange) { | |
| 78 | + | for i, patchA := range a { | |
| 79 | + | for j, patchB := range b { | |
| 80 | + | if patchA.ContentSha == patchB.ContentSha { | |
| 81 | + | patchA.Matching = j | |
| 82 | + | patchB.Matching = i | |
| 83 | + | } | |
| 84 | + | } | |
| 85 | + | } | |
| 86 | + | } | |
| 87 | + | ||
| 88 | + | func createMatrix(rows, cols int) [][]int { | |
| 89 | + | mat := make([][]int, rows) | |
| 90 | + | for i := range mat { | |
| 91 | + | mat[i] = make([]int, cols) | |
| 92 | + | } | |
| 93 | + | return mat | |
| 94 | + | } | |
| 95 | + | ||
| 96 | + | func diffsize(a *PatchRange, b *PatchRange) int { | |
| 97 | + | dmp := diffmatchpatch.New() | |
| 98 | + | diffs := dmp.DiffMain(a.Diff, b.Diff, false) | |
| 99 | + | return len(dmp.DiffPrettyText(diffs)) | |
| 100 | + | } | |
| 101 | + | ||
| 102 | + | func getCorrespondences(a []*PatchRange, b []*PatchRange, creationFactor int) { | |
| 103 | + | n := len(a) + len(b) | |
| 104 | + | fmt.Println("rows", len(a), "cols", len(b)) | |
| 105 | + | cost := createMatrix(n, n) | |
| 106 | + | ||
| 107 | + | for i, patchA := range a { | |
| 108 | + | var c int | |
| 109 | + | for j, patchB := range b { | |
| 110 | + | if patchA.Matching == j { | |
| 111 | + | c = 0 | |
| 112 | + | } else if patchA.Matching == -1 && patchB.Matching == -1 { | |
| 113 | + | c = diffsize(patchA, patchB) | |
| 114 | + | } else { | |
| 115 | + | c = COST_MAX | |
| 116 | + | } | |
| 117 | + | cost[i][j] = c | |
| 118 | + | } | |
| 119 | + | } | |
| 120 | + | ||
| 121 | + | for j, patchB := range b { | |
| 122 | + | creationCost := (patchB.DiffSize * creationFactor) / 100 | |
| 123 | + | if patchB.Matching >= 0 { | |
| 124 | + | creationCost = math.MaxInt32 | |
| 125 | + | } | |
| 126 | + | for i := len(a); i < n; i++ { | |
| 127 | + | cost[i][j] = creationCost | |
| 128 | + | } | |
| 129 | + | } | |
| 130 | + | ||
| 131 | + | for i := len(a); i < n; i++ { | |
| 132 | + | for j := len(b); j < n; j++ { | |
| 133 | + | cost[i][j] = 0 | |
| 134 | + | } | |
| 135 | + | } | |
| 136 | + | ||
| 137 | + | assignment := computeAssignment(cost, n, n) | |
| 138 | + | for i, j := range assignment { | |
| 139 | + | if i < len(a) && j < len(b) { | |
| 140 | + | a[i].Matching = j | |
| 141 | + | b[j].Matching = i | |
| 142 | + | } | |
| 143 | + | } | |
| 144 | + | ||
| 145 | + | fmt.Println("cost", cost, "assignment", assignment) | |
| 146 | + | } | |
| 147 | + | ||
| 148 | + | // computeAssignment assigns patches using the Hungarian algorithm. | |
| 149 | + | func computeAssignment(costMatrix [][]int, m, n int) []int { | |
| 150 | + | u := make([]int, m+1) // potential for workers | |
| 151 | + | v := make([]int, n+1) // potential for jobs | |
| 152 | + | p := make([]int, n+1) // job assignment | |
| 153 | + | way := make([]int, n+1) | |
| 154 | + | ||
| 155 | + | for i := 1; i <= m; i++ { | |
| 156 | + | links := make([]int, n+1) | |
| 157 | + | minV := make([]int, n+1) | |
| 158 | + | used := make([]bool, n+1) | |
| 159 | + | for j := 0; j <= n; j++ { | |
| 160 | + | minV[j] = math.MaxInt32 | |
| 161 | + | used[j] = false | |
| 162 | + | } | |
| 163 | + | ||
| 164 | + | j0 := 0 | |
| 165 | + | p[0] = i | |
| 166 | + | ||
| 167 | + | for { | |
| 168 | + | used[j0] = true | |
| 169 | + | i0 := p[j0] | |
| 170 | + | delta := math.MaxInt32 | |
| 171 | + | j1 := 0 | |
| 172 | + | ||
| 173 | + | for j := 1; j <= n; j++ { | |
| 174 | + | if !used[j] { | |
| 175 | + | cur := costMatrix[i0-1][j-1] - u[i0] - v[j] | |
| 176 | + | if cur < minV[j] { | |
| 177 | + | minV[j] = cur | |
| 178 | + | links[j] = j0 | |
| 179 | + | } | |
| 180 | + | if minV[j] < delta { | |
| 181 | + | delta = minV[j] | |
| 182 | + | j1 = j | |
| 183 | + | } | |
| 184 | + | } | |
| 185 | + | } | |
| 186 | + | ||
| 187 | + | for j := 0; j <= n; j++ { | |
| 188 | + | if used[j] { | |
| 189 | + | u[p[j]] += delta | |
| 190 | + | v[j] -= delta | |
| 191 | + | } else { | |
| 192 | + | minV[j] -= delta | |
| 193 | + | } | |
| 194 | + | } | |
| 195 | + | ||
| 196 | + | j0 = j1 | |
| 197 | + | if p[j0] == 0 { | |
| 198 | + | break | |
| 199 | + | } | |
| 200 | + | } | |
| 201 | + | ||
| 202 | + | for { | |
| 203 | + | j1 := way[j0] | |
| 204 | + | p[j0] = p[j1] | |
| 205 | + | j0 = j1 | |
| 206 | + | if j0 == 0 { | |
| 207 | + | break | |
| 208 | + | } | |
| 209 | + | } | |
| 210 | + | } | |
| 211 | + | ||
| 212 | + | assignment := make([]int, m) | |
| 213 | + | for j := 1; j <= n; j++ { | |
| 214 | + | if p[j] > 0 { | |
| 215 | + | assignment[p[j]-1] = j - 1 | |
| 216 | + | } | |
| 217 | + | } | |
| 218 | + | return assignment | |
| 219 | + | } |
+276
-0
range_diff_test.go
#
| ... | ... | @@ -0,0 +1,276 @@ | |
| 1 | + | package git | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "fmt" | |
| 5 | + | "testing" | |
| 6 | + | ||
| 7 | + | "github.com/picosh/git-pr/fixtures" | |
| 8 | + | ) | |
| 9 | + | ||
| 10 | + | func bail(err error) { | |
| 11 | + | if err != nil { | |
| 12 | + | panic(bail) | |
| 13 | + | } | |
| 14 | + | } | |
| 15 | + | ||
| 16 | + | func cmp(afile, bfile string) string { | |
| 17 | + | a, err := fixtures.Fixtures.Open(afile) | |
| 18 | + | bail(err) | |
| 19 | + | b, err := fixtures.Fixtures.Open(bfile) | |
| 20 | + | bail(err) | |
| 21 | + | aPatches, err := ParsePatchset(a) | |
| 22 | + | bail(err) | |
| 23 | + | bPatches, err := ParsePatchset(b) | |
| 24 | + | bail(err) | |
| 25 | + | actual := RangeDiff(aPatches, bPatches) | |
| 26 | + | return actual | |
| 27 | + | } | |
| 28 | + | ||
| 29 | + | func fail(expected, actual string) string { | |
| 30 | + | return fmt.Sprintf("expected:[%s] actual:[%s]", expected, actual) | |
| 31 | + | } | |
| 32 | + | ||
| 33 | + | // https://git.kernel.org/tree/t/t3206-range-diff.sh?id=d19b6cd2dd72dc811f19df4b32c7ed223256c3ee | |
| 34 | + | ||
| 35 | + | // simple A..B A..C (unmodified) | |
| 36 | + | /* | |
| 37 | + | 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/ | |
| 38 | + | 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/ | |
| 39 | + | 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/ | |
| 40 | + | 4: $(test_oid t4) = 4: $(test_oid u4) s/12/B/ | |
| 41 | + | */ | |
| 42 | + | func TestRangeDiffUnmodified(t *testing.T) { | |
| 43 | + | actual := cmp("a_b.patch", "a_c.patch") | |
| 44 | + | expected := "1: 33c682a = 1: 1668484 chore: add torch and create random tensor\n" | |
| 45 | + | if expected != actual { | |
| 46 | + | t.Fatalf(fail(expected, actual)) | |
| 47 | + | } | |
| 48 | + | } | |
| 49 | + | ||
| 50 | + | // trivial reordering | |
| 51 | + | /* | |
| 52 | + | 1: $(test_oid t1) = 1: $(test_oid r1) s/5/A/ | |
| 53 | + | 3: $(test_oid t3) = 2: $(test_oid r2) s/11/B/ | |
| 54 | + | 4: $(test_oid t4) = 3: $(test_oid r3) s/12/B/ | |
| 55 | + | 2: $(test_oid t2) = 4: $(test_oid r4) s/4/A/ | |
| 56 | + | */ | |
| 57 | + | func TestRangeDiffTrivialReordering(t *testing.T) { | |
| 58 | + | actual := cmp("a_b_reorder.patch", "a_c_reorder.patch") | |
| 59 | + | expected := `2: 22dde12 = 1: 7dbb94c docs: readme | |
| 60 | + | 1: 33c682a = 2: ad17587 chore: add torch and create random tensor | |
| 61 | + | ` | |
| 62 | + | if expected != actual { | |
| 63 | + | t.Fatalf(fail(expected, actual)) | |
| 64 | + | } | |
| 65 | + | } | |
| 66 | + | ||
| 67 | + | // removed commit | |
| 68 | + | /* | |
| 69 | + | 1: $(test_oid t1) = 1: $(test_oid d1) s/5/A/ | |
| 70 | + | 2: $(test_oid t2) < -: $(test_oid __) s/4/A/ | |
| 71 | + | 3: $(test_oid t3) = 2: $(test_oid d2) s/11/B/ | |
| 72 | + | 4: $(test_oid t4) = 3: $(test_oid d3) s/12/B/ | |
| 73 | + | */ | |
| 74 | + | func TestRangeDiffRemovedCommit(t *testing.T) { | |
| 75 | + | actual := cmp("a_b_reorder.patch", "a_c_rm_commit.patch") | |
| 76 | + | expected := `1: 33c682a < -: ------- chore: add torch and create random tensor | |
| 77 | + | 2: 22dde12 = 1: 7dbb94c docs: readme | |
| 78 | + | ` | |
| 79 | + | if expected != actual { | |
| 80 | + | t.Fatalf(fail(expected, actual)) | |
| 81 | + | } | |
| 82 | + | } | |
| 83 | + | ||
| 84 | + | // added commit | |
| 85 | + | /* | |
| 86 | + | 1: $(test_oid t1) = 1: $(test_oid a1) s/5/A/ | |
| 87 | + | 2: $(test_oid t2) = 2: $(test_oid a2) s/4/A/ | |
| 88 | + | -: $(test_oid __) > 3: $(test_oid a3) s/6/A/ | |
| 89 | + | 3: $(test_oid t3) = 4: $(test_oid a4) s/11/B/ | |
| 90 | + | 4: $(test_oid t4) = 5: $(test_oid a5) s/12/B/ | |
| 91 | + | */ | |
| 92 | + | func TestRangeDiffAddedCommit(t *testing.T) { | |
| 93 | + | actual := cmp("a_b_reorder.patch", "a_c_added_commit.patch") | |
| 94 | + | expected := `1: 33c682a = 1: 33c682a chore: add torch and create random tensor | |
| 95 | + | 2: 22dde12 = 2: 22dde12 docs: readme | |
| 96 | + | -: ------- > 3: b248060 chore: make tensor 6x6 | |
| 97 | + | ` | |
| 98 | + | if expected != actual { | |
| 99 | + | t.Fatalf(fail(expected, actual)) | |
| 100 | + | } | |
| 101 | + | } | |
| 102 | + | ||
| 103 | + | // changed commit | |
| 104 | + | /* | |
| 105 | + | 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/ | |
| 106 | + | 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/ | |
| 107 | + | 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/ | |
| 108 | + | @@ file: A | |
| 109 | + | 9 | |
| 110 | + | 10 | |
| 111 | + | -11 | |
| 112 | + | -+B | |
| 113 | + | ++BB | |
| 114 | + | 12 | |
| 115 | + | 13 | |
| 116 | + | 14 | |
| 117 | + | 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/ | |
| 118 | + | @@ file | |
| 119 | + | @@ file: A | |
| 120 | + | 9 | |
| 121 | + | 10 | |
| 122 | + | - B | |
| 123 | + | + BB | |
| 124 | + | -12 | |
| 125 | + | +B | |
| 126 | + | 13 | |
| 127 | + | */ | |
| 128 | + | func TestRangeDiffChangedCommit(t *testing.T) { | |
| 129 | + | actual := cmp("a_b_reorder.patch", "a_c_changed_commit.patch") | |
| 130 | + | fp, err := fixtures.Fixtures.ReadFile("expected_commit_changed.txt") | |
| 131 | + | if err != nil { | |
| 132 | + | t.Fatalf("file not found") | |
| 133 | + | } | |
| 134 | + | expected := string(fp) | |
| 135 | + | if expected != actual { | |
| 136 | + | t.Fatalf(fail(expected, actual)) | |
| 137 | + | } | |
| 138 | + | } | |
| 139 | + | ||
| 140 | + | // renamed file | |
| 141 | + | /* | |
| 142 | + | 1: $(test_oid t1) = 1: $(test_oid n1) s/5/A/ | |
| 143 | + | 2: $(test_oid t2) ! 2: $(test_oid n2) s/4/A/ | |
| 144 | + | @@ Metadata | |
| 145 | + | ZAuthor: Thomas Rast <trast@inf.ethz.ch> | |
| 146 | + | Z | |
| 147 | + | Z ## Commit message ## | |
| 148 | + | - s/4/A/ | |
| 149 | + | + s/4/A/ + rename file | |
| 150 | + | Z | |
| 151 | + | - ## file ## | |
| 152 | + | + ## file => renamed-file ## | |
| 153 | + | Z@@ | |
| 154 | + | Z 1 | |
| 155 | + | Z 2 | |
| 156 | + | 3: $(test_oid t3) ! 3: $(test_oid n3) s/11/B/ | |
| 157 | + | @@ Metadata | |
| 158 | + | Z ## Commit message ## | |
| 159 | + | Z s/11/B/ | |
| 160 | + | Z | |
| 161 | + | - ## file ## | |
| 162 | + | -@@ file: A | |
| 163 | + | + ## renamed-file ## | |
| 164 | + | +@@ renamed-file: A | |
| 165 | + | Z 8 | |
| 166 | + | Z 9 | |
| 167 | + | Z 10 | |
| 168 | + | 4: $(test_oid t4) ! 4: $(test_oid n4) s/12/B/ | |
| 169 | + | @@ Metadata | |
| 170 | + | Z ## Commit message ## | |
| 171 | + | Z s/12/B/ | |
| 172 | + | Z | |
| 173 | + | - ## file ## | |
| 174 | + | -@@ file: A | |
| 175 | + | + ## renamed-file ## | |
| 176 | + | +@@ renamed-file: A | |
| 177 | + | Z 9 | |
| 178 | + | Z 10 | |
| 179 | + | Z B | |
| 180 | + | */ | |
| 181 | + | // func TestRangeDiffRenamedFile(t *testing.T) {} | |
| 182 | + | ||
| 183 | + | // file with mode only change | |
| 184 | + | /* | |
| 185 | + | 1: $(test_oid t2) ! 1: $(test_oid o1) s/4/A/ | |
| 186 | + | @@ Metadata | |
| 187 | + | ZAuthor: Thomas Rast <trast@inf.ethz.ch> | |
| 188 | + | Z | |
| 189 | + | Z ## Commit message ## | |
| 190 | + | - s/4/A/ | |
| 191 | + | + s/4/A/ + add other-file | |
| 192 | + | Z | |
| 193 | + | Z ## file ## | |
| 194 | + | Z@@ | |
| 195 | + | @@ file | |
| 196 | + | Z A | |
| 197 | + | Z 6 | |
| 198 | + | Z 7 | |
| 199 | + | + | |
| 200 | + | + ## other-file (new) ## | |
| 201 | + | 2: $(test_oid t3) ! 2: $(test_oid o2) s/11/B/ | |
| 202 | + | @@ Metadata | |
| 203 | + | ZAuthor: Thomas Rast <trast@inf.ethz.ch> | |
| 204 | + | Z | |
| 205 | + | Z ## Commit message ## | |
| 206 | + | - s/11/B/ | |
| 207 | + | + s/11/B/ + mode change other-file | |
| 208 | + | Z | |
| 209 | + | Z ## file ## | |
| 210 | + | Z@@ file: A | |
| 211 | + | @@ file: A | |
| 212 | + | Z 12 | |
| 213 | + | Z 13 | |
| 214 | + | Z 14 | |
| 215 | + | + | |
| 216 | + | + ## other-file (mode change 100644 => 100755) ## | |
| 217 | + | 3: $(test_oid t4) = 3: $(test_oid o3) s/12/B/ | |
| 218 | + | */ | |
| 219 | + | // func TestRangeDiffFileWithModeOnlyChange(t *testing.T) {} | |
| 220 | + | ||
| 221 | + | // file added and later removed | |
| 222 | + | /* | |
| 223 | + | 1: $(test_oid t1) = 1: $(test_oid s1) s/5/A/ | |
| 224 | + | 2: $(test_oid t2) ! 2: $(test_oid s2) s/4/A/ | |
| 225 | + | @@ Metadata | |
| 226 | + | ZAuthor: Thomas Rast <trast@inf.ethz.ch> | |
| 227 | + | Z | |
| 228 | + | Z ## Commit message ## | |
| 229 | + | - s/4/A/ | |
| 230 | + | + s/4/A/ + new-file | |
| 231 | + | Z | |
| 232 | + | Z ## file ## | |
| 233 | + | Z@@ | |
| 234 | + | @@ file | |
| 235 | + | Z A | |
| 236 | + | Z 6 | |
| 237 | + | Z 7 | |
| 238 | + | + | |
| 239 | + | + ## new-file (new) ## | |
| 240 | + | 3: $(test_oid t3) ! 3: $(test_oid s3) s/11/B/ | |
| 241 | + | @@ Metadata | |
| 242 | + | ZAuthor: Thomas Rast <trast@inf.ethz.ch> | |
| 243 | + | Z | |
| 244 | + | Z ## Commit message ## | |
| 245 | + | - s/11/B/ | |
| 246 | + | + s/11/B/ + remove file | |
| 247 | + | Z | |
| 248 | + | Z ## file ## | |
| 249 | + | Z@@ file: A | |
| 250 | + | @@ file: A | |
| 251 | + | Z 12 | |
| 252 | + | Z 13 | |
| 253 | + | Z 14 | |
| 254 | + | + | |
| 255 | + | + ## new-file (deleted) ## | |
| 256 | + | 4: $(test_oid t4) = 4: $(test_oid s4) s/12/B/ | |
| 257 | + | */ | |
| 258 | + | // func TestRangeDiffFileAddedThenRemoved(t *testing.T) {} | |
| 259 | + | ||
| 260 | + | // changed message | |
| 261 | + | /* | |
| 262 | + | 1: $(test_oid t1) = 1: $(test_oid m1) s/5/A/ | |
| 263 | + | 2: $(test_oid t2) ! 2: $(test_oid m2) s/4/A/ | |
| 264 | + | @@ Metadata | |
| 265 | + | Z ## Commit message ## | |
| 266 | + | Z s/4/A/ | |
| 267 | + | Z | |
| 268 | + | + Also a silly comment here! | |
| 269 | + | + | |
| 270 | + | Z ## file ## | |
| 271 | + | Z@@ | |
| 272 | + | Z 1 | |
| 273 | + | 3: $(test_oid t3) = 3: $(test_oid m3) s/11/B/ | |
| 274 | + | 4: $(test_oid t4) = 4: $(test_oid m4) s/12/B/ | |
| 275 | + | */ | |
| 276 | + | // func TestRangeDiffChangedMessage(t *testing.T) {} |
+3
-3
util.go
#
| ... | ... | @@ -109,7 +109,7 @@ func patchToDiff(patch io.Reader) (string, error) { | |
| 109 | 109 | return str[idx:], nil | |
| 110 | 110 | } | |
| 111 | 111 | ||
| 112 | - | func parsePatchset(patchset io.Reader) ([]*Patch, error) { | |
| 112 | + | func ParsePatchset(patchset io.Reader) ([]*Patch, error) { | |
| 113 | 113 | patches := []*Patch{} | |
| 114 | 114 | buf := new(strings.Builder) | |
| 115 | 115 | _, err := io.Copy(buf, patchset) |
| ... | ... | @@ -172,12 +173,11 @@ func calcContentSha(diffFiles []*gitdiff.File, header *gitdiff.PatchHeader) stri | |
| 172 | 173 | authorEmail = header.Author.Email | |
| 173 | 174 | } | |
| 174 | 175 | content := fmt.Sprintf( | |
| 175 | - | "%s\n%s\n%s\n%s\n%s\n", | |
| 176 | + | "%s\n%s\n%s\n%s\n", | |
| 176 | 177 | header.Title, | |
| 177 | 178 | header.Body, | |
| 178 | 179 | authorName, | |
| 179 | 180 | authorEmail, | |
| 180 | - | header.AuthorDate, | |
| 181 | 181 | ) | |
| 182 | 182 | for _, diff := range diffFiles { | |
| 183 | 183 | // we need to ignore diffs with base commit because that depends |