Skip to content

Commit

Permalink
Add new rewrite command
Browse files Browse the repository at this point in the history
  • Loading branch information
kilpkonn committed Mar 23, 2021
1 parent 8607aec commit 335cb15
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 25 deletions.
66 changes: 66 additions & 0 deletions command/rewrite.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package command

import (
"bufio"
"fmt"
"github.com/DEVELOPEST/gtm-core/project"
"github.com/DEVELOPEST/gtm-core/scm"
"io"
"log"
"os"
"strings"

"github.com/mitchellh/cli"
)

// CommitCmd struct contain methods for commit command
type RewriteCmd struct {
UI cli.Ui
}

// NewCommit returns new CommitCmd struct
func NewRewrite() (cli.Command, error) {
return RewriteCmd{}, nil
}

// Help returns help for commit command
func (c RewriteCmd) Help() string {
helpText := `
Usage: gtm rewrite [options]
Automatically called on git history rewrite. Do not use manually!.
`
return strings.TrimSpace(helpText)
}

// Run executes commit commands with args
func (c RewriteCmd) Run(args []string) int {

reader := bufio.NewReader(os.Stdin)
for {
input, err := reader.ReadString('\n')
if err != nil {
if err != io.EOF {
log.Fatal(err)
}
break
}
input = strings.TrimSpace(input)
hashes := strings.Split(input, " ")
fmt.Println(hashes[0])
fmt.Println(hashes[1])
err = scm.RewriteNote(hashes[0], hashes[1], project.NoteNameSpace)

if err != nil {
log.Fatal(err)
}
}

return 0
}

// Synopsis return help for commit command
func (c RewriteCmd) Synopsis() string {
return "Update git notes on history rewrite"
}

5 changes: 5 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ func main() {
UI: ui,
}, nil
},
"rewrite": func() (cli.Command, error) {
return &command.RewriteCmd{
UI: ui,
}, nil
},
}

exitStatus, err := c.Run()
Expand Down
2 changes: 1 addition & 1 deletion metric/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func Process(interim bool, projPath ...string) (note.CommitNote, error) {
return note.CommitNote{}, err
}

if err := scm.CreateNote(note.Marshal(commitNote), project.NoteNameSpace); err != nil {
if err := scm.CreateNote(note.Marshal(commitNote), project.NoteNameSpace, ""); err != nil {
return note.CommitNote{}, err
}
if err := saveAndPurgeMetrics(gtmPath, metricMap, commitMap, readonlyMap); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion note/note.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func UnMarshal(s string) (CommitNote, error) {
}

default:
return CommitNote{}, fmt.Errorf("Unable to unmarshal time logged, unknown version %s", version)
continue // Ignore errors in syntax
}
}
sort.Sort(sort.Reverse(FileByTime(files)))
Expand Down
112 changes: 89 additions & 23 deletions scm/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ func HeadCommit(wd ...string) (Commit, error) {
}
defer repo.Free()

headCommit, err := lookupHeadCommit(repo)
headCommit, err := lookupCommit(repo)
if err != nil {
if err == ErrHeadUnborn {
return commit, nil
Expand All @@ -457,13 +457,14 @@ func HeadCommit(wd ...string) (Commit, error) {
}

// CreateNote creates a git note associated with the head commit
func CreateNote(noteTxt string, nameSpace string, wd ...string) error {
func CreateNote(noteTxt, nameSpace, commitHash string, wd ...string) error {
defer util.Profile()()

var (
repo *git.Repository
err error
prevNote *git.Note
commit *git.Commit
)

if len(wd) > 0 {
Expand All @@ -476,26 +477,33 @@ func CreateNote(noteTxt string, nameSpace string, wd ...string) error {
}
defer repo.Free()

headCommit, err := lookupHeadCommit(repo)
if commitHash != "" {

}
if commitHash != "" {
commit, err = lookupCommit(repo, commitHash)
} else {
commit, err = lookupCommit(repo)
}
if err != nil {
return err
}

sig := &git.Signature{
Name: headCommit.Author().Name,
Email: headCommit.Author().Email,
When: headCommit.Author().When,
Name: commit.Author().Name,
Email: commit.Author().Email,
When: commit.Author().When,
}

prevNote, err = repo.Notes.Read("refs/notes/"+nameSpace, headCommit.Id())
prevNote, err = repo.Notes.Read("refs/notes/"+nameSpace, commit.Id())

if prevNote != nil {
noteTxt += "\n" + prevNote.Message()
if err := repo.Notes.Remove(
"refs/notes/"+nameSpace,
prevNote.Author(),
prevNote.Committer(),
headCommit.Id()); err != nil {
commit.Id()); err != nil {
return err
}

Expand All @@ -504,11 +512,45 @@ func CreateNote(noteTxt string, nameSpace string, wd ...string) error {
}
}

_, err = repo.Notes.Create("refs/notes/"+nameSpace, sig, sig, headCommit.Id(), noteTxt, false)

_, err = repo.Notes.Create("refs/notes/"+nameSpace, sig, sig, commit.Id(), noteTxt, false)

return err
}

func RemoveNote(nameSpace, commitHash string, wd ...string) error {
var (
repo *git.Repository
err error
commit *git.Commit
)

if len(wd) > 0 {
repo, err = openRepository(wd[0])
} else {
repo, err = openRepository()
}
if err != nil {
return err
}
defer repo.Free()

commit, err = lookupCommit(repo, commitHash)

if err != nil {
return err
}

sig := &git.Signature{
Name: commit.Author().Name,
Email: commit.Author().Email,
When: commit.Author().When,
}

err = repo.Notes.Remove("refs/notes/"+nameSpace, sig, sig, commit.Id())
return err
}

// CommitNote contains a git note's details
type CommitNote struct {
ID string
Expand Down Expand Up @@ -611,6 +653,19 @@ func ReadNote(commitID string, nameSpace string, calcStats bool, wd ...string) (
}, nil
}

func RewriteNote(oldHash, newHash, nameSpace string, wd ...string) error {
oldNote, err := ReadNote(oldHash, nameSpace, true, wd...)
if err != nil {
return err
}
fmt.Println(oldNote.Note)
err = CreateNote(oldNote.Note, nameSpace, newHash, wd...)
if err != nil {
return err
}
return RemoveNote(nameSpace, oldHash, wd...)
}

// ConfigSet persists git configuration settings
func ConfigSet(settings map[string]string, wd ...string) error {
var (
Expand Down Expand Up @@ -984,23 +1039,34 @@ var (
ErrHeadUnborn = errors.New("Head commit not found")
)

func lookupHeadCommit(repo *git.Repository) (*git.Commit, error) {

headUnborn, err := repo.IsHeadUnborn()
if err != nil {
return nil, err
}
if headUnborn {
return nil, ErrHeadUnborn
}
func lookupCommit(repo *git.Repository, hash ...string) (*git.Commit, error) {
var (
oid *git.Oid
err error
)
if len(hash) > 0 {
oid, err = git.NewOid(hash[0])
if err != nil {
return nil, err
}
} else {
headUnborn, err := repo.IsHeadUnborn()
if err != nil {
return nil, err
}
if headUnborn {
return nil, ErrHeadUnborn
}

headRef, err := repo.Head()
if err != nil {
return nil, err
headRef, err := repo.Head()
if err != nil {
return nil, err
}
defer headRef.Free()
oid = headRef.Target()
}
defer headRef.Free()

commit, err := repo.LookupCommit(headRef.Target())
commit, err := repo.LookupCommit(oid)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 335cb15

Please sign in to comment.