-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Parse git rev-list
-style options
#1393
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Hey! Thank you so much for this PR! I'm afraid that the proposed In this case, the flags for rev-list are pretty straightforward, but we don't want and don't plan to bring more CLI flag parsing, specially not if it involves "little gems" like However, I'd hate this code to go to waste. If you could move |
@vmg - what about adding the lines 262ff as a new function |
|
Oh, you meant "as a new function". Sorry, I misread your post. Yes, I certainly agree -- I thought that was on @ben's timeline, but somehow it hasn't happened yet. |
Yeah, it was always my plan to do a |
Thanks for the quick replies! I 100% agree that such "little gems" as I think the rev-list command-line API is in quite a different category. The combination of And it'd be sad for There isn't any other part of Git's CLI that I would similarly want to see in other tools; it's all either blandly functional or a mess like I like the idea of |
Revised series pushed. I think by |
You're right, the revwalk API is a much better place for a range operator to live. A I'm still 👎 on including the argument-parsing stuff in the library, though. The revwalk API already has sorting and ordering options, so there's no need for a DSL to describe them. I'd recommend moving that stuff into your sample code; this will help people figure out how to map what they know from git into revwalk calls. |
What @ben said. Looking good, otherwise! |
While it's common to want to use a range for the revision walker, the range syntax is also used for diff, and a user may want to record the operation elsewhere (or print it in a different fomat). How would a tool that wants to print what walk it's doing get this information if it's all done directly inside the revwalk? |
Doesn't a diff tool just need two trees to compare? In that case, you'd look up the two commits using And the proposed API just modifies an existing revwalk. You can do anything you want to with the commits inside the callback; this would be sufficient to write something like |
If a libgit2-based program wants to support those syntaxes, it should |
Diff does need two tree-ishes to compare, but you may not get them as two different arguments. If we're going to parse the same as git, I don't quite get what callback you're referring to. Letting the revwalk machinery handle the figuring out of positive and negative commits for you would let you implement log, but you wouldn't have any idea what you're showing. |
We're parsing the same thing. There's a left side, which can be the preimage or the negative commit, the right side, which can be postimage or positive commit, and whether we're talking about the merge-base. Log and diff do different things, but the format is the same. I don't see why it should be so deeply ingrained in the revwalk code when we need to parse the exact same syntax elsewhere. Should we have two pieces of code doing the same? Why is this preferable to letting the library user know what the user input and have it call the appropriate functions? |
@carlosmn What API would you propose for this common parser? I still don't see what kind of output it would produce.
See, this isn't even true. Compare, from the Git documentation:
vs.
So in the |
It would give you the three pieces of information. The left side, the
Right, when you're dealing with the merge base, the meanings change a This doesn't change that we're dealing with the same syntax. You can use the information however you want afterwards. |
So it would have three output arguments, or an output argument that is a struct that exists for this single purpose. I am not convinced this really saves much complexity for the caller. Do you plan to submit an implementation of the If you think you have a use case coming up that would take advantage of this parser, I can add it. If not, I think it makes sense to say YAGNI, and if someone eventually (a) adds this particular dark corner of |
As i am writing a graphical git client, i indeed see various places where i might take advantage of a range-of-commits parser in the way @carlosmn described it here. Also i see no reason in duplicating such code. Just to add a further usecase to the above: git also allows to cherry-pick a range. |
Let me see if I'm thinking about this correctly:
What I'm getting out of this is that a revwalk is a really useful thing, and being able to set the boundaries of one from a rev-list spec is also a useful thing. The ability to specify the two sides of a diff using a syntax that's intended to generate a range of things seems quite a bit less useful. Let's not get too bogged down with this. There doesn't seem to be much disagreement that Also, I'd still like to see the arg-parsing stuff moved into the sample code. Libgit2 isn't only (or even primarily) for command-line tools, and parsing command-line options is outside the scope. |
You've already identified an use-case: letting the user pass ranges. Diff is the example of a different part of git that parses the same syntax.
It's definitely something useful, but why implement it as a black box inside the revision walker? What does a program do when it wants to know what it's asking the library to do? |
Here are the two use cases I see:
Are there any others that we should design for? |
There are lots of places where the git cli expects commit ranges - and I'm not sure in which of those 2 categories they can be assigned. However, after this discussion, I think most of them can probably be reduced to feeding a revwalker. |
Those are the main use-cases right now if we want to emulate git and those are good starting points. You'll typically end up setting up a revwalker based on that, but it doesn't mean returning a revwalk is a good idea, as you've no idea what's happening at that point or which of the commits the user asked you to show. |
@gnprice, if you're still paying attention, I have a way to get this accepted. Mostly it involves me getting my way. 😄 Let's take the command-line parsing stuff and move it into the sample. The addition to the revwalk API is fantastic, though, I'm looking forward to having it in the API. |
Full Ack from me 👍 |
Yep, that's what I concluded from the discussion so far. I plan to do it. It may be a few more days, because there's a deadline at work. Also because I want to experiment with how to have tests for the examples/ files, so that my tests here don't go to waste. (Do any of them have tests somewhere I'm missing?) Though now that I look a bit at it, maybe that deserves its own pull request. What repository is
and I can't find that object ID in either libgit2.git or any of the test repos in |
I like the way you think. 😄 You're not blind, the examples actually don't have any tests. I'm actually not sure what repo the general example was originally meant to be run against. Its function right now is as a readable code snippet. Feel free to update it to work against one of the test repositories if you like. |
Signed-off-by: Greg Price <[email protected]>
The purported command output was already inaccurate, as the refs aren't where it shows. In any event, the labels a reader of this file really needs are the indices used in commit_sorting_*, to make it possible to understand them by referring directly from those arrays to the diagram rather than from the index arrays, to commit_ids, to the diagram. Add those. Signed-off-by: Greg Price <[email protected]>
Signed-off-by: Greg Price <[email protected]>
New series pushed. This moves the parsing of the query syntax out into examples/, as requested. It also pulls out a The last commit adds a test script for the rev-list example program. This is the first test for anything in examples/, so it's pretty direct, without much of a framework. |
Yeah, this is looking very good. Somehow tests are not passing -- can you force a repush and see what happens? My only concern is the |
I'm with @vmg on the platform stuff, but the examples are problematic at best right now. The I'm tempted to ignore that for now, and leave Windows compatibility for a future PR. |
* | ||
* @param left the left-hand commit | ||
* @param right the right-hand commit | ||
* @param threedots 0 if the endpoints are separated by two dots, 1 if by three |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make some indication that these three are output parameters? Right now it's not clear unless you check the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, good catch. Done.
@gnprice, thanks for coming back to this. I like what you're doing here. 😃 |
Signed-off-by: Greg Price <[email protected]>
All the hard work is already in revparse. Signed-off-by: Greg Price <[email protected]>
This demonstrates parts of the interface for specifying revisions that Git users are familiar with from 'git rev-list', 'git log', and other Git commands. A similar query interface is used in out-of-core command-line programs that browse a Git repo (like 'tig'), and may be useful for an 'advanced search' interface in GUI or web applications. In this version, we parse all the query modifiers we can support with the existing logic in revwalk: basic include/exclude commits, and the ordering flags. More logic will be required to support '--grep', '--author', the pickaxe '-S', etc. Signed-off-by: Greg Price <[email protected]>
This test file could probably be improved by a framework like the one in git.git:t/, or by using a language like Python instead of shell. The other examples would benefit from tests too. Probably best to settle on a framework to write them in, then add more tests. Signed-off-by: Greg Price <[email protected]>
Pushed a new version responding to @ben's comments, and the Travis build failed in the same spot -- I'll see if I can reproduce locally and debug. I'm all for platform-independence as a criterion for a good long-term test framework for examples/. For now, I think the test is much better than no test, and I agree with Ben that it'd be better to merge as is and make the test better (and test the other examples!) in future work. |
Yeah, I can't reproduce. Following exactly the sequence of commands in the failed Travis log (well, I added a --reference to optimize the clone command), all tests pass. To my surprise, I'm even running the same OS as Travis -- 32-bit Ubuntu Precise. So I don't know what the difference is. I see the Travis log includes installing valgrind. Is it possible to get more information from valgrind about the segfault inside Travis? Alternatively, @ben or @vmg, are you able to reproduce the failure locally? |
Yeah, I can definitely reproduce. You were missing a couple NULLs in the Thank you again for the PR! Looking forward to more stuff for you. :) |
Fix is 812e5ae btw. |
I see, the issue is that git_object_free() got called on uninitialized values in the failure cases. Thanks for the fix! |
With this series, we support (parts of) the interface for specifying revisions that Git users are familiar with from
git rev-list
,git log
, and other Git commands. This is useful for creating out-of-core command-line programs that browse a Git repo (liketig
), and may be useful for anadvanced search
interface in GUI or web applications.In this version, we parse all the options we can support with the existing logic in revwalk: basic include/exclude commits, and the ordering flags. More logic will be required to support
--grep
,--author
, the pickaxe-S
, etc.Also included is a simple driver program that can be used like
git rev-list
.