{"thread":{"id":"1516","subject":"[PATCH] Add some simple howtos, culled from the mailing list.","startedAt":"2005-08-15T08:25:53Z","lastAt":"2005-08-15T08:25:53Z","messageCount":1,"participants":["Ryan Anderson"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"7282","messageId":"1124094353822-git-send-email-ryan@michonline.com","threadId":"1516","inReplyTo":null,"subject":"[PATCH] Add some simple howtos, culled from the mailing list.","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2005-08-15T08:25:53Z","receivedAt":"2005-08-15T08:25:53Z","isPatch":true,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"I think these are useful, and I think putting them in a new \"howto\"\ndirectory might help some users until we get to the point of splitting\nup the tutorial to be easier to read.\n\nGiven the authorship, I think it's safe to put these in the repository.\n\nSigned-off-by: Ryan Anderson <ryan@michonline.com>\n---\n\n Documentation/howto/make-dist.txt                  |   47 ++++++\n Documentation/howto/rebase-and-edit.txt            |   78 ++++++++++\n .../howto/rebase-from-internal-branch.txt          |  163 +++++++++++++++++++++++\n 3 files changed, 288 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/howto/make-dist.txt\n create mode 100644 Documentation/howto/rebase-and-edit.txt\n create mode 100644 Documentation/howto/rebase-from-internal-branch.txt\n\n5276bcd9892bd712b648761f4b1eeaf6f972594b\ndiff --git a/Documentation/howto/make-dist.txt b/Documentation/howto/make-dist.txt\nnew file mode 100644\n--- /dev/null\n+++ b/Documentation/howto/make-dist.txt\n@@ -0,0 +1,47 @@\n+Date:   Fri, 12 Aug 2005 22:39:48 -0700 (PDT)\n+From: Linus Torvalds <torvalds@osdl.org>\n+To: Dave Jones <davej@redhat.com>\n+cc: git@vger.kernel.org\n+Subject: Re: Fwd: Re: git checkout -f branch doesn't remove extra files\n+\n+On Sat, 13 Aug 2005, Dave Jones wrote:\n+>\n+>  > Git actually has a _lot_ of nifty tools. I didn't realize that people\n+>  > didn't know about such basic stuff as \"git-tar-tree\" and \"git-ls-files\".\n+>\n+> Maybe its because things are moving so fast :)  Or maybe I just wasn't\n+> paying attention on that day. (I even read the git changes via RSS,\n+> so I should have no excuse).\n+\n+Well, git-tar-tree has been there since late April - it's actually one of\n+those really early commands. I'm pretty sure the RSS feed came later ;)\n+\n+I use it all the time in doing releases, it's a lot faster than creating a\n+tar tree by reading the filesystem (even if you don't have to check things\n+out). A hidden pearl.\n+\n+This is my crappy \"release-script\":\n+\n+        [torvalds@g5 ~]$ cat bin/release-script\n+        #!/bin/sh\n+        stable=\"$1\"\n+        last=\"$2\"\n+        new=\"$3\"\n+        echo \"# git-tag-script v$new\"\n+        echo \"git-tar-tree v$new linux-$new | gzip -9 > ../linux-$new.tar.gz\"\n+        echo \"git-diff-tree -p v$stable v$new | gzip -9 > ../patch-$new.gz\"\n+        echo \"git-rev-list --pretty v$new ^v$last > ../ChangeLog-$new\"\n+        echo \"git-rev-list --pretty=short v$new ^v$last | git-shortlog > ../ShortLog\"\n+        echo \"git-diff-tree -p v$last v$new | git-apply --stat > ../diffstat-$new\"\n+\n+and when I want to do a new kernel release I literally first tag it, and\n+then do\n+\n+        release-script 2.6.12 2.6.13-rc6 2.6.13-rc7\n+\n+and check that things look sane, and then just cut-and-paste the commands.\n+\n+Yeah, it's stupid.\n+\n+                Linus\n+\ndiff --git a/Documentation/howto/rebase-and-edit.txt b/Documentation/howto/rebase-and-edit.txt\nnew file mode 100644\n--- /dev/null\n+++ b/Documentation/howto/rebase-and-edit.txt\n@@ -0,0 +1,78 @@\n+Date:\tSat, 13 Aug 2005 22:16:02 -0700 (PDT)\n+From:\tLinus Torvalds <torvalds@osdl.org>\n+To:\tSteve French <smfrench@austin.rr.com>\n+cc:\tgit@vger.kernel.org\n+Subject: Re: sending changesets from the middle of a git tree\n+\n+On Sat, 13 Aug 2005, Linus Torvalds wrote:\n+\n+> That's correct. Same things apply: you can move a patch over, and create a \n+> new one with a modified comment, but basically the _old_ commit will be \n+> immutable.\n+\n+Let me clarify.\n+\n+You can entirely _drop_ old branches, so commits may be immutable, but\n+nothing forces you to keep them. Of course, when you drop a commit, you'll \n+always end up dropping all the commits that depended on it, and if you \n+actually got somebody else to pull that commit you can't drop it from \n+_their_ repository, but undoing things is not impossible.\n+\n+For example, let's say that you've made a mess of things: you've committed\n+three commits \"old->a->b->c\", and you notice that \"a\" was broken, but you\n+want to save \"b\" and \"c\". What you can do is\n+\n+\t# Create a branch \"broken\" that is the current code\n+\t# for reference\n+\tgit branch broken\n+\n+\t# Reset the main branch to three parents back: this \n+\t# effectively undoes the three top commits\n+\tgit reset HEAD^^^\n+\tgit checkout -f\n+\n+\t# Check the result visually to make sure you know what's\n+\t# going on\n+\tgitk --all\n+\n+\t# Re-apply the two top ones from \"broken\"\n+\t#\n+\t# First \"parent of broken\" (aka b):\n+\tgit-diff-tree -p broken^ | git-apply --index\n+\tgit commit --reedit=broken^\n+\n+\t# Then \"top of broken\" (aka c):\n+\tgit-diff-tree -p broken | git-apply --index\n+\tgit commit --reedit=broken\n+\n+and you've now re-applied (and possibly edited the comments) the two\n+commits b/c, and commit \"a\" is basically gone (it still exists in the\n+\"broken\" branch, of course).\n+\n+Finally, check out the end result again:\n+\n+\t# Look at the new commit history\n+\tgitk --all\n+\n+to see that everything looks sensible.\n+\n+And then, you can just remove the broken branch if you decide you really \n+don't want it:\n+\n+\t# remove 'broken' branch\n+\trm .git/refs/heads/broken\n+\n+\t# Prune old objects if you're really really sure\n+\tgit prune\n+\n+And yeah, I'm sure there are other ways of doing this. And as usual, the \n+above is totally untested, and I just wrote it down in this email, so if \n+I've done something wrong, you'll have to figure it out on your own ;)\n+\n+\t\t\tLinus\n+-\n+To unsubscribe from this list: send the line \"unsubscribe git\" in\n+the body of a message to majordomo@vger.kernel.org\n+More majordomo info at  http://vger.kernel.org/majordomo-info.html\n+\n+\ndiff --git a/Documentation/howto/rebase-from-internal-branch.txt b/Documentation/howto/rebase-from-internal-branch.txt\nnew file mode 100644\n--- /dev/null\n+++ b/Documentation/howto/rebase-from-internal-branch.txt\n@@ -0,0 +1,163 @@\n+From:\tJunio C Hamano <junkio@cox.net>\n+To:\tgit@vger.kernel.org\n+Cc:\tPetr Baudis <pasky@suse.cz>, Linus Torvalds <torvalds@osdl.org>\n+Subject: Re: sending changesets from the middle of a git tree\n+Date:\tSun, 14 Aug 2005 18:37:39 -0700\n+\n+Petr Baudis <pasky@suse.cz> writes:\n+\n+> Dear diary, on Sun, Aug 14, 2005 at 09:57:13AM CEST, I got a letter\n+> where Junio C Hamano <junkio@cox.net> told me that...\n+>> Linus Torvalds <torvalds@osdl.org> writes:\n+>> \n+>> > Junio, maybe you want to talk about how you move patches from your \"pu\" \n+>> > branch to the real branches.\n+>> \n+> Actually, wouldn't this be also precisely for what StGIT is intended to?\n+\n+Exactly my feeling.  I was sort of waiting for Catalin to speak\n+up.  With its basing philosophical ancestry on quilt, this is\n+the kind of task StGIT is designed to do.\n+\n+I just have done a simpler one, this time using only the core\n+GIT tools.\n+\n+I had a handful commits that were ahead of master in pu, and I\n+wanted to add some documentation bypassing my usual habit of\n+placing new things in pu first.  At the beginning, the commit\n+ancestry graph looked like this:\n+\n+                             *\"pu\" head\n+    master --> #1 --> #2 --> #3\n+\n+So I started from master, made a bunch of edits, and committed:\n+\n+    $ git checkout master\n+    $ cd Documentation; ed git.txt git-apply-patch-script.txt ...\n+    $ cd ..; git add Documentation/*.txt\n+    $ git commit -s -v\n+\n+NOTE.  The -v flag to commit is a handy way to make sure that\n+your additions are not introducing bogusly formatted lines.\n+\n+After the commit, the ancestry graph would look like this:\n+\n+                              *\"pu\" head\n+    master^ --> #1 --> #2 --> #3\n+          \\\n+            \\---> master\n+\n+The old master is now master^ (the first parent of the master).\n+The new master commit holds my documentation updates.\n+\n+Now I have to deal with \"pu\" branch.\n+\n+This is the kind of situation I used to have all the time when\n+Linus was the maintainer and I was a contributor, when you look\n+at \"master\" branch being the \"maintainer\" branch, and \"pu\"\n+branch being the \"contributor\" branch.  Your work started at the\n+tip of the \"maintainer\" branch some time ago, you made a lot of\n+progress in the meantime, and now the maintainer branch has some\n+other commits you do not have yet.  And \"git rebase\" was written\n+with the explicit purpose of helping to maintain branches like\n+\"pu\".  You _could_ merge master to pu and keep going, but if you\n+eventually want to cherrypick and merge some but not necessarily\n+all changes back to the master branch, it often makes later\n+operations for _you_ easier if you rebase (i.e. carry forward\n+your changes) \"pu\" rather than merge.  So I ran \"git rebase\":\n+\n+    $ git checkout pu\n+    $ git rebase master pu\n+\n+What this does is to pick all the commits since the current\n+branch (note that I now am on \"pu\" branch) forked from the\n+master branch, and forward port these changes.\n+\n+    master^ --> #1 --> #2 --> #3\n+          \\                                  *\"pu\" head\n+            \\---> master --> #1' --> #2' --> #3'\n+\n+The diff between master^ and #1 is applied to master and\n+committed to create #1' commit with the commit information (log,\n+author and date) taken from commit #1.  On top of that #2' and #3'\n+commits are made similarly out of #2 and #3 commits.\n+\n+Old #3 is not recorded in any of the .git/refs/heads/ file\n+anymore, so after doing this you will have dangling commit if\n+you ran fsck-cache, which is normal.  After testing \"pu\", you\n+can run \"git prune\" to get rid of those original three commits.\n+\n+While I am talking about \"git rebase\", I should talk about how\n+to do cherrypicking using only the core GIT tools.\n+\n+Let's go back to the earlier picture, with different labels.\n+\n+You, as an individual developer, cloned upstream repository and\n+amde a couple of commits on top of it.\n+\n+                              *your \"master\" head\n+   upstream --> #1 --> #2 --> #3\n+\n+You would want changes #2 and #3 incorporated in the upstream,\n+while you feel that #1 may need further improvements.  So you\n+prepare #2 and #3 for e-mail submission.\n+\n+    $ git format-patch master^^ master\n+\n+This creates two files, 0001-XXXX.txt and 0002-XXXX.txt.  Send\n+them out \"To: \" your project maintainer and \"Cc: \" your mailing\n+list.  You could use contributed script git-send-email-script if\n+your host has necessary perl modules for this, but your usual\n+MUA would do as long as it does not corrupt whitespaces in the\n+patch.\n+\n+Then you would wait, and you find out that the upstream picked\n+up your changes, along with other changes.\n+\n+   where                      *your \"master\" head\n+  upstream --> #1 --> #2 --> #3\n+    used   \\ \n+   to be     \\--> #A --> #2' --> #3' --> #B --> #C\n+                                                *upstream head\n+\n+The two commits #2' and #3' in the above picture record the same\n+changes your e-mail submission for #2 and #3 contained, but\n+probably with the new sign-off line added by the upsteam\n+maintainer and definitely with different committer and ancestry\n+information, they are different objects from #2 and #3 commits.\n+\n+You fetch from upstream, but not merge.\n+\n+    $ git fetch upstream\n+\n+This leaves the updated upstream head in .git/FETCH_HEAD but\n+does not touch your .git/HEAD nor .git/refs/heads/master.  \n+You run \"git rebase\" now.\n+\n+    $ git rebase FETCH_HEAD master\n+\n+Earlier, I said that rebase applies all the commits from your\n+branch on top of the upstream head.  Well, I lied.  \"git rebase\"\n+is a bit smarter than that and notices that #2 and #3 need not\n+be applied, so it only applies #1.  The commit ancestry graph\n+becomes something like this:\n+\n+   where                     *your old \"master\" head\n+  upstream --> #1 --> #2 --> #3\n+    used   \\                      your new \"master\" head*\n+   to be     \\--> #A --> #2' --> #3' --> #B --> #C --> #1'\n+                                                *upstream\n+                                                head\n+\n+Again, \"git prune\" would discard the disused commits #1-#3 and\n+you continue on starting from the new \"master\" head, which is\n+the #1' commit.\n+\n+-jc\n+\n+-\n+To unsubscribe from this list: send the line \"unsubscribe git\" in\n+the body of a message to majordomo@vger.kernel.org\n+More majordomo info at  http://vger.kernel.org/majordomo-info.html\n+\n+\n"}]}