What's wrong
GitLogBuilder emits --not --remotes --not for ExcludingRemoteTrackingRefs() and, when neither ForRevision nor IncludingAllRefs() was called, no revision at all (GitLogBuilder.cs L180-210). The builder's docs say Log() lists commits "from HEAD" by default (L29, L48).
git only falls back to HEAD when no revision input was given. A pseudo-ref option like --remotes counts as input (git sets rev_input_given), even when it is negated or matches nothing. So git log --not --remotes --not lists nothing.
Why it matters
repository.Log().ExcludingRemoteTrackingRefs().ExecuteAsync() is the natural way to ask "what have I not pushed?", and it always returns an empty list. An empty list reads as "nothing unpushed", which is the data-loss answer the method's own remarks warn about. Adding ForPath(...), FirstParentOnly() or Take(...) makes no difference.
Reproduction (git 2.43.0)
git init -q r && cd r
git -c user.name=a -c user.email=a@b commit -q --allow-empty -m one
git log --format=%s --not --remotes --not # prints nothing
git log --format=%s --not --remotes --not HEAD # prints "one"
The same thing happens in a clone that has origin/main plus one local-only commit.
Existing tests cover only the IncludingAllRefs() and ForRevision("HEAD") combinations (GitRemoteSyncTests.cs L118-170, GitLogBuilderTests.cs L147-203). The bare call is untested.
Suggested fix
When _excludingRemoteTrackingRefs && !_includingAllRefs && _revision is null, append HEAD through AppendOperands, so the documented default holds. Alternatively, throw InvalidOperationException asking for a revision, but defaulting to HEAD matches the docs.
Acceptance criteria
Log().ExcludingRemoteTrackingRefs() with no revision returns the commits reachable from HEAD that aren't on any remote-tracking ref.
- Integration tests cover the bare call both with a remote that is behind HEAD and in a repository with no remotes, where every commit should be returned.
- An argv test pins the emitted
HEAD operand.
What's wrong
GitLogBuilderemits--not --remotes --notforExcludingRemoteTrackingRefs()and, when neitherForRevisionnorIncludingAllRefs()was called, no revision at all (GitLogBuilder.csL180-210). The builder's docs sayLog()lists commits "from HEAD" by default (L29, L48).git only falls back to
HEADwhen no revision input was given. A pseudo-ref option like--remotescounts as input (git setsrev_input_given), even when it is negated or matches nothing. Sogit log --not --remotes --notlists nothing.Why it matters
repository.Log().ExcludingRemoteTrackingRefs().ExecuteAsync()is the natural way to ask "what have I not pushed?", and it always returns an empty list. An empty list reads as "nothing unpushed", which is the data-loss answer the method's own remarks warn about. AddingForPath(...),FirstParentOnly()orTake(...)makes no difference.Reproduction (git 2.43.0)
The same thing happens in a clone that has
origin/mainplus one local-only commit.Existing tests cover only the
IncludingAllRefs()andForRevision("HEAD")combinations (GitRemoteSyncTests.csL118-170,GitLogBuilderTests.csL147-203). The bare call is untested.Suggested fix
When
_excludingRemoteTrackingRefs && !_includingAllRefs && _revision is null, appendHEADthroughAppendOperands, so the documented default holds. Alternatively, throwInvalidOperationExceptionasking for a revision, but defaulting to HEAD matches the docs.Acceptance criteria
Log().ExcludingRemoteTrackingRefs()with no revision returns the commits reachable from HEAD that aren't on any remote-tracking ref.HEADoperand.