Certainly, if you already used Cocoapods, at some time, you made a pod to point to some branch, like this::
pod ‘MYPod’, :git => ‘https://mygit.com/mygroup/myrepo.git’, :branch => ‘my-branch’
Ok, everything normal so far. So, why the worry?
The problem lies in some internal processes of Cocoapods.
What’s going on behind the curtains?
When the tool tries to download a dependency which points to a git repo, it executes the following code:
Basically, it clones the repo, and if the developer informed a commit hash, it will try to checkout the commit.
But how is this clone getting done? Let’s see.
Git clone (what?)
Cocoapods creates the clone’s arguments based in some criteria. It’s kinda unclear how it’s done, but analyzing the source code you can have a good clue about what’s happening behind the curtains.
I’ll summarize here what this function does:
- Create the clone default arguments, with the url, the clone location and an empty template.
- If it’s a shadow clone (which by default it is, unless cocoapods identify that the repo does not support), AND THE COMMIT OPTION IS NOT USED, it only downloads the branch and takes a depth of 1, which will only get the “surface” code, without pulling history and nothing more than the repo stores.
- And if Cocoapods detects it shouldn’t force HEAD (which by default it shouldn’t), it will check if a tag or branch was specified, and pass that branch to the command.
- The function returns the arguments and git clone is executed.
So far so good, right? WELL, MAYBE NOT…
Notice the following: when you specify a commit, it will simply do a FULL clone of your repo, and then checkout the commit’s hash. It’s not the most performative, but it makes some sense.
Some repos are huge, as they store a lot of history over time, and it’s no wonder if you take old simple repos that are over 1GB in size.
That’s a big problem: have you ever thought of having to download 1GB or more when doing a pod install, being on a poor internet, or if you have a data limit for downloading?
Ahhhh, but we’re ok. We don’t use commit, we pass a branch to it, so everything will be fine.
Well, that’s where you’re wrong, and I guarantee you, you’ll be surprised!!
I swear, it wasn’t me! It was him!! (Cocoapods, you bastard!)
Before we point out whose fault it is, shall we look at the code? What does cocoapods do with the options you give it?
Well, this is where I leave you with the little surprise…
Do you know what this ls-remote does? Wants to know? Look!!
> git ls-remote https://meugit.com/meugrupo/meurepo.git minha-branch cf1a476f6b4f6e75b4e2d4cefcd2389aec56f9bf refs/heads/minha-branch
It takes your branch and… RETURNS A COMMIT HASH!
Exactly! Cocoapods will turn your branch into a commit.
AND YOU WILL DELETE YOUR BRANCH FROM THE OPTIONS!
That’s so cool!(not) 🤡
Now remember what it does when you pass a commit??? That’s right!!!
IT CLONES THE ENTIRE REPO!!! 🤬🤬🤬🤬🤬
Save me! Please!! 😭
Despite the problems, the solution is quite simple. USE TAG!
When you need to refer to a git, use tag instead of branch. Cocoapods will not convert your tag to a commit, and will get depth 1 at clone time, making downloading infinitely faster.
pod ‘MyPod’, :git => ‘https://mygit.com/mygroup/myrepo.git’, :branch => ‘my-branch’
pod ‘MyPod’, :git => ‘https://mygit.com/mygroup/myrepo.git’, :tag => ‘my-branch’
You don’t necessarily need to create a tag, just change the word branch to tag in the Podfile. It won’t check if your tag is really a tag, and it will take branch form anyway.
If he can deceive you, you can deceive him too! 😈
There is a reason for all of this
The cocoapods doesn’t do this all cause he is “evil” or by a misconception. In fact, this is important when the dev is working with pods in development.
When you do a pod install, pointing to a branch, it takes and converts your branch into a commit, and writes that commit to Podfile.lock.
That way, if new things are added to the branch (since it’s in development), it won’t impact the installed pod, unless the dev call a pod update (which is the natural way). This is not the case with the tag, as the tag is not a code under development.
So, don’t curse the tool, but take advantage of the fact that there’s an alternative out there, and if you don’t need those commit locks, use them without restrictions. 😉
Categories: Quick Tips