On Sun, Nov 25, 2007 at 11:02:05PM -0500, Nicolas Pitre wrote: > 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. There's this: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#using-git-rebase It doesn't explicitly compare the two, but I think between that and the containing chapter, it hits on the main issues. > 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 The trick of tag -d old_base remote/master git fetch remote git rebase --onto remote/master old_base my_work is something we don't document anywhere. (We might not have to quite so much if we came up with a command that did the job of git-rebase and/or cherry-pick with more intuitive syntax....) > 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. Thanks. I think the manual covers most of what's in the "rebase vs merge" section already. (Though it'd be worth reconsidering how we do it.) The "tracking a rebased remote branch" stuff would be new and, I think, helpful. I'll take a closer look at it eventually--but if someone wants to speed the process by working out exactly where to fit this in, which parts are duplicated, etc., and turn the result into a patch, I'd be happy. I do find that trying to work on top of a constantly rebased branch is annoying no matter how I do it. So I sometimes wonder if we shouldn't instead be finding ways to avoid the practice. --b. > > ----- >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