Skip to content
Closed
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
67 changes: 67 additions & 0 deletions gitcmds/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2026-present unTill Software Development Group B.V.
* @author Denis Gribanov
*/

package gitcmds

import "strings"

// LoadRepoContext gathers repository state needed by Dev() in minimal git round-trips.
// Phase 1 runs five independent local git commands concurrently.
// Phase 2 issues one gh API call that requires Org/Repo obtained in phase 1.
func LoadRepoContext(wd string) (*RepoContext, error) {
rc := &RepoContext{}

type result struct {
setFn func()
err error
}

const numConcurrent = 5
ch := make(chan result, numConcurrent)

go func() {
v, err := HasRemote(wd, "upstream")
ch <- result{setFn: func() { rc.UpstreamExists = v }, err: err}
}()

go func() {
repo, org, err := GetRepoAndOrgName(wd)
ch <- result{setFn: func() { rc.Repo = repo; rc.Org = org }, err: err}
}()

go func() {
v, err := GetCurrentBranchName(wd)
ch <- result{setFn: func() { rc.CurrentBranch = v }, err: err}
}()

go func() {
v, err := GetMainBranch(wd)
ch <- result{setFn: func() { rc.MainBranch = v }, err: err}
}()

go func() {
v, err := HaveUncommittedChanges(wd)
ch <- result{setFn: func() { rc.HasUncommittedChanges = v }, err: err}
}()

for range numConcurrent {
r := <-ch
if r.err != nil {
return nil, r.err
}
r.setFn()
}

rc.IsMain = strings.EqualFold(rc.CurrentBranch, rc.MainBranch)

// Phase 2: gh API call needs Org/Repo from phase 1
parentRepo, err := getParentRepoByOrgRepo(wd, rc.Org, rc.Repo)
if err != nil {
return nil, err
}
rc.ParentRepo = parentRepo

return rc, nil
}
19 changes: 12 additions & 7 deletions gitcmds/gitcmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,13 +479,8 @@ func GetBranchType(wd string) (string, notesPkg.BranchType, error) {
return currentBranchName, GetBranchTypeByName(currentBranchName), nil
}

// GetParentRepoName - parent repo of forked
func GetParentRepoName(wd string) (name string, err error) {
repo, org, err := GetRepoAndOrgName(wd)
if err != nil {
return "", err
}

// getParentRepoByOrgRepo fetches the parent repository full name via the GitHub API.
func getParentRepoByOrgRepo(wd, org, repo string) (string, error) {
stdout, stderr, err := new(exec.PipedExec).
Command("gh", "api", "repos/"+org+slash+repo, "--jq", ".parent.full_name").

@augmentcode augmentcode Bot Jun 9, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gitcmds/gitcmds.go:485: Using --jq ".parent.full_name" can return the literal string null for non-fork repos, which would make len(parentRepo) > 0 checks mis-detect a fork and potentially break single-remote workflows.

Severity: high

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

WorkingDir(wd).
Expand All @@ -503,6 +498,16 @@ func GetParentRepoName(wd string) (name string, err error) {
return strings.TrimSpace(stdout), nil
}

// GetParentRepoName - parent repo of forked
func GetParentRepoName(wd string) (name string, err error) {
repo, org, err := GetRepoAndOrgName(wd)
if err != nil {
return "", err
}

return getParentRepoByOrgRepo(wd, org, repo)
}

// IsBranchInMain Is my branch in main org?
func IsBranchInMain(wd string) (bool, error) {
repo, org, err := GetRepoAndOrgName(wd)
Expand Down
3 changes: 3 additions & 0 deletions gitcmds/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ func getListOfChangedFiles(wd, statusOutput string) ([]fileInfo, error) {
oldSize = newFileSize
case `??`:
newFileSize, err2 = getFileSize(wd, name)
case `AD`:

@augmentcode augmentcode Bot Jun 9, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gitcmds/status.go:168: Treating status AD as "never existed" and continue may hide a real staged add (index) vs deleted working-tree state, causing changed-file accounting to be silently wrong for that edge case.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep Code Review Agent🐛

AD means the blob is still staged even though the working-tree file was deleted, so continue hides content that would still be included by git commit. This makes qs status omit the staged file from the positive-delta summary instead of reporting the indexed addition.

Severity: low


🤖 Was this useful? React with 👍 or 👎

// file was added, then removed -> consider it never existed
continue
default:
return nil, fmt.Errorf("unknown file status %s for file %s", statusCode, name)
}
Expand Down
12 changes: 12 additions & 0 deletions gitcmds/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@ type PRInfo struct {
Title string `json:"title"`
URL string `json:"url"`
}

// RepoContext holds repository state gathered upfront for Dev()
type RepoContext struct {
Repo string
Org string
CurrentBranch string
MainBranch string
IsMain bool
HasUncommittedChanges bool
UpstreamExists bool
ParentRepo string
}
20 changes: 10 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
module github.com/untillpro/qs

go 1.26.0
go 1.26.2

require (
github.com/atotto/clipboard v0.1.4
github.com/coreos/go-semver v0.3.1
github.com/fatih/color v1.18.0
github.com/go-git/go-git/v5 v5.16.5
github.com/fatih/color v1.19.0
github.com/go-git/go-git/v5 v5.18.0
github.com/google/uuid v1.6.0
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.11.1
github.com/untillpro/goutils v0.0.0-20231201170327-3c33c6010100
github.com/voedger/voedger v1.202405300917.1
golang.org/x/mod v0.33.0
golang.org/x/mod v0.35.0
)

require (
dario.cat/mergo v1.0.2 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.3.0 // indirect
github.com/ProtonMail/go-crypto v1.4.1 // indirect
github.com/cloudflare/circl v1.6.3 // indirect
github.com/cyphar/filepath-securejoin v0.6.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.7.0 // indirect
github.com/go-git/go-billy/v5 v5.8.0 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.6.0 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-isatty v0.0.21 // indirect
github.com/pjbgf/sha1cd v0.5.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sergi/go-diff v1.4.0 // indirect
github.com/skeema/knownhosts v1.3.2 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
golang.org/x/crypto v0.48.0 // indirect
golang.org/x/net v0.50.0 // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/crypto v0.50.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/sys v0.43.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
45 changes: 22 additions & 23 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
github.com/ProtonMail/go-crypto v1.4.1 h1:9RfcZHqEQUvP8RzecWEUafnZVtEvrBVL9BiF67IQOfM=
github.com/ProtonMail/go-crypto v1.4.1/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
Expand All @@ -25,18 +25,18 @@ github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.7.0 h1:83lBUJhGWhYp0ngzCMSgllhUSuoHP1iEWYjsPl9nwqM=
github.com/go-git/go-billy/v5 v5.7.0/go.mod h1:/1IUejTKH8xipsAcdfcSAlUlo2J7lkYV8GTKxAT/L3E=
github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0=
github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s=
github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M=
github.com/go-git/go-git/v5 v5.18.0 h1:O831KI+0PR51hM2kep6T8k+w0/LIAD490gvqMCvL5hM=
github.com/go-git/go-git/v5 v5.18.0/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
Expand All @@ -60,8 +60,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs=
github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0=
Expand Down Expand Up @@ -96,30 +96,29 @@ github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
50 changes: 14 additions & 36 deletions internal/commands/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ import (
)

func Dev(cmd *cobra.Command, wd string, doDelete bool, ignoreHook bool, args []string) error {
parentRepo, err := gitcmds.GetParentRepoName(wd)
rc, err := gitcmds.LoadRepoContext(wd)
if err != nil {
return err
}

// qs dev -d is running
if doDelete {
return deleteBranches(wd, parentRepo)
return deleteBranches(wd, rc.ParentRepo)
}
// qs dev is running
var devBranchName string
Expand All @@ -42,56 +42,34 @@ func Dev(cmd *cobra.Command, wd string, doDelete bool, ignoreHook bool, args []s
// - If parentRepo exists OR upstream remote exists -> fork workflow
// - If no parentRepo AND no upstream remote -> single remote workflow
// Check if upstream remote exists
upstreamExists, err := gitcmds.HasRemote(wd, "upstream")
if err != nil {
return err
}

// Only require fork if:
// 1. No parent repo exists (not a fork), AND
// 2. Upstream remote exists (indicating fork workflow was intended)
// This catches the edge case where someone manually added upstream but didn't fork
if len(parentRepo) == 0 && upstreamExists {
repo, org, err := gitcmds.GetRepoAndOrgName(wd)
if err != nil {
return err
}

return fmt.Errorf("you are in %s/%s repo with upstream remote but no fork detected\nExecute 'qs fork' first", org, repo)
if len(rc.ParentRepo) == 0 && rc.UpstreamExists {
return fmt.Errorf("you are in %s/%s repo with upstream remote but no fork detected\nExecute 'qs fork' first", rc.Org, rc.Repo)
}

curBranch, mainBranch, isMain, err := gitcmds.GetCurrentBranchInfo(wd)
if err != nil {
return err
}
if !isMain {
if !rc.IsMain {
fmt.Println("--------------------------------------------------------")
fmt.Println("You are in")
repo, org, err := gitcmds.GetRepoAndOrgName(wd)
if err != nil {
return err
}

color.New(color.FgHiCyan).Println(org + "/" + repo + "/" + curBranch)
color.New(color.FgHiCyan).Println(rc.Org + "/" + rc.Repo + "/" + rc.CurrentBranch)

return fmt.Errorf("switch to main branch before running 'qs dev'. You are in %s branch ", curBranch)
return fmt.Errorf("switch to main branch before running 'qs dev'. You are in %s branch ", rc.CurrentBranch)
}

// Stash current changes if needed
stashedUncommittedChanges := false
if ok, err := gitcmds.HaveUncommittedChanges(wd); ok {
if err != nil {
return err
}

if rc.HasUncommittedChanges {
if err := gitcmds.Stash(wd); err != nil {
return fmt.Errorf("error stashing changes: %w", err)
}
stashedUncommittedChanges = true
}

// sync local MainBranch to ensure it's up to date with origin and upstream remotes
if err := gitcmds.SyncMainBranch(wd, mainBranch, upstreamExists); err != nil {
if err := gitcmds.SyncMainBranch(wd, rc.MainBranch, rc.UpstreamExists); err != nil {
return err
}

Expand Down Expand Up @@ -124,25 +102,25 @@ func Dev(cmd *cobra.Command, wd string, doDelete bool, ignoreHook bool, args []s

switch response {
case pushYes:
if len(parentRepo) > 0 && !upstreamExists {
if len(rc.ParentRepo) > 0 && !rc.UpstreamExists {
var upstreamResponse string
fmt.Print("Upstream not found.\nRepository " + parentRepo + " will be added as upstream. Agree[y/n]?")
fmt.Print("Upstream not found.\nRepository " + rc.ParentRepo + " will be added as upstream. Agree[y/n]?")
_, _ = fmt.Scanln(&upstreamResponse)
if upstreamResponse != pushYes {
fmt.Print(msgOkSeeYou)
return nil
}
if err := gitcmds.MakeUpstreamForBranch(wd, parentRepo); err != nil {
if err := gitcmds.MakeUpstreamForBranch(wd, rc.ParentRepo); err != nil {
return err
}
}

if err := gitcmds.CreateDevBranch(wd, devBranchName, mainBranch, notes); err != nil {
if err := gitcmds.CreateDevBranch(wd, devBranchName, rc.MainBranch, notes); err != nil {
return err
}

if issueInfo.Type == issue.GitHub {
notes, err = gitcmds.LinkBranchToGithubIssue(wd, parentRepo, issueInfo.Text, issueInfo.ID, devBranchName, args...)
notes, err = gitcmds.LinkBranchToGithubIssue(wd, rc.ParentRepo, issueInfo.Text, issueInfo.ID, devBranchName, args...)
if err != nil {
return err
}
Expand Down
Loading
Loading