Xcode bot: git submodules not initialized - xcode

I'm trying to set up an Xcode bot with OSX server.
After configuring the git repository and creating a bot, I run integrate.
It fails because the repository is checked out only partially. More precisely: Of the 6 submodules configured, only 3 are initialized and checked out.
didi#mac:/Library/Server/Xcode/Data/BotRuns/Cache/c5fda8f4-4d25-4d25-c18a-eb0b16a06692/source$ git submodule status
+c6e8420aec4147641fb1ca12d9f1d31bdd804e77 libs/asi-http-request (v1.7-320-gc6e8420)
-ae64a38766b42f236bb94f0e661cddb829f9ac43 libs/kraken
-7da02b323636bbaa0bbbf5b4eb229fcc07b1e14a libs/route-me
152f9ee5576e710705a49032253d7d5af5366f9c libs/routing (152f9ee)
347aaf74fe0c6388785095efdbf6397851514b7f libs/rtlabel (1.0-32-g347aaf7)
-562cf6b1c879f03546f5184e012cea15c4f159db libs/skmaps
(- means not initialized)
Looking at the bot log, it seems to just ignore the missing submodules in the submodule initialize part:
...
Checking connectivity... done
Submodule 'libs/asi-http-request' (https://github.com/BikeCityGuide/asi-http-request.git) registered for path 'libs/asi-http-request'
Submodule 'libs/routing' (ssh://mac_ci#rooty.bikecityguide.org/var/repos/librouting.git) registered for path 'libs/routing'
Submodule 'libs/rtlabel' (https://github.com/BikeCityGuide/RTLabel.git) registered for path 'libs/rtlabel'
Cloning into 'libs/asi-http-request'...
...
No error message here or anywhere else. No single mention of e.g. "kraken" (name of a missing submodule) anywhere in the logs.
When checking out manually (clone, submodule init, submodule update), all submodules are initialized.
.gitmodules looks like this:
$ cat .gitmodules
[submodule "libs/asi-http-request"]
path = libs/asi-http-request
url = https://github.com/BikeCityGuide/asi-http-request.git
[submodule "libs/rtlabel"]
path = libs/rtlabel
url = https://github.com/BikeCityGuide/RTLabel.git
[submodule "libs/routing"]
path = libs/routing
url = ../librouting.git
[submodule "libs/kraken"]
path = libs/kraken
url = ../kraken_ios.git
[submodule "libs/route-me"]
path = libs/route-me
url = ../route-me.git
[submodule "libs/skmaps"]
path = libs/skmaps
url = ../skmaps.git
The base repository and the 4 submodule repositories referenced with relative URL all need ssh authentication. The user set up in OSX server has access to all of them.
The log of the bot contains no trace of trying to pull the missing submodules.
I can manually fix the local repository, but I'd like not to have the same issue again with new projects and new submodules added.
git version 1.8.4.2
I'm out of ideas.

On Xcode 6.1.1 and OS X Server 4.0, it looks like they fixed the submodules with detached HEAD issue, but there are still some bugs. One of my project has one its submodules being completely ignored by Xcode Server so the app fails to build:
$ git submodule
8a88bc41c9dc0f57c921d82bc4e7b93e1c4cbf7a InAppStore (heads/master)
e4203f9f61d2546868c1274da5c7a0c56b87a737 Libraries (heads/master) <--- IGNORED
01902f255e6c3d90f0db41cb62dd2934098b98dd MixpanelTracker (heads/master)
e2bee59accd817d50dff881a42c9e9afe307226f XLFacility (1.4.1-5-ge2bee59)
The fix for me was to add a pre-integration script trigger as such:
cd "$XCS_SOURCE_DIR/{YOUR_APP_REPO_NAME_WITHOUT_DOT_GIT_SUFFIX}"
git submodule update --init --recursive
At this point things were building although there were non-fatal warnings about the checkout not being clean or something like that. They went away when I changed to the bot's configuration to have "Cleaning" set to "Always".

In Xcode 9 server, submodules are not initialized if none of the files of the submodules is referenced by one of the Xcode projects in the workspace.
This may happen, for instance, when you include a header file from a submodule that is not part of your code and therefore you added it to the "headers search paths" (c/c++) instead of adding it to the project.
A possible workaround is to add at least one file from the submodule to the Xcode project. It can even be a Readme.md file.
This is easier than checking out submodules using a custom script because it relies on Xcode Server to store your GIT credentials.

Is I understand its a bug.
I had the same problems and found that there is an issue with detached submodules.
See the next article that show how to fix this issue (doesn't help on public repository)
http://ikennd.ac/blog/2013/10/xcode-bots-common-problems-and-workarounds/
Hope this helps you.

Related

Github how to push Xcode project without old files and folders?

I finished an Xcode project and pushed it to github from Xcode 'Source Control' Menu. Then I changed the project name CountryBook to Countries. I Built project and ran. Everything was okay. Then I coiped project folder to desktop as a backup. Then pushed project again. Everything has messed up. Some old named folders and files still exist in repo. Then I deleted every directory and file from github repository. Now, backup version of project is working. But when I try to push it to repo, old files are still exist. I deleted 'origin' from 'Remotes' and created a new repo named 'Countries'. I pushed project again but it was same. A mixed version of old files and new files. When I clone the github version of project, of course it is not runnable. What sould I do and how can I push clean version of my project? I don't want to lose project.
This is Countries repo now:
This is my working project folder with correct content:
I would fix it via command line, lets assume you start from scratch:
Step 1 - prepare the working branch:
Clone the project
Navigate to root folder of the project
Checkout the main branch ("main", "master", or whatever it is)
Create a new branch you will be working with
git clone https://github.com/yourorg/yourrepo
cd yourrepo
git checkout main # or master
git checkout -b fixprojectstructure # branch name can be anything
Step 2 - clean project locally
Delete old project, old workspace, ensure the names in Podfile and Podfile.lock are fine
Build the project and ensure it's working
Step 3 - commit your changes:
# assuming you are in the root of the project
git add .
git commit -m "Some explanation"
Step 4 - push your changes:
I usually do it the lazy way: just run git push, which will show you the proper syntax to push remotely, something like
> git push
fatal: The current branch fixprojectstructure has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin fixprojectstructure
> git push --set-upstream origin fixprojectstructure
Enumerating objects: ...
...
remote: Create a pull request for 'fixprojectstructure' on GitHub by visiting:
remote: https://github.com/.../pull/new/fixprojectstructure
remote:
...
Branch 'fixprojectstructure' set up to track remote branch 'fixprojectstructure' from 'origin'.
Step 5 - merge your changes:
Basically just do what the line above is saying:
Navigate to https://github.com/.../pull/new/fixprojectstructure
Create pull request
Merge pull request to main (or whatever the initial branch was)
Note on the side: configure the gitignore file properly for your repo as well. For starters, follow the gitignore template to create a proper gitignore file, and then change it the way you need to.
For instance:
Usually, if you use cocoapods, you do not store .workspace folder and its contents in the repo. Instead it's generated using pod install command on each machine that needs it.
It's also common to exclude Pods directory from storing in the repo, although there are pro / cons arguments both ways.

How to use git in vendor folder of fork?

I always use composer packages in Laravel but I never changed one. This is my first time and I don't want to do it incorrect.
I need to use and change a packages foo/bar. Everything that follows now is just guessed:
I forked the repo
I created a develop branch
I added a vcs to my composer.json
"require": {
//...
"foo/bar": "dev-develop",
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/thisisme/bar"
}
],
composer update
Now I have the thisisme/bar fork in my vendor folder in foo.
So far so good. Now I can use my own fork.
But currently, as I don't know what is good practice to modify the repo, I cloned the repo to a completely different location. Then I push my changes there and run composer update in my project to get the changes. But this is a pain.
Do I need to have a sub git in my project in vendor/foo with
git remote add origin https://github.com/thisisme/bar.git. Because "git in git" feels wrong and finally is not really working as git commands seem to interact with the "parent git".
While VonCs answer is correct regarding git, I'm not certainly sure that git submodule support is well aligned with composer(1) vendor dir for packages from a VCS repository. At least I have not experimented much with it and when I use a composer configuration with a VCS git repository, I normally don't need that1.
While composer(1) has support for git for vendor packages, it is on repository level, that is, you can have your own repository for your package (as you have configured it shown in your question) and then composer takes care of updating (or giving a warnings about local changes).
composer(1) supports this with its own remote for the packages (non-bare) clone (in the source install, read on).
So yes, what you describe ("But this is a pain."), is as long as you don't use it to your benefit. While you develop your (cloned) package, you don't need to run composer update all the time.
.git
composer.json
vendor/foo/bar/.git
A Composer project with two Git repositories
This is why IMHO "git in git" must not feel wrong. Similar to git sub-modules, git supports this very well. By default it even keeps track in the parent project of the current revision (changes) of the sub-project but without having the information of the remote - as it is local (gitlink).
You won't see this thought as within the tree, the gitlink would be at vendor/foo/bar and commonly (& given that) vendor is git ignored, no version tracking in the main project for vendor/foo/bar/.git - but there in the sub-project.
This is not a problem as Composer manages that git sub-project for you (the initial clone and further checkouts) in terms of your main project.
And git realizes it is a different project.
You should be able to cd into the package directory within the vendor folder (vendor/foo/bar) and configure your remote(s) there. You can then work within that project and git(1) will work there and not within the parent repository.
To have this work with composer(1) it is important that you configure composer to prefer the source install variant for that repository. This is the preferred-install option and you can configure it for your repository specifically.
{
"config": {
"preferred-install": {
"foo/bar": "source"
}
}
}
From the wording in your question, I assume that you have not yet configured it.
And this is somewhat important as only with the source install, there will be a (non-bare) git clone in vendor/foo/bar and therefore the git checkout with the overall git configuration within the packages folder in the vendor directory (as you have Github configured as the repository source and composer optimizes to take the dist version by default IIRC).
After you changed your configuration to the source install and updated it, cd into vendor/foo/bar and then run git remote -v. It now should show you the "composer" remote(s) for that package.
As you use the develop branch, you can add changes locally but mind the gap that you would also need to push them to the remote repository (Github) before you use composer again to update (at least) that foo/bar package - as while you use git for the development of the foo/bar package now, in your main project you use composer to manage the dependency.
This is the price you have on the payroll using Github instead of a configuration that is more near to the place of work, but at least locally, you can handle the package with "git in git".
This is normally straight forward. One overall price remains thought, due to managing two instead of one repository but that you can't prevent with this kind of composer project [composer only versioned vendor folder]).
Note: If development takes longer than a few hours, it may also make sense to include the new Git sub-project in the backup routine of your parenting project, so that when you remove the folder vendor/foo/bar you have a backup of the (local) Git repository and working tree in it. However, this depends on the project configuration and is your own responsibility.
A bit of a workflow with some hints is also outlined in the composer documentation in Loading a package from a VCS repository.
1 There is a type of setup for a composer project where vendor itself is under git version control, with that git sub-modules can work (very well), but this is most likely not the kind of setup you have for your project, so I skip it for this answer.
If you're working with sail or docker-compose and linking the foo/bar project in the vendor dir is only a temporary until 'it works' solution you could just add it as a volume link. This is what I usually do.
Eg: I'm working on my-project in ~/projects/my-project, I clone the foo/bar repo to ~/projects/bar
Then in the docker-compose.yml I can add the volume:
volumes:
- .:/var/www/html
- ../bar:/var/www/html/vendor/foo/bar
Again, this has a huge assumption on docker being used, but I like to think that everybody is using it these days.
Do I need to have a sub git in my project in vendor/foo with git remote add origin https://github.com/thisisme/bar.git.
That could be achieved with a submodule which allows for your parent Git repository to only store a reference to another repository.
You would use git submodule add for that.
A git clone --recurse-submodule would therefore clone your project with the submodule Git repository in it cloned as well, and checked out to the exact reference you previously committed.

No submodule mapping found in .gitmodules for path '/ProjectName'

2 questions:
I created a project in xcode which has the following folders in it:
app_icon.png
app_icon#2x.png
FacebookSDK.framework
ProjectName
ProjectName.xcodeproj
I used git to create local repo and push it to a newly created github repo.
When I try to clone the repository using xcode I get the following error:
No submodule mapping found in .gitmodules for path '/ProjectName'
What is the issue? Is it the fact that I have FacebookSDK.framework folder in it?
After two attempts it miraculously was able to clone the project.. However, now when I try to commit anything in xCode the button says "Commit 1085 files" even though it shows 2 files changed...
u can run it :
git rm —cached /ProjectName

Xcode Git Submodule Commit Issue

What I did
I made a new Single Page App project in my application called "parent".
I made a new Static library project called "child" and I've Added it as a git submodule in my parent project folder.
I have imported the child project into the parent project by dragging from the finder from submodule directory, the child project file to my parent project in Xcode window -> Parent Project file tree.
Now Is my problem
When I would like to do a commit through File -> Source Control -> Commit, I select files enter my message and do a commit all goes right.
Now When I make a change into my child project and try to commit by the same way, xcode make me know it success the commit
Now try a pull from File -> Source Control -> Pull, My child project is selectable but my parent project has "Uncommited Changes".
So I come back to the commit interface and I saw the items that should have been committed during the last commit. Especially the folder of my submodule project.
What I did to resolve the problem
I use git from the command line in my parent project folder:
git add .
git commit -am "Core has been modified"
When I use this, I can access my to repository from the pull interface, that confirm that all change has been committed.
The real Problem
My company would like to make that work only with the Xcode SCM tool.
The problem seems to be linked to the use of "Submodule"
How can I make it work without the use of the Command Line
We have the same problem. It's like a small bug in XCode. Our workaround at the moment is the same as you mentioned and the only solution would be a bugfix or enhancement how XCode support
Our workflow looks like the following :
-commit submodule changes with XCode
-commit main changes with XCode
-commit main directory change with CLI ( git commit )
-push main & submodule with XCode
we hope that this small bug would be fixed in the future directly in XCode
When you make a commit in a submodule, it shows up as a change in the parent.
The solution is to make changes to the submodule first, then commit the changes to the parent. This way all of your changes to the submodule will get bundled into the parent project commit.

Xcode thinks a remote svn repos is git

I'm running Xcode 4.1 at work and home. I've successfully checked out a project from a remote svn repository (work) on my home setup. The repos was updated, so when I got home, I did an update on the local checkout.
The status of the updated files got flagged "U" (good) and a page appeared showing changes to accept, but when I hit accept, I get a popup that says:
The working copy "ABRA-D" failed to pull. fatal: Not a git repository
(or any of the parent directories): .git
Well, yes... the repo is svn, not git! Closing Xcode and restarting removes the "U" tags and I'm back where I started. Sounds like Xcode is confused about the repo type, though it knew enough to query the svn repo and find out what had been updated. Anyone know a cure?
That issue, already mentioned in "Error : Fatal: Not a git repository (or any of the parent directories): .git", has a somewhat curious solution described here:
Recently I created a new project and at some point I uploaded it to SVN. I am not quite sure how to reproduce this situation but somehow the versioning support of Xcode 4 decided to interpret the project as a git repository.
Each time I tried to copy a file per drag and drop into my project I got following error:
fatal: Not a git repository (or any of the parent directories): .git
The result was that the file got copied into the project folder, but the reference didn't get set in the project. I had to go into the folder and drag and drop the file again and uncheck the copy option this time, so that the reference gets set.
The Solution
Open Xcode and go to Window > Organizer
Find under repositories your project. It might be two entries if you use something like SVN.
Make sure it says "Type Git"
Mark the repository entry and hit backspace or delete (on mac)
Done
In my case, when i created my project it was using git. But later i removed all git files from my SVN repository. Then took an update.
Now, when i tried to add files, it gives me same error.
Solution: I removed all repositories against my project in XCode Organizer. Now when i added new files, it works fine.
I had a git and svn against the same project and tried removing the git and got this error
In the end went and manually edited xcshareddata found at and removed all the entries which had anything to do with the git repositoy.
myproject.xcodeproj/project.xcworkspace/xcshareddata

Resources