Thanks for the email... always good to see what others are doing!
What I'm advocating is _never_ using "git pull" and never having "merge
commits". If no one ever uses straight "git pull" things are much better
(even for public branches, but that can still give you issues). Instead,
everyone will always rebase their patches on top of a fetched branch (even
patches from pull requests can be rebased in this way). Further, when you
work this way you always end up with a linear history in master. Finally,
there will never be any merge commits.
BTW - I'm not advocating using rebase for the true libMesh master (or any
true release branches)... that should never be done. We don't want to
change the history of master. Just the opposite in fact: everyone should
always rebase their patches on master before pushing to it...
We've been working this way for almost two years.... and it works great!
In our case we have to work this way because our "master" is an SVN
server... so we always have to respect the history of master and rebase all
new patches on it. git-svn enforces this by making you update with a
command called "git svn rebase".... which does essentially a "git fetch"
followed by "git rebase svn/master". This always ensures that the history
in SVN (ie master) is respected... and there are never any merge commits
and your new patches float happily to the top of the patch stack.
In my personal opinion I think that "git pull" is the worst thing about
git. It makes people feel "comfy" by making them think they should
continue to work like they did with SVN (merge commits are essentially the
manual "merge" part of "svn update").
However, in Git there is a much better way.... because patches are
individualized it is simple to put them on top of other's patches with
rebase. Another benefit of rebase is that the individual new patches are
modified when conflicts arise... keeping the integrity of each patch
in-tact... instead of one big blob of a "merge commit" that might be a mess
of many different changes that all happened to conflict. Finally, in my
opinion (IMNSHO ;-) not having merge commits and keeping a linear history
in master helps a lot with git bisection and any other sort of history
Rebase is unbelievably powerful... and a much better way of working than
the brute force of "git pull" and merge commits.
If you work this way you don't need to ask other people who provide pull
requests to rebase their branch. You can do that using the workflow I sent
in my last email without interacting with them at all. Now, if there are a
lot of conflicts (like from an old pull request) you might still want to
ask them to rebase so you don't have to deal with the conflicts yourself ;-)
About cherry-pick: I was advocating it's use instead of having a "hot fix"
branch. Anything that is a "hot fix" should already be isolated in a small
patch on a branch somewhere. If it's not a small patch... it's not a "hot
fix" and should warrant a new release by merging a branch to master (after
making sure to rebase on master first of course! ;-)
One last anecdote: You can force "git fetch && git rebase" to be the
behavior of "git pull" by using "git pull --rebase" (there are some small
nuances that mean that these two operations are not exactly equal, but most
of the time they are). Some large software projects in the DOE _force_ you
to use "git pull --rebase" for all the same reasons I've specified here,
but mainly because of the cleaner history in master. You can set it to be
the default by using
git config branch.autosetuprebase always
I know of several projects that have everyone work this way.
One of the greatest things about Git is that there are so many ways to
setup your project's work flow. Every project can decide for themselves
what will work best for that project. It's freedom we never had with the
old systems. It's awesome to see all the different way of working with
On Thu, Jan 3, 2013 at 3:22 PM, Damon McDougall <damon@...:
> That page you linked is the workflow I use for my personal projects.
> Derek, your comment that '--no-ff' squashes commits is not true. There
> are several 'merge strategies' git has built in. When you merge,
> rebase or pull, git tries to figure out the simplest way to merge
> branches without causing merge conflicts. The one you will see most
> often is when you 'git pull' to update a local branch to reflect new
> changes implemented upstream. Usually the changes upstream are commits
> whose timestamp occurs in reverse chronological order. Thus, in order
> to update the the local branch, git can do something called a
> fast-forward merge which says "update me to the latest version". Since
> one doesn't really touch their local master branch, fast-forwards are
> used. If you had fiddled with your local master branch rather than
> branching off to patch something, git will create a merge commit.
> Now, fast-forwards will not only occur when you 'git pull' but can
> occur when you 'git merge' a branch whose commits can be cleanly
> played on top of your out-dated development branch, say. When git
> fast-forwards to merge a branch, no merge commit is made (otherwise
> when you git pull you would create pointless merge commits locally). I
> merge topic branches into my dev branch with the --no-ff option so I
> can see what history was merged. It's not necessary, but in my opinion
> a merge commit there is useful for my records.
> The --no-ff option does not 'squash' commits. It creates a merge
> commit, just like all the other merge strategies do.
> If you rebase a public branch everyone will hate you. Here's why:
> Note, problems only occur when *others* are watching one of your
> branches. For example, when I'm reviewing a pull request for
> matplotlib, I often tell my contributors to rebase their branch
> against the current upstream/master branch. Why? I do this because
> then I don't have to fetch the branches and merge them locally myself.
> I just push the big green 'merge' button on github and, since it was
> rebased, there are no merge conflicts and github is happy. Github will
> not let you merge a branch if it will result in a conflict. For the
> most part, it is only matplotlib developers that fetch branches to try
> them out. Therefore if I, as a developer, tell someone to rebase a
> branch I have fetched, then presumably I know that branch is bad and I
> can re-fetch it cleanly once the rebase has happened. Also, if I ask
> someone to rebase a branch, I do it in a comment on the pull request
> page and there is a paper trail the other developers can take note of
> and exercise caution that the branch is likely to be rebased.
> Furthermore, note that most matplotlib pull request branches only have
> one committer: the person that submitted the pull request. I do not
> recommend rebasing branches that are heavily shared. If I rebased
> matplotlib's upstream/master branch *everybody* that follows the
> source, pull request or not, would get nastiness occurring locally and
> I would probably get heavily scorned.
> One last note: be careful with cherry-picking. I only cherry-pick
> small changes. And when I do, it's usually because the person that
> submitted a pull request didn't branch from the correct place. For
> matplotlib, bug fix branches should branch from the maintenance
> branch. They are then merged into the maintenance branch when they are
> complete. The maintenance branch is quasi-periodically merged into
> master to snarf all the bug fixes. When someone makes a very simple
> bug fix but branched from master instead of the maintenance branch, I
> can't 'git merge' their changes into the maintenance branch without
> including (possibly) API changes into the maintenance branch. This is
> where cherry-picking a bug-fix comes in handy. In short, you should
> never really have to do it if you stick to a consistent workflow.
> Matplotlib doesn't follow the workflow Roy linked to. All development
> is done on master and when we're about to release we 'git branch
> v1.2.x master' and unstable work can still be merged into master while
> preserving the stable 1.2 release branch. This is a simpler workflow
> than the one Roy linked to; there are less branches to deal with.
> If it's any consolation I have a ton of local matplotlib branches.
> Some are mine. Some are others' pull requests I forgot about and some
> are hacks that will take me months to develop.
> Note that this is just advice from my experience in working with git.
> It is not gospel and I do not claim to know what I am doing in the
> slightest. For example, I have to google how to resolve merge
> conflicts every time I get one, because I can never remember whether I
> need to 'git add' or not after I'm done.
> Also, you will mess up. I think one has to make a catastrophic mistake
> before learning what and/or what not to do. If you're unsure about
> something, try it on a separate branch and whatever you do, don't push
> upstream unless you are completely sure the changes you have made are
> safe. I messed up my local matplotlib master branch once, and I can
> tell you I will never do that again, I'm just glad I didn't push. At
> least now I know how to fix it if it happens again, which I'm sure
> This email is pretty long and opinionated. Feel free to ignore any or all
> of it.
> Best wishes,
> Damon McDougall
> Institute for Computational Engineering Sciences
> 201 E. 24th St.
> Stop C0200
> The University of Texas at Austin
> Austin, TX 78712-1229
> Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
> with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
> MVPs and experts. ON SALE this month only -- learn more at:
> Libmesh-devel mailing list