{"thread":{"id":"3746","subject":"How to switch kernel customizations from 2.6.15.6 to 2.6.16?","startedAt":"2006-03-29T01:43:42Z","lastAt":"2006-03-30T21:50:59Z","messageCount":19,"participants":["Matt McCutchen","Linus Torvalds","Shawn Pearce","Junio C Hamano","Jakub Narebski"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"18104","messageId":"1143596622.2481.10.camel@mattlaptop.metaesthetics.net","threadId":"3746","inReplyTo":null,"subject":"How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Matt McCutchen","fromEmail":"hashproduct@verizon.net","sentAt":"2006-03-29T01:43:42Z","receivedAt":"2006-03-29T01:43:42Z","isPatch":false,"sender":{"key":"hashproduct@verizon.net","avatar":null},"body":"Dear git people,\n\nI made a customized Linux kernel based on 2.6.15.6 by cloning the stable\n2.6.15 kernel repository (which was then at version 2.6.15.6) and making\nseveral commits.  Now I would like a Linux kernel based on 2.6.16 with\nthe same customizations.  This seems to be a very simple task, but I\nhave been trying various combinations of git commands for several days\nand have not figured out how to do it.\n\nI believe that means I should pull the 2.6.16 kernel into the \"origin\"\nbranch and then rebase the \"master\" branch, merging my customizations\nwith 2.6.16.  To this end, I switched my remote file to point to the\n2.6.16 stable repository and tried to pull.  The result was not what I\nwanted.  The situation is complicated by the fact that 2.6.15.6 is not\nan ancestor of 2.6.16.  The warning in the man page about branches that\nare modified nonlinearly seems to apply.\n\nHow do I make my customized 2.6.16 kernel?\n\n-- \nMatt McCutchen\nhashproduct@verizon.net\nhttp://hashproduct.metaesthetics.net/\n"},{"id":"18105","messageId":"Pine.LNX.4.64.0603281749060.15714@g5.osdl.org","threadId":"3746","inReplyTo":"1143596622.2481.10.camel@mattlaptop.metaesthetics.net","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-03-29T02:10:46Z","receivedAt":"2006-03-29T02:10:46Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Tue, 28 Mar 2006, Matt McCutchen wrote:\n> \n> I made a customized Linux kernel based on 2.6.15.6 by cloning the stable\n> 2.6.15 kernel repository (which was then at version 2.6.15.6) and making\n> several commits.  Now I would like a Linux kernel based on 2.6.16 with\n> the same customizations.  This seems to be a very simple task, but I\n> have been trying various combinations of git commands for several days\n> and have not figured out how to do it.\n> \n> I believe that means I should pull the 2.6.16 kernel into the \"origin\"\n> branch and then rebase the \"master\" branch, \n\nDon't \"Pull\". \"Fetch\".\n\n\"Pull\" implies a merge, which is not what you want.\n\n>\t\t To this end, I switched my remote file to point to the\n> 2.6.16 stable repository and tried to pull.  The result was not what I\n> wanted.  The situation is complicated by the fact that 2.6.15.6 is not\n> an ancestor of 2.6.16.  The warning in the man page about branches that\n> are modified nonlinearly seems to apply.\n\nJust realize that you can have any number of branches, and instead of \nforcing \"origin\" to be something that it simply is not, just create a new \nbranch called \"linus\".\n\nMake that point to my tree, and do\n\n\tgit fetch linus\n\nto update it. It really is that easy.\n\nExact commands something like this:\n\n (1) Edit your .git/remotes/linus file so that it has the following \n     contents:\n\n\tURL: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6\n\tPull: refs/heads/master:refs/heads/linus\n\n (2) Use that to fetch my tree as the \"linus\" branch:\n\n\tgit fetch linus\n\nand now you have at least a nice new branch that contains the \"standard\" \nkernel. At which point you just need to do\n\n (3) rebase the work since \"origin\" onto \"linus\":\n\n\tgit rebase --onto linus origin\n\nI really really despise the \"git rebase\" command line syntax, and I find \nit very non-inuitive, but what this does is take your current branch, \ncompare its contents to \"origin\" (ie where you started from), and then \njust rebase the commits onto the state that is \"linus\".\n\n[ Junio: syntax comments:\n\n  Personally, I think the rebase syntax sucks, because the _natural_ way \n  to do it is to just describe the set of commits to rebase the same way \n  we describe all _other_ commit sets: as a \"begin..end\" sequence.\n\n  So I think rebase _should_ work something like this:\n\n\tgit rebase origin.. [--onto] linus\n\n  ie just giving an arbitrary range. This is even more noticeable for \n  \"git-format-patch\", where that insane \"<his> [<mine>]\" syntax is even \n  worse, for no good reason, when again it should really just work like \n  \"git diff\" where giving a single revision implies a single revision, and \n  giving a range implies a range, and no strange \"mine\" vs \"his\" rules ]\n\nOh well. Syntax rant over.\n\n\t\t\tLinus\n"},{"id":"18106","messageId":"20060329022330.GA15359@spearce.org","threadId":"3746","inReplyTo":"1143596622.2481.10.camel@mattlaptop.metaesthetics.net","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-03-29T02:23:30Z","receivedAt":"2006-03-29T02:23:30Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Matt McCutchen <hashproduct@verizon.net> wrote:\n> Dear git people,\n> \n> I made a customized Linux kernel based on 2.6.15.6 by cloning the stable\n> 2.6.15 kernel repository (which was then at version 2.6.15.6) and making\n> several commits.  Now I would like a Linux kernel based on 2.6.16 with\n> the same customizations.  This seems to be a very simple task, but I\n> have been trying various combinations of git commands for several days\n> and have not figured out how to do it.\n> \n> I believe that means I should pull the 2.6.16 kernel into the \"origin\"\n> branch and then rebase the \"master\" branch, merging my customizations\n> with 2.6.16.  To this end, I switched my remote file to point to the\n> 2.6.16 stable repository and tried to pull.  The result was not what I\n> wanted.  The situation is complicated by the fact that 2.6.15.6 is not\n> an ancestor of 2.6.16.  The warning in the man page about branches that\n> are modified nonlinearly seems to apply.\n> \n> How do I make my customized 2.6.16 kernel?\n\nI think you want to use `git-fetch --force` to download origin but\nnot immediately merge it yet.  This will bypass the not-an-ancestor\ncheck you are running into.\n\nThen you can perform the rebase yourself with:\n\n\t# Export your local changes into a series of patches.\n\t#\n\tgit-format-patch -k --stdout --full-index v2.6.16.6 >changes.mbox\n\n\t# Checkout the new origin (2.6.16) into master.\n\t#\n\tgit-reset --hard origin\n\n\t# Now apply your patches.\n\t#\n\tgit-am --binary -3 changes.mbox\n\nIf you get merge conflicts fix them up and restart with\n`git-am --resolved`.\n\n\nNote this is the logic of `git-rebase` except it doesn't require\nyou to actually have a common ancestor, while `git-rebase` does.\n\n-- \nShawn.\n"},{"id":"18107","messageId":"7vmzfac7gn.fsf@assigned-by-dhcp.cox.net","threadId":"3746","inReplyTo":"1143596622.2481.10.camel@mattlaptop.metaesthetics.net","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-03-29T02:26:00Z","receivedAt":"2006-03-29T02:26:00Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matt McCutchen <hashproduct@verizon.net> writes:\n\n> I made a customized Linux kernel based on 2.6.15.6 by cloning the stable\n> 2.6.15 kernel repository (which was then at version 2.6.15.6) and making\n> several commits.  Now I would like a Linux kernel based on 2.6.16 with\n> the same customizations.\n\nDrawing ancestry graph would help visualizing what you want to\nachieve.  You have:\n\n       v2.6.15\n    ---o\n        \\ \n         \\\n          \\                 \n           o---o---o v2.6.15.6\n                    \\\n                     x---x---x v2.6.15.6-matt\n\nwhere x---x---x are your own changes, and you want:\n\n       v2.6.15           v2.6.16\n    ---o---o---o---...---o---o\n        \\                     \\\n         \\                     y---y---y 2.6.16-matt\n          \\                 \n           o---o---o v2.6.15.6\n                    \\\n                     x---x---x 2.6.15.6-matt\n\nto happen, where y---y---y are analogous to x---x---x.\n\nAssuming your branches are:\n\n        origin - v2.6.15.6 (from stable team)\n        master - your changes (2.6.15.6-matt)\n\nyou could:\n\n        $ git fetch git://../torvalds/linux-2.6.git tag v2.6.16\n        $ git checkout -b 2.6.16-matt v2.6.16\n        $ git format-patch origin master | git am -3\n\nAlternatively, you might want to do a real merge:\n\n       v2.6.15           v2.6.16\n    ---o---o---o---...---o---o\n        \\                     \\\n         \\                     \\ \n          \\                     m 2.6.16-matt\n           o---o---o v2.6.15.6 /\n                    \\         /\n                     x---x---x 2.6.15.6-matt\n\nPresumably the stable team backported safer changes from the\nhistory between v2.6.15-v2.6.16, and the way things are fixed\nare probably quite different from the equivalent fixes in the\ndevelopment track that led to v2.6.16 (because what's being\npatched has also changed), so it is very likely you would see\nserious conflicts during this merge.  If you do not understand\nwhat the stable team did in order to reimplement certain fixes,\nyou would have a very difficult time deciding on how to resolve\nconflicts with this merge.\n\nAt that point it would not be a git question but the kernel\nquestion I am not qualified to answer ;-), but it might be an\ninteresting exercise.\n"},{"id":"18108","messageId":"7virpyc79a.fsf@assigned-by-dhcp.cox.net","threadId":"3746","inReplyTo":"Pine.LNX.4.64.0603281749060.15714@g5.osdl.org","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-03-29T02:30:25Z","receivedAt":"2006-03-29T02:30:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> Oh well. Syntax rant over.\n\nYeah, inertia, backward compatibility wart, craziness.\n"},{"id":"18109","messageId":"7vlkutc36w.fsf@assigned-by-dhcp.cox.net","threadId":"3746","inReplyTo":"Pine.LNX.4.64.0603281749060.15714@g5.osdl.org","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-03-29T03:58:15Z","receivedAt":"2006-03-29T03:58:15Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n>   Personally, I think the rebase syntax sucks, because the _natural_ way \n>   to do it is to just describe the set of commits to rebase the same way \n>   we describe all _other_ commit sets: as a \"begin..end\" sequence.\n\nI'd agree in general, and I am not happy about them.\n\nBut I have an excuse.\n\nrev-parse's A..B notation was invented on June 13th (178cb24).\nBut format-patch was originally posted on May 30th:\n\n\thttp://article.gmane.org/gmane.comp.version-control.git/4279\n\nbefore the convenience of rev-parse was invented ;-).\n\n>   So I think rebase _should_ work something like this:\n>\n> \tgit rebase origin.. [--onto] linus\n>\n>   ie just giving an arbitrary range.\n\nIn addition, both rebase and format-patch does a bit more than\nstraight his..mine.\n\n    *---x---x---o---o---o---o\n     \\                      ^mine\n      .---.---.---.\n                  ^his\n\nWe do _not_ want to process all six of his..mine commits when\ndoing \"format-patch his mine\" in the above picture, because\nupstream might have accepted some of them already, and we filter\nthem out with git-cherry.  \n\n>   This is even more noticeable for \"git-format-patch\", where\n>   that insane \"<his> [<mine>]\" syntax is even worse, for no\n>   good reason, when again it should really just work like \"git\n>   diff\" where giving a single revision implies a single\n>   revision, and giving a range implies a range, and no strange\n>   \"mine\" vs \"his\" rules ]\n\nHaving said that, you have been able to say format-patch A..B\nC..D E..F for quite some time (since November 21, 2005).\n\nRebase is even more strange, especially with --onto.  When you do\n\n    $ rebase --onto his origin mine\n\nin this picture,\n\n    *---x---x---o---o---o---o\n     \\      ^origin         ^mine\n      .---.---.---.\n                  ^his\n\nyou are discarding two 'x' commits, and lost-found is the only\nthing that would help you to recover them.\n\nUnlike format-patch which takes ranges, rebase does not let you\nsay \"rebase --onto base A..B C..D E..F\"; what happens might be\ntoo confusing, especially if B, D, F are not coming from the\ncurrent branch.  The current branch is rewound to base and then\nthe chosen sets of patches are applied, which is kind-of scary.\nIt would feel safer to do:\n\n\t$ git checkout -b newbranch base\n        $ git format-patch --stdout A..B C..D E..F | git am -3\n\nand after making sure the result is really what you want\nresetting the original branch to the current (newbranch) head.\n"},{"id":"18128","messageId":"Pine.LNX.4.64.0603291102440.15714@g5.osdl.org","threadId":"3746","inReplyTo":"7vlkutc36w.fsf@assigned-by-dhcp.cox.net","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-03-29T19:27:46Z","receivedAt":"2006-03-29T19:27:46Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Tue, 28 Mar 2006, Junio C Hamano wrote:\n> \n> Having said that, you have been able to say format-patch A..B\n> C..D E..F for quite some time (since November 21, 2005).\n\nYes, and the documentation still talks only about the old insane format..\n\n> Rebase is even more strange, especially with --onto.  When you do\n> \n>     $ rebase --onto his origin mine\n> \n> in this picture,\n> \n>     *---x---x---o---o---o---o\n>      \\      ^origin         ^mine\n>       .---.---.---.\n>                   ^his\n> \n> you are discarding two 'x' commits, and lost-found is the only\n> thing that would help you to recover them.\n\n.. and this is largely because the whole interface is broken.\n\nThe breakage shows up as inflexibility and having a hard time explaining \nwhat the thing does.  It shows up as confusion about the usage, and about \nthe meaning of a simple command line.\n\nFor example, in the most trivial format, doing a\n\n\tgit rebase <branchname>\n\nthe _logical_ thing (from just reading the command) to believe the above \ndoes is to think that it rebases the named branch. I pretty much guarantee \nthat that is what any native English speaker would think it does, if they \nthought about it.\n\nThe fact that it actually does the _reverse_, and rebases not the named \nbranch, but the branch you are on right now.\n\nThe fact that when things go south, the old branch has gotten lost (unless \nyou remember about ORIG_HEAD) is all related to the same thing. It's just \na very non-intuitive interface.\n\nThat was fine when people weren't supposed to use it, and it was doing \nsomething very very special, but that has clearly changed over time. Now \npeople are encouraged to use it, it's pretty well-known, and even new git \nusers seem to want to do it.\n\nI think \"git rebase\" is a lost cause. It's just fundamentally a very very \nbadly designed command, because it does everything the wrong way around.\n\nI personally believe that the _sane_ way of doing rebasing is to \n - get rid of \"git rebase\" entirely\n - teach \"git cherry-pick\" to take a _range_ of commits instead.\n\nLookie here, let's look at your example a bit more (which in turn comes \nfrom the original question that started this thread):\n\n    *---x---x---o---o---o---o\n     \\      ^origin         ^mine\n      .---.---.---.\n                  ^his\n\nWe have three branch points, and we want to move the commits on \"mine\" \nfrom \"origin\" onto \"his\". How would you do this so that it's _not_ \nconfusing, and so that you can explain to a newbie user what he is doing, \n_especially_ if things go wrong in the middle?\n\nRight now, the sequence is:\n\n\tgit checkout mine\t\t\t# if required\n\tgit rebase --onto his origin\n\nand if things go south during the rebase, it's immediately total chaos, \nand you really _really_ need to understand what you are doing.\n\nThe above just doesn't make any sense. It's hard to explain why you would \ndo something like that.\n\nIn contrast, here's an alternate workflow that is much easier to explain, \nand doesn't involve \"rebase\" at all:\n\n\tgit checkout his\n\tgit cherry-pick origin..mine\n\nNotice what this does? Show these two sequences to anybody who has some \nbasic familiarity with git terminology, but has perhaps never actually \nused it, and ask them what the two sequences do. I pretty much guarantee \nthat the second sequence will make sense and get people to generally pick \nthe right answer, while the first sequence will make people maybe _guess_ \nthe right answer, but it's not intuitive.\n\nIn particular, what do you think happens when a patch in the series \ndoesn't apply under the two circumstances? Which workflow has the \n\"intuitive\" way of recovering, and which does not?\n\nRight. The second one has a very intuitive way to recover. In fact, it's \nso intuitive that the answer may be \"ok, I'll skip that one commit \nentirely because I don't know how to resolve it, and instead cherry-pick \nthe rest, and ask the original author to cherry-pick it for me later\". And \ndoing so is as easy as\n\n\tgit reset --hard\t# undo the mess from the failed one,\n\t\t\t\t# the same way we always do for all\n\t\t\t\t# other failed things\n\n\tgit cherry-pick next..mine\t# do the rest\n\nSee? That's a very logical thing to do. It's different from \"git rebase\", \nbut it's different in a _good_ way.\n\nIn contrast, the \"rebase\" conflict resolution is pretty damn esoteric, and \nusing a simple \"gitk --all\" when things go wrong won't help you pick \nthings up at all.\n\nNow, \"git cherry-pick\" doesn't actually support the above format, and I'm \nnot saying that the \"git rebase\" name itself is evil. I think we could fix \n\"git rebase\" to work better, but the semantics - the way they are \n_designed_ right now - are just horrible.\n\n\t\t\tLinus\n"},{"id":"18130","messageId":"Pine.LNX.4.64.0603291136100.15714@g5.osdl.org","threadId":"3746","inReplyTo":"Pine.LNX.4.64.0603291102440.15714@g5.osdl.org","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-03-29T19:39:06Z","receivedAt":"2006-03-29T19:39:06Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 29 Mar 2006, Linus Torvalds wrote:\n> \n> Right now, the sequence is:\n> \n> \tgit checkout mine\t\t\t# if required\n> \tgit rebase --onto his origin\n\nvs\n\n> \tgit checkout his\n> \tgit cherry-pick origin..mine\n\nBtw, I realize that the advantage of \"git rebase\" is that it doesn't \nchange somebody elses branch. However, we'd still be a lot better off with \nus simply doing the equivalent of something like\n\n    git checkout -b new-mine his && \n\tgit cherry-pick origin..mine &&\n\tgit rename-branch -f new-mine mine\n\ninstead of what git-rebase does now.\n\n\t\t\tLinus\n"},{"id":"18132","messageId":"7vd5g580e6.fsf@assigned-by-dhcp.cox.net","threadId":"3746","inReplyTo":"Pine.LNX.4.64.0603291102440.15714@g5.osdl.org","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-03-29T20:24:33Z","receivedAt":"2006-03-29T20:24:33Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> In contrast, here's an alternate workflow that is much easier to explain, \n> and doesn't involve \"rebase\" at all:\n>\n> \tgit checkout his\n> \tgit cherry-pick origin..mine\n\nYes, I think it would be good to deprecate/discard the current\nrebase and make cherry-pick the recommended workflow.\n\nOptionally.  I've been thinking about not using git-cherry while\ncherrypicking, because falling back to three-way merge seems to\nwork equally well in dealing with \"patch already applied\" case.\n\nAnyway, teaching the range notation to cherry-pick would be\nsomething like this, I suppose.\n\n---\ndiff --git a/git-cherry-pick.sh b/git-cherry-pick.sh\nnew file mode 100755\nindex 0000000..72a3828\n--- /dev/null\n+++ b/git-cherry-pick.sh\n@@ -0,0 +1,6 @@\n+#!/bin/sh\n+\n+. git-sh-setup\n+\n+git-format-patch --stdout --full-index -k \"$@\" |\n+git-am --binary -3 -k\ndiff --git a/Makefile b/Makefile\nindex d945546..e130d8c 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -114,7 +114,7 @@ ### --- END CONFIGURATION SECTION ---\n \n SCRIPT_SH = \\\n \tgit-add.sh git-bisect.sh git-branch.sh git-checkout.sh \\\n-\tgit-cherry.sh git-clone.sh git-commit.sh \\\n+\tgit-cherry.sh git-cherry-pick.sh git-clone.sh git-commit.sh \\\n \tgit-count-objects.sh git-diff.sh git-fetch.sh \\\n \tgit-format-patch.sh git-log.sh git-ls-remote.sh \\\n \tgit-merge-one-file.sh git-parse-remote.sh \\\n@@ -139,7 +139,7 @@ SCRIPT_PYTHON = \\\n SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \\\n \t  $(patsubst %.perl,%,$(SCRIPT_PERL)) \\\n \t  $(patsubst %.py,%,$(SCRIPT_PYTHON)) \\\n-\t  git-cherry-pick git-show git-status\n+\t  git-show git-status\n \n # The ones that do not have to link with lcrypto nor lz.\n SIMPLE_PROGRAMS = \\\n@@ -484,9 +484,6 @@ common-cmds.h: Documentation/git-*.txt\n \t    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t    $@.py >$@\n \tchmod +x $@\n-\n-git-cherry-pick: git-revert\n-\tcp $< $@\n \n git-show: git-whatchanged\n \tcp $< $@\n"},{"id":"18134","messageId":"e0fe1h$d5r$1@sea.gmane.org","threadId":"3746","inReplyTo":"Pine.LNX.4.64.0603291102440.15714@g5.osdl.org","subject":"Re: Rebase semantic and cherry-pick","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-03-30T01:59:16Z","receivedAt":"2006-03-30T01:59:16Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Linus Torvalds wrote:\n\n> In contrast, here's an alternate workflow that is much easier to explain,\n> and doesn't involve \"rebase\" at all:\n> \n> git checkout his\n> git cherry-pick origin..mine\n[...] \n> Now, \"git cherry-pick\" doesn't actually support the above format, and I'm\n> not saying that the \"git rebase\" name itself is evil. I think we could fix\n> \"git rebase\" to work better, but the semantics - the way they are\n> _designed_ right now - are just horrible.\n\nPerhaps if possible also have\n\ngit cherry-pick --whole-branch branchname\n\nmeaning\n\ngit cherry-pick branchname:begining..branchname:HEAD\n\n-- \nJakub Narebski\n"},{"id":"18135","messageId":"7vwtec7j37.fsf@assigned-by-dhcp.cox.net","threadId":"3746","inReplyTo":"e0fe1h$d5r$1@sea.gmane.org","subject":"Re: Rebase semantic and cherry-pick","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-03-30T02:38:20Z","receivedAt":"2006-03-30T02:38:20Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> Perhaps if possible also have\n>\n> git cherry-pick --whole-branch branchname\n>\n> meaning\n>\n> git cherry-pick branchname:begining..branchname:HEAD\n\nThere is no branchname:beginning in git.\n"},{"id":"18136","messageId":"Pine.LNX.4.64.0603291852140.27203@g5.osdl.org","threadId":"3746","inReplyTo":"7vwtec7j37.fsf@assigned-by-dhcp.cox.net","subject":"Re: Rebase semantic and cherry-pick","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-03-30T02:54:12Z","receivedAt":"2006-03-30T02:54:12Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 29 Mar 2006, Junio C Hamano wrote:\n\n> Jakub Narebski <jnareb@gmail.com> writes:\n> \n> > Perhaps if possible also have\n> >\n> > git cherry-pick --whole-branch branchname\n> >\n> > meaning\n> >\n> > git cherry-pick branchname:begining..branchname:HEAD\n> \n> There is no branchname:beginning in git.\n\nWell, in this case you don't need it. You just do\n\n\tgit cherry-pick HEAD..branch\n\nand it just magically does the right thing.\n\nFor consistency reasons, we should probably allow that to be written as \njust \"..branch\", the same way we can write \"branch..\" to mean \"everything \nin HEAD but not in \"branch\".\n\n\t\tLinus\n"},{"id":"18137","messageId":"1143687710.2524.1.camel@mattlaptop.metaesthetics.net","threadId":"3746","inReplyTo":"7vmzfac7gn.fsf@assigned-by-dhcp.cox.net","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Matt McCutchen","fromEmail":"hashproduct@verizon.net","sentAt":"2006-03-30T03:01:50Z","receivedAt":"2006-03-30T03:01:50Z","isPatch":false,"sender":{"key":"hashproduct@verizon.net","avatar":null},"body":"On Tue, 2006-03-28 at 18:26 -0800, Junio C Hamano wrote:\n>        v2.6.15           v2.6.16\n>     ---o---o---o---...---o---o\n>         \\                     \\\n>          \\                     y---y---y 2.6.16-matt\n>           \\                 \n>            o---o---o v2.6.15.6\n>                     \\\n>                      x---x---x 2.6.15.6-matt\n> \n> to happen, where y---y---y are analogous to x---x---x.\n> \n> Assuming your branches are:\n> \n>         origin - v2.6.15.6 (from stable team)\n>         master - your changes (2.6.15.6-matt)\n\nBeautiful diagram.  This is exactly my situation.\n\n> you could:\n> \n>         $ git fetch git://../torvalds/linux-2.6.git tag v2.6.16\n>         $ git checkout -b 2.6.16-matt v2.6.16\n>         $ git format-patch origin master | git am -3\n\nThis looks like what I want.  When I run the third command, however, I\nget \"no patch found\".  Four files corresponding to my four commits\nappear in my repository; I have attached them.  What is wrong?\n\n> Alternatively, you might want to do a real merge:\n> [...] If you do not understand\n> what the stable team did in order to reimplement certain fixes,\n> you would have a very difficult time deciding on how to resolve\n> conflicts with this merge.\n\nYes, I think this is the problem what I ran into before when I was\ntrying to pull.\n\nPerhaps this is just politics, but which kernel repository is more\nofficial, and why?  Linus's or the one I have been using,\n\tgit://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.16.y.git\n?\n\nThanks for the help!\n-- \nMatt McCutchen\nhashproduct@verizon.net\nhttp://hashproduct.metaesthetics.net/\n\n\n>From nobody Mon Sep 17 00:00:00 2001\nFrom: Matt McCutchen <matt@mattlaptop.metaesthetics.net>\nDate: Sun Mar 5 20:14:20 2006 -0500\nSubject: [PATCH] Changes for Matt's custom kernel: the Stickier Patch and appropriate markers.\n\n---\n\n Documentation/filesystems/stickier.txt |   24 ++++++\n README.matt                            |    1 \n fs/namei.c                             |  132 ++++++++++++++++++++++++++------\n localversion-matt                      |    1 \n 4 files changed, 132 insertions(+), 26 deletions(-)\n create mode 100644 Documentation/filesystems/stickier.txt\n create mode 100644 README.matt\n create mode 100644 localversion-matt\n\n6a2fe5757614310ca63e7b2bac1acb5c2081d86c\ndiff --git a/Documentation/filesystems/stickier.txt b/Documentation/filesystems/stickier.txt\nnew file mode 100644\nindex 0000000..03db966\n--- /dev/null\n+++ b/Documentation/filesystems/stickier.txt\n@@ -0,0 +1,24 @@\n+Matt McCutchen's Stickier Patch\n+-------------------------------\n+\n+In the official Linux kernel's filesystem support, the only thing the sticky bit does is restrict deletion and overwriting of directory entries: you can't unlink or move another file over a file you don't own in a sticky directory you don't own.\n+\n+The Stickier Patch makes two changes to the behavior of the sticky bit.  First, creating a link to a file you don't own in a sticky directory you don't own is now forbidden.  (Doing so used to be possible but irreversible, which I considered an incongruity.)\n+\n+Second, a sticky directory you don't own has restrictions on lookup by name beyond the requirement of execute permission.  You can always look up a file that you own or on which you have at least one permission (read, write, or execute).  If you try to look up another file, you get EPERM.  If you try to look up a nonexistent file, you get ENOENT if you can read or write the directory, but EPERM if you can only execute it.  These restrictions apply to all path following, so every system call that follows paths can potentially cause EPERM.\n+\n+Why this change?  If you want to allow everyone on your computer to read a folder in your home directory, you can set its permissions to 755; however, to get to the folder, people need execute on your home directory.  But giving them execute opens the door to loads of abuse.  People can guess filenames and see if those files exist in your home directory; if the files exist, people can stat them and learn their atimes, mtimes, and sizes.  Maybe they won't hit upon any of your personal files, but the names of your mailbox and your dotfiles are likely to be well-known.  People can find out when you last got mail and about how big the mail was, what programs you've used recently, and so forth.\n+\n+With the Stickier Patch, you can set your home directory sticky (mode 1711).  People can still get to the public folder, but trying to access any other name will cause EPERM.  They can't even learn whether the files exist, much less stat them.\n+\n+Alternatively, you can set your home directory to mode 1755, in which case others can list the names of all files but only see stat information for the public ones:\n+\tdrwxr-xr-t  81 matt matt 4096 Jan 18 16:13 .\n+\tdrwxr-xr-x   3 root root 4096 Jan  8 16:46 ..\n+\t?---------   ? ?    ?       ?            ? .bashrc\n+\tlrwxrwxrwx   1 matt matt   18 Jan 18 16:14 symlink -> some/target/path\n+\tdrwxr-xr-x   1 matt matt   18 Jan 18 16:14 public\n+\t?---------   ? ?    ?       ?            ? private\n+\n+Note that the symlink appears and is stattable because it grants everyone every permission; there's nothing you can do about this unless/until I make another patch that adds lchmod and meaningful symlink permissions (r == readlink, w == writelink (to be implemented), x == traverse).  In addition, the Stickier Patch does not change the behavior of readdir, which often gives the i-number and type of a file along with its name.  (In fact, a short-form ls listing will classify private directories as directories, not as unstattable, because short-form ls bases classification on readdir.)\n+\n+Future versions of the Stickier Patch may address these issues and may also provide a way to set a directory so private entries are hidden from readdir (setuid bit?).  In the meantime, if any of these issues is a concern, one should remove read permission and announce the names of files others may access in another venue so they don't have to guess.\ndiff --git a/README.matt b/README.matt\nnew file mode 100644\nindex 0000000..8df642d\n--- /dev/null\n+++ b/README.matt\n@@ -0,0 +1 @@\n+This is Matt McCutchen's custom kernel.  Right now, the only difference between it and the official one is the Stickier Patch, described in Documentation/filesystems/sticker.txt , which changes the behavior of the sticky bit on directories.\ndiff --git a/fs/namei.c b/fs/namei.c\nindex 6dbbd42..baea761 100644\n--- a/fs/namei.c\n+++ b/fs/namei.c\n@@ -766,6 +766,66 @@ fail:\n }\n \n /*\n+ * It's inline, so penalty for filesystems that don't use sticky bit is\n+ * minimal.\n+ * MATT -- null inode allowed, it's as if nobody owns it\n+ */\n+static inline int check_sticky(struct inode *dir, struct inode *inode)\n+{\n+\tif (!(dir->i_mode & S_ISVTX))\n+\t\treturn 0;\n+\tif (inode && inode->i_uid == current->fsuid)\n+\t\treturn 0;\n+\tif (dir->i_uid == current->fsuid)\n+\t\treturn 0;\n+\treturn !capable(CAP_FOWNER);\n+}\n+\n+/*\n+ * MATT -- Will a new entry refuse to adhere to the directory?  :)\n+ */\n+static inline int check_unsticky(struct inode *dir, uid_t new_owner)\n+{\n+\tif (!(dir->i_mode & S_ISVTX))\n+\t\treturn 0;\n+\tif (new_owner == current->fsuid)\n+\t\treturn 0;\n+\tif (dir->i_uid == current->fsuid)\n+\t\treturn 0;\n+\treturn !capable(CAP_FOWNER);\n+}\n+\n+/*\n+ * MATT\n+ * Check whether we can traverse a directory entry; return 0 or -Exxxx.\n+ * 1. We can if the directory entry isn't sticky for us (see check_sticky).\n+ * 2. If the entry points nowhere, we can traverse it if we can read or\n+ *    write the directory.\n+ * 3. If the entry points to a file, we can traverse it if we can read,\n+ *    write, or execute the file.\n+ * Because of the clumsy interface, we need several permission checks.\n+ */\n+static inline int may_traverse(struct inode *dir,struct inode *inode)\n+{\n+\tif (!check_sticky(dir, inode))\n+\t\treturn 0;\n+\tif (inode) {\n+\t\tif (permission(inode, MAY_READ, NULL) == 0\n+\t\t\t|| permission(inode, MAY_WRITE, NULL) == 0\n+\t\t\t|| permission(inode, MAY_EXEC, NULL) == 0)\n+\t\t\treturn 0;\n+\t\telse\n+\t\t\treturn -EPERM;\n+\t} else {\n+\t\tif (permission(dir, MAY_READ, NULL) == 0\n+\t\t\t|| permission(dir, MAY_WRITE, NULL) == 0)\n+\t\t\treturn 0;\n+\t\telse\n+\t\t\treturn -EPERM;\n+\t}\n+}\n+\n+/*\n  * Name resolution.\n  * This is the basic name resolution function, turning a pathname into\n  * the final dentry. We expect 'base' to be positive and a directory.\n@@ -794,6 +854,7 @@ static fastcall int __link_path_walk(con\n \t\tunsigned long hash;\n \t\tstruct qstr this;\n \t\tunsigned int c;\n+\t\tstruct inode *dirsave;\n \n \t\tnd->flags |= LOOKUP_CONTINUE;\n \t\terr = exec_permission_lite(inode, nd);\n@@ -801,6 +862,7 @@ static fastcall int __link_path_walk(con\n \t\t\terr = vfs_permission(nd, MAY_EXEC);\n  \t\tif (err)\n \t\t\tbreak;\n+\t\tdirsave = inode;\n \n \t\tthis.name = name;\n \t\tc = *(const unsigned char *)name;\n@@ -852,8 +914,16 @@ static fastcall int __link_path_walk(con\n \t\tif (err)\n \t\t\tbreak;\n \n-\t\terr = -ENOENT;\n \t\tinode = next.dentry->d_inode;\n+\t\t/*\n+\t\t * MATT -- May we traverse the entry?\n+\t\t * inode might be null; may_traverse checks this case and\n+\t\t * might cause EPERM to conceal whether the inode exists.\n+\t\t */\n+\t\terr = may_traverse(dirsave, inode);\n+\t\tif (err)\n+\t\t\tgoto out_dput;\n+\t\terr = -ENOENT;\n \t\tif (!inode)\n \t\t\tgoto out_dput;\n \t\terr = -ENOTDIR; \n@@ -906,6 +976,14 @@ last_component:\n \t\tif (err)\n \t\t\tbreak;\n \t\tinode = next.dentry->d_inode;\n+\t\t/*\n+\t\t * MATT -- May we traverse the entry?\n+\t\t * inode might be null; may_traverse checks this case and\n+\t\t * might cause EPERM to conceal whether the inode exists.\n+\t\t */\n+\t\terr = may_traverse(dirsave, inode);\n+\t\tif (err)\n+\t\t\tbreak;\n \t\tif ((lookup_flags & LOOKUP_FOLLOW)\n \t\t    && inode && inode->i_op && inode->i_op->follow_link) {\n \t\t\terr = do_follow_link(&next, nd);\n@@ -1260,21 +1338,6 @@ int fastcall __user_walk(const char __us\n }\n \n /*\n- * It's inline, so penalty for filesystems that don't use sticky bit is\n- * minimal.\n- */\n-static inline int check_sticky(struct inode *dir, struct inode *inode)\n-{\n-\tif (!(dir->i_mode & S_ISVTX))\n-\t\treturn 0;\n-\tif (inode->i_uid == current->fsuid)\n-\t\treturn 0;\n-\tif (dir->i_uid == current->fsuid)\n-\t\treturn 0;\n-\treturn !capable(CAP_FOWNER);\n-}\n-\n-/*\n  *\tCheck whether we can remove a link victim from directory dir, check\n  *  whether the type of victim is right.\n  *  1. We can't do it if dir is read-only (done in permission())\n@@ -1333,12 +1396,27 @@ static inline int may_delete(struct inod\n  *  4. We can't do it if dir is immutable (done in permission())\n  */\n static inline int may_create(struct inode *dir, struct dentry *child,\n-\t\t\t     struct nameidata *nd)\n+\t\t\t     struct nameidata *nd, uid_t new_owner)\n {\n \tif (child->d_inode)\n \t\treturn -EEXIST;\n \tif (IS_DEADDIR(dir))\n \t\treturn -ENOENT;\n+\tif (check_unsticky(dir, new_owner))\n+\t\treturn -EPERM;\n+\treturn permission(dir,MAY_WRITE | MAY_EXEC, nd);\n+}\n+\n+/* Same as may_create but allow the child to already exist.\n+ * Separately you should check may_delete on an existing child, if any.\n+ */\n+static inline int may_create_or_overwrite(struct inode *dir, struct dentry *child,\n+\t\t\t     struct nameidata *nd, uid_t new_owner)\n+{\n+\tif (IS_DEADDIR(dir))\n+\t\treturn -ENOENT;\n+\tif (check_unsticky(dir, new_owner))\n+\t\treturn -EPERM;\n \treturn permission(dir,MAY_WRITE | MAY_EXEC, nd);\n }\n \n@@ -1405,7 +1483,7 @@ void unlock_rename(struct dentry *p1, st\n int vfs_create(struct inode *dir, struct dentry *dentry, int mode,\n \t\tstruct nameidata *nd)\n {\n-\tint error = may_create(dir, dentry, nd);\n+\tint error = may_create(dir, dentry, nd, current->fsuid);\n \n \tif (error)\n \t\treturn error;\n@@ -1721,7 +1799,7 @@ EXPORT_SYMBOL_GPL(lookup_create);\n \n int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)\n {\n-\tint error = may_create(dir, dentry, NULL);\n+\tint error = may_create(dir, dentry, NULL, current->fsuid);\n \n \tif (error)\n \t\treturn error;\n@@ -1794,7 +1872,7 @@ out:\n \n int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)\n {\n-\tint error = may_create(dir, dentry, NULL);\n+\tint error = may_create(dir, dentry, NULL, current->fsuid);\n \n \tif (error)\n \t\treturn error;\n@@ -2032,7 +2110,7 @@ slashes:\n \n int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)\n {\n-\tint error = may_create(dir, dentry, NULL);\n+\tint error = may_create(dir, dentry, NULL, current->fsuid);\n \n \tif (error)\n \t\treturn error;\n@@ -2092,7 +2170,7 @@ int vfs_link(struct dentry *old_dentry, \n \tif (!inode)\n \t\treturn -ENOENT;\n \n-\terror = may_create(dir, new_dentry, NULL);\n+\terror = may_create(dir, new_dentry, NULL, inode->i_uid);\n \tif (error)\n \t\treturn error;\n \n@@ -2285,12 +2363,14 @@ int vfs_rename(struct inode *old_dir, st\n \tif (error)\n \t\treturn error;\n \n-\tif (!new_dentry->d_inode)\n-\t\terror = may_create(new_dir, new_dentry, NULL);\n-\telse\n-\t\terror = may_delete(new_dir, new_dentry, is_dir);\n+\terror = may_create_or_overwrite(new_dir, new_dentry, NULL, old_dentry->d_inode->i_uid);\n \tif (error)\n \t\treturn error;\n+\tif (new_dentry->d_inode) {\n+\t\terror = may_delete(new_dir, new_dentry, is_dir);\n+\t\tif (error)\n+\t\t\treturn error;\n+\t}\n \n \tif (!old_dir->i_op || !old_dir->i_op->rename)\n \t\treturn -EPERM;\ndiff --git a/localversion-matt b/localversion-matt\nnew file mode 100644\nindex 0000000..fd815c7\n--- /dev/null\n+++ b/localversion-matt\n@@ -0,0 +1 @@\n+.matt1\n-- \n1.2.4\n\n\n\n>From nobody Mon Sep 17 00:00:00 2001\nFrom: Matt McCutchen <matt@mattlaptop.metaesthetics.net>\nDate: Sun Mar 5 20:16:19 2006 -0500\nSubject: [PATCH] Create and add to .gitignore files so that source tree is git-clean after I\nbuild the kernel.\n\n---\n\n arch/i386/kernel/.gitignore     |    3 +++\n drivers/ieee1394/.gitignore     |    1 +\n drivers/scsi/aic7xxx/.gitignore |    4 ++++\n include/asm-i386/.gitignore     |    1 +\n scripts/kconfig/.gitignore      |    1 +\n 5 files changed, 10 insertions(+), 0 deletions(-)\n create mode 100644 arch/i386/kernel/.gitignore\n create mode 100644 drivers/ieee1394/.gitignore\n create mode 100644 drivers/scsi/aic7xxx/.gitignore\n create mode 100644 include/asm-i386/.gitignore\n\na52dcfea1864b643a58ab2e1693487037f64f233\ndiff --git a/arch/i386/kernel/.gitignore b/arch/i386/kernel/.gitignore\nnew file mode 100644\nindex 0000000..e8ef014\n--- /dev/null\n+++ b/arch/i386/kernel/.gitignore\n@@ -0,0 +1,3 @@\n+vsyscall-int80.so\n+vsyscall-sysenter.so\n+vsyscall.lds\ndiff --git a/drivers/ieee1394/.gitignore b/drivers/ieee1394/.gitignore\nnew file mode 100644\nindex 0000000..33da10a\n--- /dev/null\n+++ b/drivers/ieee1394/.gitignore\n@@ -0,0 +1 @@\n+oui.c\ndiff --git a/drivers/scsi/aic7xxx/.gitignore b/drivers/scsi/aic7xxx/.gitignore\nnew file mode 100644\nindex 0000000..a1a7fcd\n--- /dev/null\n+++ b/drivers/scsi/aic7xxx/.gitignore\n@@ -0,0 +1,4 @@\n+aic79xx_reg.h\n+aic79xx_seq.h\n+aic7xxx_reg.h\n+aic7xxx_seq.h\ndiff --git a/include/asm-i386/.gitignore b/include/asm-i386/.gitignore\nnew file mode 100644\nindex 0000000..62b0ac8\n--- /dev/null\n+++ b/include/asm-i386/.gitignore\n@@ -0,0 +1 @@\n+asm-offsets.h\ndiff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore\nindex 2dac344..8298ca8 100644\n--- a/scripts/kconfig/.gitignore\n+++ b/scripts/kconfig/.gitignore\n@@ -14,3 +14,4 @@ mconf\n qconf\n gconf\n kxgettext\n+zconf.hash.c\n-- \n1.2.4\n\n\n\n>From nobody Mon Sep 17 00:00:00 2001\nFrom: Matt McCutchen <matt@mattlaptop.metaesthetics.net>\nDate: Sun Mar 5 23:12:19 2006 -0500\nSubject: [PATCH] More ignore files for build outputs\n\n---\n\n arch/i386/boot/.gitignore       |    3 +++\n arch/i386/boot/tools/.gitignore |    1 +\n 2 files changed, 4 insertions(+), 0 deletions(-)\n create mode 100644 arch/i386/boot/.gitignore\n create mode 100644 arch/i386/boot/tools/.gitignore\n\n94eb588607845f97f0fceb6e95690142ba8a807a\ndiff --git a/arch/i386/boot/.gitignore b/arch/i386/boot/.gitignore\nnew file mode 100644\nindex 0000000..495f20c\n--- /dev/null\n+++ b/arch/i386/boot/.gitignore\n@@ -0,0 +1,3 @@\n+bootsect\n+bzImage\n+setup\ndiff --git a/arch/i386/boot/tools/.gitignore b/arch/i386/boot/tools/.gitignore\nnew file mode 100644\nindex 0000000..378eac2\n--- /dev/null\n+++ b/arch/i386/boot/tools/.gitignore\n@@ -0,0 +1 @@\n+build\n-- \n1.2.4\n\n\n\n>From nobody Mon Sep 17 00:00:00 2001\nFrom: Matt McCutchen <matt@mattlaptop.metaesthetics.net>\nDate: Sun Mar 5 23:16:01 2006 -0500\nSubject: [PATCH] Fix setlocalversion to follow a `ref: ' when looking for a GIT version suffix\n\n---\n\n scripts/setlocalversion |    7 +++++++\n 1 files changed, 7 insertions(+), 0 deletions(-)\n\n75f8f156ff1f7869b23edf795e9588e25755be5d\ndiff --git a/scripts/setlocalversion b/scripts/setlocalversion\nindex 7c805c8..229bda7 100644\n--- a/scripts/setlocalversion\n+++ b/scripts/setlocalversion\n@@ -35,6 +35,13 @@ sub do_git_checks {\n \tmy $head = <H>;\n \tchomp $head;\n \tclose(H);\n+\t# Follow a ref: in the HEAD\n+\tif ($head =~ s/^ref: //) {\n+\t\topen(H,\"<.git/\" . $head) or return;\n+\t\t$head = <H>;\n+\t\tchomp $head;\n+\t\tclose(H);\n+\t}\n \n \topendir(D,\".git/refs/tags\") or return;\n \tforeach my $tagfile (grep !/^\\.{1,2}$/, readdir(D)) {\n-- \n1.2.4\n\n"},{"id":"18138","messageId":"7v7j6c62s1.fsf@assigned-by-dhcp.cox.net","threadId":"3746","inReplyTo":"Pine.LNX.4.64.0603291102440.15714@g5.osdl.org","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-03-30T03:15:58Z","receivedAt":"2006-03-30T03:15:58Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> For example, in the most trivial format, doing a\n>\n> \tgit rebase <branchname>\n>\n> the _logical_ thing (from just reading the command) to believe the above \n> does is to think that it rebases the named branch. I pretty much guarantee \n> that that is what any native English speaker would think it does, if they \n> thought about it.\n\nNot really.  Most of the commands in git suite operate on the\ncurrent branch.\n\nAfter thinking about it a bit more, I still agree with you that\nthings are not as easy to explain as they should be, but I do\nnot think rebase is so broken anymore.\n\n> In contrast, here's an alternate workflow that is much easier to explain, \n> and doesn't involve \"rebase\" at all:\n>\n> \tgit checkout his\n> \tgit cherry-pick origin..mine\n\nThis is _easy_ to explain, yes.  However, I do not necessarily\nagree with what you said here:\n\n> In particular, what do you think happens when a patch in the series \n> doesn't apply under the two circumstances? Which workflow has the \n> \"intuitive\" way of recovering, and which does not?\n>\n> Right. The second one has a very intuitive way to recover. In fact, it's \n> so intuitive that the answer may be \"ok, I'll skip that one commit \n> entirely because I don't know how to resolve it, and instead cherry-pick \n> the rest, and ask the original author to cherry-pick it for me later\". And \n> doing so is as easy as\n>\n> \tgit reset --hard\t# undo the mess from the failed one,\n> \t\t\t\t# the same way we always do for all\n> \t\t\t\t# other failed things\n>\n> \tgit cherry-pick next..mine\t# do the rest\n\nIt is not so easy to figure out what the next should be.  If we\nlimit ourselves to the simplest case that origin is an ancestor\nof mine, yes, but in general, no.  We are rebasing presumably\nbecause upstream made independent progress so \"origin\" would not\nbe an ancestor of mine anymore; and you are talking about the\ngeneric rev-list syntax next..mine === ^next mine.\n\n\"reset --hard\" to stop cherry picking is easy.  I do not think\ncontinuing is as easy as you made it sound like.\n\nThere was a nontrivial amount of thought went into making the\n\"rebase\" restartable.  Actually, that thought was really for\nmaking the \"am\" restartable, and the hope was once the user\nbecomes familiar with how to restart \"am\", restarting \"rebase\"\nis just as easy because you restart them the same way.  You have\nit fall back to 3-way merge (and in the case of rebase, it _can_\nfall back to 3-way when the patch does not apply, because all\nthe blob object names recorded in the intermediate patch format\nare from your local repository), you resolve and prepare the\nindex to be committed, and say \"git am --resolved\".  We _could_\nmake \"git rebase --resolved\" a synonym for \"git am --resolved\",\nbecause \"rebase\" being tied to \"am\" only because the former is\nimplemented in terms of the latter behind the user _is_\nunintiutive.\n\n> See? That's a very logical thing to do. It's different from \"git rebase\", \n> but it's different in a _good_ way.\n\nAs I said, yes, the part to punt is easy.  But that is different\nfrom being able to continue smoothly.  And if you want to punt\nduring \"rebase\", you could just as easily do \"git reset --hard\nORIG_HEAD\", just like you would punt a failed merge with \"git\nreset --hard ORIG_HEAD\".\n\nThe non-English (and no natural language I presume) syntax\nrebase takes is a mistake from understandability point of view.\nI fully agree with that.  Let me think aloud how we could\nrephrase them better.\n\n(1) git rebase origin\n\n         A---B---C master (HEAD)\n        /\n    ---o---o---o---o origin\n\n    I started building on tip of his but while I was woking on\n    it he made independent progress.  I want to rebuild my\n    branch as if I started at the tip of his current branch.\n\n                     A---B---C master (HEAD)\n                    /\n    ---o---o---o---o origin\n\n(2) git rebase --onto origin A..C\n\n         A---B---C master (HEAD)\n        /\n    ---o---o---o---o origin\n\n    I started building on tip of his but while I was woking on\n    it he made independent progress.  I want to rebuild my\n    branch as if I started at the tip of his current branch, but\n    come to think of it I do not need A anymore.\n\n                     B---C master (HEAD)\n                    /\n    ---o---o---o---o origin\n\n    I personally feel _this_ form is the most logical, and form\n    (1) for the sake of consistency could be spelled as:\n\n        $ git rebase --onto origin origin..master\n\n    So you could think of (1) a convenient shorthand for this\n    spelled-out form.\n\n(3) git rebase --onto origin A..C topic\n\n               B---C topic\n              /\n         .---A---. master (HEAD)\n        /\n    ---o---o---o---o origin\n\n    I have a topic that interferes with what he did in his\n    latest updates, and I'd like to resolve the conflicts\n    early.  Currently I am not on that branch so first let me\n    switch to it.\n\n         .---A---. master\n        /\n    ---o---o---o---o origin\n                    \\\n                     B---C topic (HEAD)\n\n    This form was done only as a shorthand to save typing \"git\n    checkout topic\" at the beginning, just like \"git checkout -b\n    newbranch\" can be used to save typing \"git branch newbranch\"\n    before the checkout, but I agree it may have made things\n    more confusing.  We _could_ deprecate this form and require\n    the user to always switch branches before starting the\n    rebase.\n"},{"id":"18139","messageId":"7vy7ys4nwk.fsf@assigned-by-dhcp.cox.net","threadId":"3746","inReplyTo":"1143687710.2524.1.camel@mattlaptop.metaesthetics.net","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-03-30T03:22:35Z","receivedAt":"2006-03-30T03:22:35Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matt McCutchen <hashproduct@verizon.net> writes:\n\n>> you could:\n>> \n>>         $ git fetch git://../torvalds/linux-2.6.git tag v2.6.16\n>>         $ git checkout -b 2.6.16-matt v2.6.16\n>>         $ git format-patch origin master | git am -3\n>...\n> What is wrong?\n\nMe ;-).\n\nIt should have been \n\n        $ git format-patch --stdout origin master | git am -3\n\nSorry.\n\n> Perhaps this is just politics, but which kernel repository is more\n> official, and why?  Linus's or the one I have been using,\n> \tgit://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.16.y.git\n> ?\n\nLinus tree is the main development for the 2.6.(X+1), and\n2.6.x.y are managed by the stable team.  They serve different\npurposes, and both are \"official\".\n"},{"id":"18140","messageId":"7vmzf84n2h.fsf@assigned-by-dhcp.cox.net","threadId":"3746","inReplyTo":"Pine.LNX.4.64.0603291852140.27203@g5.osdl.org","subject":"Re: Rebase semantic and cherry-pick","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-03-30T03:40:38Z","receivedAt":"2006-03-30T03:40:38Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> For consistency reasons, we should probably allow that to be written as \n> just \"..branch\", the same way we can write \"branch..\" to mean \"everything \n> in HEAD but not in \"branch\".\n\nSomething like this, perhaps.\n\n-- >8 --\nrevision arguments: ..B means HEAD..B, just like A.. means A..HEAD\n\nFor consistency reasons, we should probably allow that to be written as \njust \"..branch\", the same way we can write \"branch..\" to mean \"everything \nin HEAD but not in \"branch\".\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\ndiff --git a/rev-parse.c b/rev-parse.c\nindex f176c56..e956cd5 100644\n--- a/rev-parse.c\n+++ b/rev-parse.c\n@@ -315,16 +315,17 @@ int main(int argc, char **argv)\n \t\tdotdot = strstr(arg, \"..\");\n \t\tif (dotdot) {\n \t\t\tunsigned char end[20];\n-\t\t\tchar *n = dotdot+2;\n+\t\t\tchar *next = dotdot + 2;\n+\t\t\tchar *this = arg;\n \t\t\t*dotdot = 0;\n-\t\t\tif (!get_sha1(arg, sha1)) {\n-\t\t\t\tif (!*n)\n-\t\t\t\t\tn = \"HEAD\";\n-\t\t\t\tif (!get_sha1(n, end)) {\n-\t\t\t\t\tshow_rev(NORMAL, end, n);\n-\t\t\t\t\tshow_rev(REVERSED, sha1, arg);\n-\t\t\t\t\tcontinue;\n-\t\t\t\t}\n+\t\t\tif (!*next)\n+\t\t\t\tnext = \"HEAD\";\n+\t\t\tif (dotdot == arg)\n+\t\t\t\tthis = \"HEAD\";\n+\t\t\tif (!get_sha1(this, sha1) && !get_sha1(next, end)) {\n+\t\t\t\tshow_rev(NORMAL, end, next);\n+\t\t\t\tshow_rev(REVERSED, sha1, this);\n+\t\t\t\tcontinue;\n \t\t\t}\n \t\t\t*dotdot = '.';\n \t\t}\ndiff --git a/revision.c b/revision.c\nindex 745b0d2..2cda7e0 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -642,14 +642,19 @@ int setup_revisions(int argc, const char\n \t\tif (dotdot) {\n \t\t\tunsigned char from_sha1[20];\n \t\t\tchar *next = dotdot + 2;\n+\t\t\tchar *this = arg;\n+\t\t\tstatic const char HEAD[] = \"HEAD\";\n \t\t\t*dotdot = 0;\n \t\t\tif (!*next)\n-\t\t\t\tnext = \"HEAD\";\n-\t\t\tif (!get_sha1(arg, from_sha1) && !get_sha1(next, sha1)) {\n+\t\t\t\tnext = HEAD;\n+\t\t\tif (dotdot == arg)\n+\t\t\t\tthis = HEAD;\n+\t\t\tif (!get_sha1(this, from_sha1) &&\n+\t\t\t    !get_sha1(next, sha1)) {\n \t\t\t\tstruct commit *exclude;\n \t\t\t\tstruct commit *include;\n \n-\t\t\t\texclude = get_commit_reference(revs, arg, from_sha1, flags ^ UNINTERESTING);\n+\t\t\t\texclude = get_commit_reference(revs, this, from_sha1, flags ^ UNINTERESTING);\n \t\t\t\tinclude = get_commit_reference(revs, next, sha1, flags);\n \t\t\t\tif (!exclude || !include)\n \t\t\t\t\tdie(\"Invalid revision range %s..%s\", arg, next);\n"},{"id":"18141","messageId":"1143690475.2524.7.camel@mattlaptop.metaesthetics.net","threadId":"3746","inReplyTo":"7vy7ys4nwk.fsf@assigned-by-dhcp.cox.net","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Matt McCutchen","fromEmail":"hashproduct@verizon.net","sentAt":"2006-03-30T03:47:55Z","receivedAt":"2006-03-30T03:47:55Z","isPatch":false,"sender":{"key":"hashproduct@verizon.net","avatar":null},"body":"On Wed, 2006-03-29 at 19:22 -0800, Junio C Hamano wrote:\n> It should have been \n> \n>         $ git format-patch --stdout origin master | git am -3\n\nThanks!  My kernel is finally merged and is building as I write!  It\nturns out that parts of my commits #2-#4 had already been addressed\nbetween 2.6.15.6 and 2.6.16.  I had to merge #2 with what had already\nbeen done, and #3 and #4 became unnecessary.\n-- \nMatt McCutchen\nhashproduct@verizon.net\nhttp://hashproduct.metaesthetics.net/\n"},{"id":"18151","messageId":"Pine.LNX.4.64.0603300919280.27203@g5.osdl.org","threadId":"3746","inReplyTo":"1143687710.2524.1.camel@mattlaptop.metaesthetics.net","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-03-30T17:32:38Z","receivedAt":"2006-03-30T17:32:38Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 29 Mar 2006, Matt McCutchen wrote:\n> \n> Perhaps this is just politics, but which kernel repository is more\n> official, and why?  Linus's or the one I have been using,\n> \tgit://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.16.y.git\n> ?\n\nThe beauty of git should be (and maybe that's not entirely true simply \nbecause of practical concerns) that there really need not be any notion of \n\"more official\".\n\nYou can fetch multiple different git trees from different sources into the \nsame git tree, and then keep them _all_ around equally as different \nbranches. You can move fixes between the different branches with \"git \ncherry-pick\", and you can merge different branches with \"git merge\"\n\nNow, the reason I say \"_should_ be\" rather than \"is\" is two-fold:\n\n - right now, a lot of the infrastructure is simply set up more towards \n   the \"one single source repository\" model. When you do a \"git clone\", it \n   kind of makes the origin special. That's how all the documentation is \n   written, and that's also the only remote branch that git creates \n   _automatically_ for you.\n\n   This really isn't a technical issue: the git code code doesn't care \n   about any special \"original\" repository. But the fact that you have to \n   create the \".git/remotes/linus\" file by hand, and that all the examples \n   in the docs end up talking about a single \"origin\" branch means that \n   people _think_ of git as a \"single origin\" thing.\n\n - the more fundamental one is that when you start mixing branches, you \n   have to be very careful if you expect the upstream projects to pull the \n   changes _back_. In particular, that's where you have to think twice (or \n   three times) about doing a \"git merge\" (or a \"git pull\", which \n   implicitly merges for you if it's not a pure fast-forward).\n\n   In particular, the fact that _you_ want to merge two trees that came \n   from different sources does _not_ imply that either of the two sources \n   might want to merge with each other. So if you merge the two together, \n   you may find it impossible to have either of them then pull from you: \n   they way want your changes, but they might not like the merge you did, \n   because they have different policies about that work than you did.\n\nSo while the first point is purely a \"mental model\" issue and about lack \nof helper scripts, the second point is fundamental.\n\nFor example, in your case it was almost certainly the right thing to do to \ncherry-pick your changes from the 2.6.15.6 branch onto the development \nbranch, because I simply don't want to merge the 2.6.15.6 stuff into the \nstandard tree: part of the _rules_ for the stable branch is that the \nthings it fixes should have been fixed in the development tree already, so \nmerging the stable tree should always be unnecessary (and often clash, \nalthough _hopefully_ in many cases the fixes in the stable tree are 1:1 \nidentical and will merge beautifully).\n\nAnyway: from a technical standpoint, no tree should be \"special\" or \"more \nofficial\" for git usage. But when merging data back to any of those trees \nthat aren't special, the source/history of the data is important to keep \nin mind. Branch \"a\" may not be any more special than branch \"b\", but when \nyou push changes back to the source of branch \"a\", the history of those \nchanges (relative to what the source was) is meaningful.\n\n\t\t\tLinus\n"},{"id":"18158","messageId":"1143755459.2487.12.camel@mattlaptop.metaesthetics.net","threadId":"3746","inReplyTo":"Pine.LNX.4.64.0603300919280.27203@g5.osdl.org","subject":"Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?","fromName":"Matt McCutchen","fromEmail":"hashproduct@verizon.net","sentAt":"2006-03-30T21:50:59Z","receivedAt":"2006-03-30T21:50:59Z","isPatch":false,"sender":{"key":"hashproduct@verizon.net","avatar":null},"body":"On Thu, 2006-03-30 at 09:32 -0800, Linus Torvalds wrote:\n> The beauty of git should be (and maybe that's not entirely true simply \n> because of practical concerns) that there really need not be any notion of \n> \"more official\".\n\nI understand this, and it is one of several reasons why I prefer git to\nother version control systems.  However, I thought there would be a\nsingle official kernel repository even if git didn't require it.  Junio\nexplained to me that both yours and the stable one are official for\ndifferent purposes.  I think I will use the stable one because it is\ncurrent enough for my needs.\n\n>  - the more fundamental one is that when you start mixing branches, you \n>    have to be very careful if you expect the upstream projects to pull the \n>    changes _back_. [...]\n\nTrue.  It might help several branches coordinate development if a commit\ncould be marked as \"equivalent\" to another commit so that, if both were\ninvolved in a merge, one could be thrown out.\n\n-- \nMatt McCutchen\nhashproduct@verizon.net\nhttp://hashproduct.metaesthetics.net/\n"}]}