├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── question.md ├── go.mod ├── go.sum ├── license ├── main.go └── readme.md /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug 🐞 3 | about: Something isn't working as expected? 4 | labels: bug 5 | --- 6 | 7 | ### Bug 🐞 8 | 9 | 10 | 11 | 12 | ### Steps to Reproduce: 13 | 14 | 1. 15 | 2. 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature ✨ 3 | about: Suggest new idea for the project 4 | labels: enhancement 5 | --- 6 | 7 | ### Feature ✨ 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 🤔 3 | about: Usage question or discussion 4 | labels: question 5 | --- 6 | 7 | ### Question 🤔 8 | 9 | 10 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nikitavoloboev/gitupdate 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/bmatcuk/doublestar v1.1.5/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= 2 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/deanishe/awgo v0.22.1 h1:N61eAOqc2u2zMQjY0Srd3mAn1gaj/9nU4YaTe3aaHU0= 5 | github.com/deanishe/awgo v0.22.1/go.mod h1:FIvY0LMPTrqEqSDy79rcSqL6+oFUhFL9qlXBi+qQKks= 6 | github.com/deanishe/go-env v0.4.0 h1:tpu14o16gJGTN/w2gxntwxu2l5Eby30jSrnlgOfjzwk= 7 | github.com/deanishe/go-env v0.4.0/go.mod h1:RgEcGAqdRnt8ybQteAbv1Ys2lWIRE7TlgON/sbdjuaY= 8 | github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= 9 | github.com/integrii/flaggy v1.4.3 h1:/NY/H9ul6i7vgu+2TKKo2zyY0gJK7GtuQMcAbrgqNEs= 10 | github.com/integrii/flaggy v1.4.3/go.mod h1:tnTxHeTJbah0gQ6/K0RW0J7fMUBk9MCF5blhm43LNpI= 11 | github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 12 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 13 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 14 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 15 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 16 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 17 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 18 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 19 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 20 | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= 21 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 22 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 23 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 24 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 25 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 26 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 27 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 28 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 29 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 30 | howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= 31 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Nikita Voloboev (nikitavoloboev.xyz) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | "os" 7 | "os/exec" 8 | "path/filepath" 9 | "strings" 10 | ) 11 | 12 | func removeDuplicates(elements []string) []string { 13 | encountered := map[string]bool{} 14 | result := []string{} 15 | 16 | for v := range elements { 17 | if encountered[elements[v]] == true { 18 | // Don't do anything 19 | } else { 20 | encountered[elements[v]] = true 21 | result = append(result, elements[v]) 22 | } 23 | } 24 | 25 | return result 26 | } 27 | 28 | func main() { 29 | // Option to only consider top level folders 30 | topLevelOnly := flag.Bool("top", false, "") 31 | 32 | args := os.Args 33 | if len(args) < 2 { 34 | log.Fatal("Please provide a path as argument.") 35 | } 36 | 37 | path, err := os.Getwd() 38 | if err != nil { 39 | log.Fatal(err) 40 | } 41 | 42 | if args[1:][0] == "." { 43 | update(path, *topLevelOnly) 44 | } else { 45 | update(path+"/"+args[1:][0], *topLevelOnly) 46 | } 47 | } 48 | 49 | // Track & update files in passed in path. 50 | // If it's folder, commit entire folder. If one file, commit the file. 51 | // Commit with file names as commit msg & push to remote. 52 | func update(path string, topLevelOnly bool) { 53 | cmd := exec.Command("git") 54 | file, err := os.Stat(path) 55 | if err != nil { 56 | log.Fatal(err) 57 | } 58 | // if it's not dir, then strip the extension 59 | if !file.IsDir() { 60 | path = filepath.Dir(path) 61 | } 62 | cmd.Dir = path 63 | cmd.Args = []string{"git", "add", path} 64 | _, err = cmd.Output() 65 | if err != nil { 66 | log.Fatal(err) 67 | } else { 68 | cmd = exec.Command("git") 69 | cmd.Dir = path 70 | cmd.Args = []string{"git", "diff", "--cached", "HEAD", "--name-only"} 71 | out, err := cmd.Output() 72 | if err != nil { 73 | log.Fatal(err) 74 | } else { 75 | outS := strings.Fields(string(out)) 76 | filesChanged := make([]string, 0) 77 | // Get all files changed without extension 78 | for _, v := range outS { 79 | split := strings.Split(v, "/") 80 | if topLevelOnly { 81 | first := split[0] 82 | filesChanged = append(filesChanged, first) 83 | } else { 84 | filename := split[len(split)-1] 85 | normalizedFilename := strings.TrimPrefix(filename, ".") 86 | basename := strings.Split(normalizedFilename, ".")[0] 87 | filesChanged = append(filesChanged, basename) 88 | } 89 | } 90 | filesChanged = removeDuplicates(filesChanged) 91 | 92 | // Commit with a message 93 | commitMsg := strings.Join(filesChanged, " ") 94 | cmd = exec.Command("git") 95 | cmd.Dir = path 96 | cmd.Args = []string{"git", "commit", "-m", commitMsg} 97 | _, err = cmd.Output() 98 | if err != nil { 99 | log.Fatal(err) 100 | } 101 | 102 | // Push changes 103 | cmd = exec.Command("git") 104 | cmd.Dir = path 105 | cmd.Args = []string{"git", "push"} 106 | _, err = cmd.Output() 107 | if err != nil { 108 | log.Fatal(err) 109 | } 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # GitUpdate [![Thanks](http://bit.ly/saythankss)](https://github.com/users/nikitavoloboev/sponsorship) 2 | 3 | > Commit and push updated files with file names as commit message 4 | 5 | ## Install 6 | 7 | ```Bash 8 | go install github.com/nikitavoloboev/gitupdate@latest 9 | ``` 10 | 11 | ## Usage 12 | 13 | You can either use it by passing it a file path (with git repo) that you want to commit. i.e. 14 | 15 | `gitupdate /Users/nikivi/src/cli/gitupdate` 16 | 17 | Or if you are already in the git directory you want to commit, run: 18 | 19 | `gitupdate .` 20 | 21 | This will add all files that have changed since last commit and will include all the file names (without extension) as the commit message. [Example use](https://github.com/nikitavoloboev/knowledge/commits/main). 22 | 23 | If you want to only consider top level folders for the commit message, use the `--top` (or `-t` for short) flag. 24 | 25 | I personally find it very useful for personal repos where commits are not that important (i.e. notes/dotfiles/docs). I treat these repos as write only so there is no point in wasting time writing a commit message. 26 | 27 | ## Run 28 | 29 | 1. Clone repo 30 | 2. If you use [VSCode](https://code.visualstudio.com) with [Go](https://github.com/microsoft/vscode-go) plugin, it will install all Go dependencies for you in the background when you open the project. 31 | 3. Edit the code & run it with `go run .`. 32 | 33 | I use [watchexec](https://github.com/watchexec/watchexec) to develop. 34 | 35 | Running `watchexec --exts go "echo -- && go run ."` will automatically rerun `go run .` for you on every Go file changed. 36 | 37 | ## Contribute 38 | 39 | Have idea how to improve or something is broken? 40 | 41 | Search for [existing issues](../../issues) or open [new one](../../issues/new/choose). 42 | 43 | PRs with code/docs changes are welcome. 44 | 45 | ## Thank you 46 | 47 | You can support me on [GitHub](https://github.com/sponsors/nikitavoloboev) or look into [other projects](https://nikiv.dev/projects) I shared. 48 | 49 | I also have [personal Discord](https://discord.com/invite/TVafwaD23d) you can join for more indepth discussions. 50 | 51 | [![MIT](http://bit.ly/mitbadge)](https://choosealicense.com/licenses/mit/) [![Twitter](http://bit.ly/nikitatweet)](https://twitter.com/nikitavoloboev) 52 | --------------------------------------------------------------------------------