Skip to content

Instantly share code, notes, and snippets.

@ycamper
Last active January 28, 2021 20:09
Show Gist options
  • Save ycamper/0351d8f912e62d89c08c57a1501ccd41 to your computer and use it in GitHub Desktop.
Save ycamper/0351d8f912e62d89c08c57a1501ccd41 to your computer and use it in GitHub Desktop.
backup untracked files in git before you rm it
package main
// type go build git-safeclean.go and put it somewhere in your $PATH
// then before you type `git clean -fdx`, run `git safeclean`
import (
"bufio"
"bytes"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"github.com/otiai10/copy"
)
func fileStatus() []string {
ret := []string{}
f, err := exec.Command("git", "status", "-s").Output()
if err != nil {
panic(err)
}
scanner := bufio.NewScanner(bytes.NewReader(f))
for scanner.Scan() {
t := strings.TrimPrefix(scanner.Text(), "?? ")
ret = append(ret, t)
}
return ret
}
func mkdirIfNotExists(path string) {
if _, err := os.Stat(path); os.IsNotExist(err) {
if err := os.MkdirAll(path, 0700); err != nil {
panic(err)
}
}
}
func getProjName() string {
if path, err := os.Getwd(); err != nil {
panic(err)
} else {
c, err := filepath.Abs(path)
if err != nil {
panic(err)
}
return c
}
}
func makeBackupDir() string {
home, err := os.UserHomeDir()
if err != nil {
panic(err)
}
bdir := filepath.Join(home, ".gitbak", getProjName(), time.Now().Format("20060102150405"))
mkdirIfNotExists(bdir)
return bdir
}
func makeBackup(files []string) string {
dir := makeBackupDir()
for _, f := range files {
out := filepath.Join(dir, f)
if err := copy.Copy(f, out); err != nil {
panic(err)
}
}
return dir
}
func main() {
fmt.Println("Make backups of your untracked files here: ", makeBackup(fileStatus()))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment