{"thread":{"id":"1381","subject":"Re: git diffs","startedAt":"2005-08-01T01:00:44Z","lastAt":"2005-08-01T15:51:13Z","messageCount":3,"participants":["Linus Torvalds","Matthias Urlichs"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"6693","messageId":"Pine.LNX.4.58.0507311725590.14342@g5.osdl.org","threadId":"1381","inReplyTo":"20050731172256.73f91a20.akpm@osdl.org","subject":"Re: git diffs","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-08-01T01:00:44Z","receivedAt":"2005-08-01T01:00:44Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 31 Jul 2005, Andrew Morton wrote:\n> \n> So I finally decided to take a look at my git problems.  Discovered I\n> couldn't fix them with zero git knowledge :(\n\nHeh. We're here to please.\n\nI'll cc the git list too, because there really _are_ a lot of people out \nthere that know it fairly well, and may even have better suggestions than \nI do.\n\n> What I want to do is to pull zillions of people's git trees into one repo\n> and then run some magic command to give me unified diffs from everyone's\n> trees which will apply to your latest.\n\nAbsolutely. \n\nHere's how to do it:\n\n - start off by fetching every single tree you want to have into its own \n   local branch. I think you basically do this already. If you're using \n   cogito, I think a simple \"cg-pull\" will do it for you.\n\n   If you are using raw git, the easiest thing to do is to really just do\n\n\tresult=$(git-fetch-pack \"$repo\" \"$head\") || exit\n\n   which will fetch the named \"head\" from the named \"repo\", and stuff the \n   result in the \"result\" variable. You can then stuff that result \n   anywhere, so for example, if you pull _my_ repostiry, you could then \n   name the result \"linus-tree\" by just doing\n\n\techo $result > .git/refs/heads/linus-tree\n\n   and it really is that easy.\n\n   So just do this for all the repos you want to pull, so that you have \n   <n> heads in the same tree, names however you wish (it the head naming\n   _you_ have in your tree do not necessarily have anything at all to do \n   with the head naming in the heads in the trees the data came from. In\n   fact, that's very important, because there can be multiple HEAD or\n   \"master\" source branches, of course, and you need to make _your_ heads\n   be unique).\n\n - second phase is to select some kind of order for these things, and just \n   start merging. Start off with a known base, and for each tree you merge \n   it against the previous merge, and then just generate the diff against \n   the previous merge.\n\n   Now, one downside is that the current \"git resolve\" will _always_ \n   resolve into HEAD, which is admittedly a bit of a bummer: you can't \n   resolve into a totally temporary tree, which is what your usage might \n   want.\n\n   This might be something git could do better for you, but the upside is\n   that \"git resolve\" will always leave the previous tree in ORIG_HEAD,\n   and since you really need to generate a temporary branch for all your\n   merges anyway, you might as well just do exactly that, and switch to it\n   before you start the merge process.\n\n   Anyway, this example script will jusy always create a temporary branch\n   called \"merge-branch\" that starts at whatever point you use as your\n   base. Not a biggie. You can choose whatever as your starting point, I'm \n   just assuming that it's the \"master\" branch, and that you'd keep (for \n   example) my last release in there as the base.\n\n   But if you want to keep the result of your quilt stuff, that should be \n   doable too, for example. I'm _assuming_ that you'd do the git merge \n   diffs first, and then do the quilt stuff on top of the result, but \n   there's nothing really that forces that order.\n\n   So it should literally be as simple as something like this:\n\n\t#\n\t# Start off from \"master\", create a new branch \"merge-branch\"\n\t# off that state.\n\t#\n\tgit checkout -f master\n\tgit-rev-parse master > .git/refs/heads/merge-branch\n\n\t#\n\t# Switch to it, always leaving \"master\" untouched\n\t#\n\tgit checkout -f merge-branch\n\n\t#\n\t#\n\t# For each tree you want to merge, just do so..\n\t#\n\t# This also decides the order of the patches\n\t#\n\tfor i in linus-tree davem-net-tree davem-sparc-tree ...\n\tdo\n\t\tgit resolve HEAD $i \"Merging $i\"\n\t\tif [ \"$?\" -ne 0 ]; then\n\t\t\techo \"Automatic resolve failed, skipping $i\" >&2\n\n\t\t\t#\n\t\t\t# Revert back to previous state, we're not going\n\t\t\t# to do any manual fixups here.\n\t\t\t#\n\t\t\tgit checkout -f\n\t\telse\n\t\t\t#\n\t\t\t# Yay! The resolve worked, let's just diff what\n\t\t\t# it did and continue onward from here\n\t\t\t#\n\t\t\tgit diff ORIG_HEAD.. > merge-diff-$i\n\t\tfi\n\tdone\n\n\t#\n\t# Finally, just switch back to \"master\", throw away all the work\n\t# we did (the objects will stay around, but you can do a\n\t#\n\t#\tgit prune\n\t#\n\t# once a week to get rid of the temporary objects. Don't do it\n\t# here, it's too expensive and there's no real point).\n\t#\n\tgit checkout -f master\n\trm .git/refs/heads/merge-branch\n\nand you're hopefully done. It really _should_ be that easy.\n\nThe above will leave you with a series of diffs called\n\n\tmerge-diff-linus-tree\n\tmerge-diff-davem-net-tree\n\tmerge-diff-davem-sparc-tree\n\t...\n\nwhich are all relative to each other (ie order very much matters, and \ncomes directly from the order you did the merging in).\n\nNOTE NOTE NOTE! I wrote the above in this email client, I've not tested it \nat all. It _looks_ straightforward enough, but hey, maybe I'm a retard.\n\nAnd btw, this should all be quite efficient. It really shouldn't take many \nseconds per tree. The most expensive op _should_ be downloading the \nchanges, and the fact that \"git resolve\" will always do a \"diffstat\" of \nthe result..\n\n\t\tLinus\n"},{"id":"6698","messageId":"pan.2005.08.01.07.55.40.43904@smurf.noris.de","threadId":"1381","inReplyTo":"Pine.LNX.4.58.0507311725590.14342@g5.osdl.org","subject":"Re: git diffs","fromName":"Matthias Urlichs","fromEmail":"smurf@smurf.noris.de","sentAt":"2005-08-01T07:55:47Z","receivedAt":"2005-08-01T07:55:47Z","isPatch":false,"sender":{"key":"matthias@urlichs.de","avatar":"https://gravatar.com/avatar/2708905af227313eba6f2b2ae0f7d0259b5ac5d71baef58fe5a13c699ce0bbf0?d=mp&s=160"},"body":"Hi, Linus Torvalds wrote:\n\n> \tgit checkout -f master\n> \tgit-rev-parse master > .git/refs/heads/merge-branch\n> \n> \t#\n> \t# Switch to it, always leaving \"master\" untouched\n> \t#\n> \tgit checkout -f merge-branch\n\nIsn't that equivalent to (but slower than)\n\n    git checkout -f -b merge-branch master\n\n?\n\n-- \nMatthias Urlichs   |   {M:U} IT Design @ m-u-it.de   |  smurf@smurf.noris.de\nDisclaimer: The quote was selected randomly. Really. | http://smurf.noris.de\n - -\nYou can tell it's going to be a rotten day when the bird singing outside your\nwindow is a buzzard.\n"},{"id":"6713","messageId":"Pine.LNX.4.58.0508010849390.14342@g5.osdl.org","threadId":"1381","inReplyTo":"pan.2005.08.01.07.55.40.43904@smurf.noris.de","subject":"Re: git diffs","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-08-01T15:51:13Z","receivedAt":"2005-08-01T15:51:13Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 1 Aug 2005, Matthias Urlichs wrote:\n>\n> Hi, Linus Torvalds wrote:\n> \n> > \tgit checkout -f master\n> > \tgit-rev-parse master > .git/refs/heads/merge-branch\n> > \n> > \t#\n> > \t# Switch to it, always leaving \"master\" untouched\n> > \t#\n> > \tgit checkout -f merge-branch\n> \n> Isn't that equivalent to (but slower than)\n> \n>     git checkout -f -b merge-branch master\n\nNo.\n\nIf you had a previous merge-branch (because something went wrong last \ntime, and you just re-start the whole thing), you really want to _first_ \nforce the branch to \"master\", and then create the new merge-branch.\n\nAlso, the last \"git checkout -f merge-branch\" will be pretty much zero\ntime, because the stuff is already at the right point, so it will\nbasically end up just re-doing the symlink.\n\nSo I did it that strange way for a reason.\n\n\t\tLinus\n"}]}