This is a copy of an article I published at http://fanf.livejournal.com/128282.html I'm sending a copy here because I'm interested to know what other ways there might be of handling this situation. -- We often need to patch the software that we run in order to fix bugs quickly rather than wait for an official release, or to add functionality that we need. In many cases we have to maintain a locally-developed patch for a significant length of time, across multiple upstream releases, either because it is not yet ready for incorporation into a stable upstream version, or because it is too specific to our setup so will not be suitable for passing upstream without significant extra work. I have been experimenting with a git workflow in which I have a feature branch per patch. (Usually there is only one patch for each change we make.) To move them on to a new feature release, I tag the feature branch heads (to preserve history), rebase them onto the new release version, and octopus merge them to create a new deployment version. This is rather unsatisfactory, because there is a lot of tedious per-branch work, and I would prefer to have branches recording the development of our patches rather than a series of tags. Here is a git workflow suggested by Ian Jackson which I am trying out instead. I don't yet have much experience with it; I am writing it down now as a form of documentation. There are three branches: upstream, which is where public releases live working, which is where development happens deployment, which is what we run Which branch corresponds to upstream may change over time, for instance when we move from one stable version to the next one. The working branch exists on the developer's workstation and is not normally published. There might be multiple working branches for work-in-progress. They get rebased a lot. Starting from an upstream version, a working branch will have a number of mature patches. The developer works on top of these in commit-early-commit-often mode, without worrying about order of changes or cleanliness. Every so often we use git rebase --interactive to tidy up the patch set. Often we'll use the "squash" command to combine new commits with the mature patches that they amend. Sometimes it will be rebased onto a new upstream version. When the working branch is ready, we use the commands below to update the deployment branch. The aim is to make it look like updates from the working branch are repeatedly merged into the deployment branch. This is so that we can push updated versions of the patch set to a server without having to use --force, and pulling updates into a checked out version is just a fast-forward. However this isn't a normal merge since the tree at the head of deployment always matches the most recent good version of working. (This is similar to what stg publish does.) Diagramatically, | 1.1 | \ | `A---B-- 1.1-patched | \ | | \ | | `C-- 1.1-revised | | 2.0 | | \ | | `-C--D-- 2.0-patched | | 3.1 | | \ | | `-C--E-- 3.1-patched | | upstream | deployment The horizontal-ish lines are different rebased versions of the patch set. Letters represent patches and numbers represent version tags. The tags on the deployment branch are for the install scripts so I probably won't need one on every update. Ideally we would be able to do this with the following commands: $ git checkout deployment $ git merge -s theirs working However there is an "ours" merge strategy but not a "theirs" merge strategy. Johannes Sixt described how to simulate git merge -s theirs in a post to the git mailing list in 2010. http://article.gmane.org/gmane.comp.version-control.git/163631 So the commands are: $ git checkout deployment $ git merge --no-commit -s ours working $ git read-tree -m -u working $ git commit -m "Update to $(git describe working)" Mark Wooding suggested the following more plumbing-based version, which unlike the above does not involve switching to the deployment branch. $ d=$(git rev-parse deployment) $ w=$(git rev-parse working) $ c=$(echo "Update to $(git describe working)" | git commit-tree -p $d -p $w working^{tree}) $ git update-ref deployment $c $d $ unset c d w Tony. -- f.anthony.n.finch <dot@xxxxxxxx> http://dotat.at/ Forties, Cromarty: East, veering southeast, 4 or 5, occasionally 6 at first. Rough, becoming slight or moderate. Showers, rain at first. Moderate or good, occasionally poor at first. -- 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