Gource — визуализируем историю работы над проектом

    Спешу рассказать хабрасообществу о, относительно новом, дьявольски завораживающем проекте Gource которое еще не упоминалось. Это приложение позволяет визуализировать историю изменений в системе контроля версии. Отрисовывает невероятно красиво при помощи OpenGL.




    Скриншоты, еще видео.



    Git поддерживается нативно. Для CVS, SVN, Mercurial существуют скрипты позволяющие привести логи в нужный формат.

    Имея необходимые кодеки и конвертер ffmpeg можно рендерить в видео-файл:
    gource --output-ppm-stream - | ffmpeg -y -b 3000K -r 60 -f image2pipe -vcodec ppm -i - gource.h264

    Управление просмотром:
    • Клик правой кнопкой — переводим в режим автоматической «наводки» на активных пользователей
    • Q — информация о рендеринге
    • ↑↓ — зум
    • Пробел — пауза
    • с остальными еще не разобрался :)


    Приложение open-source, доступна бинарная версия под win и .deb пакет.
    http://code.google.com/p/gource/downloads/list

    ps. Я использовал следующие ключи для запуска gource -1280x1024 -f --highlight-all-users --multi-sampling для того чтобы запустить на полный экран в максимальном (для монитора) разрешении и постоянно видеть логины пользователей.



    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 51

      +1
      Очень напоминает программку, которая рисовала дерево в зависимости от html-тэгов страницы — получалось почти то же, что и на видео.

      Ну и в любом случае, получается душевнее, чем revision graph у того же CVS.
      +1
      А музыку оно само накладывает?
      Или вы ее руками в ролик вставили?
        +1
        Ролик с официального сайта. Приложение само по себе беззвучное :)
        0
        Историю версий лучше бы таймлайном реализовать ) интереснее было бы )
          0
          Здесь изменения отображаются именно в хронологическом порядке.
          0
          для VSS реально использовать?
            0
            Если имеется возможность вывести логи изменений и привести их к виду:
            1258533954|user|M|/trunk/abc.ru/www/js/jquery.js|
            1258533954|user|D|/trunk/abc.ru/www/js/jquery.old.js|
            то ответ — «да, можно»

            нативно работает только git, стальное конвертируется скриптами
              0
              ну как вариант поискать возможность порта на git или svn и т.д. =)
                0
                кому интересно vvs2svn — ___http://vacula2.blogspot.com/2008/01/vss-svn.html
                0
                Unsupported log format.
              +1
              Берите пример с соседнего топика:

              «Спешу рассказать хабрасообществу о относительно новом крышесносящем проекте Gource о котором еще не было упоминания» :)
                0
                не смог подобрать синонимов, поэтому немног оперефразировал :)
                «Спешу рассказать хабрасообществу о, относительно новом, дьявольски завораживающем проекте Gource»
                0
                кружочки — это файлы или изменения?
                  0
                  кружочки это ноды, ноды могут файлами или директориями.
                  лучи которые испускают пользователи бывают трех цветов:
                  * зеленый — добавление
                  * оранжевы — модификация
                  * красный — удаление
                  0
                  Всегда поражают подобные проекты, завидую белой завистью. Каждый раз задаюсь вопросом — что они курят где они берут такие идеи? :)
                    +5
                    Очень забавно смотреть за пользователями, они прям как пчелы, опыляющие цветок
                      0
                      Точно, очень на пчел похоже!
                      Интересно попробовать на своем тоже.
                      0
                      музыка! чей трек в этом ролике?
                        0
                        Нет ли у кого cvs-exp (для конвертации cvs лога в нужный формат)?
                        Все ссылки ведут на www.cs.rice.edu/~ssiyer/code/cvs-exp/ где 404
                          0
                          А можно взглянуть на формат? Я не поленюсь написать парсер. (Не раньше чем утром)
                          Было бы хорошо пример на почту me [at] zhekanax.ru
                            0
                            Хотя могу и сам получить лог из общедоступного проекта — не за чем приватную информацию слать :))
                            +2
                            gource.googlecode.com/files/cvs-exp.pl вернули пропавший скрипт
                            +2
                            Ве-ли-ко-лепно.
                            Больше часа на максимальной скорости смотрел на развитие нашего проекта. Завораживает.
                              0
                              а какая там максимальная скорость и как её установить?
                                0
                                Ну, я пользовался -s 1 --max-file-lag 10. Правда, что-то не уверен, что вторая опция помогла.
                              +1
                              Супер-вещь! Посмотрел не отрываясь. Поставил на ночь виде конвертироваться. Наложу звук и устроим завтра всем отделом просмотр :)
                                0
                                Не травите душу (
                                cvs-exp.pl нигде в инете нет, выдрать cvs-log в нормальном виде не получается, попытка реинжениринга сорцов для написания парсера взрывает мозг
                                0
                                Граждане, помогите установить на MacOSX. "./configure" в конце выдает: «configure: error: *** SDL version 1.2.0 not found!»
                                А SDL не знаю, как установить, там нормального гида нет. Тупо копирование в "..../Frameworks" не помогает. SDL беру из www.libsdl.org/release/SDL-1.2.14.dmg
                                Кто понимает в этом лучшее моего?
                                  +1
                                  поставьте macports, через них необходимые зависимости устанавливайте
                                    0
                                    Да, это стало откровением. Дело пошло. Столько либ всяких для SDL устанавливается, капец.
                                      0
                                      Все понятно. Это того просто не стоит.
                                      За пару часов смог сделать configure без ошибок. Теперь выскочили ерроры при билде. С этим уже точно разбираться нет охоты.
                                      Всем спасибо.
                                  0
                                  Ух ты, вот это круто!
                                    0
                                    Это просто праздник какой-то… Класс!
                                      0
                                      Чем то похоже на игру Eufloria.
                                        0
                                        Как получить логи TFS:

                                        1. качаем Visual Studio SDK.
                                        2. В Reference добавить: Microsoft.TeamFoundation.Client, Microsoft.TeamFoundation.VersionControl.Client
                                        3. заюзать примерно такой код на C# ), правила сами замените если нужно )

                                        using System;
                                        using System.Collections.Generic;
                                        using System.Diagnostics;
                                        using System.IO;
                                        using System.Text;
                                        using System.Windows.Forms;
                                        using Microsoft.TeamFoundation.Client;
                                        using Microsoft.TeamFoundation.VersionControl.Client;

                                        namespace GourceTFS
                                        {
                                          class Program
                                          {
                                            private const string outFile = "output_log.txt";
                                            const string tfsServerURL = "http://server:8080";

                                            /* If you want to use Gource with something other than the supported systems, there is a pipe delimited custom log format:  
                                             * timestamp - A unix timestamp of when the update occured.  
                                             * username - The name of the user who made the update.  
                                             * type   - Single character for the update type - (A)dded, (M)odified or (D)eleted.  
                                             * file   - Path of the file updated.  
                                             * colour  - A colour for the file in hex (FFFFFF) format. Optional.    
                                             */

                                            /// <summary>
                                            /// method for converting a System.DateTime value to a UNIX Timestamp
                                            /// </summary>
                                            /// <param name="value">date to convert</param>
                                            /// <returns></returns>
                                            private static double ConvertToTimestamp(DateTime value)
                                            {
                                              //create Timespan by subtracting the value provided from
                                              //the Unix Epoch
                                              TimeSpan span = (value - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime());

                                              //return the total seconds (which is a UNIX timestamp)
                                              return span.TotalSeconds;
                                            }

                                            [Serializable]
                                            class ChangeItem
                                            {
                                              public double timestamp { get; set;}
                                              public string username { get; set; }
                                              public char type { get; set; }
                                              public string file { get; set; }

                                              /// <summary>
                                              /// Converts the specified type.
                                              /// </summary>
                                              /// <param name="type">The type.</param>
                                              /// <returns></returns>
                                              public static char Convert(ChangeType type)
                                              {
                                                char _out = '\0';
                                               
                                                if (type == (ChangeType.Add | ChangeType.Edit | ChangeType.Encoding))
                                                {
                                                  _out = 'A';
                                                  return _out;
                                                }

                                                if (type == (ChangeType.Encoding | ChangeType.Delete | ChangeType.Branch))
                                                {
                                                  _out = 'D';
                                                  return _out;
                                                }

                                                switch (type)
                                                {
                                                  case ChangeType.Add:
                                                    _out = 'A';
                                                    break;
                                                  case ChangeType.Merge:
                                                    _out = 'M';
                                                    break;
                                                  case ChangeType.Edit:
                                                    _out = 'M';
                                                    break;
                                                  case ChangeType.Delete:
                                                    _out = 'D';
                                                    break;
                                                }

                                                if (_out == '\0')
                                                {
                                                  throw new ArgumentException("fff");
                                                }

                                                return _out;
                                              }
                                            }

                                            static void Main()
                                            {
                                              var TFSLogs = TFSLogsList();

                                              using (var sw = new StreamWriter(outFile, false, Encoding.UTF8))
                                              {
                                                foreach (var item in TFSLogs)
                                                {
                                                  sw.WriteLine("{0}|{1}|{2}|{3}", Math.Floor(item.timestamp), item.username, item.type, item.file);
                                                }
                                              }

                                              var pi = new ProcessStartInfo
                                                     {
                                                       FileName = Application.StartupPath + @"\Gource\gource.exe",
                                                       Arguments = outFile + "--log-format custom -1280x1024 -f --highlight-all-users --multi-sampling ",
                                                       UseShellExecute = true
                                                     };

                                              var p = new Process {StartInfo = pi};
                                              p.Start();

                                              Console.Read();
                                            }

                                            static List<ChangeItem> TFSLogsList()
                                            {
                                              const string _tfsPath = "$/SomePlace";

                                              var tfs = TeamFoundationServerFactory.GetServer(tfsServerURL);
                                              var vcs = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));  // Null means All  
                                              const VersionSpec versionFrom = null;

                                              var history = vcs.QueryHistory(_tfsPath,
                                                              VersionSpec.Latest,
                                                              0,
                                                              RecursionType.Full,
                                                              "",
                                                              versionFrom,
                                                              VersionSpec.Latest,
                                                              Int32.MaxValue,
                                                              true,
                                                              false);

                                              var GourceList = new List<ChangeItem>();
                                              var changesets = new List<Changeset>();
                                              foreach (var _item in history)
                                              {
                                                changesets.Add((Changeset)_item);
                                              }

                                              var o = new Comparison<Changeset>((p, y) => p.ChangesetId.CompareTo(y.ChangesetId));
                                              changesets.Sort(o);

                                              foreach (var changeset in changesets)
                                              {
                                                foreach (var change in changeset.Changes)
                                                {
                                                  if (change.Item.ItemType == ItemType.Folder) continue;
                                                  var item = new ChangeItem
                                                  {
                                                    username = changeset.Committer,
                                                    type = ChangeItem.Convert(change.ChangeType),
                                                    file = change.Item.ServerItem,
                                                    timestamp = ConvertToTimestamp(change.Item.CheckinDate)
                                                  };

                                                  GourceList.Add(item);
                                                }

                                                Console.WriteLine("Adding changeset: " + changeset.ChangesetId);
                                              }

                                              return GourceList;
                                            }
                                          }
                                        }

                                        * This source code was highlighted with Source Code Highlighter.


                                        P.S жаль что формат не распознался проектом Gource. Хотя делал по разному подбирая их custom format. ((
                                          0
                                          Math.Floor может необязателен.
                                            +1
                                            а [Serializable] по привычке )
                                            +1
                                            > "{0}|{1}|{2}|{3}"
                                            а если добавить еще один | в конце? как в их формате
                                              0
                                              пробовал. по всякому не работает.
                                              если подберешь поделись )
                                                0
                                                $ file tmp.log
                                                tmp.log: ASCII text
                                                $ cat tmp.log
                                                1142233434|zhe|A|/trunk|
                                                1142233494|barba|A|/trunk/index.php|
                                                1142233434|zhe|M|/trunk|
                                                1142233434|zhe|D|/trunk/index.php|
                                                $ gource --log-format custom tmp.log

                                                Насколько я вижу кодировка utf8, думаю стоит использовать однобайтовую или хотя бы попробовать убрать BOM
                                                  0
                                                  а кстати возможный вариант )
                                                    0
                                                    Все Гуд, счас буду пытаться видео записать )))

                                                    Формат: {0}|{1}|{2}|{3}
                                                    Нужно делать в ASCII.

                                                    var pi = new ProcessStartInfo
                                                    {
                                                    FileName = Application.StartupPath + @"\Gource\gource.exe",
                                                    Arguments = outFile + "--log-format custom -1280x1024 -f --highlight-all-users --multi-sampling ",
                                                    UseShellExecute = true
                                                    };

                                                    Поменять на:

                                                    var pi = new ProcessStartInfo
                                                    {
                                                    FileName = Application.StartupPath + @"\Gource\gource.exe",
                                                    Arguments = " --log-format custom " + outFile + " -1280x1024 -f --highlight-all-users --multi-sampling ",
                                                    UseShellExecute = true
                                                    };
                                                      0
                                                      заодно можешь рассказать хабрапользователю pasha_golub (комменатрий ниже) как в win записать видео. Насколько я понимаю, вы на одной платформе :)
                                            0
                                            Чумовая штука. Я уже все репы свои из SVN трансформировал.

                                            Друзья, а под Windows возможно видео записать? Я попробовал и не вышло. Если можно, покажите точно как должна выглядеть коммандная строка.

                                            Спасибо заранее
                                              0
                                                0
                                                а нафига оно?
                                                Какой ПОЛЕЗНЫЙ смысл оно несет?
                                                  0
                                                  Какая прелессть.

                                                  Only users with full accounts can post comments. Log in, please.