mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 08:02:36 +09:00 
			
		
		
		
	Compare commits
	
		
			27 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					34182c87ec | ||
| 
						 | 
					c401788383 | ||
| 
						 | 
					8335b556d1 | ||
| 
						 | 
					09fff9e1c1 | ||
| 
						 | 
					622552b709 | ||
| 
						 | 
					1709297701 | ||
| 
						 | 
					5fe8fee933 | ||
| 
						 | 
					5bb20be8b2 | ||
| 
						 | 
					06a554c22a | ||
| 
						 | 
					00bd47ae5c | ||
| 
						 | 
					b20f1ab47f | ||
| 
						 | 
					9a7f59ef35 | ||
| 
						 | 
					6a6f0616f2 | ||
| 
						 | 
					6caf04c129 | ||
| 
						 | 
					406f5de18c | ||
| 
						 | 
					39cb1ac517 | ||
| 
						 | 
					58dcbaf20b | ||
| 
						 | 
					5f212ff4e9 | ||
| 
						 | 
					45fa822ac4 | ||
| 
						 | 
					1ac8646845 | ||
| 
						 | 
					13e284c7cf | ||
| 
						 | 
					bbe6aa349f | ||
| 
						 | 
					4fd55d8796 | ||
| 
						 | 
					daaabaa1d9 | ||
| 
						 | 
					fa059debca | ||
| 
						 | 
					2854c8aa47 | ||
| 
						 | 
					506c98df5b | 
							
								
								
									
										10
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								.drone.yml
									
									
									
									
									
								
							@@ -57,11 +57,11 @@ pipeline:
 | 
			
		||||
    when:
 | 
			
		||||
      event: [ push, tag, pull_request ]
 | 
			
		||||
 | 
			
		||||
  coverage:
 | 
			
		||||
    image: plugins/coverage
 | 
			
		||||
    server: https://coverage.gitea.io
 | 
			
		||||
    when:
 | 
			
		||||
      event: [ push, tag, pull_request ]
 | 
			
		||||
  # coverage:
 | 
			
		||||
  #   image: plugins/coverage
 | 
			
		||||
  #   server: https://coverage.gitea.io
 | 
			
		||||
  #   when:
 | 
			
		||||
  #     event: [ push, tag, pull_request ]
 | 
			
		||||
 | 
			
		||||
  docker:
 | 
			
		||||
    image: plugins/docker
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
eyJhbGciOiJIUzI1NiJ9.d29ya3NwYWNlOgogIGJhc2U6IC9zcnYvYXBwCiAgcGF0aDogc3JjL2NvZGUuZ2l0ZWEuaW8vZ2l0ZWEKCnBpcGVsaW5lOgogIGNsb25lOgogICAgaW1hZ2U6IHBsdWdpbnMvZ2l0CiAgICB0YWdzOiB0cnVlCgogIHRlc3Q6CiAgICBpbWFnZTogd2ViaGlwcGllL2dvbGFuZzplZGdlCiAgICBwdWxsOiB0cnVlCiAgICBlbnZpcm9ubWVudDoKICAgICAgVEFHUzogYmluZGF0YSBzcWxpdGUKICAgICAgR09QQVRIOiAvc3J2L2FwcAogICAgY29tbWFuZHM6CiAgICAgIC0gYXBrIC1VIGFkZCBvcGVuc3NoLWNsaWVudAogICAgICAtIG1ha2UgY2xlYW4KICAgICAgLSBtYWtlIGdlbmVyYXRlCiAgICAgIC0gbWFrZSB2ZXQKICAgICAgLSBtYWtlIGxpbnQKICAgICAgLSBtYWtlIHRlc3QKICAgICAgLSBtYWtlIGJ1aWxkCiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoLCB0YWcsIHB1bGxfcmVxdWVzdCBdCgogIHRlc3QtbXlzcWw6CiAgICBpbWFnZTogd2ViaGlwcGllL2dvbGFuZzplZGdlCiAgICBwdWxsOiB0cnVlCiAgICBlbnZpcm9ubWVudDoKICAgICAgVEFHUzogYmluZGF0YQogICAgICBHT1BBVEg6IC9zcnYvYXBwCiAgICBjb21tYW5kczoKICAgICAgLSBtYWtlIHRlc3QtbXlzcWwKICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHB1c2gsIHRhZywgcHVsbF9yZXF1ZXN0IF0KCiAgdGVzdC1wZ3NxbDoKICAgIGltYWdlOiB3ZWJoaXBwaWUvZ29sYW5nOmVkZ2UKICAgIHB1bGw6IHRydWUKICAgIGVudmlyb25tZW50OgogICAgICBUQUdTOiBiaW5kYXRhCiAgICAgIEdPUEFUSDogL3Nydi9hcHAKICAgIGNvbW1hbmRzOgogICAgICAtIG1ha2UgdGVzdC1wZ3NxbAogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgcHVzaCwgdGFnLCBwdWxsX3JlcXVlc3QgXQoKICBzdGF0aWM6CiAgICBpbWFnZToga2FyYWxhYmUveGdvLWxhdGVzdDpsYXRlc3QKICAgIHB1bGw6IHRydWUKICAgIGVudmlyb25tZW50OgogICAgICBUQUdTOiBiaW5kYXRhIHNxbGl0ZQogICAgICBHT1BBVEg6IC9zcnYvYXBwCiAgICBjb21tYW5kczoKICAgICAgLSBtYWtlIHJlbGVhc2UKICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHB1c2gsIHRhZywgcHVsbF9yZXF1ZXN0IF0KCiAgY292ZXJhZ2U6CiAgICBpbWFnZTogcGx1Z2lucy9jb3ZlcmFnZQogICAgc2VydmVyOiBodHRwczovL2NvdmVyYWdlLmdpdGVhLmlvCiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoLCB0YWcsIHB1bGxfcmVxdWVzdCBdCgogIGRvY2tlcjoKICAgIGltYWdlOiBwbHVnaW5zL2RvY2tlcgogICAgcmVwbzogZ2l0ZWEvZ2l0ZWEKICAgIHRhZ3M6IFsgJyR7RFJPTkVfVEFHIyN2fScgXQogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgdGFnIF0KICAgICAgYnJhbmNoOiBbIHJlZnMvdGFncy8qIF0KCiAgZG9ja2VyOgogICAgaW1hZ2U6IHBsdWdpbnMvZG9ja2VyCiAgICByZXBvOiBnaXRlYS9naXRlYQogICAgdGFnczogWyAnJHtEUk9ORV9CUkFOQ0gjI3JlbGVhc2Uvdn0nIF0KICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHB1c2ggXQogICAgICBicmFuY2g6IFsgcmVsZWFzZS8qIF0KCiAgZG9ja2VyOgogICAgaW1hZ2U6IHBsdWdpbnMvZG9ja2VyCiAgICByZXBvOiBnaXRlYS9naXRlYQogICAgdGFnczogWyAnbGF0ZXN0JyBdCiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoIF0KICAgICAgYnJhbmNoOiBbIG1hc3RlciBdCgogIHJlbGVhc2U6CiAgICBpbWFnZTogcGx1Z2lucy9zMwogICAgcGF0aF9zdHlsZTogdHJ1ZQogICAgc3RyaXBfcHJlZml4OiBkaXN0L3JlbGVhc2UvCiAgICBzb3VyY2U6IGRpc3QvcmVsZWFzZS8qCiAgICB0YXJnZXQ6IC9naXRlYS8ke0RST05FX1RBRyMjdn0KICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHRhZyBdCiAgICAgIGJyYW5jaDogWyByZWZzL3RhZ3MvKiBdCgogIHJlbGVhc2U6CiAgICBpbWFnZTogcGx1Z2lucy9zMwogICAgcGF0aF9zdHlsZTogdHJ1ZQogICAgc3RyaXBfcHJlZml4OiBkaXN0L3JlbGVhc2UvCiAgICBzb3VyY2U6IGRpc3QvcmVsZWFzZS8qCiAgICB0YXJnZXQ6IC9naXRlYS8ke0RST05FX0JSQU5DSCMjcmVsZWFzZS92fQogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgcHVzaCBdCiAgICAgIGJyYW5jaDogWyByZWxlYXNlLyogXQoKICByZWxlYXNlOgogICAgaW1hZ2U6IHBsdWdpbnMvczMKICAgIHBhdGhfc3R5bGU6IHRydWUKICAgIHN0cmlwX3ByZWZpeDogZGlzdC9yZWxlYXNlLwogICAgc291cmNlOiBkaXN0L3JlbGVhc2UvKgogICAgdGFyZ2V0OiAvZ2l0ZWEvbWFzdGVyCiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoIF0KICAgICAgYnJhbmNoOiBbIG1hc3RlciBdCgogIGdpdGh1YjoKICAgIGltYWdlOiBwbHVnaW5zL2dpdGh1Yi1yZWxlYXNlCiAgICBmaWxlczoKICAgICAgLSBkaXN0L3JlbGVhc2UvKgogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgdGFnIF0KICAgICAgYnJhbmNoOiBbIHJlZnMvdGFncy8qIF0KCiAgZ2l0dGVyOgogICAgaW1hZ2U6IHBsdWdpbnMvZ2l0dGVyCgpzZXJ2aWNlczoKICBteXNxbDoKICAgIGltYWdlOiBteXNxbDo1LjcKICAgIGVudmlyb25tZW50OgogICAgICAtIE1ZU1FMX0RBVEFCQVNFPXRlc3QKICAgICAgLSBNWVNRTF9BTExPV19FTVBUWV9QQVNTV09SRD15ZXMKICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHB1c2gsIHRhZywgcHVsbF9yZXF1ZXN0IF0KCiAgcGdzcWw6CiAgICBpbWFnZTogcG9zdGdyZXM6OS41CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT1NUR1JFU19EQj10ZXN0CiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoLCB0YWcsIHB1bGxfcmVxdWVzdCBdCg.hp6IsxbFIQOaxJdmGv32Vf34-Nra3KqVIWzH52W687I
 | 
			
		||||
eyJhbGciOiJIUzI1NiJ9.d29ya3NwYWNlOgogIGJhc2U6IC9zcnYvYXBwCiAgcGF0aDogc3JjL2NvZGUuZ2l0ZWEuaW8vZ2l0ZWEKCnBpcGVsaW5lOgogIGNsb25lOgogICAgaW1hZ2U6IHBsdWdpbnMvZ2l0CiAgICB0YWdzOiB0cnVlCgogIHRlc3Q6CiAgICBpbWFnZTogd2ViaGlwcGllL2dvbGFuZzplZGdlCiAgICBwdWxsOiB0cnVlCiAgICBlbnZpcm9ubWVudDoKICAgICAgVEFHUzogYmluZGF0YSBzcWxpdGUKICAgICAgR09QQVRIOiAvc3J2L2FwcAogICAgY29tbWFuZHM6CiAgICAgIC0gYXBrIC1VIGFkZCBvcGVuc3NoLWNsaWVudAogICAgICAtIG1ha2UgY2xlYW4KICAgICAgLSBtYWtlIGdlbmVyYXRlCiAgICAgIC0gbWFrZSB2ZXQKICAgICAgLSBtYWtlIGxpbnQKICAgICAgLSBtYWtlIHRlc3QKICAgICAgLSBtYWtlIGJ1aWxkCiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoLCB0YWcsIHB1bGxfcmVxdWVzdCBdCgogIHRlc3QtbXlzcWw6CiAgICBpbWFnZTogd2ViaGlwcGllL2dvbGFuZzplZGdlCiAgICBwdWxsOiB0cnVlCiAgICBlbnZpcm9ubWVudDoKICAgICAgVEFHUzogYmluZGF0YQogICAgICBHT1BBVEg6IC9zcnYvYXBwCiAgICBjb21tYW5kczoKICAgICAgLSBtYWtlIHRlc3QtbXlzcWwKICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHB1c2gsIHRhZywgcHVsbF9yZXF1ZXN0IF0KCiAgdGVzdC1wZ3NxbDoKICAgIGltYWdlOiB3ZWJoaXBwaWUvZ29sYW5nOmVkZ2UKICAgIHB1bGw6IHRydWUKICAgIGVudmlyb25tZW50OgogICAgICBUQUdTOiBiaW5kYXRhCiAgICAgIEdPUEFUSDogL3Nydi9hcHAKICAgIGNvbW1hbmRzOgogICAgICAtIG1ha2UgdGVzdC1wZ3NxbAogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgcHVzaCwgdGFnLCBwdWxsX3JlcXVlc3QgXQoKICBzdGF0aWM6CiAgICBpbWFnZToga2FyYWxhYmUveGdvLWxhdGVzdDpsYXRlc3QKICAgIHB1bGw6IHRydWUKICAgIGVudmlyb25tZW50OgogICAgICBUQUdTOiBiaW5kYXRhIHNxbGl0ZQogICAgICBHT1BBVEg6IC9zcnYvYXBwCiAgICBjb21tYW5kczoKICAgICAgLSBtYWtlIHJlbGVhc2UKICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHB1c2gsIHRhZywgcHVsbF9yZXF1ZXN0IF0KCiAgIyBjb3ZlcmFnZToKICAjICAgaW1hZ2U6IHBsdWdpbnMvY292ZXJhZ2UKICAjICAgc2VydmVyOiBodHRwczovL2NvdmVyYWdlLmdpdGVhLmlvCiAgIyAgIHdoZW46CiAgIyAgICAgZXZlbnQ6IFsgcHVzaCwgdGFnLCBwdWxsX3JlcXVlc3QgXQoKICBkb2NrZXI6CiAgICBpbWFnZTogcGx1Z2lucy9kb2NrZXIKICAgIHJlcG86IGdpdGVhL2dpdGVhCiAgICB0YWdzOiBbICcke0RST05FX1RBRyMjdn0nIF0KICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHRhZyBdCiAgICAgIGJyYW5jaDogWyByZWZzL3RhZ3MvKiBdCgogIGRvY2tlcjoKICAgIGltYWdlOiBwbHVnaW5zL2RvY2tlcgogICAgcmVwbzogZ2l0ZWEvZ2l0ZWEKICAgIHRhZ3M6IFsgJyR7RFJPTkVfQlJBTkNIIyNyZWxlYXNlL3Z9JyBdCiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoIF0KICAgICAgYnJhbmNoOiBbIHJlbGVhc2UvKiBdCgogIGRvY2tlcjoKICAgIGltYWdlOiBwbHVnaW5zL2RvY2tlcgogICAgcmVwbzogZ2l0ZWEvZ2l0ZWEKICAgIHRhZ3M6IFsgJ2xhdGVzdCcgXQogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgcHVzaCBdCiAgICAgIGJyYW5jaDogWyBtYXN0ZXIgXQoKICByZWxlYXNlOgogICAgaW1hZ2U6IHBsdWdpbnMvczMKICAgIHBhdGhfc3R5bGU6IHRydWUKICAgIHN0cmlwX3ByZWZpeDogZGlzdC9yZWxlYXNlLwogICAgc291cmNlOiBkaXN0L3JlbGVhc2UvKgogICAgdGFyZ2V0OiAvZ2l0ZWEvJHtEUk9ORV9UQUcjI3Z9CiAgICB3aGVuOgogICAgICBldmVudDogWyB0YWcgXQogICAgICBicmFuY2g6IFsgcmVmcy90YWdzLyogXQoKICByZWxlYXNlOgogICAgaW1hZ2U6IHBsdWdpbnMvczMKICAgIHBhdGhfc3R5bGU6IHRydWUKICAgIHN0cmlwX3ByZWZpeDogZGlzdC9yZWxlYXNlLwogICAgc291cmNlOiBkaXN0L3JlbGVhc2UvKgogICAgdGFyZ2V0OiAvZ2l0ZWEvJHtEUk9ORV9CUkFOQ0gjI3JlbGVhc2Uvdn0KICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHB1c2ggXQogICAgICBicmFuY2g6IFsgcmVsZWFzZS8qIF0KCiAgcmVsZWFzZToKICAgIGltYWdlOiBwbHVnaW5zL3MzCiAgICBwYXRoX3N0eWxlOiB0cnVlCiAgICBzdHJpcF9wcmVmaXg6IGRpc3QvcmVsZWFzZS8KICAgIHNvdXJjZTogZGlzdC9yZWxlYXNlLyoKICAgIHRhcmdldDogL2dpdGVhL21hc3RlcgogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgcHVzaCBdCiAgICAgIGJyYW5jaDogWyBtYXN0ZXIgXQoKICBnaXRodWI6CiAgICBpbWFnZTogcGx1Z2lucy9naXRodWItcmVsZWFzZQogICAgZmlsZXM6CiAgICAgIC0gZGlzdC9yZWxlYXNlLyoKICAgIHdoZW46CiAgICAgIGV2ZW50OiBbIHRhZyBdCiAgICAgIGJyYW5jaDogWyByZWZzL3RhZ3MvKiBdCgogIGdpdHRlcjoKICAgIGltYWdlOiBwbHVnaW5zL2dpdHRlcgoKc2VydmljZXM6CiAgbXlzcWw6CiAgICBpbWFnZTogbXlzcWw6NS43CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBNWVNRTF9EQVRBQkFTRT10ZXN0CiAgICAgIC0gTVlTUUxfQUxMT1dfRU1QVFlfUEFTU1dPUkQ9eWVzCiAgICB3aGVuOgogICAgICBldmVudDogWyBwdXNoLCB0YWcsIHB1bGxfcmVxdWVzdCBdCgogIHBnc3FsOgogICAgaW1hZ2U6IHBvc3RncmVzOjkuNQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUE9TVEdSRVNfREI9dGVzdAogICAgd2hlbjoKICAgICAgZXZlbnQ6IFsgcHVzaCwgdGFnLCBwdWxsX3JlcXVlc3QgXQo.uf02h57dWfCrxG3rcNcYlZPQP2XsFhKvcF2geGTpG50
 | 
			
		||||
							
								
								
									
										29
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -1,5 +1,34 @@
 | 
			
		||||
# Changelog
 | 
			
		||||
 | 
			
		||||
## [1.1.4](https://github.com/go-gitea/gitea/releases/tag/v1.1.4) - 2017-09-04
 | 
			
		||||
 | 
			
		||||
* BUGFIXES
 | 
			
		||||
  * Fix rendering of external links (#2292) (#2315)
 | 
			
		||||
  * Fix deleted milestone bug (#1942) (#2300)
 | 
			
		||||
  * fix 500 error when view an issue which's milestone deleted (#2297) (#2299)
 | 
			
		||||
  * Fix SHA1 hash linking (#2143) (#2293)
 | 
			
		||||
  * back port from #1709 (#2291)
 | 
			
		||||
 | 
			
		||||
## [1.1.3](https://github.com/go-gitea/gitea/releases/tag/v1.1.3) - 2017-08-03
 | 
			
		||||
 | 
			
		||||
* BUGFIXES
 | 
			
		||||
  * Fix PR template error (#2008)
 | 
			
		||||
  * Fix markdown rendering (fix #1530) (#2043)
 | 
			
		||||
  * Fix missing less sources for oauth (backport #1288) (#2135)
 | 
			
		||||
  * Don't ignore gravatar error (#2138)
 | 
			
		||||
  * Fix diff of renamed and modified file (#2136)
 | 
			
		||||
  * Fix fast-forward PR bug (#2137)
 | 
			
		||||
  * Fix some security bugs
 | 
			
		||||
 | 
			
		||||
## [1.1.2](https://github.com/go-gitea/gitea/releases/tag/v1.1.2) - 2017-06-13
 | 
			
		||||
 | 
			
		||||
* BUGFIXES
 | 
			
		||||
  * Enforce netgo build tag while cross-compilation (Backport of #1690) (#1731)
 | 
			
		||||
  * fix update avatar
 | 
			
		||||
  * fix delete user failed on sqlite (#1321)
 | 
			
		||||
  * fix bug not to trim space of login username (#1806)
 | 
			
		||||
  * Backport bugfixes #1220 and #1393 to v1.1 (#1758)
 | 
			
		||||
 | 
			
		||||
## [1.1.1](https://github.com/go-gitea/gitea/releases/tag/v1.1.1) - 2017-05-04
 | 
			
		||||
 | 
			
		||||
* BUGFIXES
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							@@ -112,7 +112,7 @@ release-windows:
 | 
			
		||||
	@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
 | 
			
		||||
		go get -u github.com/karalabe/xgo; \
 | 
			
		||||
	fi
 | 
			
		||||
	xgo -dest $(DIST)/binaries -tags '$(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
 | 
			
		||||
	xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
 | 
			
		||||
ifeq ($(CI),drone)
 | 
			
		||||
	mv /build/* $(DIST)/binaries
 | 
			
		||||
endif
 | 
			
		||||
@@ -122,7 +122,7 @@ release-linux:
 | 
			
		||||
	@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
 | 
			
		||||
		go get -u github.com/karalabe/xgo; \
 | 
			
		||||
	fi
 | 
			
		||||
	xgo -dest $(DIST)/binaries -tags '$(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/*' -out gitea-$(VERSION) .
 | 
			
		||||
	xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/*' -out gitea-$(VERSION) .
 | 
			
		||||
ifeq ($(CI),drone)
 | 
			
		||||
	mv /build/* $(DIST)/binaries
 | 
			
		||||
endif
 | 
			
		||||
@@ -132,7 +132,7 @@ release-darwin:
 | 
			
		||||
	@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
 | 
			
		||||
		go get -u github.com/karalabe/xgo; \
 | 
			
		||||
	fi
 | 
			
		||||
	xgo -dest $(DIST)/binaries -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out gitea-$(VERSION) .
 | 
			
		||||
	xgo -dest $(DIST)/binaries -tags 'netgo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out gitea-$(VERSION) .
 | 
			
		||||
ifeq ($(CI),drone)
 | 
			
		||||
	mv /build/* $(DIST)/binaries
 | 
			
		||||
endif
 | 
			
		||||
 
 | 
			
		||||
@@ -360,7 +360,7 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
 | 
			
		||||
 | 
			
		||||
			issue, err := GetIssueByRef(ref)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				if IsErrIssueNotExist(err) {
 | 
			
		||||
				if IsErrIssueNotExist(err) || err == errMissingIssueNumber {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				return err
 | 
			
		||||
@@ -398,7 +398,7 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
 | 
			
		||||
 | 
			
		||||
			issue, err := GetIssueByRef(ref)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				if IsErrIssueNotExist(err) {
 | 
			
		||||
				if IsErrIssueNotExist(err) || err == errMissingIssueNumber {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				return err
 | 
			
		||||
@@ -438,7 +438,7 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
 | 
			
		||||
 | 
			
		||||
			issue, err := GetIssueByRef(ref)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				if IsErrIssueNotExist(err) {
 | 
			
		||||
				if IsErrIssueNotExist(err) || err == errMissingIssueNumber {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				return err
 | 
			
		||||
 
 | 
			
		||||
@@ -9,8 +9,8 @@ import "github.com/markbates/goth"
 | 
			
		||||
// ExternalLoginUser makes the connecting between some existing user and additional external login sources
 | 
			
		||||
type ExternalLoginUser struct {
 | 
			
		||||
	ExternalID    string `xorm:"NOT NULL"`
 | 
			
		||||
	UserID        int64 `xorm:"NOT NULL"`
 | 
			
		||||
	LoginSourceID int64 `xorm:"NOT NULL"`
 | 
			
		||||
	UserID        int64  `xorm:"NOT NULL"`
 | 
			
		||||
	LoginSourceID int64  `xorm:"NOT NULL"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetExternalLogin checks if a externalID in loginSourceID scope already exists
 | 
			
		||||
@@ -67,8 +67,8 @@ func RemoveAccountLink(user *User, loginSourceID int64) (int64, error) {
 | 
			
		||||
	return deleted, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RemoveAllAccountLinks will remove all external login sources for the given user
 | 
			
		||||
func RemoveAllAccountLinks(user *User) error {
 | 
			
		||||
	_, err := x.Delete(&ExternalLoginUser{UserID: user.ID})
 | 
			
		||||
// removeAllAccountLinks will remove all external login sources for the given user
 | 
			
		||||
func removeAllAccountLinks(e Engine, user *User) error {
 | 
			
		||||
	_, err := e.Delete(&ExternalLoginUser{UserID: user.ID})
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -366,10 +366,12 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			curFile = &DiffFile{
 | 
			
		||||
				Name:     a,
 | 
			
		||||
				Index:    len(diff.Files) + 1,
 | 
			
		||||
				Type:     DiffFileChange,
 | 
			
		||||
				Sections: make([]*DiffSection, 0, 10),
 | 
			
		||||
				Name:      b,
 | 
			
		||||
				OldName:   a,
 | 
			
		||||
				Index:     len(diff.Files) + 1,
 | 
			
		||||
				Type:      DiffFileChange,
 | 
			
		||||
				Sections:  make([]*DiffSection, 0, 10),
 | 
			
		||||
				IsRenamed: a != b,
 | 
			
		||||
			}
 | 
			
		||||
			diff.Files = append(diff.Files, curFile)
 | 
			
		||||
			if len(diff.Files) >= maxFiles {
 | 
			
		||||
@@ -402,9 +404,6 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
 | 
			
		||||
					curFile.Type = DiffFileChange
 | 
			
		||||
				case strings.HasPrefix(line, "similarity index 100%"):
 | 
			
		||||
					curFile.Type = DiffFileRename
 | 
			
		||||
					curFile.IsRenamed = true
 | 
			
		||||
					curFile.OldName = curFile.Name
 | 
			
		||||
					curFile.Name = b
 | 
			
		||||
				}
 | 
			
		||||
				if curFile.Type > 0 {
 | 
			
		||||
					if strings.HasSuffix(line, " 160000\n") {
 | 
			
		||||
 
 | 
			
		||||
@@ -146,7 +146,7 @@ func (issue *Issue) loadAttributes(e Engine) (err error) {
 | 
			
		||||
 | 
			
		||||
	if issue.Milestone == nil && issue.MilestoneID > 0 {
 | 
			
		||||
		issue.Milestone, err = getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
		if err != nil && !IsErrMilestoneNotExist(err) {
 | 
			
		||||
			return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -231,12 +231,9 @@ func (c *Comment) LoadMilestone() error {
 | 
			
		||||
		has, err := x.ID(c.OldMilestoneID).Get(&oldMilestone)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		} else if !has {
 | 
			
		||||
			return ErrMilestoneNotExist{
 | 
			
		||||
				ID: c.OldMilestoneID,
 | 
			
		||||
			}
 | 
			
		||||
		} else if has {
 | 
			
		||||
			c.OldMilestone = &oldMilestone
 | 
			
		||||
		}
 | 
			
		||||
		c.OldMilestone = &oldMilestone
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.MilestoneID > 0 {
 | 
			
		||||
@@ -244,12 +241,9 @@ func (c *Comment) LoadMilestone() error {
 | 
			
		||||
		has, err := x.ID(c.MilestoneID).Get(&milestone)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		} else if !has {
 | 
			
		||||
			return ErrMilestoneNotExist{
 | 
			
		||||
				ID: c.MilestoneID,
 | 
			
		||||
			}
 | 
			
		||||
		} else if has {
 | 
			
		||||
			c.Milestone = &milestone
 | 
			
		||||
		}
 | 
			
		||||
		c.Milestone = &milestone
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -635,7 +635,12 @@ func UserSignIn(username, password string) (*User, error) {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		user = &User{LowerName: strings.ToLower(strings.TrimSpace(username))}
 | 
			
		||||
		trimmedUsername := strings.TrimSpace(username)
 | 
			
		||||
		if len(trimmedUsername) == 0 {
 | 
			
		||||
			return nil, ErrUserNotExist{0, username, 0}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		user = &User{LowerName: strings.ToLower(trimmedUsername)}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hasUser, err := x.Get(user)
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ func useNewNameAvatars(x *xorm.Engine) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	type User struct {
 | 
			
		||||
		ID              int64 `xorm:"pk autoincr"`
 | 
			
		||||
		Avatar          string
 | 
			
		||||
		UseCustomAvatar bool
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -499,9 +499,15 @@ func (pr *PullRequest) getMergeCommit() (*git.Commit, error) {
 | 
			
		||||
		return nil, fmt.Errorf("git merge-base --is-ancestor: %v %v", stderr, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// We can ignore this error since we only get here when there's a valid commit in headFile
 | 
			
		||||
	commitID, _ := ioutil.ReadFile(pr.BaseRepo.RepoPath() + "/" + headFile)
 | 
			
		||||
	cmd := string(commitID)[:40] + ".." + pr.BaseBranch
 | 
			
		||||
	commitIDBytes, err := ioutil.ReadFile(pr.BaseRepo.RepoPath() + "/" + headFile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("ReadFile(%s): %v", headFile, err)
 | 
			
		||||
	}
 | 
			
		||||
	commitID := string(commitIDBytes)
 | 
			
		||||
	if len(commitID) < 40 {
 | 
			
		||||
		return nil, fmt.Errorf(`ReadFile(%s): invalid commit-ID "%s"`, headFile, commitID)
 | 
			
		||||
	}
 | 
			
		||||
	cmd := commitID[:40] + ".." + pr.BaseBranch
 | 
			
		||||
 | 
			
		||||
	// Get the commit from BaseBranch where the pull request got merged
 | 
			
		||||
	mergeCommit, stderr, err := process.GetManager().ExecDirEnv(-1, "", fmt.Sprintf("isMerged (git rev-list --ancestry-path --merges --reverse): %d", pr.BaseRepo.ID),
 | 
			
		||||
@@ -510,6 +516,9 @@ func (pr *PullRequest) getMergeCommit() (*git.Commit, error) {
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("git rev-list --ancestry-path --merges --reverse: %v %v", stderr, err)
 | 
			
		||||
	} else if len(mergeCommit) < 40 {
 | 
			
		||||
		// PR was fast-forwarded, so just use last commit of PR
 | 
			
		||||
		mergeCommit = commitID[:40]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
 | 
			
		||||
 
 | 
			
		||||
@@ -328,15 +328,14 @@ func (u *User) generateRandomAvatar(e Engine) error {
 | 
			
		||||
// which includes app sub-url as prefix. However, it is possible
 | 
			
		||||
// to return full URL if user enables Gravatar-like service.
 | 
			
		||||
func (u *User) RelAvatarLink() string {
 | 
			
		||||
	defaultImgURL := setting.AppSubURL + "/img/avatar_default.png"
 | 
			
		||||
	if u.ID == -1 {
 | 
			
		||||
		return defaultImgURL
 | 
			
		||||
		return base.DefaultAvatarLink()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch {
 | 
			
		||||
	case u.UseCustomAvatar:
 | 
			
		||||
		if !com.IsFile(u.CustomAvatarPath()) {
 | 
			
		||||
			return defaultImgURL
 | 
			
		||||
			return base.DefaultAvatarLink()
 | 
			
		||||
		}
 | 
			
		||||
		return setting.AppSubURL + "/avatars/" + u.Avatar
 | 
			
		||||
	case setting.DisableGravatar, setting.OfflineMode:
 | 
			
		||||
@@ -989,7 +988,7 @@ func deleteUser(e *xorm.Session, u *User) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// ***** START: ExternalLoginUser *****
 | 
			
		||||
	if err = RemoveAllAccountLinks(u); err != nil {
 | 
			
		||||
	if err = removeAllAccountLinks(e, u); err != nil {
 | 
			
		||||
		return fmt.Errorf("ExternalLoginUser: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	// ***** END: ExternalLoginUser *****
 | 
			
		||||
 
 | 
			
		||||
@@ -192,13 +192,21 @@ func HashEmail(email string) string {
 | 
			
		||||
	return EncodeMD5(strings.ToLower(strings.TrimSpace(email)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DefaultAvatarLink the default avatar link
 | 
			
		||||
func DefaultAvatarLink() string {
 | 
			
		||||
	return setting.AppSubURL + "/img/avatar_default.png"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AvatarLink returns relative avatar link to the site domain by given email,
 | 
			
		||||
// which includes app sub-url as prefix. However, it is possible
 | 
			
		||||
// to return full URL if user enables Gravatar-like service.
 | 
			
		||||
func AvatarLink(email string) string {
 | 
			
		||||
	if setting.EnableFederatedAvatar && setting.LibravatarService != nil {
 | 
			
		||||
		// TODO: This doesn't check any error. AvatarLink should return (string, error)
 | 
			
		||||
		url, _ := setting.LibravatarService.FromEmail(email)
 | 
			
		||||
		url, err := setting.LibravatarService.FromEmail(email)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Error(4, "LibravatarService.FromEmail(email=%s): error %v", email, err)
 | 
			
		||||
			return DefaultAvatarLink()
 | 
			
		||||
		}
 | 
			
		||||
		return url
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -206,7 +214,7 @@ func AvatarLink(email string) string {
 | 
			
		||||
		return setting.GravatarSource + HashEmail(email)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return setting.AppSubURL + "/img/avatar_default.png"
 | 
			
		||||
	return DefaultAvatarLink()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Seconds-based time units
 | 
			
		||||
 
 | 
			
		||||
@@ -334,13 +334,11 @@ func RepoAssignment(args ...bool) macaron.Handler {
 | 
			
		||||
		if ctx.Repo.IsWriter() || (ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)) {
 | 
			
		||||
			// Pull request is allowed if this is a fork repository
 | 
			
		||||
			// and base repository accepts pull requests.
 | 
			
		||||
			if repo.BaseRepo != nil {
 | 
			
		||||
				if repo.BaseRepo.AllowsPulls() {
 | 
			
		||||
					ctx.Data["BaseRepo"] = repo.BaseRepo
 | 
			
		||||
					ctx.Repo.PullRequest.BaseRepo = repo.BaseRepo
 | 
			
		||||
					ctx.Repo.PullRequest.Allowed = true
 | 
			
		||||
					ctx.Repo.PullRequest.HeadInfo = ctx.Repo.Owner.Name + ":" + ctx.Repo.BranchName
 | 
			
		||||
				}
 | 
			
		||||
			if repo.BaseRepo != nil && repo.BaseRepo.AllowsPulls() {
 | 
			
		||||
				ctx.Data["BaseRepo"] = repo.BaseRepo
 | 
			
		||||
				ctx.Repo.PullRequest.BaseRepo = repo.BaseRepo
 | 
			
		||||
				ctx.Repo.PullRequest.Allowed = true
 | 
			
		||||
				ctx.Repo.PullRequest.HeadInfo = ctx.Repo.Owner.Name + ":" + ctx.Repo.BranchName
 | 
			
		||||
			} else {
 | 
			
		||||
				// Or, this is repository accepts pull requests between branches.
 | 
			
		||||
				if repo.AllowsPulls() {
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,10 @@ func IsReadmeFile(name string) bool {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// NOTE: All below regex matching do not perform any extra validation.
 | 
			
		||||
	// Thus a link is produced even if the user does not exist, the issue does not exist, the commit does not exist, etc.
 | 
			
		||||
	// While fast, this is also incorrect and lead to false positives.
 | 
			
		||||
 | 
			
		||||
	// MentionPattern matches string that mentions someone, e.g. @Unknwon
 | 
			
		||||
	MentionPattern = regexp.MustCompile(`(\s|^|\W)@[0-9a-zA-Z-_\.]+`)
 | 
			
		||||
 | 
			
		||||
@@ -65,9 +69,9 @@ var (
 | 
			
		||||
	CrossReferenceIssueNumericPattern = regexp.MustCompile(`( |^)[0-9a-zA-Z]+/[0-9a-zA-Z]+#[0-9]+\b`)
 | 
			
		||||
 | 
			
		||||
	// Sha1CurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae
 | 
			
		||||
	// FIXME: this pattern matches pure numbers as well, right now we do a hack to check in renderSha1CurrentPattern
 | 
			
		||||
	// by converting string to a number.
 | 
			
		||||
	Sha1CurrentPattern = regexp.MustCompile(`(?:^|\s|\()[0-9a-f]{40}\b`)
 | 
			
		||||
	// Although SHA1 hashes are 40 chars long, the regex matches the hash from 7 to 40 chars in length
 | 
			
		||||
	// so that abbreviated hash links can be used as well. This matches git and github useability.
 | 
			
		||||
	Sha1CurrentPattern = regexp.MustCompile(`(?:^|\s|\()([0-9a-f]{7,40})\b`)
 | 
			
		||||
 | 
			
		||||
	// ShortLinkPattern matches short but difficult to parse [[name|link|arg=test]] syntax
 | 
			
		||||
	ShortLinkPattern = regexp.MustCompile(`(\[\[.*\]\]\w*)`)
 | 
			
		||||
@@ -75,12 +79,29 @@ var (
 | 
			
		||||
	// AnySHA1Pattern allows to split url containing SHA into parts
 | 
			
		||||
	AnySHA1Pattern = regexp.MustCompile(`(http\S*)://(\S+)/(\S+)/(\S+)/(\S+)/([0-9a-f]{40})(?:/?([^#\s]+)?(?:#(\S+))?)?`)
 | 
			
		||||
 | 
			
		||||
	// IssueFullPattern allows to split issue (and pull) URLs into parts
 | 
			
		||||
	IssueFullPattern = regexp.MustCompile(`(?:^|\s|\()(http\S*)://((?:[^\s/]+/)+)((?:\w{1,10}-)?[1-9][0-9]*)([\?|#]\S+.(\S+)?)?\b`)
 | 
			
		||||
 | 
			
		||||
	validLinksPattern = regexp.MustCompile(`^[a-z][\w-]+://`)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// regexp for full links to issues/pulls
 | 
			
		||||
var issueFullPattern *regexp.Regexp
 | 
			
		||||
 | 
			
		||||
// InitMarkdown initialize regexps for markdown parsing
 | 
			
		||||
func InitMarkdown() {
 | 
			
		||||
	getIssueFullPattern()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getIssueFullPattern() *regexp.Regexp {
 | 
			
		||||
	if issueFullPattern == nil {
 | 
			
		||||
		appURL := setting.AppURL
 | 
			
		||||
		if len(appURL) > 0 && appURL[len(appURL)-1] != '/' {
 | 
			
		||||
			appURL += "/"
 | 
			
		||||
		}
 | 
			
		||||
		issueFullPattern = regexp.MustCompile(appURL +
 | 
			
		||||
			`\w+/\w+/(?:issues|pulls)/((?:\w{1,10}-)?[1-9][0-9]*)([\?|#]\S+.(\S+)?)?\b`)
 | 
			
		||||
	}
 | 
			
		||||
	return issueFullPattern
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// isLink reports whether link fits valid format.
 | 
			
		||||
func isLink(link []byte) bool {
 | 
			
		||||
	return validLinksPattern.Match(link)
 | 
			
		||||
@@ -155,12 +176,15 @@ func (r *Renderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
 | 
			
		||||
	}
 | 
			
		||||
	switch {
 | 
			
		||||
	case bytes.HasPrefix(text, []byte(prefix+"[ ] ")):
 | 
			
		||||
		text = append([]byte(`<div class="ui fitted disabled checkbox"><input type="checkbox" disabled="disabled" /><label /></div>`), text[3+len(prefix):]...)
 | 
			
		||||
		text = append([]byte(`<span class="ui fitted disabled checkbox"><input type="checkbox" disabled="disabled" /><label /></span>`), text[3+len(prefix):]...)
 | 
			
		||||
		if prefix != "" {
 | 
			
		||||
			text = bytes.Replace(text, []byte(prefix), []byte{}, 1)
 | 
			
		||||
		}
 | 
			
		||||
	case bytes.HasPrefix(text, []byte(prefix+"[x] ")):
 | 
			
		||||
		text = append([]byte(`<div class="ui checked fitted disabled checkbox"><input type="checkbox" checked="" disabled="disabled" /><label /></div>`), text[3+len(prefix):]...)
 | 
			
		||||
	}
 | 
			
		||||
	if prefix != "" {
 | 
			
		||||
		text = bytes.Replace(text, []byte("</p>"), []byte{}, 1)
 | 
			
		||||
		text = append([]byte(`<span class="ui checked fitted disabled checkbox"><input type="checkbox" checked="" disabled="disabled" /><label /></span>`), text[3+len(prefix):]...)
 | 
			
		||||
		if prefix != "" {
 | 
			
		||||
			text = bytes.Replace(text, []byte(prefix), []byte{}, 1)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	r.Renderer.ListItem(out, text, flags)
 | 
			
		||||
}
 | 
			
		||||
@@ -345,32 +369,17 @@ func renderFullSha1Pattern(rawBytes []byte, urlPrefix string) []byte {
 | 
			
		||||
	return rawBytes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// renderFullIssuePattern renders issues-like URLs
 | 
			
		||||
func renderFullIssuePattern(rawBytes []byte, urlPrefix string) []byte {
 | 
			
		||||
	ms := IssueFullPattern.FindAllSubmatch(rawBytes, -1)
 | 
			
		||||
// RenderFullIssuePattern renders issues-like URLs
 | 
			
		||||
func RenderFullIssuePattern(rawBytes []byte) []byte {
 | 
			
		||||
	ms := getIssueFullPattern().FindAllSubmatch(rawBytes, -1)
 | 
			
		||||
	for _, m := range ms {
 | 
			
		||||
		all := m[0]
 | 
			
		||||
		protocol := string(m[1])
 | 
			
		||||
		paths := bytes.Split(m[2], []byte("/"))
 | 
			
		||||
		paths = paths[:len(paths)-1]
 | 
			
		||||
		if bytes.HasPrefix(paths[0], []byte("gist.")) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		path := protocol + "://" + string(m[2])
 | 
			
		||||
		id := string(m[3])
 | 
			
		||||
		path = URLJoin(path, id)
 | 
			
		||||
		var comment []byte
 | 
			
		||||
		if len(m) > 3 {
 | 
			
		||||
			comment = m[4]
 | 
			
		||||
		}
 | 
			
		||||
		urlSuffix := ""
 | 
			
		||||
		id := string(m[1])
 | 
			
		||||
		text := "#" + id
 | 
			
		||||
		if comment != nil {
 | 
			
		||||
			urlSuffix += string(comment)
 | 
			
		||||
			text += " <i class='comment icon'></i>"
 | 
			
		||||
		}
 | 
			
		||||
		// TODO if m[2] is not nil, then link is to a comment,
 | 
			
		||||
		// and we should indicate that in the text somehow
 | 
			
		||||
		rawBytes = bytes.Replace(rawBytes, all, []byte(fmt.Sprintf(
 | 
			
		||||
			`<a href="%s%s">%s</a>`, path, urlSuffix, text)), -1)
 | 
			
		||||
			`<a href="%s">%s</a>`, string(all), text)), -1)
 | 
			
		||||
	}
 | 
			
		||||
	return rawBytes
 | 
			
		||||
}
 | 
			
		||||
@@ -550,12 +559,15 @@ func RenderCrossReferenceIssueIndexPattern(rawBytes []byte, urlPrefix string, me
 | 
			
		||||
func renderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
 | 
			
		||||
	ms := Sha1CurrentPattern.FindAllSubmatch(rawBytes, -1)
 | 
			
		||||
	for _, m := range ms {
 | 
			
		||||
		all := m[0]
 | 
			
		||||
		if com.StrTo(all).MustInt() > 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		rawBytes = bytes.Replace(rawBytes, all, []byte(fmt.Sprintf(
 | 
			
		||||
			`<a href="%s">%s</a>`, URLJoin(urlPrefix, "commit", string(all)), base.ShortSha(string(all)))), -1)
 | 
			
		||||
		hash := m[1]
 | 
			
		||||
		// The regex does not lie, it matches the hash pattern.
 | 
			
		||||
		// However, a regex cannot know if a hash actually exists or not.
 | 
			
		||||
		// We could assume that a SHA1 hash should probably contain alphas AND numerics
 | 
			
		||||
		// but that is not always the case.
 | 
			
		||||
		// Although unlikely, deadbeef and 1234567 are valid short forms of SHA1 hash
 | 
			
		||||
		// as used by git and github for linking and thus we have to do similar.
 | 
			
		||||
		rawBytes = bytes.Replace(rawBytes, hash, []byte(fmt.Sprintf(
 | 
			
		||||
			`<a href="%s">%s</a>`, URLJoin(urlPrefix, "commit", string(hash)), base.ShortSha(string(hash)))), -1)
 | 
			
		||||
	}
 | 
			
		||||
	return rawBytes
 | 
			
		||||
}
 | 
			
		||||
@@ -569,12 +581,12 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string, metas map[string]strin
 | 
			
		||||
			[]byte(fmt.Sprintf(`<a href="%s">%s</a>`, URLJoin(setting.AppURL, string(m[1:])), m)), -1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rawBytes = RenderFullIssuePattern(rawBytes)
 | 
			
		||||
	rawBytes = RenderShortLinks(rawBytes, urlPrefix, false, isWikiMarkdown)
 | 
			
		||||
	rawBytes = RenderIssueIndexPattern(rawBytes, urlPrefix, metas)
 | 
			
		||||
	rawBytes = RenderCrossReferenceIssueIndexPattern(rawBytes, urlPrefix, metas)
 | 
			
		||||
	rawBytes = renderFullSha1Pattern(rawBytes, urlPrefix)
 | 
			
		||||
	rawBytes = renderSha1CurrentPattern(rawBytes, urlPrefix)
 | 
			
		||||
	rawBytes = renderFullIssuePattern(rawBytes, urlPrefix)
 | 
			
		||||
	return rawBytes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -638,10 +650,8 @@ OUTER_LOOP:
 | 
			
		||||
					// Copy the token to the output verbatim
 | 
			
		||||
					buf.Write(RenderShortLinks([]byte(token.String()), urlPrefix, true, isWikiMarkdown))
 | 
			
		||||
 | 
			
		||||
					if token.Type == html.StartTagToken {
 | 
			
		||||
						if !com.IsSliceContainsStr(noEndTags, token.Data) {
 | 
			
		||||
							stackNum++
 | 
			
		||||
						}
 | 
			
		||||
					if token.Type == html.StartTagToken && !com.IsSliceContainsStr(noEndTags, token.Data) {
 | 
			
		||||
						stackNum++
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// If this is the close tag to the outer-most, we are done
 | 
			
		||||
@@ -656,8 +666,8 @@ OUTER_LOOP:
 | 
			
		||||
				continue OUTER_LOOP
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if !com.IsSliceContainsStr(noEndTags, token.Data) {
 | 
			
		||||
				startTags = append(startTags, token.Data)
 | 
			
		||||
			if !com.IsSliceContainsStr(noEndTags, tagName) {
 | 
			
		||||
				startTags = append(startTags, tagName)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		case html.EndTagToken:
 | 
			
		||||
 
 | 
			
		||||
@@ -180,13 +180,15 @@ func TestRender_AutoLink(t *testing.T) {
 | 
			
		||||
		numericIssueLink(URLJoin(setting.AppSubURL, "issues"), 3333))
 | 
			
		||||
 | 
			
		||||
	// render external issue URLs
 | 
			
		||||
	tmp := "http://1111/2222/ssss-issues/3333?param=blah&blahh=333"
 | 
			
		||||
	test(tmp, "<a href=\""+tmp+"\">#3333 <i class='comment icon'></i></a>")
 | 
			
		||||
	test("http://test.com/issues/33333", numericIssueLink("http://test.com/issues", 33333))
 | 
			
		||||
	test("https://issues/333", numericIssueLink("https://issues", 333))
 | 
			
		||||
	for _, externalURL := range []string{
 | 
			
		||||
		"http://1111/2222/ssss-issues/3333?param=blah&blahh=333",
 | 
			
		||||
		"http://test.com/issues/33333",
 | 
			
		||||
		"https://issues/333"} {
 | 
			
		||||
		test(externalURL, externalURL)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// render valid commit URLs
 | 
			
		||||
	tmp = URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae")
 | 
			
		||||
	tmp := URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae")
 | 
			
		||||
	test(tmp, "<a href=\""+tmp+"\">d8a994ef24</a>")
 | 
			
		||||
	tmp += "#diff-2"
 | 
			
		||||
	test(tmp, "<a href=\""+tmp+"\">d8a994ef24 (diff-2)</a>")
 | 
			
		||||
@@ -290,6 +292,8 @@ func TestRender_Commits(t *testing.T) {
 | 
			
		||||
	var src = strings.Replace(subtree, "/commit/", "/src/", -1)
 | 
			
		||||
 | 
			
		||||
	test(sha, `<p><a href="`+commit+`" rel="nofollow">b6dd6210ea</a></p>`)
 | 
			
		||||
	test(sha[:7], `<p><a href="`+commit[:len(commit)-(40-7)]+`" rel="nofollow">b6dd621</a></p>`)
 | 
			
		||||
	test(sha[:39], `<p><a href="`+commit[:len(commit)-(40-39)]+`" rel="nofollow">b6dd6210ea</a></p>`)
 | 
			
		||||
	test(commit, `<p><a href="`+commit+`" rel="nofollow">b6dd6210ea</a></p>`)
 | 
			
		||||
	test(tree, `<p><a href="`+src+`" rel="nofollow">b6dd6210ea/src</a></p>`)
 | 
			
		||||
}
 | 
			
		||||
@@ -330,6 +334,22 @@ func TestRender_CrossReferences(t *testing.T) {
 | 
			
		||||
		`<p><a href="`+URLJoin(AppURL, "gogits", "gogs", "issues", "12345")+`" rel="nofollow">gogits/gogs#12345</a></p>`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRender_FullIssueURLs(t *testing.T) {
 | 
			
		||||
	setting.AppURL = AppURL
 | 
			
		||||
	setting.AppSubURL = AppSubURL
 | 
			
		||||
 | 
			
		||||
	test := func(input, expected string) {
 | 
			
		||||
		result := RenderFullIssuePattern([]byte(input))
 | 
			
		||||
		assert.Equal(t, expected, string(result))
 | 
			
		||||
	}
 | 
			
		||||
	test("Here is a link https://git.osgeo.org/gogs/postgis/postgis/pulls/6",
 | 
			
		||||
		"Here is a link https://git.osgeo.org/gogs/postgis/postgis/pulls/6")
 | 
			
		||||
	test("Look here http://localhost:3000/person/repo/issues/4",
 | 
			
		||||
		`Look here <a href="http://localhost:3000/person/repo/issues/4">#4</a>`)
 | 
			
		||||
	test("http://localhost:3000/person/repo/issues/4#issuecomment-1234",
 | 
			
		||||
		`<a href="http://localhost:3000/person/repo/issues/4#issuecomment-1234">#4</a>`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRegExp_MentionPattern(t *testing.T) {
 | 
			
		||||
	trueTestCases := []string{
 | 
			
		||||
		"@Unknwon",
 | 
			
		||||
@@ -520,50 +540,6 @@ func TestRegExp_AnySHA1Pattern(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRegExp_IssueFullPattern(t *testing.T) {
 | 
			
		||||
	testCases := map[string][]string{
 | 
			
		||||
		"https://github.com/gogits/gogs/pull/3244": {
 | 
			
		||||
			"https",
 | 
			
		||||
			"github.com/gogits/gogs/pull/",
 | 
			
		||||
			"3244",
 | 
			
		||||
			"",
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
		"https://github.com/gogits/gogs/issues/3247#issuecomment-231517079": {
 | 
			
		||||
			"https",
 | 
			
		||||
			"github.com/gogits/gogs/issues/",
 | 
			
		||||
			"3247",
 | 
			
		||||
			"#issuecomment-231517079",
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
		"https://try.gogs.io/gogs/gogs/issues/4#issue-685": {
 | 
			
		||||
			"https",
 | 
			
		||||
			"try.gogs.io/gogs/gogs/issues/",
 | 
			
		||||
			"4",
 | 
			
		||||
			"#issue-685",
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
		"https://youtrack.jetbrains.com/issue/JT-36485": {
 | 
			
		||||
			"https",
 | 
			
		||||
			"youtrack.jetbrains.com/issue/",
 | 
			
		||||
			"JT-36485",
 | 
			
		||||
			"",
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
		"https://youtrack.jetbrains.com/issue/JT-36485#comment=27-1508676": {
 | 
			
		||||
			"https",
 | 
			
		||||
			"youtrack.jetbrains.com/issue/",
 | 
			
		||||
			"JT-36485",
 | 
			
		||||
			"#comment=27-1508676",
 | 
			
		||||
			"",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for k, v := range testCases {
 | 
			
		||||
		assert.Equal(t, IssueFullPattern.FindStringSubmatch(k)[1:], v)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestMisc_IsMarkdownFile(t *testing.T) {
 | 
			
		||||
	setting.Markdown.FileExtensions = []string{".md", ".markdown", ".mdown", ".mkd"}
 | 
			
		||||
	trueTestCases := []string{
 | 
			
		||||
@@ -632,7 +608,7 @@ var sameCases = []string{
 | 
			
		||||
 | 
			
		||||
Ideas and codes
 | 
			
		||||
 | 
			
		||||
- Bezier widget (by @r-lyeh) https://github.com/ocornut/imgui/issues/786
 | 
			
		||||
- Bezier widget (by @r-lyeh) ` + AppURL + `ocornut/imgui/issues/786
 | 
			
		||||
- Node graph editors https://github.com/ocornut/imgui/issues/306
 | 
			
		||||
- [[Memory Editor|memory_editor_example]]
 | 
			
		||||
- [[Plot var helper|plot_var_example]]`,
 | 
			
		||||
@@ -668,8 +644,8 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
 | 
			
		||||
<p>Ideas and codes</p>
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>)<a href="https://github.com/ocornut/imgui/issues/786" rel="nofollow">#786</a></li>
 | 
			
		||||
<li>Node graph editors<a href="https://github.com/ocornut/imgui/issues/306" rel="nofollow">#306</a></li>
 | 
			
		||||
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="http://localhost:3000/ocornut/imgui/issues/786" rel="nofollow">#786</a></li>
 | 
			
		||||
<li>Node graph editors https://github.com/ocornut/imgui/issues/306</li>
 | 
			
		||||
<li><a href="` + baseURLContent + `memory_editor_example" rel="nofollow">Memory Editor</a></li>
 | 
			
		||||
<li><a href="` + baseURLContent + `plot_var_example" rel="nofollow">Plot var helper</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 
 | 
			
		||||
@@ -558,6 +558,7 @@ issues.remove_label_at = `removed the <div class="ui label" style="color: %s; ba
 | 
			
		||||
issues.add_milestone_at = `added this to the <b>%s</b> milestone %s`
 | 
			
		||||
issues.change_milestone_at = `modified the milestone from <b>%s</b> to <b>%s</b> %s`
 | 
			
		||||
issues.remove_milestone_at = `removed this from the <b>%s</b> milestone %s`
 | 
			
		||||
issues.deleted_milestone = `(deleted)`
 | 
			
		||||
issues.self_assign_at = `self-assigned this %s`
 | 
			
		||||
issues.add_assignee_at = `was assigned by <b>%s</b> %s`
 | 
			
		||||
issues.remove_assignee_at = `removed their assignment %s`
 | 
			
		||||
 
 | 
			
		||||
@@ -949,6 +949,23 @@ footer .ui.language .menu {
 | 
			
		||||
#create-page-form form textarea {
 | 
			
		||||
  width: 50%!important;
 | 
			
		||||
}
 | 
			
		||||
.signin .oauth2 div {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
.signin .oauth2 div p {
 | 
			
		||||
  margin: 10px 5px 0 0;
 | 
			
		||||
  float: left;
 | 
			
		||||
}
 | 
			
		||||
.signin .oauth2 a {
 | 
			
		||||
  margin-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
.signin .oauth2 a:last-child {
 | 
			
		||||
  margin-right: 0px;
 | 
			
		||||
}
 | 
			
		||||
.signin .oauth2 img {
 | 
			
		||||
  width: 32px;
 | 
			
		||||
  height: 32px;
 | 
			
		||||
}
 | 
			
		||||
.user.activate form,
 | 
			
		||||
.user.forgot.password form,
 | 
			
		||||
.user.reset.password form,
 | 
			
		||||
@@ -2742,6 +2759,10 @@ footer .ui.language .menu {
 | 
			
		||||
.user.notification .octicon.blue {
 | 
			
		||||
  color: #2185d0;
 | 
			
		||||
}
 | 
			
		||||
.user.link-account:not(.icon) {
 | 
			
		||||
  padding-top: 15px;
 | 
			
		||||
  padding-bottom: 5px;
 | 
			
		||||
}
 | 
			
		||||
.dashboard {
 | 
			
		||||
  padding-top: 15px;
 | 
			
		||||
  padding-bottom: 80px;
 | 
			
		||||
@@ -2983,24 +3004,3 @@ footer .ui.language .menu {
 | 
			
		||||
.ui.user.list .item .description a:hover {
 | 
			
		||||
  text-decoration: underline;
 | 
			
		||||
}
 | 
			
		||||
.user.link-account:not(.icon) {
 | 
			
		||||
  padding-top: 15px;
 | 
			
		||||
  padding-bottom: 5px;
 | 
			
		||||
}
 | 
			
		||||
.signin .oauth2 div {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
}
 | 
			
		||||
.signin .oauth2 div p {
 | 
			
		||||
  margin: 10px 5px 0 0;
 | 
			
		||||
  float: left;
 | 
			
		||||
}
 | 
			
		||||
.signin .oauth2 a {
 | 
			
		||||
  margin-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
.signin .oauth2 a:last-child {
 | 
			
		||||
  margin-right: 0px;
 | 
			
		||||
}
 | 
			
		||||
.signin .oauth2 img {
 | 
			
		||||
  width: 32px;
 | 
			
		||||
  height: 32px;
 | 
			
		||||
}
 | 
			
		||||
@@ -5,11 +5,13 @@ jQuery.fn.autolink = function() {
 | 
			
		||||
		.each(function() {
 | 
			
		||||
			$(this).each(function() {
 | 
			
		||||
				if (re.test($(this).text()))
 | 
			
		||||
					$(this).replaceWith(
 | 
			
		||||
						$("<span />").html(
 | 
			
		||||
							this.nodeValue.replace(re, "<a href='$1'>$1</a>")
 | 
			
		||||
						)
 | 
			
		||||
					);
 | 
			
		||||
					if($(this).parents().filter('code').length === 0) {
 | 
			
		||||
						$(this).replaceWith(
 | 
			
		||||
							$("<span />").html(
 | 
			
		||||
								this.nodeValue.replace(re, "<a href='$1'>$1</a>")
 | 
			
		||||
							)
 | 
			
		||||
						);
 | 
			
		||||
					};
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
};
 | 
			
		||||
@@ -46,6 +46,27 @@
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.signin {
 | 
			
		||||
	.oauth2{
 | 
			
		||||
		div {
 | 
			
		||||
		  display: inline-block;
 | 
			
		||||
			p {
 | 
			
		||||
			  margin: 10px 5px 0 0;
 | 
			
		||||
			  float: left;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		a {
 | 
			
		||||
		  margin-right: 5px;
 | 
			
		||||
			&:last-child {
 | 
			
		||||
			  margin-right: 0px;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		img {
 | 
			
		||||
		  width: 32px;
 | 
			
		||||
		  height: 32px;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
.user.activate,
 | 
			
		||||
.user.forgot.password,
 | 
			
		||||
.user.reset.password,
 | 
			
		||||
@@ -85,7 +106,7 @@
 | 
			
		||||
			.header {
 | 
			
		||||
				padding-left: 0 !important;
 | 
			
		||||
				text-align: center;
 | 
			
		||||
			}			
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -114,4 +114,8 @@
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    &.link-account:not(.icon) {
 | 
			
		||||
        padding-top: 15px;
 | 
			
		||||
        padding-bottom: 5px;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -341,7 +341,7 @@ func RegisterRoutes(m *macaron.Macaron) {
 | 
			
		||||
						Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey)
 | 
			
		||||
					m.Combo("/:id").Get(repo.GetDeployKey).
 | 
			
		||||
						Delete(repo.DeleteDeploykey)
 | 
			
		||||
				})
 | 
			
		||||
				}, reqRepoWriter())
 | 
			
		||||
				m.Group("/issues", func() {
 | 
			
		||||
					m.Combo("").Get(repo.ListIssues).Post(bind(api.CreateIssueOption{}), repo.CreateIssue)
 | 
			
		||||
					m.Group("/comments", func() {
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@ func TestAPI_RenderGFM(t *testing.T) {
 | 
			
		||||
<ul>
 | 
			
		||||
<li><a href="` + AppSubURL + `wiki/Links" rel="nofollow">Links, Language bindings, Engine bindings</a></li>
 | 
			
		||||
<li><a href="` + AppSubURL + `wiki/Tips" rel="nofollow">Tips</a></li>
 | 
			
		||||
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>)<a href="https://github.com/ocornut/imgui/issues/786" rel="nofollow">#786</a></li>
 | 
			
		||||
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) https://github.com/ocornut/imgui/issues/786</li>
 | 
			
		||||
</ul>
 | 
			
		||||
`,
 | 
			
		||||
		// wine-staging wiki home extract: special wiki syntax, images
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,7 @@ func GlobalInit() {
 | 
			
		||||
 | 
			
		||||
	if setting.InstallLock {
 | 
			
		||||
		highlight.NewContext()
 | 
			
		||||
		markdown.InitMarkdown()
 | 
			
		||||
		markdown.NewSanitizer()
 | 
			
		||||
		if err := models.NewEngine(); err != nil {
 | 
			
		||||
			log.Fatal(4, "Failed to initialize ORM engine: %v", err)
 | 
			
		||||
 
 | 
			
		||||
@@ -596,6 +596,16 @@ func ViewIssue(ctx *context.Context) {
 | 
			
		||||
				ctx.Handle(500, "LoadMilestone", err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			ghostMilestone := &models.Milestone{
 | 
			
		||||
				ID:   -1,
 | 
			
		||||
				Name: ctx.Tr("repo.issues.deleted_milestone"),
 | 
			
		||||
			}
 | 
			
		||||
			if comment.OldMilestoneID > 0 && comment.OldMilestone == nil {
 | 
			
		||||
				comment.OldMilestone = ghostMilestone
 | 
			
		||||
			}
 | 
			
		||||
			if comment.MilestoneID > 0 && comment.Milestone == nil {
 | 
			
		||||
				comment.Milestone = ghostMilestone
 | 
			
		||||
			}
 | 
			
		||||
		} else if comment.Type == models.CommentTypeAssignees {
 | 
			
		||||
			if err = comment.LoadAssignees(); err != nil {
 | 
			
		||||
				ctx.Handle(500, "LoadAssignees", err)
 | 
			
		||||
 
 | 
			
		||||
@@ -78,7 +78,7 @@
 | 
			
		||||
					{{end}}
 | 
			
		||||
				</h4>
 | 
			
		||||
				<div class="ui attached table segment">
 | 
			
		||||
					{{if not $file.IsRenamed}}
 | 
			
		||||
					{{if ne $file.Type 4}}
 | 
			
		||||
						{{$isImage := (call $.IsImageFile $file.Name)}}
 | 
			
		||||
						{{if and $isImage}}
 | 
			
		||||
							<div class="center">
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user