Skip to content

Commit 330d5e7

Browse files
Merge pull request #4 from prefapp/feat/allow-empty-commits
feat: Allow empty commits
2 parents 45c9bda + 6f7cb5a commit 330d5e7

2 files changed

Lines changed: 132 additions & 43 deletions

File tree

git/git.go

Lines changed: 125 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package git
22

33
import (
44
"context"
5+
"crypto/sha256"
56
"errors"
67
"fmt"
78
"os"
@@ -159,20 +160,29 @@ func getGroupedFiles(fileStatuses git.Status) ([]string, []string, []string, err
159160
case "?", "A":
160161
addedFiles = append(addedFiles, file)
161162
default:
162-
return nil, nil, nil, errors.New(
163-
fmt.Sprintf(
164-
"Unsupported status code %c for file %s",
165-
status.Worktree,
166-
file,
167-
),
163+
return nil, nil, nil, fmt.Errorf(
164+
"Unsupported status code %c for file %s",
165+
status.Worktree,
166+
file,
168167
)
169168
}
170169
}
171170

172171
return addedFiles, updatedFiles, deletedFiles, nil
173172
}
174173

175-
func UploadToRepo(ctx context.Context, client *github.Client, repo repository.Repository, path string, deletePath string, branch string, headBranch string, message string) (*github.Reference, *github.Response, error) {
174+
func UploadToRepo(
175+
ctx context.Context,
176+
client *github.Client,
177+
repo repository.Repository,
178+
path string,
179+
deletePath string,
180+
branch string,
181+
headBranch string,
182+
message string,
183+
createEmpty *bool,
184+
allowEmpty *bool,
185+
) (*github.Reference, *github.Response, error) {
176186

177187
// Get the current currentCommit
178188
currentCommit, err := getCurrentCommit(ctx, client, repo, headBranch)
@@ -186,52 +196,125 @@ func UploadToRepo(ctx context.Context, client *github.Client, repo repository.Re
186196
if err != nil {
187197
return nil, nil, err
188198
}
199+
addedAndUpdatedFiles := append(updatedFiles, addedFiles...)
189200

190-
// Create a blob for each file
191-
blobs := []*github.Blob{}
192-
filePaths := []string{}
193-
194-
// Delete the files
195-
// Get the files that are deleted
196-
fmt.Println("--- Deleted files--")
197-
fmt.Println(deletedFiles)
198-
199-
for _, file := range deletedFiles {
200-
if strings.HasPrefix(file, deletePath) {
201-
blobs = append(blobs, &github.Blob{
202-
SHA: nil,
203-
})
204-
205-
filePaths = append(filePaths, file)
201+
if (len(addedAndUpdatedFiles) == 0 && len(deletedFiles) == 0 && *allowEmpty) || *createEmpty {
202+
// In order to push an empty commit, we first need to create a
203+
// dummy file and commit it to the branch
204+
fileName := fmt.Sprintf("%x", sha256.Sum256(
205+
[]byte("firestartr-empty-commit-dummy.txt"),
206+
))
207+
dummy, err := os.Create(fileName)
208+
if err != nil {
209+
return nil, nil, err
206210
}
207-
}
211+
defer dummy.Close()
208212

209-
addedAndUpdatedFiles := append(updatedFiles, addedFiles...)
210-
// Get the updated files
211-
fmt.Println("--- Updated files--")
212-
fmt.Println(addedAndUpdatedFiles)
213+
blob, _, err := createBlobForFile(ctx, client, repo, fileName)
214+
if err != nil {
215+
return nil, nil, err
216+
}
217+
tree, _, err := createNewTree(
218+
ctx,
219+
client,
220+
repo,
221+
[]*github.Blob{blob},
222+
[]string{fileName},
223+
currentCommit.GetSHA(),
224+
)
225+
if err != nil {
226+
return nil, nil, err
227+
}
213228

214-
for _, file := range addedAndUpdatedFiles {
215-
blob, _, err := createBlobForFile(ctx, client, repo, file)
229+
commit, _, err := createNewCommit(
230+
ctx, client, repo, tree,
231+
currentCommit, message,
232+
)
233+
if err != nil {
234+
return nil, nil, err
235+
}
216236

217-
blobs = append(blobs, blob)
237+
// Then we delete it and set that commit as the new head commit
238+
// of the branch. This results in a commit that has no changes
239+
// with the main branch, but a different hash
240+
emptyTree, _, err := createNewTree(
241+
ctx,
242+
client,
243+
repo,
244+
[]*github.Blob{{SHA: nil}},
245+
[]string{fileName},
246+
commit.GetSHA(),
247+
)
248+
if err != nil {
249+
return nil, nil, err
250+
}
218251

252+
emptyCommit, _, err := createNewCommit(
253+
ctx, client, repo, emptyTree,
254+
currentCommit, message,
255+
)
219256
if err != nil {
220257
return nil, nil, err
221258
}
222259

223-
filePaths = append(filePaths, file)
224-
}
260+
ref, resp, respErr := setBranchToCommit(ctx, client, repo, branch, emptyCommit)
225261

226-
tree, _, err := createNewTree(ctx, client, repo, blobs, filePaths, currentCommit.GetSHA())
227-
if err != nil {
228-
return nil, nil, err
229-
}
262+
err = os.Remove(fileName)
263+
if err != nil {
264+
return nil, nil, err
265+
}
230266

231-
commit, _, err := createNewCommit(ctx, client, repo, tree, currentCommit, message)
232-
if err != nil {
233-
return nil, nil, err
267+
return ref, resp, respErr
268+
} else {
269+
if len(addedAndUpdatedFiles) > 0 || len(deletedFiles) > 0 {
270+
// Create a blob for each file
271+
blobs := []*github.Blob{}
272+
filePaths := []string{}
273+
274+
// Delete the files
275+
// Get the files that are deleted
276+
fmt.Println("--- Deleted files--")
277+
fmt.Println(deletedFiles)
278+
279+
for _, file := range deletedFiles {
280+
if strings.HasPrefix(file, deletePath) {
281+
blobs = append(blobs, &github.Blob{
282+
SHA: nil,
283+
})
284+
285+
filePaths = append(filePaths, file)
286+
}
287+
}
288+
289+
// Get the updated files
290+
fmt.Println("--- Updated files--")
291+
fmt.Println(addedAndUpdatedFiles)
292+
293+
for _, file := range addedAndUpdatedFiles {
294+
blob, _, err := createBlobForFile(ctx, client, repo, file)
295+
296+
blobs = append(blobs, blob)
297+
298+
if err != nil {
299+
return nil, nil, err
300+
}
301+
302+
filePaths = append(filePaths, file)
303+
}
304+
305+
tree, _, err := createNewTree(ctx, client, repo, blobs, filePaths, currentCommit.GetSHA())
306+
if err != nil {
307+
return nil, nil, err
308+
}
309+
310+
commit, _, err := createNewCommit(ctx, client, repo, tree, currentCommit, message)
311+
if err != nil {
312+
return nil, nil, err
313+
}
314+
315+
return setBranchToCommit(ctx, client, repo, branch, commit)
316+
} else {
317+
return nil, nil, errors.New("no new files to commit")
318+
}
234319
}
235-
236-
return setBranchToCommit(ctx, client, repo, branch, commit)
237320
}

main.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ func main() {
2424
message := flag.String("m", "Commit message", "Commit message")
2525
deletePath := flag.String("delete-path", "", "Path in the origin repository to delete files from before adding new ones")
2626
headBranch := flag.String("h", "", "Head branch name")
27+
createEmpty := flag.Bool("e", false, "Create an empty commit")
28+
allowEmpty := flag.Bool("a", false, "Allow empty commits")
2729
flag.Parse()
2830

2931
if *headBranch == "" {
@@ -56,7 +58,11 @@ func main() {
5658
}
5759

5860
// upload files
59-
ref, _, err := git.UploadToRepo(context.Background(), client, parsedRepo, *dir, *deletePath, *branch, *headBranch, *message)
61+
ref, _, err := git.UploadToRepo(
62+
context.Background(), client, parsedRepo,
63+
*dir, *deletePath, *branch, *headBranch,
64+
*message, createEmpty, allowEmpty,
65+
)
6066

6167
if err != nil {
6268
fmt.Println("Error uploading files:", err)

0 commit comments

Comments
 (0)