summaryrefslogtreecommitdiffstats
path: root/pkg/commands
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2020-08-27 17:00:43 +1000
committerJesse Duffield <jessedduffield@gmail.com>2020-08-27 21:51:07 +1000
commitf99d5f74d49109c19f7701005e636a38c9a70fdb (patch)
tree1bd6d6ca761ceec37f10935fdf7405a9277c6464 /pkg/commands
parent30a066aa41cedabeebac0f9e747073ff33805893 (diff)
drop merge commits when interactive rebasing just like git CLI
Diffstat (limited to 'pkg/commands')
-rw-r--r--pkg/commands/commit.go3
-rw-r--r--pkg/commands/commit_list_builder.go24
-rw-r--r--pkg/commands/git.go16
-rw-r--r--pkg/commands/git_test.go6
4 files changed, 40 insertions, 9 deletions
diff --git a/pkg/commands/commit.go b/pkg/commands/commit.go
index 1e3a410c2..56e37a967 100644
--- a/pkg/commands/commit.go
+++ b/pkg/commands/commit.go
@@ -12,6 +12,9 @@ type Commit struct {
ExtraInfo string // something like 'HEAD -> master, tag: v0.15.2'
Author string
UnixTimestamp int64
+
+ // IsMerge tells us whether we're dealing with a merge commit i.e. a commit with two parents
+ IsMerge bool
}
func (c *Commit) ShortSha() string {
diff --git a/pkg/commands/commit_list_builder.go b/pkg/commands/commit_list_builder.go
index 73f7c305d..46c59d38b 100644
--- a/pkg/commands/commit_list_builder.go
+++ b/pkg/commands/commit_list_builder.go
@@ -57,7 +57,9 @@ func (c *CommitListBuilder) extractCommitFromLine(line string) *Commit {
unixTimestamp := split[1]
author := split[2]
extraInfo := strings.TrimSpace(split[3])
- message := strings.Join(split[4:], SEPARATION_CHAR)
+ parentHashes := split[4]
+
+ message := strings.Join(split[5:], SEPARATION_CHAR)
tags := []string{}
if extraInfo != "" {
@@ -70,6 +72,10 @@ func (c *CommitListBuilder) extractCommitFromLine(line string) *Commit {
unitTimestampInt, _ := strconv.Atoi(unixTimestamp)
+ // Any commit with multiple parents is a merge commit.
+ // If there's a space then it means there must be more than one parent hash
+ isMerge := strings.Contains(parentHashes, " ")
+
return &Commit{
Sha: sha,
Name: message,
@@ -77,6 +83,7 @@ func (c *CommitListBuilder) extractCommitFromLine(line string) *Commit {
ExtraInfo: extraInfo,
UnixTimestamp: int64(unitTimestampInt),
Author: author,
+ IsMerge: isMerge,
}
}
@@ -321,5 +328,18 @@ func (c *CommitListBuilder) getLogCmd(opts GetCommitsOptions) *exec.Cmd {
filterFlag = fmt.Sprintf(" --follow -- %s", c.OSCommand.Quote(opts.FilterPath))
}
- return c.OSCommand.ExecutableFromString(fmt.Sprintf("git log %s --oneline --pretty=format:\"%%H%s%%at%s%%aN%s%%d%s%%s\" %s --abbrev=%d --date=unix %s", opts.RefName, SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, limitFlag, 20, filterFlag))
+ return c.OSCommand.ExecutableFromString(
+ fmt.Sprintf(
+ "git log %s --oneline --pretty=format:\"%%H%s%%at%s%%aN%s%%d%s%%p%s%%s\" %s --abbrev=%d --date=unix %s",
+ opts.RefName,
+ SEPARATION_CHAR,
+ SEPARATION_CHAR,
+ SEPARATION_CHAR,
+ SEPARATION_CHAR,
+ SEPARATION_CHAR,
+ limitFlag,
+ 20,
+ filterFlag,
+ ),
+ )
}
diff --git a/pkg/commands/git.go b/pkg/commands/git.go
index c671c0b5f..3f671b9ff 100644
--- a/pkg/commands/git.go
+++ b/pkg/commands/git.go
@@ -910,7 +910,8 @@ func (c *GitCommand) PrepareInteractiveRebaseCommand(baseSha string, todo string
debug = "TRUE"
}
- splitCmd := str.ToArgv(fmt.Sprintf("git rebase --interactive --autostash --keep-empty --rebase-merges %s", baseSha))
+ cmdStr := fmt.Sprintf("git rebase --interactive --autostash --keep-empty %s", baseSha)
+ splitCmd := str.ToArgv(cmdStr)
cmd := c.OSCommand.command(splitCmd[0], splitCmd[1:]...)
@@ -962,11 +963,18 @@ func (c *GitCommand) GenerateGenericRebaseTodo(commits []*Commit, actionIndex in
todo := ""
for i, commit := range commits[0:baseIndex] {
- a := "pick"
+ var commitAction string
if i == actionIndex {
- a = action
+ commitAction = action
+ } else if commit.IsMerge {
+ // your typical interactive rebase will actually drop merge commits by default. Damn git CLI, you scary!
+ // doing this means we don't need to worry about rebasing over merges which always causes problems.
+ // you typically shouldn't be doing rebases that pass over merge commits anyway.
+ commitAction = "drop"
+ } else {
+ commitAction = "pick"
}
- todo = a + " " + commit.Sha + " " + commit.Name + "\n" + todo
+ todo = commitAction + " " + commit.Sha + " " + commit.Name + "\n" + todo
}
return todo, commits[baseIndex].Sha, nil
diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go
index 6e0d345ee..0991b96cd 100644
--- a/pkg/commands/git_test.go
+++ b/pkg/commands/git_test.go
@@ -1639,7 +1639,7 @@ func TestGitCommandRebaseBranch(t *testing.T) {
"master",
test.CreateMockCommand(t, []*test.CommandSwapper{
{
- Expect: "git rebase --interactive --autostash --keep-empty --rebase-merges master",
+ Expect: "git rebase --interactive --autostash --keep-empty master",
Replace: "echo",
},
}),
@@ -1652,7 +1652,7 @@ func TestGitCommandRebaseBranch(t *testing.T) {
"master",
test.CreateMockCommand(t, []*test.CommandSwapper{
{
- Expect: "git rebase --interactive --autostash --keep-empty --rebase-merges master",
+ Expect: "git rebase --interactive --autostash --keep-empty master",
Replace: "test",
},
}),
@@ -1775,7 +1775,7 @@ func TestGitCommandDiscardOldFileChanges(t *testing.T) {
"test999.txt",
test.CreateMockCommand(t, []*test.CommandSwapper{
{
- Expect: "git rebase --interactive --autostash --keep-empty --rebase-merges abcdef",
+ Expect: "git rebase --interactive --autostash --keep-empty abcdef",
Replace: "echo",
},
{