Showing posts with label git. Show all posts
Showing posts with label git. Show all posts

Jul 5, 2011

Experience with having a non Dist::Zilla user contribute to a Dist::Zilla project (it's not hard for them or me)

I've heard many times that Dist::Zilla makes it harder for people to contribute to the project. This is not true, it is either unfortunately either ignorance or FUD (much like saying Linux is harder to use than Windows). Truly, there are things that some dzil users do that can make it harder, but it doesn't have to be that way. Michael Schwern recently contributed to one of my dzil projects without ever realizing I was using dzil, until I told him. He more recently stated on twitter, "While your solution works, it seems like it makes more work for you to shield contributors from dzil". This was true in this case because I wasn't sure how to effectively move a series of multiple patches, I now know it's easy to do with git. Here's how you can allow contributors to contribute to your dzil project without causing you or them undo pain.

  1. Don't use anything that changes the line numbers of your source
    Examples: don't use DZP::Prepender. Use modules like OurPkgVersion to insert VERSION, and make sure your # ABSTRACT and any pod is below the 1; at the end of your module. This will keep the line numbers of errors in your code from being different from the final build. It's still ok to use PodWeaver as it will save you way more time than it'll hurt, so long as you follow the rules about pod being at the bottom


  2. Use a plugin that commits builds to your source control software
    I personally recommend DZP::Git::CommitBuild






  3. Make your build branch your default branch
    I'm not sure how to do this with just git, but on github you can go to the admin section of your repository and change the default branch there. This makes it so that when someone clone's your repository the initial checkout is of your build branch. Your build branch shouldn't require dzil, it's the final build.







Now that you have your final build branch as the default branch anyone who wants to contribute can simply clone your repo and start hacking. Their are a couple of mistakes they could make, They could either change or add files that are maintained, or pruned by dzil. This did happen when Schwern sent me patches, one of them was the addition of a .gitignore, which I already had, but is being pruned out of the build branch. I can also see it happening to meta's and makefiles. These patches can simply be rejected as unnecessary, dzil-ified, or if they are truly a bug, then they can be reported and fixed upstream.

So what if someone sends you a pull request from build/master? well if it's just one or two patches, you add their remote, and do a git remote update and then you can git log remote build/master to find the sha1 of this patch. Now that you have the sha1 all you have to do is git cherry-pick [sha1] and it should apply. If there are any conflicts you may have to resolve them with git mergetool. However, the only conflict with Schwern's patches for me was the .gitignore, all other patches applied without assistance and applied correcly, surprisingly even the pod patch applied without issue.

If you have more patches than is comfortable with git cherry-pick then you need git rebase. The command you want is git rebase -i --onto master [sha1 before first sha1 in series] [tip of remote branch checkout]. So in my case git rebase -i --onto master 3f1e3748 schwern. What this appears to do is ends up rewriting my local schwern/build/master checkout and removes all the build commits, and then applies the patches on top. This means I can now do git merge schwern from the master branch, and all of his patches that I want will be successfully merged. For more on this strategy you may want to read this stackoverflow question.

given this is not quite as easy as a git pull that's a fast forward, but reality is it's not that hard once you know how to do the rebase and how it works. Of course this isn't ideal for constant contributors, those should simply learn to use dzil, but for the random contributor it should be ok.

Jun 5, 2011

My solution to not using PluginBundle:AUTHOR for dzil is git

I am now tired of updating my dist.ini's for my Dist::Zilla projects. For many people this is when they start using a PluginBundle with their authorname. I discussed why you shouldn't do this a year ago. Now that I'm tired of managing my dist.ini's on an individual basis I'm going to show you how I'm going to solve the same problem everyone else is, which is getting tired of updating your dzil configuration for all of your projects. I'm using git to do it. You probably haven't considered this, or am thinking I'm wrong because you believe that git can't merge branches without a common history, which is not true. I did it with Regen2, Funtoo, Portage, and Sunrise, which have way more files than any perl repo, including Perl.


First let's talk about the advantages and disadvantages of doing this with git.

I'll start with the disadvantages. You'll have another repository to manage. Git isn't completely automatic, you'll have to remember to merge your changes. You'll also have to add the repository to your existing repositories. You will have to resolve merge conflicts at least once, and probably occasionally more, though most should be fast-forwards.

The advantages are... now the changes to your dist.ini are getting recorded in your history. You can now have a master dist.ini, but remove items without filters in your individual modules. You can share even more configuration as merged differences allow you to maintain differences in downstream commits. It doesn't automatically update all of your modules. Wait didn't I list that last one in disadvantages? Yep, it's an advantage because what if you update your PluginBundle and that update breaks one of your modules, but you don't know it because you haven't worked on that module in a while. You can use this for more than just dist.ini.

Ok so the first thing you you want to do is create your master dzil repo. This is not a git or dzil tutorial so go do that. I did it by creating a dzil new project and removing the files I couldn't use and making a few tweaks and amending all of those changes to the initial commit. Check out my repo for inspiration. Remember the directory structure has to be the same as a dzil repo structure for any common files.

Now add a remote from your new repo to an existing dzil project. Next you need to merge the branch from the remote into your project. The first time you do this you'll have to resolve conflicts. If they're like mine then they'll be easy and obvious. Once that's done future changes will be fast-forwards unless you change something in your perl module repo, then you might end up with a simple merge conflict. One thing to remember NEVER EVER try to merge from your module repo to your dzil repo, it will cause you extreme pain in the future. cherry-picking that direction is possible but not merging.

After that, all that is left to do is run your dzil tests and fix any breakage in your module. Happy merging.

Jul 2, 2010

git workflows

If you use git and you're past the tutorial and using it for an actual project, I suggest you take a look at the workflows manpage as well. It will give you ideas on how to branch, merge, rebase and cherry-pick.

This has been a public service announcement, that is all.

Jun 17, 2010

RT git workflow

git was designed to be very flexible in its workflow. One of the things it was designed to do was handle email patches, since there are a lot of patches sent to and from the mailing list. This is a good thing, even if you don't have a mailing list, or you have your own bug tracker (in addition to RT), you can use RT to receive email patches from git. First you have to configure your MUA (mail client)(and go write a patch), some suggestions are given in git.git's SubmittingPatches document. If you like the CLI I suggest you use the git send-email command. I'm going to walk you through using it, but you'll have to learn how to set it up for your smtp server on your own (one hint: if you don't provide an smtp pass as an argument or as a config option you will be prompted for it).

now you have a patch that you haven't pushed yet. you can run one of the following sets of steps to get going.
git format-patch -M HEAD~1 # commitish. commit before the number of patches you want to generate
vi 0001-patch-name # and add some description between the --- and the diff stat
git send-email 0001-patch-name # can replace this step with MUA of choice

git format-patch -M HEAD~5 # generate a patchset of the last 5 patches
git send-email --annotate *patch # will open the core.editor you set in gitconfig to edit the patch

git send-email --annotate --format-patch -M --to=destination-email origin/master
# generate all the patches that aren't committed against origin/master branch in your local branch


for the time being you should probably just send it to one of your own projects on cpan so you can see. If you look at the web interface for the bug you'll notice it's clobbered your formatting, same goes with the email RT sends you... so this is useless right? well... certainly doesn't help... now look at the 'with headers' version. Their are lots of headers here, but all your content is intact. Now download this file (right click save as should do it).

you may now ( you may have to run git reset --hard HEAD^ first to undo you last commit).
git apply downloaded-file.txt

which will only apply the diff no commit log or anything (reset without HEAD^ now).

or you can git am -i downloaded-file.txt -i is interactive and will allow you to choose whole folders full of mail patches and which to apply.

I think this is a good workflow for 1 off patches. obviously you don't send them to yourself, I'm just trying to show you what it's like to send and receive.

Mar 24, 2010

my git remote

So occasionally I like to fork a project on GitHub well the proper way to do it is to use GitHub's fork button which then clone's the repo into your account. this is great! I can than clone that locally develop it an push to it. Usually I do this push with git push origin. I can then ask the owner of the original repo that I forked from to 'pull' my changes in. Wait did I just say original? why am I calling my repo on github origin? it's probably not the origin repo... it's not the primary project repo... so I decided I needed a new convention. I now do git remote add my uri://... for my repo's on github and git remote add origin uri:// for the projects authoritative repo. This also helps when I need to update my repo from the origin and then push them to my public forks.

May 11, 2009

Git Presentation

I'm doing a git presentation and the Lansing Coldfusion User Group tomorrow night. Anyone who wants to is welcome to come Below are the slides for the presentation.



EDIT: I don't know why but google doesn't show all slides formatted right in mini mode. It's cut off some of the text and overlapped some things.