I've found a really good tutorial on "Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References"
Now I need to understand if my approach can work.
Suppose I have my "main" project with all the assets I need (View Controllers, Delegates, etc.).
Now I create a new project and simply add a reference to every file I need from the first project; of course I DON'T select the "copy if needed" option.
In this way do I build a new project with all the assets from my main project?
If I change the code in the main project, this change will be reflected to all the referencig projects?
Is this an easier way to share code between projects?
Thanks.
Since I keep all my code under version control, the way I do it is to have modular code as Git repositories. That way, to add common code, or chunks of functionality to my project I just need to add these as submodules.
The advantages of this are:
Common code is kept in one place, versioned and backed up.
Having small repositories for code that does just one thing encourages writing modular code with minimal dependencies.
Submodules are added to a repository at a particular revision. So, if you change your common codebase, these changes are not automatically applied to the clones - you have to explicitly pull in changes. That way, if you accidentally change something that could break one of your projects, it won't appear suddenly.
If you set up your submodules properly, you can make changes to the common code from within one of your projects that can be pushed to all other repositories. That way you can work locally.
Your entire project is in a repository, without references to other projects, so you can move them, save them, archive and restore them without worrying about where the references point to.
Related
How do I have a Project Explorer's Working Set be built automatically from the contents of .gitignore, and then kept in sync with .gitignore?
I am working on a C++ AutoTools project which, as it is common for AutoTools projects, generates quite a lot of files during the build stage. I do have them .gitignored already. Now I'm trying Eclipse on that project, and found that I'd have to carefully pick files to ignore again.
You cannot. This feature does not exist.
The working sets functionality was implemented a long time before GIT appeared, and it was a method for removing clutter in large projects, and what is important, it was was a method that resided in the UI domain.
In fact, A working set extension point documentation shows it is possible to create a self-updating working set, and the search over the egit codebase returns no results.
As I have said, this feature is not implemented.
However, you can create your own plugin that will do what you want. It is not very complicated, and should not take more than a day or two. Or just open a feature request in the Eclipse bugzilla.
As for your underlying problem, you could try using the derived resources mechanism. It was added to make possible to prevent team providers (CVS/GIT) from managing files that are a result of a build.
Just a word of warning - GIT won't allow you to ignore further changes to any resource already under its control.
I am trying to release a custom view that utilizes WEPopoverController as well as UIButton+Glossy but I don't know how I should add their code to my git repository. Should I submodule it?
Here is the UIView if anyone is interested:
Of course you could add them as submodules so it boils down to more of a personal opinion.
In my opinion submodules are overused. I would use it only to in a case where I want to break a specific project into smaller projects. So let's say I have a large project but a specific part of it can be usefull by itself. In that case I could create a submodule so people that is only intersted in that part can fork/clone it.
In your case where you are only using it in your app the best way is probably to copy the files into your repo, not using submodules. In that case It may be a good idea to add them to a vendor folder just to make it clear that it's part of a separate project you are using here.
Let's say that in the future the project gets updated and breaks the API or cause other problems. You better have a static version of the file you have tested with your application than leaving it open for anyone to update the submodule to a version of those libraries that might be not supported by your application.
I am in the process of moving to Git from SVN. In SVN I had multiple eclipse projects in a single SVN repository that is convenient for browsing projects. I was going to move to having one git repository per eclipse project but EGit suggests doing otherwise.
The guide for EGit suggests putting multiple projects into a single Git repository.
Looking at similar questions such as this suggest one project per repository.
Which approach is best practice and what do people implement?
It depends on how closely-related these projects are. Ask yourself the following questions:
Will they always need to be branched/tagged together?
Will you want to commit over all projects, or does a commit mostly only touch one project?
Does the build system operate on all of them or do they have a boundary there?
If you put them all in one, some things from above will be easier. You will only have to branch/tag/stash/commit in one repository, as opposed to doing it for every repository separately.
But if you need to have e.g. separate release cycles for the projects, then it's necessary to have each project in an independent repository.
Note that you can always split up a repository later, or combine multiple repositories into one again without losing history.
Combining is a bit harder to do than splitting, so I would go for one repository first and see how it goes.
I use 1 repo per project.
Some reasoning:
When you discover you messed up something after several commits, it's much easier to fix when it's just one project. Just think about, you did commits to two other projects and now you need to fix the commit you did on the 3rd project.
As Fedir said, your history and log is much cleaner. It only shows the commits for that project.
It works better with the development workflow I have. I have a master branch for production, develop branch for, well, development, and I create branches to implement features (you can read more about it here: http://blog.avirtualhome.com/development-workflow-using-git/)
When you work in a team, and so "share" the git repo, do the team members really need all the other projects as well?
Just a few thoughts, but what it boils down to: Do what works for you.
I have multiple projects (Eclipse projects) and have tried different things to find out what worked best in terms of actual daily development. Here is what I found and I think that most people would find the same thing if they kept track of the results and analyzed the results objectively.
In short applying the following rules will give the best results:
Make a separate repository for each project group.
Each project group consist of a group of projects that are tightly connected to each other, that should be administered together and that cannot be easily decoupled from each other.
A project group can contain a single project.
A project group that contains multiple projects should be examined to see if some of its projects can be decoupled from each other so it can be split into smaller project groups that are still contain projects that are tightly connected to each other, that should be administered together and that cannot be easily decoupled from each other.
The following guidelines explain this process for determining which projects to put in the same repository in more detail:
If a project is not closely connected to any other project (for example, the project can be opened without other projects being opened and no other projects relies on the project being opened when they are opened) then you should definitely place it in its own repository for the reasons explained in the answers above this one.
If a project is dependent upon other projects or other projects depend upon the project then it comes down to exactly how connected are they upon each other, how well they can be packaged together and how easily can they be decoupled from each other.
A) For example a testing project that contains junit test classes to test the classes of a main project is a case where the two projects are very connected with each other, can easily be packaged together and cannot be easily decoupled from each other. These projects should be placed in the same repository for the reasons explained in part C below.
B) In a case where one project relies on another project to provide some sort of shared resources it really comes down to how well that they can be administered together and how easily that they can be decoupled from each other. For example if the project with the shared resources is relied upon by many projects, then it should be put in its own repository because the other unrelated projects are impacted by changes to the shared source code project. In a case like this, the shared resources project should be decoupled from the dependent projects instead of being directly connected to the dependent projects. (For example, it would be better to create versioned archive files [Jar files with a name like "projectName".1.0.1.0.jar for example] and include a copy of those in each project instead of sharing the resources by linking the projects together.)
C) If the multiple projects are connected, can be easily administered together but cannot be easily decoupled from each other, then it depends upon how tightly connected they are with each other.
I) If the projects are put into one repository, then the projects will be kept in sync with each other in the repository each time there is a commit, which can be a real life saver if the projects are tightly connected. However, this also creates the issues noted in the answers above this one.
II) If the projects are put into separate repositories, then you will have to take care to keep there commits in sync with each other and be sure to include some sort of mechanism to indicate which commits belong to the same sync point across the projects (Perhaps something like including the same sync point number in the comments for the commit of each project when a group of commits is done across the projects.)
III) So in cases like this, it is almost always better to put these projects together into a single repository to reduce the overhead of human effort in syncing the commits and to avoid human error should the commits need to be backed out. The only time that it might be better to place them in separate repositories is when only one of the projects is being changed regularly and the other connected projects are rarely changed.
I think this question is related to one I answered here. basically Git by its nature supports a very fine granular structure when it comes to projects/repositories. I have read and been taught that 1 repository per project is almost always best practice. You lose almost nothing by keeping the projects separate and gain a lot as other have been describing.
Probably, it will be more performant to work with if You will create multiple git repositories.
If You will make a branch, only project's files would be branched, and not all the projects.
Small project it will be faster to analyze, to commit. Operations will take less of time.
The log will be more clear also, You could make more granulated configuration if You will have multiple git repositories.
I have a project A. This produces a product that's working and already submitted to the app store etc. Now, I'd like to create a new project, let's call it project B, and I want B to be based on A. Obviously B will add more UI and behavior on top of A.
After doing some research, the only option seems to be using cross-project referencing, because I'd like to reuse Project A's XIBs, images etc in Project B. Am I correct in assuming that cross-project referencing should work in that scenario?
Well I'm having some serious problems in getting this thing working. I'd like to achieve project level reuse. In Java or in .NET this wouldn't even be a consideration, the technology allows that. Because iPhone doesn't support frameworks, I think the developers are pushed towards more primitive approaches like code duplication.
So, how can I tackle this problem. How can I create my Project B, based on Project A (including XIBs, images, etc)?
Thanks,
If A and B are so similar perhaps you could consider simply creating a new build target; this would give you a single project with target A and target B. Both targets would have access to any of the resources in the project.
If you have a fair bit of shared code then you can create a static library; iOS doesn't support dynamic linking to user-generated libraries, but it supports static linking just fine. This would make the cross-project dependencies useful, because you could have project B reference library A from project A and build it as a dependency.
I did this same thing at one point:
I copied and pasted the entire app and then had two separate apps that I could work on individually.
Contrary to popular opinion, it is possible to create iOS frameworks.
Maybe you could use a scm tool like Git or Piston (http://piston.rubyforge.org) and 'clone' the code. Do something like:
#add original project to git
cd /your/base/project/code
git init
git add . #Stages all files to check-in index
git commit -m 'Your commit message here'
Then
#clone the original project into a new one
cd /your/new/project/directory
git clone /your/base/project/code
git checkout -b aNewWorkingBranchName #create a new working branch to modify
#modify code to your <3's content, use git pull/push/merge/rebase/diff as required to track/update original project
This should let you develop the 'new' project independently, while allowing you to pull in changes when required. Piston allows 'vendor' branching against both Git or Subversion repositories, tying your new code to a particular remote revision. Have a look at its documentation.
I work on a large project where all the source files are stored in a version control except the project files. This was the lead developer's decision. His reasoning was:
Its to time consuming to reconcile the differences among developers' working directories.
It allows developers to work independently until their changes are stable
Instead, a developer initially gets a copy of a fellow developer's project files. Then when new files are added each developer notifies all the rest about the change. This strikes me as far more time consuming in the long run.
In my opinion the supposed benefits of not tracking changes to the project files are outweighed by the danger. In addition to references to its needed source files each project file has configuration settings that would be very time consuming and error prone to reproduce if it became corrupted or there was a hardware failure. Some of them have source code embedded in them that would be nearly impossible to recover.
I tried to convince the lead that both of his reasons can be accomplished by:
Agreeing on a standard folder structure
Using relative paths in the project files
Using the version control system more effectively
But so far he's unwilling to heed my suggestions. I checked the svn log and discovered that each major version's history begins with an Add. I have a feeling he doesn't know how to use the branching feature at all.
Am I worrying about nothing or are my concerns valid?
Your concerns are valid. There's no good reason to exclude project files from the repository. They should absolutely be under version control. You'll need to standardize on a directory structure for automated builds as well, so your lead is just postponing the inevitable.
Here are some reasons to check project (*.*proj) files into version control:
Avoid unnecessary build breaks. Relying on individual developers to notify the rest of the team every time the add, remove or rename a source file is not a sustainable practice. There will be mistakes and you will end up with broken builds and your team will waste valuable time trying to determine why the build broke.
Maintain an authoritative source configuration. If there are no project files in the repository, you don't have enough information there to reliably build the solution. Is your team planning to deliver a build from one of your developer's machines? If so, which one? The whole point of having a source control repository is to maintain an authoritative source configuration from which you build and deliver releases.
Simplify management of your projects. Having each team member independently updating their individual copies of your various project files gets more complicated when you introduce project types that not everyone is familiar with. What happens if you need to introduce a WiX project to generate an MSI package or a Database project?
I'd also argue that the two points made in defense of this strategy of not checking in project files are easily refuted. Let's take a look at each:
Its to time consuming to reconcile the differences among developers' working directories.
Source configurations should always be setup with relative paths. If you have hard coded paths in your source configuration (project files, resource files, etc.) then you're doing it wrong. Choosing to ignore the problem is not going to make it go away.
It allows developers to work independently until their changes are stable
No, using version control lets developers work in isolation until their changes are stable. If you each continue to maintain your own separate copies of the project files, as soon as someone checks in a change that references a class in a new source file, you've broken everyone on the team until they stop what they're doing and carefully update their project files. Compare that experience with just "getting latest" from source control.
Generally, a project checked out of SVN should be working, or there should be tools included to make it work (e.g. autogen.sh). If the project file is missing or you need knowledge about which files should be in the project, there is something missing.
Automatically generated files should not be in SVN, as it is pointless to track the changes to these.
Project files with relative path belong under source control.
Files that don't: For example in .Net, I would not put the .suo (user options) web.config (or app.config under source control. You may have developers using different connection strings, etc.
In the case of web.config, I like to put a web.config.example in. That way you copy the file to web.config upon initial checkout and tweak what settings you'd like. If you add something that needs to be added to all web.config, you merge those lines into the .example version and notify the team to merge that into their local version.
I think it depends on the IDE and configuration of the project. Some IDEs have hard-coded absolute paths and that's a real problem with multiple developers working on the same code with different local copies and configurations. Avoid absolute path references to libraries, for example, if you can.
In Eclipse (and Java), it's fine to commit .project and .classpath files (so long as the classpath doesn't have absolute references). However, you may find that using tools like Maven can help having some independence from the IDE and individual settings (in which case you wouldn't need to commit .project, .settings and .classpath in Eclipse since m2eclipse would re-create them for you automatically). This might not apply as well to other languages/environments.
In addition, if I need to reference something really specific to my machine (either configuration or file location), it tend to have my own local branch in Git which I rebase when necessary, committing only the common parts to the remote repository. Git diff/rebase works well: it tends to be able to work out the diffs even if the local changes affect files that have been modified remotely, except when those changes conflict, in which case you get the opportunity to merge the changes manually.
That's just retarded. With a set up like that, I can have a perfectly working project containing files that are subtly different from everyone else. Imagine the havoc this would cause if someone accidentally propagates this mess into QA and everyone is trying to figure out what's going on. Imagine the catastrophe that would ensue if it ever got released to the production environment...!