Version Control in Gamedev

edited in General
Hi all,
I've shared the slide deck from Tuesday evening here:
http://www.slideshare.net/mattbenic/source-andassetcontrolingamedev

The Github repo I set up for the ill-fated demo is at:
https://github.com/mattbenic/SourceControlInGameDev

The only thing really worth having in that repo is the .gitignore file, which you can use as a template when prepping your own projects for git. Other than that, those bugs are still in there waiting to be fixed, so feel free to mess around as you like to get used to git :) What I'd really love to see here is people actually trying to use this and posting any issues they run into.

Comments

  • I strongly recommend learning the command line functions for git. 1) You'll learn the capabilities and options of each function which might be defaulted or hidden in a GUI; 2) You can default back to command line if your GUI fails; and 3) You'll understand eventually using a GUI better.
  • Oh yeah totally, there are also some advanced features in there that it's likely no gui will ever implement. It's just so damned easy getting into the GUI though, and obviously we don't want to expect our artists to use the cmd, so GUI just sort of happens :)
  • edited
    I'd have to recommend tortoise git (if you're on windows) and then reverting to command line when you want to do something "unusual". From a UX perpective a command line is an incredibly poor way to learn. Tortoise git does a great job of showing you optional configuration params I would have never found digging through command line documentation, which whilst very thorough is also super dense and not suited to learning.

    Another cool thing is that tortoise git is just a ui layer that calls the command line itself, and it always shows what commands it's calling. There are several advanced git-jitsu manouveres i've pulled thanks to having a clear ui in front of me. Especially interrogating logs and viewing diffs across versions I find incredibly painful without GUI.

    Unfortunately the other GUI's i've used are ...ahem... not good. And no excuse for not knowing how to use the command line at all.
  • Actually I personally discourage TortoiseGit use, despite being a massive fan of TortoiseSVN when we used SVN :)

    I find of all the Git UI tools, it hides Git's true nature the most and people using it take the longest to click to the concepts behind Git. SourceTree and SmartGit give a far clearer idea (always showing the working set, state of all files, etc in a single view instead of having to dig through the folder hierarchy or open a separate window).

    We also found TG to be pretty unstable, but to be fair it's been almost 2 years since I used it, so it may have come a long way in that time.
  • [url = http://www.gamasutra.com/blogs/BurkayOzdemir/20130303/187697/Using_Unity3D_with_external_VCS_Mercurial__Bitbucket_step_to_step_guide.php]Using Unity3D with external VCS, -Mercurial & Bitbucket- step to step guide[/url]

    Found it on Gamasutra, hope it helps some folks.
  • FYI Microsoft Team Foundation Server recently enables you to use Git as your version control, tightly integrated with their suite of tracking and management tools. This should give a clear idea of how well Git is trending as the popular choice in the 3rd generation of VCS.
  • Ok, so I got a bitbucket repository running with Git Bash and have done some things like cloning my project, pushing some stuff and pulling some stuff.

    So far the workflow seems to go : Make Changes -> git Add files -> git Commit -> git Push

    This leads me to a few questions.

    1) Do I have to explicitly call the "git add <file>" command for every file I want to commit?
    2) Is it better practice to git add a file before I change it to avoid forgetting to add it later? Worst case scenario I will push a file I haven't changed.
    3) Does the push command force other remote repositories to pull or does it only upload it to the bitbucket copy of the repository.

    If someone can help me out that'd be cool. :)
  • Personally I prefer Mercurial because I like the simplicity of it, but sometimes I do miss the power of Git. Either choice is a good option. I also HIGHLY recommend Bitbucket for a central repo hosting solution. They offer a professional service with unlimited private repos as long as your team is no bigger than 5 members. If you are larger, it is pretty cheap to upgrade. A lack of private repos is a big issue for Github as far as I'm concerned.

    Some tutorials to guide you through the basics of using Git or Mercurial in your workflow.
    Git Tutorial: http://atlassian.com/git/
    Mercurial Tutorial: http://hginit.com/
  • 1. As far as I know, you can use wildcards and stuff when you're using the command line git add. But if you're working with a lot of files, I think this is one of the areas where using a GUI makes more sense. <_<

    3. Push just uploads it to bitbucket (or, afaik, whatever you've set the 'origin' to be). The other repositories have to run a Pull (or Fetch) to get the changes.
  • edited
    1) Yes, but you can run git add -A to add all files (it will ignore files listed in .gitignore)
    2) If you add the empty file and then edit you will need to add again to update the staging area before you commit. What I do before I'm ready to commit is run git status which will show you which files have been changed, which files have been added and which files are not being tracked.
    3) No, if you have to use some other mechanism to notify people of updates to the server repo. I seem to remember BitBucket does have notifications but I could be wrong
  • edited
    francoisvn said:
    A lack of private repos is a big issue for Github as far as I'm concerned.
    I totally agree, it would be nice to at least have one private repo allowable per account. Where github can turn out to be cheaper though, is when you have large teams working on a project. There is no limit to the number of users that can have access, the different pricing tiers just dictate the number of private repos you can have.
    Rigormortis said:
    Ok, so I got a bitbucket repository running with Git Bash and have done some things like cloning my project, pushing some stuff and pulling some stuff.
    Yay, congrats :)
    So far the workflow seems to go : Make Changes -> git Add files -> git Commit -> git Push
    Well, when working with others on your team it's actually more like:
    1. Make changes, test
    2. Stage changes you want to commit (git add)
    3. Commit (git commit)
    (repeat 1-3 as needed, you can push multiple commits at a time)
    4. Pull (= Fetch + Merge) (git pull)
    5. Retest merged code, repeat from 1 if problems found
    6. Push (git push)

    Obviously now, while it's just you, you'll likely just be making changes, committing and pushing. Git won't let you push to a repository if it has newer unmerged changes anyway, it'll fail and you will need to pull and then retry.

    This leads me to a few questions.

    1) Do I have to explicitly call the "git add <file>" command for every file I want to commit?
    2) Is it better practice to git add a file before I change it to avoid forgetting to add it later? Worst case scenario I will push a file I haven't changed.
    3) Does the push command force other remote repositories to pull or does it only upload it to the bitbucket copy of the repository.

    If someone can help me out that'd be cool.
    Awesome, this is exactly the sort of discussion I was hoping to see :)

    1) Yes. You explicitly tell git what you want included in any given commit. git add -A will add all changed files in your working set but be sure your .gitignore is set up correctly so you don't end up committing stuff you don't need to. As jono said, this is where a GUI really comes in handy, I like to be able to quickly review the diffs per file before committing and be selective about what is committed (you can do this on commandline as well, GUI is just quicker).
    2) No. When you're ready to commit (you have completed a piece of functionality, or you're at a point where you want to be able to experiment and have a safety net, etc) you add what you want to commit.
    3) No. You can have your current branch (probably master right now) track a particular remote branch, and when you just git push/git pull with no additional parameters those operations will act on that remote. Your actions will have no effect on other repositories (unless there is some kind of commit hook set up on the remote, but that's a whole other kettle of fish). git remote show origin will show you which branches are tracked on that remote.



  • I personally use SmartGit which comes with Git Bash if you want to work on command line.
  • I'm a total SourceTree fanboy, but the windows version is only in Beta right now (still really, really good).

    SmartGit is excellent as well though, and is a very close second choice for me. The fact that it's multiplatform and free for non commercial work is great as well :)
  • I have to agree with @mattbenic that SourceTree is superior.
  • With my limited exposure to source tree I found it a horrible experience. Now that it is coming to win I might give it another whirl make sure I'm not missing anything...
  • TheFuntastic said:
    With my limited exposure to source tree I found it a horrible experience. Now that it is coming to win I might give it another whirl make sure I'm not missing anything...
    I suspect I may have had the same feeling about it if I used it early on when I was just figuring Git out. I butted my head with TortoiseGit for a while first (oooh, look! It's just like ToirtoiseSVN) and then moved on to Smart. Then when I first did git work on Mac and tried SourceTreeit was all hearts and roses :P

    With it being the first truly free Git GUI of that caliber (Smart isn't really free if you're doing commercial work with it), now that it's multiplatform I wouldn't be surprised to see ST become something of a standard.
  • edited
    Okay, so I've taken SourceTree for a spin today. Typical day to day stuff, pushing pulling etc. Included trying to track down a regression bug through the git log.

    The most important thing I can say about these sort of evaluations is that it's less about which is empirically better and more about which you can be more productive in. If you've already paid the learning costs of one platform and overcome the learning curve, that is where you will inherently be more productive, and therefore will always exhibit a bias in its favour.

    Disclaimer out the way, the results of my super unscientific experiment (TortoiseGit vs SourceTree)

    What I like about source tree:
    • The Graph looks nice, and actually makes sense. Huzzah! (the graph in tortoise is terrible)
    • The UI/Button Names and such not only look nicer, but are generally a lot more consistent, consolidated and well thought out. Probably does give a better representation of the "Git way" to novices
    What I don't like:
    • Dude, where my file tree?
    • Diff viewer is meh. Linked up external diff, so probably I could learn to live with it
    To expand on the negative, it feels like source tree lacks any context. Things feel a bit too automagical, which is really unnerving when things go fubar and you're trying to rescue your repo from the clutches of death. Being able to see that little tick icon overlayed on the same file structure your eyes have already seen a million times in your IDE gives me a much better sense of "what's actually happened". Though in time I guess I would get used to source trees way if I was pressed. This is actually why I don't like working on the command line - so little context!

    Another point is diff tools. I find that standard git/source tree representation very difficult to grok. Show me my whole god damn file. That's the way my eyes are used to seeing it in my IDE. That's definitely the way I want to see it when I'm trying to figure what the hell has gone wrong. Don't make me think more than I have to about "what function is this snippet of code actually from".

    Best diff viewer in my opinion is actually the one built into monodevelop. So easy to understand exactly what's going on! And so easy to pick your changes. Wish all IDE's and Git UI's had that!

    Personal preferences aside I would totally recommend it over tortoise to someone non technical.
  • edited
    The most important thing I can say about these sort of evaluations is that it's less about which is empirically better and more about which you can be more productive in. If you've already paid the learning costs of one platform and overcome the learning curve, that is where you will inherently be more productive, and therefore will always exhibit a bias in its favour.
    Totally, it's always (initially) more productive to stick to the tools you already know. Sometimes the early slowdown to learn a tool is worth it, sometimes it's not :)
    Diff viewer is meh. Linked up external diff, so probably I could learn to live with it
    I love the built in diff viewer-the one shown in the bottom right panel when you select any files in your working set, or anywhere else really. The external diff that's used for handling conflicts, I agree with you.. totally meh! Thankfully you can easily choose a different merge/diff tool in the settings, most of the major ones are supported out of the box in a dropdown (not sure about that on windows yet) and any others can be configured with a custom commandline.
    It's worth mentioning some of the reasons I like the built in viewer:
    1) It allows me to easily stage chunks of changes, something that Smart doesn't do. You can do this in commandline git, but I'd be very hesitant to do it without a view that shows me the result.
    2) Image diff! I love that I can easily see previous version vs new version. This has actually helped me solve a number of real project issues.
    3) Multi-file-select support. I can select all the files I've changed in a commit and get a quick overview of all changes by just scrolling down in this view.
    Dude, where my file tree?
    1) Click on "Working Copy". By default this view will only show you new/modified files in a flat structure. I actually find this more useful than having to dig through the directory structure. There are definitely cases where the directories help though, so:
    2) To see the files in this view laid out in a directory tree, select "Tree View" from the first dropdown above your Working Copy that is defaulted to "Flat View".
    3) To change from only seeing pending (new/deleted/modified) files, select "Show All" in the second dropdown that defaults to "Show Pending".


    image
    Screenshot_2013_03_25_2_26_PM.png
    634 x 231 - 51K
  • Oh, since you mention dealing with a regression bug, one pet peeve I do have about SourceTree is the inability to do a free text search through the log text. You can search by commit ID, but that is very seldom useful-you end up having to scroll through the list of commits.
  • Image Diff?!? Now that is something I can get behind. But I just get a binary blob in the diff view if I try view a png. Is that expected behavior?

    Occurs to me SourceTree will probably handle cherry picking type operations way better that command line/tortoise-git.

    And hmm... seems tree view is totally missing in the windows version. Lame.
  • I just booted into windows for the first time in a while, you're right the tree view is missing from ST in windows. As I mentioned before the Windows version is still in Beta, so it's very likely this feature (and image view) will make it in as they update the app. The updates have been coming through thick and fast, so hopefully soon :)
  • edited
    We use Mercurial with TortoiseHG and Bitbucket. It's fast to set up and great for game jamming.

    My past versioning control experience is with SVN (also Tortoise) and Unity Asset Manager (which is of course kak).

    Mercurial wins. There isn't really anything more I want out of a versioning control system. We've got five people using it (including 2 artists) and we don't have any production hindering problems. I don't care about tree view and stuff, and we recently ditched JIRA because it didn't make us more productive, so I'm not sure if the bonus features in TortoiseHG are any good.

  • Unity Asset Manager (which is of course kak).
    So true it's just scary O_O

    To give Asset Server its dues, it is fantastically easy for artists to use from within Unity. It just isn't as fully featured as a modern VCS needs to be, in particular the fact that there's no branching (so no support for different released versions of your game) is a real issue.
  • I have been tinkering with this again, and I've run into some problems.

    I am trying to figure out how the branching works, but I constantly run into issues with the Temp/UnityLockfile when switching branches or trying to commit. So far as I understand it I can exclude the tracking off this file with a .gitignore file. This is the one I've been trying so far :

    # Unity3D .gitignore file.
    #	 Store this file at the root of your local repository.
    .DS_Store
    Library/AssetImportState
    Library/AssetServerCacheV3
    Library/FailedAssetImports.txt
    Library/ScriptAssemblies
    Library/ScriptMapper
    Library/assetDatabase3
    Library/cache
    Library/expandedItems
    Library/metadata
    Library/previews
    Library/guidmapper
    Library/ScriptMapper
    Library/assetDatabase3
    Temp
    *.pidb
    build


    If I understand this correctly I'm excluding all the Library subfolders specified, any file that ends with .pidb, and the entire Temp directory. Also the file named build and the first file that ends with DS_store? But it doesn't seem to be working. The .gitignore file is placed at the root in my .git folder.

    Any help or suggestions would really be appreciated.
  • edited
    @Rigormortis, I'm a bit of a noob with version control but I've got git working nicely with Sourcetree on my work windows machine and my macbook pro. The .gitignore file goes in your working directory, not your .git directory. Also, you need to append a "/" to directories you wish to ignore so:

    "Temp/"

    and all the Library subfolders as well. See if that does the trick?
  • @Tachyon, that did the trick...thanks.
  • edited
    Tachyon is kind of right. You can have a .gitignore file in any of the directories in your project, including the root. Practically though, I've always found having a single .gitignore in the root to be a more manageable solution.
    The trick is, the .git directory isn't part of your project :) It's your repository.

    Out of interest, here's a newer template .gitignore that I've been working on with @Chippit as we set up some new repos, taking experience with previous big repos into account:

    https://gist.github.com/mattbenic/5300183
    Thanked by 1TheFuntastic
  • I need some more help please...the situation is as follows. I created a project with a few basic objects and scripts. I pushed it to a bitbucket remote server. The second user cloned the project on their side and received all the files.

    The problem is that all the scripts are missing from the objects. They are in the correct folders in the cloned project but they aren't linked to the objects. At first we thought it was because we forgot to enable the meta version control but that wasn't the problem.

    We're using the .gitignore file that @mattbenic posted if that is any help.
  • Are the .meta files actually committed? It's really, really important that they be there.
    Also, check that your .gitignore still matches the one on gist, I corrected something pretty major there (refined the /ProjectSettings exclusion to only exclude /ProjectSettings/EditorBuildSettings.asset)
  • @mattbenic, we haven't tested it again to be absolutely sure, but I think we did find the problem. When I turned on the version control I had already created 2 branches. So the setting didn't cross over to the other branches, which I assumed it did. I'll check to make sure that it is working now and update here.
  • Ah yes. The settings in Unity are completely unknown to git :) They're stored in your projectsettings files, and if those changes aren't merged into the other branches, then yes they'll be missed.
  • Just FYI, In my quest to master commandline git (because really, my inability to use it when SourceTree failed me was just inexcusable :)), I've been using this great quick reference:

    http://gitref.org/

    It's wonderfully concise (as opposed to the actual manual) with good examples and is getting me through the bulk of stuff.
    Thanked by 1wogan
Sign In or Register to comment.