On Sun, 25 Nov 2007, J. Bruce Fields wrote: > There's a very brief mention of this: > > "As with git-fetch, git-push will complain if this does not > result in a <<fast-forwards,fast forward>>. Normally this is a > sign of something wrong. However, if you are sure you know what > you're doing, you may force git-push to perform the update > anyway by preceding the branch name by a plus sign: ... or use "git push -f" (is it mentioned in the manual?) > But it'd probably be better to have a separate section. That makes it > possible to say a little more, and also gets a section called "what to > do when a push fails" into the table of contents. > > (Though that's a little vague--push can also fail just because you > mispell the url or something. A more precise reference to the > particular error might be better, but we'll have to agree on the error > message first....) > > Anyway, here's a first draft. I think we should devote a section of the manual to the "rebase" workflow compared to the "merge" workflow. One of the public Git repo I currently maintain is constantly rebased, and I've provided a quick Git update cheat sheet along with its announcement for that case: http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2007-November/043147.html I also wrote an introductory document for $job internal use. I have a section where I briefly cover the main differences and implications for merge vs rebase. Here it is -- please feel free to add it to the manual if you think it can be valuable. ----- >8 Rebase vs Merge --------------- Merge and rebase may look like they are doing the same thing, but they act very differently on the repository. Merging basically takes all the changes in the remote branch and mix them with your local branch. For example, if you create a branch "mywork" from the orion/core branch, you will end up with something that looks like this: a--b--c <-- orion/master \ A--B--C <-- mywork After a fetch, the remote branch might have advanced in parallel to local changes as follows: a--b--c--d--e--f <-- orion/master \ A--B--C <-- mywork If you later do a 'git merge orion/master', your history will look like this, where 'M' is a merge commit: a--b--c--d--e--f <-- orion/master \ \ A--B--C--M <-- mywork A rebase, on the other hand, takes all your changes and reapplies them to the current state of the specified branch, and assign the result to the currently checked out branch. With the same example, if you were to do a 'git rebase orion/master', you would get something like this: a--b--c--d--e--f <-- orion/master \ A'--B'--C' <-- mywork Rebase does what the name implies and creates a new baseline for your branch. The benefit of this is that you end up with a cleaner history log, especially if you have to update with the remote branch often, in both your repository and in upstream repositories that gets updated from you. Tracking a rebased remote branch -------------------------------- Let's suppose that the remote branch you're tracking is itself subject to be rebased. Before performing a fetch to update that remote branch, your history might look like the previous example: a--b--c--d--e--f <-- orion/master \ A'--B'--C' <-- mywork If the remote branch had some commit replaced, or was rebased on a different commit (or both), then things could look like this after a fetch: a---b---c'--d'--e'--f'--g <-- orion/master \ c---d---e---f <-- orion/master@{1} \ A---B---C <-- mywork In this example, commits c, d, e and f are not present anymore in the remote repository. They are still reachable from your "mywork" local branch though. The "orion/master@{1}" is the notation used to refer to the previous value (before the fetch) of "orion/master". If you were to use 'git merge' to bring the new commits (c', d', e', f' and g) into your local branch, that wouldn't get rid of the commits that they are meant to replace, and is likely to cause a major merge conflict. The only option in that case is to rebase your work. Yet there is a twist because 'rebase' moves every commit reachable from the current branch on top of the specified branch by default, including those c-d-e-f commits. So the --onto argument to 'git rebase' must be used to skip over those unwanted commits as follows: git rebase --onto orion/master orion/master@{1} mywork This means to rebase commits between orion/master@{1} and mywork on top of orion/master and assing mywork to the result. The git-rebase man page provides more examples and a detailed explanation of how 'rebase' works which is worth a read. NOte: the orion Git repository is indeed rebased often. So you'll have to use this rebase invokation when fetching updates from it. - 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