Re: What's cooking in git.git (topics)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux