Skip to content

Commit 82a335f

Browse files
authored
✨ Add sparse commit #57
You can now perform a commit without including all the files by specifying them as args: For example: gut save myfile.go myfile.js The function starts by verifying if all the paths are valid. Then, all the logic is passed down to src/executor/commit.go:Commit() If len(args)==0, it adds all the files to the staging area. Otherwise it empties the staging area and adds only the specified files.
2 parents 0277a80 + edee7d1 commit 82a335f

File tree

6 files changed

+124
-10
lines changed

6 files changed

+124
-10
lines changed

cmd/save.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ import (
2929

3030
// saveCmd represents the save command
3131
var saveCmd = &cobra.Command{
32-
Use: "save",
33-
Short: "Save (commit) your current work locally",
32+
Use: "save [files...]",
33+
Short: "Save (commit) your current work locally",
34+
Long: `Save (commit) your current work locally
35+
To commit only some files, pass them as arguments to the command.
36+
In case no files are passed as arguments, all files will be committed.`,
3437
Aliases: []string{"s", "commit"},
3538
Run: controller.Save,
3639
}

src/controller/init.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func Init(cmd *cobra.Command, args []string) {
2626
}
2727

2828
associateProfileToPath(profile, wd)
29-
_, err = executor.Commit(wd, "🎉 Initial commit from Gut")
29+
_, err = executor.Commit(wd, "🎉 Initial commit from Gut", nil)
3030
if err != nil {
3131
exitOnError("Oups, something went wrong while creating the first commit", err)
3232
}

src/controller/pathHelper.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,27 @@ func isDirectoryEmpty(path string) (bool, error) {
8787
}
8888
return false, err
8989
}
90+
91+
// Merge the path with the current directory if the path is relative
92+
// and return the absolute path
93+
// If the path is absolute, return the path
94+
func mergeLocalPathWithCurrDir(path string) string {
95+
wd, err := os.Getwd()
96+
if err != nil {
97+
exitOnError("Sorry, I can't get the current directory 😓", err)
98+
}
99+
if filepath.IsAbs(path) {
100+
return path
101+
}
102+
return filepath.Join(wd, path)
103+
}
104+
105+
// Predicate function to check if the paths exist
106+
func validatePaths(paths []string) error {
107+
for _, path := range paths {
108+
if !checkIfPathExist(mergeLocalPathWithCurrDir(path)) {
109+
return errors.New("the path " + path + " doesn't exist")
110+
}
111+
}
112+
return nil
113+
}

src/controller/save.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/briandowns/spinner"
1212
"github.com/julien040/gut/src/executor"
1313
"github.com/julien040/gut/src/print"
14+
"github.com/julien040/gut/src/prompt"
1415
"github.com/spf13/cobra"
1516
)
1617

@@ -108,6 +109,29 @@ func Save(cmd *cobra.Command, args []string) {
108109
// Check if the user config is set
109110
verifUserConfig(wd)
110111

112+
// Check if files have been passed as arguments
113+
if len(args) > 0 {
114+
err = validatePaths(args)
115+
if err != nil {
116+
exitOnError("I failed to validate the paths you entered", err)
117+
}
118+
119+
message := "The following files will be saved:\n"
120+
for _, arg := range args {
121+
message += "\t- " + arg + "\n"
122+
}
123+
message += "Do you want to continue?"
124+
125+
res, err := prompt.InputBool(message, true)
126+
if err != nil {
127+
exitOnKnownError(errorReadInput, err)
128+
}
129+
if !res {
130+
return
131+
}
132+
133+
}
134+
111135
// Get the flag from the cmd
112136
title := cmd.Flag("title").Value.String()
113137
message := cmd.Flag("message").Value.String()
@@ -120,7 +144,7 @@ func Save(cmd *cobra.Command, args []string) {
120144
sp.Start()
121145

122146
// Commit the changes
123-
Result, err := executor.Commit(wd, commitMessage)
147+
Result, err := executor.Commit(wd, commitMessage, args)
124148
sp.Stop()
125149
if err != nil {
126150
exitOnError("Error while committing", err)

src/executor/commit.go

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,49 @@ func AddAll(path string) error {
5353
}
5454
}
5555

56-
func Commit(path string, message string) (CommitResult, error) {
56+
// Remove all files from the staging area
57+
func RemoveAll(path string) error {
58+
// Check if git is installed
59+
isGitInstalled := IsGitInstalled()
60+
if isGitInstalled {
61+
// Run git add . to add all files using git
62+
// This is a workaround for the fact that go-git does not support .gitignore
63+
err := GitRemoveAll()
64+
65+
return err
66+
} else {
67+
repo, err := OpenRepo(path)
68+
if err != nil {
69+
return err
70+
}
71+
w, err := repo.Worktree()
72+
if err != nil {
73+
return err
74+
}
75+
// Replace the .gitignore file with the one in the repo
76+
replaceGitIgnore(w, filepath.Join(path, ".gitignore"))
77+
78+
// Remove all files
79+
err = w.Reset(&git.ResetOptions{
80+
Mode: git.MixedReset,
81+
})
82+
83+
return err
84+
}
85+
}
86+
87+
// Add a file to the staging area
88+
func AddIndexPath(w git.Worktree, path string) error {
89+
// Add the file
90+
_, err := w.Add(path)
91+
92+
return err
93+
}
94+
95+
// Commit the changes
96+
// If no files are passed as arguments, all files will be committed
97+
// Otherwise, only the files passed as arguments will be committed
98+
func Commit(path string, message string, file []string) (CommitResult, error) {
5799
repo, err := OpenRepo(path)
58100
if err != nil {
59101
return CommitResult{}, err
@@ -62,10 +104,26 @@ func Commit(path string, message string) (CommitResult, error) {
62104
if err != nil {
63105
return CommitResult{}, err
64106
}
65-
// Add all files
66-
err = AddAll(path)
67-
if err != nil {
68-
return CommitResult{}, err
107+
108+
// If no files are passed as arguments, add all files
109+
if len(file) == 0 {
110+
// Add all files
111+
err = AddAll(path)
112+
if err != nil {
113+
return CommitResult{}, err
114+
}
115+
} else {
116+
// Add only the files passed as arguments
117+
RemoveAll(path)
118+
replaceGitIgnore(w, filepath.Join(path, ".gitignore"))
119+
120+
for _, v := range file {
121+
// Add the file
122+
err = AddIndexPath(*w, v)
123+
if err != nil {
124+
return CommitResult{}, err
125+
}
126+
}
69127
}
70128

71129
status, err := w.Status()
@@ -87,7 +145,7 @@ func Commit(path string, message string) (CommitResult, error) {
87145
}
88146
}
89147
hash, err := w.Commit(message, &git.CommitOptions{
90-
All: true,
148+
// All: true,
91149
})
92150
if err != nil {
93151
return CommitResult{}, err

src/executor/git.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@ func GitAddAll() error {
205205
return runCommand("git", "add", ".")
206206
}
207207

208+
// Remove all the files from the index
209+
func GitRemoveAll() error {
210+
return runCommand("git", "reset", "HEAD", "--", ".")
211+
}
212+
208213
// Diff the index with the HEAD and return true if there is no diff
209214
func GitDiffIndexHead() (bool, error) {
210215
// If there is no diff, output will be empty

0 commit comments

Comments
 (0)