Enable enumerating commits not reachable and not reachable by remotes #119

Closed
Haacked opened this Issue Mar 1, 2012 · 6 comments

Comments

Projects
None yet
2 participants
Contributor

Haacked commented Mar 1, 2012

I need the abliity to list commits in a branch that are already "published" vs those that are not. By published, I mean commits that are reachable from a remote in the repository.

LibGit2 recently added a feature that should make this possible. libgit2/libgit2#576

Here's a scenario to make this clear.

  1. Clone repo from GitHub, make a couple commits on master. Push to GitHub.
  2. Create a new branch locally, add some commits.

The new branch hasn't been pushed, so it doesn't have a remote yet. When I get a list of commits, I'd like to be able to filter out the ones that are reachable by a remote (in this case origin/master).

This is equivalent to the command:

git log HEAD --shortstat --pretty=raw --not --remotes

I separately will want to be able to get a list of commits in that branch that are reachable by a remote.

If this is possible today, do let me know. I know that the libgit2 folks recently added a feature to make this more efficient (in the pull request I linked to) based on the logic used within Git.

Member

nulltoken commented Mar 1, 2012

How about this?

[Fact]
public void HaackedLog()
{
    SelfCleaningDirectory scd = BuildTemporaryCloneOfTestRepo(StandardTestRepoPath);

    using (var repo = new Repository(scd.DirectoryPath))
    {
        Branch master = repo.Branches["master"];
        master.IsTracking.ShouldBeTrue();
        master.TrackedBranch.ShouldEqual(repo.Branches["refs/remotes/origin/master"]);
        master.AheadBy.ShouldEqual(2);
        master.BehindBy.ShouldEqual(2);

        repo.Head.ShouldEqual(master);

        var filter = new Filter { Since = repo.Head.TrackedBranch, Until = repo.Head };
        repo.Commits.QueryBy(filter).Count().ShouldEqual(2);
    }
}
Contributor

Haacked commented Mar 1, 2012

Would that work on a branch that isn't yet tracked? For example, suppose I push my master branch and then clone it into a new branch named "foo". But I don't yet push "foo" remotely. I add a couple of commits to "foo".

Will that code you show get the two commits in "foo" but filter out the commits reachable by the remote master?

Does that make sense?

Member

nulltoken commented Mar 2, 2012

Will that code you show get the two commits in "foo" but filter out the commits reachable by the remote master?

Yes, it should. At least, I hope so ;-) In fact, everything come down to commit Ids. As Libgit2 walker only knows about commit Ids.

The Filter.Since and Filter.Until properties allow the user to pass different kinds of objects (Commit, Tag, Reference, ObjectId, string representation of a object Id...). Those objects are then peeled down to the Commit they point to, then the commit Oid is passed to the walker.

Does that make sense?

I hope I clearly understood your request. Feel free to correct me if I didn't.

[Fact]
public void HaackedLog()
{
    SelfCleaningDirectory scd = BuildTemporaryCloneOfTestRepo(StandardTestRepoPath);

    using (var repo = new Repository(scd.DirectoryPath))
    {
        Branch master = repo.Branches["master"];
        master.IsTracking.ShouldBeTrue();
        master.TrackedBranch.ShouldEqual(repo.Branches["refs/remotes/origin/master"]);
        master.AheadBy.ShouldEqual(2);
        master.BehindBy.ShouldEqual(2);

        repo.Head.ShouldEqual(master);

        var filter = new Filter { Since = repo.Head.TrackedBranch, Until = repo.Head };
        repo.Commits.QueryBy(filter).Count().ShouldEqual(2);

        /* Create a new branch pointing to the same commit than the tracked branched */
        Branch branch = repo.CreateBranch("Braanck", master.TrackedBranch.Tip.Sha);
        branch.IsTracking.ShouldBeFalse();

        filter = new Filter { Since = branch, Until = "HEAD" };
        repo.Commits.QueryBy(filter).Count().ShouldEqual(2);

        filter = new Filter { Since = branch.Tip, Until = "HEAD" };
        repo.Commits.QueryBy(filter).Count().ShouldEqual(2);

        repo.Head.Tip.Sha.ShouldEqual("32eab9cb1f450b5fe7ab663462b77d7f4b703344");
        filter = new Filter { Since = "refs/heads/Braanck", Until = "32eab9cb1f450b5fe7ab663462b77d7f4b703344" };
        repo.Commits.QueryBy(filter).Count().ShouldEqual(2);
    }
}
Member

nulltoken commented Mar 6, 2012

@Haacked Did my answer make actually sense?

Contributor

Haacked commented Mar 6, 2012

Yes it did, but I haven't tried it out yet. Sorry. I had to move onto other things, but I have it in my TODO list. :)

Member

nulltoken commented Mar 26, 2012

@Haacked Closing this issue. Do not hesitate to reopen it if the provided answer doesn't cover the whole topic of the question.

Cheers!

nulltoken closed this Mar 26, 2012

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