Skip to content

Commit 357d5a5

Browse files
sapklunny
authored andcommitted
Backport to v1.2 of PR 2266 2467 2663 (#2788)
* Only check at least one email gpg key (#2266) * Only require one email (possibly not yet validated) * Update message error and check validation of commit * Add integrations tests * Complete integration for import * Add pre-check/optimization * Add some test (not finished) * Finish * Fix fixtures * Fix typo * Don't guess key ID * Make repo private to no interfere with other tests (#2467) * GPG key email verification no longer case sensitive (#2661) (#2663) * GPG key email verification no longer case sensitive (#2661) * case insensitive GPG key email verification now cached (#2661) Signed-off-by: Julian Scholle <[email protected]>
1 parent d81cf34 commit 357d5a5

36 files changed

+852
-24
lines changed

integrations/api_gpg_keys_test.go

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
// Copyright 2017 The Gogs Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package integrations
6+
7+
import (
8+
"net/http"
9+
"strconv"
10+
"testing"
11+
12+
"github.com/stretchr/testify/assert"
13+
14+
api "code.gitea.io/sdk/gitea"
15+
)
16+
17+
func TestGPGKeys(t *testing.T) {
18+
prepareTestEnv(t)
19+
session := loginUser(t, "user2")
20+
21+
tt := []struct {
22+
name string
23+
reqBuilder func(testing.TB, *http.Request, int) *TestResponse
24+
results []int
25+
}{
26+
{name: "NoLogin", reqBuilder: MakeRequest,
27+
results: []int{http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized},
28+
},
29+
{name: "LoggedAsUser2", reqBuilder: session.MakeRequest,
30+
results: []int{http.StatusOK, http.StatusOK, http.StatusNotFound, http.StatusNoContent, http.StatusInternalServerError, http.StatusInternalServerError, http.StatusCreated, http.StatusCreated}},
31+
}
32+
33+
for _, tc := range tt {
34+
35+
//Basic test on result code
36+
t.Run(tc.name, func(t *testing.T) {
37+
t.Run("ViewOwnGPGKeys", func(t *testing.T) {
38+
testViewOwnGPGKeys(t, tc.reqBuilder, tc.results[0])
39+
})
40+
t.Run("ViewGPGKeys", func(t *testing.T) {
41+
testViewGPGKeys(t, tc.reqBuilder, tc.results[1])
42+
})
43+
t.Run("GetGPGKey", func(t *testing.T) {
44+
testGetGPGKey(t, tc.reqBuilder, tc.results[2])
45+
})
46+
t.Run("DeleteGPGKey", func(t *testing.T) {
47+
testDeleteGPGKey(t, tc.reqBuilder, tc.results[3])
48+
})
49+
50+
t.Run("CreateInvalidGPGKey", func(t *testing.T) {
51+
testCreateInvalidGPGKey(t, tc.reqBuilder, tc.results[4])
52+
})
53+
t.Run("CreateNoneRegistredEmailGPGKey", func(t *testing.T) {
54+
testCreateNoneRegistredEmailGPGKey(t, tc.reqBuilder, tc.results[5])
55+
})
56+
t.Run("CreateValidGPGKey", func(t *testing.T) {
57+
testCreateValidGPGKey(t, tc.reqBuilder, tc.results[6])
58+
})
59+
t.Run("CreateValidSecondaryEmailGPGKey", func(t *testing.T) {
60+
testCreateValidSecondaryEmailGPGKey(t, tc.reqBuilder, tc.results[7])
61+
})
62+
})
63+
}
64+
65+
//Check state after basic add
66+
t.Run("CheckState", func(t *testing.T) {
67+
68+
var keys []*api.GPGKey
69+
70+
req := NewRequest(t, "GET", "/api/v1/user/gpg_keys") //GET all keys
71+
resp := session.MakeRequest(t, req, http.StatusOK)
72+
DecodeJSON(t, resp, &keys)
73+
74+
primaryKey1 := keys[0] //Primary key 1
75+
assert.EqualValues(t, "38EA3BCED732982C", primaryKey1.KeyID)
76+
assert.EqualValues(t, 1, len(primaryKey1.Emails))
77+
assert.EqualValues(t, "[email protected]", primaryKey1.Emails[0].Email)
78+
assert.EqualValues(t, true, primaryKey1.Emails[0].Verified)
79+
80+
subKey := primaryKey1.SubsKey[0] //Subkey of 38EA3BCED732982C
81+
assert.EqualValues(t, "70D7C694D17D03AD", subKey.KeyID)
82+
assert.EqualValues(t, 0, len(subKey.Emails))
83+
84+
primaryKey2 := keys[1] //Primary key 2
85+
assert.EqualValues(t, "FABF39739FE1E927", primaryKey2.KeyID)
86+
assert.EqualValues(t, 1, len(primaryKey2.Emails))
87+
assert.EqualValues(t, "[email protected]", primaryKey2.Emails[0].Email)
88+
assert.EqualValues(t, false, primaryKey2.Emails[0].Verified)
89+
90+
var key api.GPGKey
91+
req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(primaryKey1.ID, 10)) //Primary key 1
92+
resp = session.MakeRequest(t, req, http.StatusOK)
93+
DecodeJSON(t, resp, &key)
94+
assert.EqualValues(t, "38EA3BCED732982C", key.KeyID)
95+
assert.EqualValues(t, 1, len(key.Emails))
96+
assert.EqualValues(t, "[email protected]", key.Emails[0].Email)
97+
assert.EqualValues(t, true, key.Emails[0].Verified)
98+
99+
req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(subKey.ID, 10)) //Subkey of 38EA3BCED732982C
100+
resp = session.MakeRequest(t, req, http.StatusOK)
101+
DecodeJSON(t, resp, &key)
102+
assert.EqualValues(t, "70D7C694D17D03AD", key.KeyID)
103+
assert.EqualValues(t, 0, len(key.Emails))
104+
105+
req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(primaryKey2.ID, 10)) //Primary key 2
106+
resp = session.MakeRequest(t, req, http.StatusOK)
107+
DecodeJSON(t, resp, &key)
108+
assert.EqualValues(t, "FABF39739FE1E927", key.KeyID)
109+
assert.EqualValues(t, 1, len(key.Emails))
110+
assert.EqualValues(t, "[email protected]", key.Emails[0].Email)
111+
assert.EqualValues(t, false, key.Emails[0].Verified)
112+
113+
})
114+
115+
//Check state after basic add
116+
t.Run("CheckCommits", func(t *testing.T) {
117+
t.Run("NotSigned", func(t *testing.T) {
118+
var branch api.Branch
119+
req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/not-signed")
120+
resp := session.MakeRequest(t, req, http.StatusOK)
121+
DecodeJSON(t, resp, &branch)
122+
assert.EqualValues(t, false, branch.Commit.Verification.Verified)
123+
})
124+
125+
t.Run("SignedWithNotValidatedEmail", func(t *testing.T) {
126+
var branch api.Branch
127+
req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/good-sign-not-yet-validated")
128+
resp := session.MakeRequest(t, req, http.StatusOK)
129+
DecodeJSON(t, resp, &branch)
130+
assert.EqualValues(t, false, branch.Commit.Verification.Verified)
131+
})
132+
133+
t.Run("SignedWithValidEmail", func(t *testing.T) {
134+
var branch api.Branch
135+
req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/good-sign")
136+
resp := session.MakeRequest(t, req, http.StatusOK)
137+
DecodeJSON(t, resp, &branch)
138+
assert.EqualValues(t, true, branch.Commit.Verification.Verified)
139+
})
140+
})
141+
}
142+
143+
func testViewOwnGPGKeys(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
144+
req := NewRequest(t, "GET", "/api/v1/user/gpg_keys")
145+
reqBuilder(t, req, expected)
146+
}
147+
148+
func testViewGPGKeys(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
149+
req := NewRequest(t, "GET", "/api/v1/users/user2/gpg_keys")
150+
reqBuilder(t, req, expected)
151+
}
152+
153+
func testGetGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
154+
req := NewRequest(t, "GET", "/api/v1/user/gpg_keys/1")
155+
reqBuilder(t, req, expected)
156+
}
157+
158+
func testDeleteGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
159+
req := NewRequest(t, "DELETE", "/api/v1/user/gpg_keys/1")
160+
reqBuilder(t, req, expected)
161+
}
162+
163+
func testCreateGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int, publicKey string) {
164+
req := NewRequestWithJSON(t, "POST", "/api/v1/user/gpg_keys", api.CreateGPGKeyOption{
165+
ArmoredKey: publicKey,
166+
})
167+
reqBuilder(t, req, expected)
168+
}
169+
170+
func testCreateInvalidGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
171+
testCreateGPGKey(t, reqBuilder, expected, "invalid_key")
172+
}
173+
174+
func testCreateNoneRegistredEmailGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
175+
testCreateGPGKey(t, reqBuilder, expected, `-----BEGIN PGP PUBLIC KEY BLOCK-----
176+
177+
mQENBFmGUygBCACjCNbKvMGgp0fd5vyFW9olE1CLCSyyF9gQN2hSuzmZLuAZF2Kh
178+
dCMCG2T1UwzUB/yWUFWJ2BtCwSjuaRv+cGohqEy6bhEBV90peGA33lHfjx7wP25O
179+
7moAphDOTZtDj1AZfCh/PTcJut8Lc0eRDMhNyp/bYtO7SHNT1Hr6rrCV/xEtSAvR
180+
3b148/tmIBiSadaLwc558KU3ucjnW5RVGins3AjBZ+TuT4XXVH/oeLSeXPSJ5rt1
181+
rHwaseslMqZ4AbvwFLx5qn1OC9rEQv/F548QsA8m0IntLjoPon+6wcubA9Gra21c
182+
Fp6aRYl9x7fiqXDLg8i3s2nKdV7+e6as6Tp9ABEBAAG0FG5vdGtub3duQGV4YW1w
183+
bGUuY29tiQEcBBABAgAGBQJZhlMoAAoJEC8+pvYULDtte/wH/2JNrhmHwDY+hMj0
184+
batIK4HICnkKxjIgbha80P2Ao08NkzSge58fsxiKDFYAQjHui+ZAw4dq79Ax9AOO
185+
Iv2GS9+DUfWhrb6RF+vNuJldFzcI0rTW/z2q+XGKrUCwN3khJY5XngHfQQrdBtMK
186+
qsoUXz/5B8g422RTbo/SdPsyYAV6HeLLeV3rdgjI1fpaW0seZKHeTXQb/HvNeuPg
187+
qz+XV1g6Gdqa1RjDOaX7A8elVKxrYq3LBtc93FW+grBde8n7JL0zPM3DY+vJ0IJZ
188+
INx/MmBfmtCq05FqNclvU+sj2R3N1JJOtBOjZrJHQbJhzoILou8AkxeX1A+q9OAz
189+
1geiY5E=
190+
=TkP3
191+
-----END PGP PUBLIC KEY BLOCK-----`)
192+
}
193+
194+
func testCreateValidGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
195+
//User2 <[email protected]> //primary & activated
196+
testCreateGPGKey(t, reqBuilder, expected, `-----BEGIN PGP PUBLIC KEY BLOCK-----
197+
198+
mQENBFmGVsMBCACuxgZ7W7rI9xN08Y4M7B8yx/6/I4Slm94+wXf8YNRvAyqj30dW
199+
VJhyBcnfNRDLKSQp5o/hhfDkCgdqBjLa1PnHlGS3PXJc0hP/FyYPD2BFvNMPpCYS
200+
eu3T1qKSNXm6X0XOWD2LIrdiDC8HaI9FqZVMI/srMK2CF8XCL2m67W1FuoPlWzod
201+
5ORy0IZB7spoF0xihmcgnEGElRmdo5w/vkGH8U7Zyn9Eb57UVFeafgeskf4wqB23
202+
BjbMdW2YaB+yzMRwYgOnD5lnBD4uqSmvjaV9C0kxn7x+oJkkiRV8/z1cNcO+BaeQ
203+
Akh/yTTeTzYGSc/ZOqCX1O+NOPgSeixVlqenABEBAAG0GVVzZXIyIDx1c2VyMkBl
204+
eGFtcGxlLmNvbT6JAVQEEwEIAD4WIQRXgbSh0TtGbgRd7XI46jvO1zKYLAUCWYZW
205+
wwIbAwUJA8JnAAULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRA46jvO1zKYLF/e
206+
B/91wm2KLMIQBZBA9WA2/+9rQWTo9EqgYrXN60rEzX3cYJWXZiE4DrKR1oWDGNLi
207+
KXOCW62snvJldolBqq0ZqaKvPKzl0Y5TRqbYEc9AjUSqgRin1b+G2DevLGT4ibq+
208+
7ocQvz0XkASEUAgHahp0Ubiiib1521WwT/duL+AG8Gg0+DK09RfV3eX5/EOkQCKv
209+
8cutqgsd2Smz40A8wXuJkRcipZBtrB/GkUaZ/eJdwEeSYZjEA9GWF61LJT2stvRN
210+
HCk7C3z3pVEek1PluiFs/4VN8BG8yDzW4c0tLty4Fj3VwPqwIbB5AJbquVfhQCb4
211+
Eep2lm3Lc9b1OwO5N3coPJkouQENBFmGVsMBCADAGba2L6NCOE1i3WIP6CPzbdOo
212+
N3gdTfTgccAx9fNeon9jor+3tgEjlo9/6cXiRoksOV6W4wFab/ZwWgwN6JO4CGvZ
213+
Wi7EQwMMMp1E36YTojKQJrcA9UvMnTHulqQQ88F5E845DhzFQM3erv42QZZMBAX3
214+
kXCgy1GNFocl6tLUvJdEqs+VcJGGANMpmzE4WLa8KhSYnxipwuQ62JBy9R+cHyKT
215+
OARk8znRqSu5bT3LtlrZ/HXu+6Oy4+2uCdNzZIh5J5tPS7CPA6ptl88iGVBte/CJ
216+
7cjgJWSQqeYp2Y5QvsWAivkQ4Ww9plHbbwV0A2eaHsjjWzlUl3HoJ/snMOhBABEB
217+
AAGJATwEGAEIACYWIQRXgbSh0TtGbgRd7XI46jvO1zKYLAUCWYZWwwIbDAUJA8Jn
218+
AAAKCRA46jvO1zKYLBwLCACQOpeRVrwIKVaWcPMYjVHHJsGscaLKpgpARAUgbiG6
219+
Cbc2WI8Sm3fRwrY0VAfN+u9QwrtvxANcyB3vTgTzw7FimfhOimxiTSO8HQCfjDZF
220+
Xly8rq+Fua7+ClWUpy21IekW41VvZYjH2sL6EVP+UcEOaGAyN53XfhaRVZPhNtZN
221+
NKAE9N5EG3rbsZ33LzJj40rEKlzFSseAAPft8qA3IXjzFBx+PQXHMpNCagL79he6
222+
lqockTJ+oPmta4CF/J0U5LUr1tOZXheL3TP6m8d08gDrtn0YuGOPk87i9sJz+jR9
223+
uy6MA3VSB99SK9ducGmE1Jv8mcziREroz2TEGr0zPs6h
224+
=J59D
225+
-----END PGP PUBLIC KEY BLOCK-----`)
226+
}
227+
228+
func testCreateValidSecondaryEmailGPGKey(t *testing.T, reqBuilder func(testing.TB, *http.Request, int) *TestResponse, expected int) {
229+
//User2 <[email protected]> //secondary and not activated
230+
testCreateGPGKey(t, reqBuilder, expected, `-----BEGIN PGP PUBLIC KEY BLOCK-----
231+
232+
mQENBFmGWN4BCAC18V4tVGO65VLCV7p14FuXJlUtZ5CuYMvgEkcOqrvRaBSW9ao4
233+
PGESOhJpfWpnW3QgJniYndLzPpsmdHEclEER6aZjiNgReWPOjHD5tykWocZAJqXD
234+
eY1ym59gvVMLcfbV2yQsyR2hbJlc+dJsl16tigSEe3nwxZSw2IsW92pgEzT9JNUr
235+
Q+mC8dw4dqY0tYmFazYUGNxufUc/twgQT/Or1aNs0az5Q6Jft4rrTRsh/S7We0VB
236+
COKGkdcQyYgAls7HJBuPjQRi6DM9VhgBSHLAgSLyaUcZvhZBJr8Qe/q4PP3/kYDJ
237+
wm4RMnjOLz2pFZPgtRqgcAwpmFtLrACbEB3JABEBAAG0GlVzZXIyIDx1c2VyMjFA
238+
ZXhhbXBsZS5jb20+iQFUBBMBCAA+FiEEPOLHOjPSO42DWM57+r85c5/h6ScFAlmG
239+
WN4CGwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQ+r85c5/h6Sfx
240+
Lgf/dq64NBV8+X9an3seaLxePRviva48e4K67/wV/JxtXNO5Z/DhMGz5kHXCsG9D
241+
CXuWYO8ehlTjEnMZ6qqdDnY+H6bQsb2OS5oPn4RwpPXslAjEKtojPAr0dDsMS2DB
242+
dUuIm1AoOnewOVO0OFRf1EqX1bivxnN0FVMcO0m8AczfnKDaGb0y/qg/Y9JAsKqp
243+
j5pZNMWUkntRtGySeJ4CVJMmkVKJAHsa1Qj6MKdFeid4h4y94cBJ4ZdyBxNdpQOx
244+
ydf0doicovfeqGNO4oWzsGP4RBK2CqGPCUT+EFl20jPvMkKwOjxgqc8p0z3b2UT9
245+
+9bnmCGHgF/fW1HJ3iKmfFPqnLkBDQRZhljeAQgA5AirU/NJGgm19ZJYFOiHftjS
246+
azbrPxGeD3cSqmvDPIMc1DNZGfQV5D4EVumnVbQBtL6xHFoGKz9KisUMbe4a/X2J
247+
S8JmIphQWG0vMJX1DaZIzr2gT71MnPD7JMGsSUCh5dIKpTNTZX4w+oGPGOu0/UlL
248+
x0448AryKwp30J2p6D4GeI0nb03n35S2lTOpnHDn1wj7Jl/8LS2fdFOdNaNHXSZe
249+
twdSwJKhyBEiScgeHBDyKqo8zWkYoSb9eA2HiYlbVaiNtp24KP1mIEpiUdrRjWno
250+
zauYSZGHZlOFMgF4dKWuetPiuH9m7UYZGKyMLfQ9vYFb+xcPh2bLCQHJ1OEmMQAR
251+
AQABiQE8BBgBCAAmFiEEPOLHOjPSO42DWM57+r85c5/h6ScFAlmGWN4CGwwFCQPC
252+
ZwAACgkQ+r85c5/h6Sfjfwf+O4WEjRdvPJLxNy7mfAGoAqDMHIwyH/tVzYgyVhnG
253+
h/+cfRxJbGc3rpjYdr8dmvghzjEAout8uibPWaIqs63RCAPGPqgWLfxNO5c8+y8V
254+
LZMVOTV26l2olkkdBWAuhLqKTNh6TiQva03yhOgHWj4XDvFfxICWPFXVd6t5ELpD
255+
iApGu1OAj8JfhmzbG03Yzx+Ku7bWDxMonx3V/IDEu5LS5zrboHYDKCA53bXXghoi
256+
Aceqql+PKrDwEjoY4bptwMHLmcjGjdCQ//Qx1neho7nZcS7xjTucY8gQuulwCyXF
257+
y6wM+wMz8dunIG9gw4+Re6c4Rz9tX1kzxLrU7Pl21tMqfg==
258+
=0N/9
259+
-----END PGP PUBLIC KEY BLOCK-----`)
260+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ref: refs/heads/master
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[core]
2+
repositoryformatversion = 0
3+
filemode = true
4+
bare = true
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Unnamed repository; edit this file 'description' to name the repository.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/sh
2+
#
3+
# An example hook script to check the commit log message taken by
4+
# applypatch from an e-mail message.
5+
#
6+
# The hook should exit with non-zero status after issuing an
7+
# appropriate message if it wants to stop the commit. The hook is
8+
# allowed to edit the commit message file.
9+
#
10+
# To enable this hook, rename this file to "applypatch-msg".
11+
12+
. git-sh-setup
13+
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
14+
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
15+
:
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/sh
2+
#
3+
# An example hook script to check the commit log message.
4+
# Called by "git commit" with one argument, the name of the file
5+
# that has the commit message. The hook should exit with non-zero
6+
# status after issuing an appropriate message if it wants to stop the
7+
# commit. The hook is allowed to edit the commit message file.
8+
#
9+
# To enable this hook, rename this file to "commit-msg".
10+
11+
# Uncomment the below to add a Signed-off-by line to the message.
12+
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
13+
# hook is more suited to it.
14+
#
15+
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
16+
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
17+
18+
# This example catches duplicate Signed-off-by lines.
19+
20+
test "" = "$(grep '^Signed-off-by: ' "$1" |
21+
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
22+
echo >&2 Duplicate Signed-off-by lines.
23+
exit 1
24+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/sh
2+
#
3+
# An example hook script to prepare a packed repository for use over
4+
# dumb transports.
5+
#
6+
# To enable this hook, rename this file to "post-update".
7+
8+
exec git update-server-info
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/sh
2+
#
3+
# An example hook script to verify what is about to be committed
4+
# by applypatch from an e-mail message.
5+
#
6+
# The hook should exit with non-zero status after issuing an
7+
# appropriate message if it wants to stop the commit.
8+
#
9+
# To enable this hook, rename this file to "pre-applypatch".
10+
11+
. git-sh-setup
12+
precommit="$(git rev-parse --git-path hooks/pre-commit)"
13+
test -x "$precommit" && exec "$precommit" ${1+"$@"}
14+
:
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/bin/sh
2+
#
3+
# An example hook script to verify what is about to be committed.
4+
# Called by "git commit" with no arguments. The hook should
5+
# exit with non-zero status after issuing an appropriate message if
6+
# it wants to stop the commit.
7+
#
8+
# To enable this hook, rename this file to "pre-commit".
9+
10+
if git rev-parse --verify HEAD >/dev/null 2>&1
11+
then
12+
against=HEAD
13+
else
14+
# Initial commit: diff against an empty tree object
15+
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
16+
fi
17+
18+
# If you want to allow non-ASCII filenames set this variable to true.
19+
allownonascii=$(git config --bool hooks.allownonascii)
20+
21+
# Redirect output to stderr.
22+
exec 1>&2
23+
24+
# Cross platform projects tend to avoid non-ASCII filenames; prevent
25+
# them from being added to the repository. We exploit the fact that the
26+
# printable range starts at the space character and ends with tilde.
27+
if [ "$allownonascii" != "true" ] &&
28+
# Note that the use of brackets around a tr range is ok here, (it's
29+
# even required, for portability to Solaris 10's /usr/bin/tr), since
30+
# the square bracket bytes happen to fall in the designated range.
31+
test $(git diff --cached --name-only --diff-filter=A -z $against |
32+
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
33+
then
34+
cat <<\EOF
35+
Error: Attempt to add a non-ASCII file name.
36+
37+
This can cause problems if you want to work with people on other platforms.
38+
39+
To be portable it is advisable to rename the file.
40+
41+
If you know what you are doing you can disable this check using:
42+
43+
git config hooks.allownonascii true
44+
EOF
45+
exit 1
46+
fi
47+
48+
# If there are whitespace errors, print the offending file names and fail.
49+
exec git diff-index --check --cached $against --

0 commit comments

Comments
 (0)