I'm currently in the process of porting the next version of UE4 which takes up a lot of my spare time, so it took a while before I could revisit.
I might be able to help you out a little with the issues you have, answer some questions and possibly improve your productivity with Git.
I always put central SCM repositories on a server. <snip> So yeah, I see a lot of benefits of having the SCM repositories on the server and working copies on the working or production machines, for me this is the natural order of things, and this has nothing to do with Xcode. However, most probably I misunderstood your question.
I think the disconnect came from me assuming you were working on the FreeBSD project and thus using the FreeBSD SVN server.
What I read from your latest explanation is that the code is in only 2 places (dev systems, local server) whereas I was assuming you have it in 3 places
(dev systems, local server, remote server). If I understood it correctly, then yes, that is the natural order of things.
Like I said earlier, you should always have a central repository somewhere, whether you're using Git or SVN. That single repository is key to cooperation.
Yes, it's possible to use Git in a star-like pattern where every developer connects to every developer but I'm pretty sure such a workflow would quickly
fall under its own weight.
Small tip that might benefit you when using Git to deploy: using shallow checkouts on your production servers will consume less HD space and prevent
unnecessary fragmentation
Subversion: svn commit | svn update
Git: git commit (to the local clone) | git push (to the server) | git pull (to the local repo) | git push (to anywhere) | git pull (from anywhere) | git fetch (from an arbitrary remote) | git fetch, what? Git give me a break. And what the hell is a detached HEAD? I resolved that question using Time Machine, since in Git’s plungers toolbox, I could not find the right one after one hour of searching the web.
However, you’re right, the mere commands git commit/push replace svn commit and git pull replaces svn update. And this is what I meant that the good news is that we may use Git as if it were Subversion (note I did not say using svn commands as the frontend for git repositories), and leave all this sophistication to those who care to bother.
I think I can help you and anyone else who reads this thread through.
Assuming most people use Git with only a single remote (typically called "origin"), then there's no need for most of the distinctions you list above.
It is perfectly safe to not care about multiple remotes if you don't use it. In that regard, yes, Git can be used as SVN because SVN simply didn't have any
support for multiple remotes.
Now the question about detached HEAD is an interesting one because I've heard people ask it before. This one really comes from not understanding the
differences between Git and SVN. It's really well explained
in this Atlassian tutorial towards the bottom. To understand it, you will need to understand
how Git works compared to SVN. Once you do, it'll make sense.
If I had a whiteboard here you'd understand it in a heartbeat. A drawing says so much more than words but I'll try.
The message says you were no longer working on a branch but had checked out a specific commit. If you were to add commits here, you'd still be in this
detached state. You could create a new branch from where you were and fix it like that. Or you could simply go back to an existing branch.
Since I'm assuming you didn't mean to branch out, a simple
git checkout <branch-you-want-to-be-on>
would have done the trick.
I'd like to add my personal experience from the first time I used Git. It was in a professional environment, I had 15+ years of of SCM experience and I had
Git explained to me by a (1-in-a-100) junior. While I had no issue understanding the basics, I didn't get the benefit of Git over anything else.
That all changed when I started getting errors like you did. Now you have to know that I'm the type of person who doesn't do things without understanding
what goes on. So I took a few hours to read up about how it all works and once I did that, it just clicked. From there, I went on to more advanced topics up
to the point that I (again
) became the person that was teaching people.
Yes, this is the benefit from the point of view of the single developer, however this may turn into a disadvantage for a dev team, when some not so disciplined developers are not that committed to push their changes. The single developer got his sandbox and may stay in there for ever if he likes. Also with Subversion you can work offline, you only need a connection in the very moment of committing and updating, however, it is more likely that the work makes it into the central repository. For example in an Xcode project source file list, I see a tiny M as an indication beneath modified files. This indication goes away once I execute svn commit on projects under Subversion control or git commit on projects under Git control. So, far so good for Subversion and bad for Git, since actually nothing needs to be pushed in order the developer receives his „Commit“-Satisfaction.
I do understand your issue here, but I'm afraid that it's Apple that made your life more difficult. They could have easily added some indication that code
hasn't been pushed to the remote. Maybe they even added in an option somewhere, but like I said I'm not familiar with XCode.
Throughout my years I've seen juniors not commit their code (back on SVN) and I've seen juniors not push their code (on Git). It's really a basic thing to
do and I can't fault any software about this. If people don't send their code to the server, which is the easiest thing ever, I cringe to think what else they
forgot to do.
In a professional setting there are some extra checks (e.g. Jira can warn about changing the status of a ticket when no code is pushed), but it just comes
down to human error if it doesn't happen.
It may well be, that it is my personal problem that I am not ready for all this fantastic Git options. I will happily stay with
git commit; git push (in one breathe) and
git pull. Creating branches and merging was easy for me using subversion, and I understood what actually was going on. I read
git-branch(1) and I understood nothing, and so I copied and pasted a command from StackOverflow.
Well, a man page isn't exactly the best place to find explanations about how the Git branching model works. I would really encourage you to take a step
back and read the documentation instead. If you knew nothing about branching in svn, the man page wouldn't help you either.
The
official Git branching documentation starts here, but I really recommend reading more than just that chapter.
I'm not a big fan of StackOverflow as far as software goes, because of the very thing you posted here. I would never ever run a command that I don't
understand. There was a thread on this forum earlier where someone had this nice obfuscated shell command that - once executed - would simple
do an
rm -rf /*
. It was fun to see, but I'm betting someone executed it without verifying.
Back in the day you first started using CVS, didn't you have to read about how branching worked as well? While my branching experience with CVS was
limited, I surely had to learn how to use SVN branching.
Don't assume because you're an expert at SVN you can use Git without ever learning about it. I have plenty of experience with both and can tell you that
it simply doesn't work this way. You'll just be hating Git more the longer you're (forced to) using it.
To give an extra example about using multiple repositories etc I'd like to add a little part about how I currently use Git in my UE4 port.
What I'm doing there is really advanced stuff that goes a lot further than simple checkin/checkout. Using SVN this would be a massive mess. Using Git,
well, checkout the commands below. It's a testament to Gits power that this is possible.
So I have my main remote (origin) running on my personal GitHub. Epic has its own GitHub account.
In my local development environment I have both remotes set up. Each time Epic makes changes, I integrate these in my local copy and push them to
my Github. Remember when I said in my previous post that everyone has everything, just as if every developer's repository is the server?
That's why we're fetching changes from the remotes. In general, this is done automatically when using
git pull
but I also use it to see how
much new stuff there is.
It is important to note that
nothing changes in my local copy of the code when doing this. That's why I'm not using git pull (which will automatically merge).
git fetch --all
Then the re-integration starts. I use rebasing for my workflow. This has advantages and disadvantages, but I'll leave it to the readers to find this out. I
consider this an advanced git command and it won't make sense how this works unless you actually understand how Git works (differently from SVN).
In this command I'll assume I'm rebasing my master branch on Epic's master branch. I might also have to fix some merge conflicts while running this.
git rebase -i epic/master
The last and final step is sending it all to my GitHub. I have to force push though.
Never do this unless you know what the implications are.
git push -f