This page shows the source for this entry, with WebCore formatting language tags and attributes highlighted.

Title

Using Unity, Collab and Git

Description

If you're familiar with the topic, you might be recoiling in horror. It would be unclear, though, whether you're recoiling from the "using Collab" part or the "using Collab with Git" part. Neither is as straightforward as I'd hoped. <abstract> <abbr title="too long; didn't read">tl;dr</abbr>: If you have to use Collab with Unity, but want to back it up with Git, disable <c>core.autocrlf</c><fn> and add <c>* -text</c> to the <c>.gitattributes</c>. </abstract> <h>Collab's Drawbacks</h> Collab is the source-control system integrated into the Unity IDE. It was built for designers to be able to do some version control, but not much more. Even with its limited scope, it's a poor tool. <h level="3">The functionality horror</h> <ul> The system does not ever show you any differences, neither in the web UI nor the local UI, neither for uncommitted nor committed files Some changes cannot be reverted. No reason is given. You can only delete new files from the file system. There is no support for renaming Reverting to a known commit has worked for me <i>exactly once</i> out of about 10 tries. The operation fails with an <span class="error">Error occurred</span> and no further information. If you really get stuck, your only choice is to restore the entire workspace by re-cloning/re-downloading it. Conflict resolution is poorly supported, although it works better than expected (it integrates with <i>BeyondCompare</i>, thank goodness). </ul> <h level="3">The usability horror</h> <ul> The UI only lets you commit all changed files at once.<ul> There is no notion of "commits". You can’t commit individual files or chunks. There is no staging area. You can't exclude files. You can ignore them completely, but that doesn't help.</ul> The UI is only accessible via mouse from the menu bar. You can <i>sometimes</i> revert folders (sometimes you can't, again with an <span class="error">Error occurred</span> message), but you can't revert arbitrary groups of files. The UI is almost entirely in that custom drop-down menu. You can scroll through your changed files, but you can't expand the menu to show more files at once. You can show a commit history, but there are no diffs. None. There aren't even any diffs in the web version of the UI, which is marginally better, but read-only. </ul> <h>Pair Git with Collab</h> This is really dangerous, <i>especially</i> with Unity projects. There is so much in a Unity project without a proper "Undo" that you very often want to return to a known good version. So what can we do to improve this situation? We would like to use Git <i>instead of</i> Collab. However, we have to respect the capabilities and know-how of the designers on our team, who don't know how to use Git. On our current project, there's no time to train everyone on Git---and they already know how to use Collab and don't feel tremendously limited by it. Remember, <i>any</i> source control is better than <i>no</i> source control. The designers are regularly backing up their work now. In its defense, Collab is definitely better than nothing (or using a file-share or some other weak form of code-sharing). Instead, those of us who know Git are using Git <i>alongside</i> Collab. <h>It <i>kind of</i> works...</h> We started naively, with all of our default settings in Git. Our workflow was: <ol> Pull in Unity/Collab Fetch from Git/Rebase to head (we actually just use "pull with rebase") </ol> Unfortunately, we would often end up with a ton of files marked as changed in Collab. These were always line-ending differences. As mentioned above, Collab is not a good tool for reverting changes. The project has time constraints---it's a prototype for a conference, with a hard deadline---so, despite its limitations, we reverted in Collab and updated Git with the line-endings that Collab expected. We limped along like this for a bit, but with two developers on Git/Collab on Windows and one designer on Collab on Mac, we were spending too much time "fixing up" files. The benefit of having Git was outweighed by the problems it caused with Collab. <h>Know Your Enemy</h> So we investigated what was really going on. The following screenshots show that Collab doesn't seem to care about line-endings. They're all over the map. <img src="{att_link}collab_vs_git.png" href="{att_link}collab_vs_git.png" align="none" caption="JSON file with mixed line-endings" scale="25%"> <img src="{att_link}collab_vs_git_dot_cs_file.png" href="{att_link}collab_vs_git_dot_cs_file.png" align="none" caption="CS file with CRLF line-endings" scale="25%"> <img src="{att_link}collab_vs_git_dot_unity_file.png" href="{att_link}collab_vs_git_dot_unity_file.png" align="none" caption=".unity file with LF line-endings" scale="25%"> <h>Configuring Git</h> Git, on the other hand, <i>really</i> cares about line-endings. By default, Git will transform the line-endings <i>in files that it considers to be text files</i> (this part is important later) to the line-ending of the local platform. In the repository, all text files are LF-only. If you work on MacOS or Linux, line-endings in the workspace are unchanged; if you work on Windows, Git changes all of these line-endings to CRLF on checkout---and back to LF on commit. Our first "fix" was to turn off the <c>core.autocrlf</c> option in the local Git repository. <code> git config --local core.autocrlf false </code> We thought this would fix everything since now Git was no longer transforming our line-endings on commit and checkout. This turned out to be only part of the problem, though. As you can see above, the text files in the repository have an arbitrary mix of line-endings already. Even with the feature turned off, Git <i>was still normalizing line-endings to LF</i> on Windows. The only thing we'd changed so far is to stop using the CRLF instead of LF. Any time we <c>git reset</c>, for example, the line-endings in our workspace would still end up being different than what was in Git or Collab. <h>Git: Stop doing stuff</h> What we really want is for Git to stop changing any line-endings at all. This isn't part of the command-line configuration, though. Instead, you have to set up <c>.gitattributes</c>. Git has default settings that determine which files it treats as which types. We wanted to adjust these default settings by telling Git that, in this repository, it should treat <i>no files as text</i>. Once we knew this, it's quite easy to configure. Simply add a <c>.gitattributes</c> file to the root of the repository, with the following contents: <code> * -text </code> This translates to "do not treat any file as text" (i.e. match all files; disable text-handling). <h>Conclusion</h> With these settings, the two developers were able to reset their workspaces and both Git and Collab were happy. Collab is still a sub-par tool, but we can now work with designers and still have Git to allow the developers to use a better workflow. The designers using only Collab were completely unaffected by our changes. <hr> <ft><i>Technically</i>, I don't think you have to change the <c>autocrlf</c> setting. Turning off text-handling in Git should suffice. However, I haven't tested with this feature left on and, due to time-constraints, am not going to risk it.</ft>