github.com/driusan/dgit@v0.0.0-20221118233547-f39f0c15edbb/git/apply_test.go (about) 1 package git 2 3 import ( 4 "io/ioutil" 5 "os" 6 "testing" 7 ) 8 9 // TestApply tests that the basic usage of the "Apply" command works 10 // as expected and is atomic for the unified diff format. 11 func TestUnidiffApply(t *testing.T) { 12 dir, err := ioutil.TempDir("", "gitapply") 13 if err != nil { 14 t.Fatal(err) 15 } 16 defer os.RemoveAll(dir) 17 18 // Init a repo to test an initial commit in. 19 c, err := Init(nil, InitOptions{Quiet: true}, dir) 20 if err != nil { 21 t.Fatal(err) 22 } 23 if err := os.Chdir(dir); err != nil { 24 t.Fatal(err) 25 } 26 if err := ioutil.WriteFile(dir+"/foo.txt", []byte("foo\n"), 0644); err != nil { 27 t.Fatal(err) 28 } 29 30 patch, err := ioutil.TempFile("", "applytestpatch") 31 if err != nil { 32 t.Fatal(err) 33 } 34 defer os.Remove(patch.Name()) 35 if err := ioutil.WriteFile(patch.Name(), []byte( 36 `diff --git a/foo.txt b/foo.txt 37 --- a/foo.txt 38 +++ b/foo.txt 39 @@ -1 +1 @@ 40 -foo 41 +bar 42 `), 0644); err != nil { 43 t.Fatal(err) 44 } 45 46 if err := Apply(c, ApplyOptions{}, []File{File(patch.Name())}); err != nil { 47 t.Fatalf("Error with basic git apply: %v", err) 48 } 49 50 file, err := ioutil.ReadFile("foo.txt") 51 if err != nil { 52 t.Fatal(err) 53 } 54 55 if got := string(file); got != "bar\n" { 56 t.Fatalf("Unexpected value of foo.txt after simple patch: got %v want %v", got, "bar\n") 57 } 58 59 // Make it an invalid patch. (The content of foo.txt is currently "bar\n", not "foo\n") 60 if err := ioutil.WriteFile(patch.Name(), []byte( 61 `diff --git a/foo.txt b/foo.txt 62 --- a/foo.txt 63 +++ b/foo.txt 64 @@ -1 +1 @@ 65 -foo 66 +barr 67 `), 0644); err != nil { 68 t.Fatal(err) 69 } 70 if err := Apply(c, ApplyOptions{}, []File{File(patch.Name())}); err == nil { 71 t.Fatal("Expected error with invalid patch, got none.") 72 } 73 74 file, err = ioutil.ReadFile("foo.txt") 75 if err != nil { 76 t.Fatal(err) 77 } 78 79 if got := string(file); got != "bar\n" { 80 t.Fatalf("Unexpected value of foo.txt after invalid patch: got %v want %v", got, "bar\n") 81 } 82 83 // Now ensure that the changes are atomic. If they're not, bar.txt will 84 // be modified but foo.txt will fail. 85 if err := ioutil.WriteFile(dir+"/foo.txt", []byte("foo\n"), 0644); err != nil { 86 t.Fatal(err) 87 } 88 89 if err := ioutil.WriteFile(dir+"/bar.txt", []byte("bar\n"), 0644); err != nil { 90 t.Fatal(err) 91 } 92 if err := ioutil.WriteFile(patch.Name(), []byte( 93 `diff --git a/bar.txt b/bar.txt 94 --- a/bar.txt 95 +++ b/bar.txt 96 @@ -1 +1 @@ 97 -bar 98 +qux 99 100 diff --git a/foo.txt b/foo.txt 101 --- a/foo.txt 102 +++ b/foo.txt 103 @@ -1 +1 @@ 104 -foob 105 +barr 106 `), 0644); err != nil { 107 t.Fatal(err) 108 } 109 if err := Apply(c, ApplyOptions{}, []File{File(patch.Name())}); err == nil { 110 t.Fatal("Expected error with invalid patch, got none.") 111 } 112 113 file, err = ioutil.ReadFile("foo.txt") 114 if err != nil { 115 t.Fatal(err) 116 } 117 118 if got := string(file); got != "foo\n" { 119 t.Fatalf("Unexpected value of foo.txt after invalid patch: got %v want %v", got, "foo\n") 120 } 121 file, err = ioutil.ReadFile("bar.txt") 122 if err != nil { 123 t.Fatal(err) 124 } 125 126 if got := string(file); got != "bar\n" { 127 t.Fatalf("Unexpected value of bar.txt after invalid patch: got %v want %v", got, "bar\n") 128 } 129 130 // Now make the work directory such that the patch should apply 131 if err := ioutil.WriteFile(dir+"/foo.txt", []byte("foob\n"), 0644); err != nil { 132 t.Fatal(err) 133 } 134 if err := Apply(c, ApplyOptions{}, []File{File(patch.Name())}); err != nil { 135 t.Fatalf("Unexpected error with multi-file patch %v", err) 136 } 137 138 file, err = ioutil.ReadFile("foo.txt") 139 if err != nil { 140 t.Fatal(err) 141 } 142 143 if got := string(file); got != "barr\n" { 144 t.Fatalf("Unexpected value of foo.txt after invalid patch: got %v want %v", got, "barr\n") 145 } 146 147 file, err = ioutil.ReadFile("bar.txt") 148 if err != nil { 149 t.Fatal(err) 150 } 151 152 if got := string(file); got != "qux\n" { 153 t.Fatalf("Unexpected value of bar.txt after invalid patch: got %v want %v", got, "qux\n") 154 } 155 156 // Test that Reverse works as expected 157 if err := Apply(c, ApplyOptions{Reverse: true}, []File{File(patch.Name())}); err != nil { 158 t.Fatalf("Unexpected error with reverse patch: %v", err) 159 } 160 161 file, err = ioutil.ReadFile("foo.txt") 162 if err != nil { 163 t.Fatal(err) 164 } 165 166 if got := string(file); got != "foob\n" { 167 t.Fatalf("Unexpected value of foo.txt after invalid patch: got %v want %v", got, "foob\n") 168 } 169 170 file, err = ioutil.ReadFile("bar.txt") 171 if err != nil { 172 t.Fatal(err) 173 } 174 175 if got := string(file); got != "bar\n" { 176 t.Fatalf("Unexpected value of bar.txt after invalid patch: got %v want %v", got, "bar\n") 177 } 178 179 // Ensure that a subdirectory works as expected. 180 if err := os.Mkdir("qux", 0755); err != nil { 181 t.Fatal(err) 182 } 183 if err := ioutil.WriteFile(dir+"/qux/qux.txt", []byte("qux\n"), 0644); err != nil { 184 t.Fatal(err) 185 } 186 if err := ioutil.WriteFile(patch.Name(), []byte( 187 `diff --git a/foo.txt b/foo.txt 188 --- a/foo.txt 189 +++ b/foo.txt 190 @@ -1 +1 @@ 191 -foob 192 +barr 193 194 diff --git a/qux/qux.txt b/qux/qux.txt 195 --- a/qux/qux.txt 196 +++ b/qux/qux.txt 197 @@ -1 +1 @@ 198 -qux 199 +quux 200 `), 0644); err != nil { 201 t.Fatal(err) 202 } 203 if err := Apply(c, ApplyOptions{}, []File{File(patch.Name())}); err != nil { 204 t.Fatalf("Unexpected error with file in subdirectory: %v", err) 205 } 206 207 file, err = ioutil.ReadFile("foo.txt") 208 if err != nil { 209 t.Fatal(err) 210 } 211 212 if got := string(file); got != "barr\n" { 213 t.Fatalf("Unexpected value of foo.txt after invalid patch: got %v want %v", got, "barr\n") 214 } 215 216 file, err = ioutil.ReadFile("bar.txt") 217 if err != nil { 218 t.Fatal(err) 219 } 220 221 if got := string(file); got != "bar\n" { 222 t.Fatalf("Unexpected value of bar.txt after invalid patch: got %v want %v", got, "bar\n") 223 } 224 file, err = ioutil.ReadFile("qux/qux.txt") 225 if err != nil { 226 t.Fatal(err) 227 } 228 229 if got := string(file); got != "quux\n" { 230 t.Fatalf("Unexpected value of qux/qux.txt after invalid patch: got %v want %v", got, "quux\n") 231 } 232 233 // Stage "foo\n" into the index. 234 if err := ioutil.WriteFile(dir+"/foo.txt", []byte("foo\n"), 0644); err != nil { 235 t.Fatal(err) 236 } 237 if _, err := Add(c, AddOptions{}, []File{"foo.txt"}); err != nil { 238 t.Fatal(err) 239 } 240 241 // Put something else on the filesystem 242 if err := ioutil.WriteFile(dir+"/foo.txt", []byte("bar\n"), 0644); err != nil { 243 t.Fatal(err) 244 } 245 if err := ioutil.WriteFile(patch.Name(), []byte( 246 `diff --git a/foo.txt b/foo.txt 247 --- a/foo.txt 248 +++ b/foo.txt 249 @@ -1 +1 @@ 250 -foo 251 +bara 252 `), 0644); err != nil { 253 t.Fatal(err) 254 } 255 256 if err := Apply(c, ApplyOptions{Cached: true}, []File{File(patch.Name())}); err != nil { 257 t.Fatalf("Error while applying to index: %v", err) 258 } 259 file, err = ioutil.ReadFile("foo.txt") 260 if err != nil { 261 t.Fatal(err) 262 } 263 264 if got := string(file); got != "bar\n" { 265 t.Fatalf("--cached affected filesystem with foo.txt: got %v want %v", got, "bar\n") 266 } 267 268 idx, err := LsFiles(c, LsFilesOptions{Cached: true}, []File{"foo.txt"}) 269 if err != nil { 270 t.Fatal(err) 271 } 272 if len(idx) != 1 || idx[0].PathName != "foo.txt" { 273 t.Fatal("LsFiles did not return foo.txt") 274 } 275 if want := hashString("bara\n"); idx[0].Sha1 != want { 276 t.Errorf("Did not apply --cached patch correctly. Got %v want %v", idx[0].Sha1, want) 277 } 278 }