Skip to content

Commit baefea3

Browse files
authored
Fix #732: Add LFS objects to base repository on merging (#7082)
On merge we walk the merge history and ensure that all lfs objects pointed to in the history are added to the base repository. This switches from relying on having git-lfs installed on the server, (and in fact .gitattributes being correctly installed.)
1 parent d145955 commit baefea3

File tree

7 files changed

+648
-292
lines changed

7 files changed

+648
-292
lines changed

integrations/api_helper_for_declarative_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,44 @@ func doAPICreateRepository(ctx APITestContext, empty bool, callback ...func(*tes
6666
}
6767
}
6868

69+
func doAPIAddCollaborator(ctx APITestContext, username string, mode models.AccessMode) func(*testing.T) {
70+
return func(t *testing.T) {
71+
permission := "read"
72+
73+
if mode == models.AccessModeAdmin {
74+
permission = "admin"
75+
} else if mode > models.AccessModeRead {
76+
permission = "write"
77+
}
78+
addCollaboratorOption := &api.AddCollaboratorOption{
79+
Permission: &permission,
80+
}
81+
req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/collaborators/%s?token=%s", ctx.Username, ctx.Reponame, username, ctx.Token), addCollaboratorOption)
82+
if ctx.ExpectedCode != 0 {
83+
ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
84+
return
85+
}
86+
ctx.Session.MakeRequest(t, req, http.StatusNoContent)
87+
}
88+
}
89+
90+
func doAPIForkRepository(ctx APITestContext, username string, callback ...func(*testing.T, api.Repository)) func(*testing.T) {
91+
return func(t *testing.T) {
92+
createForkOption := &api.CreateForkOption{}
93+
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/forks?token=%s", username, ctx.Reponame, ctx.Token), createForkOption)
94+
if ctx.ExpectedCode != 0 {
95+
ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)
96+
return
97+
}
98+
resp := ctx.Session.MakeRequest(t, req, http.StatusAccepted)
99+
var repository api.Repository
100+
DecodeJSON(t, resp, &repository)
101+
if len(callback) > 0 {
102+
callback[0](t, repository)
103+
}
104+
}
105+
}
106+
69107
func doAPIGetRepository(ctx APITestContext, callback ...func(*testing.T, api.Repository)) func(*testing.T) {
70108
return func(t *testing.T) {
71109
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", ctx.Username, ctx.Reponame, ctx.Token)

integrations/git_test.go

+38-5
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,23 @@ func testGit(t *testing.T, u *url.URL) {
3939

4040
u.Path = baseAPITestContext.GitPath()
4141

42+
forkedUserCtx := NewAPITestContext(t, "user4", "repo1")
43+
4244
t.Run("HTTP", func(t *testing.T) {
4345
PrintCurrentTest(t)
46+
ensureAnonymousClone(t, u)
4447
httpContext := baseAPITestContext
4548
httpContext.Reponame = "repo-tmp-17"
49+
forkedUserCtx.Reponame = httpContext.Reponame
4650

4751
dstPath, err := ioutil.TempDir("", httpContext.Reponame)
4852
assert.NoError(t, err)
4953
defer os.RemoveAll(dstPath)
5054

51-
t.Run("CreateRepo", doAPICreateRepository(httpContext, false))
52-
ensureAnonymousClone(t, u)
55+
t.Run("CreateRepoInDifferentUser", doAPICreateRepository(forkedUserCtx, false))
56+
t.Run("AddUserAsCollaborator", doAPIAddCollaborator(forkedUserCtx, httpContext.Username, models.AccessModeRead))
57+
58+
t.Run("ForkFromDifferentUser", doAPIForkRepository(httpContext, forkedUserCtx.Username))
5359

5460
u.Path = httpContext.GitPath()
5561
u.User = url.UserPassword(username, userPassword)
@@ -62,12 +68,23 @@ func testGit(t *testing.T, u *url.URL) {
6268
mediaTest(t, &httpContext, little, big, littleLFS, bigLFS)
6369

6470
t.Run("BranchProtectMerge", doBranchProtectPRMerge(&httpContext, dstPath))
71+
t.Run("MergeFork", func(t *testing.T) {
72+
t.Run("CreatePRAndMerge", doMergeFork(httpContext, forkedUserCtx, "master", httpContext.Username+":master"))
73+
t.Run("DeleteRepository", doAPIDeleteRepository(httpContext))
74+
rawTest(t, &forkedUserCtx, little, big, littleLFS, bigLFS)
75+
mediaTest(t, &forkedUserCtx, little, big, littleLFS, bigLFS)
76+
})
6577
})
6678
t.Run("SSH", func(t *testing.T) {
6779
PrintCurrentTest(t)
6880
sshContext := baseAPITestContext
6981
sshContext.Reponame = "repo-tmp-18"
7082
keyname := "my-testing-key"
83+
forkedUserCtx.Reponame = sshContext.Reponame
84+
t.Run("CreateRepoInDifferentUser", doAPICreateRepository(forkedUserCtx, false))
85+
t.Run("AddUserAsCollaborator", doAPIAddCollaborator(forkedUserCtx, sshContext.Username, models.AccessModeRead))
86+
t.Run("ForkFromDifferentUser", doAPIForkRepository(sshContext, forkedUserCtx.Username))
87+
7188
//Setup key the user ssh key
7289
withKeyFile(t, keyname, func(keyFile string) {
7390
t.Run("CreateUserKey", doAPICreateUserKey(sshContext, "test-key", keyFile))
@@ -81,8 +98,6 @@ func testGit(t *testing.T, u *url.URL) {
8198
assert.NoError(t, err)
8299
defer os.RemoveAll(dstPath)
83100

84-
t.Run("CreateRepo", doAPICreateRepository(sshContext, false))
85-
86101
t.Run("Clone", doGitClone(dstPath, sshURL))
87102

88103
little, big := standardCommitAndPushTest(t, dstPath)
@@ -91,8 +106,13 @@ func testGit(t *testing.T, u *url.URL) {
91106
mediaTest(t, &sshContext, little, big, littleLFS, bigLFS)
92107

93108
t.Run("BranchProtectMerge", doBranchProtectPRMerge(&sshContext, dstPath))
109+
t.Run("MergeFork", func(t *testing.T) {
110+
t.Run("CreatePRAndMerge", doMergeFork(sshContext, forkedUserCtx, "master", sshContext.Username+":master"))
111+
t.Run("DeleteRepository", doAPIDeleteRepository(sshContext))
112+
rawTest(t, &forkedUserCtx, little, big, littleLFS, bigLFS)
113+
mediaTest(t, &forkedUserCtx, little, big, littleLFS, bigLFS)
114+
})
94115
})
95-
96116
})
97117
}
98118

@@ -341,3 +361,16 @@ func doProtectBranch(ctx APITestContext, branch string, userToWhitelist string)
341361
assert.EqualValues(t, "success%3DBranch%2Bprotection%2Bfor%2Bbranch%2B%2527"+url.QueryEscape(branch)+"%2527%2Bhas%2Bbeen%2Bupdated.", flashCookie.Value)
342362
}
343363
}
364+
365+
func doMergeFork(ctx, baseCtx APITestContext, baseBranch, headBranch string) func(t *testing.T) {
366+
return func(t *testing.T) {
367+
var pr api.PullRequest
368+
var err error
369+
t.Run("CreatePullRequest", func(t *testing.T) {
370+
pr, err = doAPICreatePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, baseBranch, headBranch)(t)
371+
assert.NoError(t, err)
372+
})
373+
t.Run("MergePR", doAPIMergePullRequest(baseCtx, baseCtx.Username, baseCtx.Reponame, pr.Index))
374+
375+
}
376+
}

0 commit comments

Comments
 (0)