@@ -2,16 +2,47 @@ package git
22
33import (
44 "context"
5+ "errors"
56 "fmt"
67 "os"
7- "path/filepath"
88 "strings"
99
1010 "github.com/cli/go-gh/v2/pkg/repository"
11+ "github.com/go-git/go-git/v6"
1112 "github.com/google/go-github/v67/github"
12- "github.com/prefapp/gh-commit/utils"
1313)
1414
15+ func getGitPorcelain (dirPath string ) (git.Status , error ) {
16+ repo , err := git .PlainOpen (dirPath )
17+ if err != nil {
18+ return nil , err
19+ }
20+ wt , err := repo .Worktree ()
21+ if err != nil {
22+ return nil , err
23+ }
24+ status , err := wt .Status ()
25+ if err != nil {
26+ return nil , err
27+ }
28+ return status , nil
29+ }
30+
31+ func GetHeadBranch (repoPath string ) (string , error ) {
32+ repo , err := git .PlainOpen (repoPath )
33+ if err != nil {
34+ return "" , err
35+ }
36+
37+ head , err := repo .Head ()
38+ if err != nil {
39+ return "" , err
40+ }
41+ headBranchName := strings .Split (head .Name ().String (), "/" )[2 ]
42+
43+ return headBranchName , nil
44+ }
45+
1546func getCurrentCommit (ctx context.Context , client * github.Client , repo repository.Repository , branch string ) (* github.RepositoryCommit , error ) {
1647
1748 // Get the branch reference
@@ -94,112 +125,105 @@ func setBranchToCommit(ctx context.Context, client *github.Client, repo reposito
94125
95126 ref := fmt .Sprintf ("refs/heads/%s" , branch )
96127
97- return client .Git .UpdateRef (ctx , repo .Owner , repo .Name , & github.Reference {
98- Ref : github .String (ref ),
99- Object : & github.GitObject {
100- SHA : commit .SHA ,
101- },
102- }, true )
103- }
104-
105- func listFilesOrigin (ctx context.Context , client * github.Client , repo repository.Repository , branch string ) ([]string , error ) {
128+ refExists , _ , _ := client .Git .GetRef (ctx , repo .Owner , repo .Name , ref )
106129
107- // Get the current commit
108- currentCommit , err := getCurrentCommit (ctx , client , repo , branch )
109- if err != nil {
110- return nil , err
111- }
112-
113- // Get the tree
114- tree , _ , err := client .Git .GetTree (ctx , repo .Owner , repo .Name , * currentCommit .Commit .Tree .SHA , true )
115- // If there is an error here most likely the tree is not found and the repository is empty
116- if err != nil {
117- return []string {}, nil
118- }
119-
120- // Get the files
121- files := []string {}
122- for _ , entry := range tree .Entries {
123- files = append (files , * entry .Path )
130+ if refExists == nil {
131+ return client .Git .CreateRef (ctx , repo .Owner , repo .Name , & github.Reference {
132+ Ref : github .String (ref ),
133+ Object : & github.GitObject {
134+ SHA : commit .SHA ,
135+ },
136+ })
137+ } else {
138+ return client .Git .UpdateRef (ctx , repo .Owner , repo .Name , & github.Reference {
139+ Ref : github .String (ref ),
140+ Object : & github.GitObject {
141+ SHA : commit .SHA ,
142+ },
143+ }, true )
124144 }
125145
126- return files , nil
127146}
128147
129- func getDeletedFiles (basePath string , originFiles []string , deletedPath string , updatedFiles []string ) []string {
130-
131- files := []string {}
132- fmt .Println ("--- Origin files--" )
133- fmt .Println (originFiles )
134- for _ , f := range originFiles {
135- if deletedPath == "" && ! utils .FileExistsInList (updatedFiles , filepath .Join (basePath , f )) && (strings .HasSuffix (f , ".yml" ) || strings .HasSuffix (f , ".yaml" )) {
136- files = append (files , f )
137- continue
138- }
139- if strings .HasPrefix (f , deletedPath ) && ! utils .FileExistsInList (updatedFiles , filepath .Join (basePath , f )) {
140- files = append (files , f )
141- continue
148+ func getGroupedFiles (fileStatuses git.Status ) ([]string , []string , []string , error ) {
149+ addedFiles := []string {}
150+ updatedFiles := []string {}
151+ deletedFiles := []string {}
152+
153+ for file , status := range fileStatuses {
154+ switch fmt .Sprintf ("%c" , status .Worktree ) {
155+ case "D" :
156+ deletedFiles = append (deletedFiles , file )
157+ case "M" , "R" , "C" , "U" :
158+ updatedFiles = append (updatedFiles , file )
159+ case "?" , "A" :
160+ addedFiles = append (addedFiles , file )
161+ 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+ ),
168+ )
142169 }
143170 }
144171
145- return files
146-
172+ return addedFiles , updatedFiles , deletedFiles , nil
147173}
148174
149- func UploadToRepo (ctx context.Context , client * github.Client , repo repository.Repository , path string , deletePath string , branch string , message string ) (* github.Reference , * github.Response , error ) {
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 ) {
150176
151177 // Get the current currentCommit
152- currentCommit , err := getCurrentCommit (ctx , client , repo , branch )
178+ currentCommit , err := getCurrentCommit (ctx , client , repo , headBranch )
153179 if err != nil {
154- panic ( err )
180+ return nil , nil , err
155181 }
156182
157- // List all files in the path
158- files := utils .ListFiles (path , []string {".git" })
159- fmt .Println ("--- Files--" )
160- fmt .Println (files )
161- // Get a list of deleted files, this means that the files that are in the origin repository inspecting the tree but in the files list
162- // are not present
163- originFiles , err := listFilesOrigin (ctx , client , repo , branch )
183+ fileStatuses , err := getGitPorcelain (path )
164184
185+ addedFiles , updatedFiles , deletedFiles , err := getGroupedFiles (fileStatuses )
165186 if err != nil {
166187 return nil , nil , err
167188 }
168189
169190 // Create a blob for each file
170191 blobs := []* github.Blob {}
171- blobPaths := []string {}
192+ filePaths := []string {}
172193
173194 // Delete the files
174195 // Get the files that are deleted
175- deletedFiles := getDeletedFiles (path , originFiles , deletePath , files )
176196 fmt .Println ("--- Deleted files--" )
177197 fmt .Println (deletedFiles )
178198
179- for _ , f := range deletedFiles {
180- blobs = append (blobs , & github.Blob {
181- SHA : nil ,
182- })
183- blobPaths = append (blobPaths , f )
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 )
206+ }
184207 }
185208
209+ addedAndUpdatedFiles := append (updatedFiles , addedFiles ... )
186210 // Get the updated files
187211 fmt .Println ("--- Updated files--" )
188- fmt .Println (files )
212+ fmt .Println (addedAndUpdatedFiles )
189213
190- for _ , file := range files {
191- blob , _ , _ := createBlobForFile (ctx , client , repo , file )
214+ for _ , file := range addedAndUpdatedFiles {
215+ blob , _ , err := createBlobForFile (ctx , client , repo , file )
192216
193217 blobs = append (blobs , blob )
194- relativePath , err := filepath .Rel (path , file )
195218
196219 if err != nil {
197220 return nil , nil , err
198221 }
199- blobPaths = append (blobPaths , relativePath )
222+
223+ filePaths = append (filePaths , file )
200224 }
201225
202- tree , _ , err := createNewTree (ctx , client , repo , blobs , blobPaths , currentCommit .GetSHA ())
226+ tree , _ , err := createNewTree (ctx , client , repo , blobs , filePaths , currentCommit .GetSHA ())
203227 if err != nil {
204228 return nil , nil , err
205229 }
@@ -210,5 +234,4 @@ func UploadToRepo(ctx context.Context, client *github.Client, repo repository.Re
210234 }
211235
212236 return setBranchToCommit (ctx , client , repo , branch , commit )
213-
214237}
0 commit comments