* Newbie contribution idea for 'git log --children': input requested @ 2022-09-11 23:09 Jacob Stopak 2022-09-12 0:41 ` Junio C Hamano 0 siblings, 1 reply; 7+ messages in thread From: Jacob Stopak @ 2022-09-11 23:09 UTC (permalink / raw) To: git Hello! This is my first idea for a suggested code change, and I'm seeking some input on whether it makes sense to address, and if so, a bit of help with how to implement. I was futzing with "git log --children" and noticed that the output doesn't display children for the HEAD commit in a detached HEAD state (or even when HEAD points to a branch tip that in fact does have a child commit that is ahead of the branch). I assume the children of the HEAD commit don't display because of the way Git starts parsing backward in a parent-wise direction, so the children of the HEAD commit would never be found. But it seems like displaying the children of the HEAD commit _when they exist_ would be useful for users who have checked out a commit somewhere in the middle of a long commit history. In this case, a user might want to be able to easily find and check out a commit in the "child" direction without having to go all the way back up to the branch tip (or nearest tag) to see commits between the detached HEAD and the branch tip. I'm not sure if this really qualifies as a "bug" per se, or if there is some way to do this that I'm just missing, or if it goes against the way Git's rev lists work. But I'm wondering if it could be addressed by simply adding a discrete check to see if any commits point to HEAD as a parent, (only when the --children option is used of course), and if so, populate those ids into the log message. It does seem to make sense that ALL commits with children would show those children in the log when the --children option is used... The current behavior seems to be that all commits _except_ HEAD will display their children. Thx for your thoughts! Best, Jack ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Newbie contribution idea for 'git log --children': input requested 2022-09-11 23:09 Newbie contribution idea for 'git log --children': input requested Jacob Stopak @ 2022-09-12 0:41 ` Junio C Hamano 2022-09-15 5:08 ` Jeff King 0 siblings, 1 reply; 7+ messages in thread From: Junio C Hamano @ 2022-09-12 0:41 UTC (permalink / raw) To: Jacob Stopak; +Cc: git Jacob Stopak <jacob@initialcommit.io> writes: > I'm not sure if this really qualifies as a "bug" per se, or if > there is some way to do this that I'm just missing, or if it goes > against the way Git's rev lists work. As it goes against the way GIt's rev lists work, you can call that "working in the way it was designed", or a "design bug". > But I'm wondering if it could be addressed by simply adding a > discrete check to see if any commits point to HEAD as a parent, > (only when the --children option is used of course), and if so, > populate those ids into the log message. In a history where all commits and their parent-child relationship can be enumerated and the links can be reversed in-core, it would be trivial to implement. The challenge is to make sure it works without wasting unusably large resources to do so in a real world project. Having a commit-graph might help. Thanks. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Newbie contribution idea for 'git log --children': input requested 2022-09-12 0:41 ` Junio C Hamano @ 2022-09-15 5:08 ` Jeff King 2022-09-15 17:08 ` Junio C Hamano 2022-09-18 3:19 ` Jacob Stopak 0 siblings, 2 replies; 7+ messages in thread From: Jeff King @ 2022-09-15 5:08 UTC (permalink / raw) To: Jacob Stopak; +Cc: Junio C Hamano, git On Sun, Sep 11, 2022 at 05:41:21PM -0700, Junio C Hamano wrote: > > But I'm wondering if it could be addressed by simply adding a > > discrete check to see if any commits point to HEAD as a parent, > > (only when the --children option is used of course), and if so, > > populate those ids into the log message. > > In a history where all commits and their parent-child relationship > can be enumerated and the links can be reversed in-core, it would be > trivial to implement. The challenge is to make sure it works > without wasting unusably large resources to do so in a real world > project. Having a commit-graph might help. I talked a little with Jacob about this at the contributor summit. As I don't think I've ever used --children myself, I was curious about the use case. :) I think it is that one might want to do something like: git log --children $some_old_oid and get a better idea of what was going on around the commit, both before and after. And there I think that yeah, enumerating all available commits to build the reverse index would make sense. I don't think it would be a strict fix for --children, though, for two reasons: - the current --children is free-ish because we're marking the commits as we traverse, so no extra parsing is required (just some storage for the reverse index) - the semantics aren't quite the same. One obvious issue is that you might care more about children reachable from your starting tips than arbitrary (possibly unreachable) children in your object store. But another is that --children implies parent rewriting, so it's not a strict reversal of the parent-child links. So we'd want to retain the existing --children, and this new mode might become --children=all or something. Just sketching out an implementation, I think it is kind of similar to the "decorate" mechanism, where we build the commit->metadata mapping ahead of time, and then add output to the commits that we show. So we'd probably want to load it around the same time we call load_ref_decorations(). The next question is: what do we put in it? One idea is to just reverse all the commits we know about. I.e., use for_each_loose_object() and for_each_packed_object(), similar to the way "cat-file --batch-all-objects" works. Use lookup_commit_in_graph() to use the commit-graph when we can, and check object types via oid_object_info() before trying to parse them (so we can avoid loading non-commits from disk entirely). But another idea is to do a _separate_ traversal in order to decide which commits to care about. Then we have to know which tips to start that traversal from, and we may end up with something similar to --decorate-refs in terms of expressing that traversal. But I suspect the output here is more interesting to the user, because now you can ask just about reachable children, or children reachable from release tags, or from a specific branch, etc. So you could do something like: git show --children=refs/heads/* $some_old_commit and see where we went from $some_old_commit that eventually ended up on a branch. But getting back to the original use case, which is about providing context for a commit: now we have the child commit id, but it's still a bit of a pain to actually see what it's in it. I usually solve this by doing a single traversal, and asking the pager to jump straight to the commit of interest, at which point I can scroll up and down to see the context. Like: git log --color | less +/$some_old_commit I'm not 100% sure I understand the original use case. But if I do, and that solves it, I wonder if we could make it more ergonomic somehow. Likewise, I think using something like "tig" would be nice for viewing context, but AFAIK it does not have an option to jump to a specific commit. You can jump by line number, but it would be nice to be able to do: tig --highlight=1234abcd and get a graph starting at HEAD, but jump immediately to the line for 1234abcd. -Peff ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Newbie contribution idea for 'git log --children': input requested 2022-09-15 5:08 ` Jeff King @ 2022-09-15 17:08 ` Junio C Hamano 2022-09-18 3:19 ` Jacob Stopak 1 sibling, 0 replies; 7+ messages in thread From: Junio C Hamano @ 2022-09-15 17:08 UTC (permalink / raw) To: Jeff King; +Cc: Jacob Stopak, git Jeff King <peff@peff.net> writes: > Just sketching out an implementation, I think it is kind of similar to > the "decorate" mechanism, where we build the commit->metadata mapping > ahead of time, and then add output to the commits that we show. So we'd > probably want to load it around the same time we call > load_ref_decorations(). Yup, and yuck. I personaly doubt that the current --children is all that useful to begin with, and as you later mention, it would not be useful without some interactive "jump to" feature, either using the pager over "log --graph --oneline" output or "tig". Thanks. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Newbie contribution idea for 'git log --children': input requested 2022-09-15 5:08 ` Jeff King 2022-09-15 17:08 ` Junio C Hamano @ 2022-09-18 3:19 ` Jacob Stopak 2022-09-20 22:28 ` Jeff King 1 sibling, 1 reply; 7+ messages in thread From: Jacob Stopak @ 2022-09-18 3:19 UTC (permalink / raw) To: Jeff King; +Cc: Junio C Hamano, git On Thu, Sep 15, 2022 at 12:08:10AM -0500, Jeff King wrote: > > I usually solve this by doing a single traversal, and asking the pager > to jump straight to the commit of interest, at which point I can scroll > up and down to see the context. Like: > > git log --color | less +/$some_old_commit > > I'm not 100% sure I understand the original use case. But if I do, and > that solves it, I wonder if we could make it more ergonomic somehow. Great points thanks for the details. I do think your method addresses the use case I was trying to describe, which is being able to quickly see context in both directions when you jump to a commit far from any branch/tag. But like you implied, it would be nice to be able to do it with a real command line option to git log instead of repiping into less, something like: git log --scroll-to=commit_id I peeked into builtin/log.c and saw how it calls setup_pager(); at the end of cmd_log_init_finish(...). I have a basic understanding now of how the default pager and pager environment are roped in. One obvious issue is that different pagers might have different ways (or no way at all) to auto-scroll to a pattern. But this might be solved by allowing the user to add their pager option such as +/ to the pager environment, which would only be applied when the user adds the --scroll-to=commit_id option to git log. (I guess this would rely on the user knowing what the option format is for their pager, which isn't ideal... but I assume that it's not great practice to have git store option formats for external tools like pagers since they could change over time and then there is the can of worms of which pagers git would even support this feature for - although it does seem git stores default flags for LESS and LV). Anyway, then the commit_id would be dynamically added after, probably in a format like "commit <commit_id>" so that the same pattern in commit messages doesn't match. But I don't think I saw an existing way to pass in dynamic parameters, such as a commit id, into the pager environment. This ability could potentially be useful for setting other dynamic pager options as well, which can currently only be done by stuff like repiping git log's output as in your example. From what I can tell only static content like flags appear to be able to be set in the current pager environment, but maybe I'm missing something obvious... It would be great to get your thoughts. -Jack ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Newbie contribution idea for 'git log --children': input requested 2022-09-18 3:19 ` Jacob Stopak @ 2022-09-20 22:28 ` Jeff King 2022-09-21 0:24 ` Jacob Stopak 0 siblings, 1 reply; 7+ messages in thread From: Jeff King @ 2022-09-20 22:28 UTC (permalink / raw) To: Jacob Stopak; +Cc: Junio C Hamano, git On Sat, Sep 17, 2022 at 08:19:01PM -0700, Jacob Stopak wrote: > On Thu, Sep 15, 2022 at 12:08:10AM -0500, Jeff King wrote: > > > > I usually solve this by doing a single traversal, and asking the pager > > to jump straight to the commit of interest, at which point I can scroll > > up and down to see the context. Like: > > > > git log --color | less +/$some_old_commit > > > > I'm not 100% sure I understand the original use case. But if I do, and > > that solves it, I wonder if we could make it more ergonomic somehow. > > Great points thanks for the details. I do think your method addresses the use > case I was trying to describe, which is being able to quickly see context in > both directions when you jump to a commit far from any branch/tag. One thing my suggestion doesn't help with is when $some_old_commit is the current HEAD. Something like: git checkout HEAD~50 git log --magically-start-at=HEAD wouldn't work, because to get context you need to start traversing from somewhere else. So really you want to start with "--branches --tags", or maybe even "--all" as traversal points, and then show whatever commit (be it HEAD or something else) in context. > But like you implied, it would be nice to be able to do it with a real command > line option to git log instead of repiping into less, something like: > > git log --scroll-to=commit_id > > I peeked into builtin/log.c and saw how it calls setup_pager(); at the end of > cmd_log_init_finish(...). I have a basic understanding now of how the default > pager and pager environment are roped in. > > One obvious issue is that different pagers might have different ways (or no way > at all) to auto-scroll to a pattern. But this might be solved by allowing the > user to add their pager option such as +/ to the pager environment, which would > only be applied when the user adds the --scroll-to=commit_id option to git log. Yes, exactly. It's awkward to assume too much about the pager, because it could be literally anything. I think the worst thing we can do is stick extra bits on the command-line like this, because it may actually break other pagers. As you noted, we do have a default LESS variable, which is OK, because at worst it is simply ignored. I think we _could_ append "+/whatever" into $LESS, and that would work. It feels kind of dirty somehow, though. > Anyway, then the commit_id would be dynamically added after, probably in a format like > "commit <commit_id>" so that the same pattern in commit messages doesn't match. Right, and you can anchor it with "+/^commit ...". But of course that depends on the output format. Something like "--oneline" would have a partial commit. If done inside Git, it would know the format it will use. But if you don't mind being a little sloppy, you can probably write a regex which works well enough. Taking it all together, a script like this works: -- >8 -- #!/bin/sh focus=$1; shift # use --short rather than --verify so we match --oneline short=$(git rev-parse --short "$focus") || exit 1 # this regex tries to match a variety of formats: # # - anchor to the left to avoid false positives # - make "commit" optional to catch both regular and oneline # - skip --graph markers # - we can ignore colors; less skips ANSI codes when matching regex='^[*|\\ ]*(commit )?' # yuck, there's no way to ask "which pager would you use for git-log". # Stuffing the value inside $LESS works, but if we override Git's # internal value, then we have to recreate it. LESS="${LESS-FRX} +/$regex$short" export LESS exec git log --branches --tags "$@" -- >8 -- Saving that as git-focus and setting the execute bit lets you do stuff like: git checkout HEAD~50 git focus HEAD I think this could be done inside Git, though it would be a little awkward. Maybe it's worth living with that script for a while and seeing if you like it. -Peff ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Newbie contribution idea for 'git log --children': input requested 2022-09-20 22:28 ` Jeff King @ 2022-09-21 0:24 ` Jacob Stopak 0 siblings, 0 replies; 7+ messages in thread From: Jacob Stopak @ 2022-09-21 0:24 UTC (permalink / raw) To: Jeff King; +Cc: Junio C Hamano, git On Tue, Sep 20, 2022 at 06:28:24PM -0400, Jeff King wrote: > Taking it all together, a script like this works: ... > I think this could be done inside Git, though it would be a little > awkward. Maybe it's worth living with that script for a while and seeing > if you like it. > > -Peff Wow thanks for putting that script together! Looks awesome I'm looking forward to testing it out - I think it should be fine for my purposes. Also unrelated - thought of a different patch idea to work on related to the git shortlog command, so will be submitting that hopefully one of these days... o.O ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-09-21 0:24 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-09-11 23:09 Newbie contribution idea for 'git log --children': input requested Jacob Stopak 2022-09-12 0:41 ` Junio C Hamano 2022-09-15 5:08 ` Jeff King 2022-09-15 17:08 ` Junio C Hamano 2022-09-18 3:19 ` Jacob Stopak 2022-09-20 22:28 ` Jeff King 2022-09-21 0:24 ` Jacob Stopak
Code repositories for project(s) associated with this public inbox https://80x24.org/mirrors/git.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).