{"thread":{"id":"9056","subject":"A question about git-rev-list","startedAt":"2007-07-16T08:55:35Z","lastAt":"2007-07-17T04:33:49Z","messageCount":4,"participants":["David Kastrup","Linus Torvalds","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"47523","messageId":"86wsx0wwvs.fsf@lola.quinscape.zz","threadId":"9056","inReplyTo":null,"subject":"A question about git-rev-list","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-07-16T08:55:35Z","receivedAt":"2007-07-16T08:55:35Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"\nHi,\n\nif I do\n\ngit-rev-list --remove-empty HEAD --not some-commit -- filename | tail -1\n\ndo I have any guarantee that the commit id I get (if any) is a direct\ndescendant of some-commit?  I _think_ --remove-empty might be\nnecessary for that option, but have no idea whether this hunch is\ncorrect.  Do I need additional options like --topo-order, or is that\nunnecessary?\n\nThanks,\n\n-- \nDavid Kastrup\n"},{"id":"47586","messageId":"alpine.LFD.0.999.0707161258560.20061@woody.linux-foundation.org","threadId":"9056","inReplyTo":"86wsx0wwvs.fsf@lola.quinscape.zz","subject":"Re: A question about git-rev-list","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-07-16T20:05:34Z","receivedAt":"2007-07-16T20:05:34Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 16 Jul 2007, David Kastrup wrote:\n> \n> if I do\n> \n> git-rev-list --remove-empty HEAD --not some-commit -- filename | tail -1\n> \n> do I have any guarantee that the commit id I get (if any) is a direct\n> descendant of some-commit?\n\nNo. You get the guarantee that\n\n - it's some kind of parent of HEAD\n - it's *not* a parent of some-commit\n\nBut the trivial case is a simple history like\n\n\t /-B-\\\n\tA     D\n         \\-C-/\n\n(where \"A\" is the root commit, and \"D\" is the current HEAD, and there are \ntwo development lines from A to  D).\n\nIf you now do\n\n\tgit-rev-list HEAD --not C\n\nyou would generally see B on the list of commits, even though it's \nobviously not a direct descendant of C.\n\nNo amount of flags will change that. Of course, B might not show up \nfor _other_ reasons (ie simply because it doesn't change \"filename\" at \nall), but generally you must always think of git-rev-list (and git log) as \na _set_ operation.\n\nThere are no git operations that will look for \"chain of commits from C to \nD\" if that is what you want. No such chain necessarily even exists, and \nquite often it is ambiguous when it *does* exist (ie there is not a single \nchain from A to D, there are two chains).\n\nYou could add some kind of function that looks for the \"shortest chain of \ncommits from X to Y\", but that would really be something fundamentally \ndifferent from what git-rev-list gives you.\n\n\t\t\tLinus\n"},{"id":"47595","messageId":"85bqecm4mn.fsf@lola.goethe.zz","threadId":"9056","inReplyTo":"alpine.LFD.0.999.0707161258560.20061@woody.linux-foundation.org","subject":"Re: A question about git-rev-list","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-07-16T21:16:00Z","receivedAt":"2007-07-16T21:16:00Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> On Mon, 16 Jul 2007, David Kastrup wrote:\n>> \n>> if I do\n>> \n>> git-rev-list --remove-empty HEAD --not some-commit -- filename | tail -1\n>> \n>> do I have any guarantee that the commit id I get (if any) is a direct\n>> descendant of some-commit?\n>\n> No. You get the guarantee that\n>\n>  - it's some kind of parent of HEAD\n>  - it's *not* a parent of some-commit\n>\n> But the trivial case is a simple history like\n>\n> \t /-B-\\\n> \tA     D\n>        \\-C-/\n>\n> (where \"A\" is the root commit, and \"D\" is the current HEAD, and there are \n> two development lines from A to  D).\n>\n> If you now do\n>\n> \tgit-rev-list HEAD --not C\n>\n> you would generally see B on the list of commits, even though it's \n> obviously not a direct descendant of C.\n\nOk, thanks.  As explained in a different posting, I try to tackle this\nnow with the equivalent of\n\ngit-rev-list HEAD --parents --not B -- somefile.c | awk '/ B/{print $1}'\n\nThis will give me one descendant if there is one.  The problem I have\nwith that is that \"somefile.c\" renders commits uninteresting, but\nnot if they have interesting parents (what do their parents have to do\nwith it?).  So if I have\n\nA -> B -> B1 -> C -> HEAD\n\nwhere somefile.c does not change between B and B1, then\ngit-rev-list HEAD --not B -- somefile.c\nspews out\nHEAD\nC\nand that's it.  Quite as expected.  However, \ngit-rev-list HEAD --not B --parents -- somefile.c\nspews out\nHEAD C\nC B1\nB1 B\n\nand look and behold, B1 became interesting because of its unlisted\nparent B.\n\nThere is something wrong with that.\n\n-- \nDavid Kastrup, Kriemhildstr. 15, 44793 Bochum\n"},{"id":"47610","messageId":"7v8x9fbqdu.fsf@assigned-by-dhcp.cox.net","threadId":"9056","inReplyTo":"85bqecm4mn.fsf@lola.goethe.zz","subject":"Re: A question about git-rev-list","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-07-17T04:33:49Z","receivedAt":"2007-07-17T04:33:49Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"David Kastrup <dak@gnu.org> writes:\n\n> ...  The problem I have\n> with that is that \"somefile.c\" renders commits uninteresting, but\n> not if they have interesting parents (what do their parents have to do\n> with it?).  So if I have\n>\n> A -> B -> B1 -> C -> HEAD\n>\n> where somefile.c does not change between B and B1, then\n> git-rev-list HEAD --not B -- somefile.c\n> spews out\n> HEAD\n> C\n> and that's it.  Quite as expected.  However, \n> git-rev-list HEAD --not B --parents -- somefile.c\n> spews out\n> HEAD C\n> C B1\n> B1 B\n>\n> and look and behold, B1 became interesting because of its unlisted\n> parent B.\n>\n> There is something wrong with that.\n\nThere indeed is, and that is not what I am seeing.\n\nRunning this script in an empty directory gives me:\n\n    #!/bin/sh\n\n    GIT_AUTHOR_NAME='A U Thor'\n    GIT_AUTHOR_EMAIL=a.u.thor@example.xz\n    GIT_COMMITTER_NAME=\"$GIT_AUTHOR_NAME\"\n    GIT_COMMITTER_EMAIL=\"$GIT_AUTHOR_EMAIL\"\n    GIT_AUTHOR_DATE='2007-07-16 00:00:00 +0000'\n    GIT_COMMITTER_DATE='2007-07-16 00:00:00 +0000'\n\n    export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL \\\n            GIT_AUTHOR_DATE GIT_COMMITTER_DATE\n\n    rm -fr .git\n    git init\n    echo A >somefile.c; git add somefile.c; git commit -m 'A'; git tag A\n    echo B >somefile.c; git add somefile.c; git commit -m 'B'; git tag B\n    echo B1 >another; git add another; git commit -m 'B1'; git tag B1\n    echo C >somefile.c; git add somefile.c; git commit -m 'C'; git tag C\n    echo H >somefile.c; git add somefile.c; git commit -m 'H'; git tag H\n\n    git rev-list --parents HEAD --not B -- somefile.c |\n    git name-rev --tags --stdin\n\n$ sh t000.sh\nInitialized empty Git repository in .git/\nCreated initial commit 7a13cf5: A\n 1 files changed, 1 insertions(+), 0 deletions(-)\n create mode 100644 somefile.c\nCreated commit b66d40b: B\n 1 files changed, 1 insertions(+), 1 deletions(-)\nCreated commit 5530c91: B1\n 1 files changed, 1 insertions(+), 0 deletions(-)\n create mode 100644 another\nCreated commit 7ee2b7e: C\n 1 files changed, 1 insertions(+), 1 deletions(-)\nCreated commit 71fafc0: H\n 1 files changed, 1 insertions(+), 1 deletions(-)\n71fafc0f49ffb82b123c09ec0857f9f458ed32c4 (tags/H) 7ee2b7ed072190c56a2eedda3130f6bb729d0da1 (tags/C)\n7ee2b7ed072190c56a2eedda3130f6bb729d0da1 (tags/C) b66d40bd7ed6d7403c16d8e37e6e410852598247 (tags/B)\n\n\nThe commit listed are H and then C; their (rewritten) parents\nare C and B, respectively.\n"}]}