Onward and upward ...
I've been in branching hell today, but I think I've at least figured out what's wrong.
a. When you create a branch in Xcode 4, it always creates it in the local repository.
This make sense to me as GIT is designed to be worked on locally and then changes pushed and pulled to other repositories, so this seems reasonable. b. There's no way in Xcode, AFAICT, to push that branch to the remote repository. So, you have to use the command line for this. Well, OK, that was true getting the initial branch uploaded too.
Looks like thats the case, maybe that will come in a future version. But once it's there, it gets a little weirder:
c. You can clone either remote branch in Xcode, by selecting the appropriate branch in its "extra" repository entry for the remote repository as a whole. (You can't avoid it creating this extra one for you.) If you select nothing, you only get one branch -- I always got 'master'. Otherwise, you can select one thing and you get that branch.
I can't see any options for cloning a particular branch, but my remote repository is just a "bare" repository on my local filesystem, so perhaps these options are only there for "real" remote repositories. (Although I do need to file a bug as Xcode cant see any of the commits inside my bare repository, which may be why it can't pick up any alternative branches either.) d. You can't clone multiple branches into the same local repository AFAICT. (I tried to multiple select for the clone, but it doesn't let you.)
The problem is that Xcode can only merge branches within a local repository (AFAICT), so you're going to have to do something manually or you'll never be able to merge anything. Googling found me this command line solution:
git branch --track branch-2 origin/branch-2
where 'branch-2' is of course a branch that's missing from the local repository. Xcode will eventually notice the change, and then I think everything's fine after that.
Anyone got an opinion if this is a design flaw in Xcode, or just a bug, or am I misunderstanding something here?
I'm just learning GIT at the moment so a lot of this is still quite confusing but.... It looks like when you clone a GIT repository you do get all the various branches in your local repository, you just don't automatically get local branches set up to track them all.
This makes sense if you consider a big repository with hundreds of branches, if you got all the historical branches set-up locally by default it would be overwhelming. So it makes some sense that you need to pick the branches you are interested in. Obviously there's no Xcode interface for this currently so it's back to the command line. e. If you create a branch in a local repository with Xcode, and push it to the remote repository yourself (a-b above), then that branch won't pull in Xcode -- you get an error that "The operation could not be performed because the tracking branch for the current branch could not be located." It seems to me there's no way to fix that even from the command line. I couldn't see anything that suggested you could do the "--track" thing on an existing local branch. Is there a way of doing it that I'm missing?
The only way I found to get out of this state was to trash the local repository and re-clone the remote copy, then add the other branch manually as a tracking branch (d above).
I found the following GIT command fixes this error without having to trash the local repository...
git branch --set-upstream master origin/master
This also worked for me with other branches, so for a second development branch i used...
git branch --set-upstream development origin/development
which got the second branch working after the initial push from the command line and the same error in Xcode. Afterwards I could then push and pull the development branch to the remote repository whenever I selected it as my working branch in Xcode.
I also tested adding a second local repository to check that I could push changes up from one, and then pull down from the other repository. It all seems to work ok for both branches all in the IDE. So apart from the initial set-up which needs to be done from the command line, and the fix above to get things up and running, it looks like you should be able to get multiple branches pushing and pulling from within the Xcode IDE all in one repository.
(As mentioned before this was all done with a simple "bare" repository on my local filesystem as the remote, so I've no idea how much of this works with repositories on services like GitHub or Beanstalk) I think Xcode's problem is that it doesn't really seem to understand remote repositories as mirrors, only as "local" repositories hosted elsewhere -- which is certainly a valid git usage case too. Unfortunately, when someone else owns the server, like Beanstalk, the other repository isn't local *anywhere*, so it's impossible to administer within Xcode.
That's a pity, because when you stick within the bounds of what Xcode can actually do, git-based Xcode-integrated SCM is a joy to use.
After a few days learning about GIT, it's amazing just how rich the functionality is, I guess it's going to take a while for it to all filter through into the Xcode IDE.
(I've only just joined the mailing-list so I didn't have the original copy of this mail to reply to, I'm hoping just having the matching subject line will add this to the correct thread?) |