@@ -20,7 +20,7 @@ type project struct {
20
20
wd string
21
21
isRepo bool
22
22
root config.Root
23
- baseRef string
23
+ baseRev string
24
24
normalizedRepo string
25
25
stackManager * stack.Manager
26
26
@@ -139,18 +139,6 @@ func (p *project) isDefaultBranch() bool {
139
139
return branch == git .DefaultBranch
140
140
}
141
141
142
- // defaultBaseRef returns the baseRef for the current git environment.
143
- func (p * project ) defaultBaseRef () string {
144
- if p .isDefaultBranch () &&
145
- p .remoteDefaultCommit () == p .headCommit () {
146
- _ , err := p .git .wrapper .RevParse (defaultBranchBaseRef )
147
- if err == nil {
148
- return defaultBranchBaseRef
149
- }
150
- }
151
- return p .defaultBranchRef ()
152
- }
153
-
154
142
// defaultLocalBaseRef returns the baseRef in case there's no remote setup.
155
143
func (p * project ) defaultLocalBaseRef () string {
156
144
git := p .gitcfg ()
@@ -163,9 +151,58 @@ func (p *project) defaultLocalBaseRef() string {
163
151
return git .DefaultBranch
164
152
}
165
153
166
- func (p project ) defaultBranchRef () string {
167
- git := p .gitcfg ()
168
- return git .DefaultRemote + "/" + git .DefaultBranch
154
+ // selectChangeBase returns the revision used for change comparison based on the current Git state.
155
+ func (p * project ) selectChangeBase () string {
156
+ gitcfg := p .gitcfg ()
157
+ gw := p .git .wrapper
158
+
159
+ // Try using remote default branch first
160
+ defaultBranchRev , _ := gw .RevParse (gitcfg .DefaultRemote + "/" + gitcfg .DefaultBranch )
161
+ if defaultBranchRev == "" {
162
+ // Fall back to local default branch
163
+ defaultBranchRev , _ = gw .RevParse (gitcfg .DefaultBranch )
164
+
165
+ if defaultBranchRev == "" {
166
+ // There's no default branch available, so we can't look for a common parent with it.
167
+ return defaultBranchBaseRef
168
+ }
169
+ }
170
+
171
+ branch , _ := gw .CurrentBranch ()
172
+
173
+ // Either we are on a branch or at a detached HEAD.
174
+ if branch != "" {
175
+ if branch == gitcfg .DefaultBranch {
176
+ // We are at the tip of the default branch -> latest default commit.
177
+ return defaultBranchBaseRef
178
+ }
179
+
180
+ // Fallthrough to common parent if not on default branch
181
+ } else {
182
+ headRev , _ := gw .RevParse ("HEAD" )
183
+ isDetachedDefaultBranchTip := headRev == defaultBranchRev
184
+ if isDetachedDefaultBranchTip {
185
+ // We are at the latest commit of the default branch.
186
+ return defaultBranchBaseRef
187
+ }
188
+
189
+ isDefaultBranchAncestor , _ := gw .IsFirstParentAncestor ("HEAD" , defaultBranchRev )
190
+ if isDefaultBranchAncestor {
191
+ // We are at an older commit of the default branch.
192
+ return defaultBranchBaseRef
193
+ }
194
+
195
+ // Fallthrough to common parent if not at commit of default branch
196
+ }
197
+
198
+ commonParentWithDefaultBranch , _ := gw .FindNearestCommonParent (defaultBranchRev , "HEAD" )
199
+ if commonParentWithDefaultBranch != "" {
200
+ // We have a nearest common parent with the default branch. Similar to the historic merge base.
201
+ return commonParentWithDefaultBranch
202
+ }
203
+
204
+ // Fall back to default. Should never happen unless running on an isolated commit.
205
+ return defaultBranchBaseRef
169
206
}
170
207
171
208
func (p * project ) setDefaults () error {
0 commit comments