Step-by-step guide of Mercurial for iPhone projects? - iphone

I am looking for a step-by-step Mercurial guide for iPhone projects. Please assume:
hg already installed
the audience is comfortable with command line operations
everything is on OS X
As a newbie, I am particular interested in:
what files should be excluded
how to exclude above files
guideline/suggestion of naming builds
any relevant experience to share with
Please do not discuss how hg is better/worse than any other SCS. This is a how-to question, not a why question.
Thanks!

A more general exclusion tip that applies to all source-control systems is that it's really useful to set up Xcode to use a shared build directory somewhere away from the source code. I prefer to use /Users/Shared/builds/ but it could go anywhere. The nice thing is that you don't need to bother excluding build products from hg, and it makes it convenient to exclude them from backups as well.
You can set this up in Xcode's preferences, under "building".

Files you should exclude are: .DS_Store build *.mode1v3 *.pbxuser. You can also always ignore stuff from other SCSs like .git and .svn. I also ignore .LSOverride which is in some of my projects since I have multiple installs of the developer tools (for SDK betas) and sometimes want to override the standard launch service behavior.
These files can be ignored by listing them in a .hgignore file in the root of the working directory. The .hgignore file must be created manually. It is typically put under version control, so that the settings will propagate to other repositories with push and pull [1].

Related

As a dev, do you use .gitignore to ignore everything and purposefully include? Or do you just exclude with it?

We have an internal discussion going here and we are somewhat torn on the best practice for using .gitignore on projects that contain a lot of files (like a CMS).
Method 1
Method 1 would be to purposefully .gitignore all files that come standard with your build. That would generally start like:
# ignore everything in the root except the "wp-content" directory.
!wp-content/
# ignore everything in the "wp-content" directory, except:
# "mu-plugins", "plugins", "themes" directory
wp-content/*
!wp-content/mu-plugins/
!wp-content/plugins/
!wp-content/themes/
# ignore these plugins
wp-content/plugins/hello.php
# ignore specific themes
wp-content/themes/twenty*/
# ignore node dependency directories
node_modules/
# ignore log files and databases
*.log
*.sql
*.sqlite
Some staff members like this approach since if you create something outside of the standard files, for example like a /build folder, then it would automatically be detected for inclusion. However, writing custom theming and plugins require you to add a few layers to this file to "step in" to the folders you want to keep, and generally, the file is a bit messier to read.
Method 2
Method 2 ignores everything, and then you whitelist what you want in the repo. That would look like
# Ignore everything, but all to descend into subdirectories
*
!*/
# root files
!/.gitignore
!/.htaccess.live
!/favicon.ico
!/robots.txt
# theme
!/wp-content/themes/mytheme/**
/wp-content/themes/mytheme/style.css # Ignore Compiled CSS
/wp-content/themes/mytheme/js # Ignore Compiled JS
# plugins
!/wp-content/plugins/my-plugin/**
# deployment resources
!/build/**
Some staff like this since it's cleaner, you have to purposefully add something (which makes accidental adds harder), and it also in effect shows you your .git folder structure.
What is the best practice? Which method do you enjoy and would you recommend doing one over the other?
The second method is the best practice, when it comes to exlude some folder contents of gitignore rules.
It better reflect the following rule:
It is not possible to re-include a file if a parent directory of that file is excluded.
To exclude files (or all files) from a subfolder of an ignored folder f, you would do:
f/**
!f/**/
!f/a/sub/folder/someFile.txt
Meaning: you need to whitelist folders first, before being able to exclude from gitignore files.
It is clearer, shorter (unless you have a large number of folder to whitelist)
What if it is a Joomla install with a large amount of directories and files?
Or what if a core upgrade adds new files or folders
Don't forget you can have multiple gitignore files, one per folder.
That means you can mix and match both approaches.
And you have:
http://gitignore.io/ (which does blacklist when it comes to Joomla application)
github/gitignore (same approach for Joomla)
The ideal .gitignore file, is the one that does not exist.
For some reason, you're deeply intermingling files you want to track via source control, with files you DON'T want to track.
This, I think, is the source of your sadness.
You are mixing git's intended purpose, which is versioning of programmer-edited files, with deployment, which is intended to get the files where they belong in the correct directories.
Your question is not clear, as to whether you think the Wordpress core files should be versioned. I'm assuming not, since that's how you've set up your .gitignore.
Your question is also not clear, as to whether you are deploying a web site, or shipping plugins as a product. Those are both different use cases, and they require different types of versioning. If this is a deployed web site, you SHOULD be versioning Wordpress along with everything else. If you are shipping a plugin or a theme, then you should have a test suite of plenty of different Wordpress versions to test against.
I think your source control system should be set up, solely to track just the plugins/* and/or themes/* files that go into your distribution. Zipping that folder should give you the plugin asset that your customers download.
To debug your plugins, there should be a deploy step in your IDE that copies each of those tracked files, into a Wordpress install at a location you choose. This permits you to more easily test against different Wordpress versions.
You're reducing workflow problems, to trying to choose a .gitignore. Fix the problem at the root by getting the workflow right.

Version control without clutter

I personally don't like the .gitignore or .svn in my client copies. What is the best clutter-free server/client based versioning software that I would like to use for hobby projects for free. Because I would also like to archive my directory structure as is from the client (Here I assume I can manage this versioning nightmare.)
Clutter-free: Put versioning info on the server or on a separate directory that is configurable.
Perforce has no clutter. It's free for up to 20 users now.
TFS "11" has the concept of .tfignore files now as well. TFS Express is completely free as well as the TFS Preview (http://tfspreview.com) at the moment.
You don't have to use .tfignore files though if you don't have a need for them...
If you are using Windows, the new (>=1.7) TortoiseSVN does not have the .svn folders any more. It is using a database instead, so you don't have "clutter" in your directories.

How should I handle Sphinx configuration in version control?

I have a problem with my development workflow and Sphinx. I want to keep configuration file for Sphinx in version control so it's easier to manage. This means it's easier to link the file to code updates, etc ... However, the configuration file is stored in /usr/local/etc.
There are two solutions I can think of. Store the file in the repository and move it to the correct folder on deployment or recompile Sphinx to look for the file in my repository. I had a suggestion from someone to use a symlink, but that still requires a change on deployment.
Is there an elegant solution in Sphinx I'm missing?
perhaps have the /usr/local/etc/sphinx.conf file be a script that pulls the actual sphinx config from the file in your repo.
http://sphinxsearch.com/docs/current.html#rel098 scroll down to general and you'll see:
"added scripting (shebang syntax) support to config files (example: #!/usr/bin/php in the first line)"

Best practices for using Hg with Grails?

What should I check in/not check in? Since many of the files are sometimes auto-generated I'm not entirely sure how to handle this using version control...does it have something to do with tags?
For instance in ANT, I know not to check-in my target/bin directories...but Grails adds another level of confusion to this...since some of code is generated and some of it is not.
(It may become clearer as I go...but it seems to be that there needs to be some way of being able to tell what was just generated and what was modified by a developer so that it needs to be placed in version control)
Here's the .hgignore directory I've got on my most recent grails project (with a couple of project specific things taken out):
syntax: glob
out
target
logs
*.iml
.idea
*.iws
*.war
workspace.xml
lib/build
lib/compile
lib/runtime
lib/test
~$*
stacktrace.log
*.tmproj
*.launch
reports/
*.orig
*.zip
.DS_Store
*/.DS_Store
web-app/WEB-INF/classes
cobertura.ser
The generated code in Grails should be placed under version control. It's not secondary executable code that is generated by the build process like class files, but instead is code that is part of your source. The generated code is intended to be just a starting point for your application and will most likely be modified at some point anyway.
Also check this:
http://www.grails.org/Checking+Projects+into+SVN
and this:
https://stackoverflow.com/questions/4201578

How to manage external dependencies which are constantly being modified

Our development uses lots of open-source code and I'm trying to figure out what the best way to manage these external dependencies.
Our current configuration:
we are developing for both linux and windows
We use svn for our own code
external dependencies (boost, log4cpp, etc) are not stored in svn. Instead I put them under ./extern (or c:\extern on windows). I don't want to put them in our repository because I will not be able to update them that way. Some of these are constantly being updated.
My questions
What to do if I need to modify external code?
Currently I have created a folder in my svn repository called extern_hacks and that is where I put the modified external code. I then link (or copy on windows) the files into the external directory structure. This solution is problematic since it is hard to keep track of copying the files, and very hard to update from svn when files are sitting in two repositories (mine for the modified files, and the original repository say sourceforge)
How to manage versions of external dependencies?
I'm interested to hear how others deal with these issues. Thanks.
I keep them in svn, and manage them as vendor branches. Keeping them loose externally makes it very hard to go back to a previous build, or fix bugs in a previous build (especially if the bug is from a change to the external dependency)
Keeping them in svn has saved me lots of headache, and also allows you to get a new workstation able to work on your codebase quickly.
I do not understand why you say
I don't want to put them in our repository because I will not be able to update them that way. Some of these are constantly being updated.
You really need to
include external dependencies in your source control and periodically update them and then tese, test, test.
Coordinate your build process with the updates for the external dependencies.
If your code depends upon something, then you really need to have control over when it gets updated/modified. Coding in a space where these dependencies can get updated at any time is too painful as you're no doubt finding out. I personally prefer option 1.
When I had to do something like this, I added the external source as external, and then applied a patch to it. The patch contains my modifications to the external source. So, I actually only version control my patches. Most of the times this works, if there are no "dramatic" changes in the external code.
Have you considered Maven? It's a build system that has excellent support for managing dependencies. For each project you can specify the required dependencies in an xml file as part of that project. The external libraries are held in a dependency repository (in our case Artifactory) this is separate from your version control system and can just be a network drive. It also allows managing different versions of projects.
I would be careful considering Maven because:
it is another repository in a system where you already have a repository with your current version control system;
it (Maven) is based on the only "common version control" every developer have, the file system (which means no metadata, or properties attached to the file, no proper history in term of who modified what and when)
Now when dealing with third-parties, you can consider having them in your version control system, but in a packaged way: that is in a very compact way, with sources and documentations zipped, in order to have the least possible number of files.
That way, you will manage the deployment of those (many) third-party libraries easily since the number of files to deploy is low.
Plus, having them under source control allows you to make a branch (say, a 'hack' branch), in which you will stored the packaged (or zipped) version of the hacked library.
What you can store in an external way is the un-zipped, complete set of files representing those libraries since there is no real development on them, or just a punctual hack: normally, your job is not to develop existing libraries, but to use them (even a bit modified) for implementing faster some features of your project.
If you need at some point to compare some hacked version with some official version, you will just pull out from svn the appropriate 'hacked' version number, unzip-it and compare-it with the official (and externally stored) version (with winmerge for instance)