Hi, It's been a long time since I read the user manual, so I'm only comment to point out a few shortcuts (whether or not they're more logical to present to new users) and clarifications on the usecases you presented. On Mon, Jul 6, 2009 at 5:05 PM, Bruno Haible<bruno@xxxxxxxxx> wrote: > 1) After the section "Rewriting a single commit", it may be useful to > have a section "Inserting one or more new commits". This is something that > cannot be done with the "detached head" technique. I found this sequence > of commands useful: > > If you want to add a commit in the middle of a branch: > > A---C---...---Z master > > => > > A---B---C---...---Z master > > it is achieved by > > $ git checkout A > $ git branch temp > $ git checkout temp > [make changes for B] > $ git commit -a > > now: > > A---C---...---Z master > \ > --B temp > > $ git checkout master > $ git rebase temp > $ git branch -d temp Or compress those 8 steps down to 4 using a detached HEAD and multi-argument rebase: $ git checkout A [make changes for B] $ git commit -a $ git rebase HEAD master The last command above means "rebase master against HEAD". I think the rebase command would be much easier to understand for new users if it used an "--against" before the first reference(*). For example, "git rebase --against temp" for rebasing the current branch against temp (instead of "git rebase temp") or "git rebase --against HEAD master" (rather than "git rebase HEAD master"); the real git rebase commands don't parse so well for new users and take a long time to wrap ones' head around, whereas this simple change seems to make it much easier. (*) Except when --onto is specified. Then --since may make more sense than --against. Also, I'm not yet suggesting we make this change (since I have no patch handy), but note that if anyone wants to try this then the "--against" should be optional for backwards compatibility. It's mostly a documentation change. <snip case 2> > 3) When do I need "git merge", and when do I need "git rebase", in the > context of branch surgery? > > The simple answer, that I would find worth mentioning, is: > - "git merge" copies commits from one branch to another. git merge does not copy commits at all; unlike cvs/svn, a commit may (and often is) part of more than one branch in git. A merge simply creates a new commit which has more than one parent: the previous tip of the current branch, and the tip of the other branch you are merging. > - "git rebase" only moves commits around to make history more linear. git rebase actually doesn't move around commits; the old commits still exist with no modifications (which is useful for undoing rebases if you later decide you don't like them). Instead, git rebase just re-applies commits, effectively making an extra "copy" of each commit (I put "copy" in quotes because the "copied" commits will have different parents, different commit times, and potentially different contents especially when conflict resolution is necessary, so they're not quite copies). > 4) It would be good to have a section "Cutting branches" > > How do I remove the N most recent commits from a branch? > > D---E---F---G---H---.........---Y---Z master > > => > D---E master > > It goes like this: > > $ git checkout master > $ git reset --hard E If master is the active branch, you only need the latter command. If master is not the active branch, then you can achieve the same with much less cost by $ git branch -f master E > 5) Then, it would be good to have a section "Replacing branches" > > How do I copy the contents of a branch over to another branch, replacing > the recent development on that branch? > > If you want to copy a branch into another, while throwing away commits: > > F1---F2---F3 released > / > D---E---F---G---H---.........---Y---Z master > > => > F1---F2---F3 released > / > D---E---F1---F2---F3 master > > This is achieved by > > $ git checkout master > $ git reset --hard E # Cut the branch "master" > $ git merge released # Copy commits from branch "released" to "master" I'm assuming master isn't checked out. If so, the following is faster: $ git branch -f master E (If master is checked out, just 'git reset ---hard released') > 6) Also, it would be good to have a section "Reconnecting branches after rebase". > If you want to reconnect a branch to a rebased master, here's how to do it: > > /--C'--...---P'--Q'--...---Z' new rebased master > A---B---C---...---P---Q---...---Z old master > \ > --BA---...---BZ release-branch > > => > A---B---C'--...---P'--Q'--...---Z' new rebased master > \ > --BA---...---BZ release-branch > > This is achieved by > > $ git checkout release-branch > $ git rebase --onto P' P or, $ git rebase --onto P' P release-branch > This might seem exotic, but these use cases all came up while rewriting the > history after a "git cvsimport". They may seem exotic at first to cvs/svn refugees, but it isn't very long before lots of users end up doing these kinds of things routinely. Amusing story: I spent several months at $dayjob attempting to convince our group to switch from cvs to git instead of from cvs to svn. I often mentioned cool features like pulling directly from other developers, but was often ignored and laughed off for mentioning exotic cases that nearly no one would care about. And our surveys showed that most developers didn't care about anything other than "checkout, update, and commit". I succeeded in the end anyway, and we found out that developers only cared about simple stuff because cvs made anything else painful. The very first week after switching to git, we had multiple requests from people about how to pull changes directly from other developers (including from people that previously only cared about "checkout, update, and commit"). When the cost of certain activities changes dramatically (which git does by making lots new things possible and fast), formerly "exotic" usecases can become natural and common -- and really helpful. Anyway, I hope some of my ramblings are useful to you. Elijah -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html