{"thread":{"id":"15474","subject":"[RFH] git cherry-pick takes forever","startedAt":"2008-09-10T08:26:10Z","lastAt":"2008-09-11T07:56:16Z","messageCount":3,"participants":["Michal Vitecek","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"90330","messageId":"20080910082610.GA3144@mageo.cz","threadId":"15474","inReplyTo":null,"subject":"[RFH] git cherry-pick takes forever","fromName":"Michal Vitecek","fromEmail":"fuf@mageo.cz","sentAt":"2008-09-10T08:26:10Z","receivedAt":"2008-09-10T08:26:10Z","isPatch":false,"sender":{"key":"fuf@mageo.cz","avatar":null},"body":" Hello everyone,\n\n I have two git repositories: one is the origin of the other. However no\n merging is being done as the projects in the repositories quite differ\n but still use the same core. So to propagate changes I cherry-pick\n those which are useful from one repository to another.\n\n however 'git cherry-pick' has lately started to last almost forever:\n\n $ time git cherry-pick b42b77e66a83f1298d9900a9bb1078b9b42e8618\n Finished one cherry-pick.\n Created commit 7caef83: - removed some superfluous newlines\n 2 files changed, 0 insertions(+), 2 deletions(-)\n git cherry-pick b42b77e66a83f1298d9900a9bb1078b9b42e8618  282.97s user 34.69s system 100% cpu 5:17.63 total\n\n Both repositories have approximately 16k commits and their forking\n point (merge base) is 250 to 490 commits far away. 'git gc' (even\n --prune) has been run.\n\n What can I do to make the 'git cherry-pick' instant again?\n\n        Thank you,\n\n P.S.: I'm using git-1.6.0.1.\n-- \n\t\tMichal Vitecek\t\t(fuf@mageo.cz)\n"},{"id":"90338","messageId":"7vk5dkxqvf.fsf@gitster.siamese.dyndns.org","threadId":"15474","inReplyTo":"20080910082610.GA3144@mageo.cz","subject":"Re: [RFH] git cherry-pick takes forever","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-09-10T10:00:20Z","receivedAt":"2008-09-10T10:00:20Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michal Vitecek <fuf@mageo.cz> writes:\n\n>  Hello everyone,\n>\n>  I have two git repositories: one is the origin of the other. However no\n>  merging is being done as the projects in the repositories quite differ\n>  but still use the same core. So to propagate changes I cherry-pick\n>  those which are useful from one repository to another.\n>\n>  however 'git cherry-pick' has lately started to last almost forever:\n\nCan you define \"lately\"?  Is it a function of your git version, or is it a\nfunction of the age of your repositories?\n\n>  $ time git cherry-pick b42b77e66a83f1298d9900a9bb1078b9b42e8618\n>  Finished one cherry-pick.\n>  Created commit 7caef83: - removed some superfluous newlines\n>  2 files changed, 0 insertions(+), 2 deletions(-)\n>  git cherry-pick b42b77e66a83f1298d9900a9bb1078b9b42e8618  282.97s user 34.69s system 100% cpu 5:17.63 total\n>\n>  Both repositories have approximately 16k commits and their forking\n>  point (merge base) is 250 to 490 commits far away.\n\nWhen talking about cherry-pick, the size of the history (unless the\nrepository has too many objects and badly packed) does not matter; the\noperation is purely about your current state, the cherry-picked commit\nitself, and the parent commit of the cherry-picked one.\n\nTaking 5 minutes to cherry-pick a change to only two paths, one line\ndeletion each, is plain ridiculous, but if the tree state of cherry-picked\ncommit and the tree state of the target is vastly different (e.g. almost\nno common pathnames), the behaviour is certainly understandable.  Ancient\ngit used straight three-way merge for cherry-pick, but recent ones use\nmore expensive \"recursive-merge\", which tries to detect renames.  If the\nstates of trees are very dissimilar, you can end up wasting a lot of time.\n\n    $ H=$(git rev-parse 7caef83^) ;# the commit before cherry-pick\n    $ C=b42b77e6 ;# the cherry-picked one\n\ncherry-pick operation roughly runs these two diffs:\n\n    $ time git diff --shortstat -M $H $C\n    $ time git diff --shortstat -M $H $C^1\n\nand uses the result to perform its work.  Can you clock these?\n\nIf you rarely have renames, it may be much more efficient to run \"git\nformat-patch -1 --stdout $C | git am -3\" instead of cherry-pick.\n"},{"id":"90421","messageId":"20080911075616.GB3144@mageo.cz","threadId":"15474","inReplyTo":"7vk5dkxqvf.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFH] git cherry-pick takes forever","fromName":"Michal Vitecek","fromEmail":"fuf@mageo.cz","sentAt":"2008-09-11T07:56:16Z","receivedAt":"2008-09-11T07:56:16Z","isPatch":false,"sender":{"key":"fuf@mageo.cz","avatar":null},"body":" Hello,\n\nJunio C Hamano wrote:\n>Michal Vitecek <fuf@mageo.cz> writes:\n>>  I have two git repositories: one is the origin of the other. However no\n>>  merging is being done as the projects in the repositories quite differ\n>>  but still use the same core. So to propagate changes I cherry-pick\n>>  those which are useful from one repository to another.\n>>\n>>  however 'git cherry-pick' has lately started to last almost forever:\n>\n>Can you define \"lately\"?  Is it a function of your git version, or is it a\n>function of the age of your repositories?\n\n It's a function a cherry-picking some commits - afterwards\n cherry-picking crawls. One of the commits removes a number of files\n (614) and also renames some (303).\n\n>>  $ time git cherry-pick b42b77e66a83f1298d9900a9bb1078b9b42e8618\n>>  Finished one cherry-pick.\n>>  Created commit 7caef83: - removed some superfluous newlines\n>>  2 files changed, 0 insertions(+), 2 deletions(-)\n>>  git cherry-pick b42b77e66a83f1298d9900a9bb1078b9b42e8618  282.97s user 34.69s system 100% cpu 5:17.63 total\n>>\n>>  Both repositories have approximately 16k commits and their forking\n>>  point (merge base) is 250 to 490 commits far away.\n>\n>When talking about cherry-pick, the size of the history (unless the\n>repository has too many objects and badly packed) does not matter; the\n>operation is purely about your current state, the cherry-picked commit\n>itself, and the parent commit of the cherry-picked one.\n\n I too thought so but after cherry-picking starting taking so long I\n began to doubt my thoughts :)\n\n>Taking 5 minutes to cherry-pick a change to only two paths, one line\n>deletion each, is plain ridiculous, but if the tree state of cherry-picked\n>commit and the tree state of the target is vastly different (e.g. almost\n>no common pathnames), the behaviour is certainly understandable.  Ancient\n>git used straight three-way merge for cherry-pick, but recent ones use\n>more expensive \"recursive-merge\", which tries to detect renames.  If the\n>states of trees are very dissimilar, you can end up wasting a lot of time.\n>\n>    $ H=$(git rev-parse 7caef83^) ;# the commit before cherry-pick\n>    $ C=b42b77e6 ;# the cherry-picked one\n>\n>cherry-pick operation roughly runs these two diffs:\n>\n>    $ time git diff --shortstat -M $H $C\n\n $ time git diff --shortstat -M $H $C\n 2 files changed, 0 insertions(+), 2 deletions(-)\n git diff --shortstat -M $H $C  0.00s user 0.00s system 72% cpu 0.006 total\n\n>    $ time git diff --shortstat -M $H $C^1\n\n $ time git diff --shortstat -M $H $C\\^1\n git diff --shortstat -M $H $C\\^1  0.00s user 0.00s system 0% cpu 0.003 total\n\n>and uses the result to perform its work.  Can you clock these?\n>\n>If you rarely have renames, it may be much more efficient to run \"git\n>format-patch -1 --stdout $C | git am -3\" instead of cherry-pick.\n\n Turning off renames detection in diff (via 'git config --add diff.renames\n false') helped and 'git cherry-pick' is instant now.\n\n Maybe my repositories are \"strange\" in some way. I would be more than\n happy to provide more information if needed.\n\n        Thank you,\n-- \n\t\tMichal Vitecek\t\t(fuf@mageo.cz)\n"}]}