{"thread":{"id":"3019","subject":"RE: git pull on Linux/ACPI release tree","startedAt":"2006-01-09T08:05:42Z","lastAt":"2006-01-12T07:33:20Z","messageCount":5,"participants":["Brown, Len","Junio C Hamano","Alex Riesen","Linus Torvalds"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"14348","messageId":"F7DC2337C7631D4386A2DF6E8FB22B3005A13706@hdsmsx401.amr.corp.intel.com","threadId":"3019","inReplyTo":null,"subject":"RE: git pull on Linux/ACPI release tree","fromName":"Brown, Len","fromEmail":"len.brown@intel.com","sentAt":"2006-01-09T08:05:42Z","receivedAt":"2006-01-09T08:05:42Z","isPatch":false,"sender":{"key":"len.brown@intel.com","avatar":"https://gravatar.com/avatar/a091f34f66caadb51d85a8a496800c6ccae73737e2f45762373e6b8c55fa5dd6?d=mp&s=160"},"body":"Linus,\nI think Tony has articulated the work-flow problem that\noriginally started this thread, as well as the fix.\n\n>I'll try to update the using-topic-branches document to capture this.\n>Some of the problem is that it doesn't quite capture what I'm doing\n>with my test/release branches.\n>\n>My release branch really is just used as a transfer point to Linus.\n>I usually[1] don't leave patches sitting in \"release\" for long enough\n>that I'll be tempted to merge in from Linus ... once I decide that\n>some patches are ready to go to Linus I'll update \"release\" from Linus\n>(which will be a fast-forward, so no history) merge in the topic\n>branches, do one final sanity build, push to kernel.org and send\n>the \"please pull\" e-mail.\n>\n>The huge majority of my \"automatic update from upstream\" merges\n>go into my test branch ... which never becomes part of the real\n>history as I never ask Linus to pull from it.\n>\n>-Tony\n>\n>[1] Sometimes I goof on this because I forget that I've applied\n>a trivial patch directly to the release branch without going through\n>a topic branch.  I think I'll fix my update script to check \n>for this case.\n\nI figured that checking some trivial patches directly into \"release\"\nwould be a convenient way to make sure I didn't forget to push them --\nas they didn't depend on anything else in my tree.  Okay.\n\nTo make sure that my test branch (where I generate my consolidated\nplain patch, and what Andrew pulls) includes everything, I then pull\n\"release\" into \"test\".  Still good.\n\nBut then I decide I need to update my test tree from upstream.\nI did this by pulling \"linus\" into \"release\", and then pulling\n\"release\" into \"test\".  This creates the book-keeping merge\nin \"release\" that irritates gitk users.\n\nThis \"flow\", BTW, is a habit I picked up from the\n\"two-phase release strategy\" that we used in bk days.\nThere I'd pull from upstream down into my to-linus tree and then pull\nfrom the to-linus tree into the to-andrew tree.\nI expect BK also created a merge cset, but apparently\nnobody was looking at the history like they do with gitk today.\n\nSo if I simply don't pull from \"linus\" into a modified\n\"release\" branch then the cluttered history issue goes away.\nI should fetch \"linus\" into \"release\" right before I merge\nthe topic branches into \"release\" and push upstream.\nThe fetch is a clean fast-forward, and the merges all have\nreal content.\n\nThis will work as long as \"release\" doesn't get too old\nto be pulled upstream without conflicts.  Based on past\nexperience with low latency pulls upstream, I think this will be rare.\n\nAndrew will still get cluttered history in the test tree,\nbut as he's focused on the content and not the (throw-away) history,\nthis is surely a non-issue.\n\nSo problem #1 is solved, yes?\n\nGoing forward...\nI'm hopeful that gitk users will not be irritated also\nby the liberal use of topic branches.  I'm starting to like using\nthem quite a bit.  Yes, it is true that I could cherry-pick\nthe topics out of their original context to re-manufacture linear\nhistory.  But that is extra work.  Also, as you poined out,\nthere is real value in the real history because the context is accurate.\nFurther, I find that sometimes I need to augment a topic branch\nwith a follow-up patch.  I can checkout the topic branch an plop\nthe follow-up right on the tip where it logically should live,\nand (Tony's) scripts will remind me when the branch is not fully\npulled into test or release -- so it will never get misplaced.\n\nIn the case where a topic branch is a single commit, gitk users\nwill see both the original commit, as well as the merge commit\nback into \"release\".\n\n-Len\n"},{"id":"15380","messageId":"Pine.LNX.4.64.0601090835580.3169@g5.osdl.org","threadId":"3019","inReplyTo":"F7DC2337C7631D4386A2DF6E8FB22B3005A13706@hdsmsx401.amr.corp.intel.com","subject":"RE: git pull on Linux/ACPI release tree","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-01-09T16:47:39Z","receivedAt":"2006-01-09T16:47:39Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 9 Jan 2006, Brown, Len wrote:\n> >\n> >The huge majority of my \"automatic update from upstream\" merges\n> >go into my test branch ... which never becomes part of the real\n> >history as I never ask Linus to pull from it.\n> >\n> >-Tony\n> >\n> >[1] Sometimes I goof on this because I forget that I've applied\n> >a trivial patch directly to the release branch without going through\n> >a topic branch.  I think I'll fix my update script to check \n> >for this case.\n> \n> I figured that checking some trivial patches directly into \"release\"\n> would be a convenient way to make sure I didn't forget to push them --\n> as they didn't depend on anything else in my tree.  Okay.\n\nOne thing we could do is to make it easier to apply a patch to a \n_non_current_ branch.\n\nIn other words, let's say that we want to encourage the separation of a \n\"development branch\" and a \"testing and use\" branch (which I'd definitely \npersonally like to encourage people to do).\n\nAnd one way to do that might be to teach \"git-apply\" to apply patches to a \nnon-active branch, and then you keep the \"testing and use\" branch as your \n_checked_out_ branch (and it's going to be really dirty), but when you \nactually apply patches you could do that to the \"development\" branch with \nsomething like\n\n\tgit-apply -b development < patch-file\n\n(Now, of course, that's only if you apply somebody elses patch - if you \nactually do development _yourself_, you'd either have to check out the \ndevelopment branch and do it there, or you'd move the patch you have in \nyour \"ugly\" checked-out testing branch into the development branch with\n\n\tgit diff | git-apply -b development\n\nor something similar..)\n\nThen you could always do \"git pull . development\" to pull in the \ndevelopment stuff into your working branch - keeping the development \nbranch clean all the time.\n\nDo you think that kind of workflow would be more palatable to you? It \nshouldn't be /that/ hard to make git-apply branch-aware... (It was part of \nmy original plan, but it is more work than just using the working \ndirectory, so I never finished the thought).\n\n> I'm hopeful that gitk users will not be irritated also\n> by the liberal use of topic branches.\n\n\"gitk\" is actually pretty good at showing multiple branches. Try doing a\n\n\tgitk --all -d\n\nand you'll see all the topic branches in date order. The \"-d\" isn't \nstrictly necessary, and to some degree makes the output messier by \ninterleaving the commits from different branches, so you may not want to \ndo it, but it is sometimes nice to see the \"relative dates\" of individual \ncommits rather than the denser format that gitk defaults to.\n\n> In the case where a topic branch is a single commit, gitk users\n> will see both the original commit, as well as the merge commit\n> back into \"release\".\n\nYes, topic branches will always imply more commits, but I think they are \nof the \"nice\" kind.\n\nI definitely encourage people to use git as a distributed concurrent \ndevelopment system ratehr than the \"collection of patches\" thing. Quilt is \nmuch better at the collection of patches. \n\nSo I'd encourage topic branches - even within something like ACPI, you \nmight have separate topics (\"interpreter\" branch vs \"x86\" branch vs \n\"generic-acpi\" branch).\n\nAnd yes, that will make history sometimes messier too, and it will cause \nmore merges, but the difference there is that the merges will be \nmeaningful (ie merging the \"acpi interpreter\" branch into the generic ACPI \nbranch suddenly has _meaning_, even if there only ends up being a couple \nof commits per merge).\n\nOk?\n\n\t\tLinus\n"},{"id":"14362","messageId":"7vu0cdjhd1.fsf@assigned-by-dhcp.cox.net","threadId":"3019","inReplyTo":"Pine.LNX.4.64.0601090835580.3169@g5.osdl.org","subject":"Re: git pull on Linux/ACPI release tree","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-01-09T20:06:50Z","receivedAt":"2006-01-09T20:06:50Z","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> One thing we could do is to make it easier to apply a patch to a \n> _non_current_ branch.\n>...\n> And one way to do that might be to teach \"git-apply\" to apply patches to a \n> non-active branch,...\n>\n> \tgit diff | git-apply -b development\n>\n> or something similar..)\n>\n> Then you could always do \"git pull . development\" to pull in the \n> development stuff into your working branch - keeping the development \n> branch clean all the time.\n\nI had to do something like that last night, when I hacked on\ngitweb.  gitweb as shipped does not work for anybody but kay\n(e.g. it has /home/kay hardcoded in it).  So I did:\n\n\t$ git clone git://git.kernel.org/pub/scm/git/gitweb gitweb\n        $ cd gitweb\n        $ git checkout -b custom\n        $ edit gitweb.cgi ;# adjust /home/kay -> somewhere else etc.\n        $ git commit -a -m \"customization for junio's home\"\n\nThen I started preparing a proposed fix for Kay:\n\n\t$ git checkout -b symref master\n        $ edit gitweb.cgi\n        $ git commit -a -s -m \"make it work on symref repository\"\n\nNow the thing is that I cannot test symref branch as is.  I\ndeliberately omitted the change necessary to make the upstream\nwork on my local machine from that branch, because I want to\nkeep my home-machine customization separate from what I will\neventually feed Kay.  So I do a throwaway test branch:\n\n\t$ git checkout -b test master\n        $ git pull . custom symref ;# an octopus ;-)\n        # I could have done two separate pulls, custom then symref.\n\nThe interesting part starts here.  Inevitably, I find bugs and\nbugs and bugs in the test branch, and I fix them in the working\ntree, without committing.  Eventually things starts working.\nI did not commit here in the test branch, because the symref\nbranch is where I intend to keep this set of changes.  So\ninstead, I did this:\n\n\t$ git diff HEAD >P.diff\n        $ git checkout -f symref\n        $ git reset --soft HEAD^\n        $ git apply P.diff\n        $ git commit -a -C ORIG_HEAD\n\nUsually I strongly discourage people to use \"checkout -f\"\nbecause it will leave files that are in the current branch but\nnot in the new branch behind in the working tree.  Here I used\n\"checkout -f symref\" because I knew this is a one-file project.\n\nInstead of fixing the symref commit in place like this, I could\nhave committed P.diff as a separate \"fixup\" commit on top of the\nsymref branch, in which case the above sequence would have been:\n\n\t$ git diff HEAD >P.diff\n        $ git checkout -f symref\n        $ git apply P.diff\n        $ git commit -a -m 'fixup bugs in the previous.'\n\nbut I did not --- it would have been more disgusting than\nhonest.\n\nAnd after that, the usual format-patch:\n\n\t$ git format-patch origin..symref\n\nIn either case, this *was* cumbersome.  And I did it twice for\ntwo independent topics.  Admittedly, these topic branches were\nboth single-commit topics, and in real life your subsystem\nmaintainers must be facing bigger mess than this toy experience\nof mine, but the principle is the same.\n\nI think there are a couple of ways to improve what I had to do.\nI'll think aloud here.  The fictitious transcripts all start\nafter I got things working in the test branch working tree, with\na clean index file (i.e. changes are in the working tree only).\n\n1. Make a commit in the \"test\" branch, and then cherry-pick the\n   commit back to the topic branch:\n\n\t$ git commit -a -m \"Fix symref fix\"\n        $ git checkout symref\n        $ git cherry-pick -r test\n\n2. Fix \"git checkout <branch>\" so that it does a reasonable thing\n   even when a dirty path is different in current HEAD and\n   destination branch.  Then I could:\n\n\t$ git checkout symref ;# this would not work in the current git\n\t    # it would die like this:\n            # $ git checkout symref\n            # fatal: Entry 'gitweb.cgi' not uptodate. Cannot merge.\n\t$ git diff ;# just to make sure inevitable automated merge\n\t\t    # did the right thing\n        $ git commit -a -m \"Fix symref fix\"\n\t    # I could collapse them into one instead, like this:\n\t    # $ git reset --soft HEAD^\n\t    # $ git commit -a -C ORIG_HEAD\n\nTo retest (possibly with latest from Kay), we can rebuild the\ntest branch from scratch since it is by definition a throwaway\nbranch and never is exposed to public:\n\n        $ git fetch origin\n\t$ git checkout test\n        $ git reset --head origin\n        $ git pull . custom symref\n\nObviously I prefer to have #2 work well, but #1 would work today.\n\nI am not sure if making \"git-apply\" to take different branch is\na sane approach.  It might make sense to teach git-applymbox and\ngit-am about branches, though.  So is teaching git-merge about\nmerging into different branch.\n"},{"id":"14411","messageId":"81b0412b0601100731p46ec276btfe04382a9e53bd5c@mail.gmail.com","threadId":"3019","inReplyTo":"7vu0cdjhd1.fsf-u5dp/1a/izZijMVVUgEtmwqrb7wDvxM8@public.gmane.org","subject":"Re: git pull on Linux/ACPI release tree","fromName":"Alex Riesen","fromEmail":"raa.lkml-re5jqeeqqe8avxtiumwx3w@public.gmane.org","sentAt":"2006-01-10T15:31:19Z","receivedAt":"2006-01-10T15:31:19Z","isPatch":false,"sender":{"key":"raa.lkml-re5jqeeqqe8avxtiumwx3w@public.gmane.org","avatar":null},"body":"On 1/9/06, Junio C Hamano <junkio-j9pdmedNgrk@public.gmane.org> wrote:\n> 2. Fix \"git checkout <branch>\" so that it does a reasonable thing\n>    even when a dirty path is different in current HEAD and\n>    destination branch.  Then I could:\n>\n>         $ git checkout symref ;# this would not work in the current git\n>             # it would die like this:\n>             # $ git checkout symref\n>             # fatal: Entry 'gitweb.cgi' not uptodate. Cannot merge.\n\nThat is actually very interesting. I already wished sometimes to be\nable to switch branches with a dirty working directory (and usually\nended up with git diff+checkout+apply).\nEven if it results in a merge and conflict markers in files it looks\nlike a very practical idea!\n\n>         $ git diff ;# just to make sure inevitable automated merge\n>                     # did the right thing\n>         $ git commit -a -m \"Fix symref fix\"\n>             # I could collapse them into one instead, like this:\n>             # $ git reset --soft HEAD^\n>             # $ git commit -a -C ORIG_HEAD\n-\nTo unsubscribe from this list: send the line \"unsubscribe linux-acpi\" in\nthe body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org\nMore majordomo info at  http://vger.kernel.org/majordomo-info.html\n"},{"id":"14538","messageId":"7v4q49uchr.fsf_-_@assigned-by-dhcp.cox.net","threadId":"3019","inReplyTo":"81b0412b0601100731p46ec276btfe04382a9e53bd5c@mail.gmail.com","subject":"[PATCH] checkout: automerge local changes while switching branches.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-01-12T07:33:20Z","receivedAt":"2006-01-12T07:33:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"When switching branches from A to B, if the working tree has a\nlocal modification at paths that are different between A and B,\nwe refused the operation saying \"cannot merge.\"  This attempts\nto do an automerge for such paths.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n Alex Riesen <raa.lkml-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> writes:\n\n > On 1/9/06, Junio C Hamano <junkio-j9pdmedNgrk@public.gmane.org> wrote:\n >> 2. Fix \"git checkout <branch>\" so that it does a reasonable thing\n >>    even when a dirty path is different in current HEAD and\n >>    destination branch.  Then I could:\n >>\n >>         $ git checkout symref ;# this would not work in the current git\n >>             # it would die like this:\n >>             # $ git checkout symref\n >>             # fatal: Entry 'gitweb.cgi' not uptodate. Cannot merge.\n >\n > That is actually very interesting. I already wished sometimes to be\n > able to switch branches with a dirty working directory (and usually\n > ended up with git diff+checkout+apply).\n > Even if it results in a merge and conflict markers in files it looks\n > like a very practical idea!\n\n This is still experimental and probably has rough edges, but I\n actually tested it once and it worked fine ;-).\n\n git-checkout.sh |   24 +++++++++++++++++++++++-\n 1 files changed, 23 insertions(+), 1 deletions(-)\n\n7929db987a9aac1d0370b64a8a00ffa13e6bab82\ndiff --git a/git-checkout.sh b/git-checkout.sh\nindex 3bbd111..1b2db91 100755\n--- a/git-checkout.sh\n+++ b/git-checkout.sh\n@@ -121,7 +121,29 @@ then\n \tgit-checkout-index -q -f -u -a\n else\n     git-update-index --refresh >/dev/null\n-    git-read-tree -m -u $old $new\n+    git-read-tree -m -u $old $new || (\n+\techo >&2 -n \"Try automerge [y/N]? \"\n+\tread yesno\n+\tcase \"$yesno\" in [yY]*) ;; *) exit 1 ;; esac\n+\n+\t# NEEDSWORK: We may want to reset the index from the $new for\n+\t# these paths after the automerge happens, but it is not done\n+\t# yet.  Probably we need to leave unmerged ones alone, and\n+\t# yank the object name & mode from $new for cleanly merged\n+\t# paths and stuff them in the index.\n+\n+\tnames=`git diff-files --name-only`\n+\techo \"$names\" | git update-index --remove --stdin\n+\n+\twork=`git write-tree` &&\n+\tgit read-tree -m -u $old $work $new || exit\n+\tif result=`git write-tree 2>/dev/null`\n+\tthen\n+\t    echo >&2 \"Trivially automerged.\" ;# can this even happen?\n+\t    exit 0\n+\tfi\n+\tgit merge-index -o git-merge-one-file -a\n+    )\n fi\n \n # \n-- \n1.1.1-g8ecb\n"}]}