Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -747,13 +747,14 @@ bottom, each stack rising out of it and the current branch marked. Under each br
PR state and titles come from a local cache that's refreshed when it goes stale, and the commits
come from local git, so it stays quick.

`git stack log short` draws the same tree with just the branch names, one line each. It only reads
local git, so it never waits on GitHub. To make that what `git stack` and `git stack log` show,
`git stack log short` draws the same tree with just the branch names, one line each, and
`(needs restack)` after any branch whose parent has moved on. It only reads local git, so it never
waits on GitHub. To make that what `git stack` and `git stack log` show,
`git config --global stack.log.short true`; `git stack log long` still gets you the full tree.

```
❯ git stack log short
○ billing-webhook-retries
○ billing-webhook-retries (needs restack)
● billing-webhook-schema
│ ○ fix-login-timeout
├─┘
Expand Down
4 changes: 2 additions & 2 deletions cmd/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ func showLog(ctx context.Context, c *cli, m logMode) error {
}
o := app.ViewOptions{CurrentStackOnly: m.currentStack, PRs: app.PRsFresh, Commits: true}
if short {
// Names only: no PR state, commits or restack checks to work out.
o = app.ViewOptions{CurrentStackOnly: m.currentStack, SkipRestackCheck: true}
// Names and restack markers only: no PR state or commits to work out.
o = app.ViewOptions{CurrentStackOnly: m.currentStack}
}
v, err := a.View(ctx, repo, o)
if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions cmd/log_short.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ func newLogShortCmd(c *cli, currentStack *bool) *cobra.Command {
return &cobra.Command{
Use: "short",
Short: "Show every stack as a tree of branch names",
Long: `Shows the same tree as git stack log with only the branch names; no PRs, state
or commits. It reads nothing but local git, so it never touches the network.`,
Long: `Shows the same tree as git stack log with only the branch names, and
"(needs restack)" after any branch whose parent has moved on; no PRs, state or
commits. It reads nothing but local git, so it never touches the network.`,
Args: cobra.NoArgs,
ValidArgsFunction: completeNothing,
RunE: func(cmd *cobra.Command, _ []string) error {
Expand Down
11 changes: 11 additions & 0 deletions cmd/log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,17 @@ func TestLogShortAndStack(t *testing.T) {
if err != nil || !strings.Contains(out, "other") || !strings.Contains(errOut, "loose is in no stack") {
t.Errorf("log short -s on an untracked branch:\n%s\n%s (%v)", out, errOut, err)
}

// Moving trunk on leaves the bottom branches needing a restack.
gittest.Run(t, dir, "switch", "-q", "main")
gittest.Commit(t, dir, "main.txt", "more", "more")
out, errOut, err = runWith(t, f, "--cwd", dir, "log", "short")
if err != nil {
t.Fatalf("log short after trunk moved: %v\n%s", err, errOut)
}
if want := "○ c\n○ b\n○ a (needs restack)\n│ ○ other (needs restack)\n├─┘\n● main\n"; out != want {
t.Errorf("log short after trunk moved =\n%s\nwant\n%s", out, want)
}
}

// TestLogShortConfig checks that stack.log.short makes log and bare git stack
Expand Down
15 changes: 11 additions & 4 deletions pkg/ui/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ type LogOptions struct {
// would run past it is cut short with "…". 0 never cuts (not a
// terminal).
Width int
// Short shows only the branch names, with no PR, state or commits.
// Short shows only the branch names, with "(needs restack)" after those
// that need one, and no PR, state or commits.
Short bool
}

Expand Down Expand Up @@ -57,10 +58,11 @@ type LogOptions struct {
// ├─┘
// ■ main
//
// Short leaves just the branch names, one line each:
// Short leaves just the branch names, one line each, marking those that
// need a restack:
//
// ● feat-b
// ○ feat-a
// ○ feat-a (needs restack)
// │ ○ hotfix
// ├─┘
// ■ main
Expand Down Expand Up @@ -105,10 +107,15 @@ func RenderLog(v *app.View, o LogOptions) string {
gutter := prefix + st.Prefix.Render("│")
for i := len(s) - 1; i >= 0; i-- {
r := s[i]
b.WriteString(prefix + logMarker(r, st) + " " + logName(r, st) + "\n")
b.WriteString(prefix + logMarker(r, st) + " " + logName(r, st))
if o.Short {
if r.NeedsRestack {
b.WriteString(" " + st.Restack.Render("(needs restack)"))
}
b.WriteString("\n")
continue
}
b.WriteString("\n")
pr, title := logPR(r, o)
b.WriteString(FitLine(gutter+" "+pr, title, o.Width) + "\n")
if meta := logMeta(r, o); meta != "" {
Expand Down
2 changes: 1 addition & 1 deletion pkg/ui/log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func TestRenderLogPlain(t *testing.T) {
func TestRenderLogShort(t *testing.T) {
out := RenderLog(&app.View{Rows: logRows()}, LogOptions{Now: now, Short: true})
want := strings.Join([]string{
"○ feat/ui-tests",
"○ feat/ui-tests (needs restack)",
"● feat/ui",
"○ feat/api",
"│ ○ fix/typo",
Expand Down
4 changes: 3 additions & 1 deletion pkg/ui/picker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ func TestPickerNavigationKeys(t *testing.T) {

func TestPickerFilterKeepsTreeContext(t *testing.T) {
tm := newTestPicker(t, PickerOptions{})
// No waiting on "> hot": the renderer may draw just the last "t" after a
// cursor move, so the text need never appear whole. Messages are handled
// in order, so enter still sees the full filter.
tm.Type("hot")
waitForText(t, tm, "> hot")
tm.Send(tea.KeyPressMsg{Code: tea.KeyEnter})
p := finalPicker(t, tm)
if r := p.Result(); r.Branch != "hotfix" {
Expand Down
Loading