* Wanted - a file browser interface to git @ 2005-10-19 0:58 John Ellson 2005-10-19 1:07 ` Linus Torvalds 0 siblings, 1 reply; 6+ messages in thread From: John Ellson @ 2005-10-19 0:58 UTC (permalink / raw) To: git I know that Linus thinks that files are less important than commits, but we are finding a real need to be able to browse though old versions of files and we have not yet found an efficient way to do it with git. An example is: "I know that file xxx contained algorithm yyy at some point in the past and now I'd like to browse back through the history of xxx to find the exact details." I think what I'd like is a file browser on git that: - can navigate the directory tree, starting by default with the HEAD tree, but able to browse the state of the tree at any time in the history. - can select any file from the tree, and then view the state of that file at any time in its history by stepping forward or back through commits that have affected that file. - can view the difference between any pair of states of the file, with annotations as to the source of the changes. - can search for a string across the complete history of a file. - can invoke the users choice of editor on the file. Neither gitk nor qgit provide tree browsing, so it can be hard to get at a specific file. qgit has nice file browser that annotates all changes, but I think I'd prefer a two panel diff view. Neither qgit not gitk provide links to an editor so that a file can be worked on once found. Am I out in left field here, or does anyone else feel the need for something like this? John ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Wanted - a file browser interface to git 2005-10-19 0:58 Wanted - a file browser interface to git John Ellson @ 2005-10-19 1:07 ` Linus Torvalds 2005-10-19 1:23 ` John Ellson 2005-10-19 3:15 ` [PATCH] cg-history FILE [NTH_PARENT] - was: " John Ellson 0 siblings, 2 replies; 6+ messages in thread From: Linus Torvalds @ 2005-10-19 1:07 UTC (permalink / raw) To: John Ellson; +Cc: git On Tue, 18 Oct 2005, John Ellson wrote: > > An example is: "I know that file xxx contained algorithm yyy at some point in > the past and now I'd like to browse back through the history of xxx to find > the exact details." You are aware of "git whatchanged -p xxx", right? Yeah, it's not graphical, and I agree that it might be very cool to have a graphical version of it. But I thought I'd mention it even so. A surprising number of people seem to have never realized, and at least for me personally, it's one of the most common things I do. Linus ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Wanted - a file browser interface to git 2005-10-19 1:07 ` Linus Torvalds @ 2005-10-19 1:23 ` John Ellson 2005-10-19 3:03 ` Linus Torvalds 2005-10-19 3:15 ` [PATCH] cg-history FILE [NTH_PARENT] - was: " John Ellson 1 sibling, 1 reply; 6+ messages in thread From: John Ellson @ 2005-10-19 1:23 UTC (permalink / raw) To: Linus Torvalds; +Cc: git Linus Torvalds wrote: > On Tue, 18 Oct 2005, John Ellson wrote: > >> An example is: "I know that file xxx contained algorithm yyy at some point in >> the past and now I'd like to browse back through the history of xxx to find >> the exact details." >> > > You are aware of "git whatchanged -p xxx", right? > > Yeah, it's not graphical, and I agree that it might be very cool to have a > graphical version of it. But I thought I'd mention it even so. A > surprising number of people seem to have never realized, and at least for > me personally, it's one of the most common things I do. > > Linus > Linus, I wasn't aware of it, no. Looks very useful. Thanks. I see that you can take the tree id from the diff-tree lines and then produce the state of the file at that time with "cg-admin-cat -r <id> xxx" Is that how you would do it? Are there any plans for cogito to support it? John ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Wanted - a file browser interface to git 2005-10-19 1:23 ` John Ellson @ 2005-10-19 3:03 ` Linus Torvalds 0 siblings, 0 replies; 6+ messages in thread From: Linus Torvalds @ 2005-10-19 3:03 UTC (permalink / raw) To: John Ellson; +Cc: git On Tue, 18 Oct 2005, John Ellson wrote: > Linus Torvalds wrote: > > > > You are aware of "git whatchanged -p xxx", right? > > I wasn't aware of it, no. Looks very useful. Thanks. > > I see that you can take the tree id from the diff-tree lines and > then produce the state of the file at that time with "cg-admin-cat -r <id> > xxx" > Is that how you would do it? Well, I'd do it with the git commands: once you see the diff, you should know the SHA1's of the source and destination, and then you can just do git-cat-file blob [sha1] to get the before (or after) state. The way I'd get the SHA1 is either (now with the extended diff format) in the short form from the diff itself (the "index" line), or by just separately doing a git-diff-tree -r [sha-of-commit] to see the "raw" diff format. All the diff things can take a pathname limiter, the same way "git-whatchanged" does, so if you are only interested in one file, just name the file: git-diff-tree -r [sha-of-commit] [filename] And just to make clear how powerful this is: "filename" doesn't have to be a single file. It can be a set of files and/or directories, so if you want to track multiple things at the same time, just do multiple filenames. What I do a lot is to check what has changed in some particular subsystem, ie somebody says that something broke in SCSI, and then I do git-whatchanged -p drivers/scsi/ include/scsi/ and it will show any changes to anything under either of those directories. "git-whatchanged" really is very powerful. The silly thing is that it really boils down to just a single line script (well, with various argument handling etc it's actually five lines, but the "core" is really just a single pipeline of "git-rev-list | git-diff-tree --stdin". > Are there any plans for cogito to support it? Well, cogito could certainly just do a "cg-whatchanged", but it's really the same thing. Since cogito depends on git anyway, cogito users could just use the git-whatchanged functionality. Or to make it more seamless, just do alias cg-whatchanged=git-whatchanged or something like that ;^) Linus ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] cg-history FILE [NTH_PARENT] - was: Re: Wanted - a file browser interface to git 2005-10-19 1:07 ` Linus Torvalds 2005-10-19 1:23 ` John Ellson @ 2005-10-19 3:15 ` John Ellson 2005-10-19 4:01 ` [PATCH] cg-history FILE [NTH_PARENT] Linus Torvalds 1 sibling, 1 reply; 6+ messages in thread From: John Ellson @ 2005-10-19 3:15 UTC (permalink / raw) To: Linus Torvalds; +Cc: git Linus Torvalds wrote: > > On Tue, 18 Oct 2005, John Ellson wrote: >> An example is: "I know that file xxx contained algorithm yyy at some point in >> the past and now I'd like to browse back through the history of xxx to find >> the exact details." > > You are aware of "git whatchanged -p xxx", right? > > Yeah, it's not graphical, and I agree that it might be very cool to have a > graphical version of it. But I thought I'd mention it even so. A > surprising number of people seem to have never realized, and at least for > me personally, it's one of the most common things I do. > > Linus OK. Here is a not-very-smart cogito command to display the history of a file, or the state of the nth parent of the file in its history. Feedback and or complete rewrites are requested ;-) John produce the history of a file, or its state at its nth_parent --- commit 8478ad1164e37e9cca039a3f9552d2a98f7bead6 tree 40b39d5f9af573a7815f073cada03c7903bfc6fa parent 5d74e4859afc81a4658133d5a83809ac814dbf34 author John Ellson <ellson@ontap.ellson.com> Tue, 18 Oct 2005 23:13:44 -0400 committer John Ellson <ellson@ontap.ellson.com> Tue, 18 Oct 2005 23:13:44 -0400 cg-history | 36 ++++++++++++++++++++++++++++++++++++ 1 files changed, 36 insertions(+), 0 deletions(-) diff --git a/cg-history b/cg-history new file mode 100755 index 0000000..ba86f71 --- /dev/null +++ b/cg-history @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# +# Display the change history of a file. +# Copyright (c) John Ellson, 2005 +# +# The change history of a file is displayed on stdout, or +# if an integer is provided for NTH_PARENT, then the complete +# state of the file at that step in its history is sent to stdout. +# + +USAGE="cg-history FILE [NTH_PARENT]" + +. ${COGITO_LIB}cg-Xlib || exit 1 + +[ "$ARGS" ] || usage + +if [ "${ARGS[1]}" = "" ]; then + git-whatchanged -p "${ARGS[0]}" +else + i=0 + git-whatchanged -p "${ARGS[0]}" | + while read -r cmd sha rest + do + case "$cmd" in + diff-tree) + i=`expr $i + 1` + if [ $i = ${ARGS[1]} ] ; then + cg-admin-cat -r "$sha" "${ARGS[0]}" + exit 0 + fi + ;; + *) + ;; + esac + done +fi ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] cg-history FILE [NTH_PARENT] 2005-10-19 3:15 ` [PATCH] cg-history FILE [NTH_PARENT] - was: " John Ellson @ 2005-10-19 4:01 ` Linus Torvalds 0 siblings, 0 replies; 6+ messages in thread From: Linus Torvalds @ 2005-10-19 4:01 UTC (permalink / raw) To: John Ellson; +Cc: git [ Ok, time for some serious power-git usage ] On Tue, 18 Oct 2005, John Ellson wrote: > > produce the history of a file, or its state at its nth_parent > > + git-whatchanged -p "${ARGS[0]}" | Actually, you're much better of _not_ using "-p" to generate a patch. In fact, you don't even want the pretty format that "git-whatchanged" does, you really want the raw output. Try this instead: git-rev-list HEAD | git-diff-tree --stdin -s -r "$ARG" which will give _just_ a list of the commits that change the file "$ARG". Here, the "--stdin" to git-diff-tree means that it should take its revision input from stdin (ie obvously the list of commits generated by git-rev-list), and the "-s" stands for "silent", ie git-diff-tree won't actually output the diff itself. And the "-r" means that it should check the trees "recursively", which is needed since we want the diff-tree to traverse down the tree rather than just look at the top-level ("-p" to generate patches enables recursive by default since patches don't make sense on raw trees, but without the -p you need to do it explicitly). And since we didn't ask for the header, the only thing you get is the list of commits that changed the file describled by the argument. So now, you can just pick the n'th such commit, and do something like this # # Get the "${ARGS[1]}"th commit that changes file "${ARGS[0]}" # rev=$(git-rev-list HEAD | git-diff-tree --stdin -s -r "${ARGS[0]}" | head -n "${ARGS[1]}" | tail -1) # # Pick up the file from that tree # filerev=$(git-ls-tree -r "$rev" "${ARGS[0]}" | cut -f1 | cut -d' ' -f3) # # And show it # git-cat-file blob $filerev and you're done (untested, but you should get the idea). Now, the interesting part about is that you can feed the output from git-diff-tree _back_ to git-diff-tree, so you can do some really fancy footwork like: git-rev-list rev1..rev2 | git-diff-tree --stdin -s -r "$ARG" | git-diff-tree --stdin -M --pretty -p and what this will do is: - generate a list of all commits between rev1 and rev2 - filter out just the commits that change the file "$ARG", and pass those on. - for those commits, show the _whole_ diff, with rename detection and with pretty-printed commit comment headers In other words, you can basically look at all the full commits that changed one file (or a set of files). Efficiently. This is kind of like "git-whatchanged", but it shows the full context of what changed. Of course, the second git-diff-tree can be used to limit the context to something else, ie you could do a variation of the above, something like git-rev-list v2.6.12.. | git-diff-tree --stdin -s -r drivers/usb/ | git-diff-tree --stdin -M --pretty -p drivers/ include/ which will show any commit that changed the drivers/usb/ directory after v2.6.12, but then limit the output of those commits to the drivers/ and include/ subdirectories (so anything that was changed in that same commit in a filesystem would _not_ be shown, for example, but if there were changes to drivers/scsi/ at the same time, they _would_ show). Or, if you want to go really wild, do something like this on the kernel git tree: git-rev-list v2.6.12.. | git-diff-tree --stdin -s -r drivers/usb/ | git-diff-tree --stdin -s -r drivers/scsi/ | git-diff-tree --stdin -M --pretty -p drivers/scsi/ drivers/usb/ | less -S which says to print out only those commits that change something _both_ in drivers/usb/ _and_ in drivers/scsi/ at the same time, and then show only those parts of the changes. Try it out. It really does work, and is extremely powerful. It's even pretty efficient (make sure your tree is packed first, though ;). I can do the above in about three seconds for the current kernel history on my machine. That's 3 _seconds_ to go through what right now is 8005 commits: git-rev-list v2.6.12.. | wc -l and the reason is exactly that the filename-based parsing is very good at efficiently pruning out all the tree information that isn't needed. Very cool. However, the "normal" situation is just the standard "git-whatchanged", which is much easier to use than something more complex like the above. The core git commands are really designed to be scriptable, but "real life" seldom wants the complexity of quite that much flexibility. Linus ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2005-10-19 4:01 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-10-19 0:58 Wanted - a file browser interface to git John Ellson 2005-10-19 1:07 ` Linus Torvalds 2005-10-19 1:23 ` John Ellson 2005-10-19 3:03 ` Linus Torvalds 2005-10-19 3:15 ` [PATCH] cg-history FILE [NTH_PARENT] - was: " John Ellson 2005-10-19 4:01 ` [PATCH] cg-history FILE [NTH_PARENT] Linus Torvalds
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 NNTP newsgroup(s).