{"thread":{"id":"30748","subject":"[BUG] Out of memory on git log --simplify-by-decoration --first-parent","startedAt":"2012-06-08T18:23:44Z","lastAt":"2012-06-08T22:01:55Z","messageCount":4,"participants":["Vincent van Ravesteijn","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"193174","messageId":"4FD24330.2030805@lyx.org","threadId":"30748","inReplyTo":null,"subject":"[BUG] Out of memory on git log --simplify-by-decoration --first-parent","fromName":"Vincent van Ravesteijn","fromEmail":"vfr@lyx.org","sentAt":"2012-06-08T18:23:44Z","receivedAt":"2012-06-08T18:23:44Z","isPatch":false,"sender":{"key":"vfr@lyx.org","avatar":"https://avatars.githubusercontent.com/u/687868?v=4"},"body":"git dies after calling the following command on the git repo:\n\n$ git log f623ca1c...b9cfa4e9 --simplify-by-decoration --first-parent\n\nThis happens in simplify_merges () in revision.c. The list below shows \nthe number of times the \"while (list) { ..}\" block is executed until git \ndies:\n\n1475\n3544\n8274\n19588\n45689\n106077\n245329\n565153\n1269244\n2614903\n5871845\n13138892\nfatal: Out of memory, malloc failed (tried to allocate 8 bytes)\n\nVerified with msysgit and on Ubuntu Linux.\n\nVincent\n"},{"id":"193186","messageId":"7vwr3hbm6x.fsf@alter.siamese.dyndns.org","threadId":"30748","inReplyTo":"4FD24330.2030805@lyx.org","subject":"Re: [BUG] Out of memory on git log --simplify-by-decoration --first-parent","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-08T20:09:10Z","receivedAt":"2012-06-08T20:09:10Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Vincent van Ravesteijn <vfr@lyx.org> writes:\n\n> git dies after calling the following command on the git repo:\n>\n> $ git log f623ca1c...b9cfa4e9 --simplify-by-decoration --first-parent\n\nI wouldn't be surprised anything random happens when --first-parent\nis used together with simplify_merges(); the function needs full\nanalysis of all commits in the specified range, and first-parent\ntraversal specifically tells us not to descend into other parents.\nIt might not be a bad idea to forbid this combination when the\ncommand line options are parsed.\n\nWhat information were you trying to get out of the above command?\n"},{"id":"193188","messageId":"4FD25F34.1060400@lyx.org","threadId":"30748","inReplyTo":"7vwr3hbm6x.fsf@alter.siamese.dyndns.org","subject":"Re: [BUG] Out of memory on git log --simplify-by-decoration --first-parent","fromName":"Vincent van Ravesteijn","fromEmail":"vfr@lyx.org","sentAt":"2012-06-08T20:23:16Z","receivedAt":"2012-06-08T20:23:16Z","isPatch":false,"sender":{"key":"vfr@lyx.org","avatar":"https://avatars.githubusercontent.com/u/687868?v=4"},"body":"Op 8-6-2012 22:09, Junio C Hamano schreef:\n> Vincent van Ravesteijn<vfr@lyx.org>  writes:\n>\n>> git dies after calling the following command on the git repo:\n>>\n>> $ git log f623ca1c...b9cfa4e9 --simplify-by-decoration --first-parent\n> I wouldn't be surprised anything random happens when --first-parent\n> is used together with simplify_merges(); the function needs full\n> analysis of all commits in the specified range, and first-parent\n> traversal specifically tells us not to descend into other parents.\n> It might not be a bad idea to forbid this combination when the\n> command line options are parsed.\n>\n> What information were you trying to get out of the above command?\n\nI was using gitk and I tried to simplify the history a bit, just for \nvisualization,... so I tried by checking \"Limit to first parent\" and \n\"Simple history\". Then, git errored out with an out-of-memory error.\n\nVincent\n"},{"id":"193193","messageId":"7vr4tpbgz0.fsf@alter.siamese.dyndns.org","threadId":"30748","inReplyTo":"4FD25F34.1060400@lyx.org","subject":"Re: [BUG] Out of memory on git log --simplify-by-decoration --first-parent","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-08T22:01:55Z","receivedAt":"2012-06-08T22:01:55Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Vincent van Ravesteijn <vfr@lyx.org> writes:\n\n> Op 8-6-2012 22:09, Junio C Hamano schreef:\n>> Vincent van Ravesteijn<vfr@lyx.org>  writes:\n>>\n>>> git dies after calling the following command on the git repo:\n>>>\n>>> $ git log f623ca1c...b9cfa4e9 --simplify-by-decoration --first-parent\n> ...\n>> What information were you trying to get out of the above command?\n>\n> I was using gitk and I tried to simplify the history a bit, just for\n> visualization,... so I tried by checking \"Limit to first parent\" and\n> \"Simple history\". Then, git errored out with an out-of-memory error.\n\nI see.  I am not sure what it _means_ to simplify merges away in a\nhistory that is showing first-parent-only ancestry, but in any case,\nthis patch may help.\n\n-- >8 --\nSubject: [PATCH] revision: cull side parents before running simplify-merges\n\nThe simplify_merges() function needs to look at all history chain to\nfind the closest ancestor that is relevant after the simplification,\nbut after --first-parent traversal, side parents haven't been marked\nfor relevance (they are irrelevant by definition due to the nature\nof first-parent-only traversal) nor culled from the parents list of\nresulting commits.\n\nRemove these side parents from parents list before starting to\nfurther simplifying the result.\n\n---\n\n revision.c | 27 ++++++++++++++++++---------\n 1 file changed, 18 insertions(+), 9 deletions(-)\n\ndiff --git a/revision.c b/revision.c\nindex 935e7a7..acfdbac 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1358,11 +1358,13 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg\n \t\trevs->topo_order = 1;\n \t} else if (!strcmp(arg, \"--simplify-merges\")) {\n \t\trevs->simplify_merges = 1;\n+\t\trevs->topo_order = 1;\n \t\trevs->rewrite_parents = 1;\n \t\trevs->simplify_history = 0;\n \t\trevs->limited = 1;\n \t} else if (!strcmp(arg, \"--simplify-by-decoration\")) {\n \t\trevs->simplify_merges = 1;\n+\t\trevs->topo_order = 1;\n \t\trevs->rewrite_parents = 1;\n \t\trevs->simplify_history = 0;\n \t\trevs->simplify_by_decoration = 1;\n@@ -2013,25 +2015,31 @@ static struct commit_list **simplify_one(struct rev_info *revs, struct commit *c\n \n static void simplify_merges(struct rev_info *revs)\n {\n-\tstruct commit_list *list;\n+\tstruct commit_list *list, *next;\n \tstruct commit_list *yet_to_do, **tail;\n+\tstruct commit *commit;\n \n-\tif (!revs->topo_order)\n-\t\tsort_in_topological_order(&revs->commits, revs->lifo);\n \tif (!revs->prune)\n \t\treturn;\n \n \t/* feed the list reversed */\n \tyet_to_do = NULL;\n-\tfor (list = revs->commits; list; list = list->next)\n-\t\tcommit_list_insert(list->item, &yet_to_do);\n+\tfor (list = revs->commits; list; list = next) {\n+\t\tcommit = list->item;\n+\t\tnext = list->next;\n+\t\tfree(list);\n+\t\tif (revs->first_parent_only &&\n+\t\t    commit->parents && commit->parents->next)\n+\t\t\tcommit->parents->next = NULL;\n+\t\tcommit_list_insert(commit, &yet_to_do);\n+\t}\n \twhile (yet_to_do) {\n \t\tlist = yet_to_do;\n \t\tyet_to_do = NULL;\n \t\ttail = &yet_to_do;\n \t\twhile (list) {\n-\t\t\tstruct commit *commit = list->item;\n-\t\t\tstruct commit_list *next = list->next;\n+\t\t\tcommit = list->item;\n+\t\t\tnext = list->next;\n \t\t\tfree(list);\n \t\t\tlist = next;\n \t\t\ttail = simplify_one(revs, commit, tail);\n@@ -2043,9 +2051,10 @@ static void simplify_merges(struct rev_info *revs)\n \trevs->commits = NULL;\n \ttail = &revs->commits;\n \twhile (list) {\n-\t\tstruct commit *commit = list->item;\n-\t\tstruct commit_list *next = list->next;\n \t\tstruct merge_simplify_state *st;\n+\n+\t\tcommit = list->item;\n+\t\tnext = list->next;\n \t\tfree(list);\n \t\tlist = next;\n \t\tst = locate_simplify_state(revs, commit);\n"}]}