Skip to content

Commit 8a98fb6

Browse files
authored
πŸ”€ v.0.3.0 merge commit
## Features - Gitignore templates now include ".gut" to avoid committing user configuration - New command "git ignore update" to stop tracking previously committed files - The init command now prompts for a gitignore template - Errors generated from a dirty working tree are now more helpful - `gut save` now allows you specify an external editor (instead of using the built-in editor) ## Bug fixes - Color printing on the Windows Command Prompt should no longer print ANSI codes - `gut squash` now works with a local-only repository ## Deprecation ### Renaming the `gut undo` command As pointed out by an HN commenter, the 'undo' command is not well-named. Its role is to revert the working tree to the state of the last commit, not to undo the last commit. This is a subtle but important difference. Therefore, we should rename the command to something more appropriate. I think 'reset' is a good candidate.
2 parents 82a335f + 8cb75ea commit 8a98fb6

File tree

23 files changed

+301
-29
lines changed

23 files changed

+301
-29
lines changed

β€Žcmd/ignore.goβ€Ž

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,22 @@ var listTemplatesCmd = &cobra.Command{
4949
Aliases: []string{"ls"},
5050
}
5151

52+
var updateIgnoreCmd = &cobra.Command{
53+
Use: "update",
54+
Short: "Start ignoring previously committed files",
55+
Long: `Start ignoring previously committed files
56+
Sometimes, you may want to stop tracking files that were previously committed.
57+
However if you just add them to your .gitignore, they will still be tracked.
58+
To untrack the files that are already being tracked by Git and listed in your .gitignore, you can run this command.
59+
60+
If you want to add a template to your .gitignore, use the command 'gut ignore'.
61+
`,
62+
Run: controller.IgnoreUpdate,
63+
Aliases: []string{"up", "untrack", "fix"},
64+
}
65+
5266
func init() {
5367
rootCmd.AddCommand(ignoreCmd)
5468
ignoreCmd.AddCommand(listTemplatesCmd)
69+
ignoreCmd.AddCommand(updateIgnoreCmd)
5570
}

β€Žcmd/reset.goβ€Ž

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
Copyright Β© 2023 Julien CAGNIART
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in
12+
all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
THE SOFTWARE.
21+
*/
22+
package cmd
23+
24+
import (
25+
"github.com/julien040/gut/src/controller"
26+
"github.com/spf13/cobra"
27+
)
28+
29+
// undoCmd represents the undo command
30+
var resetCmd = &cobra.Command{
31+
Use: "reset [file]...",
32+
Short: "Rollback files specified to the last commit (require git)",
33+
Long: `Rollback the repository to the last commit. If you have uncommitted changes, they will be lost.
34+
If zero arguments are passed, all the files will be rolled back.
35+
If one or more arguments are passed, only the files passed as arguments will be rolled back.`,
36+
Run: controller.Undo,
37+
}
38+
39+
func init() {
40+
rootCmd.AddCommand(resetCmd)
41+
42+
}

β€Žcmd/save.goβ€Ž

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

3030
// saveCmd represents the save command
3131
var saveCmd = &cobra.Command{
32-
Use: "save [files...]",
32+
Use: "save [-e=[editor]] [-m=message] [-t=title] [files...]",
3333
Short: "Save (commit) your current work locally",
3434
Long: `Save (commit) your current work locally
3535
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.`,
36+
In case no files are passed as arguments, all files will be committed.
37+
38+
The -e flag allows you to specify the editor to use for writing the commit message.
39+
If you want to use the default Git editor, you can also use the -e flag without any argument (e.g., git save -e).
40+
To specify the editor, use the -e flag followed by the editor command (e.g. gut save -e="mate -w")`,
3741
Aliases: []string{"s", "commit"},
3842
Run: controller.Save,
3943
}
@@ -43,4 +47,12 @@ func init() {
4347
saveCmd.Flags().StringP("message", "m", "", "The commit message")
4448
saveCmd.Flags().StringP("title", "t", "", "The title of the commit")
4549

50+
// https://github.com/spf13/pflag#setting-no-option-default-values-for-flags
51+
// To set the default value of a flag to an empty string, use the NoOptDefVal field.
52+
// -e return config
53+
// -e "mate -w" return mate -w
54+
// no flag return none
55+
saveCmd.Flags().StringP("editor", "e", "none", "The editor to use to write the commit message. Set -e to use the default git editor or specify one with -e=\"editor\"")
56+
saveCmd.Flag("editor").NoOptDefVal = "config"
57+
4658
}

β€Žcmd/undo.goβ€Ž

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ THE SOFTWARE.
2222
package cmd
2323

2424
import (
25+
"fmt"
26+
2527
"github.com/julien040/gut/src/controller"
2628
"github.com/spf13/cobra"
2729
)
@@ -33,7 +35,10 @@ var undoCmd = &cobra.Command{
3335
Long: `Rollback the repository to the last commit. If you have uncommitted changes, they will be lost.
3436
If zero arguments are passed, all the files will be rolled back.
3537
If one or more arguments are passed, only the files passed as arguments will be rolled back.`,
36-
Run: controller.Undo,
38+
Run: func(cmd *cobra.Command, args []string) {
39+
fmt.Println("Starting from v.1.0.0, the undo command is deprecated. Please use the reset command instead.")
40+
controller.Undo(cmd, args)
41+
},
3742
}
3843

3944
func init() {

β€Žgo.modβ€Ž

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/BurntSushi/toml v1.2.1
99
github.com/briandowns/spinner v1.20.0
1010
github.com/charmbracelet/lipgloss v0.6.0
11-
github.com/fatih/color v1.13.0
11+
github.com/fatih/color v1.15.0
1212
github.com/go-git/go-git v4.7.0+incompatible
1313
github.com/go-git/go-git/v5 v5.5.1
1414
github.com/matoous/go-nanoid/v2 v2.0.0
@@ -56,8 +56,8 @@ require (
5656
github.com/inconshreveable/mousetrap v1.0.1 // indirect
5757
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
5858
github.com/kevinburke/ssh_config v1.2.0 // indirect
59-
github.com/mattn/go-colorable v0.1.9 // indirect
60-
github.com/mattn/go-isatty v0.0.16 // indirect
59+
github.com/mattn/go-colorable v0.1.13 // indirect
60+
github.com/mattn/go-isatty v0.0.17 // indirect
6161
github.com/pjbgf/sha1cd v0.3.0 // indirect
6262
github.com/sergi/go-diff v1.3.1 // indirect
6363
github.com/skeema/knownhosts v1.1.1 // indirect

β€Žgo.sumβ€Ž

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FM
6464
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
6565
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
6666
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
67+
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
68+
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
6769
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
6870
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
6971
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
@@ -125,11 +127,15 @@ github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlW
125127
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
126128
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
127129
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
130+
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
131+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
128132
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
129133
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
130134
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
131135
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
132136
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
137+
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
138+
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
133139
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
134140
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
135141
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=

β€Žsrc/controller/clone.goβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func Clone(cmd *cobra.Command, args []string) {
7070
}
7171

7272
/* --------------------------------- Clone repo ------------------------------ */
73-
fmt.Printf("\nYour repo is %s and will be cloned in %s", color.GreenString(repo), color.BlueString(path))
73+
fmt.Fprintf(color.Output, "\nYour repo is %s and will be cloned in %s", color.GreenString(repo), color.BlueString(path))
7474
s := spinner.New(spinner.CharSets[9], 100*time.Millisecond) // Build a new spinner
7575
s.Start()
7676
err = executor.Clone(repo, path, shouldConserveGitHistory)

β€Žsrc/controller/error.goβ€Ž

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ var (
1616
Err: errors.New("error reading input"),
1717
}
1818
errorWorkingTreeNotClean = GutError{
19-
Message: "I can't continue further because the working tree is not clean",
19+
Message: "I can't continue further because the working tree is not clean. Commit your changes with gut save",
2020
Code: 2,
2121
Err: errors.New("working tree not clean"),
2222
}
@@ -56,17 +56,21 @@ func getLinkForError(GutError GutError) string {
5656
//
5757
// This should be used when the error is known and can be resolved by the user
5858
func exitOnKnownError(typeOfError GutError, err error) {
59+
60+
// When the error is linked to the user input, we don't print the error message
61+
// because it's not useful
62+
if typeOfError.Code == 1 {
63+
os.Exit(1)
64+
return
65+
}
5966
// Print the error message to stderr
6067
fmt.Fprintln(os.Stderr, "")
6168
if err != nil {
6269
fmt.Fprintf(os.Stderr, color.RedString("%s (error: %s)\n"), color.RedString(typeOfError.Message), color.RedString(err.Error()))
63-
/* print.Message("%s (error: %s)", print.Error, typeOfError.Message, err.Error()) */
6470
} else {
6571
fmt.Fprintf(os.Stderr, "%s\n", color.RedString(typeOfError.Message))
66-
/* print.Message("%s", print.Error, typeOfError.Message) */
6772
}
6873
fmt.Fprintf(os.Stderr, "To resolve this issue, please follow the instructions on this page: %s\n", getLinkForError(typeOfError))
69-
/* print.Message("To resolve this issue, please follow the instructions on this page: %s", print.Optional, getLinkForError(typeOfError)) */
7074

7175
os.Exit(1)
7276
}

β€Žsrc/controller/ignore.goβ€Ž

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ func Ignore(cmd *cobra.Command, args []string) {
181181
}
182182
template := selectGitignoreTemplate(templates)
183183
gitignoreTemplateContent := splitStringByNewLine(template.contents)
184+
185+
// Add .gut to the gitignore template
186+
gitignoreTemplateContent = append(gitignoreTemplateContent, ".gut")
187+
184188
// Get the difference between the local .gitignore and the gitignore template
185189
diff := Difference(gitignoreContent, gitignoreTemplateContent)
186190
// Append the difference to the local .gitignore
@@ -233,3 +237,30 @@ func IgnoreList(cmd *cobra.Command, args []string) {
233237
print.Message("Here's the content of the "+temp.name+" template:", print.Info)
234238
fmt.Println(temp.contents)
235239
}
240+
241+
func IgnoreUpdate(cmd *cobra.Command, args []string) {
242+
wd, err := os.Getwd()
243+
if err != nil {
244+
exitOnError("Sorry, I can't get your current working directory πŸ˜“", err)
245+
}
246+
247+
// Check if a repo is initialized & git is installed
248+
checkIfGitRepoInitialized(wd)
249+
checkIfGitInstalled()
250+
251+
res, err := prompt.InputBool("Do you want to start untracking the files in the .gitignore that were previously tracked by git?", true)
252+
if err != nil {
253+
exitOnKnownError(errorReadInput, err)
254+
}
255+
256+
if res {
257+
err := executor.GitRmCached()
258+
if err != nil {
259+
exitOnError("Sorry, I couldn't untrack the files πŸ˜“", err)
260+
} else {
261+
print.Message("I've untracked the files for you πŸŽ‰", print.Success)
262+
}
263+
264+
}
265+
266+
}

β€Žsrc/controller/init.goβ€Ž

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package controller
22

33
import (
44
"os"
5+
"path/filepath"
56

67
"github.com/julien040/gut/src/executor"
78
"github.com/julien040/gut/src/print"
9+
"github.com/julien040/gut/src/prompt"
810
"github.com/spf13/cobra"
911
)
1012

@@ -25,6 +27,23 @@ func Init(cmd *cobra.Command, args []string) {
2527
exitOnError("Oups, something went wrong while initializing the repository", err)
2628
}
2729

30+
// Ask for a .gitignore
31+
res, err := prompt.InputBool("Do you want to create a .gitignore file?", true)
32+
if err != nil {
33+
exitOnKnownError(errorReadInput, err)
34+
}
35+
if res {
36+
getGitignoreContentFromPath(wd)
37+
templates, err := fetchIgnoreList()
38+
if err != nil {
39+
exitOnError("Sorry, I couldn't fetch the list of available gitignore templates πŸ˜“", err)
40+
}
41+
template := selectGitignoreTemplate(templates)
42+
gitignoreTemplateContent := splitStringByNewLine(template.contents)
43+
gitignoreTemplateContent = append(gitignoreTemplateContent, ".gut")
44+
appendToGitignore(filepath.Join(wd, ".gitignore"), gitignoreTemplateContent, template.name)
45+
}
46+
2847
associateProfileToPath(profile, wd)
2948
_, err = executor.Commit(wd, "πŸŽ‰ Initial commit from Gut", nil)
3049
if err != nil {

0 commit comments

Comments
Β (0)