Skip to content

Log().ExcludingRemoteTrackingRefs() without ForRevision returns no commits, even when HEAD has unpushed work #161

Description

@matt-edmondson

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions