├── .github └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── Makefile ├── README.md ├── go.mod ├── main.go └── omg.gif /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | 7 | build: 8 | name: Build 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout code 12 | uses: actions/checkout@master 13 | - name: Setup Go 14 | uses: actions/setup-go@v2 15 | with: 16 | go-version: 1.x 17 | - name: Build 18 | run: go build -v . 19 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | release: 10 | name: Release 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@master 15 | - name: Setup Go 16 | uses: actions/setup-go@v2 17 | with: 18 | go-version: 1.x 19 | - name: Cross build 20 | run: make cross 21 | - name: Create Release 22 | id: create_release 23 | uses: actions/create-release@master 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | with: 27 | tag_name: ${{ github.ref }} 28 | release_name: Release ${{ github.ref }} 29 | - name: Upload 30 | run: make upload 31 | env: 32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | git-fixauthor 2 | git-fixauthor.exe 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | BIN := git-fixauthor 2 | VERSION := $$(make -s show-version) 3 | CURRENT_REVISION := $(shell git rev-parse --short HEAD) 4 | BUILD_LDFLAGS := "-s -w -X main.revision=$(CURRENT_REVISION)" 5 | GOBIN ?= $(shell go env GOPATH)/bin 6 | export GO111MODULE=on 7 | 8 | .PHONY: all 9 | all: clean build 10 | 11 | .PHONY: build 12 | build: 13 | go build -ldflags=$(BUILD_LDFLAGS) -o $(BIN) . 14 | 15 | .PHONY: install 16 | install: 17 | go install -ldflags=$(BUILD_LDFLAGS) . 18 | 19 | .PHONY: show-version 20 | show-version: $(GOBIN)/gobump 21 | @gobump show -r . 22 | 23 | $(GOBIN)/gobump: 24 | @cd && go get github.com/x-motemen/gobump/cmd/gobump 25 | 26 | .PHONY: cross 27 | cross: $(GOBIN)/goxz 28 | goxz -n $(BIN) -pv=v$(VERSION) -build-ldflags=$(BUILD_LDFLAGS) . 29 | 30 | $(GOBIN)/goxz: 31 | cd && go get github.com/Songmu/goxz/cmd/goxz 32 | 33 | .PHONY: test 34 | test: build 35 | go test -v ./... 36 | 37 | .PHONY: clean 38 | clean: 39 | rm -rf $(BIN) goxz 40 | go clean 41 | 42 | .PHONY: bump 43 | bump: $(GOBIN)/gobump 44 | ifneq ($(shell git status --porcelain),) 45 | $(error git workspace is dirty) 46 | endif 47 | ifneq ($(shell git rev-parse --abbrev-ref HEAD),master) 48 | $(error current branch is not master) 49 | endif 50 | @gobump up -w . 51 | git commit -am "bump up version to $(VERSION)" 52 | git tag "v$(VERSION)" 53 | git push origin master 54 | git push origin "refs/tags/v$(VERSION)" 55 | 56 | .PHONY: upload 57 | upload: $(GOBIN)/ghr 58 | ghr "v$(VERSION)" goxz 59 | 60 | $(GOBIN)/ghr: 61 | cd && go get github.com/tcnksm/ghr 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # git-fixauthor 2 | 3 | ![OMG](https://raw.githubusercontent.com/mattn/git-fixauthor/master/omg.gif) 4 | 5 | Have you ever committed as different git author? 6 | 7 | ## Usage 8 | 9 | Don't worry, and calm down. Please drink a cup of water. Then, change the git author and email to real one. Next, git pull to get newest branch. And run this. 10 | 11 | ``` 12 | $ git fixauthor -name "Your Wrong Name" 13 | ``` 14 | 15 | Pray that someone else don't git push after your git pull. 16 | 17 | ``` 18 | $ git push --force 19 | ``` 20 | 21 | ## Installation 22 | 23 | ``` 24 | $ go get github.com/mattn/git-fixauthor 25 | ``` 26 | 27 | ## Disclaimer 28 | 29 | I will not compensate for any disadvantages that you have lost with my tool. If possible, you ask your administrator before using this. 30 | 31 | ## License 32 | 33 | MIT 34 | 35 | ## Author 36 | 37 | Yasuhiro Matsumoto (a.k.a. mattn) 38 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/mattn/git-fixauthor 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "log" 7 | "os" 8 | "os/exec" 9 | "strings" 10 | ) 11 | 12 | const name = "git-fixauthor" 13 | 14 | const version = "0.0.1" 15 | 16 | var revision = "HEAD" 17 | 18 | const fix = ` 19 | if [ "$GIT_COMMITTER_EMAIL" = "%[1]s" ] 20 | then 21 | export GIT_COMMITTER_NAME="$[2]s" 22 | export GIT_COMMITTER_EMAIL="$[3]s" 23 | fi 24 | if [ "$GIT_AUTHOR_EMAIL" = "%s[1]s" ] 25 | then 26 | export GIT_AUTHOR_NAME="$[2]s" 27 | export GIT_AUTHOR_EMAIL="$[3]s" 28 | fi 29 | ` 30 | 31 | var ( 32 | fromEmail = flag.String("email", "", "old email") 33 | ) 34 | 35 | func gitconfig(name string) string { 36 | b, err := exec.Command("git", "config", name).CombinedOutput() 37 | if err != nil { 38 | log.Fatalf("cannot get new name/email: %v", err) 39 | } 40 | return strings.TrimSpace(string(b)) 41 | } 42 | 43 | func main() { 44 | flag.Parse() 45 | if *fromEmail == "" { 46 | flag.Usage() 47 | os.Exit(1) 48 | } 49 | name := gitconfig("user.name") 50 | email := gitconfig("user.email") 51 | cmd := exec.Command("git", "filter-branch", "-f", "--env-filter", fmt.Sprintf(fix, *fromEmail, name, email), "HEAD") 52 | cmd.Stdout = os.Stdout 53 | cmd.Stderr = os.Stderr 54 | err := cmd.Run() 55 | if err != nil { 56 | log.Fatal(err) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /omg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattn/git-fixauthor/b54d75270229a7a5797fb58106c9e77c4349924a/omg.gif --------------------------------------------------------------------------------