Documentation / howto / rebase-from-internal-branch.txton commit [PATCH] Allow "+remote:local" refspec to cause --force when fetching. (efe9bf0)
   1From:   Junio C Hamano <junkio@cox.net>
   2To:     git@vger.kernel.org
   3Cc:     Petr Baudis <pasky@suse.cz>, Linus Torvalds <torvalds@osdl.org>
   4Subject: Re: sending changesets from the middle of a git tree
   5Date:   Sun, 14 Aug 2005 18:37:39 -0700
   6
   7Petr Baudis <pasky@suse.cz> writes:
   8
   9> Dear diary, on Sun, Aug 14, 2005 at 09:57:13AM CEST, I got a letter
  10> where Junio C Hamano <junkio@cox.net> told me that...
  11>> Linus Torvalds <torvalds@osdl.org> writes:
  12>> 
  13>> > Junio, maybe you want to talk about how you move patches from your "pu" 
  14>> > branch to the real branches.
  15>> 
  16> Actually, wouldn't this be also precisely for what StGIT is intended to?
  17
  18Exactly my feeling.  I was sort of waiting for Catalin to speak
  19up.  With its basing philosophical ancestry on quilt, this is
  20the kind of task StGIT is designed to do.
  21
  22I just have done a simpler one, this time using only the core
  23GIT tools.
  24
  25I had a handful commits that were ahead of master in pu, and I
  26wanted to add some documentation bypassing my usual habit of
  27placing new things in pu first.  At the beginning, the commit
  28ancestry graph looked like this:
  29
  30                             *"pu" head
  31    master --> #1 --> #2 --> #3
  32
  33So I started from master, made a bunch of edits, and committed:
  34
  35    $ git checkout master
  36    $ cd Documentation; ed git.txt git-apply-patch-script.txt ...
  37    $ cd ..; git add Documentation/*.txt
  38    $ git commit -s -v
  39
  40NOTE.  The -v flag to commit is a handy way to make sure that
  41your additions are not introducing bogusly formatted lines.
  42
  43After the commit, the ancestry graph would look like this:
  44
  45                              *"pu" head
  46    master^ --> #1 --> #2 --> #3
  47          \
  48            \---> master
  49
  50The old master is now master^ (the first parent of the master).
  51The new master commit holds my documentation updates.
  52
  53Now I have to deal with "pu" branch.
  54
  55This is the kind of situation I used to have all the time when
  56Linus was the maintainer and I was a contributor, when you look
  57at "master" branch being the "maintainer" branch, and "pu"
  58branch being the "contributor" branch.  Your work started at the
  59tip of the "maintainer" branch some time ago, you made a lot of
  60progress in the meantime, and now the maintainer branch has some
  61other commits you do not have yet.  And "git rebase" was written
  62with the explicit purpose of helping to maintain branches like
  63"pu".  You _could_ merge master to pu and keep going, but if you
  64eventually want to cherrypick and merge some but not necessarily
  65all changes back to the master branch, it often makes later
  66operations for _you_ easier if you rebase (i.e. carry forward
  67your changes) "pu" rather than merge.  So I ran "git rebase":
  68
  69    $ git checkout pu
  70    $ git rebase master pu
  71
  72What this does is to pick all the commits since the current
  73branch (note that I now am on "pu" branch) forked from the
  74master branch, and forward port these changes.
  75
  76    master^ --> #1 --> #2 --> #3
  77          \                                  *"pu" head
  78            \---> master --> #1' --> #2' --> #3'
  79
  80The diff between master^ and #1 is applied to master and
  81committed to create #1' commit with the commit information (log,
  82author and date) taken from commit #1.  On top of that #2' and #3'
  83commits are made similarly out of #2 and #3 commits.
  84
  85Old #3 is not recorded in any of the .git/refs/heads/ file
  86anymore, so after doing this you will have dangling commit if
  87you ran fsck-cache, which is normal.  After testing "pu", you
  88can run "git prune" to get rid of those original three commits.
  89
  90While I am talking about "git rebase", I should talk about how
  91to do cherrypicking using only the core GIT tools.
  92
  93Let's go back to the earlier picture, with different labels.
  94
  95You, as an individual developer, cloned upstream repository and
  96amde a couple of commits on top of it.
  97
  98                              *your "master" head
  99   upstream --> #1 --> #2 --> #3
 100
 101You would want changes #2 and #3 incorporated in the upstream,
 102while you feel that #1 may need further improvements.  So you
 103prepare #2 and #3 for e-mail submission.
 104
 105    $ git format-patch master^^ master
 106
 107This creates two files, 0001-XXXX.txt and 0002-XXXX.txt.  Send
 108them out "To: " your project maintainer and "Cc: " your mailing
 109list.  You could use contributed script git-send-email-script if
 110your host has necessary perl modules for this, but your usual
 111MUA would do as long as it does not corrupt whitespaces in the
 112patch.
 113
 114Then you would wait, and you find out that the upstream picked
 115up your changes, along with other changes.
 116
 117   where                      *your "master" head
 118  upstream --> #1 --> #2 --> #3
 119    used   \ 
 120   to be     \--> #A --> #2' --> #3' --> #B --> #C
 121                                                *upstream head
 122
 123The two commits #2' and #3' in the above picture record the same
 124changes your e-mail submission for #2 and #3 contained, but
 125probably with the new sign-off line added by the upsteam
 126maintainer and definitely with different committer and ancestry
 127information, they are different objects from #2 and #3 commits.
 128
 129You fetch from upstream, but not merge.
 130
 131    $ git fetch upstream
 132
 133This leaves the updated upstream head in .git/FETCH_HEAD but
 134does not touch your .git/HEAD nor .git/refs/heads/master.  
 135You run "git rebase" now.
 136
 137    $ git rebase FETCH_HEAD master
 138
 139Earlier, I said that rebase applies all the commits from your
 140branch on top of the upstream head.  Well, I lied.  "git rebase"
 141is a bit smarter than that and notices that #2 and #3 need not
 142be applied, so it only applies #1.  The commit ancestry graph
 143becomes something like this:
 144
 145   where                     *your old "master" head
 146  upstream --> #1 --> #2 --> #3
 147    used   \                      your new "master" head*
 148   to be     \--> #A --> #2' --> #3' --> #B --> #C --> #1'
 149                                                *upstream
 150                                                head
 151
 152Again, "git prune" would discard the disused commits #1-#3 and
 153you continue on starting from the new "master" head, which is
 154the #1' commit.
 155
 156-jc
 157
 158-
 159To unsubscribe from this list: send the line "unsubscribe git" in
 160the body of a message to majordomo@vger.kernel.org
 161More majordomo info at  http://vger.kernel.org/majordomo-info.html
 162
 163