{"thread":{"id":"11782","subject":"--first-parent plus path limiting","startedAt":"2008-01-29T08:29:57Z","lastAt":"2008-01-29T20:03:34Z","messageCount":6,"participants":["Johannes Sixt","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"66822","messageId":"479EE405.1010001@viscovery.net","threadId":"11782","inReplyTo":null,"subject":"--first-parent plus path limiting","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-01-29T08:29:57Z","receivedAt":"2008-01-29T08:29:57Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"While trying to find out when builtin-fetch.c was merged into master, I\nnoticed that this:\n\n$ git log --first-parent --pretty=oneline -- builtin-fetch.c\n\nlists b888d61c (Make fetch a builtin), which I did not expect. This one\ndoesn't list it, as expected:\n\n$ git log --first-parent --pretty=oneline\n\n-- Hannes\n"},{"id":"66826","messageId":"7vk5ltow61.fsf@gitster.siamese.dyndns.org","threadId":"11782","inReplyTo":"479EE405.1010001@viscovery.net","subject":"Re: --first-parent plus path limiting","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-01-29T08:47:34Z","receivedAt":"2008-01-29T08:47:34Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> While trying to find out when builtin-fetch.c was merged into master, I\n> noticed that this:\n>\n> $ git log --first-parent --pretty=oneline -- builtin-fetch.c\n>\n> lists b888d61c (Make fetch a builtin), which I did not expect.\n\nWhy didn't you?\n\n> This one\n> doesn't list it, as expected:\n>\n> $ git log --first-parent --pretty=oneline\n\nWhy did you expect that?  This tells \"follow only the first\nparent chain, ignoring all merges\".\n\nAs most everything that is nontrivial is developed on a topic\nbranch in git.git, \"Make fetch a builtin\" will not be on the\nfirst parent chain of the \"master\".\n\nThe former is about \"First simplify the history with respect to\nbuiltin-fetch.c, and then follow the first-parent of the\nsimplified history.\n\nAs the builtin-fetch topic was worked on for some time on its\nown topic, like this:\n\n ---o---o---o---...---o---A---M--- master\n     \\                       /\n      o---o---X---...---o---B\n\nSo if a commit M has two parents A and B, and the file in M is\nthe same as the file in B, the history simplifies commit A and\nthe side branch that leads to it away.  Perhaps commit A was the\nfirst parent and B was the last commit of the fetch-pack series,\nand \"Make fetch a builtin\" was an ancestor of B, like X above.\n\n$ gitk b888d61c^..v1.5.4-rc5 -- builtin-fetch.c\n\nis somewhat interesting to view.\n"},{"id":"66828","messageId":"479EEC3D.9030100@viscovery.net","threadId":"11782","inReplyTo":"7vk5ltow61.fsf@gitster.siamese.dyndns.org","subject":"Re: --first-parent plus path limiting","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-01-29T09:05:01Z","receivedAt":"2008-01-29T09:05:01Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Junio C Hamano schrieb:\n> Johannes Sixt <j.sixt@viscovery.net> writes:\n> \n>> While trying to find out when builtin-fetch.c was merged into master, I\n>> noticed that this:\n>>\n>> $ git log --first-parent --pretty=oneline -- builtin-fetch.c\n>>\n>> lists b888d61c (Make fetch a builtin), which I did not expect.\n> \n> Why didn't you?\n\nBecause ... [see below]\n\n>> This one\n>> doesn't list it, as expected:\n>>\n>> $ git log --first-parent --pretty=oneline\n> \n> Why did you expect that?  This tells \"follow only the first\n> parent chain, ignoring all merges\".\n\nWith \"as expected\" I actually meant \"as expected\", not \"contrary to\nexpectations\" ;) So, I did expect *not* to see the commit when the path is\nnot limited.\n\n> The former is about \"First simplify the history with respect to\n> builtin-fetch.c, and then follow the first-parent of the\n> simplified history.\n\nI was expecting that it works like \"First follow the first-parent, and\nthen simplify the history with respect to builtin-fetch.c.\" But that's\ncertainly a matter of definition. In this case, I would have found my\ninterpretation more useful, but then I don't use --first-parent that often...\n\nThanks for your clarifications,\n-- Hannes\n"},{"id":"66829","messageId":"7v63xdov20.fsf@gitster.siamese.dyndns.org","threadId":"11782","inReplyTo":"479EEC3D.9030100@viscovery.net","subject":"Re: --first-parent plus path limiting","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-01-29T09:11:35Z","receivedAt":"2008-01-29T09:11:35Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> I was expecting that it works like \"First follow the first-parent, and\n> then simplify the history with respect to builtin-fetch.c.\"\n\nIf you first follow the first-parent, the result will by\ndefinition not have any merges, so there is nothing left to\nsimplify.  History simplification is about merge removal,\nlooking at all parents.\n\nRemoving commits from a single strand of pearls that do not\ntouch the specified pathspecs is called \"--dense\" (which is on\nthe default) and can be disabled with \"--sparse\".\n\nSo, no, it is not a matter of definition, as \"first follow the\nfirst-parent then simplify\" does not make much sense.\n"},{"id":"66830","messageId":"479EEF68.7080505@viscovery.net","threadId":"11782","inReplyTo":"7v63xdov20.fsf@gitster.siamese.dyndns.org","subject":"Re: --first-parent plus path limiting","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-01-29T09:18:32Z","receivedAt":"2008-01-29T09:18:32Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Junio C Hamano schrieb:\n> Johannes Sixt <j.sixt@viscovery.net> writes:\n> \n>> I was expecting that it works like \"First follow the first-parent, and\n>> then simplify the history with respect to builtin-fetch.c.\"\n> \n> If you first follow the first-parent, the result will by\n> definition not have any merges, so there is nothing left to\n> simplify.  History simplification is about merge removal,\n> looking at all parents.\n> \n> Removing commits from a single strand of pearls that do not\n> touch the specified pathspecs is called \"--dense\" (which is on\n> the default) and can be disabled with \"--sparse\".\n> \n> So, no, it is not a matter of definition, as \"first follow the\n> first-parent then simplify\" does not make much sense.\n\nOK.\n\nIs there a combination of options that does --first-parent on the full\nhistory, but then --dense on the resulting strand of pearls with respect\nto a certain path?\n\n-- Hannes\n"},{"id":"66850","messageId":"7vy7a8mmax.fsf@gitster.siamese.dyndns.org","threadId":"11782","inReplyTo":"479EEF68.7080505@viscovery.net","subject":"Re: --first-parent plus path limiting","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-01-29T20:03:34Z","receivedAt":"2008-01-29T20:03:34Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> Is there a combination of options that does --first-parent on the full\n> history, but then --dense on the resulting strand of pearls with respect\n> to a certain path?\n\n\nThe way these features are combined in the revision walker is\npretty much hardwired.\n\nMarking commits that do not change the tree with respect to set\nof paths as irrelevant (i.e. REV_TREE_SAME) comes first, and the\nmerge simplification happens about the same time.  Following\nfirst-parent-chain only works on the result of that.  If you\ntell a single-tree form of diff-tree to be applied to the\nresulting commit (i.e. give -p/--stat/--name-status and friends\nto \"git log\"), they work on the resulting commit with the same\npathspec unless --full-diff is given.\n\n\tSide note: incidentally, this is why you do not get \"git\n\tlog $single_pathspec\" to notice a file that matches the\n\tsingle pathspec was created by copying or renaming.\n\nBut there is a deeper issue between \"first-parent\" and the\nsimplification (both merge history simplification and dense\nprocessing) with pathspec.  They are based on quite different\nviewpoint to what the history is.\n\nThe first-parent view is about what was seen by who made merges.\nIf you follow a branch that never fast-forwards (e.g. my \"next\"\nis that way) using --first-parent, you will see the evolution of\nthe branch: \"I merged updates to this topic, then I merged\nupdates to that topic, etc.\"  Even though there is no meaning to\nthe concept of \"branch\" other than \"a sticky label that moves\naround, mostly going forward, on a possible DAG of commits\", it\nmakes you pretend that one person and nobody else \"owns\" the\nbranch and grows it, and ask only about what that one person did\nand saw.  It is probably against the distributed nature of git\nhistory that fast-forward merge can happen anytime and there is\nno true mainline nor owner of the branch.\n\nOn the other hand, history simplification based on pathspecs is\nabout what changed the area.  It does not matter the feature was\ncooked in a side branch (which is a second class citizen in the\nworld view \"first-parent\" takes) --- if \"the mainline\" did not\ntouch that area and the changes to the area were merged from a\nside branch, the history on that side branch is much more\ninteresting than the history of the mainline when you are\ninspecting the changes to the area specified by a set of paths.\nThe philosophy is more natural to the distributed nature of git\nhistory.\n\nThese two inherently do not mesh well.\n\nHaving said that, culling with first-parent first and then\napplying pathspecs may have its own use.  You will be asking\nthis question:\n\n    I do not care about the details of what other people did.\n    Among the actions that was made to this branch of mine, find\n    the ones that change the area.\n\nThis will not find the \"Make fetch built-in\" commit if you dig\nfrom 'master' (because that was not something that happened on\n\"master\"), but will find the merge to the \"mainline\" that\ntouched the file.\n"}]}