How to delete files or folders in a git repository using Xcode? - xcode

My project had several folders that accidentally got added to my GitHub repository. I could delete them (one file at a time) from the GitHub website but that is tedious for a large number of files. I tried using git on the command line but it was conflicting with the Xcode source control updates. I would just like to do it graphically in Xcode if possible.
The closest Xcode question that I could find was this one, but it was about removing source control altogether, which I don't want to do.
I struggled with this for quite some time but it turned out to be fairly easy. I am sharing my answer below.

As long as you have your project already connected to a remote GitHub repository, all you have to do is use Finder to delete the files or folders.
Then go to Source Control and choose Commit and after that Push.
This will delete the files from your GitHub repository without you having to use the command line.

Related

XCode not showing files pulled from Source Control

I am working on a Swift based XCode project that is synced with Git based master repository. One of my team member has added few files, to the master which I have pulled.
I find those files in my project directory, but not in my project. When I am manually trying to add these files to the project, in that case, I am getting Modify tag on my project, then I am unable to pull new changes from master.
This is very annoying. How do I take care of this.
Also, how do we make sure as a team that everyone of us is working separately on different module, and make surely everyone is able to commit/pull each other's changes.
The project folder with M tag is prohibiting us from doing so.
Edit 1
I have followed steps for this as well
git rm -r --cached ProjectName.xcodeproj
git commit -m "Removed file that shouldn't be tracked"
Even after doing this,
I had made changes in File1.swift, with my team member's changes in File2.swift
He had already committed it, I wanted to pull those changes, however due to changes in File1.swift I was unable to pull it.In order to make it work, I had to discard changes in File1.swift and then only I was able to pull those changes. If this is so, then it is defeating the purpose of using git
Xcode project files
The Xcode project file, or to be more precise, the pbxproj file inside the xcodeproj container keeps track of all files (among other things). Unlike Eclipse, Xcode does not monitor your source/project folder for changes thus does not update the list of files which can lead to inconsistencies after a merge.
Merge conflicts
If your team member adds or removes a file in his local copy of the repository and pushes his changes to the server, he basically overwrittes the pbxproj and therefore updates the list of files of the Xcode project. If you pull those changes there are two possible scenarios:
Git can merge the changes automatically which usually means it will keep your copy of the pbxproj file without the updated file references.
Git cannot merge the changes and therefore indicates a merge conflict that you need to resolve yourself. Depending on the differences and amount of changes these merge conflicts can be pretty annoying to resolve. Sometimes it might be easier to just delete your copy of the pbxproj file, use the one from the server and reapply your local changes, e.g., add file references.
In both cases you might need to compare your pbxproj file against the one from the server and merge things by hand. And yes, your project file will be marked with an M (for modified) which is perfectly fine. Just commit your changes and you are good to go again.
One more thing: Whenever you want to pull changes from the git server you can either stash your changes (git stash) or commit them.
Avoiding merge conflicts
In case you want to avoid merge conflicts in the future, I recommend having a look at the following tools.
Cocoapods
Cocoapods can be used to modularise your project into smaller pieces by creating private Pods. The benefit of this technique: You do not have to keep track of newly added or removed files. Just run pod update and you are up and running again. There are several blog posts that describe this technique in detail, e.g., here
phoenx
At my former company we had a pretty huge codebase and ran into some trouble when using Cocoapods. Therefore, we have developed our own meta-build system called phoenx. Phoenx can generate Xcode project and workspace setups of arbitrary complexity. It uses metadata files (something like Podfiles and Podspecs) to generate the projects etc. . Build settings will be stored in xcconfig files. At the moment it does not provide any setup tool so you have to invest a bit of time to write the xcconfig and metadata files by hand. We are working on a more convenient way to use it though. If you want to give it a try you can install it via sudo gem install phoenx. Documentation is available on GitHub.
Hope that helps!

All files missing from Git, Frameworks gone from Project Navigator

I was attempting to add a remote repository to my already in progress project. In the process of doing so all my files disappeared from the Commit section of Source Control (Using Git)
Also, all of the Frameworks that I downloaded from the internet (specifically my Parse Frameworks) disappeared from Finder and appeared red in the navigator.
Any ideas on how to fix this? I attempted to "Discard all Changes..." which proved to do nothing, and I tried dragging in newly downloaded frameworks, which also did not work. Should I just make a new project folder?
Looks like your frameworks folder got nuked/moved.
Without more info, this is my generic advice: first make a copy of the directory which encapsulates your git repo. Then look into the git commands git reset and the big hammer git reflog. Good luck.

Retrieve source files from git

I've been saving all my source files using the xcode git repository. I saw some articles online about speeding up the Mac performance and I used a tool called 'Monolingual' to cleanup unwanted language files on the hard drive. Unfortunately this also deleted my entire user directory along with all my source code.
Is there any way to retrieve the files from the local git? When i try to view them from xcode organizer, it doesn't show the previous saved repositories
The question is: did it remove also the .git directory which contains your code history?
If yes, then you need to restore (from a time machine backup for instance) at least that directory, in order to be able to checkout again your working tree from that git repo.

Best practices for Xcode + Git for multi-developer projects

I can create a repo and use GitHub / BitBucket fine for my own projects. I have had problems when collaborating with other developers or trying to fork a project on GitHub.
I am aware of other answers like Best practices for git repositories on open source projects but there are OSX / Xcode specific problems I want to know how to solve.
.DS_Store files can be a pain. You can use .gitignore to prevent, but what happens if they have already been included, or another developer adds them back in through a clumsy git command?
The .xcodeproj will have changes to the directory names and developer profiles for the other person. What's the best way to do merges or to avoid conflicts?
If I have forked or pulled from a github project, how can I clean up these issues and also minimise merge conflicts for the maintainer?
If people have an example .gitignore created for Xcode, or scripts they use to initialise their repos then that would be great!
Put .DS_Store in .gitignore. Then, if you haven't already, add .gitignore to the repo. (You should not ignore .gitignore.) Now all developers will ignore .DS_Store files. If any were added to the repo erroneously before you put .DS_Store in .gitignore, you can now remove them (in a commit) and they should stay out.
The xcodeproj is a directory. The only file in this directory that must be in the repository is the project.pbxproj file. I generally ignore all of the others by putting these lines in my .gitignore:
*.xcuserstate
project.xcworkspace/
xcuserdata/
You should avoid putting absolute paths in your build settings. Use relative paths.
Your Debug and Release builds should use iPhone Developer as the code signing identity, so that Xcode will automatically select the local developer's profile. When you want to create an IPA (for distribution), Xcode will offer to re-sign it with a different identity, at which point you can choose your distribution profile if you need to.
If you're trying to use a project from github that has made these mistakes, you can try to get the maintainer to fix them, or you can make sure you don't touch the .DS_Store files and the code signing identities in the same commits that you want to send upstream.
For the 2nd issue regarding the .xcodeproj and merge conflicts.
Using a .gitattributes file to specify that merge conflicts for all .pbxproj files should be handled using the merge=union strategy, which should mean that Git knows to merge in the changes from both sides of the conflict, taking the upstream changes first.
This article explains it in a bit more depth
I'll try one by one:
I. You need to use git filter-branch only if you need to remove the files from your history completely. If those files do not contain any credit card information, then i think the following should be enough:
git rm --cached .DS_Store
git commit -m "{Your message}"
then add this file to .gitignore and commit it.
This will commit the removal of the file from the repository but will keep the file in working directory. If you push it though and then somebody else will pull this commit, they might have their file removed, so you MUST communicate this.
By committing .gitignore you will prevent other developers from adding this file again.
If you're not a maintainer, then i don't think you should do anything, but address this issue to the maintainer.
II. I'm a strong believer that hidden files of any nature are most of the time not supposed to be put into the repository exactly for that reason. Therefore i think that you should do the same thing with .xcodeproj as with .DS_Store and put it into .gitignore and commit it. .gitignore is the exception for the rule above.
III. If those files are properly ignored , then there will be no issues in future with them. If they are already in the repo and somebody wants do such cleanup it should be done by maintainer and communicated inside the team.
Hope that helps!
git filter-branch might help you to remove unwanted files (.DS_Store files) from your repository -- see e.g. https://help.github.com/articles/remove-sensitive-data
If a clumsy git commit has added files you should be able to replay the corrected changesets onto a clean repository.
You're right in the sense that if a .DS_Store is already added the .gitignore won't be of much help however I think this is still a good resource for you and others.
When I start a project, I normally look at this list to see if there is a good .gitignore already existing. More specifically for you, this one is the Objective-C .gitignore.
Hopefully those resources are of some use.
As a Mac user you should download a tool like SourceTree which supports Git Flow. Git Flow will help you establish some best practices around how your collaborators will commit code to the repo and at the very least make merge conflicts less frequent and more manageable. For a set of gitignore files for various project types you can go to GitHub and download one that is ready to go. For Xcode they have it listed as Objective-C.gitignore. That is a good starting place and it even covers Cocoapods. If you're using external libraries, your project should use CocoaPods so that you can isolate that code and keep it outside of your repo and avoid git submodules.
Now when you find a file has made it into your repo like .DS_Store just remove it, and move on. Make sure you add it to the .gitignore file that is checked into the project.
As for xcodeproj... there shouldn't be that much customization within the file that is user specific since the above mentioned gitignore filters that out. If a scheme is to be shared make sure you check shared under Manage Schemes and you will check in files in that subdirectory. You should be using automatic selection of certificates so the only real choice is Developer or Distribution. You should also take advantage of variables provided within Xcode that avoid hardcoding complete paths. When trying to think of an example Plists came to mind, in this case, you might have written /Users/me/MyProject/Resources/MyProject.plist, but instead should use $(SRCROOT)/resources/MyProject.plist.

SVN: Colleague checked in a folder into repository, but I can't Update my version to it

In showing a colleague how to use SVN yesterday, we created a test folder and file within our existing Visual Studio Solution. We'll call it "Test" folder with two files, "Test.ascx" and "Test.ascx.cs". We added it (or Visual SVN added it, 'cos it's awesome), and committed it. We also added and committed other files elsewhere in the project.
We can see it in the repository (and the other files).
Doing an update on my own machine to pull down these new files resulted in the other files being pulled down correctly, BUT the Test folder does not appear. No matter how many times I try Updating from various points in VS and in TortoiseSVN (urgh) Repo browser, it can't see that there are any changes to pull down.
Where am I going wrong?
This is a known problem.
You can use
$ svn update --depth=infinity
to force the update. With TortoiseSVN, use the "Update to revision" command in the Submenu, then change the depth combobox to "fully recursive".
I've had ghost errors like this before and found the easiest work around is to delete the parent folder and update it's parent:
Project Root
Project
NewFolder
Delete Project, then Update Project Root
We can see it in the repository (and the other files).
...
No matter how many times I try Updating from various points in VS and in TortoiseSVN (urgh) Repo browser, it can't see that there are any changes to pull down.
So you can or cannot see it in the repository browser?
Did you commit and update the parent folder of your Test folder?
I don't know, svn is always telling me to clean, did you try that?
It's not an answer, I know, but I have tried all the solutions you guys have kindly suggested and I just end up with conflicts, crashed TortoiseSVN and built up Karma. Therefore, a trusty edit in the .svn/entries file sorted it.
I have until now been a single developer using SVN just to manage my source code. Other people don't have problems, and I just check in stuff. I use Visual SVN as a layer to frig SVN for .NET (which it isn't great with) and I seem to constantly run into issues. I am performing very simple operations, not even branching/tagging. Simple simple simple. And yet I have issues with it?

Resources